parent
af681f8b25
commit
926c640c6f
@ -0,0 +1,98 @@
|
||||
import {
|
||||
REVOKE_REASON_MISSING_REVOKE_URL,
|
||||
REVOKE_REASON_NETWORK_ERROR,
|
||||
REVOKE_REASON_NO_SESSION,
|
||||
REVOKE_REASON_SERVER_REJECTED,
|
||||
REVOKE_SCOPE_GLOBAL,
|
||||
REVOKE_SCOPE_LOCAL,
|
||||
SESSION_DIAGNOSTIC_EVENTS
|
||||
} from './consts.ts';
|
||||
import { emitSessionDiagnostic, type SessionDiagnostics } from './diagnostics.ts';
|
||||
import { toError } from './session-helpers.ts';
|
||||
import type { Logger } from '$libs/logr';
|
||||
import type { RevokeFn, RevokeOptions, RevokeResult, Session } from './types.ts';
|
||||
|
||||
export interface ResolveSessionRevokeInput<TUser, TCredential = undefined, TData = undefined> {
|
||||
readonly current: Session<TUser, TCredential, TData> | null;
|
||||
readonly options: RevokeOptions;
|
||||
readonly onRevoke?: RevokeFn<TUser, TCredential, TData>;
|
||||
readonly logger?: Logger;
|
||||
readonly diagnostics: SessionDiagnostics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve whether revoke is local, global, or degraded. The caller owns the
|
||||
* actual state mutation so this helper remains pure from the engine runtime.
|
||||
*/
|
||||
export async function resolveSessionRevoke<TUser, TCredential = undefined, TData = undefined>({
|
||||
current,
|
||||
options,
|
||||
onRevoke,
|
||||
logger,
|
||||
diagnostics
|
||||
}: ResolveSessionRevokeInput<TUser, TCredential, TData>): Promise<RevokeResult> {
|
||||
if (current === null) {
|
||||
return {
|
||||
localRevoked: true,
|
||||
globalRevoked: false,
|
||||
scope: REVOKE_SCOPE_LOCAL,
|
||||
reason: REVOKE_REASON_NO_SESSION
|
||||
};
|
||||
}
|
||||
|
||||
const requestedScope =
|
||||
options.scope ?? (onRevoke !== undefined ? REVOKE_SCOPE_GLOBAL : REVOKE_SCOPE_LOCAL);
|
||||
|
||||
if (requestedScope !== REVOKE_SCOPE_GLOBAL) {
|
||||
return {
|
||||
localRevoked: true,
|
||||
globalRevoked: false,
|
||||
scope: REVOKE_SCOPE_LOCAL
|
||||
};
|
||||
}
|
||||
|
||||
if (onRevoke === undefined) {
|
||||
emitSessionDiagnostic(diagnostics, SESSION_DIAGNOSTIC_EVENTS.REVOKE_GLOBAL_NO_HANDLER, {
|
||||
error: REVOKE_REASON_MISSING_REVOKE_URL
|
||||
});
|
||||
return {
|
||||
localRevoked: true,
|
||||
globalRevoked: false,
|
||||
scope: REVOKE_SCOPE_LOCAL,
|
||||
reason: REVOKE_REASON_MISSING_REVOKE_URL
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const ok = await onRevoke(current, { logger });
|
||||
if (ok) {
|
||||
return {
|
||||
localRevoked: true,
|
||||
globalRevoked: true,
|
||||
scope: REVOKE_SCOPE_GLOBAL
|
||||
};
|
||||
}
|
||||
|
||||
emitSessionDiagnostic(
|
||||
diagnostics,
|
||||
SESSION_DIAGNOSTIC_EVENTS.REVOKE_GLOBAL_SERVER_REJECTED,
|
||||
{ error: REVOKE_REASON_SERVER_REJECTED }
|
||||
);
|
||||
return {
|
||||
localRevoked: true,
|
||||
globalRevoked: false,
|
||||
scope: REVOKE_SCOPE_LOCAL,
|
||||
reason: REVOKE_REASON_SERVER_REJECTED
|
||||
};
|
||||
} catch (err) {
|
||||
emitSessionDiagnostic(diagnostics, SESSION_DIAGNOSTIC_EVENTS.REVOKE_GLOBAL_HANDLER_FAILED, {
|
||||
error: toError(err)
|
||||
});
|
||||
return {
|
||||
localRevoked: true,
|
||||
globalRevoked: false,
|
||||
scope: REVOKE_SCOPE_LOCAL,
|
||||
reason: REVOKE_REASON_NETWORK_ERROR
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue