diff --git a/config/Symphony.config b/config/Symphony.config index a4a70ebc..87e83f76 100644 --- a/config/Symphony.config +++ b/config/Symphony.config @@ -1,5 +1,6 @@ { "url":"https://my.symphony.com", + "overrideUserAgent": false, "minimizeOnClose" : "ENABLED", "launchOnStartup" : "ENABLED", "alwaysOnTop" : "DISABLED", diff --git a/docs/development/DEV_SETUP.md b/docs/development/DEV_SETUP.md index 3ed6408b..bc6e1e5d 100644 --- a/docs/development/DEV_SETUP.md +++ b/docs/development/DEV_SETUP.md @@ -72,6 +72,20 @@ npm run test:spectron -- --match=spell* ## Packaging: +- Add Artifactory credentials to your home directory `.npmrc` file + +1. Login to https://repo.symphony.com/ in your browser +2. Open https://repo.symphony.com/artifactory/webapp/#/profile +3. Click generate token +4. Execute `curl --location --request GET 'https://repo.symphony.com/artifactory/api/npm/auth' --header 'X-JFrog-Art-Api: '` +5. Update ~/.npmrc with: + +``` +registry = https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/ +_auth = +always-auth = true +``` + ### Mac 🖥 - npm install - npm run dev (to run locally) diff --git a/docs/features/silent-installation-windows.md b/docs/features/silent-installation-windows.md index b991300a..b9f6367f 100644 --- a/docs/features/silent-installation-windows.md +++ b/docs/features/silent-installation-windows.md @@ -48,6 +48,7 @@ Add “/l* symphony_install.log” to get debug information from the install wri - OPEN_EXTERNAL (Boolean) - DEV_TOOLS_ENABLED (Boolean) - AUTO_LAUNCH_PATH (String) +- OVERRIDE_USER_AGENT (Boolean) You'll need to quote the Boolean values when passing from the command line. #### Check-boxes (in the installer UI) that can be altered are listed below: diff --git a/installer/win/WixSharpInstaller/Symphony.cs b/installer/win/WixSharpInstaller/Symphony.cs index 6c00933b..d1d7bc58 100644 --- a/installer/win/WixSharpInstaller/Symphony.cs +++ b/installer/win/WixSharpInstaller/Symphony.cs @@ -187,6 +187,7 @@ class Script new PublicProperty("CONTEXT_ORIGIN_URL", ""), new PublicProperty("POINTER_LOCK", "true"), new PublicProperty("USER_DATA_PATH", ""), + new PublicProperty("OVERRIDE_USER_AGENT", "false"), new Property("MSIINSTALLPERUSER", "1"), new Property("PROGRAMSFOLDER", System.Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES%")) }; @@ -214,7 +215,7 @@ class Script new ElevatedManagedAction(CustomActions.UpdateConfig, Return.check, When.After, Step.InstallFiles, Condition.NOT_BeingRemoved ) { // The UpdateConfig action needs the built-in property INSTALLDIR as well as most of the custom properties - UsesProperties = "INSTALLDIR,POD_URL,CONTEXT_ORIGIN_URL,MINIMIZE_ON_CLOSE,ALWAYS_ON_TOP,AUTO_START,BRING_TO_FRONT,MEDIA,LOCATION,NOTIFICATIONS,MIDI_SYSEX,POINTER_LOCK,FULL_SCREEN,OPEN_EXTERNAL,CUSTOM_TITLE_BAR,DEV_TOOLS_ENABLED,AUTO_LAUNCH_PATH,USER_DATA_PATH" + UsesProperties = "INSTALLDIR,POD_URL,CONTEXT_ORIGIN_URL,MINIMIZE_ON_CLOSE,ALWAYS_ON_TOP,AUTO_START,BRING_TO_FRONT,MEDIA,LOCATION,NOTIFICATIONS,MIDI_SYSEX,POINTER_LOCK,FULL_SCREEN,OPEN_EXTERNAL,CUSTOM_TITLE_BAR,DEV_TOOLS_ENABLED,AUTO_LAUNCH_PATH,USER_DATA_PATH,OVERRIDE_USER_AGENT" }, // CleanRegistry @@ -383,6 +384,7 @@ public class CustomActions data = ReplaceProperty(data, "devToolsEnabled", session.Property("DEV_TOOLS_ENABLED")); data = ReplaceProperty(data, "autoLaunchPath", FixPathFormat(session.Property("AUTO_LAUNCH_PATH"))); data = ReplaceProperty(data, "userDataPath", FixPathFormat(session.Property("USER_DATA_PATH"))); + data = ReplaceProperty(data, "overrideUserAgent", session.Property("OVERRIDE_USER_AGENT")); // Write the contents back to the file System.IO.File.WriteAllText(filename, data); diff --git a/installer/win/install_instructions_win.md b/installer/win/install_instructions_win.md index 8153b809..6dcfe19f 100644 --- a/installer/win/install_instructions_win.md +++ b/installer/win/install_instructions_win.md @@ -492,3 +492,24 @@ The default (if not specified, or if specified as empty string "") is +------------------------------------------------------------------- +### OVERRIDE_USER_AGENT + +Expected values: + +* "true" + "Electron/X.X" is removed from user-agents. +* "false" + User-agents are not modified (default) + +#### Example, install with user-agent override + + msiexec /i Symphony.msi OVERRIDE_USER_AGENT="true" + +#### Example, install without user-agent override + + msiexec /i Symphony.msi OVERRIDE_USER_AGENT="false" + +or + + msiexec /i Symphony.msi \ No newline at end of file diff --git a/spec/chromeFlags.spec.ts b/spec/chromeFlags.spec.ts index f8d24641..c1ca61cc 100644 --- a/spec/chromeFlags.spec.ts +++ b/spec/chromeFlags.spec.ts @@ -60,8 +60,12 @@ describe('chrome flags', () => { it('should call `setChromeFlags` correctly', () => { const spy = jest.spyOn(app.commandLine, 'appendSwitch'); setChromeFlags(); - expect(spy).nthCalledWith(1, 'auth-negotiate-delegate-whitelist', 'url'); - expect(spy).nthCalledWith(2, 'auth-server-whitelist', 'whitelist'); + expect(spy).nthCalledWith( + 1, + 'auth-negotiate-delegate-whitelist', + 'whitelist', + ); + expect(spy).nthCalledWith(2, 'auth-server-whitelist', 'url'); expect(spy).nthCalledWith(3, 'disable-background-timer-throttling', 'true'); expect(spy).nthCalledWith(4, 'disable-d3d11', true); expect(spy).nthCalledWith(5, 'disable-gpu', true); @@ -79,8 +83,12 @@ describe('chrome flags', () => { }); const spy = jest.spyOn(app.commandLine, 'appendSwitch'); setChromeFlags(); - expect(spy).nthCalledWith(1, 'auth-negotiate-delegate-whitelist', 'url'); - expect(spy).nthCalledWith(2, 'auth-server-whitelist', 'whitelist'); + expect(spy).nthCalledWith( + 1, + 'auth-negotiate-delegate-whitelist', + 'whitelist', + ); + expect(spy).nthCalledWith(2, 'auth-server-whitelist', 'url'); expect(spy).nthCalledWith(3, 'disable-background-timer-throttling', 'true'); expect(spy).not.nthCalledWith(4); }); @@ -166,8 +174,12 @@ describe('chrome flags', () => { it('should call `setChromeFlags` correctly', () => { const spy = jest.spyOn(app.commandLine, 'appendSwitch'); setChromeFlags(); - expect(spy).nthCalledWith(1, 'auth-negotiate-delegate-whitelist', 'url'); - expect(spy).nthCalledWith(2, 'auth-server-whitelist', 'whitelist'); + expect(spy).nthCalledWith( + 1, + 'auth-negotiate-delegate-whitelist', + 'whitelist', + ); + expect(spy).nthCalledWith(2, 'auth-server-whitelist', 'url'); expect(spy).nthCalledWith( 3, 'disable-background-timer-throttling', diff --git a/src/app/chrome-flags.ts b/src/app/chrome-flags.ts index 12b193df..b2a674c3 100644 --- a/src/app/chrome-flags.ts +++ b/src/app/chrome-flags.ts @@ -35,9 +35,8 @@ export const setChromeFlags = () => { ]) as any; const configFlags: object = { 'auth-negotiate-delegate-whitelist': - flagsConfig.customFlags.authServerWhitelist, - 'auth-server-whitelist': flagsConfig.customFlags.authNegotiateDelegateWhitelist, + 'auth-server-whitelist': flagsConfig.customFlags.authServerWhitelist, 'disable-background-timer-throttling': 'true', 'disable-d3d11': flagsConfig.disableGpu || null, 'disable-gpu': flagsConfig.disableGpu || null, diff --git a/src/app/config-handler.ts b/src/app/config-handler.ts index dd45f40f..a0ebfecd 100644 --- a/src/app/config-handler.ts +++ b/src/app/config-handler.ts @@ -47,6 +47,7 @@ export interface IGlobalConfig { contextOriginUrl: string; url: string; contextIsolation: boolean; + overrideUserAgent?: boolean; } export interface ICloudConfig { diff --git a/src/app/window-handler.ts b/src/app/window-handler.ts index d60a8bf1..b4760392 100644 --- a/src/app/window-handler.ts +++ b/src/app/window-handler.ts @@ -167,6 +167,7 @@ export class WindowHandler { 'url', 'contextIsolation', 'contextOriginUrl', + 'overrideUserAgent', ]); this.userConfig = config.getUserConfigFields(['url']); @@ -385,7 +386,8 @@ export class WindowHandler { cleanAppCacheOnCrash(this.mainWindow); // loads the main window with url from config/cmd line logger.info(`Loading main window with url ${this.url}`); - this.mainWindow.loadURL(this.url); + const userAgent = this.getUserAgent(this.mainWindow); + this.mainWindow.loadURL(this.url, { userAgent }); // check for build expiry in case of test builds this.checkExpiry(this.mainWindow); // update version info from server @@ -456,9 +458,9 @@ export class WindowHandler { `Looks like about:blank got loaded which may lead to blank screen`, ); logger.info(`Reloading the app to check if it resolves the issue`); - await this.mainWindow.loadURL( - this.userConfig.url || this.globalConfig.url, - ); + const url = this.userConfig.url || this.globalConfig.url; + const userAgent = this.getUserAgent(this.mainWindow); + await this.mainWindow.loadURL(url, { userAgent }); return; } logger.info('window-handler: did-finish-load, url: ' + this.url); @@ -1757,8 +1759,10 @@ export class WindowHandler { logger.info( `window-utils: user has logged in, getting back to Symphony app`, ); + const userAgent = this.getUserAgent(this.mainWindow); this.mainWindow.loadURL( this.url || this.userConfig.url || this.globalConfig.url, + { userAgent }, ); return; } @@ -1766,7 +1770,10 @@ export class WindowHandler { logger.info( `window-utils: user hasn't logged in yet, loading login page again`, ); - this.mainWindow.loadURL(this.userConfig.url || this.globalConfig.url); + const userAgent = this.getUserAgent(this.mainWindow); + this.mainWindow.loadURL(this.userConfig.url || this.globalConfig.url, { + userAgent, + }); } } @@ -1785,7 +1792,8 @@ export class WindowHandler { const reloadUrl = webContentsUrl || this.userConfig.url || this.globalConfig.url; logger.info(`window-handler: Trying to reload ${reloadUrl}.`); - await this.mainWindow.loadURL(reloadUrl); + const userAgent = this.getUserAgent(this.mainWindow); + await this.mainWindow.loadURL(reloadUrl, { userAgent }); return; } logger.error( @@ -1971,7 +1979,8 @@ export class WindowHandler { this.url = this.globalConfig.url + `?x-km-csrf-token=${csrfToken}`; } this.execCmd(this.screenShareIndicatorFrameUtil, []); - await this.mainWindow.loadURL(this.url); + const userAgent = this.getUserAgent(this.mainWindow); + await this.mainWindow.loadURL(this.url, { userAgent }); } catch (e) { logger.error( `window-handler: failed to switch client because of error ${e}`, @@ -2053,6 +2062,25 @@ export class WindowHandler { return { ...defaultWindowOpts, ...windowOpts }; } + + /** + * getUserAgent retrieves current window user-agent and updates it + * depending on global config setup + * Electron user-agent is removed due to Microsoft Azure not supporting SSO if found - cf SDA-3201 + * @param mainWindow + * @returns updated user-agents + */ + private getUserAgent(mainWindow: ICustomBrowserWindow): string { + const doOverrideUserAgents = !!this.globalConfig.overrideUserAgent; + let userAgent = mainWindow.webContents.getUserAgent(); + if (doOverrideUserAgents) { + const electronUserAgentRegex = /(Electron[0-9\/.]*)/; + userAgent = userAgent + .replace(electronUserAgentRegex, '') + .replace(' ', ' '); + } + return userAgent; + } } const windowHandler = new WindowHandler();