@httpc/kit
Version:
httpc toolbox for building function-based API with minimal code and end-to-end type safety
43 lines (42 loc) • 1.74 kB
JavaScript
import { PassthroughMiddleware, UnauthorizedError, useContext } from "@httpc/server";
import { RESOLVE, useContainer } from "../di";
import { useAuthentication } from "./context";
import { catchLogAndThrowUnauthorized } from "../services";
import { useLogger } from "../logging";
export function BasicAuthenticationMiddleware(options) {
const authenticate = options?.onAuthenticate || onAuthenticate;
function hashToCredentials(hash) {
let value;
try {
value = Buffer.from(hash, "base64").toString("utf8");
}
catch (ex) {
useLogger().error("BasicAuthenticationMiddleware: Cannot parse authorization header", ex);
return;
}
const [username, password] = value.split(":");
return {
username,
password,
};
}
return PassthroughMiddleware(async () => {
const { request, user } = useContext();
if (!user) {
const [schema, hash] = request.headers.authorization?.split(" ") || [];
if (schema?.toUpperCase() === "BASIC") {
const credentials = hashToCredentials(hash);
if (!credentials || !credentials.username || !credentials.password) {
throw new UnauthorizedError();
}
useAuthentication(await authenticate(credentials)
.catch(catchLogAndThrowUnauthorized("BasicAuthenticationMiddleware")));
}
}
});
}
async function onAuthenticate(credentials) {
const container = useContainer();
const auth = RESOLVE(container, "BasicAuthentication");
return await auth.authenticate(credentials);
}