C1 (Critical): getStudioSession was stamped with the same TECH_LOG_STUDIO_SESSION auth profile as every other Studio operation, and that profile requires the CSRF header it is getStudioSession's own job to issue -- an unconditional cycle that recursed without bound in HTTP mode. Fixed with a credential-free TECH_LOG_STUDIO_BOOTSTRAP auth profile for getStudioSession alone, a synchronous re-entrancy guard in createCsrfTokenProvider as defense in depth, and a throwing stub in place of the prior `let x!: T` assertion. Added a composition-level regression test that wires the real executor, CSRF provider, and credential-attach function together and proves getStudioSession dispatches exactly once while its token reaches both a JSON operation and the multipart upload. Also: invalidate the cached CSRF token on a 401/403 from the upload path (I2), a throwing useStudioAssetGateway() accessor so Task 11 cannot silently compile a null-gateway UI (I3), and the M1-M5 minors from the review (guard a malformed success body, cover the untested error fallbacks, align aborted uploads with the JSON path's non-retryable CANCELLED mapping, derive the credential header name from one source instead of two, and correct the adapter review doc's operation count). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
100 lines
3.3 KiB
TypeScript
100 lines
3.3 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import {
|
|
validateEnvelope,
|
|
validateOperationPayload,
|
|
validateOperationRequest,
|
|
} from "../../src/adapters/http/schema-registry.ts";
|
|
import {
|
|
composeRuntimeSchemaCodecs,
|
|
validateWithRuntimeSchemaRegistry,
|
|
} from "../../src/contracts/schema-registry.ts";
|
|
import { INSTALLED_REST_AUTH_PROFILES } from "../../src/contracts/rest-profiles.ts";
|
|
|
|
describe("HTTP platform schema boundary", () => {
|
|
it("rejects an invalid top-level envelope", () => {
|
|
expect(validateEnvelope({ success: true }).success).toBe(false);
|
|
});
|
|
|
|
it("accepts and clones a generic valid response envelope", () => {
|
|
const source = {
|
|
success: true,
|
|
data: [],
|
|
meta: { requestId: "request-1", traceId: "trace-1" },
|
|
};
|
|
const result = validateEnvelope(source);
|
|
expect(result).toMatchObject({ success: true, data: source });
|
|
if (!result.success) throw new Error("expected valid envelope");
|
|
expect(result.data).not.toBe(source);
|
|
});
|
|
|
|
it("fails closed without leaking input when a feature schema is absent", () => {
|
|
const result = validateOperationPayload("UnknownPayload", {
|
|
secret: "not-projected",
|
|
});
|
|
expect(result).toMatchObject({
|
|
success: false,
|
|
issues: [{ path: "", code: "SCHEMA_NOT_REGISTERED" }],
|
|
});
|
|
expect(JSON.stringify(result)).not.toContain("not-projected");
|
|
expect(
|
|
validateOperationRequest("UnknownCommand", { name: "Example" }).success,
|
|
).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("runtime schema codec contribution", () => {
|
|
const codec = {
|
|
schemaId: "Example",
|
|
parse: (value: unknown) => ({ success: true as const, data: value }),
|
|
};
|
|
|
|
it("resolves installed codecs and fails missing IDs closed", () => {
|
|
const registry = composeRuntimeSchemaCodecs([{ Example: codec }]);
|
|
expect(validateWithRuntimeSchemaRegistry("Example", 42, registry)).toEqual({
|
|
success: true,
|
|
data: 42,
|
|
});
|
|
expect(
|
|
validateWithRuntimeSchemaRegistry("Missing", 42, registry),
|
|
).toMatchObject({
|
|
success: false,
|
|
issues: [{ code: "SCHEMA_NOT_REGISTERED" }],
|
|
});
|
|
});
|
|
|
|
it("rejects duplicate codec contributions", () => {
|
|
expect(() =>
|
|
composeRuntimeSchemaCodecs([{ Example: codec }, { Example: codec }]),
|
|
).toThrow("duplicate runtime schema codec");
|
|
});
|
|
});
|
|
|
|
describe("REST auth profile registry", () => {
|
|
it("installs the TechLog Studio session auth profile", () => {
|
|
const profile = INSTALLED_REST_AUTH_PROFILES.get(
|
|
"TECH_LOG_STUDIO_SESSION",
|
|
);
|
|
expect(profile).toBeTruthy();
|
|
expect(profile?.transport).toBe("SAME_ORIGIN_COOKIE");
|
|
expect(profile?.credentials).toBe("include");
|
|
expect([...(profile?.requiredCredentialHeaders ?? [])]).toEqual([
|
|
"x-csrf-token",
|
|
]);
|
|
expect([...(profile?.allowedCredentialHeaders ?? [])]).toEqual([
|
|
"x-csrf-token",
|
|
]);
|
|
});
|
|
|
|
it("installs a credential-header-free bootstrap profile for getStudioSession", () => {
|
|
const profile = INSTALLED_REST_AUTH_PROFILES.get(
|
|
"TECH_LOG_STUDIO_BOOTSTRAP",
|
|
);
|
|
expect(profile).toBeTruthy();
|
|
expect(profile?.transport).toBe("SAME_ORIGIN_COOKIE");
|
|
expect(profile?.credentials).toBe("include");
|
|
expect([...(profile?.requiredCredentialHeaders ?? [])]).toEqual([]);
|
|
expect([...(profile?.allowedCredentialHeaders ?? [])]).toEqual([]);
|
|
});
|
|
});
|