ci(windows-smoke): login tokens move to the keychain and stay signed in (cinny #105) #45

Merged
jared merged 1 commits from ci/smoke-keychain into main 2026-10-23 20:34:18 -04:00
Showing only changes of commit ad8c362854 - Show all commits
+65
View File
@@ -375,6 +375,71 @@ record(
}; app still responsive: ${alive}`,
);
// 11. Login tokens only in the keychain (cinny #105 step 2). Simulate an
// install from before step 2: a full session in localStorage, pointed at an
// unreachable server so nothing ever rejects (and logs out) the fake token.
// After a reload the tokens must have moved: localStorage keeps a token-less
// shell, Credential Manager holds them; after another reload the app is still
// signed in. Builds without step 2 only mirror (tokens stay): n/a.
{
const name = 'login tokens move to the keychain and stay signed in (#105)';
const KEY = 'cinny_session_v1';
const fake = {
accessToken: `syt_smoke_${Date.now()}`,
refreshToken: 'mar_smoke',
deviceId: 'SMOKEDEV',
userId: '@smoke:ci.invalid',
baseUrl: 'https://127.0.0.1:9',
};
const state = () =>
page.evaluate(async (k) => {
const blob = JSON.parse(localStorage.getItem(k) ?? 'null');
const kc = await window.__TAURI_INTERNALS__.invoke('secure_session_get').catch(() => null);
return {
tokensIn: blob?.tokensIn,
blobHasToken: typeof blob?.accessToken === 'string',
legacyToken: localStorage.getItem('cinny_access_token') !== null,
kcToken: kc?.accessToken ?? null,
loginScreen: /Username or email/.test(document.body.innerText),
};
}, KEY);
try {
await page.evaluate(([k, f]) => localStorage.setItem(k, JSON.stringify(f)), [KEY, fake]);
await page.reload();
const moved = await until(async () => {
const st = await state();
return st.tokensIn === 'keychain' || (st.blobHasToken && st.kcToken === fake.accessToken) ? st : undefined;
}, 30_000);
if (moved && moved.tokensIn !== 'keychain') {
record(name, 'n/a', 'build mirrors the tokens but keeps them in localStorage (before step 2)');
} else {
await page.reload();
await new Promise((r) => setTimeout(r, 8000));
const after = await state();
const ok =
moved &&
!moved.blobHasToken &&
!moved.legacyToken &&
moved.kcToken === fake.accessToken &&
after.tokensIn === 'keychain' &&
after.kcToken === fake.accessToken &&
!after.loginScreen;
record(name, ok ? 'pass' : 'fail', `after migration: ${JSON.stringify(moved)}; after restart: ${JSON.stringify(after)}`);
}
} catch (e) {
record(name, 'fail', String(e).slice(0, 200));
} finally {
// Leave the runner as we found it: no session, no keychain entry.
await page
.evaluate(async (k) => {
localStorage.removeItem(k);
await window.__TAURI_INTERNALS__.invoke('secure_session_clear').catch(() => undefined);
}, KEY)
.catch(() => undefined);
await page.reload().catch(() => undefined);
}
}
await page.screenshot({ path: `${OUT}/02-end.png` }).catch(() => undefined);
writeFileSync(`${OUT}/results.json`, JSON.stringify(results, null, 2));