feat: worst-scan fansub web — initial release

Posts engine (SQLite + auto-publisher via poller), public feed with
clickable tags, reader, admin panel, submit/search/queue tools.
BFF proxy to pipeline API. Clean dark design. Docker-ready.
This commit is contained in:
renato97
2026-07-23 15:58:28 -03:00
commit 25449aa5df
71 changed files with 11296 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
import { SignJWT, jwtVerify } from "jose"
const SECRET = new TextEncoder().encode(
process.env.JWT_SECRET || process.env.WEB_PASSWORD || "worst-scan-web-dev-secret",
)
const COOKIE_NAME = "session"
export interface SessionPayload {
authenticated: boolean
timestamp: number
}
export async function createSession(): Promise<string> {
return new SignJWT({ authenticated: true, timestamp: Date.now() })
.setProtectedHeader({ alg: "HS256" })
.setExpirationTime("7d")
.sign(SECRET)
}
export async function verifySession(token: string): Promise<SessionPayload | null> {
try {
const { payload } = await jwtVerify(token, SECRET)
return payload as unknown as SessionPayload
} catch {
return null
}
}
export function sessionCookieOptions(): { name: string; options: { httpOnly: boolean; secure: boolean; sameSite: "lax"; path: string; maxAge: number } } {
return {
name: COOKIE_NAME,
options: {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
path: "/",
maxAge: 60 * 60 * 24 * 7,
},
}
}