Harden live frontdoor authentication harness

This commit is contained in:
master
2026-03-10 07:39:58 +02:00
parent 425bccf10a
commit f0535bcdf6
2 changed files with 43 additions and 7 deletions

View File

@@ -59,6 +59,20 @@ async function waitForShell(page) {
]);
}
async function waitForAuthTransition(page, usernameField, passwordField, timeoutMs = 10_000) {
await Promise.race([
page.waitForURL((url) => url.toString().includes('/connect/authorize') || url.toString().includes('/auth/callback'), {
timeout: timeoutMs,
}).catch(() => {}),
usernameField.waitFor({ state: 'visible', timeout: timeoutMs }).catch(() => {}),
passwordField.waitFor({ state: 'visible', timeout: timeoutMs }).catch(() => {}),
page.waitForFunction(() => Boolean(sessionStorage.getItem('stellaops.auth.session.full')), null, {
timeout: timeoutMs,
}).catch(() => {}),
page.waitForTimeout(timeoutMs),
]);
}
export async function authenticateFrontdoor(options = {}) {
const baseUrl = options.baseUrl?.trim() || DEFAULT_BASE_URL;
const username = options.username?.trim() || DEFAULT_USERNAME;
@@ -134,9 +148,6 @@ export async function authenticateFrontdoor(options = {}) {
'button.cta',
]);
await clickIfVisible(signInTrigger);
await page.waitForTimeout(1_500);
const usernameField = createLocator(page, [
'input[name="username"]',
'input[name="Username"]',
@@ -149,6 +160,13 @@ export async function authenticateFrontdoor(options = {}) {
'input[type="password"]',
]);
const signInClicked = await clickIfVisible(signInTrigger);
if (signInClicked) {
await waitForAuthTransition(page, usernameField, passwordField);
} else {
await page.waitForTimeout(1_500);
}
const hasLoginForm = (await usernameField.count()) > 0 && (await passwordField.count()) > 0;
if (page.url().includes('/connect/authorize') || hasLoginForm) {
const filledUser = await fillIfVisible(usernameField, username);
@@ -168,15 +186,31 @@ export async function authenticateFrontdoor(options = {}) {
await submitButton.click({ timeout: 10_000 });
await page.waitForURL(
(url) => !url.toString().includes('/connect/authorize') && !url.toString().includes('/auth/callback'),
{ timeout: 30_000 },
).catch(() => {});
await Promise.race([
page.waitForURL(
(url) => !url.toString().includes('/connect/authorize') && !url.toString().includes('/auth/callback'),
{ timeout: 30_000 },
).catch(() => {}),
page.waitForFunction(() => Boolean(sessionStorage.getItem('stellaops.auth.session.full')), null, {
timeout: 30_000,
}).catch(() => {}),
]);
}
await waitForShell(page);
await page.waitForTimeout(2_500);
const sessionStatus = await page.evaluate(() => ({
hasFullSession: Boolean(sessionStorage.getItem('stellaops.auth.session.full')),
hasSessionInfo: Boolean(sessionStorage.getItem('stellaops.auth.session.info')),
}));
const signInStillVisible = await signInTrigger.isVisible().catch(() => false);
if (!sessionStatus.hasFullSession || (!page.url().includes('/connect/authorize') && signInStillVisible)) {
throw new Error(
`Frontdoor authentication did not establish a Stella Ops session. finalUrl=${page.url()} signInVisible=${signInStillVisible}`,
);
}
await context.storageState({ path: statePath });
const report = {