Spaces:
Sleeping
Sleeping
Download src/lib/session.ts from mrfakename/spacefactory2: direct link, hf CLI and curl.
- Browser
- Download file 2.55 kB
-
https://huggingface.co/spaces/mrfakename/spacefactory2/resolve/main/src/lib/session.ts
- Command line
-
hf download hf://spaces/mrfakename/spacefactory2/src/lib/session.ts
-
curl -L -o session.ts https://huggingface.co/spaces/mrfakename/spacefactory2/resolve/main/src/lib/session.ts
2.55 kB
| import { cookies } from "next/headers"; | |
| import crypto from "node:crypto"; | |
| export interface Session { | |
| accessToken: string; | |
| expiresAt: number; // epoch ms | |
| user: { | |
| name: string; // username | |
| fullName?: string; | |
| avatarUrl?: string; | |
| }; | |
| } | |
| const COOKIE_NAME = "sf_session"; | |
| function sessionKey(): Buffer { | |
| const secret = | |
| process.env.SESSION_SECRET || | |
| process.env.OAUTH_CLIENT_SECRET || | |
| "spacefactory-dev-secret"; | |
| return crypto.createHash("sha256").update(secret).digest(); | |
| } | |
| export function seal(data: unknown): string { | |
| const iv = crypto.randomBytes(12); | |
| const cipher = crypto.createCipheriv("aes-256-gcm", sessionKey(), iv); | |
| const plaintext = Buffer.from(JSON.stringify(data), "utf8"); | |
| const enc = Buffer.concat([cipher.update(plaintext), cipher.final()]); | |
| const tag = cipher.getAuthTag(); | |
| return Buffer.concat([iv, tag, enc]).toString("base64url"); | |
| } | |
| export function unseal<T>(sealed: string): T | null { | |
| try { | |
| const raw = Buffer.from(sealed, "base64url"); | |
| const iv = raw.subarray(0, 12); | |
| const tag = raw.subarray(12, 28); | |
| const enc = raw.subarray(28); | |
| const decipher = crypto.createDecipheriv("aes-256-gcm", sessionKey(), iv); | |
| decipher.setAuthTag(tag); | |
| const dec = Buffer.concat([decipher.update(enc), decipher.final()]); | |
| return JSON.parse(dec.toString("utf8")) as T; | |
| } catch { | |
| return null; | |
| } | |
| } | |
| export async function getSession(): Promise<Session | null> { | |
| const jar = await cookies(); | |
| const cookie = jar.get(COOKIE_NAME); | |
| if (!cookie?.value) return null; | |
| const session = unseal<Session>(cookie.value); | |
| if (!session) return null; | |
| if (session.expiresAt && session.expiresAt < Date.now()) return null; | |
| return session; | |
| } | |
| export function sessionCookie(session: Session) { | |
| return { | |
| name: COOKIE_NAME, | |
| value: seal(session), | |
| httpOnly: true, | |
| secure: process.env.NODE_ENV === "production", | |
| // The Space may be embedded in an iframe on huggingface.co; SameSite=None | |
| // (with Secure) keeps the session usable there. | |
| sameSite: (process.env.NODE_ENV === "production" ? "none" : "lax") as | |
| | "none" | |
| | "lax", | |
| path: "/", | |
| maxAge: Math.max(60, Math.floor((session.expiresAt - Date.now()) / 1000)), | |
| }; | |
| } | |
| export function clearedSessionCookie() { | |
| return { | |
| name: COOKIE_NAME, | |
| value: "", | |
| httpOnly: true, | |
| secure: process.env.NODE_ENV === "production", | |
| sameSite: (process.env.NODE_ENV === "production" ? "none" : "lax") as | |
| | "none" | |
| | "lax", | |
| path: "/", | |
| maxAge: 0, | |
| }; | |
| } | |