UI: Dependency bumps 1.17.x (#26346)

* re-form yarn.lock, remove resolutions that are out of date. resolves:

- mout VAULT-25595 VAULT-25603
- follow-redirects VAULT-25605
- terser VAULT-25594 VAULT-25593
- minimatch VAULT-25591
- loader-utils VAULT-25216 VAULT-25590 VAULT-25589 VAULT-25588 VAULT-25587
- decode-uri-component VAULT-25586
- qs VAULT-25585
- @xmldom/xmldom VAULT-25217

* VAULT-25596 pin async in resolutions due to testem > fireworm

* VAULT-25606 pin nth-check due to ember-svg-jar

* fix typescript errors after bump

* update ember-template-lint to 6.0.0

* Add broken rules to template-eslintrc

* pin ansi-html

* remove ember-d3 in favor of specific d3 libraries we import

* add changelog
This commit is contained in:
Chelsea Shaw
2024-04-12 17:13:45 -05:00
committed by GitHub
parent 1ee302dfcd
commit 52c0dc812b
14 changed files with 2916 additions and 8510 deletions

3
changelog/26346.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:change
ui: Update dependencies including D3 libraries
```

View File

@@ -15,6 +15,11 @@ module.exports = {
},
'require-input-label': 'off',
'no-array-prototype-extensions': 'off',
// from bump to ember-template-lint@6.0.0
'no-builtin-form-components': 'off',
'no-at-ember-render-modifiers': 'off',
'no-unnecessary-curly-strings': 'off',
'no-unnecessary-curly-parens': 'off',
},
overrides: [
{

View File

@@ -35,7 +35,7 @@ export default class LdapLibraryCheckOutRoute extends Route {
}
}
model(_params: object, transition: Transition) {
const { ttl } = transition.to.queryParams;
const ttl = transition.to?.queryParams['ttl'];
const library = this.modelFor('libraries.library') as LdapLibraryModel;
return library.checkOutAccount(ttl);
}

View File

@@ -34,10 +34,9 @@ export default class SyncSecretsDestinationsDestinationRoute extends Route {
// if transitioning from either of the mentioned routes and a purge has been initiated redirect to the secrets view
const baseRoute = 'vault.cluster.sync.secrets.destinations.destination';
const routes = [`${baseRoute}.edit`, `${baseRoute}.sync`];
if (routes.includes(transition.to.name) && model.purgeInitiatedAt) {
// const target = transition.to.name.
// this.flashMessages.info('Actions are ')
const action = transition.to.localName === 'edit' ? 'Editing a destination' : 'Syncing secrets';
const toRoute = transition.to?.name;
if (toRoute && routes.includes(toRoute) && model.purgeInitiatedAt) {
const action = transition.to?.localName === 'edit' ? 'Editing a destination' : 'Syncing secrets';
this.flashMessages.info(`${action} is not permitted once a purge has been initiated.`);
this.router.replaceWith('vault.cluster.sync.secrets.destinations.destination.secrets');
}

View File

@@ -109,13 +109,12 @@
"codemirror": "^5.58.2",
"columnify": "^1.5.4",
"concurrently": "^8.2.2",
"d3-axis": "^1.0.8",
"d3-ease": "^1.0.5",
"d3-scale": "^1.0.7",
"d3-selection": "^1.3.0",
"d3-time-format": "^2.1.1",
"d3-tip": "^0.9.1",
"d3-transition": "^1.2.0",
"d3-array": "^3.2.4",
"d3-axis": "^3.0.0",
"d3-format": "^3.1.0",
"d3-scale": "^4.0.2",
"d3-selection": "^3.0.0",
"d3-shape": "^3.2.0",
"date-fns": "^2.30.0",
"date-fns-tz": "^1.2.2",
"deepmerge": "^4.0.0",
@@ -142,7 +141,6 @@
"ember-composable-helpers": "5.0.0",
"ember-concurrency": "2.3.4",
"ember-copy": "2.0.1",
"ember-d3": "^0.5.1",
"ember-data": "~4.12.4",
"ember-engines": "0.8.23",
"ember-exam": "^9.0.0",
@@ -164,7 +162,7 @@
"ember-source": "~4.12.0",
"ember-style-modifier": "^4.1.0",
"ember-svg-jar": "2.4.0",
"ember-template-lint": "5.7.2",
"ember-template-lint": "^6.0.0",
"ember-template-lint-plugin-prettier": "4.0.0",
"ember-test-selectors": "6.0.0",
"ember-tether": "3.0.0",
@@ -209,16 +207,17 @@
"xstate": "^3.3.3"
},
"resolutions": {
"ansi-html": "^0.0.8",
"async": "^2.6.4",
"eslint-utils": "^1.4.1",
"ember-basic-dropdown": "6.0.1",
"highlight.js": "^10.4.1",
"https-proxy-agent": "^2.2.3",
"ini": "^1.3.6",
"kind-of": "^6.0.3",
"minimatch": "^3.0.2",
"node-notifier": "^8.0.1",
"nth-check": "^2.0.1",
"prismjs": "^1.21.0",
"qs": "^6.3.0",
"serialize-javascript": "^3.1.0",
"underscore": "^1.12.1",
"xmlhttprequest-ssl": "^1.6.2",

View File

@@ -4,6 +4,7 @@
*/
import { currentRouteName, find, settled, waitUntil } from '@ember/test-helpers';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
import page from 'vault/tests/pages/access/identity/aliases/add';
import aliasIndexPage from 'vault/tests/pages/access/identity/aliases/index';
import aliasShowPage from 'vault/tests/pages/access/identity/aliases/show';
@@ -61,10 +62,7 @@ export const testAliasCRUD = async function (name, itemType, assert) {
await settled();
await aliasIndexPage.confirmDelete();
await settled();
assert.ok(
aliasIndexPage.flashMessage.latestMessage.startsWith('Successfully deleted'),
`${itemType}: shows flash message`
);
assert.dom(GENERAL.latestFlashContent).includesText(`Successfully deleted`);
assert.strictEqual(
aliasIndexPage.items.filterBy('id', aliasID).length,
@@ -109,10 +107,7 @@ export const testAliasDeleteFromForm = async function (name, itemType, assert) {
await page.editForm.waitForConfirm();
await page.editForm.confirmDelete();
await settled();
assert.ok(
aliasIndexPage.flashMessage.latestMessage.startsWith('Successfully deleted'),
`${itemType}: shows flash message`
);
assert.dom(GENERAL.latestFlashContent).includesText(`Successfully deleted`);
assert.strictEqual(
currentRouteName(),
'vault.cluster.access.identity.aliases.index',

View File

@@ -8,6 +8,7 @@ import { selectChoose, clickTrigger } from 'ember-power-select/test-support/help
import page from 'vault/tests/pages/access/identity/create';
import showPage from 'vault/tests/pages/access/identity/show';
import indexPage from 'vault/tests/pages/access/identity/index';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
const SELECTORS = {
identityRow: (name) => `[data-test-identity-row="${name}"]`,
popupMenu: '[data-test-popup-menu-trigger]',
@@ -18,10 +19,7 @@ export const testCRUD = async (name, itemType, assert) => {
await settled();
await page.editForm.name(name).submit();
await settled();
assert.ok(
showPage.flashMessage.latestMessage.startsWith('Successfully saved'),
`${itemType}: shows a flash message`
);
assert.dom(GENERAL.latestFlashContent).includesText('Successfully saved');
assert.strictEqual(
currentRouteName(),
'vault.cluster.access.identity.show',
@@ -41,10 +39,7 @@ export const testCRUD = async (name, itemType, assert) => {
await click(SELECTORS.menuDelete);
await indexPage.confirmDelete();
await settled();
assert.ok(
indexPage.flashMessage.latestMessage.startsWith('Successfully deleted'),
`${itemType}: shows flash message`
);
assert.dom(GENERAL.latestFlashContent).includesText('Successfully deleted');
assert.strictEqual(indexPage.items.filterBy('name', name).length, 0, `${itemType}: the row is deleted`);
};
@@ -73,10 +68,7 @@ export const testDeleteFromForm = async (name, itemType, assert) => {
await settled();
await page.editForm.confirmDelete();
await settled();
assert.ok(
indexPage.flashMessage.latestMessage.startsWith('Successfully deleted'),
`${itemType}: shows flash message`
);
assert.dom(GENERAL.latestFlashContent).includesText('Successfully deleted');
assert.strictEqual(
currentRouteName(),
'vault.cluster.access.identity.index',

View File

@@ -3,23 +3,12 @@
* SPDX-License-Identifier: BUSL-1.1
*/
import { waitFor } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import initPage from 'vault/tests/pages/init';
import Pretender from 'pretender';
import { setRunOptions } from 'ember-a11y-testing/test-support';
const HEALTH_RESPONSE = {
initialized: false,
sealed: true,
standby: true,
performance_standby: false,
replication_performance_mode: 'unknown',
replication_dr_mode: 'unknown',
server_time_utc: 1538066726,
version: '1.13.0-dev1',
};
import { setupMirage } from 'ember-cli-mirage/test-support';
import initPage from 'vault/tests/pages/init';
const CLOUD_SEAL_RESPONSE = {
keys: [],
@@ -83,28 +72,7 @@ const assertRequest = (req, assert, isCloud) => {
module('Acceptance | init', function (hooks) {
setupApplicationTest(hooks);
const setInitResponse = (server, resp) => {
server.put('/v1/sys/init', () => {
return [200, { 'Content-Type': 'application/json' }, JSON.stringify(resp)];
});
};
const setStatusResponse = (server, resp) => {
server.get('/v1/sys/seal-status', () => {
return [200, { 'Content-Type': 'application/json' }, JSON.stringify(resp)];
});
};
hooks.beforeEach(function () {
this.server = new Pretender();
this.server.get('/v1/sys/health', () => {
return [200, { 'Content-Type': 'application/json' }, JSON.stringify(HEALTH_RESPONSE)];
});
this.server.get('/v1/sys/internal/ui/feature-flags', this.server.passthrough);
});
hooks.afterEach(function () {
this.server.shutdown();
});
setupMirage(hooks);
test('cloud seal init', async function (assert) {
// continue button is disabled, violating color-contrast
@@ -114,39 +82,38 @@ module('Acceptance | init', function (hooks) {
},
});
assert.expect(6);
setInitResponse(this.server, CLOUD_SEAL_RESPONSE);
setStatusResponse(this.server, CLOUD_SEAL_STATUS_RESPONSE);
this.server.put('/sys/init', (schema, req) => {
assertRequest(req, assert, true);
return CLOUD_SEAL_RESPONSE;
});
this.server.get('/sys/seal-status', () => {
return CLOUD_SEAL_STATUS_RESPONSE;
});
await initPage.init(5, 3);
await waitFor('[data-test-advance-button]');
assert.strictEqual(
initPage.keys.length,
CLOUD_SEAL_RESPONSE.recovery_keys.length,
'shows all of the recovery keys'
);
assert.strictEqual(initPage.buttonText, 'Continue to Authenticate', 'links to authenticate');
assertRequest(
this.server.handledRequests.find((req) => req.url === '/v1/sys/init'),
assert,
true
);
});
test('shamir seal init', async function (assert) {
assert.expect(6);
setInitResponse(this.server, SEAL_RESPONSE);
setStatusResponse(this.server, SEAL_STATUS_RESPONSE);
this.server.put('/sys/init', (schema, req) => {
assertRequest(req, assert, false);
return SEAL_RESPONSE;
});
this.server.get('/sys/seal-status', () => {
return SEAL_STATUS_RESPONSE;
});
await initPage.init(3, 2);
await waitFor('[data-test-advance-button]');
assert.strictEqual(initPage.keys.length, SEAL_RESPONSE.keys.length, 'shows all of the recovery keys');
assert.strictEqual(initPage.buttonText, 'Continue to Unseal', 'links to unseal');
assertRequest(
this.server.handledRequests.find((r) => r.url === '/v1/sys/init'),
assert,
false
);
});
});

View File

@@ -5,7 +5,7 @@
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { currentURL, settled, click, visit, fillIn, typeIn } from '@ember/test-helpers';
import { currentURL, settled, click, visit, fillIn, typeIn, waitFor } from '@ember/test-helpers';
import { create } from 'ember-cli-page-object';
import { selectChoose, clickTrigger } from 'ember-power-select/test-support/helpers';
@@ -289,6 +289,7 @@ module('Acceptance | secrets/database/*', function (hooks) {
.hasText('Rotate your root credentials?', 'Modal appears asking to rotate root credentials');
assert.dom('[data-test-enable-connection]').exists('Enable button exists');
await click('[data-test-enable-connection]');
await waitFor('[data-test-component="info-table-row"]');
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/show/${testCase.name}`),
`Saves connection and takes you to show page for ${testCase.name}`

View File

@@ -174,6 +174,7 @@ module('Acceptance | tools', function (hooks) {
await fillIn('[data-test-tools-input="wrapping-token"]', 'sometoken');
await click('[data-test-tools-submit]');
await waitFor('.CodeMirror');
assert.deepEqual(
JSON.parse(codemirror().getValue()),
AUTH_RESPONSE.auth,

View File

@@ -15,6 +15,8 @@ export const GENERAL = {
icon: (name: string) => `[data-test-icon="${name}"]`,
tab: (name: string) => `[data-test-tab="${name}"]`,
secretTab: (name: string) => `[data-test-secret-list-tab="${name}"]`,
flashMessage: '[data-test-flash-message]',
latestFlashContent: '[data-test-flash-message]:last-of-type [data-test-flash-message-body]',
filter: (name: string) => `[data-test-filter="${name}"]`,
filterInput: '[data-test-filter-input]',

View File

@@ -12,10 +12,11 @@ import { setupRenderingTest } from 'ember-qunit';
import { render, settled } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import sinon from 'sinon';
import Pretender from 'pretender';
import { create } from 'ember-cli-page-object';
import authForm from '../../pages/components/auth-form';
import { validate } from 'uuid';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { Response } from 'miragejs';
const component = create(authForm);
@@ -39,6 +40,7 @@ const routerService = Service.extend({
module('Integration | Component | auth form', function (hooks) {
setupRenderingTest(hooks);
setupMirage(hooks);
hooks.beforeEach(function () {
this.owner.register('service:router', routerService);
@@ -60,35 +62,21 @@ module('Integration | Component | auth form', function (hooks) {
test('it renders with vault style errors', async function (assert) {
assert.expect(1);
const server = new Pretender(function () {
this.get('/v1/auth/**', () => {
return [
400,
{ 'Content-Type': 'application/json' },
JSON.stringify({
errors: ['Not allowed'],
}),
];
});
this.get('/v1/sys/internal/ui/mounts', this.passthrough);
this.server.get('/auth/token/lookup-self', () => {
return new Response(400, { 'Content-Type': 'application/json' }, { errors: ['Not allowed'] });
});
this.set('cluster', EmberObject.create({}));
this.set('selectedAuth', 'token');
await render(hbs`<AuthForm @cluster={{this.cluster}} @selectedAuth={{this.selectedAuth}} />`);
return component.login().then(() => {
assert.strictEqual(component.errorText, 'Error Authentication failed: Not allowed');
server.shutdown();
});
await component.login();
assert.strictEqual(component.errorText, 'Error Authentication failed: Not allowed');
});
test('it renders AdapterError style errors', async function (assert) {
assert.expect(1);
const server = new Pretender(function () {
this.get('/v1/auth/**', () => {
return [400, { 'Content-Type': 'application/json' }, JSON.stringify({ errors: ['API Error here'] })];
});
this.get('/v1/sys/internal/ui/mounts', this.passthrough);
this.server.get('/auth/token/lookup-self', () => {
return new Response(400, { 'Content-Type': 'application/json' }, { errors: ['API Error here'] });
});
this.set('cluster', EmberObject.create({}));
@@ -100,7 +88,6 @@ module('Integration | Component | auth form', function (hooks) {
'Error Authentication failed: API Error here',
'shows the error from the API'
);
server.shutdown();
});
});
@@ -110,10 +97,8 @@ module('Integration | Component | auth form', function (hooks) {
type: 'approle',
},
};
const server = new Pretender(function () {
this.get('/v1/sys/internal/ui/mounts', () => {
return [200, { 'Content-Type': 'application/json' }, JSON.stringify({ data: { auth: methods } })];
});
this.server.get('/sys/internal/ui/mounts', () => {
return { data: { auth: methods } };
});
await render(hbs`<AuthForm @cluster={{this.cluster}} />`);
@@ -130,19 +115,15 @@ module('Integration | Component | auth form', function (hooks) {
type: 'approle',
},
};
const server = new Pretender(function () {
this.get('/v1/sys/internal/ui/mounts', () => {
return [200, { 'Content-Type': 'application/json' }, JSON.stringify({ data: { auth: methods } })];
});
this.server.get('/sys/internal/ui/mounts', () => {
return { data: { auth: methods } };
});
this.set('cluster', EmberObject.create({}));
await render(hbs`<AuthForm @cluster={{this.cluster}} />`);
assert.strictEqual(component.tabs.length, 2, 'renders a tab for userpass and Other');
assert.strictEqual(component.tabs.objectAt(0).name, 'foo', 'uses the path in the label');
assert.strictEqual(component.tabs.objectAt(1).name, 'Other', 'second tab is the Other tab');
server.shutdown();
});
test('it renders the description', async function (assert) {
@@ -152,10 +133,8 @@ module('Integration | Component | auth form', function (hooks) {
description: 'app description',
},
};
const server = new Pretender(function () {
this.get('/v1/sys/internal/ui/mounts', () => {
return [200, { 'Content-Type': 'application/json' }, JSON.stringify({ data: { auth: methods } })];
});
this.server.get('/sys/internal/ui/mounts', () => {
return { data: { auth: methods } };
});
this.set('cluster', EmberObject.create({}));
await render(hbs`<AuthForm @cluster={{this.cluster}} />`);
@@ -165,7 +144,6 @@ module('Integration | Component | auth form', function (hooks) {
'app description',
'renders a description for auth methods'
);
server.shutdown();
});
test('it calls authenticate with the correct path', async function (assert) {
@@ -178,10 +156,8 @@ module('Integration | Component | auth form', function (hooks) {
type: 'userpass',
},
};
const server = new Pretender(function () {
this.get('/v1/sys/internal/ui/mounts', () => {
return [200, { 'Content-Type': 'application/json' }, JSON.stringify({ data: { auth: methods } })];
});
this.server.get('/sys/internal/ui/mounts', () => {
return { data: { auth: methods } };
});
this.set('cluster', EmberObject.create({}));
@@ -194,7 +170,6 @@ module('Integration | Component | auth form', function (hooks) {
const { data } = authSpy.getCall(0).args[0];
assert.strictEqual(data.path, 'foo', 'uses the id for the path');
authSpy.restore();
server.shutdown();
});
test('it renders no tabs when no supported methods are present in passed methods', async function (assert) {
@@ -203,10 +178,8 @@ module('Integration | Component | auth form', function (hooks) {
type: 'approle',
},
};
const server = new Pretender(function () {
this.get('/v1/sys/internal/ui/mounts', () => {
return [200, { 'Content-Type': 'application/json' }, JSON.stringify({ data: { auth: methods } })];
});
this.server.get('/sys/internal/ui/mounts', () => {
return { data: { auth: methods } };
});
this.set('cluster', EmberObject.create({}));
await render(hbs`<AuthForm @cluster={{this.cluster}} />`);
@@ -216,21 +189,22 @@ module('Integration | Component | auth form', function (hooks) {
});
test('it makes a request to unwrap if passed a wrappedToken and logs in', async function (assert) {
assert.expect(3);
this.owner.register('service:auth', workingAuthService);
this.auth = this.owner.lookup('service:auth');
const authSpy = sinon.spy(this.auth, 'authenticate');
const server = new Pretender(function () {
this.post('/v1/sys/wrapping/unwrap', () => {
return [
200,
{ 'content-type': 'application/json' },
JSON.stringify({
auth: {
client_token: '12345',
},
}),
];
});
const authSpy = sinon.stub(this.auth, 'authenticate');
this.server.post('/sys/wrapping/unwrap', (_, req) => {
assert.strictEqual(req.url, '/v1/sys/wrapping/unwrap', 'makes call to unwrap the token');
assert.strictEqual(
req.requestHeaders['X-Vault-Token'],
wrappedToken,
'uses passed wrapped token for the unwrap'
);
return {
auth: {
client_token: '12345',
},
};
});
const wrappedToken = '54321';
@@ -241,32 +215,17 @@ module('Integration | Component | auth form', function (hooks) {
);
later(() => cancelTimers(), 50);
await settled();
assert.strictEqual(
server.handledRequests[0].url,
'/v1/sys/wrapping/unwrap',
'makes call to unwrap the token'
);
assert.strictEqual(
server.handledRequests[0].requestHeaders['x-vault-token'],
wrappedToken,
'uses passed wrapped token for the unwrap'
);
assert.ok(authSpy.calledOnce, 'a call to authenticate was made');
server.shutdown();
authSpy.restore();
});
test('it shows an error if unwrap errors', async function (assert) {
const server = new Pretender(function () {
this.post('/v1/sys/wrapping/unwrap', () => {
return [
400,
{ 'Content-Type': 'application/json' },
JSON.stringify({
errors: ['There was an error unwrapping!'],
}),
];
});
this.server.post('/sys/wrapping/unwrap', () => {
return new Response(
400,
{ 'Content-Type': 'application/json' },
{ errors: ['There was an error unwrapping!'] }
);
});
this.set('wrappedToken', '54321');
@@ -279,32 +238,27 @@ module('Integration | Component | auth form', function (hooks) {
'Error Token unwrap failed: There was an error unwrapping!',
'shows the error'
);
server.shutdown();
});
test('it should retain oidc role when mount path is changed', async function (assert) {
assert.expect(1);
assert.expect(2);
const auth_url = 'http://dev-foo-bar.com';
const server = new Pretender(function () {
this.post('/v1/auth/:path/oidc/auth_url', (req) => {
const { role, redirect_uri } = JSON.parse(req.requestBody);
const goodRequest =
req.params.path === 'foo-oidc' &&
role === 'foo' &&
redirect_uri.includes('/auth/foo-oidc/oidc/callback');
this.server.post('/auth/:path/oidc/auth_url', (_, req) => {
const { role, redirect_uri } = JSON.parse(req.requestBody);
const goodRequest =
req.params.path === 'foo-oidc' &&
role === 'foo' &&
redirect_uri.includes('/auth/foo-oidc/oidc/callback');
return [
goodRequest ? 200 : 400,
{ 'Content-Type': 'application/json' },
JSON.stringify(
goodRequest ? { data: { auth_url } } : { errors: [`role "${role}" could not be found`] }
),
];
});
this.get('/v1/sys/internal/ui/mounts', this.passthrough);
return new Response(
goodRequest ? 200 : 400,
{ 'Content-Type': 'application/json' },
JSON.stringify(
goodRequest ? { data: { auth_url } } : { errors: [`role "${role}" could not be found`] }
)
);
});
window.open = (url) => {
assert.strictEqual(url, auth_url, 'auth_url is returned when required params are passed');
};
@@ -322,29 +276,21 @@ module('Integration | Component | auth form', function (hooks) {
await component.oidcRole('foo');
await component.oidcMoreOptions();
await component.oidcMountPath('foo-oidc');
assert.dom('[data-test-role]').hasValue('foo', 'role is retained when mount path is changed');
await component.login();
server.shutdown();
});
test('it should set nonce value as uuid for okta method type', async function (assert) {
assert.expect(1);
const server = new Pretender(function () {
this.post('/v1/auth/okta/login/foo', (req) => {
const { nonce } = JSON.parse(req.requestBody);
assert.true(validate(nonce), 'Nonce value passed as uuid for okta login');
return [
200,
{ 'content-type': 'application/json' },
JSON.stringify({
auth: {
client_token: '12345',
},
}),
];
});
this.get('/v1/sys/internal/ui/mounts', this.passthrough);
this.server.post('/auth/okta/login/foo', (_, req) => {
const { nonce } = JSON.parse(req.requestBody);
assert.true(validate(nonce), 'Nonce value passed as uuid for okta login');
return {
auth: {
client_token: '12345',
},
};
});
this.set('cluster', EmberObject.create({}));
@@ -354,7 +300,5 @@ module('Integration | Component | auth form', function (hooks) {
await component.username('foo');
await component.password('bar');
await component.login();
server.shutdown();
});
});

View File

@@ -4,11 +4,10 @@
*/
import { run } from '@ember/runloop';
import { copy } from 'ember-copy';
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { TOKEN_SEPARATOR, TOKEN_PREFIX, ROOT_PREFIX } from 'vault/services/auth';
import Pretender from 'pretender';
import { setupMirage } from 'ember-cli-mirage/test-support';
function storage() {
return {
@@ -126,43 +125,28 @@ const GITHUB_RESPONSE = {
module('Integration | Service | auth', function (hooks) {
setupTest(hooks);
setupMirage(hooks);
hooks.beforeEach(function () {
this.owner.lookup('service:flash-messages').registerTypes(['warning']);
this.store = storage();
this.memStore = storage();
this.server = new Pretender(function () {
this.get('/v1/auth/token/lookup-self', function (request) {
const resp = copy(ROOT_TOKEN_RESPONSE, true);
resp.id = request.requestHeaders['x-vault-token'];
resp.data.id = request.requestHeaders['x-vault-token'];
return [200, {}, resp];
});
this.post('/v1/auth/userpass/login/:username', function (request) {
const { username } = request.params;
const resp = copy(USERPASS_RESPONSE, true);
resp.auth.metadata.username = username;
return [200, {}, resp];
});
this.post('/v1/auth/github/login', function () {
const resp = copy(GITHUB_RESPONSE, true);
return [200, {}, resp];
});
this.server.get('/auth/token/lookup-self', function (_, request) {
const resp = { ...ROOT_TOKEN_RESPONSE };
resp.id = request.requestHeaders['X-Vault-Token'];
resp.data.id = request.requestHeaders['X-Vault-Token'];
return resp;
});
this.server.post('/auth/userpass/login/:username', function (_, request) {
const { username } = request.params;
const resp = { ...USERPASS_RESPONSE };
resp.auth.metadata.username = username;
return resp;
});
this.server.prepareBody = function (body) {
return body ? JSON.stringify(body) : '{"error": "not found"}';
};
this.server.prepareHeaders = function (headers) {
headers['content-type'] = 'application/javascript';
return headers;
};
});
hooks.afterEach(function () {
this.server.shutdown();
this.server.post('/auth/github/login', function () {
return { ...GITHUB_RESPONSE };
});
});
test('token authentication: root token', function (assert) {
@@ -318,13 +302,11 @@ module('Integration | Service | auth', function (hooks) {
test('token auth expiry with non-root token', function (assert) {
assert.expect(5);
const tokenResp = TOKEN_NON_ROOT_RESPONSE();
this.server.map(function () {
this.get('/v1/auth/token/lookup-self', function (request) {
const resp = copy(tokenResp, true);
resp.id = request.requestHeaders['x-vault-token'];
resp.data.id = request.requestHeaders['x-vault-token'];
return [200, {}, resp];
});
this.server.get('/auth/token/lookup-self', function (_, request) {
const resp = { ...tokenResp };
resp.id = request.requestHeaders['X-Vault-Token'];
resp.data.id = request.requestHeaders['X-Vault-Token'];
return resp;
});
const done = assert.async();

11042
ui/yarn.lock

File diff suppressed because it is too large Load Diff