Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/sandros94/unjwt. A collection of JWT utilities based on the Web Crypto API, in a single zero-depend unjwt.s94.dev
auth browser decrypt edge encrypt jose jwe jwk jws jwt security serverless session sign verify webcrypto
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107import { H3, HTTPError, serve } from "h3";
import { defineJWESession, defineJWSSession, generateJWK, deriveJWKFromPassword,} from "unjwt/adapters/h3";
const [atJwk, rtJwk] = await Promise.all([ generateJWK("RS256"), deriveJWKFromPassword("refresh_token_secret", { alg: "PBES2-HS256+A128KW", salt: "playground-salt", iterations: 600_000, }),]);
const refreshToken = defineJWESession({ key: rtJwk, name: "refresh_token", maxAge: 7 * 24 * 60 * 60, // 7 days});
const accessToken = defineJWSSession({ key: atJwk, name: "access_token", maxAge: 15 * 60, // 15 minutes hooks: { async onExpire({ event }) { const refreshSession = await refreshToken.use(event); if (!refreshSession.data.sub) { // no valid refresh session, nothing to do return; }
console.log("Access token expired, refreshing...");
// refresh the access token const accessSession = await accessToken.use(event); await accessSession.update({ sub: refreshSession.data.sub, scope: refreshSession.data.scope, }); }, },});
const app = new H3();
app.post("/login", async (event) => { const refreshSession = await refreshToken.use(event); const accessSession = await accessToken.use(event);
if (accessSession.data.sub) { // user already logged in, return existing info return { accessToken: { id: accessSession.id, createdAt: accessSession.createdAt, expiresAt: accessSession.expiresAt, data: accessSession.data, }, refreshSession: { id: refreshSession.id, createdAt: refreshSession.createdAt, expiresAt: refreshSession.expiresAt, data: refreshSession.data, }, }; }
const data = await event.req.json();
if (!data.username || !data.password) { throw new HTTPError("Username and password are required", { status: 400 }); }
// validate user credentials here
const claims = { sub: data.username, scope: ["read:profile"], };
await accessSession.update(claims);
await refreshSession.update(claims);
return { accessToken: { id: accessSession.id, createdAt: accessSession.createdAt, expiresAt: accessSession.expiresAt, data: accessSession.data, }, refreshSession: { id: refreshSession.id, createdAt: refreshSession.createdAt, expiresAt: refreshSession.expiresAt, data: refreshSession.data, }, };});
serve(app);