mirror of
https://github.com/hashicorp/vault.git
synced 2026-06-09 08:55:13 -04:00
UI: Update template helpers and cleanup component args (#30580)
* make displayName a global helper * rename authTabTypes to visibleMountsByType * remove superfluous arg * move all of mount displaying to component * rename hasMountData to isVisibleMount, update comment
This commit is contained in:
parent
87f1d18e51
commit
e8c196aa62
15 changed files with 112 additions and 109 deletions
|
|
@ -40,22 +40,16 @@
|
|||
<:authSelectOptions>
|
||||
<div class="has-bottom-margin-m">
|
||||
{{#if this.showCustomAuthOptions}}
|
||||
{{! URL contains "with" query param and it references a visible mount }}
|
||||
{{! treat it as a "preferred" mount and hide all other tabs }}
|
||||
{{#if @directLinkData.hasMountData}}
|
||||
{{#let @directLinkData as |mount|}}
|
||||
<Auth::SingleMount
|
||||
@description={{mount.description}}
|
||||
@path={{mount.path}}
|
||||
@shouldRenderPath={{not-eq @selectedAuthMethod "token"}}
|
||||
@type={{this.displayName mount.type}}
|
||||
/>
|
||||
{{/let}}
|
||||
{{#if @directLinkData.isVisibleMount}}
|
||||
{{! URL contains a "with" query param that references a mount with listing_visibility="unauth" }}
|
||||
{{! Treat it as a "preferred" mount and hide all other tabs }}
|
||||
<Auth::MountsDisplay
|
||||
@mounts={{array @directLinkData}}
|
||||
@shouldRenderPath={{not-eq @selectedAuthMethod "token"}}
|
||||
/>
|
||||
{{else}}
|
||||
<Auth::Tabs
|
||||
@authTabData={{@authTabData}}
|
||||
@authTabTypes={{this.authTabTypes}}
|
||||
@displayNameHelper={{this.displayName}}
|
||||
@authTabData={{@visibleMountsByType}}
|
||||
@handleTabClick={{this.setAuthType}}
|
||||
@selectedAuthMethod={{this.selectedAuthMethod}}
|
||||
/>
|
||||
|
|
@ -72,7 +66,7 @@
|
|||
<F.Options>
|
||||
{{#each this.availableMethodTypes as |type|}}
|
||||
<option selected={{eq this.selectedAuthMethod type}} value={{type}}>
|
||||
{{this.displayName type}}
|
||||
{{auth-display-name type}}
|
||||
</option>
|
||||
{{/each}}
|
||||
</F.Options>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Component from '@glimmer/component';
|
|||
import { service } from '@ember/service';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { action } from '@ember/object';
|
||||
import { ALL_LOGIN_METHODS, supportedTypes } from 'vault/utils/supported-login-methods';
|
||||
import { supportedTypes } from 'vault/utils/supported-login-methods';
|
||||
import { getRelativePath } from 'core/utils/sanitize-path';
|
||||
|
||||
import type AuthService from 'vault/vault/services/auth';
|
||||
|
|
@ -15,7 +15,7 @@ import type FlagsService from 'vault/services/flags';
|
|||
import type Store from '@ember-data/store';
|
||||
import type VersionService from 'vault/services/version';
|
||||
import type ClusterModel from 'vault/models/cluster';
|
||||
import type { AuthTabData, AuthTabMountData } from 'vault/vault/auth/form';
|
||||
import type { UnauthMountsByType, AuthTabMountData } from 'vault/vault/auth/form';
|
||||
import type { HTMLElementEvent } from 'vault/forms';
|
||||
|
||||
/**
|
||||
|
|
@ -29,26 +29,26 @@ import type { HTMLElementEvent } from 'vault/forms';
|
|||
* dynamically renders the corresponding form.
|
||||
*
|
||||
*
|
||||
* @param {object} authTabData - auth methods to render as tabs, contains mount data for any mounts with listing_visibility="unauth"
|
||||
* @param {object} cluster - The route model which is the ember data cluster model. contains information such as cluster id, name and boolean for if the cluster is in standby
|
||||
* @param {function} handleNamespaceUpdate - callback task that passes user input to the controller and updates the namespace query param in the url
|
||||
* @param {boolean} hasVisibleAuthMounts - whether or not any mounts have been tuned with listing_visibility="unauth"
|
||||
* @param {string} namespaceQueryParam - namespace query param from the url
|
||||
* @param {function} onSuccess - callback after the initial authentication request, if an mfa_requirement exists the parent renders the mfa form otherwise it fires the authSuccess action in the auth controller and handles transitioning to the app
|
||||
* @param {string} canceledMfaAuth - saved auth type from a cancelled mfa verification
|
||||
* @param {object} cluster - The route model which is the ember data cluster model. contains information such as cluster id, name and boolean for if the cluster is in standby
|
||||
* @param {object} directLinkData - mount data built from the "with" query param. If param is a mount path and maps to a visible mount, the login form defaults to this mount. Otherwise the form preselects the passed auth type.
|
||||
* @param {function} handleNamespaceUpdate - callback task that passes user input to the controller and updates the namespace query param in the url
|
||||
* @param {string} namespaceQueryParam - namespace query param from the url
|
||||
* @param {string} oidcProviderQueryParam - oidc provider query param, set in url as "?o=someprovider". if present, disables the namespace input
|
||||
* @param {function} onSuccess - callback after the initial authentication request, if an mfa_requirement exists the parent renders the mfa form otherwise it fires the authSuccess action in the auth controller and handles transitioning to the app
|
||||
* @param {object} visibleMountsByType - auth methods to render as tabs, contains mount data for any mounts with listing_visibility="unauth"
|
||||
*
|
||||
* */
|
||||
|
||||
interface Args {
|
||||
authTabData: AuthTabData;
|
||||
cluster: ClusterModel;
|
||||
handleNamespaceUpdate: CallableFunction;
|
||||
hasVisibleAuthMounts: boolean;
|
||||
namespaceQueryParam: string;
|
||||
onSuccess: CallableFunction;
|
||||
canceledMfaAuth: string;
|
||||
directLinkData: (AuthTabMountData & { hasMountData: boolean }) | null;
|
||||
cluster: ClusterModel;
|
||||
directLinkData: (AuthTabMountData & { isVisibleMount: boolean }) | null;
|
||||
handleNamespaceUpdate: CallableFunction;
|
||||
namespaceQueryParam: string;
|
||||
oidcProviderQueryParam: string;
|
||||
onSuccess: CallableFunction;
|
||||
visibleMountsByType: UnauthMountsByType;
|
||||
}
|
||||
|
||||
export default class AuthFormTemplate extends Component<Args> {
|
||||
|
|
@ -64,13 +64,8 @@ export default class AuthFormTemplate extends Component<Args> {
|
|||
@tracked selectedAuthMethod = '';
|
||||
@tracked errorMessage = '';
|
||||
|
||||
displayName = (type: string) => {
|
||||
const displayName = ALL_LOGIN_METHODS?.find((t) => t.type === type)?.displayName;
|
||||
return displayName || type;
|
||||
};
|
||||
|
||||
get authTabTypes() {
|
||||
const visibleMounts = this.args.authTabData;
|
||||
const visibleMounts = this.args.visibleMountsByType;
|
||||
return visibleMounts ? Object.keys(visibleMounts) : [];
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +106,7 @@ export default class AuthFormTemplate extends Component<Args> {
|
|||
// This getter determines whether to render an alternative view (e.g., tabs or a preferred mount).
|
||||
// If `true`, the "Sign in with other methods →" link is shown.
|
||||
get showCustomAuthOptions() {
|
||||
const hasLoginCustomization = this.args?.directLinkData?.hasMountData || this.args.hasVisibleAuthMounts;
|
||||
const hasLoginCustomization = this.args?.directLinkData?.isVisibleMount || this.args.visibleMountsByType;
|
||||
// Show if customization exists and the user has NOT clicked "Sign in with other methods →"
|
||||
return hasLoginCustomization && !this.showOtherMethods;
|
||||
}
|
||||
|
|
@ -123,12 +118,12 @@ export default class AuthFormTemplate extends Component<Args> {
|
|||
this.setAuthType(this.preselectedType);
|
||||
} else {
|
||||
// if nothing has been preselected, select first tab or set to 'token'
|
||||
const authType = this.args.hasVisibleAuthMounts ? (this.authTabTypes[0] as string) : 'token';
|
||||
const authType = this.args.visibleMountsByType ? (this.authTabTypes[0] as string) : 'token';
|
||||
this.setAuthType(authType);
|
||||
}
|
||||
|
||||
// DETERMINES INITIAL RENDER: custom selection (direct link or tabs) vs dropdown
|
||||
if (this.args.hasVisibleAuthMounts) {
|
||||
if (this.args.visibleMountsByType) {
|
||||
// render tabs if selectedAuthMethod is one, otherwise render dropdown (i.e. showOtherMethods = false)
|
||||
this.showOtherMethods = this.authTabTypes.includes(this.selectedAuthMethod) ? false : true;
|
||||
} else {
|
||||
|
|
|
|||
33
ui/app/components/auth/mounts-display.hbs
Normal file
33
ui/app/components/auth/mounts-display.hbs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
|
||||
{{#if (gt @mounts.length 1)}}
|
||||
{{! render dropdown of mount paths }}
|
||||
<Hds::Form::Select::Field name="path" data-test-select="path" as |F|>
|
||||
<F.Label>Mount path</F.Label>
|
||||
<F.Options>
|
||||
{{#each @mounts as |mount|}}
|
||||
<option value={{mount.path}}>{{mount.path}}</option>
|
||||
{{/each}}
|
||||
</F.Options>
|
||||
</Hds::Form::Select::Field>
|
||||
{{else}}
|
||||
{{! render a single mount path }}
|
||||
{{#let (get @mounts "0") as |mount|}}
|
||||
{{#unless @hideType}}
|
||||
<Hds::Text::Body @tag="p" @weight="semibold" data-test-auth-method={{mount.type}}>
|
||||
{{auth-display-name mount.type}}
|
||||
</Hds::Text::Body>
|
||||
{{/unless}}
|
||||
{{#if mount.description}}
|
||||
<Hds::Text::Body @tag="p" @color="faint" data-test-description>{{mount.description}}</Hds::Text::Body>
|
||||
{{/if}}
|
||||
{{! the token auth method does't support custom paths so no need to render an input }}
|
||||
{{#if @shouldRenderPath}}
|
||||
{{! path is hidden so it is submitted with FormData but does not clutter the login form }}
|
||||
<input type="hidden" id="path" name="path" value={{mount.path}} data-test-input="path" />
|
||||
{{/if}}
|
||||
{{/let}}
|
||||
{{/if}}
|
||||
|
|
@ -50,15 +50,14 @@
|
|||
/>
|
||||
{{else}}
|
||||
<Auth::FormTemplate
|
||||
@authTabData={{this.authTabData}}
|
||||
@canceledMfaAuth={{this.canceledMfaAuth}}
|
||||
@cluster={{@cluster}}
|
||||
@directLinkData={{@directLinkData}}
|
||||
@handleNamespaceUpdate={{@onNamespaceUpdate}}
|
||||
@hasVisibleAuthMounts={{if @visibleAuthMounts true false}}
|
||||
@namespaceQueryParam={{@namespaceQueryParam}}
|
||||
@oidcProviderQueryParam={{@oidcProviderQueryParam}}
|
||||
@onSuccess={{this.onAuthResponse}}
|
||||
@canceledMfaAuth={{this.canceledMfaAuth}}
|
||||
@directLinkData={{@directLinkData}}
|
||||
@visibleMountsByType={{this.visibleMountsByType}}
|
||||
/>
|
||||
{{/if}}
|
||||
</:content>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import { action } from '@ember/object';
|
|||
* @param {string} oidcProviderQueryParam - oidc provider query param, set in url as "?o=someprovider"
|
||||
* @param {function} onAuthSuccess - callback task in controller that receives the auth response (after MFA, if enabled) when login is successful
|
||||
* @param {function} onNamespaceUpdate - callback task that passes user input to the controller to update the login namespace in the url query params
|
||||
* @param {object} visibleAuthMounts - keys are auth methods to render as tabs, values is an array of mount data for mounts with listing_visibility="unauth"
|
||||
* @param {object} visibleAuthMounts - mount paths with listing_visibility="unauth", keys are the mount path and value is it's mount data such as "type" or "description," if it exists
|
||||
* */
|
||||
|
||||
export const CSP_ERROR =
|
||||
|
|
@ -43,7 +43,7 @@ export default class AuthPage extends Component {
|
|||
@tracked mfaAuthData;
|
||||
@tracked mfaErrors = '';
|
||||
|
||||
get authTabData() {
|
||||
get visibleMountsByType() {
|
||||
const visibleAuthMounts = this.args.visibleAuthMounts;
|
||||
if (visibleAuthMounts) {
|
||||
const authMounts = visibleAuthMounts;
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
|
||||
{{#if @type}}
|
||||
<Hds::Text::Body @tag="p" @weight="semibold" data-test-auth-method={{@type}}>{{@type}}</Hds::Text::Body>
|
||||
{{/if}}
|
||||
{{#if @description}}
|
||||
<Hds::Text::Body @tag="p" @color="faint">{{@description}} data-test-description</Hds::Text::Body>
|
||||
{{/if}}
|
||||
{{! the token auth method does't support custom paths so no need to render an input }}
|
||||
{{#if @shouldRenderPath}}
|
||||
{{! path is hidden so it is submitted with FormData but does not clutter the login form }}
|
||||
<input type="hidden" id="path" name="path" value={{@path}} data-test-input="path" />
|
||||
{{/if}}
|
||||
|
|
@ -5,32 +5,18 @@
|
|||
|
||||
<Hds::Tabs @onClickTab={{this.onClickTab}} @selectedTabIndex={{this.selectedTabIndex}} as |T|>
|
||||
{{#each-in @authTabData as |methodType mounts|}}
|
||||
<T.Tab data-test-auth-tab={{methodType}}>{{@displayNameHelper methodType}}</T.Tab>
|
||||
<T.Tab data-test-auth-tab={{methodType}}>{{auth-display-name methodType}}</T.Tab>
|
||||
<T.Panel>
|
||||
<div class="has-top-padding-m">
|
||||
{{! Elements "behind" tabs always render on the DOM and are just superficially hidden/shown.
|
||||
However, for accessibility, we only want to render form inputs relevant to the selected method.
|
||||
By wrapping the elements in this conditional, it only renders them when the tab is selected. }}
|
||||
{{#if (eq @selectedAuthMethod methodType)}}
|
||||
{{#if (gt mounts.length 1)}}
|
||||
{{! render dropdown of mount paths }}
|
||||
<Hds::Form::Select::Field name="path" data-test-select="path" as |F|>
|
||||
<F.Label>Mount path</F.Label>
|
||||
<F.Options>
|
||||
{{#each mounts as |mount|}}
|
||||
<option value={{mount.path}}>{{mount.path}}</option>
|
||||
{{/each}}
|
||||
</F.Options>
|
||||
</Hds::Form::Select::Field>
|
||||
{{else}}
|
||||
{{#let (get mounts "0") as |mount|}}
|
||||
<Auth::SingleMount
|
||||
@description={{mount.description}}
|
||||
@path={{mount.path}}
|
||||
@shouldRenderPath={{not-eq @selectedAuthMethod "token"}}
|
||||
/>
|
||||
{{/let}}
|
||||
{{/if}}
|
||||
<Auth::MountsDisplay
|
||||
@mounts={{mounts}}
|
||||
@shouldRenderPath={{not-eq @selectedAuthMethod "token"}}
|
||||
@hideType={{true}}
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
</T.Panel>
|
||||
|
|
|
|||
|
|
@ -6,24 +6,27 @@
|
|||
import Component from '@glimmer/component';
|
||||
import { action } from '@ember/object';
|
||||
|
||||
import type { AuthTabData } from 'vault/vault/auth/form';
|
||||
import type { UnauthMountsByType } from 'vault/vault/auth/form';
|
||||
|
||||
interface Args {
|
||||
authTabData: AuthTabData;
|
||||
authTabTypes: string[];
|
||||
authTabData: UnauthMountsByType;
|
||||
handleTabClick: CallableFunction;
|
||||
selectedAuthMethod: string;
|
||||
}
|
||||
|
||||
export default class AuthTabs extends Component<Args> {
|
||||
get tabTypes() {
|
||||
return this.args.authTabData ? Object.keys(this.args.authTabData) : [];
|
||||
}
|
||||
|
||||
get selectedTabIndex() {
|
||||
const index = this.args.authTabTypes.indexOf(this.args.selectedAuthMethod);
|
||||
const index = this.tabTypes.indexOf(this.args.selectedAuthMethod);
|
||||
// negative index means the selected method isn't a tab, default to first tab
|
||||
return index < 0 ? 0 : index;
|
||||
}
|
||||
|
||||
@action
|
||||
onClickTab(_event: Event, idx: number) {
|
||||
this.args.handleTabClick(this.args.authTabTypes[idx]);
|
||||
this.args.handleTabClick(this.tabTypes[idx]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
11
ui/app/helpers/auth-display-name.ts
Normal file
11
ui/app/helpers/auth-display-name.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { ALL_LOGIN_METHODS } from 'vault/utils/supported-login-methods';
|
||||
|
||||
export default function authDisplayName(methodType: string) {
|
||||
const displayName = ALL_LOGIN_METHODS?.find((t) => t.type === methodType)?.displayName;
|
||||
return displayName || methodType;
|
||||
}
|
||||
|
|
@ -106,11 +106,11 @@ export default class AuthRoute extends ClusterRouteBase {
|
|||
*/
|
||||
getMountOrTypeData(authMount, visibleAuthMounts) {
|
||||
if (visibleAuthMounts?.[authMount]) {
|
||||
return { path: authMount, ...visibleAuthMounts[authMount], hasMountData: true };
|
||||
return { path: authMount, ...visibleAuthMounts[authMount], isVisibleMount: true };
|
||||
}
|
||||
const types = supportedTypes(this.version.isEnterprise);
|
||||
if (types.includes(sanitizePath(authMount))) {
|
||||
return { type: authMount, hasMountData: false };
|
||||
return { type: authMount, isVisibleMount: false };
|
||||
}
|
||||
// `type` is necessary because it determines which login fields to render.
|
||||
// If we can't safely glean it from the query param, ignore it and return null
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ module('Acceptance | auth login form', function (hooks) {
|
|||
|
||||
test('it renders preferred mount view if "with" query param is a mount path with listing_visibility="unauth"', async function (assert) {
|
||||
await visit('/vault/auth?with=my-oidc%2F');
|
||||
await waitFor(AUTH_FORM.preferredMethod('OIDC'));
|
||||
assert.dom(AUTH_FORM.preferredMethod('OIDC')).hasText('OIDC', 'it renders mount type');
|
||||
await waitFor(AUTH_FORM.preferredMethod('oidc'));
|
||||
assert.dom(AUTH_FORM.preferredMethod('oidc')).hasText('OIDC', 'it renders mount type');
|
||||
assert.dom(GENERAL.inputByAttr('role')).exists();
|
||||
assert.dom(GENERAL.inputByAttr('path')).hasAttribute('type', 'hidden');
|
||||
assert.dom(GENERAL.inputByAttr('path')).hasValue('my-oidc/');
|
||||
|
|
@ -122,7 +122,7 @@ module('Acceptance | auth login form', function (hooks) {
|
|||
assert
|
||||
.dom(AUTH_FORM.tabBtn('oidc'))
|
||||
.hasAttribute('aria-selected', 'true', 'it selects tab matching query param');
|
||||
assert.dom(AUTH_FORM.preferredMethod('OIDC')).doesNotExist('it does not render single mount view');
|
||||
assert.dom(AUTH_FORM.preferredMethod('oidc')).doesNotExist('it does not render single mount view');
|
||||
assert.dom(GENERAL.backButton).doesNotExist();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export const AUTH_FORM = {
|
|||
selectMethod: '[data-test-select="auth type"]',
|
||||
form: '[data-test-auth-form]',
|
||||
login: '[data-test-auth-submit]',
|
||||
preferredMethod: (displayName: string) => `p[data-test-auth-method="${displayName}"]`, // display name => i.e "OIDC" not "oidc"
|
||||
preferredMethod: (method: string) => `p[data-test-auth-method="${method}"]`,
|
||||
tabs: '[data-test-auth-tab]',
|
||||
tabBtn: (method: string) => `[data-test-auth-tab="${method}"] button`, // method is all lowercased
|
||||
description: '[data-test-description]',
|
||||
|
|
|
|||
|
|
@ -25,12 +25,12 @@ module('Integration | Component | auth | form template', function (hooks) {
|
|||
setupMirage(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
window.localStorage.clear();
|
||||
this.version = this.owner.lookup('service:version');
|
||||
this.authTabData = null;
|
||||
this.visibleMountsByType = null;
|
||||
this.cluster = { id: '1' };
|
||||
this.directLinkData = null;
|
||||
this.handleNamespaceUpdate = sinon.spy();
|
||||
this.hasVisibleAuthMounts = false;
|
||||
this.namespaceQueryParam = '';
|
||||
this.oidcProviderQueryParam = '';
|
||||
this.onSuccess = sinon.spy();
|
||||
|
|
@ -39,11 +39,10 @@ module('Integration | Component | auth | form template', function (hooks) {
|
|||
this.renderComponent = () => {
|
||||
return render(hbs`
|
||||
<Auth::FormTemplate
|
||||
@authTabData={{this.authTabData}}
|
||||
@visibleMountsByType={{this.visibleMountsByType}}
|
||||
@cluster={{this.cluster}}
|
||||
@directLinkData={{this.directLinkData}}
|
||||
@handleNamespaceUpdate={{this.handleNamespaceUpdate}}
|
||||
@hasVisibleAuthMounts={{this.hasVisibleAuthMounts}}
|
||||
@namespaceQueryParam={{this.namespaceQueryParam}}
|
||||
@oidcProviderQueryParam={{this.oidcProviderQueryParam}}
|
||||
@onSuccess={{this.onSuccess}}
|
||||
|
|
@ -67,7 +66,7 @@ module('Integration | Component | auth | form template', function (hooks) {
|
|||
});
|
||||
|
||||
test('it selects type in the dropdown if @directLinkData data just contains type', async function (assert) {
|
||||
this.directLinkData = { type: 'oidc', hasMountData: false };
|
||||
this.directLinkData = { type: 'oidc', isVisibleMount: false };
|
||||
await this.renderComponent();
|
||||
assert.dom(GENERAL.selectByAttr('auth type')).hasValue('oidc');
|
||||
assert.dom(GENERAL.inputByAttr('role')).exists();
|
||||
|
|
@ -96,8 +95,7 @@ module('Integration | Component | auth | form template', function (hooks) {
|
|||
|
||||
module('listing visibility', function (hooks) {
|
||||
hooks.beforeEach(function () {
|
||||
this.hasVisibleAuthMounts = true;
|
||||
this.authTabData = {
|
||||
this.visibleMountsByType = {
|
||||
userpass: [
|
||||
{
|
||||
path: 'userpass/',
|
||||
|
|
@ -185,7 +183,7 @@ module('Integration | Component | auth | form template', function (hooks) {
|
|||
test('it renders the mount description', async function (assert) {
|
||||
await this.renderComponent();
|
||||
await click(AUTH_FORM.tabBtn('token'));
|
||||
assert.dom('section p').hasText('token based credentials data-test-description');
|
||||
assert.dom('section p').hasText('token based credentials');
|
||||
});
|
||||
|
||||
test('it renders a dropdown if multiple mount paths are returned', async function (assert) {
|
||||
|
|
@ -261,9 +259,9 @@ module('Integration | Component | auth | form template', function (hooks) {
|
|||
|
||||
// if mount data exists, the mount has listing_visibility="unauth"
|
||||
test('it renders single mount view instead of tabs if @directLinkData data exists and includes mount data', async function (assert) {
|
||||
this.directLinkData = { path: 'my-oidc/', type: 'oidc', hasMountData: true };
|
||||
this.directLinkData = { path: 'my-oidc/', type: 'oidc', isVisibleMount: true };
|
||||
await this.renderComponent();
|
||||
assert.dom(AUTH_FORM.preferredMethod('OIDC')).hasText('OIDC', 'it renders mount type');
|
||||
assert.dom(AUTH_FORM.preferredMethod('oidc')).hasText('OIDC', 'it renders mount type');
|
||||
assert.dom(GENERAL.inputByAttr('role')).exists();
|
||||
assert.dom(GENERAL.inputByAttr('path')).hasAttribute('type', 'hidden');
|
||||
assert.dom(GENERAL.inputByAttr('path')).hasValue('my-oidc/');
|
||||
|
|
@ -277,7 +275,7 @@ module('Integration | Component | auth | form template', function (hooks) {
|
|||
|
||||
test('it does not render tabs if @directLinkData data exists and just includes type', async function (assert) {
|
||||
// set a type that is NOT in a visible mount because mount data exists otherwise
|
||||
this.directLinkData = { type: 'ldap', hasMountData: false };
|
||||
this.directLinkData = { type: 'ldap', isVisibleMount: false };
|
||||
await this.renderComponent();
|
||||
|
||||
assert.dom(GENERAL.selectByAttr('auth type')).hasValue('ldap', 'dropdown has type selected');
|
||||
|
|
@ -287,7 +285,7 @@ module('Integration | Component | auth | form template', function (hooks) {
|
|||
await click(AUTH_FORM.advancedSettings);
|
||||
assert.dom(GENERAL.inputByAttr('path')).exists();
|
||||
|
||||
assert.dom(AUTH_FORM.preferredMethod('LDAP')).doesNotExist('single mount view does not render');
|
||||
assert.dom(AUTH_FORM.preferredMethod('ldap')).doesNotExist('single mount view does not render');
|
||||
assert.dom(AUTH_FORM.tabBtn('ldap')).doesNotExist('tab does not render');
|
||||
assert
|
||||
.dom(GENERAL.backButton)
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ module('Integration | Component | auth | page', function (hooks) {
|
|||
});
|
||||
|
||||
test('it selects type in the dropdown if @directLinkData references NON visible type', async function (assert) {
|
||||
this.directLinkData = { type: 'ldap', hasMountData: false };
|
||||
this.directLinkData = { type: 'ldap', isVisibleMount: false };
|
||||
await this.renderComponent();
|
||||
assert.dom(GENERAL.selectByAttr('auth type')).hasValue('ldap', 'dropdown has type selected');
|
||||
assert.dom(AUTH_FORM.authForm('ldap')).exists();
|
||||
|
|
@ -133,7 +133,7 @@ module('Integration | Component | auth | page', function (hooks) {
|
|||
await click(AUTH_FORM.advancedSettings);
|
||||
assert.dom(GENERAL.inputByAttr('path')).exists();
|
||||
|
||||
assert.dom(AUTH_FORM.preferredMethod('LDAP')).doesNotExist('single mount view does not render');
|
||||
assert.dom(AUTH_FORM.preferredMethod('ldap')).doesNotExist('single mount view does not render');
|
||||
assert.dom(AUTH_FORM.tabBtn('ldap')).doesNotExist('tab does not render');
|
||||
assert
|
||||
.dom(GENERAL.backButton)
|
||||
|
|
@ -142,9 +142,9 @@ module('Integration | Component | auth | page', function (hooks) {
|
|||
});
|
||||
|
||||
test('it renders single mount view instead of tabs if @directLinkData data references a visible type', async function (assert) {
|
||||
this.directLinkData = { path: 'my-oidc/', type: 'oidc', hasMountData: true };
|
||||
this.directLinkData = { path: 'my-oidc/', type: 'oidc', isVisibleMount: true };
|
||||
await this.renderComponent();
|
||||
assert.dom(AUTH_FORM.preferredMethod('OIDC')).hasText('OIDC', 'it renders mount type');
|
||||
assert.dom(AUTH_FORM.preferredMethod('oidc')).hasText('OIDC', 'it renders mount type');
|
||||
assert.dom(GENERAL.inputByAttr('role')).exists();
|
||||
assert.dom(GENERAL.inputByAttr('path')).hasAttribute('type', 'hidden');
|
||||
assert.dom(GENERAL.inputByAttr('path')).hasValue('my-oidc/');
|
||||
|
|
|
|||
2
ui/types/vault/auth/form.d.ts
vendored
2
ui/types/vault/auth/form.d.ts
vendored
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
export interface AuthTabData {
|
||||
export interface UnauthMountsByType {
|
||||
// key is the auth method type
|
||||
[key: string]: AuthTabMountData[];
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue