74 lines
1.8 KiB
TypeScript
74 lines
1.8 KiB
TypeScript
import type { AuthRequestPayload } from "./types.js";
|
|
|
|
export const AUTH_NONCE_LENGTH = 24;
|
|
export const AUTH_MAX_TIMESTAMP_DRIFT_SECONDS = 10;
|
|
export const AUTH_MAX_ATTEMPTS_PER_WINDOW = 10;
|
|
export const AUTH_ATTEMPT_WINDOW_SECONDS = 10;
|
|
export const AUTH_RECENT_NONCE_WINDOW_SIZE = 10;
|
|
|
|
export interface AuthProofMaterial {
|
|
secret: string;
|
|
nonce: string;
|
|
timestamp: number;
|
|
}
|
|
|
|
export function createAuthProofMaterial(input: AuthProofMaterial): AuthProofMaterial {
|
|
return {
|
|
secret: input.secret,
|
|
nonce: input.nonce,
|
|
timestamp: input.timestamp
|
|
};
|
|
}
|
|
|
|
export function serializeAuthProofMaterial(input: AuthProofMaterial): string {
|
|
const material = createAuthProofMaterial(input);
|
|
return JSON.stringify({
|
|
secret: material.secret,
|
|
nonce: material.nonce,
|
|
timestamp: material.timestamp
|
|
});
|
|
}
|
|
|
|
export function isValidAuthNonce(nonce: string): boolean {
|
|
return /^[A-Za-z0-9_-]{24}$/.test(nonce);
|
|
}
|
|
|
|
export function isTimestampFresh(
|
|
proofTimestamp: number,
|
|
now: number,
|
|
maxDriftSeconds: number = AUTH_MAX_TIMESTAMP_DRIFT_SECONDS
|
|
): { ok: true } | { ok: false; reason: "stale_timestamp" | "future_timestamp" } {
|
|
const drift = proofTimestamp - now;
|
|
if (Math.abs(drift) < maxDriftSeconds) {
|
|
return { ok: true };
|
|
}
|
|
|
|
return {
|
|
ok: false,
|
|
reason: drift < 0 ? "stale_timestamp" : "future_timestamp"
|
|
};
|
|
}
|
|
|
|
export function createAuthRequestSigningInput(input: {
|
|
secret: string;
|
|
nonce: string;
|
|
proofTimestamp: number;
|
|
}): string {
|
|
return serializeAuthProofMaterial({
|
|
secret: input.secret,
|
|
nonce: input.nonce,
|
|
timestamp: input.proofTimestamp
|
|
});
|
|
}
|
|
|
|
export function extractAuthRequestSigningInput(
|
|
payload: Pick<AuthRequestPayload, "nonce" | "proofTimestamp">,
|
|
secret: string
|
|
): string {
|
|
return createAuthRequestSigningInput({
|
|
secret,
|
|
nonce: payload.nonce,
|
|
proofTimestamp: payload.proofTimestamp
|
|
});
|
|
}
|