test(core): pin the shell's one use of browser storage, not ban it
CI / verify (pull_request) Successful in 1m12s
CI / infrastructure-smoke (pull_request) Successful in 42s
CI / package-release (pull_request) Successful in 48s
CI / migration-smoke (pull_request) Successful in 2m26s
CI / image-build (pull_request) Successful in 1m8s
CI / deploy-smoke (same-origin) (pull_request) Successful in 49s
CI / package-publication (pull_request) Successful in 57s
CI / deploy-smoke (split) (pull_request) Successful in 2m41s
CI / verify (pull_request) Successful in 1m12s
CI / infrastructure-smoke (pull_request) Successful in 42s
CI / package-release (pull_request) Successful in 48s
CI / migration-smoke (pull_request) Successful in 2m26s
CI / image-build (pull_request) Successful in 1m8s
CI / deploy-smoke (same-origin) (pull_request) Successful in 49s
CI / package-publication (pull_request) Successful in 57s
CI / deploy-smoke (split) (pull_request) Successful in 2m41s
CI failed in `identity-verification-boundaries.test.ts`: its guard that a
reset token never reaches browser storage was a blanket ban on the word
`localStorage` anywhere in the shell. The sidebar preference (ADR 0058)
legitimately reads it in the entry point.
The guarantee is unchanged: the reset token stays in React state for
the life of one form. The guard is now precise:
- `localStorage` appears only in `main.tsx`, only to hand it to the
sidebar preference;
- the shell's only storage write is the sidebar's own key and a
validated mode;
- the files that ever hold the token (`auth-protocol.ts`,
`ResetPasswordForm.tsx`, `HostApp.tsx`) touch no storage API at all;
- `sessionStorage` and `document.cookie` stay banned everywhere.
A planted `localStorage.setItem("t", token)` in `auth-protocol.ts` fails
it. The runtime reset-token test in `auth-recovery.test.tsx` now runs
with the production localStorage-backed preference and asserts storage
holds nothing but the sidebar key.
It passed locally only because Turbo restored `@ekklesia/core:test` from
cache: that test reads shell source that Core's task hash does not
include.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
af31724cb4
commit
cf2f847c8c
@@ -4,6 +4,10 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { consumeAuthLanding, type HostAuthLanding, readAuthLanding } from "../src/auth-protocol.js";
|
||||
import { HostApp } from "../src/browser/HostApp.js";
|
||||
import { createMemoryHostHistory } from "../src/browser/host-history.js";
|
||||
import {
|
||||
createLocalSidebarPreference,
|
||||
SIDEBAR_PREFERENCE_KEY,
|
||||
} from "../src/browser/sidebar-preference.js";
|
||||
import type { EkklesiaHostConfig } from "../src/host-protocol.js";
|
||||
|
||||
/**
|
||||
@@ -99,6 +103,9 @@ async function render(config: EkklesiaHostConfig, authLanding?: HostAuthLanding)
|
||||
<HostApp
|
||||
config={config}
|
||||
history={createMemoryHostHistory("/")}
|
||||
// The production store over this browser's real storage, so the assertions below cover
|
||||
// the shell's one use of it (ADR 0058) as well.
|
||||
sidebarPreference={createLocalSidebarPreference(window.localStorage)}
|
||||
{...(authLanding ? { authLanding } : {})}
|
||||
/>,
|
||||
);
|
||||
@@ -463,7 +470,11 @@ describe("reset password", () => {
|
||||
|
||||
// A reset token is a bearer credential for one account. It lives in React state for the life of
|
||||
// the form and nowhere else.
|
||||
expect(localStorage.length).toBe(0);
|
||||
// The only thing this browser's storage may ever hold is the sidebar's mode (ADR 0058).
|
||||
for (let index = 0; index < localStorage.length; index += 1) {
|
||||
expect(localStorage.key(index)).toBe(SIDEBAR_PREFERENCE_KEY);
|
||||
}
|
||||
expect(JSON.stringify({ ...localStorage })).not.toContain("reset-token-abc");
|
||||
expect(sessionStorage.length).toBe(0);
|
||||
expect(text()).not.toContain("reset-token-abc");
|
||||
expect(container.innerHTML).not.toContain("reset-token-abc");
|
||||
|
||||
Reference in New Issue
Block a user