UNPKG

@authx/http-proxy-resource

Version:

The AuthX proxy for resources is a flexible HTTP proxy designed to sit in front of a resource.

151 lines (150 loc) 5.39 kB
/// <reference types="node" resolution-mode="require"/> /// <reference types="node" resolution-mode="require"/> import { EventEmitter } from "events"; import { Server, IncomingMessage, ServerResponse } from "http"; import { ServerOptions } from "http-proxy"; export { AuthXKeyCache } from "./AuthXKeyCache.js"; export { validateAuthorizationHeader, NotAuthorizedError, } from "./validateAuthorizationHeader.js"; export interface Behavior { /** * The options to pass to node-proxy. * * @remarks * The HTTP header `X-OAuth-Scopes` will be set on both the request and * response, containing a space-deliminated list of authorized scopes from a * valid token. * * If a valid token contains no scopes, the `X-OAuth-Scopes` will be an empty * string. * * If no token exists, or the token is invalid, the `X-OAuth-Scopes` will be * removed from both the request and response. */ readonly proxyOptions: ServerOptions; /** * If set to true, proxied requests will retain the token in their HTTP * `Authorization` header. Only valid tokens will be sent to the target. * * @defaultValue `false` */ readonly sendTokenToTarget?: boolean; /** * The minimum scopes required for a request to be proxied. * * @remarks * If one or more scopes are configured, the proxy will ensure that they are * provided by a valid token, returning a 401 for a missing or invalid token, * and a 403 for a valid token that is missing required scopes. The header * `X-OAuth-Required-Scopes` will be set on both the request and response, * containing a space-deliminated list of the required scopes. * * To ensure that a valid token is present, use an empty array. * * If this option is not set, all requests will be proxied to the target. */ readonly requireScopes?: string[]; } export interface Rule { /** * Each rule is tested in order, with the first to return `true` used to * handle the request. This function MUST NOT manipulate the `request` object. */ readonly test: (request: IncomingMessage) => boolean; /** * The behavior to use for a matching request. * * @remarks * If the request must be modified, such as to change the URL path, a custom * function can be used here. This function will be called _after_ the * `X-OAuth-Scopes` headers have been set or removed. * * If the function handles the request (such as returning an error), it must * return `undefined` to prevent the proxy from also attempting to handle it; * otherwise, it should return a `Behavior` config. */ readonly behavior: Behavior | ((request: IncomingMessage, response: ServerResponse) => Behavior | undefined); } export interface Config { /** * The root URL to AuthX server. */ readonly authxUrl: string; /** * The number of seconds between successful attempts at refreshing public keys * from the AuthX server. * * @defaultValue `60` */ readonly authxPublicKeyRefreshInterval?: number; /** * The number of seconds to wait before aborting and retrying a request for * public keys from the AuthX server. * * @defaultValue `30` */ readonly authxPublicKeyRefreshRequestTimeout?: number; /** * The number of seconds between failed attempts at refreshing public keys * from the AuthX server. * * @defaultValue `10` */ readonly authxPublicKeyRetryInterval?: number; /** * The pathname at which the proxy will provide a readiness check. * * @remarks * Requests to this path will return a 200 with the body "READY" when the * proxy is ready to accept incoming connections, and a 503 with the body * "NOT READY" otherwise. * * When closing the proxy, readiness checks will immediately begin failing, * even before the proxy stops accepting requests. * * @defaultValue `"/_ready"` */ readonly readinessEndpoint?: string; /** * The number of seconds for which the proxy will cache the AuthX server's * token introspection response for a revocable token. * * @defaultValue `60` */ readonly revocableTokenCacheDuration?: number; /** * The rules the proxy will use to handle a request. */ readonly rules: Rule[]; } export interface Metadata { request: IncomingMessage; response: ServerResponse; rule: undefined | Rule; behavior: undefined | Behavior; message: string; authorizationId: undefined | string; authorizationSubject: undefined | string; authorizationScopes: undefined | ReadonlyArray<string>; } export default class AuthXResourceProxy extends EventEmitter { private readonly _config; private readonly _proxy; private _closed; private _closing; private _cache; private readonly _tokenDataCache; readonly server: Server; constructor(config: Config); private _callback; listen(options?: number | { port: number; host?: string; path?: string; backlog?: number; exclusive?: boolean; readableAll?: boolean; writableAll?: boolean; ipv6Only?: boolean; }): Promise<void>; close(delay?: number): Promise<void>; }