UNPKG

@trifrost/core

Version:

Blazingly fast, runtime-agnostic server framework for modern edge and node environments

71 lines (70 loc) 3.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Sym_TriFrostMiddlewareSessionCookieAuth = void 0; exports.SessionCookieAuth = SessionCookieAuth; const constants_1 = require("../../types/constants"); const types_1 = require("./types"); /* Specific symbol attached to auth mware to identify them by */ exports.Sym_TriFrostMiddlewareSessionCookieAuth = Symbol('TriFrost.Middleware.SessionCookieAuth'); /** * Session Cookie Authentication middleware. * * This middleware retrieves a named cookie from the request, typically holding * a session identifier, and calls the provided validate() function. If valid, * the `$auth` state is set on the context. * * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies * * @example * .use(SessionCookieAuth({ * cookie: 'session_id', * validate: (ctx, value) => lookupSession(value) * })) */ function SessionCookieAuth(opts) { if (typeof opts?.cookie !== 'string' || !opts.cookie.length) throw new Error('TriFrostMiddleware@SessionCookieAuth: A cookie name must be provided'); /* Define secret function */ let secretFn; const secretType = typeof opts.secret?.val; if (secretType === 'function') { secretFn = opts.secret.val; } else if (secretType === 'string' && opts.secret.val.length) { secretFn = () => opts.secret.val; } else { throw new Error('TriFrostMiddleware@SessionCookieAuth: A secret must be provided'); } const algorithm = typeof opts.secret.algorithm === 'string' ? opts.secret.algorithm : 'SHA-256'; const validateFn = typeof opts.validate === 'function' ? opts.validate : null; const mware = async function TriFrostSessionCookieAuth(ctx) { /* Get cookie, if cookie is not found return 401 */ const cookie = ctx.cookies.get(opts.cookie); if (typeof cookie !== 'string' || !cookie.length) return ctx.status(401); /* Get resolved secret */ const secret = secretFn(ctx); if (typeof secret !== 'string' || !secret.length) return ctx.status(401); /* Verify HMAC signature */ const verified = await ctx.cookies.verify(cookie, secret, { algorithm }); if (!verified) return ctx.status(401); /* If no validation function, set state and continue */ if (!validateFn) return ctx.setState({ $auth: { cookie: verified } }); /* Validate, if not valid return 401 */ const result = await validateFn(ctx, verified); if (!result) return ctx.status(401); const authenticated = result === true ? { cookie: verified } : result; return ctx.setState({ $auth: authenticated }); }; /* Add symbols for introspection/use further down the line */ Reflect.set(mware, constants_1.Sym_TriFrostName, 'TriFrostSessionCookieAuth'); Reflect.set(mware, constants_1.Sym_TriFrostDescription, 'Session Cookie Authentication middleware'); Reflect.set(mware, types_1.Sym_TriFrostMiddlewareAuth, true); Reflect.set(mware, constants_1.Sym_TriFrostFingerPrint, exports.Sym_TriFrostMiddlewareSessionCookieAuth); return mware; }