Some checks failed
Use-case regression gate / usecase-regressions (push) Has been cancelled
Exercise reset, registration and invitation against an isolated issuer and mailbox. The nodes stay unestablished and do not contact production. Assistant: grok Assistant-Session: 01a12cc2-e3b2-77a3-8aef-9cc60e577fee
145 lines
7.1 KiB
JavaScript
145 lines
7.1 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { chromium } from 'playwright';
|
|
|
|
const [appUrl, issuerUrl, password] = process.argv.slice(2);
|
|
const app = new URL(appUrl);
|
|
const issuer = new URL(issuerUrl);
|
|
for (const base of [app, issuer]) {
|
|
if (base.protocol !== 'http:' || !['localhost', '127.0.0.1'].includes(base.hostname)) {
|
|
throw new Error('Communication checks require isolated loopback servers');
|
|
}
|
|
}
|
|
const allowed = new Set([app.origin, issuer.origin]);
|
|
const browser = await chromium.launch({headless: true});
|
|
try {
|
|
const context = await browser.newContext();
|
|
const aborted = [];
|
|
await context.route('**/*', route => {
|
|
const origin = new URL(route.request().url()).origin;
|
|
if (allowed.has(origin)) return route.continue();
|
|
aborted.push(route.request().url());
|
|
return route.abort();
|
|
});
|
|
const page = await context.newPage();
|
|
page.setDefaultTimeout(10000);
|
|
let callbackUrl = '';
|
|
page.on('request', request => {
|
|
const url = request.url();
|
|
if (url.includes('/auth/callback/') && !callbackUrl) callbackUrl = url;
|
|
});
|
|
|
|
await page.goto(`${issuer.origin}/recover`);
|
|
await page.getByRole('button', {name: 'Send reset'}).click();
|
|
await page.getByRole('link', {name: 'Open mailbox'}).click();
|
|
const mailboxText = await page.locator('main').innerText();
|
|
assert.match(mailboxText, /Local mailbox/);
|
|
assert.doesNotMatch(mailboxText, /handle=/);
|
|
assert.equal(mailboxText.includes(password), false);
|
|
await page.getByRole('button', {name: 'Use reset', exact: true}).click();
|
|
await page.getByLabel('Password').fill(password);
|
|
await page.getByRole('button', {name: 'Save password'}).click();
|
|
assert.match(await page.locator('main').innerText(), /Password updated/);
|
|
assert.equal((await page.locator('main').innerText()).includes(password), false);
|
|
|
|
await page.goto(app.origin + '/');
|
|
await page.locator('main').getByRole('link', {name: 'Sign in', exact: true}).click();
|
|
await page.waitForURL(url => url.origin === issuer.origin && url.pathname === '/authorize');
|
|
await page.getByRole('button', {name: 'Continue'}).click();
|
|
await page.waitForURL('**/app/');
|
|
assert.ok(callbackUrl);
|
|
await page.goto(app.origin + '/account/session/');
|
|
const sessionText = await page.locator('main').innerText();
|
|
const sessionHtml = await page.content();
|
|
const resetCode = new URL(callbackUrl).searchParams.get('code');
|
|
assert.match(sessionText, /member-recovered/);
|
|
assert.match(sessionText, /member@example\.test/);
|
|
assert.equal(sessionText.includes(password), false);
|
|
assert.equal(sessionHtml.includes(password), false);
|
|
assert.equal(sessionHtml.includes(resetCode), false);
|
|
|
|
const replay = await page.goto(callbackUrl);
|
|
assert.equal(replay.status(), 400);
|
|
assert.match(await page.locator('body').innerText(), /Invalid OIDC callback state/);
|
|
|
|
await page.goto(`${issuer.origin}/recover?expired=1`);
|
|
await page.getByRole('button', {name: 'Send reset'}).click();
|
|
await page.getByRole('link', {name: 'Open mailbox'}).click();
|
|
await page.getByRole('button', {name: 'Use expired reset'}).click();
|
|
assert.match(await page.locator('main').innerText(), /Handle expired/);
|
|
|
|
await page.goto(app.origin + '/auth/logout/');
|
|
await page.waitForURL(app.origin + '/');
|
|
await page.locator('main').getByRole('link', {name: 'Sign in', exact: true}).click();
|
|
await page.getByLabel('Subject').fill('member-other');
|
|
await page.getByLabel('Name').fill('Other Member');
|
|
await page.getByLabel('Email').fill('member@example.test');
|
|
await page.getByRole('button', {name: 'Continue'}).click();
|
|
await page.waitForURL('**/app/');
|
|
await page.goto(app.origin + '/account/session/');
|
|
const other = await page.locator('main').innerText();
|
|
assert.match(other, /member-other/);
|
|
assert.doesNotMatch(other, /member-recovered/);
|
|
await page.goto(app.origin + '/auth/logout/');
|
|
await page.waitForURL(app.origin + '/');
|
|
|
|
await page.goto(app.origin + '/auth/register/');
|
|
await page.waitForURL(`${issuer.origin}/register`);
|
|
assert.match(await page.locator('main').innerText(), /Registration sink/);
|
|
await page.getByRole('button', {name: 'Send verification'}).click();
|
|
await page.getByRole('link', {name: 'Open mailbox'}).click();
|
|
await page.getByRole('button', {name: 'Cancel verification'}).click();
|
|
assert.match(await page.locator('main').innerText(), /Handle cancelled/);
|
|
await page.goto(`${issuer.origin}/mailbox`);
|
|
assert.match(await page.locator('main').innerText(), /verification cancelled/);
|
|
assert.equal(await page.getByRole('button', {name: 'Use verification'}).count(), 0);
|
|
await page.goto(`${issuer.origin}/register`);
|
|
await page.getByRole('button', {name: 'Send verification'}).click();
|
|
await page.getByRole('link', {name: 'Open mailbox'}).click();
|
|
await page.getByRole('button', {name: 'Use verification'}).click();
|
|
assert.match(await page.locator('main').innerText(), /Verification consumed/);
|
|
assert.match(await page.locator('main').innerText(), /does not sign in/);
|
|
await page.goto(app.origin + '/');
|
|
assert.equal(
|
|
await page.locator('main').getByRole('link', {name: 'Sign in', exact: true}).count(),
|
|
1,
|
|
);
|
|
|
|
const refused = new URL('/authorize', issuer.origin);
|
|
refused.searchParams.set('client_id', 'intruder');
|
|
refused.searchParams.set('redirect_uri', 'http://127.0.0.1:9/callback');
|
|
refused.searchParams.set('response_type', 'code');
|
|
refused.searchParams.set('state', 'x');
|
|
refused.searchParams.set('code_challenge', 'not-used');
|
|
refused.searchParams.set('code_challenge_method', 'S256');
|
|
await page.goto(refused.toString());
|
|
assert.match(await page.locator('main').innerText(), /Client refused/);
|
|
|
|
await page.goto(app.origin + '/');
|
|
await page.locator('main').getByRole('link', {name: 'Sign in', exact: true}).click();
|
|
await page.getByLabel('Tenant').fill('tenant:other');
|
|
await page.getByRole('button', {name: 'Continue'}).click();
|
|
assert.match(await page.locator('main').innerText(), /Tenant refused/);
|
|
|
|
await page.goto(`${issuer.origin}/invite`);
|
|
await page.getByLabel('Caller').fill('intruder');
|
|
await page.getByRole('button', {name: 'Send invitation'}).click();
|
|
assert.match(await page.locator('main').innerText(), /Caller refused/);
|
|
await page.goto(`${issuer.origin}/invite`);
|
|
await page.getByLabel('Caller').fill('coulomb-social-test');
|
|
await page.getByLabel('Suppress').check();
|
|
await page.getByRole('button', {name: 'Send invitation'}).click();
|
|
assert.match(await page.locator('main').innerText(), /Invitation suppressed/);
|
|
await page.goto(`${issuer.origin}/invite`);
|
|
await page.getByLabel('Caller').fill('coulomb-social-test');
|
|
await page.getByRole('button', {name: 'Send invitation'}).click();
|
|
await page.getByRole('link', {name: 'Open mailbox'}).click();
|
|
await page.goto(`${issuer.origin}/invite`);
|
|
await page.getByLabel('Caller').fill('coulomb-social-test');
|
|
await page.getByRole('button', {name: 'Send invitation'}).click();
|
|
await page.getByRole('link', {name: 'Open mailbox'}).click();
|
|
assert.equal(await page.getByRole('button', {name: 'Open invitation'}).count(), 2);
|
|
assert.equal(aborted.length, 0);
|
|
console.log('Isolated recovery, registration and invitation journey passed');
|
|
} finally {
|
|
await browser.close();
|
|
}
|