import { type DB } from "../../core";
import { type Static, type TObject } from "../../core/utils";
import type { Context, Hono } from "hono";
import { sign } from "hono/jwt";
import type { ServerEnv } from "../../modules/Controller";
import * as tbbox from "@sinclair/typebox";
export type JWTPayload = Parameters<typeof sign>[0];
export declare const strategyActions: readonly ["create", "change"];
export type StrategyActionName = (typeof strategyActions)[number];
export type StrategyAction<S extends TObject = TObject> = {
    schema: S;
    preprocess: (input: Static<S>) => Promise<Omit<DB["users"], "id" | "strategy">>;
};
export type StrategyActions = Partial<Record<StrategyActionName, StrategyAction>>;
export interface Strategy {
    getController: (auth: Authenticator) => Hono<any>;
    getType: () => string;
    getMode: () => "form" | "external";
    getName: () => string;
    toJSON: (secrets?: boolean) => any;
    getActions?: () => StrategyActions;
}
export type User = DB["users"];
export type ProfileExchange = {
    email?: string;
    strategy?: string;
    strategy_value?: string;
    [key: string]: any;
};
export type SafeUser = Omit<User, "strategy_value">;
export type CreateUser = Pick<User, "email"> & {
    [key: string]: any;
};
export type AuthResponse = {
    user: SafeUser;
    token: string;
};
export interface UserPool {
    findBy: (strategy: string, prop: keyof SafeUser, value: string | number) => Promise<User>;
    create: (strategy: string, user: CreateUser) => Promise<User>;
}
export declare const cookieConfig: TObject<{
    path: tbbox.TOptional<tbbox.TString>;
    sameSite: tbbox.TOptional<tbbox.TUnsafe<"strict" | "lax" | "none">>;
    secure: tbbox.TOptional<tbbox.TBoolean>;
    httpOnly: tbbox.TOptional<tbbox.TBoolean>;
    expires: tbbox.TOptional<tbbox.TNumber>;
    renew: tbbox.TOptional<tbbox.TBoolean>;
    pathSuccess: tbbox.TOptional<tbbox.TString>;
    pathLoggedOut: tbbox.TOptional<tbbox.TString>;
}>;
export declare const jwtConfig: TObject<{
    secret: tbbox.TString;
    alg: tbbox.TOptional<tbbox.TUnsafe<"HS256" | "HS384" | "HS512">>;
    expires: tbbox.TOptional<tbbox.TNumber>;
    issuer: tbbox.TOptional<tbbox.TString>;
    fields: tbbox.TArray<tbbox.TString>;
}>;
export declare const authenticatorConfig: TObject<{
    jwt: TObject<{
        secret: tbbox.TString;
        alg: tbbox.TOptional<tbbox.TUnsafe<"HS256" | "HS384" | "HS512">>;
        expires: tbbox.TOptional<tbbox.TNumber>;
        issuer: tbbox.TOptional<tbbox.TString>;
        fields: tbbox.TArray<tbbox.TString>;
    }>;
    cookie: TObject<{
        path: tbbox.TOptional<tbbox.TString>;
        sameSite: tbbox.TOptional<tbbox.TUnsafe<"strict" | "lax" | "none">>;
        secure: tbbox.TOptional<tbbox.TBoolean>;
        httpOnly: tbbox.TOptional<tbbox.TBoolean>;
        expires: tbbox.TOptional<tbbox.TNumber>;
        renew: tbbox.TOptional<tbbox.TBoolean>;
        pathSuccess: tbbox.TOptional<tbbox.TString>;
        pathLoggedOut: tbbox.TOptional<tbbox.TString>;
    }>;
}>;
type AuthConfig = Static<typeof authenticatorConfig>;
export type AuthAction = "login" | "register";
export type AuthResolveOptions = {
    identifier?: "email" | string;
    redirect?: string;
    forceJsonResponse?: boolean;
};
export type AuthUserResolver = (action: AuthAction, strategy: Strategy, profile: ProfileExchange, opts?: AuthResolveOptions) => Promise<ProfileExchange | undefined>;
type AuthClaims = SafeUser & {
    iat: number;
    iss?: string;
    exp?: number;
};
export declare class Authenticator<Strategies extends Record<string, Strategy> = Record<string, Strategy>> {
    private readonly strategies;
    private readonly userPool;
    private readonly config;
    constructor(strategies: Strategies, userPool: UserPool, config?: AuthConfig);
    resolveLogin(c: Context, strategy: Strategy, profile: Partial<SafeUser>, verify: (user: User) => Promise<void>, opts?: AuthResolveOptions): Promise<(Response & import("hono").TypedResponse<{
        user: {
            email: string;
            id: string | number | {
                readonly __select__: string | number;
                readonly __insert__: string | number | undefined;
                readonly __update__: string | number;
            };
            role?: string | undefined;
            strategy: string;
        };
        token: string;
    }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<undefined, 302, "redirect">)>;
    resolveRegister(c: Context, strategy: Strategy, profile: CreateUser, verify: (user: User) => Promise<void>, opts?: AuthResolveOptions): Promise<(Response & import("hono").TypedResponse<{
        user: {
            email: string;
            id: string | number | {
                readonly __select__: string | number;
                readonly __insert__: string | number | undefined;
                readonly __update__: string | number;
            };
            role?: string | undefined;
            strategy: string;
        };
        token: string;
    }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<undefined, 302, "redirect">)>;
    private respondWithUser;
    respondWithError(c: Context, error: Error, opts?: AuthResolveOptions): Promise<Response & import("hono").TypedResponse<undefined, 302, "redirect">>;
    getStrategies(): Strategies;
    strategy<StrategyName extends keyof Strategies, Strat extends Strategy = Strategies[StrategyName]>(strategy: StrategyName): Strat;
    jwt(_user: SafeUser | ProfileExchange): Promise<string>;
    safeAuthResponse(_user: User): Promise<AuthResponse>;
    verify(jwt: string): Promise<AuthClaims | undefined>;
    private get cookieOptions();
    private getAuthCookie;
    requestCookieRefresh(c: Context<ServerEnv>): Promise<void>;
    private setAuthCookie;
    private deleteAuthCookie;
    logout(c: Context<ServerEnv>): Promise<void>;
    isJsonRequest(c: Context): boolean;
    getBody(c: Context): Promise<any>;
    private getSafeUrl;
    resolveAuthFromRequest(c: Context): Promise<SafeUser | undefined>;
    toJSON(secrets?: boolean): {
        jwt: {
            alg?: "HS256" | "HS384" | "HS512" | undefined;
            expires?: number | undefined;
            issuer?: string | undefined;
            secret: string;
            fields: string[];
        } | undefined;
        cookie: {
            path?: string | undefined;
            expires?: number | undefined;
            sameSite?: "strict" | "lax" | "none" | undefined;
            secure?: boolean | undefined;
            httpOnly?: boolean | undefined;
            renew?: boolean | undefined;
            pathSuccess?: string | undefined;
            pathLoggedOut?: string | undefined;
        };
    };
}
export {};
