@trifrost/core
Version:
Blazingly fast, runtime-agnostic server framework for modern edge and node environments
71 lines (70 loc) • 3.2 kB
JavaScript
;
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;
}