Files
openmaic/OpenMAIC/lib/server/access-token.ts
2026-08-16 14:58:47 +08:00

40 lines
1.3 KiB
TypeScript

import { createHmac, timingSafeEqual } from 'crypto';
import {
parseFreshAccessToken,
resolveAccessCodeSessionTtlSeconds,
type AccessTokenValidationOptions,
} from '@/lib/server/access-token-policy';
/** Create an HMAC-signed token: `timestamp.signature` */
export function createAccessToken(accessCode: string, nowMs = Date.now()): string {
if (!Number.isSafeInteger(nowMs) || nowMs < 0) {
throw new TypeError('Access token issue time must be a non-negative safe integer');
}
const timestamp = nowMs.toString();
const signature = createHmac('sha256', accessCode).update(timestamp).digest('hex');
return `${timestamp}.${signature}`;
}
/** Verify an HMAC-signed token against the access code */
export function verifyAccessToken(
token: string,
accessCode: string,
options: AccessTokenValidationOptions = {},
): boolean {
const parsed = parseFreshAccessToken(token, {
...options,
ttlSeconds:
options.ttlSeconds ??
resolveAccessCodeSessionTtlSeconds(process.env.ACCESS_CODE_SESSION_TTL_SECONDS),
});
if (!parsed) return false;
const expected = createHmac('sha256', accessCode).update(parsed.issuedAtText).digest('hex');
const sigBuf = Buffer.from(parsed.signatureHex, 'hex');
const expBuf = Buffer.from(expected, 'hex');
if (sigBuf.length !== expBuf.length) return false;
return timingSafeEqual(sigBuf, expBuf);
}