feat(auth): add remembered local login to the frontend
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import { getAuthGeneration, getAuthState } from "./authState";
|
||||
|
||||
export type AuthOperationGuard = Readonly<{
|
||||
authGeneration: number;
|
||||
issuer: string;
|
||||
subject: string;
|
||||
sessionId: string | null;
|
||||
disposalEpoch: number;
|
||||
}>;
|
||||
|
||||
export type AuthOperationPrecondition = Readonly<{
|
||||
operation: AuthOperationGuard;
|
||||
isCurrent: () => boolean;
|
||||
}>;
|
||||
|
||||
export class StaleAuthOperationError extends Error {
|
||||
constructor() {
|
||||
super("The authenticated operation is no longer current");
|
||||
this.name = "StaleAuthOperationError";
|
||||
}
|
||||
}
|
||||
|
||||
export function captureAuthOperation(options: {
|
||||
sessionId?: string | null;
|
||||
disposalEpoch?: number;
|
||||
} = {}): AuthOperationGuard | null {
|
||||
const user = getAuthState();
|
||||
if (!user) return null;
|
||||
return {
|
||||
authGeneration: getAuthGeneration(),
|
||||
issuer: user.issuer,
|
||||
subject: user.subject,
|
||||
sessionId: options.sessionId ?? null,
|
||||
disposalEpoch: options.disposalEpoch ?? 0,
|
||||
};
|
||||
}
|
||||
|
||||
export function isAuthOperationCurrent(
|
||||
operation: AuthOperationGuard | null,
|
||||
options: { sessionId?: string | null; disposalEpoch: number },
|
||||
): boolean {
|
||||
if (!operation) return false;
|
||||
const user = getAuthState();
|
||||
return Boolean(
|
||||
user
|
||||
&& getAuthGeneration() === operation.authGeneration
|
||||
&& user.issuer === operation.issuer
|
||||
&& user.subject === operation.subject
|
||||
&& operation.sessionId === (options.sessionId ?? null)
|
||||
&& operation.disposalEpoch === options.disposalEpoch,
|
||||
);
|
||||
}
|
||||
|
||||
export function requireCurrentAuthOperation(
|
||||
operation: AuthOperationGuard | null,
|
||||
options: { sessionId?: string | null; disposalEpoch: number },
|
||||
): asserts operation is AuthOperationGuard {
|
||||
if (!isAuthOperationCurrent(operation, options)) throw new StaleAuthOperationError();
|
||||
}
|
||||
|
||||
export function requireAuthOperationPrecondition(
|
||||
precondition: AuthOperationPrecondition | undefined,
|
||||
): void {
|
||||
if (precondition && !precondition.isCurrent()) throw new StaleAuthOperationError();
|
||||
}
|
||||
Reference in New Issue
Block a user