Files
Investidor-V2/tools/portal-qa-credential-browser-check.cjs
nala 287e991486
tests / ci (push) Waiting to run
oportunidades 7
2026-10-13 11:40:29 +02:00

131 lines
4.6 KiB
JavaScript

/** Read the local credential; stop at the normal MFA challenge, without submitting a code. */
const fs = require('node:fs');
const path = require('node:path');
const {
chromium,
} = require('C:/Users/macbook/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright');
const root = path.resolve(__dirname, '..');
const directory = path.join(
root,
'storage/app/private/investmoz-v2/portal-audit',
);
const base = 'http://127.0.0.1:18097';
const target = 'desk_restore_20261009_174726_test:55441';
const credential = JSON.parse(
fs.readFileSync(
path.join(directory, 'investor-mfa-qa-private.json'),
'utf8',
),
);
const proof = {
captured_at: new Date().toISOString(),
base,
target,
account_id: 18,
isolated_browser_context: true,
events: [],
last_step: 'initialize',
password_changed: false,
mfa_changed: false,
mfa_code_submitted: false,
active_writes: 0,
};
let browser;
(async () => {
if (
credential.actor_id !== 18 ||
credential.email !== 'investor-mfa-qa@example.invalid'
)
throw new Error();
browser = await chromium.launch({
headless: true,
executablePath:
'C:/Users/macbook/AppData/Local/ms-playwright/chromium-1243/chrome-win64/chrome.exe',
});
const context = await browser.newContext({ locale: 'pt-MZ' });
let confirmed = false;
await context.route('**/*', async (route) => {
const request = route.request();
if (
new URL(request.url()).origin !== base ||
(!['GET', 'HEAD'].includes(request.method()) &&
(!confirmed || new URL(request.url()).pathname !== '/login'))
) {
return route.abort();
}
await route.continue();
});
const page = await context.newPage();
page.on('response', (response) => {
const request = response.request(),
url = new URL(response.url());
if (['/login', '/two-factor-challenge'].includes(url.pathname)) {
const headers = response.headers();
proof.events.push({
method: request.method(),
path: url.pathname,
status: response.status(),
target: headers['x-investmoz-qa-target'] || null,
redirect_path: headers.location
? new URL(headers.location, base).pathname
: null,
});
}
});
proof.last_step = 'load_login';
const response = await page.goto(base + '/login', {
waitUntil: 'networkidle',
});
if ((await response.allHeaders())['x-investmoz-qa-target'] !== target)
throw new Error();
confirmed = true;
await page.locator('[aria-label="Conta de ensaio QA"]').waitFor();
proof.qa18_notice_visible = (
await page.locator('[aria-label="Conta de ensaio QA"]').innerText()
).includes('conta 18');
proof.last_step = 'submit_local_credential';
await page.locator('#email').fill(credential.email);
await page.locator('#password').fill(credential.password);
await page.locator('[data-test="login-button"]').click();
await page.waitForURL(base + '/two-factor-challenge', { timeout: 20000 });
proof.last_step = 'normal_mfa_challenge_visible';
proof.final_path = new URL(page.url()).pathname;
proof.account18_mfa_visible = (
await page.locator('body').innerText()
).includes(credential.email);
proof.passed = proof.qa18_notice_visible && proof.account18_mfa_visible;
proof.cookie_attributes = (await context.cookies()).map(
({ name, domain, path, secure, httpOnly, sameSite }) => ({
name,
domain,
path,
secure,
httpOnly,
sameSite,
}),
);
await context.close();
})()
.catch(() => {
// Playwright errors can include filled input values: never export their messages/stacks.
proof.passed = false;
proof.error =
'Browser check failed; credential values and error details withheld.';
process.exitCode = 1;
})
.finally(async () => {
if (browser) await browser.close();
credential.password = undefined;
credential.totp_secret = undefined;
const name =
'investor-credential-browser-' +
proof.captured_at.replace(/[^0-9TZ-]/g, '-') +
'.json';
fs.writeFileSync(
path.join(directory, name),
JSON.stringify(proof, null, 2),
{ mode: 0o600 },
);
console.log(JSON.stringify(proof));
});