123 lines
3.0 KiB
TypeScript
123 lines
3.0 KiB
TypeScript
import type { QuizConfig } from "./types.ts";
|
|
import { createBlobAccessToken } from "../services/webTokenService.ts";
|
|
import {
|
|
sqlDeleteWebToken,
|
|
sqlGetWebToken,
|
|
sqlUpdateWebToken,
|
|
} from "../db/sqlUserRepository.ts";
|
|
import { WebToken } from "../db/interfaces.ts";
|
|
|
|
export const DEFAULT_CACHE_TIMEOUT = 5 * 60 * 1000;
|
|
|
|
export async function isTokenExpired(
|
|
tokenId: string,
|
|
stateId: string,
|
|
): Promise<boolean> {
|
|
const token = await sqlGetWebToken(tokenId);
|
|
//console.log("sqlGetWebToken", token);
|
|
const now = Date.now();
|
|
|
|
// If token doesn't exist or doesn't match stateId, consider it expired
|
|
if (!token || token.state_id !== stateId) {
|
|
return true;
|
|
}
|
|
|
|
// Check if token is expired
|
|
const isExpired = token.expires_on <= now;
|
|
|
|
// If token is expired, delete it
|
|
if (isExpired) {
|
|
await sqlDeleteWebToken(tokenId);
|
|
}
|
|
|
|
return isExpired;
|
|
}
|
|
|
|
export async function isCreateTokenValid(
|
|
tokenId: string,
|
|
stateId: string,
|
|
): Promise<WebToken | null> {
|
|
const token = await sqlGetWebToken(tokenId) as WebToken | null;
|
|
const now = Date.now();
|
|
|
|
if (
|
|
!token ||
|
|
token.state_id !== stateId ||
|
|
!token.is_active ||
|
|
token.expires_on <= now ||
|
|
token.token_type !== "blob_create"
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
return token;
|
|
}
|
|
|
|
export async function consumeCreateToken(tokenId: string): Promise<void> {
|
|
await sqlUpdateWebToken(tokenId, {
|
|
is_active: false,
|
|
last_used_on: Date.now(),
|
|
});
|
|
}
|
|
|
|
export async function evaluateMediaUrls(
|
|
userId: string,
|
|
stateId: string,
|
|
questions: QuizConfig["questions"],
|
|
baseUrl: string,
|
|
): Promise<boolean> {
|
|
let urlsUpdated = false;
|
|
|
|
for (const question of questions) {
|
|
if (!question) continue;
|
|
|
|
const mediaFields = [
|
|
"audio_file_1",
|
|
"audio_file_2",
|
|
"background_image_data",
|
|
"video_file_data",
|
|
] as const;
|
|
|
|
for (const field of mediaFields) {
|
|
const blobUrl = question[field];
|
|
|
|
if (blobUrl) {
|
|
const urlObj = new URL(blobUrl, baseUrl);
|
|
const blobType = field.startsWith("audio")
|
|
? "audio"
|
|
: field.startsWith("video")
|
|
? "video"
|
|
: "image";
|
|
const token_id = urlObj.searchParams.get("token_id");
|
|
const state_id = urlObj.searchParams.get("state_id");
|
|
|
|
if (token_id && state_id && state_id === stateId) {
|
|
if (await isTokenExpired(token_id, state_id)) {
|
|
const newTokenId = await createBlobAccessToken(
|
|
userId,
|
|
blobType,
|
|
DEFAULT_CACHE_TIMEOUT,
|
|
stateId,
|
|
);
|
|
question[field] = urlObj.pathname + "?token_id=" + newTokenId +
|
|
"&state_id=" + stateId;
|
|
urlsUpdated = true;
|
|
}
|
|
} else {
|
|
const newTokenId = await createBlobAccessToken(
|
|
userId,
|
|
blobType,
|
|
DEFAULT_CACHE_TIMEOUT,
|
|
stateId,
|
|
);
|
|
question[field] = urlObj.pathname + "?token_id=" + newTokenId +
|
|
"&state_id=" + stateId;
|
|
urlsUpdated = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return urlsUpdated;
|
|
}
|