Merge pull request #2747 from shubhamkumar9199/fix/unsafe-json-parse
WEB-(394)-fix: replace all direct JSON.parse usages with safe parsing utilities
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
export function safeParse<T>(raw: string | null | undefined, defaultValue: T): T {
|
||||||
|
if (!raw) return defaultValue;
|
||||||
|
try {
|
||||||
|
return JSON.parse(raw) as T;
|
||||||
|
} catch {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function safeParseObject<T extends object>(raw: string | null | undefined, defaultValue: T): T {
|
||||||
|
if (!raw) return defaultValue;
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(raw);
|
||||||
|
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? (parsed as T) : defaultValue;
|
||||||
|
} catch {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function safeParseArray<T = unknown>(raw: string | null | undefined, defaultValue: T[] = []): T[] {
|
||||||
|
if (!raw) return defaultValue;
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(raw);
|
||||||
|
return Array.isArray(parsed) ? (parsed as T[]) : defaultValue;
|
||||||
|
} catch {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { AlertService } from 'app/core/alert/alert.service';
|
import { AlertService } from 'app/core/alert/alert.service';
|
||||||
import { Dates } from 'app/core/utils/dates';
|
import { Dates } from 'app/core/utils/dates';
|
||||||
|
import { safeParse, safeParseArray, safeParseObject } from 'app/core/utils/json';
|
||||||
|
|
||||||
/** Environment Imports */
|
/** Environment Imports */
|
||||||
import { environment } from '../../environments/environment';
|
import { environment } from '../../environments/environment';
|
||||||
@@ -108,8 +109,9 @@ export class SettingsService {
|
|||||||
/**
|
/**
|
||||||
* Returns date format setting.
|
* Returns date format setting.
|
||||||
*/
|
*/
|
||||||
get dateFormat() {
|
get dateFormat(): string {
|
||||||
return JSON.parse(localStorage.getItem('mifosXDateFormat'));
|
const parsed = safeParse<string | null>(localStorage.getItem('mifosXDateFormat'), null);
|
||||||
|
return typeof parsed === 'string' && parsed.length > 0 ? parsed : 'dd MMMM yyyy';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -119,7 +121,10 @@ export class SettingsService {
|
|||||||
if (!localStorage.getItem('mifosXLanguage')) {
|
if (!localStorage.getItem('mifosXLanguage')) {
|
||||||
this.setDefaultLanguage();
|
this.setDefaultLanguage();
|
||||||
}
|
}
|
||||||
return JSON.parse(localStorage.getItem('mifosXLanguage'));
|
return safeParseObject<{ name: string; code: string } | undefined>(
|
||||||
|
localStorage.getItem('mifosXLanguage'),
|
||||||
|
undefined
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get languageCode() {
|
get languageCode() {
|
||||||
@@ -147,7 +152,7 @@ export class SettingsService {
|
|||||||
* Returns list of default server
|
* Returns list of default server
|
||||||
*/
|
*/
|
||||||
get servers() {
|
get servers() {
|
||||||
return JSON.parse(localStorage.getItem('mifosXServers'));
|
return safeParseArray<string>(localStorage.getItem('mifosXServers'), []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -160,7 +165,7 @@ export class SettingsService {
|
|||||||
if (environment.baseApiUrl && environment.baseApiUrl !== '') {
|
if (environment.baseApiUrl && environment.baseApiUrl !== '') {
|
||||||
return environment.baseApiUrl;
|
return environment.baseApiUrl;
|
||||||
} else {
|
} else {
|
||||||
return this.servers()[0];
|
return this.servers[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +222,7 @@ export class SettingsService {
|
|||||||
* Returns list of Tenant Identifiers
|
* Returns list of Tenant Identifiers
|
||||||
*/
|
*/
|
||||||
get tenantIdentifiers(): any {
|
get tenantIdentifiers(): any {
|
||||||
return JSON.parse(localStorage.getItem('mifosXTenantIdentifiers'));
|
return safeParseArray<string>(localStorage.getItem('mifosXTenantIdentifiers'), []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -260,6 +265,6 @@ export class SettingsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get themeDarkEnabled(): boolean {
|
get themeDarkEnabled(): boolean {
|
||||||
return JSON.parse(localStorage.getItem('mifosXThemeDarkEnabled'));
|
return safeParse<boolean>(localStorage.getItem('mifosXThemeDarkEnabled'), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Injectable, EventEmitter } from '@angular/core';
|
import { Injectable, EventEmitter } from '@angular/core';
|
||||||
|
import { safeParseObject } from 'app/core/utils/json';
|
||||||
import { Theme } from './theme.model';
|
import { Theme } from './theme.model';
|
||||||
import { ThemeManagerService } from './theme-manager.service';
|
import { ThemeManagerService } from './theme-manager.service';
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ export class ThemeStorageService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTheme(): Theme {
|
getTheme(): Theme {
|
||||||
return JSON.parse(localStorage.getItem(this.themeStorageKey));
|
return safeParseObject<Theme | null>(localStorage.getItem(this.themeStorageKey), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearTheme() {
|
clearTheme() {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export class BusinessDateTabComponent implements OnInit {
|
|||||||
businessDateData: any;
|
businessDateData: any;
|
||||||
|
|
||||||
dateIndex = 0;
|
dateIndex = 0;
|
||||||
userDateFormat: '';
|
userDateFormat: string = '';
|
||||||
isBusinessDateEnabled = false;
|
isBusinessDateEnabled = false;
|
||||||
isEditInProgress = false;
|
isEditInProgress = false;
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { MatDivider } from '@angular/material/divider';
|
|||||||
import { NgIf, NgFor, KeyValuePipe } from '@angular/common';
|
import { NgIf, NgFor, KeyValuePipe } from '@angular/common';
|
||||||
import { DateFormatPipe } from '../../pipes/date-format.pipe';
|
import { DateFormatPipe } from '../../pipes/date-format.pipe';
|
||||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||||
|
import { safeParseObject } from 'app/core/utils/json';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'mifosx-view-checker-inbox',
|
selector: 'mifosx-view-checker-inbox',
|
||||||
@@ -52,7 +53,7 @@ export class ViewCheckerInboxComponent {
|
|||||||
) {
|
) {
|
||||||
this.route.data.subscribe((data: { checkerInboxDetail: any }) => {
|
this.route.data.subscribe((data: { checkerInboxDetail: any }) => {
|
||||||
this.checkerInboxDetail = data.checkerInboxDetail;
|
this.checkerInboxDetail = data.checkerInboxDetail;
|
||||||
this.jsondata = JSON.parse(this.checkerInboxDetail.commandAsJson);
|
this.jsondata = safeParseObject<any>(this.checkerInboxDetail.commandAsJson, {});
|
||||||
this.displayJSONData = !_.isEmpty(this.jsondata);
|
this.displayJSONData = !_.isEmpty(this.jsondata);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import { Dates } from './core/utils/dates';
|
|||||||
import { animate, style, transition, trigger } from '@angular/animations';
|
import { animate, style, transition, trigger } from '@angular/animations';
|
||||||
import { I18nService } from './core/i18n/i18n.service';
|
import { I18nService } from './core/i18n/i18n.service';
|
||||||
import { ThemingService } from './shared/theme-toggle/theming.service';
|
import { ThemingService } from './shared/theme-toggle/theming.service';
|
||||||
|
import { safeParseArray } from 'app/core/utils/json';
|
||||||
|
|
||||||
import { AuthService } from './zitadel/auth.service';
|
import { AuthService } from './zitadel/auth.service';
|
||||||
|
|
||||||
@@ -195,7 +196,7 @@ export class WebAppComponent implements OnInit, OnDestroy {
|
|||||||
// Stores top 100 user activites as local storage object.
|
// Stores top 100 user activites as local storage object.
|
||||||
let activities: string[] = [];
|
let activities: string[] = [];
|
||||||
if (localStorage.getItem('mifosXLocation')) {
|
if (localStorage.getItem('mifosXLocation')) {
|
||||||
const activitiesArray: string[] = JSON.parse(localStorage.getItem('mifosXLocation'));
|
const activitiesArray = safeParseArray<string>(localStorage.getItem('mifosXLocation'), []);
|
||||||
const length = activitiesArray.length;
|
const length = activitiesArray.length;
|
||||||
activities = length > 100 ? activitiesArray.slice(length - 100) : activitiesArray;
|
activities = length > 100 ? activitiesArray.slice(length - 100) : activitiesArray;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user