From d4be5504bf7cda0b3192a4d6fce31256669799f8 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Tue, 24 Nov 2020 16:19:52 -0500 Subject: [PATCH] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20extract=20origin=20p?= =?UTF-8?q?rocedures=20into=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/desktop/app/initializers/ipc.js | 8 +- ui/desktop/app/routes/application.js | 19 +---- ui/desktop/app/routes/origin.js | 16 ++-- ui/desktop/app/services/origin.js | 76 +++++++++++++++++++ ui/desktop/tests/unit/services/origin-test.js | 12 +++ yarn.lock | 27 ++----- 6 files changed, 105 insertions(+), 53 deletions(-) create mode 100644 ui/desktop/app/services/origin.js create mode 100644 ui/desktop/tests/unit/services/origin-test.js diff --git a/ui/desktop/app/initializers/ipc.js b/ui/desktop/app/initializers/ipc.js index e5dcffe8c..74e9d8545 100644 --- a/ui/desktop/app/initializers/ipc.js +++ b/ui/desktop/app/initializers/ipc.js @@ -1,5 +1,4 @@ import Ember from 'ember'; -import { assert } from '@ember/debug'; import config from '../config/environment'; /** @@ -42,9 +41,10 @@ export function initialize() { window.addEventListener('message', async function (event) { if (event.origin !== window.location.origin) return; const { method, payload } = event?.data ?? {}; - assert(`IPC requires a method, you passed '${method}'.`, method); - const response = await mockIPC.invoke(method, payload); - event.ports[0].postMessage(response); + if (method) { + const response = await mockIPC.invoke(method, payload); + event.ports[0].postMessage(response); + } }); } } diff --git a/ui/desktop/app/routes/application.js b/ui/desktop/app/routes/application.js index 0dc41c9bd..009d73daf 100644 --- a/ui/desktop/app/routes/application.js +++ b/ui/desktop/app/routes/application.js @@ -15,7 +15,7 @@ export default class ApplicationRoute extends Route.extend( // =services @service session; - @service ipc; + @service origin; // =attributes @@ -24,26 +24,13 @@ export default class ApplicationRoute extends Route.extend( */ routeIfUnauthenticated = 'index'; - /** - * @type {ApplicationAdapter} - */ - get adapter() { - return this.store.adapterFor('application'); - } - /** * Check that the origin specified in the renderer matches the origin * reported by the main process. If they differ, update the main process * origin so that the renderer's CSP can be rewritten to allow requests. */ - async beforeModel() { - const rendererOrigin = this.session.data.origin; - const mainOrigin = await this.ipc.invoke('getOrigin'); - const isMatch = rendererOrigin === mainOrigin; - this.adapter.host = rendererOrigin; - if (rendererOrigin && !isMatch) { - await this.ipc.invoke('setOrigin', rendererOrigin); - } + beforeModel() { + return this.origin.updateOrigin(); } /** diff --git a/ui/desktop/app/routes/origin.js b/ui/desktop/app/routes/origin.js index e46824ef8..64487c640 100644 --- a/ui/desktop/app/routes/origin.js +++ b/ui/desktop/app/routes/origin.js @@ -5,8 +5,7 @@ import { action } from '@ember/object'; export default class OriginRoute extends Route { // =services - @service session; - @service ipc; + @service origin; @service intl; @service notify; @@ -22,20 +21,15 @@ export default class OriginRoute extends Route { // =methods /** - * Points the API to the specified origin and persists it to the session, - * as well as the main process. When the main process receives the origin, - * it is expected that the renderer will be restarted. + * Points the API to the specified origin and persists it the selection. + * When the main process receives the origin, it is expected that the renderer + * will be restarted. * @param {string} origin */ @action async setOrigin(origin) { - this.adapter.host = origin; - // Check if we have a Boundary endpoint... try { - // If scopes load, this could be a Boundary API - await this.store.query('scope', {}); - this.session.set('data.origin', origin); - await this.ipc.invoke('setOrigin', origin); + await this.origin.setOrigin(origin); this.replaceWith('index'); } catch (e) { // If scopes don't load, we assume this is not a Boundary API diff --git a/ui/desktop/app/services/origin.js b/ui/desktop/app/services/origin.js new file mode 100644 index 000000000..5fe141900 --- /dev/null +++ b/ui/desktop/app/services/origin.js @@ -0,0 +1,76 @@ +import Service from '@ember/service'; +import { assert } from '@ember/debug'; +import { inject as service } from '@ember/service'; + +export default class OriginService extends Service { + + // =services + + @service ipc; + @service store; + @service session; + + // =attributes + + /** + * @type {ApplicationAdapter} + */ + get adapter() { + return this.store.adapterFor('application'); + } + + /** + * @type {?string} + */ + get rendererOrigin() { + return this.session.data.origin; + } + + /** + * @param {?string} origin + */ + set rendererOrigin(origin) { + this.session.set('data.origin', origin); + } + + /** + * @type {Promise{?string}} + */ + get mainOrigin() { + return this.ipc.invoke('getOrigin'); + } + + // =methods + + /** + * Sets the main origin equal to the current renderer origin (if any). + */ + async updateOrigin() { + const rendererOrigin = this.rendererOrigin; + if (rendererOrigin) await this.setOrigin(rendererOrigin); + } + + /** + * Validates that the specified origin is a Boundary API. If so, the app is + * updated to use the origin. If it is not a Boundary API, or an origin + * wasn't specified, throws an error. + * @param {string} origin - protocol://host:port + */ + async setOrigin(origin) { + const originalHost = this.adapter.host; + assert(`setOrigin expects a string, you passed ${origin}`, typeof origin === 'string'); + try { + this.adapter.host = origin; + await this.store.query('scope', {}); + this.rendererOrigin = origin; + if (origin !== await this.mainOrigin) { + await this.ipc.invoke('setOrigin', origin); + } + } catch (e) { + this.adapter.host = originalHost; + this.rendererOrigin = null; + throw e; + } + } + +} diff --git a/ui/desktop/tests/unit/services/origin-test.js b/ui/desktop/tests/unit/services/origin-test.js new file mode 100644 index 000000000..c133a53a5 --- /dev/null +++ b/ui/desktop/tests/unit/services/origin-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Service | origin', function(hooks) { + setupTest(hooks); + + // TODO: Replace this with your real tests. + test('it exists', function(assert) { + let service = this.owner.lookup('service:origin'); + assert.ok(service); + }); +}); diff --git a/yarn.lock b/yarn.lock index 166223ce3..7841d1b9d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7401,7 +7401,7 @@ debug@~4.1.0: dependencies: ms "^2.1.1" -debuglog@*, debuglog@^1.0.1: +debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -12028,7 +12028,7 @@ import-lazy@^2.1.0: resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= -imurmurhash@*, imurmurhash@^0.1.4: +imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -13725,11 +13725,6 @@ lodash._baseflatten@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash._baseindexof@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" - integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw= - lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -13738,16 +13733,11 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@*, lodash._bindcallback@^3.0.0: +lodash._bindcallback@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= -lodash._cacheindexof@*: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" - integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI= - lodash._createassigner@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" @@ -13757,19 +13747,12 @@ lodash._createassigner@^3.0.0: lodash._isiterateecall "^3.0.0" lodash.restparam "^3.0.0" -lodash._createcache@*: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" - integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM= - dependencies: - lodash._getnative "^3.0.0" - lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= -lodash._getnative@*, lodash._getnative@^3.0.0: +lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= @@ -13982,7 +13965,7 @@ lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= -lodash.restparam@*, lodash.restparam@^3.0.0: +lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=