feat: integrate bounded external auth sessions

This commit is contained in:
donghyeon-ka
2026-07-25 20:54:18 +09:00
parent 37ca2c3172
commit 44414c5244
4 changed files with 197 additions and 0 deletions
@@ -0,0 +1,45 @@
/**
* Creates the skeleton-owned side of an external session integration.
* Credential acquisition and storage stay inside the supplied external owner.
*
* @param {{
* readState(): import("../../application/ports/auth-session-port.js").SessionState,
* attachCredential(request: Request): Promise<Request>,
* recoverSession(): Promise<"restored" | "no-session">,
* notifyUnauthenticated(): void
* }} owner
* @returns {import("../../application/ports/auth-session-port.js").AuthSessionPort}
*/
export function createExternalAuthSessionAdapter(owner) {
return Object.freeze({
getState() {
return owner.readState();
},
async attach(request) {
const attached = await owner.attachCredential(request);
if (!(attached instanceof Request)) {
throw new TypeError("Auth owner returned an invalid request");
}
return attached;
},
async recover() {
const result = await owner.recoverSession();
if (result !== "restored" && result !== "no-session") {
throw new TypeError("Auth owner returned an invalid recovery state");
}
return result;
},
onUnauthenticated() {
owner.notifyUnauthenticated();
},
});
}
export function createAnonymousSessionAdapter() {
return createExternalAuthSessionAdapter({
readState: () => "unauthenticated",
attachCredential: async (request) => request,
recoverSession: async () => "no-session",
notifyUnauthenticated: () => {},
});
}
+5
View File
@@ -109,6 +109,11 @@ export function createHttpClient(dependencies) {
continue;
}
if (outcome.error.httpStatus === 401 && recoveryUsed) {
authSession.onUnauthenticated();
return outcome;
}
if (!shouldRetry(operation, outcome.error, retryCount)) {
return outcome;
}