diff --git a/e2e-tests/desktop/fixtures/electronTest.js b/e2e-tests/desktop/fixtures/electronTest.js
index 181381ead..093c4cb36 100644
--- a/e2e-tests/desktop/fixtures/electronTest.js
+++ b/e2e-tests/desktop/fixtures/electronTest.js
@@ -133,6 +133,8 @@ export const electronTest = test.extend({
electronPage: async ({ electronApp }, use) => {
const page = await electronApp.firstWindow();
await page.evaluate(() => localStorage.clear());
+ // Reset the cluster URL stored by electron
+ await page.evaluate(() => window.desktop.cluster.resetClusterUrl());
await page.context().tracing.start({ screenshots: true, snapshots: true });
await use(page);
diff --git a/ui/desktop/app/controllers/application.js b/ui/desktop/app/controllers/application.js
index 78c534fd3..904862cfa 100644
--- a/ui/desktop/app/controllers/application.js
+++ b/ui/desktop/app/controllers/application.js
@@ -45,7 +45,7 @@ export default class ApplicationController extends Controller {
* @type {object}
*/
get currentScope() {
- if (this.scope.org.isOrg) {
+ if (this.scope.org?.isOrg) {
return { name: this.scope.org.displayName, icon: 'org' };
} else {
return { name: this.intl.t('titles.global'), icon: 'globe' };
@@ -100,13 +100,14 @@ export default class ApplicationController extends Controller {
}
/**
- * Disconnects from clusterUrl and invalidates session, thereby resetting
- * the client and reloading to the onboarding clusterUrl screen.
+ * Invalidates the session and navigates to the cluster-url route.
+ * The cluster URL is preserved so that upon reload the user is directed
+ * back to the authentication screen for the same cluster.
*/
@action
disconnect() {
- this.clusterUrl.resetClusterUrl();
this.session.invalidate();
+ this.router.replaceWith('cluster-url');
}
@action
diff --git a/ui/desktop/app/initializers/cluster-url.js b/ui/desktop/app/initializers/cluster-url.js
deleted file mode 100644
index fac5228de..000000000
--- a/ui/desktop/app/initializers/cluster-url.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Copyright IBM Corp. 2021, 2026
- * SPDX-License-Identifier: BUSL-1.1
- */
-
-import { getOwner } from '@ember/application';
-
-export function initialize(registry) {
- // Lookup the application route
- const ApplicationRoute = registry.resolveRegistration
- ? registry.resolveRegistration('route:application')
- : registry.resolve('route:application');
-
- ApplicationRoute.reopen({
- init() {
- this._super(...arguments);
- const originalBeforeModel = this.beforeModel;
-
- // Override the beforeModel hook and initialize the clusterUrl
- this.beforeModel = async function () {
- const clusterUrl = getOwner(this).lookup('service:clusterUrl');
- return clusterUrl.updateClusterUrl().then(
- () => originalBeforeModel.apply(this, arguments),
- () => originalBeforeModel.apply(this, arguments),
- );
- };
- },
- });
-}
-
-export default {
- after: 'ember-simple-auth',
- initialize,
-};
diff --git a/ui/desktop/app/routes/application.js b/ui/desktop/app/routes/application.js
index 191ba5fbf..e5d73ff0d 100644
--- a/ui/desktop/app/routes/application.js
+++ b/ui/desktop/app/routes/application.js
@@ -15,6 +15,7 @@ export default class ApplicationRoute extends Route {
@service session;
@service clusterUrl;
@service intl;
+ @service store;
@service rdp;
@service terminal;
@@ -25,19 +26,20 @@ export default class ApplicationRoute extends Route {
*/
routeIfUnauthenticated = 'index';
- /**
- * Check that the clusterUrl specified in the renderer matches the clusterUrl
- * reported by the main process. If they differ, update the main process
- * clusterUrl so that the renderer's CSP can be rewritten to allow requests.
- */
@notifyError(({ message }) => message, {
catch: true,
log: { origin: 'ApplicationRoute:beforeModel' },
})
async beforeModel() {
this.intl.setLocale(['en-us']);
+
+ const clusterUrl = await this.clusterUrl.getClusterUrl();
+ if (clusterUrl) {
+ const adapter = this.store.adapterFor('application');
+ adapter.host = clusterUrl;
+ }
+
await this.session.setup();
- await this.clusterUrl.updateClusterUrl();
const theme = this.session.get('data.theme');
/* eslint-disable-next-line ember/no-controller-access-in-routes */
const controller = this.controllerFor(this.routeName);
diff --git a/ui/desktop/app/routes/cluster-url.js b/ui/desktop/app/routes/cluster-url.js
index 6494080e3..5ff9bc586 100644
--- a/ui/desktop/app/routes/cluster-url.js
+++ b/ui/desktop/app/routes/cluster-url.js
@@ -41,9 +41,9 @@ export default class ClusterUrlRoute extends Route {
* Adds the existing clusterUrl, if any, to the controller scope.
* @param {Controller} controller
*/
- setupController(controller) {
+ async setupController(controller) {
super.setupController(...arguments);
- let clusterUrl = this.clusterUrl.rendererClusterUrl;
+ let clusterUrl = await this.clusterUrl.getClusterUrl();
// If clusterUrl is unset and this is a development environment,
// auto-set the clusterUrl field of the UI for better DX.
// The controller URL is almost always the same as the current window when
diff --git a/ui/desktop/app/routes/index.js b/ui/desktop/app/routes/index.js
index 16a7af83e..b3ae29160 100644
--- a/ui/desktop/app/routes/index.js
+++ b/ui/desktop/app/routes/index.js
@@ -18,12 +18,12 @@ export default class IndexRoute extends Route {
/**
* If no clusterUrl is specified yet, redirects to cluster-url, otherwise scopes.
*/
- redirect() {
+ async beforeModel() {
// cleanup terminal view when navigating to index route - on window reload
this.terminal.cleanup();
- const rendererClusterUrl = this.clusterUrl.rendererClusterUrl;
- if (!rendererClusterUrl) {
+ const clusterUrl = await this.clusterUrl.getClusterUrl();
+ if (!clusterUrl) {
this.router.replaceWith('cluster-url');
} else {
this.router.replaceWith('scopes');
diff --git a/ui/desktop/app/routes/scopes/scope/authenticate.js b/ui/desktop/app/routes/scopes/scope/authenticate.js
index 52bc046b0..4c84354ad 100644
--- a/ui/desktop/app/routes/scopes/scope/authenticate.js
+++ b/ui/desktop/app/routes/scopes/scope/authenticate.js
@@ -17,8 +17,11 @@ export default class ScopesScopeAuthenticateRoute extends Route {
// =methods
- beforeModel() {
- if (this.session.isAuthenticated) {
+ async beforeModel() {
+ const clusterUrl = await this.clusterUrl.getClusterUrl();
+ if (!clusterUrl) {
+ this.router.replaceWith('cluster-url');
+ } else if (this.session.isAuthenticated) {
this.router.replaceWith('scopes.scope.index');
}
}
@@ -64,17 +67,13 @@ export default class ScopesScopeAuthenticateRoute extends Route {
};
}
- redirect() {
- if (!this.clusterUrl.rendererClusterUrl) this.router.replaceWith('index');
- }
-
/**
* Adds the existing clusterUrl, if any, to the controller scope.
* @param {Controller} controller
*/
- setupController(controller) {
+ async setupController(controller) {
super.setupController(...arguments);
- const clusterUrl = this.clusterUrl.rendererClusterUrl;
+ const clusterUrl = await this.clusterUrl.getClusterUrl();
controller.setProperties({ clusterUrl });
}
}
diff --git a/ui/desktop/app/routes/scopes/scope/projects/settings/index.js b/ui/desktop/app/routes/scopes/scope/projects/settings/index.js
index 59d2b3a80..4f8697b95 100644
--- a/ui/desktop/app/routes/scopes/scope/projects/settings/index.js
+++ b/ui/desktop/app/routes/scopes/scope/projects/settings/index.js
@@ -22,7 +22,7 @@ export default class ScopesScopeProjectsSettingsIndexRoute extends Route {
const logLevel = await window.desktop.logging.getLogLevel();
const logPath = await window.desktop.logging.getLogPath();
- const serverInformation = this.clusterUrl.rendererClusterUrl;
+ const serverInformation = await this.clusterUrl.getClusterUrl();
const { isLinux } = await window.desktop.system.checkOS();
return {
diff --git a/ui/desktop/app/routes/scopes/scope/projects/targets/index.js b/ui/desktop/app/routes/scopes/scope/projects/targets/index.js
index dd4e9d9da..3ed9afe53 100644
--- a/ui/desktop/app/routes/scopes/scope/projects/targets/index.js
+++ b/ui/desktop/app/routes/scopes/scope/projects/targets/index.js
@@ -18,7 +18,6 @@ export default class ScopesScopeProjectsTargetsIndexRoute extends Route {
// =services
@service abilities;
- @service clusterUrl;
@service resourceFilterStore;
@service router;
@service session;
diff --git a/ui/desktop/app/services/cluster-url.js b/ui/desktop/app/services/cluster-url.js
index 0480e3e67..5b5365fe0 100644
--- a/ui/desktop/app/services/cluster-url.js
+++ b/ui/desktop/app/services/cluster-url.js
@@ -12,7 +12,6 @@ export default class ClusterUrlService extends Service {
// =services
@service store;
- @service storage;
// =attributes
@@ -23,35 +22,10 @@ export default class ClusterUrlService extends Service {
return this.store.adapterFor('application');
}
- /**
- * @type {?string}
- */
- get rendererClusterUrl() {
- return this.storage.getItem('cluster-url');
- }
-
- /**
- * @param {?string} clusterUrl
- */
- set rendererClusterUrl(clusterUrl) {
- this.storage.setItem('cluster-url', clusterUrl);
- }
-
- /**
- * @type {Promise{?string}}
- */
- get mainClusterUrl() {
- return window.desktop.cluster.getClusterUrl();
- }
-
// =methods
- /**
- * Sets the main clusterUrl equal to the current renderer clusterUrl (if any).
- */
- async updateClusterUrl() {
- const rendererClusterUrl = this.rendererClusterUrl;
- if (rendererClusterUrl) await this.setClusterUrl(rendererClusterUrl);
+ async getClusterUrl() {
+ return window.desktop.cluster.getClusterUrl();
}
/**
@@ -73,26 +47,24 @@ export default class ClusterUrlService extends Service {
clusterUrl = clusterUrl.trim();
clusterUrl = clusterUrl.replace(/\/*$/, '');
this.adapter.host = clusterUrl;
- this.rendererClusterUrl = clusterUrl;
- if (clusterUrl !== (await this.mainClusterUrl)) {
+ if (clusterUrl !== (await this.getClusterUrl())) {
await window.desktop.cluster.setClusterUrl(clusterUrl);
}
} catch (e) {
this.adapter.host = originalHost;
- this.rendererClusterUrl = null;
throw e;
}
}
/**
- * Resets the clusterUrl.
+ * Resets the clusterUrl in both the electron store and the adapter host.
*/
@notifyError(({ message }) => message, {
catch: true,
log: { origin: 'resetClusterUrl' },
})
async resetClusterUrl() {
- this.rendererClusterUrl = null;
- await window.desktop.cluster.resetClusterUrl();
+ this.adapter.host = undefined;
+ return window.desktop.cluster.resetClusterUrl();
}
}
diff --git a/ui/desktop/electron-app/src/ipc/handlers.js b/ui/desktop/electron-app/src/ipc/handlers.js
index 493516010..e6e4e77c5 100644
--- a/ui/desktop/electron-app/src/ipc/handlers.js
+++ b/ui/desktop/electron-app/src/ipc/handlers.js
@@ -33,7 +33,7 @@ handle('getClusterUrl', () => runtimeSettings.clusterUrl);
handle('setClusterUrl', async (requestOrigin) => {
const clusterUrl = sanitizer.urlValidate(requestOrigin);
await runtimeSettings.validateClusterUrl(clusterUrl);
- await runtimeSettings.setClusterUrl(clusterUrl);
+ await runtimeSettings.triggerClusterUrlUpdate(clusterUrl);
});
/**
diff --git a/ui/desktop/electron-app/src/models/runtime-settings.js b/ui/desktop/electron-app/src/models/runtime-settings.js
index 0dfa45249..a0dddc3bb 100644
--- a/ui/desktop/electron-app/src/models/runtime-settings.js
+++ b/ui/desktop/electron-app/src/models/runtime-settings.js
@@ -4,26 +4,25 @@
*/
const { netRequest } = require('../helpers/request-promise.js');
+const store = require('../services/electron-store-manager');
// Runtime settings are any configuration, especially user-specified,
// set up at runtime. For example, the Boundary clusterUrl is a runtime setting.
class RuntimeSettings {
- // Internal private clusterUrl is exposed via getter/setter below.
- #clusterUrl = undefined;
-
/**
* The user-specified Boundary clusterUrl, which should be allowed by CSP.
* @type {?string}
*/
get clusterUrl() {
- return this.#clusterUrl;
+ return store.get('clusterUrl');
}
- async setClusterUrl(clusterUrl) {
- if (this.#clusterUrl !== clusterUrl) {
- this.#clusterUrl = clusterUrl;
- await this.triggerClusterUrlChanged();
- }
+ /**
+ * Sets the user specified Boundary clusterUrl.
+ * @param value {string}
+ */
+ set clusterUrl(value) {
+ store.set('clusterUrl', value);
}
/**
@@ -51,8 +50,8 @@ class RuntimeSettings {
/**
* Sets the clusterUrl to null.
*/
- async resetClusterUrl() {
- await this.setClusterUrl(null);
+ resetClusterUrl() {
+ store.delete('clusterUrl');
}
// Quick and dirty event handler pattern to enable the application to respond
@@ -63,11 +62,14 @@ class RuntimeSettings {
this.#clusterUrlWatchers.push(fn);
}
- async triggerClusterUrlChanged() {
- // We currently only store one function but this will execute serially
- // which may or may not be the desired behavior if there ever is more
- for (const fn of this.#clusterUrlWatchers) {
- await fn(this.#clusterUrl);
+ async triggerClusterUrlUpdate(clusterUrl) {
+ if (this.clusterUrl !== clusterUrl) {
+ this.clusterUrl = clusterUrl;
+ for (const fn of this.#clusterUrlWatchers) {
+ // We currently only store one function but this will execute serially
+ // which may or may not be the desired behavior if there ever is more
+ await fn(this.clusterUrl);
+ }
}
}
}
diff --git a/ui/desktop/tests/acceptance/authentication-test.js b/ui/desktop/tests/acceptance/authentication-test.js
index 75f8049d5..d1522269b 100644
--- a/ui/desktop/tests/acceptance/authentication-test.js
+++ b/ui/desktop/tests/acceptance/authentication-test.js
@@ -71,12 +71,6 @@ module('Acceptance | authentication', function (hooks) {
const MODAL_CANCEL_BTN = '.hds-modal__footer .hds-button--color-secondary';
const HEADER_DROPDOWN_BTN = '.app-header__utility-actions button';
- const setDefaultClusterUrl = (test) => {
- const windowOrigin = window.location.origin;
- const clusterUrl = test.owner.lookup('service:clusterUrl');
- clusterUrl.rendererClusterUrl = windowOrigin;
- };
-
hooks.beforeEach(async function () {
await invalidateSession();
@@ -130,7 +124,7 @@ module('Acceptance | authentication', function (hooks) {
urls.targets = `${urls.projects}/targets`;
urls.sessions = `${urls.projects}/sessions`;
- setDefaultClusterUrl(this);
+ window.desktop.cluster.getClusterUrl.resolves(window.location.origin);
});
hooks.afterEach(async function () {
@@ -147,8 +141,17 @@ module('Acceptance | authentication', function (hooks) {
test('visiting authenticate route without clusterUrl redirects to clusterUrl index', async function (assert) {
assert.expect(1);
- this.owner.lookup('service:clusterUrl').rendererClusterUrl = null;
- await visit(urls.authenticate.global);
+ window.desktop.cluster.getClusterUrl.resolves(null);
+
+ try {
+ await visit(urls.authenticate.global);
+ } catch (e) {
+ if (e.message === 'TransitionAborted') {
+ // Ignore the expected transition abort error caused by the redirect in beforeModel
+ } else {
+ throw e;
+ }
+ }
assert.strictEqual(currentURL(), urls.clusterUrl);
});
diff --git a/ui/desktop/tests/acceptance/cluster-url-test.js b/ui/desktop/tests/acceptance/cluster-url-test.js
index 8e39b391d..da05aac2b 100644
--- a/ui/desktop/tests/acceptance/cluster-url-test.js
+++ b/ui/desktop/tests/acceptance/cluster-url-test.js
@@ -8,13 +8,11 @@ import { visit, currentURL, fillIn, click, find } from '@ember/test-helpers';
import { setupApplicationTest } from 'desktop/tests/helpers';
import sinon from 'sinon';
import { invalidateSession } from 'ember-simple-auth/test-support';
-import { setupBrowserFakes } from 'ember-browser-services/test-support';
import { setupDesktopContextBridgeApiMock } from '../helpers/desktop-context-bridge-api-mock';
import config from '../../config/environment';
module('Acceptance | clusterUrl', function (hooks) {
setupApplicationTest(hooks);
- setupBrowserFakes(hooks, { window: true });
const currentOrigin = window.location.origin;
@@ -108,7 +106,15 @@ module('Acceptance | clusterUrl', function (hooks) {
test('visiting index without a clusterUrl specified redirects to clusterUrl route', async function (assert) {
assert.expect(2);
- await visit(urls.index);
+ try {
+ await visit(urls.index);
+ } catch (e) {
+ if (e.message === 'TransitionAborted') {
+ // Ignore the expected transition abort error caused by the redirect in beforeModel
+ } else {
+ throw e;
+ }
+ }
assert.notOk(window.desktop.clusterUrl);
assert.strictEqual(currentURL(), urls.clusterUrl);
diff --git a/ui/desktop/tests/acceptance/projects-test.js b/ui/desktop/tests/acceptance/projects-test.js
index da5be4cfc..1dc79122d 100644
--- a/ui/desktop/tests/acceptance/projects-test.js
+++ b/ui/desktop/tests/acceptance/projects-test.js
@@ -49,12 +49,6 @@ module('Acceptance | projects', function (hooks) {
projects: null,
};
- const setDefaultClusterUrl = (test) => {
- const windowOrigin = window.location.origin;
- const clusterUrl = test.owner.lookup('service:clusterUrl');
- clusterUrl.rendererClusterUrl = windowOrigin;
- };
-
hooks.beforeEach(async function () {
instances.scopes.global = this.server.schema.scopes.find('global');
instances.authMethods.global = this.server.schema.authMethods.first();
@@ -87,7 +81,7 @@ module('Acceptance | projects', function (hooks) {
urls.authenticate.methods.global = `${urls.authenticate.global}/${instances.authMethods.global.id}`;
urls.projects = `${urls.scopes.org}/projects`;
- setDefaultClusterUrl(this);
+ window.desktop.cluster.getClusterUrl.resolves(window.location.origin);
});
test('visiting index while unauthenticated redirects to global authenticate method', async function (assert) {
diff --git a/ui/desktop/tests/acceptance/projects/sessions/index-test.js b/ui/desktop/tests/acceptance/projects/sessions/index-test.js
index c5b6a91fb..706ba165c 100644
--- a/ui/desktop/tests/acceptance/projects/sessions/index-test.js
+++ b/ui/desktop/tests/acceptance/projects/sessions/index-test.js
@@ -72,12 +72,6 @@ module('Acceptance | projects | sessions | index', function (hooks) {
session: null,
};
- const setDefaultClusterUrl = (test) => {
- const windowOrigin = window.location.origin;
- const clusterUrl = test.owner.lookup('service:clusterUrl');
- clusterUrl.rendererClusterUrl = windowOrigin;
- };
-
hooks.beforeEach(async function () {
// create scopes
instances.scopes.global = this.server.schema.scopes.find('global');
@@ -148,8 +142,7 @@ module('Acceptance | projects | sessions | index', function (hooks) {
urls.sessions2 = `${urls.projects2}/sessions`;
urls.session = `${urls.projects}/sessions/${instances.session.id}`;
- setDefaultClusterUrl(this);
-
+ window.desktop.cluster.getClusterUrl.resolves(window.location.origin);
window.desktop.daemon.isCacheDaemonRunning.resolves(true);
this.stubCacheDaemonSearch('sessions', 'sessions', 'targets');
diff --git a/ui/desktop/tests/acceptance/projects/sessions/session-test.js b/ui/desktop/tests/acceptance/projects/sessions/session-test.js
index cccfd9295..fdc7d9b7e 100644
--- a/ui/desktop/tests/acceptance/projects/sessions/session-test.js
+++ b/ui/desktop/tests/acceptance/projects/sessions/session-test.js
@@ -58,12 +58,6 @@ module('Acceptance | projects | sessions | session', function (hooks) {
rdpSession: null,
};
- const setDefaultClusterUrl = (test) => {
- const windowOrigin = window.location.origin;
- const clusterUrl = test.owner.lookup('service:clusterUrl');
- clusterUrl.rendererClusterUrl = windowOrigin;
- };
-
let originalUncaughtException = QUnit.onUncaughtException;
hooks.beforeEach(async function () {
@@ -139,7 +133,7 @@ module('Acceptance | projects | sessions | session', function (hooks) {
urls.session = `${urls.projects}/sessions/${instances.session.id}`;
urls.rdpSession = `${urls.projects}/sessions/${instances.rdpSession.id}`;
- setDefaultClusterUrl(this);
+ window.desktop.cluster.getClusterUrl.resolves(window.location.origin);
// mock RDP service calls
this.rdpService = this.owner.lookup('service:rdp');
diff --git a/ui/desktop/tests/acceptance/projects/settings/index-test.js b/ui/desktop/tests/acceptance/projects/settings/index-test.js
index 3140f9170..9dd7ba62a 100644
--- a/ui/desktop/tests/acceptance/projects/settings/index-test.js
+++ b/ui/desktop/tests/acceptance/projects/settings/index-test.js
@@ -69,12 +69,6 @@ module('Acceptance | projects | settings | index', function (hooks) {
const RDP_RECOMMENDED_CLIENT = '[data-test-recommended-rdp-client]';
const RDP_RECOMMENDED_CLIENT_LINK = '[data-test-recommended-rdp-client] a';
- const setDefaultClusterUrl = (test) => {
- const windowOrigin = window.location.origin;
- const clusterUrl = test.owner.lookup('service:clusterUrl');
- clusterUrl.rendererClusterUrl = windowOrigin;
- };
-
hooks.beforeEach(async function () {
// Generate scopes
instances.scopes.global = this.server.schema.scopes.find('global');
@@ -96,7 +90,7 @@ module('Acceptance | projects | settings | index', function (hooks) {
urls.projects = `${urls.scopes.org}/projects`;
urls.settings = `${urls.projects}/settings`;
- setDefaultClusterUrl(this);
+ window.desktop.cluster.getClusterUrl.resolves(window.location.origin);
// mock RDP client data
window.desktop.rdp.getRdpClients.resolves([
diff --git a/ui/desktop/tests/acceptance/projects/targets/index-test.js b/ui/desktop/tests/acceptance/projects/targets/index-test.js
index 2e2e50992..1ad5e18d4 100644
--- a/ui/desktop/tests/acceptance/projects/targets/index-test.js
+++ b/ui/desktop/tests/acceptance/projects/targets/index-test.js
@@ -90,12 +90,6 @@ module('Acceptance | projects | targets | index', function (hooks) {
sessions: null,
};
- const setDefaultClusterUrl = (test) => {
- const windowOrigin = window.location.origin;
- const clusterUrl = test.owner.lookup('service:clusterUrl');
- clusterUrl.rendererClusterUrl = windowOrigin;
- };
-
hooks.beforeEach(async function () {
// bypass mirage config that expects recursive to be passed in as queryParam
this.server.get('/targets', ({ targets }) => targets.all());
@@ -165,7 +159,7 @@ module('Acceptance | projects | targets | index', function (hooks) {
// Generate resource counter
getTargetCount = () => this.server.schema.targets.all().models.length;
- setDefaultClusterUrl(this);
+ window.desktop.cluster.getClusterUrl.resolves(window.location.origin);
window.desktop.daemon.isCacheDaemonRunning.resolves(true);
this.stubCacheDaemonSearch('sessions', 'targets', 'aliases', 'sessions');
diff --git a/ui/desktop/tests/acceptance/projects/targets/target-test.js b/ui/desktop/tests/acceptance/projects/targets/target-test.js
index bff8331f0..ac469140e 100644
--- a/ui/desktop/tests/acceptance/projects/targets/target-test.js
+++ b/ui/desktop/tests/acceptance/projects/targets/target-test.js
@@ -77,12 +77,6 @@ module('Acceptance | projects | targets | target', function (hooks) {
targetWithManyHosts: null,
};
- const setDefaultClusterUrl = (test) => {
- const windowOrigin = window.location.origin;
- const clusterUrl = test.owner.lookup('service:clusterUrl');
- clusterUrl.rendererClusterUrl = windowOrigin;
- };
-
hooks.beforeEach(async function () {
// bypass mirage config that expects recursive to be passed in as queryParam
this.server.get('/targets', ({ targets }) => targets.all());
@@ -150,8 +144,7 @@ module('Acceptance | projects | targets | target', function (hooks) {
urls.targetWithTwoHosts = `${urls.targets}/${instances.targetWithTwoHosts.id}`;
urls.targetWithManyHosts = `${urls.targets}/${instances.targetWithManyHosts.id}`;
- setDefaultClusterUrl(this);
-
+ window.desktop.cluster.getClusterUrl.resolves(window.location.origin);
window.desktop.daemon.isCacheDaemonRunning.resolves(true);
this.stubCacheDaemonSearch('sessions', 'targets', 'aliases', 'sessions');
diff --git a/ui/desktop/tests/acceptance/scopes-test.js b/ui/desktop/tests/acceptance/scopes-test.js
index 2e273c00e..46e0928b9 100644
--- a/ui/desktop/tests/acceptance/scopes-test.js
+++ b/ui/desktop/tests/acceptance/scopes-test.js
@@ -73,12 +73,6 @@ module('Acceptance | scopes', function (hooks) {
target: null,
};
- const setDefaultClusterUrl = (test) => {
- const windowOrigin = window.location.origin;
- const clusterUrl = test.owner.lookup('service:clusterUrl');
- clusterUrl.rendererClusterUrl = windowOrigin;
- };
-
hooks.beforeEach(async function () {
// bypass mirage config that expects recursive to be passed in as queryParam
this.server.get('/targets', ({ targets }) => targets.all());
@@ -135,8 +129,7 @@ module('Acceptance | scopes', function (hooks) {
urls.globalTargets = `${urls.globalProjects}/targets`;
urls.target = `${urls.targets}/${instances.target.id}`;
- setDefaultClusterUrl(this);
-
+ window.desktop.cluster.getClusterUrl.resolves(window.location.origin);
window.desktop.daemon.isCacheDaemonRunning.resolves(true);
this.stubCacheDaemonSearch('sessions', 'targets', 'aliases', 'sessions');
diff --git a/ui/desktop/tests/integration/components/settings-card/server-test.js b/ui/desktop/tests/integration/components/settings-card/server-test.js
index 7fffff61c..c5f26e02c 100644
--- a/ui/desktop/tests/integration/components/settings-card/server-test.js
+++ b/ui/desktop/tests/integration/components/settings-card/server-test.js
@@ -16,25 +16,17 @@ module('Integration | Component | settings-card/server', function (hooks) {
setupRenderingTest(hooks);
setupIntl(hooks, 'en-us');
- const setDefaultClusterUrl = (test) => {
- const windowOrigin = 'hashicorp.cloud';
- const clusterUrl = test.owner.lookup('service:clusterUrl');
- clusterUrl.rendererClusterUrl = windowOrigin;
- };
-
- setDefaultClusterUrl(this);
-
test('it displays HCP cluster url in server information section', async function (assert) {
- await render(hbs``);
+ this.set('model', { serverInformation: 'boundary.hashicorp.cloud' });
+ await render(hbs``);
assert.dom(SERVER_NAME).hasText('HashiCorp Cloud Platform');
- assert.dom(SERVER_URL).hasText('hashicorp.cloud');
+ assert.dom(SERVER_URL).hasText('boundary.hashicorp.cloud');
});
test('it displays non HCP cluster url in server information section', async function (assert) {
- this.owner.lookup('service:clusterUrl').rendererClusterUrl =
- 'everythingelse';
- await render(hbs``);
- assert.dom(SERVER_NAME).hasText('Self-Managed');
+ this.set('model', { serverInformation: 'everythingelse' });
+ await render(hbs``);
+ assert.dom(SERVER_NAME).hasText('Self-managed');
assert.dom(SERVER_URL).hasText('everythingelse');
});
});
diff --git a/ui/desktop/tests/unit/controllers/application-test.js b/ui/desktop/tests/unit/controllers/application-test.js
index d44aa473b..76783d4cf 100644
--- a/ui/desktop/tests/unit/controllers/application-test.js
+++ b/ui/desktop/tests/unit/controllers/application-test.js
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { authenticateSession } from 'ember-simple-auth/test-support';
import { setupDesktopContextBridgeApiMock } from '../../helpers/desktop-context-bridge-api-mock';
+import sinon from 'sinon';
module('Unit | Controller | application', function (hooks) {
setupTest(hooks);
@@ -40,18 +41,19 @@ module('Unit | Controller | application', function (hooks) {
assert.strictEqual(session.data.theme, 'light');
});
- test('disconnect action de-authenticates a user and resets cluster url', async function (assert) {
+ test('disconnect action de-authenticates a user and keeps last cluster url', async function (assert) {
const url = 'http://localhost:9200';
await clusterUrl.setClusterUrl(url);
assert.true(session.isAuthenticated);
- assert.strictEqual(clusterUrl.rendererClusterUrl, url);
assert.strictEqual(await window.desktop.cluster.getClusterUrl(), url);
+ assert.strictEqual(clusterUrl.adapter.host, url);
+ sinon.stub(controller.router, 'replaceWith');
await controller.disconnect();
assert.false(session.isAuthenticated);
- assert.notOk(clusterUrl.rendererClusterUrl);
- assert.notOk(await window.desktop.cluster.getClusterUrl());
+ assert.strictEqual(await window.desktop.cluster.getClusterUrl(), url);
+ assert.strictEqual(clusterUrl.adapter.host, url);
});
});
diff --git a/ui/desktop/tests/unit/controllers/cluster-url-test.js b/ui/desktop/tests/unit/controllers/cluster-url-test.js
index d733e91cb..db86bdb97 100644
--- a/ui/desktop/tests/unit/controllers/cluster-url-test.js
+++ b/ui/desktop/tests/unit/controllers/cluster-url-test.js
@@ -12,16 +12,13 @@ import { setupDesktopContextBridgeApiMock } from '../../helpers/desktop-context-
module('Unit | Controller | cluster-url', function (hooks) {
setupTest(hooks);
setupIntl(hooks, 'en-us');
+ setupDesktopContextBridgeApiMock(hooks);
let controller;
- let clusterUrl;
-
- setupDesktopContextBridgeApiMock(hooks);
hooks.beforeEach(async function () {
await authenticateSession({});
controller = this.owner.lookup('controller:cluster-url');
- clusterUrl = this.owner.lookup('service:cluster-url');
});
test('it exists', function (assert) {
@@ -30,12 +27,10 @@ module('Unit | Controller | cluster-url', function (hooks) {
test('setClusterUrl action de-authenticates a user and resets cluster url', async function (assert) {
const newClusterUrl = 'http://localhost:9200';
- assert.notEqual(clusterUrl.rendererClusterUrl, newClusterUrl);
assert.notEqual(window.desktop.clusterUrl, newClusterUrl);
await controller.setClusterUrl(newClusterUrl);
- assert.strictEqual(clusterUrl.rendererClusterUrl, newClusterUrl);
assert.strictEqual(window.desktop.clusterUrl, newClusterUrl);
});
});
diff --git a/ui/desktop/tests/unit/controllers/scopes/scope/authenticate/method/index-test.js b/ui/desktop/tests/unit/controllers/scopes/scope/authenticate/method/index-test.js
index 76c98c51e..2cc73c529 100644
--- a/ui/desktop/tests/unit/controllers/scopes/scope/authenticate/method/index-test.js
+++ b/ui/desktop/tests/unit/controllers/scopes/scope/authenticate/method/index-test.js
@@ -35,12 +35,6 @@ module(
targets: null,
};
- const setDefaultClusterUrl = (test) => {
- const windowOrigin = window.location.origin;
- const clusterUrl = test.owner.lookup('service:clusterUrl');
- clusterUrl.rendererClusterUrl = windowOrigin;
- };
-
hooks.beforeEach(async function () {
controller = this.owner.lookup(
'controller:scopes/scope/authenticate/method/index',
@@ -58,7 +52,7 @@ module(
urls.targets = '/scopes/global/projects/targets';
- setDefaultClusterUrl(this);
+ window.desktop.cluster.getClusterUrl.resolves(window.location.origin);
});
test('it exists', function (assert) {
diff --git a/ui/desktop/tests/unit/services/cluster-url-test.js b/ui/desktop/tests/unit/services/cluster-url-test.js
index f97b85065..dac267ebb 100644
--- a/ui/desktop/tests/unit/services/cluster-url-test.js
+++ b/ui/desktop/tests/unit/services/cluster-url-test.js
@@ -17,37 +17,69 @@ module('Unit | Service | clusterUrl', function (hooks) {
service = this.owner.lookup('service:clusterUrl');
});
- test('resets clusterUrl on error', async function (assert) {
- assert.expect(4);
-
+ test('keeps clusterUrl on error', async function (assert) {
+ assert.expect(3);
await service.setClusterUrl(window.location.origin);
-
- assert.strictEqual(service.rendererClusterUrl, window.location.origin);
assert.strictEqual(service.adapter.host, window.location.origin);
window.desktop.cluster.setClusterUrl.rejects();
- service.setClusterUrl('invalid-origin').catch(() => {
- assert.notOk(service.rendererClusterUrl);
+
+ try {
+ await service.setClusterUrl('http://other-origin');
+ } catch {
assert.strictEqual(service.adapter.host, window.location.origin);
- });
+ assert.true(
+ window.desktop.cluster.setClusterUrl.calledWithExactly(
+ 'http://other-origin',
+ ),
+ );
+ }
});
test('drops trailing slashes from clusterUrl on setClusterUrl', async function (assert) {
assert.expect(4);
await service.setClusterUrl(`${window.location.origin}/`);
- assert.strictEqual(service.rendererClusterUrl, window.location.origin);
assert.strictEqual(service.adapter.host, window.location.origin);
+ assert.true(
+ window.desktop.cluster.setClusterUrl.calledWithExactly(
+ window.location.origin,
+ ),
+ );
+
await service.setClusterUrl(`${window.location.origin}//////`);
- assert.strictEqual(service.rendererClusterUrl, window.location.origin);
assert.strictEqual(service.adapter.host, window.location.origin);
+ assert.true(
+ window.desktop.cluster.setClusterUrl.calledWithExactly(
+ window.location.origin,
+ ),
+ );
});
test('trim spaces from clusterUrl on setClusterUrl', async function (assert) {
assert.expect(4);
await service.setClusterUrl(` ${window.location.origin}/ `);
- assert.strictEqual(service.rendererClusterUrl, window.location.origin);
assert.strictEqual(service.adapter.host, window.location.origin);
+ assert.true(
+ window.desktop.cluster.setClusterUrl.calledWithExactly(
+ window.location.origin,
+ ),
+ );
+
await service.setClusterUrl(` ${window.location.origin} `);
- assert.strictEqual(service.rendererClusterUrl, window.location.origin);
assert.strictEqual(service.adapter.host, window.location.origin);
+ assert.true(
+ window.desktop.cluster.setClusterUrl.calledWithExactly(
+ window.location.origin,
+ ),
+ );
+ });
+
+ test('resetClusterUrl clears adapter host and invokes IPC', async function (assert) {
+ await service.setClusterUrl(window.location.origin);
+ assert.strictEqual(service.adapter.host, window.location.origin);
+
+ await service.resetClusterUrl();
+
+ assert.strictEqual(service.adapter.host, undefined);
+ assert.true(window.desktop.cluster.resetClusterUrl.calledOnce);
});
});