// @ts-nocheck import type { BaseRequest, BaseResponse } from "../../framework"; import OverrideableBuilder from "supertokens-js-override"; import { SessionContainerInterface } from "../session/types"; import { TypeInput as EmailDeliveryTypeInput, TypeInputWithService as EmailDeliveryTypeInputWithService } from "../../ingredients/emaildelivery/types"; import EmailDeliveryIngredient from "../../ingredients/emaildelivery"; import { TypeInput as SmsDeliveryTypeInput, TypeInputWithService as SmsDeliveryTypeInputWithService } from "../../ingredients/smsdelivery/types"; import SmsDeliveryIngredient from "../../ingredients/smsdelivery"; import { GeneralErrorResponse, NormalisedAppinfo, User, UserContext } from "../../types"; import RecipeUserId from "../../recipeUserId"; export type TypeInput = ({ contactMethod: "PHONE"; validatePhoneNumber?: (phoneNumber: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL"; validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL_OR_PHONE"; validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; validatePhoneNumber?: (phoneNumber: string, tenantId: string) => Promise | string | undefined; }) & { flowType: "USER_INPUT_CODE" | "MAGIC_LINK" | "USER_INPUT_CODE_AND_MAGIC_LINK"; emailDelivery?: EmailDeliveryTypeInput; smsDelivery?: SmsDeliveryTypeInput; getCustomUserInputCode?: (tenantId: string, userContext: UserContext) => Promise | string; override?: { functions?: (originalImplementation: RecipeInterface, builder: OverrideableBuilder) => RecipeInterface; apis?: (originalImplementation: APIInterface, builder: OverrideableBuilder) => APIInterface; }; }; export type TypeNormalisedInput = ({ contactMethod: "PHONE"; validatePhoneNumber: (phoneNumber: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL"; validateEmailAddress: (email: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL_OR_PHONE"; validateEmailAddress: (email: string, tenantId: string) => Promise | string | undefined; validatePhoneNumber: (phoneNumber: string, tenantId: string) => Promise | string | undefined; }) & { flowType: "USER_INPUT_CODE" | "MAGIC_LINK" | "USER_INPUT_CODE_AND_MAGIC_LINK"; getCustomUserInputCode?: (tenantId: string, userContext: UserContext) => Promise | string; getSmsDeliveryConfig: () => SmsDeliveryTypeInputWithService; getEmailDeliveryConfig: () => EmailDeliveryTypeInputWithService; override: { functions: (originalImplementation: RecipeInterface, builder: OverrideableBuilder) => RecipeInterface; apis: (originalImplementation: APIInterface, builder: OverrideableBuilder) => APIInterface; }; }; export type RecipeInterface = { createCode: (input: ({ email: string; } | { phoneNumber: string; }) & { userInputCode?: string; session: SessionContainerInterface | undefined; shouldTryLinkingWithSessionUser: boolean | undefined; tenantId: string; userContext: UserContext; }) => Promise<{ status: "OK"; preAuthSessionId: string; codeId: string; deviceId: string; userInputCode: string; linkCode: string; codeLifetime: number; timeCreated: number; }>; createNewCodeForDevice: (input: { deviceId: string; userInputCode?: string; tenantId: string; userContext: UserContext; }) => Promise<{ status: "OK"; preAuthSessionId: string; codeId: string; deviceId: string; userInputCode: string; linkCode: string; codeLifetime: number; timeCreated: number; } | { status: "RESTART_FLOW_ERROR" | "USER_INPUT_CODE_ALREADY_USED_ERROR"; }>; consumeCode: (input: { userInputCode: string; deviceId: string; preAuthSessionId: string; session: SessionContainerInterface | undefined; shouldTryLinkingWithSessionUser: boolean | undefined; tenantId: string; userContext: UserContext; } | { linkCode: string; preAuthSessionId: string; session: SessionContainerInterface | undefined; shouldTryLinkingWithSessionUser: boolean | undefined; tenantId: string; userContext: UserContext; }) => Promise<{ status: "OK"; consumedDevice: { preAuthSessionId: string; failedCodeInputAttemptCount: number; email?: string; phoneNumber?: string; }; createdNewRecipeUser: boolean; user: User; recipeUserId: RecipeUserId; } | { status: "INCORRECT_USER_INPUT_CODE_ERROR" | "EXPIRED_USER_INPUT_CODE_ERROR"; failedCodeInputAttemptCount: number; maximumCodeInputAttempts: number; } | { status: "RESTART_FLOW_ERROR"; } | { 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"; }>; checkCode: (input: { userInputCode: string; deviceId: string; preAuthSessionId: string; tenantId: string; userContext: UserContext; } | { linkCode: string; preAuthSessionId: string; tenantId: string; userContext: UserContext; }) => Promise<{ status: "OK"; consumedDevice: { preAuthSessionId: string; failedCodeInputAttemptCount: number; email?: string; phoneNumber?: string; }; } | { status: "INCORRECT_USER_INPUT_CODE_ERROR" | "EXPIRED_USER_INPUT_CODE_ERROR"; failedCodeInputAttemptCount: number; maximumCodeInputAttempts: number; } | { status: "RESTART_FLOW_ERROR"; }>; updateUser: (input: { recipeUserId: RecipeUserId; email?: string | null; phoneNumber?: string | null; userContext: UserContext; }) => Promise<{ status: "OK" | "UNKNOWN_USER_ID_ERROR" | "EMAIL_ALREADY_EXISTS_ERROR" | "PHONE_NUMBER_ALREADY_EXISTS_ERROR"; } | { status: "EMAIL_CHANGE_NOT_ALLOWED_ERROR" | "PHONE_NUMBER_CHANGE_NOT_ALLOWED_ERROR"; reason: string; }>; revokeAllCodes: (input: { email: string; tenantId: string; userContext: UserContext; } | { phoneNumber: string; tenantId: string; userContext: UserContext; }) => Promise<{ status: "OK"; }>; revokeCode: (input: { codeId: string; tenantId: string; userContext: UserContext; } | { preAuthSessionId: string; tenantId: string; userContext: UserContext; }) => Promise<{ status: "OK"; }>; listCodesByEmail: (input: { email: string; tenantId: string; userContext: UserContext; }) => Promise; listCodesByPhoneNumber: (input: { phoneNumber: string; tenantId: string; userContext: UserContext; }) => Promise; listCodesByDeviceId: (input: { deviceId: string; tenantId: string; userContext: UserContext; }) => Promise; listCodesByPreAuthSessionId: (input: { preAuthSessionId: string; tenantId: string; userContext: UserContext; }) => Promise; }; export type DeviceType = { preAuthSessionId: string; failedCodeInputAttemptCount: number; email?: string; phoneNumber?: string; codes: { codeId: string; timeCreated: string; codeLifetime: number; }[]; }; export type APIOptions = { recipeImplementation: RecipeInterface; appInfo: NormalisedAppinfo; config: TypeNormalisedInput; recipeId: string; isInServerlessEnv: boolean; req: BaseRequest; res: BaseResponse; emailDelivery: EmailDeliveryIngredient; smsDelivery: SmsDeliveryIngredient; }; export type APIInterface = { createCodePOST?: (input: ({ email: string; } | { phoneNumber: string; }) & { tenantId: string; session: SessionContainerInterface | undefined; shouldTryLinkingWithSessionUser: boolean | undefined; options: APIOptions; userContext: UserContext; }) => Promise<{ status: "OK"; deviceId: string; preAuthSessionId: string; flowType: "USER_INPUT_CODE" | "MAGIC_LINK" | "USER_INPUT_CODE_AND_MAGIC_LINK"; } | { status: "SIGN_IN_UP_NOT_ALLOWED"; reason: string; } | GeneralErrorResponse>; resendCodePOST?: (input: { deviceId: string; preAuthSessionId: string; } & { tenantId: string; session: SessionContainerInterface | undefined; shouldTryLinkingWithSessionUser: boolean | undefined; options: APIOptions; userContext: UserContext; }) => Promise; consumeCodePOST?: (input: ({ userInputCode: string; deviceId: string; preAuthSessionId: string; } | { linkCode: string; preAuthSessionId: string; }) & { tenantId: string; session: SessionContainerInterface | undefined; shouldTryLinkingWithSessionUser: boolean | undefined; options: APIOptions; userContext: UserContext; }) => Promise<{ status: "OK"; createdNewRecipeUser: boolean; user: User; session: SessionContainerInterface; } | { status: "INCORRECT_USER_INPUT_CODE_ERROR" | "EXPIRED_USER_INPUT_CODE_ERROR"; failedCodeInputAttemptCount: number; maximumCodeInputAttempts: number; } | { status: "RESTART_FLOW_ERROR"; } | { status: "SIGN_IN_UP_NOT_ALLOWED"; reason: string; } | GeneralErrorResponse>; emailExistsGET?: (input: { email: string; tenantId: string; options: APIOptions; userContext: UserContext; }) => Promise<{ status: "OK"; exists: boolean; } | GeneralErrorResponse>; phoneNumberExistsGET?: (input: { phoneNumber: string; tenantId: string; options: APIOptions; userContext: UserContext; }) => Promise<{ status: "OK"; exists: boolean; } | GeneralErrorResponse>; }; export type TypePasswordlessEmailDeliveryInput = { type: "PASSWORDLESS_LOGIN"; isFirstFactor: boolean; email: string; userInputCode?: string; urlWithLinkCode?: string; codeLifetime: number; preAuthSessionId: string; tenantId: string; }; export type TypePasswordlessSmsDeliveryInput = { type: "PASSWORDLESS_LOGIN"; isFirstFactor: boolean; phoneNumber: string; userInputCode?: string; urlWithLinkCode?: string; codeLifetime: number; preAuthSessionId: string; tenantId: string; };