UNPKG

@trifrost/core

Version:

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

74 lines (73 loc) 3.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Sym_TriFrostMiddlewareApiKeyAuth = void 0; exports.ApiKeyAuth = ApiKeyAuth; 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_TriFrostMiddlewareApiKeyAuth = Symbol('TriFrost.Middleware.ApiKeyAuth'); /** * API Key Authentication middleware. * * This middleware checks for an API key either in the request headers or * query parameters, using configurable names. It then calls the provided * validate() function. If valid, the `$auth` state is set on the context. * * @see https://swagger.io/docs/specification/authentication/api-keys/ * * @example * .use(ApiKeyAuth({ * apiKey: {header: 'x-api-key'}, * apiClient: {header: 'x-api-id'}, * validate: (ctx, key) => key === ctx.env.MY_API_KEY * })) */ function ApiKeyAuth(opts) { if (typeof opts?.validate !== 'function') throw new Error('TriFrostMiddleware@ApiKeyAuth: A validate function must be provided'); const hasApiKeyHeader = (0, string_1.isNeString)(opts.apiKey?.header); const hasApiKeyQuery = (0, string_1.isNeString)(opts.apiKey?.query); if (!hasApiKeyHeader && !hasApiKeyQuery) { throw new Error('TriFrostMiddleware@ApiKeyAuth: You must configure apiKey header or query'); } /* Determine key behavior */ const apiKeyHeader = hasApiKeyHeader ? opts.apiKey.header : null; const apiKeyQuery = hasApiKeyQuery ? opts.apiKey.query : null; /* Determine client behavior */ const apiClientHeader = (0, string_1.isNeString)(opts.apiClient?.header) ? opts.apiClient.header : null; const apiClientQuery = (0, string_1.isNeString)(opts.apiClient?.query) ? opts.apiClient.query : null; const apiClientEnabled = apiClientHeader || apiClientQuery; const mware = async function TriFrostApiKeyAuth(ctx) { /* Api Client */ let apiClient = null; if (apiClientEnabled) { if (apiClientHeader) apiClient = ctx.headers[apiClientHeader]; if (!apiClient && apiClientQuery) apiClient = ctx.query.get(apiClientQuery); if (typeof apiClient !== 'string' || !apiClient.length) return ctx.status(401); } /* Get value from header, falling back to query */ let apiKey = null; if (apiKeyHeader) apiKey = ctx.headers[apiKeyHeader]; if (!apiKey && apiKeyQuery) apiKey = ctx.query.get(apiKeyQuery); if (typeof apiKey !== 'string' || !apiKey.length) return ctx.status(401); /* Validate, if not valid return 401 */ const result = await opts.validate(ctx, { apiKey, apiClient }); if (!result) return ctx.status(401); const authenticated = result === true ? { apiKey, apiClient } : result; return ctx.setState({ $auth: authenticated }); }; /* Add symbols for introspection/use further down the line */ Reflect.set(mware, constants_1.Sym_TriFrostName, 'TriFrostApiKeyAuth'); Reflect.set(mware, constants_1.Sym_TriFrostDescription, 'API Key Authentication middleware'); Reflect.set(mware, types_1.Sym_TriFrostMiddlewareAuth, true); Reflect.set(mware, constants_1.Sym_TriFrostFingerPrint, exports.Sym_TriFrostMiddlewareApiKeyAuth); return mware; }