diff --git a/ui/app/adapters/cluster.js b/ui/app/adapters/cluster.js
index 131d143e84..19f7682f71 100644
--- a/ui/app/adapters/cluster.js
+++ b/ui/app/adapters/cluster.js
@@ -61,6 +61,12 @@ export default ApplicationAdapter.extend({
}
if (replicationStatus && replicationStatus instanceof AdapterError === false) {
ret = Object.assign(ret, replicationStatus.data);
+ } else if (
+ replicationStatus instanceof AdapterError &&
+ replicationStatus?.errors.find((err) => err === 'disabled path')
+ ) {
+ // set redacted if result is an error which only happens when redacted
+ ret = Object.assign(ret, { replication_redacted: true });
}
return resolve(ret);
});
diff --git a/ui/app/components/sidebar/nav/cluster.hbs b/ui/app/components/sidebar/nav/cluster.hbs
index 6668bade2e..bb3c142de0 100644
--- a/ui/app/components/sidebar/nav/cluster.hbs
+++ b/ui/app/components/sidebar/nav/cluster.hbs
@@ -52,7 +52,14 @@
}}
Monitoring
{{/if}}
- {{#if (and this.version.isEnterprise this.namespace.inRootNamespace (has-permission "status" routeParams="replication"))}}
+ {{#if
+ (and
+ this.version.isEnterprise
+ this.namespace.inRootNamespace
+ (not this.cluster.replicationRedacted)
+ (has-permission "status" routeParams="replication")
+ )
+ }}
{{/if}}
- {{#if (and @isRootNamespace (has-permission "status" routeParams="replication"))}}
+ {{#if
+ (and @isRootNamespace (has-permission "status" routeParams="replication") (not (is-empty-value @replication)))
+ }}
{
return this._super(...arguments);
});
diff --git a/ui/mirage/handlers/reduced-disclosure.js b/ui/mirage/handlers/reduced-disclosure.js
index c0be1b072b..73fc189d36 100644
--- a/ui/mirage/handlers/reduced-disclosure.js
+++ b/ui/mirage/handlers/reduced-disclosure.js
@@ -4,6 +4,7 @@
*/
import modifyPassthroughResponse from '../helpers/modify-passthrough-response';
+import { Response } from 'miragejs';
export default function (server) {
server.get('/sys/health', (schema, req) =>
@@ -12,7 +13,10 @@ export default function (server) {
server.get('/sys/seal-status', (schema, req) =>
modifyPassthroughResponse(req, { version: '', cluster_name: '', build_date: '' })
);
- server.get('sys/replication/status', () => new Response(404));
- server.get('sys/replication/dr/status', () => new Response(404));
- server.get('sys/replication/performance/status', () => new Response(404));
+ server.get('sys/replication/status', () => new Response(404, {}, { errors: ['disabled path'] }));
+ server.get('sys/replication/dr/status', () => new Response(404, {}, { errors: ['disabled path'] }));
+ server.get(
+ 'sys/replication/performance/status',
+ () => new Response(404, {}, { errors: ['disabled path'] })
+ );
}
diff --git a/ui/tests/acceptance/enterprise-reduced-disclosure-test.js b/ui/tests/acceptance/enterprise-reduced-disclosure-test.js
index 93976d204d..ad5b8c332a 100644
--- a/ui/tests/acceptance/enterprise-reduced-disclosure-test.js
+++ b/ui/tests/acceptance/enterprise-reduced-disclosure-test.js
@@ -134,4 +134,17 @@ module('Acceptance | Enterprise | reduced disclosure test', function (hooks) {
.dom('[data-test-footer-version]')
.hasText(`Vault ${versionSvc.version}`, 'Version is shown after login');
});
+
+ test('does not allow access to replication pages', async function (assert) {
+ await authPage.login();
+ assert.dom('[data-test-sidebar-nav-link="Replication"]').doesNotExist('hides replication nav item');
+
+ await visit(`/vault/replication/dr`);
+ assert.strictEqual(
+ currentRouteName(),
+ 'vault.cluster.dashboard',
+ 'redirects to dashboard if replication access attempted'
+ );
+ assert.dom('[data-test-card="replication"]').doesNotExist('hides replication card on dashboard');
+ });
});