mirror of
https://github.com/finos/SymphonyElectron.git
synced 2024-12-26 00:41:11 -06:00
SDA-4182: Add GPOs to auto update channel (#1896)
This commit is contained in:
parent
7d23cd60f8
commit
15056f16ff
@ -3,6 +3,7 @@
|
||||
"autoUpdateUrl": "",
|
||||
"autoUpdateChannel": "latest",
|
||||
"isAutoUpdateEnabled": true,
|
||||
"forceAutoUpdate": false,
|
||||
"autoUpdateCheckInterval": "30",
|
||||
"enableBrowserLogin": false,
|
||||
"browserLoginAutoConnect": false,
|
||||
|
44
spec/registryHandler.spec.ts
Normal file
44
spec/registryHandler.spec.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { retrieveWindowsRegistry } from '../src/app/registry-handler';
|
||||
import {
|
||||
EChannelRegistry,
|
||||
RegistryStore,
|
||||
} from '../src/app/stores/registry-store';
|
||||
|
||||
let mockChannel = { value: '', type: 'REG_SZ' };
|
||||
|
||||
jest.mock('winreg', () => {
|
||||
return jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
get: (_file, callback) => callback(null, mockChannel),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
jest.mock('../src/common/env', () => {
|
||||
return {
|
||||
isWindowsOS: true,
|
||||
isLinux: false,
|
||||
isMac: false,
|
||||
isDevEnv: true,
|
||||
};
|
||||
});
|
||||
|
||||
describe('Windows Registry', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks().resetModules();
|
||||
});
|
||||
|
||||
it('it should return channel - latest', async () => {
|
||||
mockChannel.value = 'latest';
|
||||
await retrieveWindowsRegistry();
|
||||
const registry = RegistryStore.getRegistry();
|
||||
expect(registry.currentChannel).toBe(EChannelRegistry.LATEST);
|
||||
});
|
||||
|
||||
it('it should return channel - beta', async () => {
|
||||
mockChannel.value = 'beta';
|
||||
await retrieveWindowsRegistry();
|
||||
const registry = RegistryStore.getRegistry();
|
||||
expect(registry.currentChannel).toBe(EChannelRegistry.BETA);
|
||||
});
|
||||
});
|
@ -7,6 +7,8 @@ import { logger } from '../common/logger';
|
||||
import { isUrl } from '../common/utils';
|
||||
import { whitelistHandler } from '../common/whitelist-handler';
|
||||
import { config } from './config-handler';
|
||||
import { retrieveWindowsRegistry } from './registry-handler';
|
||||
import { EChannelRegistry, RegistryStore } from './stores/registry-store';
|
||||
import { windowHandler } from './window-handler';
|
||||
|
||||
const DEFAULT_AUTO_UPDATE_CHANNEL = 'client-bff/sda-update';
|
||||
@ -23,122 +25,139 @@ export class AutoUpdate {
|
||||
private autoUpdateTrigger: AutoUpdateTrigger | undefined = undefined;
|
||||
|
||||
constructor() {
|
||||
const opts = this.getGenericServerOptions();
|
||||
if (isMac) {
|
||||
this.autoUpdater = new MacUpdater(opts);
|
||||
} else if (isWindowsOS) {
|
||||
this.autoUpdater = new NsisUpdater(opts);
|
||||
}
|
||||
this.getGenericServerOptions().then((opts) => {
|
||||
if (isMac) {
|
||||
this.autoUpdater = new MacUpdater(opts);
|
||||
} else if (isWindowsOS) {
|
||||
this.autoUpdater = new NsisUpdater(opts);
|
||||
}
|
||||
|
||||
if (this.autoUpdater) {
|
||||
this.autoUpdater.logger = electronLog;
|
||||
this.autoUpdater.autoDownload = false;
|
||||
this.autoUpdater.autoInstallOnAppQuit = true;
|
||||
this.autoUpdater.allowDowngrade = true;
|
||||
if (this.autoUpdater) {
|
||||
this.autoUpdater.logger = electronLog;
|
||||
this.autoUpdater.autoDownload = false;
|
||||
this.autoUpdater.autoInstallOnAppQuit = true;
|
||||
this.autoUpdater.allowDowngrade = true;
|
||||
|
||||
this.autoUpdater.on('update-not-available', () => {
|
||||
if (this.autoUpdateTrigger === AutoUpdateTrigger.AUTOMATED) {
|
||||
logger.info(
|
||||
'auto-update-handler: no update available found with automatic check',
|
||||
);
|
||||
this.autoUpdater.on('update-not-available', () => {
|
||||
if (this.autoUpdateTrigger === AutoUpdateTrigger.AUTOMATED) {
|
||||
logger.info(
|
||||
'auto-update-handler: no update available found with automatic check',
|
||||
);
|
||||
this.autoUpdateTrigger = undefined;
|
||||
return;
|
||||
}
|
||||
const mainWebContents = windowHandler.mainWebContents;
|
||||
// Display client banner
|
||||
if (mainWebContents && !mainWebContents.isDestroyed()) {
|
||||
mainWebContents.send('display-client-banner', {
|
||||
reason: 'autoUpdate',
|
||||
action: 'update-not-available',
|
||||
});
|
||||
}
|
||||
this.autoUpdateTrigger = undefined;
|
||||
return;
|
||||
}
|
||||
const mainWebContents = windowHandler.mainWebContents;
|
||||
// Display client banner
|
||||
if (mainWebContents && !mainWebContents.isDestroyed()) {
|
||||
mainWebContents.send('display-client-banner', {
|
||||
reason: 'autoUpdate',
|
||||
action: 'update-not-available',
|
||||
});
|
||||
}
|
||||
this.autoUpdateTrigger = undefined;
|
||||
});
|
||||
});
|
||||
|
||||
const { autoUpdateChannel } = config.getConfigFields([
|
||||
'autoUpdateChannel',
|
||||
]);
|
||||
const { installVariant } = config.getConfigFields(['installVariant']);
|
||||
this.autoUpdater.on('update-available', (info) => {
|
||||
const mainWebContents = windowHandler.mainWebContents;
|
||||
// Display client banner
|
||||
if (mainWebContents && !mainWebContents.isDestroyed()) {
|
||||
mainWebContents.send('display-client-banner', {
|
||||
reason: 'autoUpdate',
|
||||
action: 'update-available',
|
||||
data: {
|
||||
...info,
|
||||
autoUpdateTrigger: this.autoUpdateTrigger,
|
||||
autoUpdateChannel,
|
||||
installVariant,
|
||||
channelConfigLocation: null,
|
||||
sessionStartDatetime: null,
|
||||
machineStartDatetime: null,
|
||||
machineId: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
const { autoUpdateChannel } = config.getConfigFields([
|
||||
'autoUpdateChannel',
|
||||
]);
|
||||
let finalAutoUpdateChannel = autoUpdateChannel;
|
||||
|
||||
this.autoUpdater.on('download-progress', (info) => {
|
||||
const mainWebContents = windowHandler.mainWebContents;
|
||||
// Display client banner
|
||||
if (
|
||||
mainWebContents &&
|
||||
!mainWebContents.isDestroyed() &&
|
||||
!this.didPublishDownloadProgress
|
||||
) {
|
||||
mainWebContents.send('display-client-banner', {
|
||||
reason: 'autoUpdate',
|
||||
action: 'download-progress',
|
||||
data: {
|
||||
...info,
|
||||
autoUpdateTrigger: this.autoUpdateTrigger,
|
||||
autoUpdateChannel,
|
||||
installVariant,
|
||||
channelConfigLocation: null,
|
||||
sessionStartDatetime: null,
|
||||
machineStartDatetime: null,
|
||||
machineId: null,
|
||||
},
|
||||
});
|
||||
this.didPublishDownloadProgress = true;
|
||||
}
|
||||
});
|
||||
if (isWindowsOS) {
|
||||
const registryAutoUpdate = RegistryStore.getRegistry();
|
||||
const identifiedChannelFromRegistry = [
|
||||
EChannelRegistry.BETA,
|
||||
EChannelRegistry.LATEST,
|
||||
].includes(registryAutoUpdate.currentChannel)
|
||||
? registryAutoUpdate.currentChannel
|
||||
: '';
|
||||
|
||||
this.autoUpdater.on('update-downloaded', (info) => {
|
||||
this.isUpdateAvailable = true;
|
||||
const mainWebContents = windowHandler.mainWebContents;
|
||||
// Display client banner
|
||||
if (mainWebContents && !mainWebContents.isDestroyed()) {
|
||||
mainWebContents.send('display-client-banner', {
|
||||
reason: 'autoUpdate',
|
||||
action: 'update-downloaded',
|
||||
data: {
|
||||
...info,
|
||||
autoUpdateTrigger: this.autoUpdateTrigger,
|
||||
autoUpdateChannel,
|
||||
installVariant,
|
||||
channelConfigLocation: null,
|
||||
sessionStartDatetime: null,
|
||||
machineStartDatetime: null,
|
||||
machineId: null,
|
||||
},
|
||||
});
|
||||
if (identifiedChannelFromRegistry) {
|
||||
finalAutoUpdateChannel = identifiedChannelFromRegistry;
|
||||
}
|
||||
}
|
||||
if (isMac) {
|
||||
config.backupGlobalConfig();
|
||||
}
|
||||
});
|
||||
|
||||
this.autoUpdater.on('error', (error) => {
|
||||
this.autoUpdateTrigger = undefined;
|
||||
logger.error(
|
||||
'auto-update-handler: Error occurred while updating. ',
|
||||
error,
|
||||
);
|
||||
});
|
||||
}
|
||||
const { installVariant } = config.getConfigFields(['installVariant']);
|
||||
this.autoUpdater.on('update-available', (info) => {
|
||||
const mainWebContents = windowHandler.mainWebContents;
|
||||
// Display client banner
|
||||
if (mainWebContents && !mainWebContents.isDestroyed()) {
|
||||
mainWebContents.send('display-client-banner', {
|
||||
reason: 'autoUpdate',
|
||||
action: 'update-available',
|
||||
data: {
|
||||
...info,
|
||||
autoUpdateTrigger: this.autoUpdateTrigger,
|
||||
autoUpdateChannel: finalAutoUpdateChannel,
|
||||
installVariant,
|
||||
channelConfigLocation: null,
|
||||
sessionStartDatetime: null,
|
||||
machineStartDatetime: null,
|
||||
machineId: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.autoUpdater.on('download-progress', (info) => {
|
||||
const mainWebContents = windowHandler.mainWebContents;
|
||||
// Display client banner
|
||||
if (
|
||||
mainWebContents &&
|
||||
!mainWebContents.isDestroyed() &&
|
||||
!this.didPublishDownloadProgress
|
||||
) {
|
||||
mainWebContents.send('display-client-banner', {
|
||||
reason: 'autoUpdate',
|
||||
action: 'download-progress',
|
||||
data: {
|
||||
...info,
|
||||
autoUpdateTrigger: this.autoUpdateTrigger,
|
||||
autoUpdateChannel: finalAutoUpdateChannel,
|
||||
installVariant,
|
||||
channelConfigLocation: null,
|
||||
sessionStartDatetime: null,
|
||||
machineStartDatetime: null,
|
||||
machineId: null,
|
||||
},
|
||||
});
|
||||
this.didPublishDownloadProgress = true;
|
||||
}
|
||||
});
|
||||
|
||||
this.autoUpdater.on('update-downloaded', (info) => {
|
||||
this.isUpdateAvailable = true;
|
||||
const mainWebContents = windowHandler.mainWebContents;
|
||||
// Display client banner
|
||||
if (mainWebContents && !mainWebContents.isDestroyed()) {
|
||||
mainWebContents.send('display-client-banner', {
|
||||
reason: 'autoUpdate',
|
||||
action: 'update-downloaded',
|
||||
data: {
|
||||
...info,
|
||||
autoUpdateTrigger: this.autoUpdateTrigger,
|
||||
autoUpdateChannel: finalAutoUpdateChannel,
|
||||
installVariant,
|
||||
channelConfigLocation: null,
|
||||
sessionStartDatetime: null,
|
||||
machineStartDatetime: null,
|
||||
machineId: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
if (isMac) {
|
||||
config.backupGlobalConfig();
|
||||
}
|
||||
});
|
||||
|
||||
this.autoUpdater.on('error', (error) => {
|
||||
this.autoUpdateTrigger = undefined;
|
||||
logger.error(
|
||||
'auto-update-handler: Error occurred while updating. ',
|
||||
error,
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,7 +192,7 @@ export class AutoUpdate {
|
||||
this.autoUpdateTrigger = trigger;
|
||||
logger.info('auto-update-handler: Checking for updates', trigger);
|
||||
if (this.autoUpdater) {
|
||||
const opts: GenericServerOptions = this.getGenericServerOptions();
|
||||
const opts: GenericServerOptions = await this.getGenericServerOptions();
|
||||
this.autoUpdater.setFeedURL(opts);
|
||||
const updateCheckResult = await this.autoUpdater.checkForUpdates();
|
||||
logger.info('auto-update-handler: ', updateCheckResult);
|
||||
@ -221,16 +240,31 @@ export class AutoUpdate {
|
||||
return updateUrl;
|
||||
};
|
||||
|
||||
private getGenericServerOptions = (): GenericServerOptions => {
|
||||
private getGenericServerOptions = async (): Promise<GenericServerOptions> => {
|
||||
let userAutoUpdateChannel;
|
||||
const { autoUpdateChannel, betaAutoUpdateChannelEnabled } =
|
||||
config.getConfigFields([
|
||||
'autoUpdateChannel',
|
||||
'betaAutoUpdateChannelEnabled',
|
||||
]);
|
||||
|
||||
userAutoUpdateChannel = betaAutoUpdateChannelEnabled
|
||||
? 'beta'
|
||||
: autoUpdateChannel;
|
||||
if (isWindowsOS) {
|
||||
await retrieveWindowsRegistry();
|
||||
const registryAutoUpdate = RegistryStore.getRegistry();
|
||||
const identifiedChannelFromRegistry = [
|
||||
EChannelRegistry.BETA,
|
||||
EChannelRegistry.LATEST,
|
||||
].includes(registryAutoUpdate.currentChannel)
|
||||
? registryAutoUpdate.currentChannel
|
||||
: '';
|
||||
if (identifiedChannelFromRegistry) {
|
||||
userAutoUpdateChannel = identifiedChannelFromRegistry;
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`auto-update-handler: using channel ${userAutoUpdateChannel}`);
|
||||
|
||||
const opts: GenericServerOptions = {
|
||||
|
61
src/app/registry-handler.ts
Normal file
61
src/app/registry-handler.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { logger } from '../common/logger';
|
||||
import { RegistryStore } from './stores/registry-store';
|
||||
|
||||
enum RegistryValueType {
|
||||
REG_SZ = 'REG_SZ',
|
||||
}
|
||||
|
||||
const CHANNEL_NEST_LOCATION = '\\SOFTWARE\\Policies\\Symphony\\Update';
|
||||
const CHANNEL_KEY = 'channel';
|
||||
|
||||
export const retrieveWindowsRegistry = async (): Promise<string> => {
|
||||
const Registry = require('winreg');
|
||||
const registryLocalStore = RegistryStore;
|
||||
const fetchLogic = (err, channel) => {
|
||||
if (err) {
|
||||
logger.info('registry-handler: error occurred. Details: ', err);
|
||||
|
||||
return 'An error has occurred';
|
||||
} else {
|
||||
if (channel.type === RegistryValueType.REG_SZ) {
|
||||
registryLocalStore.setRegistry({ currentChannel: channel.value });
|
||||
logger.info(
|
||||
'registry-handler: value retrieved successfully, send to Registry Store',
|
||||
);
|
||||
|
||||
return channel.value;
|
||||
} else {
|
||||
logger.info(
|
||||
'registry-handler: the value was looked for did not exist or its VALUE_TYPE is incorrect',
|
||||
);
|
||||
|
||||
return 'Key Value doesnt exist';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const regKeyLocal = new Registry({
|
||||
hive: Registry.HKLM,
|
||||
key: CHANNEL_NEST_LOCATION,
|
||||
});
|
||||
|
||||
const regKeyUser = new Registry({
|
||||
hive: Registry.HKCU,
|
||||
key: CHANNEL_NEST_LOCATION,
|
||||
});
|
||||
|
||||
return regKeyUser.get(CHANNEL_KEY, (error, channel) => {
|
||||
if (error && !channel) {
|
||||
regKeyLocal.get(CHANNEL_KEY, (err, localChannel) => {
|
||||
return fetchLogic(err, localChannel);
|
||||
});
|
||||
} else if (channel.type === RegistryValueType.REG_SZ) {
|
||||
registryLocalStore.setRegistry({ currentChannel: channel.value });
|
||||
logger.info(
|
||||
'registry-handler: value retrieved successfully, send to Registry Store',
|
||||
);
|
||||
|
||||
return channel;
|
||||
}
|
||||
});
|
||||
};
|
28
src/app/stores/registry-store.ts
Normal file
28
src/app/stores/registry-store.ts
Normal file
@ -0,0 +1,28 @@
|
||||
export interface IRegistry {
|
||||
currentChannel: string | 'beta' | 'latest';
|
||||
}
|
||||
|
||||
export const EChannelRegistry = {
|
||||
/**
|
||||
* Has higher authority over autoUpdateChannel, utilized to set Update Channel to LATEST
|
||||
*/
|
||||
LATEST: 'latest',
|
||||
|
||||
/**
|
||||
* Has higher authority over autoUpdateChannel, utilized to set Update Channel to BETA
|
||||
*/
|
||||
BETA: 'beta',
|
||||
};
|
||||
|
||||
class Registry {
|
||||
private registry: IRegistry = { currentChannel: '' };
|
||||
public getRegistry = (): IRegistry => {
|
||||
return { ...this.registry };
|
||||
};
|
||||
|
||||
public setRegistry = (newRegistry: IRegistry) => {
|
||||
this.registry = { ...this.registry, ...newRegistry };
|
||||
};
|
||||
}
|
||||
|
||||
export const RegistryStore = new Registry();
|
Loading…
Reference in New Issue
Block a user