diff --git a/changelog/_14445.txt b/changelog/_14445.txt new file mode 100644 index 0000000000..ef4c67d3ed --- /dev/null +++ b/changelog/_14445.txt @@ -0,0 +1,3 @@ +```release-note:bug +ui: Fix secrets to secrets-engines redirect for bookmarked URLs. +``` \ No newline at end of file diff --git a/ui/app/router.js b/ui/app/router.js index 7ac7838656..af00bd8a72 100644 --- a/ui/app/router.js +++ b/ui/app/router.js @@ -168,6 +168,7 @@ Router.map(function () { }); }); this.route('secrets-redirect', { path: '/secrets' }); // legacy redirect + this.route('secrets-redirect-with-path', { path: '/secrets/*path' }); // legacy redirect with wildcard to capture full path this.route('secrets', { path: '/secrets-engines' }, function () { this.route('enable', function () { this.route('create', { path: '/:mount_type' }); diff --git a/ui/app/routes/vault/cluster/secrets-redirect-with-path.js b/ui/app/routes/vault/cluster/secrets-redirect-with-path.js new file mode 100644 index 0000000000..ad4a1b3b12 --- /dev/null +++ b/ui/app/routes/vault/cluster/secrets-redirect-with-path.js @@ -0,0 +1,27 @@ +/** + * Copyright IBM Corp. 2016, 2025 + * SPDX-License-Identifier: BUSL-1.1 + */ +import Route from '@ember/routing/route'; +import { service } from '@ember/service'; + +export default class SecretsRedirectWithPathRoute extends Route { + @service router; + + beforeModel(transition) { + // Redirect to secrets page under /secrets-engines + // if the user navigates to the legacy path /secrets + // Preserve the full path after /secrets (e.g., /secrets/kv/kv/list -> /secrets-engines/kv/kv/list) + const params = transition.to.params; + const path = params?.path; + + if (path) { + // Construct the new URL with full path including /vault/secrets-engines/*path + const newUrl = `/vault/secrets-engines/${path}`; + this.router.replaceWith(newUrl); + } else { + // If no path, just redirect to the base secrets page + this.router.replaceWith('vault.cluster.secrets'); + } + } +} diff --git a/ui/tests/acceptance/cluster-test.js b/ui/tests/acceptance/cluster-test.js index d01e8e64bd..84f103953a 100644 --- a/ui/tests/acceptance/cluster-test.js +++ b/ui/tests/acceptance/cluster-test.js @@ -10,7 +10,7 @@ import { v4 as uuidv4 } from 'uuid'; import { login, loginMethod, logout } from 'vault/tests/helpers/auth/auth-helpers'; import { mountBackend } from 'vault/tests/helpers/components/mount-backend-form-helpers'; -import { runCmd } from 'vault/tests/helpers/commands'; +import { mountEngineCmd, runCmd, deleteEngineCmd } from 'vault/tests/helpers/commands'; import { GENERAL } from 'vault/tests/helpers/general-selectors'; const tokenWithPolicy = async function (name, policy) { @@ -120,4 +120,15 @@ module('Acceptance | cluster', function (hooks) { 'Navigating to /secrets redirects to /secrets-engines' ); }); + + test('redirects to /secrets-engines/kv/kv/list from legacy /secrets/kv/kv/list path', async function (assert) { + await runCmd(mountEngineCmd('kv', this.backend), false); + await visit('/vault/secrets/kv/kv/list'); + assert.strictEqual( + currentURL(), + '/vault/secrets-engines/kv/kv/list', + 'Navigating to /secrets redirects to /secrets-engines' + ); + await runCmd(deleteEngineCmd('kv')); + }); });