fix: break the TechLog CSRF bootstrap cycle and close the review's fix-round-1 items
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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c9c832c365
commit
2cab4974b7
@@ -43,6 +43,30 @@ export function useStudio(): StudioContextValue {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix round 1 (I3). `StudioContextValue.assetGateway` stays nullable — most
|
||||
* test harnesses render `StudioProvider` without a `createAssetGateway` prop
|
||||
* and that must keep compiling — but a nullable field lets Asset UI write
|
||||
* `if (!assetGateway) return null` and ship a confusingly empty screen with
|
||||
* the type checker fully satisfied, since "no gateway" and "gateway with an
|
||||
* empty list" look identical to that check. Asset UI must use this accessor
|
||||
* instead of reading `useStudio().assetGateway` directly: it throws with a
|
||||
* clear message the one time this is actually unmet — in the real app,
|
||||
* `StudioShell` always supplies `createAssetGateway`, so this never throws in
|
||||
* production.
|
||||
*/
|
||||
export function useStudioAssetGateway(): StudioAssetGateway {
|
||||
const { assetGateway } = useStudio();
|
||||
if (!assetGateway) {
|
||||
throw new Error(
|
||||
"useStudioAssetGateway must be used within a StudioProvider that was " +
|
||||
"given a createAssetGateway prop. StudioShell (the production path) " +
|
||||
"always supplies one; a test harness that renders Asset UI must too.",
|
||||
);
|
||||
}
|
||||
return assetGateway;
|
||||
}
|
||||
|
||||
export function useStudioEditorSession() {
|
||||
const studio = useStudio();
|
||||
return useMemo(
|
||||
|
||||
Reference in New Issue
Block a user