@pagopa/io-spid-commons
Version:
Common code for integrating SPID authentication
68 lines (67 loc) • 3.82 kB
TypeScript
/// <reference types="express-serve-static-core" />
/// <reference types="passport" />
/// <reference types="request-ip" />
import { IResponseErrorForbiddenNotAuthorized, IResponseErrorInternal, IResponseErrorValidation, IResponsePermanentRedirect } from "@pagopa/ts-commons/lib/responses";
import * as express from "express";
import * as T from "fp-ts/lib/Task";
import * as t from "io-ts";
import { SamlConfig } from "passport-saml";
import { RedisClientType, RedisClusterType } from "redis";
import { SPID_LEVELS } from "./config";
import { noopCacheProvider } from "./strategy/redis_cache_provider";
import { IServiceProviderConfig } from "./utils/middleware";
export type AssertionConsumerServiceT<T extends Record<string, unknown>> = (userPayload: unknown, extraLoginRequestParams?: T) => Promise<IResponseErrorInternal | IResponseErrorValidation | IResponsePermanentRedirect | IResponseErrorForbiddenNotAuthorized>;
export type LogoutT = () => Promise<IResponsePermanentRedirect>;
export type DoneCallbackT<T extends Record<string, unknown>> = (sourceIp: string | null, request: string, response: string, extraLoginRequest?: T) => void;
export interface IEventInfo {
readonly name: string;
readonly type: "ERROR" | "INFO";
readonly data: {
readonly [key: string]: string;
readonly message: string;
};
}
export type EventTracker = (params: IEventInfo) => void;
export interface IExtraLoginRequestParamConfig<T extends Record<string, unknown>> {
readonly codec: t.Type<T>;
readonly requestMapper: (req: express.Request) => t.Validation<T>;
}
export interface IApplicationConfig<T extends Record<string, unknown> = Record<string, never>, R = T extends Record<string, never> ? undefined : T extends Record<string, unknown> ? IExtraLoginRequestParamConfig<T> : never> {
readonly assertionConsumerServicePath: string;
readonly clientErrorRedirectionUrl: string;
readonly clientLoginRedirectionUrl: string;
readonly loginPath: string;
readonly metadataPath: string;
readonly sloPath: string;
readonly spidLevelsWhitelist: ReadonlyArray<keyof SPID_LEVELS>;
readonly startupIdpsMetadata?: Record<string, string>;
readonly eventTraker?: EventTracker;
readonly hasClockSkewLoggingEvent?: boolean;
readonly extraLoginRequestParamConfig?: R;
}
export { noopCacheProvider, IServiceProviderConfig, SamlConfig };
/**
* Wraps assertion consumer service handler
* with SPID authentication and redirects.
*/
export declare const withSpidAuthMiddleware: <T extends Record<string, unknown>>(acs: AssertionConsumerServiceT<T>, clientLoginRedirectionUrl: string, clientErrorRedirectionUrl: string, extraRequestParamsCodec?: t.Type<T, T, unknown> | undefined) => (req: express.Request, res: express.Response, next: express.NextFunction) => void;
type ExpressMiddleware = (req: express.Request, res: express.Response, next: express.NextFunction) => void;
interface IWithSpidT<T extends Record<string, unknown> = Record<string, never>> {
readonly appConfig: IApplicationConfig<T>;
readonly samlConfig: SamlConfig;
readonly serviceProviderConfig: IServiceProviderConfig;
readonly redisClient: RedisClientType | RedisClusterType;
readonly app: express.Express;
readonly acs: AssertionConsumerServiceT<T>;
readonly logout: LogoutT;
readonly doneCb?: DoneCallbackT<T>;
readonly lollipopMiddleware?: ExpressMiddleware;
}
/**
* Apply SPID authentication middleware
* to an express application.
*/
export declare const withSpid: <T extends Record<string, unknown> = Record<string, never>>({ acs, app, appConfig, doneCb, logout, redisClient, samlConfig, serviceProviderConfig, lollipopMiddleware, }: IWithSpidT<T>) => T.Task<{
readonly app: express.Express;
readonly idpMetadataRefresher: () => T.Task<void>;
}>;