Files
SupportBot/Structures/DashboardSession.js
T

75 lines
1.8 KiB
JavaScript
Raw Permalink Normal View History

2026-05-16 15:10:27 +01:00
const crypto = require("crypto");
const SESSION_COOKIE = "sb_dashboard";
const SESSION_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
function signSession(payload, secret) {
const body = Buffer.from(JSON.stringify(payload)).toString("base64url");
const sig = crypto
.createHmac("sha256", secret)
.update(body)
.digest("base64url");
return `${body}.${sig}`;
}
function verifySession(token, secret) {
if (!token || typeof token !== "string") return null;
const dot = token.lastIndexOf(".");
if (dot <= 0) return null;
const body = token.slice(0, dot);
const sig = token.slice(dot + 1);
const expected = crypto
.createHmac("sha256", secret)
.update(body)
.digest("base64url");
if (sig.length !== expected.length) return null;
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return null;
}
try {
const payload = JSON.parse(
Buffer.from(body, "base64url").toString("utf8"),
);
if (!payload?.userId || !payload?.exp) return null;
if (Date.now() > payload.exp) return null;
return payload;
} catch {
return null;
}
}
function createSessionPayload(user) {
return {
userId: user.id,
username: user.username,
globalName: user.global_name || null,
avatar: user.avatar || null,
exp: Date.now() + SESSION_MAX_AGE_MS,
};
}
2026-05-19 23:22:11 +01:00
function sessionCookieOptions(maxAgeMs = SESSION_MAX_AGE_MS, opts = {}) {
const secure =
opts.secure !== undefined
? Boolean(opts.secure)
: process.env.NODE_ENV === "production";
2026-05-16 15:10:27 +01:00
return {
httpOnly: true,
2026-05-19 23:22:11 +01:00
secure,
2026-05-16 15:10:27 +01:00
sameSite: "lax",
maxAge: maxAgeMs,
path: "/",
};
}
module.exports = {
SESSION_COOKIE,
SESSION_MAX_AGE_MS,
signSession,
verifySession,
createSessionPayload,
sessionCookieOptions,
};