integratedhub/services/webTokenService.ts
2026-02-14 02:20:19 +00:00

78 lines
2.0 KiB
TypeScript

import { sqlCreateWebToken } from "../db/sqlUserRepository.ts";
const BLOB_TOKEN_DEFAULT_EXPIRY_MS = Number(
Deno.env.get("BLOB_TOKEN_DEFAULT_EXPIRY") ?? 60 * 60 * 1000,
);
const BLOB_TOKEN_MAX_EXPIRY_MS = Number(
Deno.env.get("BLOB_TOKEN_MAX_EXPIRY") ?? 24 * 60 * 60 * 1000,
);
const BLOB_CREATE_TOKEN_DEFAULT_EXPIRY_MS = Number(
Deno.env.get("BLOB_CREATE_TOKEN_DEFAULT_EXPIRY") ?? 5 * 60 * 1000,
);
const BLOB_CREATE_TOKEN_MAX_EXPIRY_MS = Number(
Deno.env.get("BLOB_CREATE_TOKEN_MAX_EXPIRY") ?? 15 * 60 * 1000,
);
export type BlobTokenType = "audio" | "image" | "video";
function resolveBlobExpiry(expiresIn?: number): number {
const resolved = typeof expiresIn === "number" && expiresIn > 0
? expiresIn
: BLOB_TOKEN_DEFAULT_EXPIRY_MS;
if (
Number.isFinite(BLOB_TOKEN_MAX_EXPIRY_MS) && BLOB_TOKEN_MAX_EXPIRY_MS > 0
) {
return Math.min(resolved, BLOB_TOKEN_MAX_EXPIRY_MS);
}
return resolved;
}
export async function createBlobAccessToken(
userId: string,
blobType: BlobTokenType,
expiresIn: number,
stateId: string,
): Promise<string> {
const now = Date.now();
const tokenId = `blob_${crypto.randomUUID()}`;
const expiresOn: number = now + resolveBlobExpiry(expiresIn);
await sqlCreateWebToken(
tokenId,
stateId,
userId,
blobType,
"blob",
expiresOn,
null,
);
return tokenId;
}
export async function createOneTimeBlobCreateToken(
userId: string,
blobType: BlobTokenType,
expiresIn: number,
stateId: string,
): Promise<string> {
const now = Date.now();
const tokenId = `blob_create_${crypto.randomUUID()}`;
const resolvedExpiry = typeof expiresIn === "number" && expiresIn > 0
? Math.min(expiresIn, BLOB_CREATE_TOKEN_MAX_EXPIRY_MS)
: BLOB_CREATE_TOKEN_DEFAULT_EXPIRY_MS;
const expiresOn: number = now + resolvedExpiry;
await sqlCreateWebToken(
tokenId,
stateId,
userId,
"blob_create",
blobType,
expiresOn,
{ single_use: true },
);
return tokenId;
}