UNPKG

@mark01/express-utils

Version:

npm package that contains utilities for express.js

80 lines (79 loc) 2.5 kB
import { decodeJwt, importPKCS8, importSPKI, jwtVerify, SignJWT } from 'jose'; import { z } from 'zod'; import { AppError } from '../error'; export const signHS256JWT = async (secret, issuer, audience, jti, sub, expiration) => { const secretEncoded = new TextEncoder().encode(secret); const payload = { aud: audience, exp: Math.floor(Date.now() / 1000) + expiration * 60, iat: Math.floor(Date.now() / 1000), iss: issuer, jti, nbf: Math.floor(Date.now() / 1000), sub, }; const headers = { alg: 'HS256', typ: 'JWT', }; return new SignJWT(payload).setProtectedHeader(headers).sign(secretEncoded); }; export const signEdDSAJWT = async (privateKey, issuer, audience, jti, sub, expiration) => { const privateKeyEncoded = await importPKCS8(privateKey, 'EdDSA'); const payload = { aud: audience, exp: Math.floor(Date.now() / 1000) + expiration * 60, iat: Math.floor(Date.now() / 1000), iss: issuer, jti, nbf: Math.floor(Date.now() / 1000), sub, }; const headers = { alg: 'EdDSA', typ: 'JWT', }; return new SignJWT(payload) .setProtectedHeader(headers) .sign(privateKeyEncoded); }; export const verifyEdDSAJWT = async (token, publicKey, audience, issuer) => { try { const publicKeyEncoded = await importSPKI(publicKey, 'EdDSA'); const options = { audience, issuer, }; return jwtVerify(token, publicKeyEncoded, options); } catch (error) { throw new AppError('Invalid JWT', 401, error); } }; export const extractJWTFromAuthHeader = (req) => { const { authorization } = req.headers; if (authorization?.startsWith('Bearer ')) { return authorization.split(' ')[1]; } return undefined; }; export const validateJWTPayload = (jwtPayload) => { const JWTPayloadSchema = z.object({ aud: z.string(), exp: z.number(), iat: z.number(), iss: z.string(), jti: z.string(), nbf: z.number(), sub: z.string(), }); const validation = JWTPayloadSchema.safeParse(jwtPayload); if (!validation.success) { throw new AppError('Invalid JWT payload', 401, validation.error); } return validation.data; }; export const decodeJWTPayload = (token) => { const jwtPayload = decodeJwt(token); return validateJWTPayload(jwtPayload); };