mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
Merge pull request #179 from VishwasShashidhar/electron-113
Electron 113 (User Config Changes)
This commit is contained in:
commit
35177567ce
@ -479,7 +479,8 @@
|
|||||||
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[AI_UserProgramFiles][Manufacturer]\[ProductName]"/>
|
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[AI_UserProgramFiles][Manufacturer]\[ProductName]"/>
|
||||||
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
|
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
|
||||||
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
|
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
|
||||||
<ROW Action="Symphony.exe" Type="1042" Source="Symphony.exe" Target="--install"/>
|
<ROW Action="Symphony.exe" Type="1042" Source="Symphony.exe" Target="--install --peruser"/>
|
||||||
|
<ROW Action="Symphony.exe_All_User" Type="1042" Source="Symphony.exe" Target="--install"/>
|
||||||
<ROW Action="UninstallPreviousVersions" Type="1" Source="aicustact.dll" Target="UninstallPreviousVersions" Options="1"/>
|
<ROW Action="UninstallPreviousVersions" Type="1" Source="aicustact.dll" Target="UninstallPreviousVersions" Options="1"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
|
||||||
@ -497,7 +498,8 @@
|
|||||||
<ROW Action="AI_DATA_SETTER" Sequence="54"/>
|
<ROW Action="AI_DATA_SETTER" Sequence="54"/>
|
||||||
<ROW Action="AI_SETMIXINSTLOCATION" Sequence="749"/>
|
<ROW Action="AI_SETMIXINSTLOCATION" Sequence="749"/>
|
||||||
<ROW Action="AI_TxtUpdaterInstall" Sequence="5101"/>
|
<ROW Action="AI_TxtUpdaterInstall" Sequence="5101"/>
|
||||||
<ROW Action="Symphony.exe" Condition="( NOT Installed )" Sequence="5935"/>
|
<ROW Action="Symphony.exe" Condition="( NOT Installed ) AND ( MSIINSTALLPERUSER )" Sequence="5935"/>
|
||||||
|
<ROW Action="Symphony.exe_All_User" Condition="( NOT Installed ) AND ( ALLUSERS )" Sequence="5936"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
|
||||||
<ROW Action="AI_ResolveKnownFolders" Sequence="52"/>
|
<ROW Action="AI_ResolveKnownFolders" Sequence="52"/>
|
||||||
|
175
js/config.js
175
js/config.js
@ -9,6 +9,12 @@ const isMac = require('./utils/misc.js').isMac;
|
|||||||
const getRegistry = require('./utils/getRegistry.js');
|
const getRegistry = require('./utils/getRegistry.js');
|
||||||
const configFileName = 'Symphony.config';
|
const configFileName = 'Symphony.config';
|
||||||
|
|
||||||
|
// For modifying user config while installation
|
||||||
|
const pick = require('lodash.pick');
|
||||||
|
const childProcess = require('child_process');
|
||||||
|
const AppDirectory = require('appdirectory');
|
||||||
|
const dirs = new AppDirectory('Symphony');
|
||||||
|
|
||||||
// cached config when first reading files. initially undefined and will be
|
// cached config when first reading files. initially undefined and will be
|
||||||
// updated when read from disk.
|
// updated when read from disk.
|
||||||
let userConfig;
|
let userConfig;
|
||||||
@ -32,12 +38,17 @@ function getConfigField(fieldName) {
|
|||||||
.then(function(value) {
|
.then(function(value) {
|
||||||
// got value from user config
|
// got value from user config
|
||||||
return value;
|
return value;
|
||||||
}, function () {
|
}, function() {
|
||||||
// failed to get value from user config, so try global config
|
// failed to get value from user config, so try global config
|
||||||
return getGlobalConfigField(fieldName);
|
return getGlobalConfigField(fieldName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a specific user config value for a field
|
||||||
|
* @param fieldName
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
function getUserConfigField(fieldName) {
|
function getUserConfigField(fieldName) {
|
||||||
return readUserConfig().then(function(config) {
|
return readUserConfig().then(function(config) {
|
||||||
if (typeof fieldName === 'string' && fieldName in config) {
|
if (typeof fieldName === 'string' && fieldName in config) {
|
||||||
@ -48,14 +59,23 @@ function getUserConfigField(fieldName) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function readUserConfig() {
|
/**
|
||||||
|
* Reads the user config file and returns all the attributes
|
||||||
|
* @param customConfigPath
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function readUserConfig(customConfigPath) {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
if (userConfig) {
|
if (userConfig) {
|
||||||
resolve(userConfig);
|
resolve(userConfig);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let configPath = path.join(app.getPath('userData'), configFileName);
|
let configPath = customConfigPath;
|
||||||
|
|
||||||
|
if (!configPath) {
|
||||||
|
configPath = path.join(app.getPath('userData'), configFileName);
|
||||||
|
}
|
||||||
|
|
||||||
fs.readFile(configPath, 'utf8', function(err, data) {
|
fs.readFile(configPath, 'utf8', function(err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -74,6 +94,11 @@ function readUserConfig() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a specific user config value for a field
|
||||||
|
* @param fieldName
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
function getGlobalConfigField(fieldName) {
|
function getGlobalConfigField(fieldName) {
|
||||||
return readGlobalConfig().then(function(config) {
|
return readGlobalConfig().then(function(config) {
|
||||||
if (typeof fieldName === 'string' && fieldName in config) {
|
if (typeof fieldName === 'string' && fieldName in config) {
|
||||||
@ -127,7 +152,7 @@ function readGlobalConfig() {
|
|||||||
.then(function(url) {
|
.then(function(url) {
|
||||||
globalConfig.url = url;
|
globalConfig.url = url;
|
||||||
resolve(globalConfig);
|
resolve(globalConfig);
|
||||||
}).catch(function () {
|
}).catch(function() {
|
||||||
resolve(globalConfig);
|
resolve(globalConfig);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -145,8 +170,7 @@ function updateConfigField(fieldName, newValue) {
|
|||||||
return readUserConfig()
|
return readUserConfig()
|
||||||
.then(function(config) {
|
.then(function(config) {
|
||||||
return saveUserConfig(fieldName, newValue, config);
|
return saveUserConfig(fieldName, newValue, config);
|
||||||
},
|
}, function() {
|
||||||
function() {
|
|
||||||
// in case config doesn't exist, can't read or is corrupted.
|
// in case config doesn't exist, can't read or is corrupted.
|
||||||
// add configVersion - just in case in future we need to provide
|
// add configVersion - just in case in future we need to provide
|
||||||
// upgrade capabilities.
|
// upgrade capabilities.
|
||||||
@ -156,6 +180,13 @@ function updateConfigField(fieldName, newValue) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves an updated value to the user config
|
||||||
|
* @param fieldName
|
||||||
|
* @param newValue
|
||||||
|
* @param oldConfig
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
function saveUserConfig(fieldName, newValue, oldConfig) {
|
function saveUserConfig(fieldName, newValue, oldConfig) {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
let configPath = path.join(app.getPath('userData'), configFileName);
|
let configPath = path.join(app.getPath('userData'), configFileName);
|
||||||
@ -182,6 +213,136 @@ function saveUserConfig(fieldName, newValue, oldConfig) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to update multiple user config field
|
||||||
|
* @param {Object} newGlobalConfig - The latest config changes from installer
|
||||||
|
* @param {Object} oldUserConfig - The old user config data
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function updateUserConfig(newGlobalConfig, oldUserConfig) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Picking some values from global config to overwrite user config
|
||||||
|
const configDataToUpdate = pick(newGlobalConfig, ['url', 'minimizeOnClose', 'launchOnStartup', 'alwaysOnTop']);
|
||||||
|
const updatedUserConfigData = Object.assign(oldUserConfig, configDataToUpdate);
|
||||||
|
const jsonNewConfig = JSON.stringify(updatedUserConfigData, null, ' ');
|
||||||
|
// get user config path
|
||||||
|
let userConfigFile;
|
||||||
|
|
||||||
|
if (isMac) {
|
||||||
|
userConfigFile = path.join(dirs.userConfig(), configFileName);
|
||||||
|
} else {
|
||||||
|
userConfigFile = path.join(app.getPath('userData'), configFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFile(userConfigFile, jsonNewConfig, 'utf8', (err) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to overwrite user config on windows installer
|
||||||
|
* @param {String} perUserInstall - Is a flag to determine whether we are installing for per user
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function updateUserConfigWin(perUserInstall) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const userConfigFile = path.join(app.getPath('userData'), configFileName);
|
||||||
|
// flag to determine whether per user installation
|
||||||
|
if (!perUserInstall) {
|
||||||
|
reject();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if user config file does't exists just copy global config file
|
||||||
|
if (!fs.existsSync(userConfigFile)) {
|
||||||
|
resolve(copyConfigWin());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise.all([readGlobalConfig(), readUserConfig(userConfigFile)])
|
||||||
|
.then((data) => {
|
||||||
|
resolve(updateUserConfig(data[0], data[1]));
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to overwrite user config on mac installer
|
||||||
|
* @param {String} globalConfigPath - The global config path from installer
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function updateUserConfigMac(globalConfigPath) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const userConfigFile = path.join(dirs.userConfig(), configFileName);
|
||||||
|
|
||||||
|
// if user config file does't exists just copy global config file
|
||||||
|
if (!fs.existsSync(userConfigFile)) {
|
||||||
|
resolve(copyConfigMac(globalConfigPath));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise.all([readGlobalConfig(), readUserConfig(userConfigFile)])
|
||||||
|
.then((data) => {
|
||||||
|
resolve(updateUserConfig(data[0], data[1]));
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to copy global config file to user config directory for Windows
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function copyConfigWin() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const globalConfigFileName = path.join('config', configFileName);
|
||||||
|
const execPath = path.dirname(app.getPath('exe'));
|
||||||
|
const globalConfigPath = path.join(execPath, '', globalConfigFileName);
|
||||||
|
const userConfigPath = app.getPath('userData');
|
||||||
|
|
||||||
|
childProcess.exec(`echo D|xcopy /y /e /s /c "${globalConfigPath}" "${userConfigPath}"`, { timeout: 60000 }, (err) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method which copies global config file to user config directory for mac
|
||||||
|
* @param {String} globalConfigPath - The global config path from installer
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function copyConfigMac(globalConfigPath) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let userConfigPath = dirs.userConfig() + '/';
|
||||||
|
let userName = process.env.USER;
|
||||||
|
|
||||||
|
childProcess.exec(`rsync -r "${globalConfigPath}" "${userConfigPath}" && chown -R "${userName}" "${userConfigPath}"`, { timeout: 60000 }, (err) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the cached config
|
||||||
|
*/
|
||||||
function clearCachedConfigs() {
|
function clearCachedConfigs() {
|
||||||
userConfig = null;
|
userConfig = null;
|
||||||
globalConfig = null;
|
globalConfig = null;
|
||||||
@ -191,6 +352,8 @@ module.exports = {
|
|||||||
getConfigField,
|
getConfigField,
|
||||||
updateConfigField,
|
updateConfigField,
|
||||||
configFileName,
|
configFileName,
|
||||||
|
updateUserConfigWin,
|
||||||
|
updateUserConfigMac,
|
||||||
|
|
||||||
// items below here are only exported for testing, do NOT use!
|
// items below here are only exported for testing, do NOT use!
|
||||||
saveUserConfig,
|
saveUserConfig,
|
||||||
|
15
js/main.js
15
js/main.js
@ -7,6 +7,7 @@ const nodeURL = require('url');
|
|||||||
const squirrelStartup = require('electron-squirrel-startup');
|
const squirrelStartup = require('electron-squirrel-startup');
|
||||||
const AutoLaunch = require('auto-launch');
|
const AutoLaunch = require('auto-launch');
|
||||||
const urlParser = require('url');
|
const urlParser = require('url');
|
||||||
|
|
||||||
const childProcess = require('child_process');
|
const childProcess = require('child_process');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const AppDirectory = require('appdirectory');
|
const AppDirectory = require('appdirectory');
|
||||||
@ -124,10 +125,11 @@ function setupThenOpenMainWindow() {
|
|||||||
// allows installer to launch app and set auto startup mode then
|
// allows installer to launch app and set auto startup mode then
|
||||||
// immediately quit.
|
// immediately quit.
|
||||||
let hasInstallFlag = getCmdLineArg(process.argv, '--install', true);
|
let hasInstallFlag = getCmdLineArg(process.argv, '--install', true);
|
||||||
|
let perUserInstall = getCmdLineArg(process.argv, '--peruser', true);
|
||||||
if (!isMac && hasInstallFlag) {
|
if (!isMac && hasInstallFlag) {
|
||||||
getConfigField('launchOnStartup')
|
getConfigField('launchOnStartup')
|
||||||
.then(setStartup)
|
.then(setStartup)
|
||||||
.then(updateUserConfigWin)
|
.then(() => updateUserConfigWin(perUserInstall))
|
||||||
.then(app.quit)
|
.then(app.quit)
|
||||||
.catch(app.quit);
|
.catch(app.quit);
|
||||||
return;
|
return;
|
||||||
@ -139,8 +141,11 @@ function setupThenOpenMainWindow() {
|
|||||||
// as the app is launched as a root user we don't get
|
// as the app is launched as a root user we don't get
|
||||||
// access to the config file
|
// access to the config file
|
||||||
let launchOnStartup = process.argv[3];
|
let launchOnStartup = process.argv[3];
|
||||||
updateUserConfigMac()
|
// We wire this in via the post install script
|
||||||
.then(setStartup(launchOnStartup))
|
// to get the config file path where the app is installed
|
||||||
|
let appGlobalConfigPath = process.argv[2];
|
||||||
|
setStartup(launchOnStartup)
|
||||||
|
.then(() => updateUserConfigMac(appGlobalConfigPath))
|
||||||
.then(app.quit)
|
.then(app.quit)
|
||||||
.catch(app.quit);
|
.catch(app.quit);
|
||||||
return;
|
return;
|
||||||
@ -183,7 +188,7 @@ function updateUserConfigMac() {
|
|||||||
let globalConfigPath = process.argv[2];
|
let globalConfigPath = process.argv[2];
|
||||||
let userName = process.env.USER;
|
let userName = process.env.USER;
|
||||||
|
|
||||||
childProcess.exec(`rsync -r "${globalConfigPath}" "${userConfigPath}" && chown -R "${userName}" "${userConfigPath}"`, { timeout: 60000 }, (err) => {
|
childProcess.exec(`rsync -r "${globalConfigPath}" "${userConfigPath}" && chown -R "${userName}" "${userConfigPath}"`, {timeout: 60000}, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
}
|
}
|
||||||
@ -201,7 +206,7 @@ function updateUserConfigWin() {
|
|||||||
let userConfigPath = app.getPath('userData');
|
let userConfigPath = app.getPath('userData');
|
||||||
let globalConfigPath = path.join(__dirname, '..', '..', '..', 'config/Symphony.config');
|
let globalConfigPath = path.join(__dirname, '..', '..', '..', 'config/Symphony.config');
|
||||||
|
|
||||||
childProcess.exec(`echo D|xcopy /y /e /s /c "${globalConfigPath}" "${userConfigPath}"`, { timeout: 60000 }, (err) => {
|
childProcess.exec(`echo D|xcopy /y /e /s /c "${globalConfigPath}" "${userConfigPath}"`, {timeout: 60000}, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,7 @@
|
|||||||
"electron-squirrel-startup": "^1.0.0",
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
"filesize": "^3.5.10",
|
"filesize": "^3.5.10",
|
||||||
"keymirror": "0.1.1",
|
"keymirror": "0.1.1",
|
||||||
|
"lodash.pick": "^4.4.0",
|
||||||
"winreg": "^1.2.3"
|
"winreg": "^1.2.3"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
Loading…
Reference in New Issue
Block a user