studiocms
Version:
Astro Native CMS for AstroDB. Built from the ground up by the Astro community.
63 lines (62 loc) • 2.28 kB
JavaScript
import * as crypto from "node:crypto";
import logger from "studiocms:logger";
function base64UrlEncode(input) {
return Buffer.from(input).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}
function base64UrlDecode(input) {
let newInput = input.replace(/-/g, "+").replace(/_/g, "/");
while (newInput.length % 4 !== 0) {
newInput += "=";
}
return Buffer.from(newInput, "base64").toString();
}
function generateJwt(secret, payload, noExpire) {
const header = { alg: "HS256", typ: "JWT" };
const currentDate = /* @__PURE__ */ new Date();
const thirtyYearsFromToday = Math.floor(
currentDate.setFullYear(currentDate.getFullYear() + 30) / 1e3
);
const exp = noExpire ? thirtyYearsFromToday : Math.floor(Date.now() / 1e3) + 86400;
const payloadObj = {
...payload,
iat: Math.floor(Date.now() / 1e3),
// Corrected iat
exp
};
const encodedHeader = base64UrlEncode(JSON.stringify(header));
const encodedPayload = base64UrlEncode(JSON.stringify(payloadObj));
const signatureInput = `${encodedHeader}.${encodedPayload}`;
const signature = Buffer.from(
crypto.createHmac("sha256", secret + secret).update(signatureInput).digest()
).toString("base64url");
return `${encodedHeader}.${encodedPayload}.${signature}`;
}
function verifyJwt(token, secret) {
const [encodedHeader, encodedPayload, encodedSignature] = token.split(".");
const header = JSON.parse(base64UrlDecode(encodedHeader));
const payload = JSON.parse(base64UrlDecode(encodedPayload));
if (header.alg !== "HS256") {
logger.warn("Invalid algorithm");
return { isValid: false };
}
const currentTime = Math.floor(Date.now() / 1e3);
if (payload.exp && currentTime > payload.exp) {
logger.warn("Token has expired");
return { isValid: false };
}
const signatureInput = `${encodedHeader}.${encodedPayload}`;
const generatedSignature = Buffer.from(
crypto.createHmac("sha256", secret + secret).update(signatureInput).digest()
).toString("base64url");
if (generatedSignature !== encodedSignature) {
logger.warn("Invalid signature");
return { isValid: false };
}
return { isValid: true, userId: payload.userId };
}
export {
base64UrlDecode,
base64UrlEncode,
generateJwt,
verifyJwt
};