import { Request, Response, CookieOptions, NextFunction } from 'express';
import { HttpError } from 'http-errors';

type SameSiteType = boolean | "lax" | "strict" | "none";
type TokenRetriever = (req: Request) => string | null | undefined;
type DoubleCsrfCookieOptions = Omit<CookieOptions, "httpOnly">;
declare module "http" {
    interface IncomingHttpHeaders {
        "x-csrf-token"?: string | undefined;
    }
}
declare module "express-serve-static-core" {
    interface Request {
        csrfToken?: (overwrite?: boolean) => ReturnType<CsrfTokenCreator>;
    }
}
type CsrfSecretRetriever = (req?: Request) => string | Array<string>;
type DoubleCsrfConfigOptions = Partial<DoubleCsrfConfig> & {
    getSecret: CsrfSecretRetriever;
};
type doubleCsrfProtection = (req: Request, res: Response, next: NextFunction) => void;
type RequestMethod = "GET" | "HEAD" | "PATCH" | "PUT" | "POST" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE";
type CsrfIgnoredMethods = Array<RequestMethod>;
type CsrfRequestValidator = (req: Request) => boolean;
type CsrfTokenAndHashPairValidator = (token: string, hash: string, possibleSecrets: Array<string>) => boolean;
type CsrfCookieSetter = (res: Response, name: string, value: string, options: DoubleCsrfCookieOptions) => void;
type CsrfTokenCreator = (req: Request, res: Response, ovewrite?: boolean, validateOnReuse?: boolean) => string;
type CsrfErrorConfig = {
    statusCode: number;
    message: string;
    code: string | undefined;
};
type CsrfErrorConfigOptions = Partial<CsrfErrorConfig>;
interface DoubleCsrfConfig {
    getSecret: CsrfSecretRetriever;
    cookieName: string;
    size: number;
    cookieOptions: DoubleCsrfCookieOptions;
    ignoredMethods: CsrfIgnoredMethods;
    getTokenFromRequest: TokenRetriever;
    errorConfig: CsrfErrorConfigOptions;
}
interface DoubleCsrfUtilities {
    invalidCsrfTokenError: HttpError;
    generateToken: CsrfTokenCreator;
    validateRequest: CsrfRequestValidator;
    doubleCsrfProtection: doubleCsrfProtection;
}

declare function doubleCsrf({ getSecret, cookieName, cookieOptions: { sameSite, path, secure, ...remainingCookieOptions }, size, ignoredMethods, getTokenFromRequest, errorConfig: { statusCode, message, code, }, }: DoubleCsrfConfigOptions): DoubleCsrfUtilities;

export { type CsrfCookieSetter, type CsrfErrorConfig, type CsrfErrorConfigOptions, type CsrfIgnoredMethods, type CsrfRequestValidator, type CsrfSecretRetriever, type CsrfTokenAndHashPairValidator, type CsrfTokenCreator, type DoubleCsrfConfig, type DoubleCsrfConfigOptions, type DoubleCsrfCookieOptions, type DoubleCsrfUtilities, type RequestMethod, type SameSiteType, type TokenRetriever, doubleCsrf, type doubleCsrfProtection };
