feat: add shared auth proof helpers
This commit is contained in:
73
src/auth.ts
Normal file
73
src/auth.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
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
|
||||
});
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./types.js";
|
||||
export * from "./codec.js";
|
||||
export * from "./errors.js";
|
||||
export * from "./auth.js";
|
||||
|
||||
Reference in New Issue
Block a user