fix(auth): confirm passkey operations and preserve safe legacy migration

Fence displayed identity and native prompt generations, classify secret-free outcomes, recover atomic addition receipts without restoring old credentials, and expose truthful own-key verification metadata. Preserve required verifier and enrollment authority boundaries. Include real-store, production browser, native CTAP2 and visible responsive regressions.

Validation: root check/fmt; API 115; passkey security 25; Web unit 712/component 605; auth/entry/activation/hosting browsers; product auth E2E 8 and two explicit browser suites. Server suite: 1262 lib+12 CLI, 3 ignored and 2 environment-specific exclusions. State-name checker retains 15 byte-identical baseline findings; no new exceptions. Physical keys/mobile and hosted CI remain unverified.
This commit is contained in:
2026-10-26 07:18:23 +09:00
parent b284934e34
commit f17b5212c7
66 changed files with 4716 additions and 532 deletions
@@ -19,7 +19,7 @@ const mime: Record<string, string> = {
};
const policies = new Map<string, boolean>();
// 各fixture processはscenarioを逐次実行する。setupのBearer-only要求はcookieを
// 送らないので、秘密やheadersを読まず直前の合成page条件で応答を選ぶ。
// 送らないので、Bearer有無と直前の合成page条件で応答を選ぶ。header値は読まない。
let setupMode: string | null = null;
Deno.serve({ hostname: "127.0.0.1", port: Number(port) }, async (request) => {
const url = new URL(request.url);
@@ -28,19 +28,27 @@ Deno.serve({ hostname: "127.0.0.1", port: Number(port) }, async (request) => {
if (url.pathname === "/hosting/setup" && selected?.startsWith("setup-")) {
setupMode = selected;
}
const tokenRequest = request.headers.has("authorization");
const mode = selected ??
(tokenRequest ? setupMode : null) ??
request.headers.get("cookie")?.match(/ui-fixture=([\w-]+)/)?.[1] ??
(url.pathname.startsWith("/api/auth/passkeys/addition/")
? setupMode
: null) ??
"admin-on";
if (selected) policies.delete(mode);
const setup = setupProjectionResponse(url.pathname, mode, selected !== null);
const setup = setupProjectionResponse(
url.pathname,
mode,
selected !== null,
tokenRequest,
);
if (setup) return setup;
const anonymous = mode.startsWith("anonymous") || mode.startsWith("account-");
const ordinary = mode.startsWith("ordinary");
if (url.pathname === "/api/auth/whoami") {
return Response.json({
authentication_reference: anonymous ? null : "fixture-authentication",
session: !anonymous
? { kind: "authenticated", expires_at: "2099-01-01T00:00:00Z" }
: { kind: "anonymous" },
@@ -53,6 +61,17 @@ Deno.serve({ hostname: "127.0.0.1", port: Number(port) }, async (request) => {
},
});
}
if (url.pathname === "/api/auth/passkeys") {
return Response.json({
user: {
user_id: "fixture-user",
account_id: "fixture-account",
handle: "alice",
display_name: "Alice",
},
keys: [],
});
}
if (url.pathname === "/api/workspaces") return Response.json([]);
if (url.pathname === "/api/hosting/access") {
return Response.json({ is_admin: !ordinary && !anonymous });