UNPKG

@trifrost/core

Version:

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

60 lines (59 loc) 2.62 kB
import { isNeString } from '@valkyriestudios/utils/string'; import { Sym_TriFrostDescription, Sym_TriFrostFingerPrint, Sym_TriFrostName } from '../../types/constants'; import { Sym_TriFrostMiddlewareAuth } from './types'; /* Specific symbol attached to auth mware to identify them by */ export const Sym_TriFrostMiddlewareBasicAuth = Symbol('TriFrost.Middleware.BasicAuth'); /** * HTTP Basic Authentication middleware. * * This middleware extracts the `Authorization` header using the Basic scheme, * decodes the base64-encoded username and password, 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/Authentication#basic_authentication_scheme * * @example * .use(BasicAuth({ * validate: (ctx, {user, pass}) => user === 'admin' && pass === ctx.env.ADMIN_SECRET * })) */ export function BasicAuth(opts) { if (typeof opts?.validate !== 'function') throw new Error('TriFrostMiddleware@BasicAuth: A validate function must be provided'); const realm = isNeString(opts.realm) ? opts.realm : 'Restricted Area'; const NOT_AUTH = 'Basic realm="' + realm + '"'; const mware = async function TriFrostBasicAuth(ctx) { const authHeader = ctx.headers.authorization; if (typeof authHeader !== 'string' || !authHeader.startsWith('Basic ')) { ctx.setHeader('www-authenticate', NOT_AUTH); return ctx.status(401); } let decoded = ''; try { decoded = atob(authHeader.slice(6).trim()); } catch { /* Nothing to do here */ } const idx = decoded.indexOf(':'); if (idx === -1) { ctx.setHeader('www-authenticate', NOT_AUTH); return ctx.status(401); } const user = decoded.slice(0, idx); const pass = decoded.slice(idx + 1); const result = await opts.validate(ctx, { user, pass }); if (!result) { ctx.setHeader('www-authenticate', NOT_AUTH); return ctx.status(401); } const authenticated = result === true ? { user } : result; return ctx.setState({ $auth: authenticated }); }; /* Add symbols for introspection/use further down the line */ Reflect.set(mware, Sym_TriFrostName, 'TriFrostBasicAuth'); Reflect.set(mware, Sym_TriFrostDescription, 'HTTP Basic Authentication middleware'); Reflect.set(mware, Sym_TriFrostMiddlewareAuth, true); Reflect.set(mware, Sym_TriFrostFingerPrint, Sym_TriFrostMiddlewareBasicAuth); return mware; }