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