Spaces:
Sleeping
Sleeping
| import { SignJWT, jwtVerify } from "jose"; | |
| import bcrypt from "bcryptjs"; | |
| import fs from "node:fs"; | |
| import path from "node:path"; | |
| import crypto from "node:crypto"; | |
| import { DATA_DIR } from "@/lib/dataDir"; | |
| import { getSettings } from "@/lib/localDb"; | |
| const DEFAULT_PASSWORD = "123456"; | |
| function loadJwtSecret() { | |
| if (process.env.JWT_SECRET) return process.env.JWT_SECRET; | |
| const file = path.join(DATA_DIR, "jwt-secret"); | |
| try { | |
| return fs.readFileSync(file, "utf8").trim(); | |
| } catch {} | |
| fs.mkdirSync(DATA_DIR, { recursive: true }); | |
| const generated = crypto.randomBytes(32).toString("hex"); | |
| fs.writeFileSync(file, generated, { mode: 0o600 }); | |
| return generated; | |
| } | |
| const SECRET = new TextEncoder().encode(loadJwtSecret()); | |
| export function shouldUseSecureCookie(request) { | |
| const forceSecureCookie = process.env.AUTH_COOKIE_SECURE === "true"; | |
| const forwardedProto = request?.headers?.get?.("x-forwarded-proto"); | |
| const isHttpsRequest = forwardedProto === "https"; | |
| return forceSecureCookie || isHttpsRequest; | |
| } | |
| export async function createDashboardAuthToken(claims = {}) { | |
| return new SignJWT({ authenticated: true, ...claims }) | |
| .setProtectedHeader({ alg: "HS256" }) | |
| .setIssuedAt() | |
| .setExpirationTime("24h") | |
| .sign(SECRET); | |
| } | |
| export async function verifyDashboardAuthToken(token) { | |
| if (!token) return false; | |
| try { | |
| await jwtVerify(token, SECRET); | |
| return true; | |
| } catch { | |
| return false; | |
| } | |
| } | |
| export async function getDashboardAuthSession(token) { | |
| if (!token) return null; | |
| try { | |
| const { payload } = await jwtVerify(token, SECRET); | |
| return payload; | |
| } catch { | |
| return null; | |
| } | |
| } | |
| export async function setDashboardAuthCookie(cookieStore, request, claims = {}) { | |
| const token = await createDashboardAuthToken(claims); | |
| cookieStore.set("auth_token", token, { | |
| httpOnly: true, | |
| secure: shouldUseSecureCookie(request), | |
| sameSite: "lax", | |
| path: "/", | |
| }); | |
| } | |
| export function clearDashboardAuthCookie(cookieStore) { | |
| cookieStore.delete("auth_token"); | |
| } | |
| // Verify the current dashboard password (re-auth for sensitive actions). | |
| export async function verifyDashboardPassword(password) { | |
| if (typeof password !== "string" || !password) return false; | |
| const settings = await getSettings(); | |
| const storedHash = settings?.password; | |
| if (storedHash) return bcrypt.compare(password, storedHash); | |
| const initialPassword = process.env.INITIAL_PASSWORD || DEFAULT_PASSWORD; | |
| return password === initialPassword; | |
| } | |