vault/ui/tests/helpers/auth/auth-helpers.ts
claire bontempo 31051ef1e4
UI: Implement api service in auth components (#31085)
* change entity_id to camel casing, remove "backends" key from stored auth data

* fix tokenExpirationEpoch returning NaN, use authSuccess in auth service tests

* camel case mfa_requirement references

* refactor auth service

* implement api service for token method

* implement api service in standard auth methods

* add lookupSelf request to persistAuthData method in auht service instead of calling in components

* implement api service in oidc-jwt component

* implement api service in okta component

* implement api service in saml component

* use api service for wrapped_token query param

* remaining test updates, enterprise tests and stabilize auth helpers

* upate renew() to use new persistAuthData method, add a test

* revert as this will be addressed upstream

* rename supported-login-methods to auth-form-helpers and delete old supported-auth-backends helper, update tests

* cleanup normalize after testing mfa validation for each auth method

* update type declarations, set displayName in each method component

* stabilize redirect tests by waiting for login before asserting url

* stabilize tests

* modernize typescript syntax, move error const to util

* use mirage instead of vault server to resolve test race conditions

* fix file import
2025-07-09 10:11:23 -07:00

121 lines
3.4 KiB
TypeScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import { click, currentRouteName, fillIn, visit, waitUntil } from '@ember/test-helpers';
import VAULT_KEYS from 'vault/tests/helpers/vault-keys';
import { AUTH_FORM } from 'vault/tests/helpers/auth/auth-form-selectors';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
import type { LoginFields } from 'vault/vault/auth/form';
export const { rootToken } = VAULT_KEYS;
// LOGOUT
export const logout = async () => {
// make sure we're always logged out and logged back in
await visit('/vault/logout');
// clear session storage to ensure we have a clean state
window.localStorage.clear();
return;
};
// LOGIN WITH TOKEN
export const login = async (token = rootToken) => {
// make sure we're always logged out and logged back in
await logout();
await visit('/vault/auth');
await fillIn(AUTH_FORM.selectMethod, 'token');
await fillIn(GENERAL.inputByAttr('token'), token);
await click(GENERAL.submitButton);
return await waitUntil(() => currentRouteName() === 'vault.cluster.dashboard');
};
export const loginNs = async (ns: string, token = rootToken) => {
// make sure we're always logged out and logged back in
await logout();
await visit('/vault/auth');
await fillIn(GENERAL.inputByAttr('namespace'), ns);
await fillIn(AUTH_FORM.selectMethod, 'token');
await fillIn(GENERAL.inputByAttr('token'), token);
await click(GENERAL.submitButton);
return await waitUntil(() => currentRouteName() === 'vault.cluster.dashboard');
};
// LOGIN WITH NON-TOKEN METHODS
export const loginMethod = async (
loginFields: LoginFields,
options: { authType?: string; toggleOptions?: boolean }
) => {
// make sure we're always logged out and logged back in
await logout();
const type = options?.authType || 'token';
await fillIn(AUTH_FORM.selectMethod, type);
await fillInLoginFields(loginFields, options);
await click(GENERAL.submitButton);
return await waitUntil(() => currentRouteName() === 'vault.cluster.dashboard');
};
export const fillInLoginFields = async (loginFields: LoginFields, { toggleOptions = false } = {}) => {
if (toggleOptions) await click(AUTH_FORM.advancedSettings);
for (const [input, value] of Object.entries(loginFields)) {
if (value) {
await fillIn(GENERAL.inputByAttr(input), value);
}
}
};
const LOGIN_DATA = {
token: { token: 'mysupersecuretoken' },
username: { username: 'matilda', password: 'some-password' },
role: { role: 'some-dev' },
};
// maps auth type to login input data
export const AUTH_METHOD_LOGIN_DATA = {
// token methods
token: LOGIN_DATA.token,
github: LOGIN_DATA.token,
// username and password methods
userpass: LOGIN_DATA.username,
ldap: LOGIN_DATA.username,
okta: LOGIN_DATA.username,
radius: LOGIN_DATA.username,
// role
oidc: LOGIN_DATA.role,
jwt: LOGIN_DATA.role,
saml: LOGIN_DATA.role,
};
// Mock response for `sys/internal/ui/mounts`
export const SYS_INTERNAL_UI_MOUNTS = {
'userpass/': {
description: '',
options: {},
type: 'userpass',
},
'userpass2/': {
description: '',
options: {},
type: 'userpass',
},
// there was a problem with the API service camel-casing mounts that were snake cased
// so including a snake cased mount for testing
'my_oidc/': {
description: '',
options: {},
type: 'oidc',
},
'ldap/': {
description: '',
options: null,
type: 'ldap',
},
};