Skip to content

Commit

Permalink
SDA-4714 - Use plist parser to validate if a field exists (#2227)
Browse files Browse the repository at this point in the history
* SDA-4714 - Use plist parser to validate if a field exists

* SDA-4714 - Fix uts
  • Loading branch information
KiranNiranjan authored Nov 20, 2024
1 parent 09d2f8d commit b76884d
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 12 deletions.
46 changes: 39 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@
"dependencies": {
"@types/lazy-brush": "^1.0.0",
"adm-zip": "^0.5.10",
"bplist-parser": "^0.3.2",
"classnames": "2.2.6",
"electron-dl": "3.5.0",
"electron-fetch": "1.9.1",
Expand Down
4 changes: 2 additions & 2 deletions spec/appMenu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { autoLaunchInstance } from '../src/app/auto-launch-controller';
import { config } from '../src/app/config-handler';
import { exportCrashDumps, exportLogs } from '../src/app/reports-handler';
import { updateAlwaysOnTop } from '../src/app/window-actions';
import { windowHandler } from '../src/app/window-handler';
import { zoomIn, zoomOut } from '../src/app/window-utils';
import { apiName } from '../src/common/api-interface';
import * as envMock from '../src/common/env';
import { logger } from '../src/common/logger';
import { BrowserWindow, dialog, session, shell } from './__mocks__/electron';
import { windowHandler } from '../src/app/window-handler';
import { apiName } from '../src/common/api-interface';

jest.mock('../src/app/stores', () => {
const mock = new Map<string, any>();
Expand Down
39 changes: 39 additions & 0 deletions spec/plistHandler.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,44 @@
import { getAllUserDefaults } from '../src/app/plist-handler';

jest.mock('../src/app/config-handler', () => {
return {
ConfigFieldsDefaultValues: {},
CloudConfigDataTypes: {
NOT_SET: 'NOT_SET',
ENABLED: 'ENABLED',
DISABLED: 'DISABLED',
},
config: {
getConfigFields: jest.fn(() => {
return {
minimizeOnClose: 'ENABLED',
launchOnStartup: 'ENABLED',
alwaysOnTop: 'ENABLED',
isAlwaysOnTop: 'ENABLED',
bringToFront: 'ENABLED',
devToolsEnabled: true,
};
}),
getGlobalConfigFields: jest.fn(() => {
return {
devToolsEnabled: true,
};
}),
getFilteredCloudConfigFields: jest.fn(() => {
return {
devToolsEnabled: true,
};
}),
getCloudConfigFields: jest.fn(() => {
return {
devToolsEnabled: true,
};
}),
updateUserConfig: jest.fn(),
},
};
});

describe('Plist Handler', () => {
it('should return config object', () => {
expect(getAllUserDefaults()).toStrictEqual({
Expand Down
7 changes: 6 additions & 1 deletion src/app/config-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { terminateC9Shell } from './c9-shell-handler';
import {
getAllUserDefaults,
initializePlistFile,
readPlistFile,
setPlistFromPreviousSettings,
} from './plist-handler';
import { appStats } from './stats';
Expand Down Expand Up @@ -840,7 +841,7 @@ class Config {
/**
* Reads a stores the global config file
*/
private readGlobalConfig() {
private async readGlobalConfig() {
if (isMac) {
if (fs.existsSync(this.tempGlobalConfigFilePath)) {
this.globalConfig = this.parseConfigData(
Expand All @@ -862,6 +863,8 @@ class Config {
this.globalConfig as IConfig,
appGlobalConfigData,
);
// Validate user config before starting the application
await readPlistFile();
// After everything is set from previous SDA version
this.globalConfig = getAllUserDefaults();
return;
Expand All @@ -877,6 +880,8 @@ class Config {
'installVariant',
'string',
);
// Validate user config before starting the application
await readPlistFile();
this.globalConfig = getAllUserDefaults();
logger.info(
`config-handler: Global configuration from plist: `,
Expand Down
55 changes: 53 additions & 2 deletions src/app/plist-handler.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import * as bplistParser from 'bplist-parser';
import { execSync } from 'child_process';
import { systemPreferences } from 'electron';
import { app, systemPreferences } from 'electron';
import * as fs from 'fs';

import { logger } from '../common/logger';
import { getGuid } from '../common/utils';
import { IConfig } from './config-handler';
import { ConfigFieldsDefaultValues, IConfig } from './config-handler';

let plistData = {};

const GENERAL_SETTINGS = {
url: 'string',
Expand Down Expand Up @@ -62,6 +67,18 @@ export const getAllUserDefaults = (): IConfig => {
const settings: any = {};

Object.keys(GENERAL_SETTINGS).map((key) => {
// Validate plist file only for keys that exist in ConfigFieldsDefaultValues
if (ConfigFieldsDefaultValues.hasOwnProperty(key)) {
// If plistData has entries but the key is missing, set it to the default value
if (Object.keys(plistData).length && !hasField(key)) {
logger.info(
'plist-handler: field does not exists in plist file using default value',
key,
);
settings[key] = ConfigFieldsDefaultValues[key];
return;
}
}
settings[key] = systemPreferences.getUserDefault(
key,
GENERAL_SETTINGS[key],
Expand Down Expand Up @@ -158,3 +175,37 @@ export const initializePlistFile = (path: string) => {
logger.error('plist-handler: initialize exception', error?.message);
}
};

/**
* Reads and parses a plist file from the user's home directory.
* The plist file is located at `~/Library/Preferences/com.symphony.electron-desktop.plist`.
* If the file exists and is successfully parsed, its data is stored in the `plistData` variable.
*
* @returns {Promise<void>} A promise that resolves once the file has been read and processed.
* @throws {Error} Throws an error if the plist file cannot be read or parsed, which is logged using the logger.
*/
export const readPlistFile = async () => {
const userPath = app.getPath('home');
const plistPath = `${userPath}/Library/Preferences/com.symphony.electron-desktop.plist`;
try {
if (fs.existsSync(plistPath)) {
const data = fs.readFileSync(plistPath);
const parsedData = bplistParser.parseBuffer(data);
if (parsedData && parsedData.length > 0) {
plistData = parsedData[0];
}
}
} catch (error) {
logger.error('plist-handler: failed to read plist', error);
}
};

/**
* Checks if a given field name exists in the `plistData` object.
*
* @param {string} fieldName - The name of the field to check for in the `plistData` object.
* @returns {boolean} Returns `true` if the field exists, `false` otherwise.
*/
export const hasField = (fieldName: string): boolean => {
return plistData.hasOwnProperty(fieldName);
};

0 comments on commit b76884d

Please sign in to comment.