@httpc/kit
Version:
httpc toolbox for building function-based API with minimal code and end-to-end type safety
55 lines (54 loc) • 2.38 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthenticationApiKeyMiddleware = void 0;
const server_1 = require("@httpc/server");
const di_1 = require("../di");
const context_1 = require("./context");
const services_1 = require("../services");
function AuthenticationApiKeyMiddleware(options) {
const authenticate = options?.onAuthenticate || onAuthenticate;
const extractKey = options?.extractKey || extractApiKey;
return (0, server_1.PassthroughMiddleware)(async () => {
const { request, user } = (0, server_1.useContext)();
// try to authenticate if not already present
if (!user) {
const apiKey = extractKey(request);
if (apiKey) {
(0, context_1.useAuthentication)(await authenticate(apiKey)
.catch((0, services_1.catchLogAndThrowUnauthorized)("ApiKeyMiddleware")));
}
}
});
}
exports.AuthenticationApiKeyMiddleware = AuthenticationApiKeyMiddleware;
/**
* Look for api key in the request in this order
* 1. apikey or api-key or x-api-key header
* 2. authorization header with schema APIKEY or API_KEY
* 3. query string with param apikey or api_key
*/
function extractApiKey(request) {
const apiKey = (request.headers["apikey"] || request.headers["api_key"] || request.headers["api-key"] || request.headers["x-api-key"]);
if (apiKey) {
return apiKey.trim();
}
if (request.headers.authorization) {
let [schema, token] = request.headers.authorization.split(" ");
schema = schema.toLowerCase();
if (schema === "api-key" || schema === "api_key" || schema === "apikey") {
return token.trim() || undefined;
}
}
if (request.url) {
let qs = new URL(request.url, `https://${request.headers.host}`).searchParams;
// lowercase all param names
qs = new URLSearchParams([...qs.entries()].map(([key, value]) => [key.toLowerCase(), value]));
return (qs.get("api_key") || qs.get("api-key") || qs.get("apikey"))?.trim() || undefined;
}
}
async function onAuthenticate(apiKey) {
const container = (0, di_1.useContainer)();
const auth = (0, di_1.RESOLVE)(container, "ApiKeyAuthentication");
return await auth.authenticate(apiKey);
}
//cspell: ignore apikey