// @ts-nocheck
import { SessionContainerInterface } from "./recipe/session/types";
import { UserContext } from "./types";
import { LoginMethod, User } from "./user";
import RecipeUserId from "./recipeUserId";
import { AccountInfoWithRecipeId } from "./recipe/accountlinking/types";
import type { BaseRequest, BaseResponse } from "./framework";
import type SuperTokens from "./supertokens";
export declare const AuthUtils: {
    /**
     * This helper function can be used to map error statuses (w/ an optional reason) to error responses with human readable reasons.
     * This maps to a response in the format of `{ status: "3rd param", reason: "human readable string from second param" }`
     *
     * The errorCodeMap is expected to be something like:
     * ```
     * {
     *      EMAIL_VERIFICATION_REQUIRED: "This is returned as reason if the resp(1st param) has the status code EMAIL_VERIFICATION_REQUIRED and an undefined reason",
     *      STATUS: {
     *          REASON: "This is returned as reason if the resp(1st param) has STATUS in the status prop and REASON in the reason prop"
     *      }
     * }
     * ```
     */
    getErrorStatusResponseWithReason<T = "SIGN_IN_UP_NOT_ALLOWED">(resp: {
        status: string;
        reason?: string;
    }, errorCodeMap: Record<string, Record<string, string | undefined> | string | undefined>, errorStatus: T): {
        status: T;
        reason: string;
    };
    /**
     * Runs all checks we need to do before trying to authenticate a user:
     * - if this is a first factor auth or not
     * - if the session user is required to be primary (and tries to make it primary if necessary)
     * - if any of the factorids are valid (as first or secondary factors), taking into account mfa factor setup rules
     * - if sign up is allowed (if isSignUp === true)
     *
     * It returns the following statuses:
     * - OK: the auth flow can proceed
     * - SIGN_UP_NOT_ALLOWED: if isSignUpAllowed returned false. This is mostly because of conflicting users with the same account info
     * - LINKING_TO_SESSION_USER_FAILED (SESSION_USER_ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR):
     * if the session user should become primary but we couldn't make it primary because of a conflicting primary user.
     */
    preAuthChecks: ({ stInstance, authenticatingAccountInfo, tenantId, isSignUp, isVerified, signInVerifiesLoginMethod, authenticatingUser, factorIds, skipSessionUserUpdateInCore, session, shouldTryLinkingWithSessionUser, userContext, }: {
        stInstance: SuperTokens;
        authenticatingAccountInfo: AccountInfoWithRecipeId;
        authenticatingUser: User | undefined;
        tenantId: string;
        factorIds: string[];
        isSignUp: boolean;
        isVerified: boolean;
        signInVerifiesLoginMethod: boolean;
        skipSessionUserUpdateInCore: boolean;
        session?: SessionContainerInterface;
        shouldTryLinkingWithSessionUser: boolean | undefined;
        userContext: UserContext;
    }) => Promise<{
        status: "OK";
        validFactorIds: string[];
        isFirstFactor: boolean;
    } | {
        status: "SIGN_UP_NOT_ALLOWED";
    } | {
        status: "SIGN_IN_NOT_ALLOWED";
    } | {
        status: "LINKING_TO_SESSION_USER_FAILED";
        reason: "SESSION_USER_ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR";
    }>;
    /**
     * Runs the linking process and all check we need to before creating a session + creates the new session if necessary:
     * - runs the linking process which will: try to link to the session user, or link by account info or try to make the authenticated user primary
     * - checks if sign in is allowed (if isSignUp === false)
     * - creates a session if necessary
     * - marks the factor as completed if necessary
     *
     * It returns the following statuses:
     * - OK: the auth flow went as expected
     * - LINKING_TO_SESSION_USER_FAILED(EMAIL_VERIFICATION_REQUIRED): if we couldn't link to the session user because linking requires email verification
     * - LINKING_TO_SESSION_USER_FAILED(RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR):
     * if we couldn't link to the session user because the authenticated user has been linked to another primary user concurrently
     * - LINKING_TO_SESSION_USER_FAILED(ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR):
     * if we couldn't link to the session user because of a conflicting primary user that has the same account info as authenticatedUser
     * - LINKING_TO_SESSION_USER_FAILED (SESSION_USER_ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR):
     * if the session user should be primary but we couldn't make it primary because of a conflicting primary user.
     */
    postAuthChecks: ({ stInstance, authenticatedUser, recipeUserId, isSignUp, factorId, session, req, res, tenantId, userContext, }: {
        stInstance: SuperTokens;
        authenticatedUser: User;
        recipeUserId: RecipeUserId;
        tenantId: string;
        factorId: string;
        isSignUp: boolean;
        session?: SessionContainerInterface;
        userContext: UserContext;
        req: BaseRequest;
        res: BaseResponse;
    }) => Promise<{
        status: "OK";
        session: SessionContainerInterface;
        user: User;
    } | {
        status: "SIGN_IN_NOT_ALLOWED";
    }>;
    /**
     * This function tries to find the authenticating user (we use this information to see if the current auth is sign in or up)
     * if a session was passed and the authenticating user was not found on the current tenant, it checks if the session user
     * has a matching login method on other tenants. If it does and the credentials check out on the other tenant, it associates
     * the recipe user for the login method (matching account info, recipeId and credentials) with the current tenant.
     *
     * While this initially complicates the auth logic, we want to avoid creating a new recipe user if a tenant association will do,
     * because it'll make managing MFA factors (i.e.: secondary passwords) a lot easier for the app, and,
     * most importantly, this way all secondary factors are app-wide instead of mixing app-wide (totp) and tenant-wide (password) factors.
     */
    getAuthenticatingUserAndAddToCurrentTenantIfRequired: ({ stInstance, recipeId, accountInfo, checkCredentialsOnTenant, tenantId, session, userContext, }: {
        stInstance: SuperTokens;
        recipeId: string;
        accountInfo: {
            email: string;
            thirdParty?: undefined;
            phoneNumber?: undefined;
            webauthn?: undefined;
        } | {
            email?: undefined;
            thirdParty?: undefined;
            phoneNumber: string;
            webauthn?: undefined;
        } | {
            email?: undefined;
            thirdParty: {
                id: string;
                userId: string;
            };
            phoneNumber?: undefined;
            webauthn?: undefined;
        } | {
            email?: undefined;
            thirdParty?: undefined;
            phoneNumber?: undefined;
            webauthn: {
                credentialId: string;
            };
        };
        tenantId: string;
        session: SessionContainerInterface | undefined;
        checkCredentialsOnTenant: (tenantId: string) => Promise<boolean>;
        userContext: UserContext;
    }) => Promise<{
        user: User;
        loginMethod: LoginMethod;
    } | undefined>;
    /**
     * This function checks if the current authentication attempt should be considered a first factor or not.
     * To do this it'll also need to (if a session was passed):
     * - load the session user (and possibly make it primary)
     * - check the linking status of the input and session user
     * - call and check the results of shouldDoAutomaticAccountLinking
     * So in the non-first factor case it also returns the results of those checks/operations.
     *
     * It returns the following statuses:
     * - OK: if everything went well
     * - LINKING_TO_SESSION_USER_FAILED (SESSION_USER_ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR):
     * if the session user should be primary but we couldn't make it primary because of a conflicting primary user.
     */
    checkAuthTypeAndLinkingStatus: (stInstance: SuperTokens, session: SessionContainerInterface | undefined, shouldTryLinkingWithSessionUser: boolean | undefined, accountInfo: AccountInfoWithRecipeId, inputUser: User | undefined, skipSessionUserUpdateInCore: boolean, userContext: UserContext) => Promise<{
        status: "OK";
        isFirstFactor: true;
    } | {
        status: "OK";
        isFirstFactor: false;
        inputUserAlreadyLinkedToSessionUser: true;
        sessionUser: User;
    } | {
        status: "OK";
        isFirstFactor: false;
        inputUserAlreadyLinkedToSessionUser: false;
        sessionUser: User;
        linkingToSessionUserRequiresVerification: boolean;
    } | {
        status: "LINKING_TO_SESSION_USER_FAILED";
        reason: "SESSION_USER_ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR";
    }>;
    /**
     * This function checks the auth type (first factor or not), links by account info for first factor auths otherwise
     * it tries to link the input user to the session user
     *
     * It returns the following statuses:
     * - OK: the linking went as expected
     * - LINKING_TO_SESSION_USER_FAILED(EMAIL_VERIFICATION_REQUIRED): if we couldn't link to the session user because linking requires email verification
     * - LINKING_TO_SESSION_USER_FAILED(RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR):
     * if we couldn't link to the session user because the authenticated user has been linked to another primary user concurrently
     * - LINKING_TO_SESSION_USER_FAILED(ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR):
     * if we couldn't link to the session user because of a conflicting primary user that has the same account info as authenticatedUser
     * - LINKING_TO_SESSION_USER_FAILED (SESSION_USER_ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR):
     * if the session user should be primary but we couldn't make it primary because of a conflicting primary user.
     */
    linkToSessionIfRequiredElseCreatePrimaryUserIdOrLinkByAccountInfo: ({ stInstance, tenantId, inputUser, recipeUserId, session, shouldTryLinkingWithSessionUser, userContext, }: {
        stInstance: SuperTokens;
        tenantId: string;
        inputUser: User;
        recipeUserId: RecipeUserId;
        session: SessionContainerInterface | undefined;
        shouldTryLinkingWithSessionUser: boolean | undefined;
        userContext: UserContext;
    }) => Promise<{
        status: "OK";
        user: User;
    } | {
        status: "LINKING_TO_SESSION_USER_FAILED";
        reason: "EMAIL_VERIFICATION_REQUIRED" | "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR" | "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR" | "SESSION_USER_ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR";
    }>;
    /**
     * This function loads the session user and tries to make it primary.
     * It returns:
     * - OK: if the session user was a primary user or we made it into one or it can/should become one but `skipSessionUserUpdateInCore` is set to true
     * - SHOULD_AUTOMATICALLY_LINK_FALSE: if shouldDoAutomaticAccountLinking returned `{ shouldAutomaticallyLink: false }`
     * - ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR:
     * If we tried to make it into a primary user but it didn't succeed because of a conflicting primary user
     *
     * It throws INVALID_CLAIM_ERROR if shouldDoAutomaticAccountLinking returned `{ shouldAutomaticallyLink: false }` but the email verification status was wrong
     */
    tryAndMakeSessionUserIntoAPrimaryUser: (stInstance: SuperTokens, session: SessionContainerInterface, skipSessionUserUpdateInCore: boolean, userContext: UserContext) => Promise<{
        status: "OK";
        sessionUser: User;
    } | {
        status: "SHOULD_AUTOMATICALLY_LINK_FALSE";
    } | {
        status: "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR";
    }>;
    /**
     * This function tries linking by session, and doesn't attempt to make the authenticated user a primary or link it by account info
     *
     * It returns the following statuses:
     * - OK: the linking went as expected
     * - LINKING_TO_SESSION_USER_FAILED(EMAIL_VERIFICATION_REQUIRED): if we couldn't link to the session user because linking requires email verification
     * - LINKING_TO_SESSION_USER_FAILED(RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR):
     * if we couldn't link to the session user because the authenticated user has been linked to another primary user concurrently
     * - LINKING_TO_SESSION_USER_FAILED(ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR):
     * if we couldn't link to the session user because of a conflicting primary user that has the same account info as authenticatedUser
     * - LINKING_TO_SESSION_USER_FAILED (INPUT_USER_IS_NOT_A_PRIMARY_USER):
     * if the session user is not primary. This can be resolved by making it primary and retrying the call.
     */
    tryLinkingBySession: ({ stInstance, linkingToSessionUserRequiresVerification, authLoginMethod, authenticatedUser, sessionUser, userContext, }: {
        stInstance: SuperTokens;
        authenticatedUser: User;
        linkingToSessionUserRequiresVerification: boolean;
        sessionUser: User;
        authLoginMethod: LoginMethod;
        userContext: UserContext;
    }) => Promise<{
        status: "OK";
        user: User;
    } | {
        status: "LINKING_TO_SESSION_USER_FAILED";
        reason: "EMAIL_VERIFICATION_REQUIRED" | "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR" | "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR";
    } | {
        status: "LINKING_TO_SESSION_USER_FAILED";
        reason: "INPUT_USER_IS_NOT_A_PRIMARY_USER";
    }>;
    filterOutInvalidFirstFactorsOrThrowIfAllAreInvalid: (stInstance: SuperTokens, factorIds: string[], tenantId: string, hasSession: boolean, userContext: UserContext) => Promise<string[]>;
    loadSessionInAuthAPIIfNeeded: (stInstance: SuperTokens, req: BaseRequest, res: BaseResponse, shouldTryLinkingWithSessionUser: boolean | undefined, userContext: UserContext) => Promise<SessionContainerInterface | undefined>;
};
