@trifrost/core
Version:
Blazingly fast, runtime-agnostic server framework for modern edge and node environments
64 lines (63 loc) • 2.76 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Sym_TriFrostMiddlewareBasicAuth = void 0;
exports.BasicAuth = BasicAuth;
const string_1 = require("@valkyriestudios/utils/string");
const constants_1 = require("../../types/constants");
const types_1 = require("./types");
/* Specific symbol attached to auth mware to identify them by */
exports.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
* }))
*/
function BasicAuth(opts) {
if (typeof opts?.validate !== 'function')
throw new Error('TriFrostMiddleware@BasicAuth: A validate function must be provided');
const realm = (0, string_1.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, constants_1.Sym_TriFrostName, 'TriFrostBasicAuth');
Reflect.set(mware, constants_1.Sym_TriFrostDescription, 'HTTP Basic Authentication middleware');
Reflect.set(mware, types_1.Sym_TriFrostMiddlewareAuth, true);
Reflect.set(mware, constants_1.Sym_TriFrostFingerPrint, exports.Sym_TriFrostMiddlewareBasicAuth);
return mware;
}