Spaces:
Sleeping
Sleeping
| export const APP_COOKIE = "app_session"; | |
| export const APP_SESSION_MAX_AGE = 60 * 60 * 24 * 7; | |
| export const DEFAULT_APP_USERNAME = "student"; | |
| export const DEFAULT_APP_PASSWORD = "password"; | |
| const encoder = new TextEncoder(); | |
| export function appUsername() { | |
| return process.env.APP_USERNAME || DEFAULT_APP_USERNAME; | |
| } | |
| export function appPassword() { | |
| return process.env.APP_PASSWORD || DEFAULT_APP_PASSWORD; | |
| } | |
| function safeEqual(a: string, b: string) { | |
| if (a.length !== b.length) return false; | |
| let diff = 0; | |
| for (let i = 0; i < a.length; i += 1) { | |
| diff |= a.charCodeAt(i) ^ b.charCodeAt(i); | |
| } | |
| return diff === 0; | |
| } | |
| async function sha256Hex(value: string) { | |
| const digest = await crypto.subtle.digest("SHA-256", encoder.encode(value)); | |
| return [...new Uint8Array(digest)] | |
| .map((byte) => byte.toString(16).padStart(2, "0")) | |
| .join(""); | |
| } | |
| export async function appSessionToken() { | |
| return sha256Hex(`${appUsername()}:${appPassword()}`); | |
| } | |
| export async function verifyAppCredentials(username: string, password: string) { | |
| return safeEqual(username, appUsername()) && safeEqual(password, appPassword()); | |
| } | |
| export async function isValidAppSession(value: string | undefined) { | |
| if (!value) return false; | |
| return safeEqual(value, await appSessionToken()); | |
| } | |
| function attributes(isHttps: boolean, maxAge: number) { | |
| const parts = [`Path=/`, `Max-Age=${maxAge}`, "HttpOnly"]; | |
| if (isHttps) { | |
| parts.push("Secure", "SameSite=None", "Partitioned"); | |
| } else { | |
| parts.push("SameSite=Lax"); | |
| } | |
| return parts.join("; "); | |
| } | |
| export function setAppSessionCookie(headers: Headers, value: string, isHttps: boolean) { | |
| headers.append( | |
| "set-cookie", | |
| `${APP_COOKIE}=${encodeURIComponent(value)}; ${attributes(isHttps, APP_SESSION_MAX_AGE)}` | |
| ); | |
| } | |
| export function clearAppSessionCookie(headers: Headers, isHttps: boolean) { | |
| headers.append("set-cookie", `${APP_COOKIE}=; ${attributes(isHttps, 0)}`); | |
| } | |