api/security: jwt session token

This commit is contained in:
wukko
2024-08-16 23:28:03 +06:00
parent 33c2fee847
commit 16acf62886
4 changed files with 110 additions and 19 deletions

59
api/src/security/jwt.js Normal file
View File

@@ -0,0 +1,59 @@
import { nanoid } from "nanoid";
import { createHmac } from "crypto";
import { env } from "../config.js";
const toBase64URL = (b) => Buffer.from(b).toString("base64url");
const fromBase64URL = (b) => Buffer.from(b, "base64url").toString();
const makeHmac = (header, payload) =>
createHmac("sha256", env.jwtSecret)
.update(`${header}.${payload}`)
.digest("base64url");
export const generate = () => {
const exp = new Date().getTime() + env.jwtLifetime * 1000;
const header = toBase64URL(JSON.stringify({
alg: "HS256",
typ: "JWT"
}));
const payload = toBase64URL(JSON.stringify({
jti: nanoid(3),
exp,
}));
const signature = makeHmac(header, payload);
return {
token: `${header}.${payload}.${signature}`,
exp,
};
}
export const verify = (jwt) => {
const [header, payload, signature] = jwt.split(".", 3);
const timestamp = new Date().getTime();
if ([header, payload, signature].join('.') !== jwt) {
return false;
}
const verifySignature = makeHmac(header, payload);
if (verifySignature !== signature) {
return false;
}
if (timestamp >= JSON.parse(fromBase64URL(payload)).exp) {
return false;
}
return true;
}
export default {
generate,
verify,
}

View File

@@ -0,0 +1,19 @@
import { env } from "../config.js";
export const verifyTurnstileToken = async (turnstileResponse, ip) => {
const result = await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
secret: env.turnstileSecret,
response: turnstileResponse,
remoteip: ip,
}),
})
.then(r => r.json())
.catch(() => {});
return !!result?.success;
}