{"version":3,"sources":["v2/helpers/time.ts","v2/helpers/text.ts","v2/api/auth/config.ts","v2/components/common/Input.tsx","v2/components/common/Button.tsx","v2/components/Checkbox.tsx","v2/pages/auth/forms/Login.tsx","v2/pages/auth/forms/MFA.tsx","v2/components/Logo.tsx","v2/pages/auth/Disclosure.tsx","v2/pages/auth/forms/MFARecovery.tsx","v2/pages/auth/forms/ForgotPassword.tsx","v2/pages/auth/index.tsx"],"names":["sleep","ms","Promise","r","setTimeout","titleCase","value","toLowerCase","replace","split","map","word","charAt","toUpperCase","slice","join","initAmplify","Amplify","configure","Auth","identityPoolId","window","env","COGNITO_IDENTITY_POOL_ID","region","COGNITO_REGION","userPoolId","COGNITO_USER_POOL_ID","userPoolWebClientId","COGNITO_CLIENT_ID","endpoint","COGNITO_ENDPOINT","authenticationFlowType","COGNITO_AUTH_FLOW","mandatorySignIn","cookieStorage","domain","location","hostname","path","expires","secure","ENV","Storage","bucket","COGNITO_BUCKET","Input","forwardRef","_ref","ref","label","disabled","successMsg","errorMsg","helpMsg","leftIcon","rightIcon","status","className","props","finalStatus","style","error","input","icon","success","neutral","IconWrapper","_ref2","children","position","cloneElement","clsx","React","createElement","htmlFor","id","Object","assign","outline","Button","variant","loading","loadingPlaceholder","default","secondary","alternate","ghost","green","red","spinner","viewBox","fill","xmlns","d","opacity","onFocus","event","currentTarget","blur","fontWeight","Fragment","CheckboxState","Checkbox","defaultState","Unchecked","state","externalState","onChange","checkboxRef","useRef","internalState","setInternalState","useState","focused","setFocused","undefined","useEffect","baseClass","stateClass","tabIndex","onClick","handleStateChange","nextState","Checked","Indeterminate","onBlur","boxShadow","Icon","name","displayName","DEFAULT_PATHS","MFA_CHALLENGE_TYPES","FORM_VALIDATION_SCHEMA","Joi","object","email","string","tlds","allow","required","messages","password","Login","_errors$email","_errors$password","setAuthState","setCognitoUser","useContext","AuthContext","rememberMe","setRememberMe","isSubmitting","setIsSubmitting","passwordVisible","setPasswordVisible","setStatus","rememberMeEmail","localStorage","getItem","register","handleSubmit","formState","errors","useForm","resolver","joiResolver","defaultValues","mode","reValidateMode","onSubmit","async","clearAuthCookies","cookies","document","cookie","i","length","eqPos","indexOf","substr","trim","userOrChallenge","AuthService","login","data","challengeName","includes","AuthState","MFA","sessionStorage","setItem","toast","TOAST_THEME","requestedPathVal","href","err","removeItem","message","type","placeholder","_document$getElementB","getElementById","click","Text","FORGOT_PASSWORD","code","array","items","regex","_cognitoUser$challeng","cognitoUser","lastResend","setLastResend","isVerifying","setIsVerifying","rememberDevice","setRememberDevice","setValue","trigger","isSubmitted","Array","isSMS","inputRefs","current","getKeyForIndex","index","concat","every","field","confirmMFA","errorMessage","Error","handlePaste","_event$clipboardData","paste","clipboardData","getData","isNaN","Number","_inputRefs$current4","preventDefault","inputRef","CODE_LENGTH","addEventListener","removeEventListener","keyDownListener","e","key","focus","handleNumberKey","handleBackspaceKey","onKeyPress","keyCode","which","keyValue","String","fromCharCode","test","digit","maxLength","pattern","inputMode","target","select","_inputRefs$current","_inputRefs$current2","onKeyDown","isBackspaceOnEmpty","previousInputExists","_inputRefs$current3","handleCancel","LOGIN","challengeParam","CODE_DELIVERY_DESTINATION","handleResend","now","Date","msSinceLastResend","secondsLeft","Math","ceil","resendConfirmationCode","handleRecovery","MFA_RECOVERY","Logo","src","alt","Disclosure","year","getFullYear","FiAlertCircle","open","Path","URL_DISCLOSURES","RECOVERY_CODE_VALIDATION_SCHEMA","recoveryCode","MFARecovery","_errors$recoveryCode","UserActions","verifyRecoveryCode","username","PASSWORD_RESET_SCHEMA","verificationCode","newPassword","min","confirmPassword","valid","with","EMAIL_VALIDATION_SCHEMA","ForgotPassword","_errorsEmail$email","_errorsReset$verifica","_errorsReset$newPassw","_errorsReset$confirmP","setEmail","codeSent","setCodeSent","registerReset","handleSubmitReset","errorsReset","reset","resetResetForm","registerEmail","handleSubmitEmail","errorsEmail","sendResetCode","forgotPassword","resetPassword","forgotPasswordSubmit","createContext","authState","title","forms","subtitle","form","SIGNUP","Provider"],"mappings":"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","file":"static/js/64.b87235af.chunk.js","sourcesContent":["// helper function to delay execution\nexport const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n","export const titleCase = (value: string) => {\n return value\n .toLowerCase()\n .replace(\"_\", \" \")\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n};\n","import Amplify from \"@aws-amplify/core\";\n\n/**\n * Initializes the AWS amplify SDK\n *\n * this is already done by v1 but will\n * need be called once v1 is deprecated\n */\nconst initAmplify = () =>\n Amplify.configure({\n Auth: {\n identityPoolId: window.env.COGNITO_IDENTITY_POOL_ID,\n region: window.env.COGNITO_REGION,\n userPoolId: window.env.COGNITO_USER_POOL_ID,\n userPoolWebClientId: window.env.COGNITO_CLIENT_ID,\n endpoint: window.env.COGNITO_ENDPOINT,\n authenticationFlowType: window.env.COGNITO_AUTH_FLOW,\n mandatorySignIn: false,\n cookieStorage: {\n domain: window.location.hostname,\n path: \"/\",\n expires: 7,\n secure: window.env.ENV === \"PROD\",\n },\n },\n Storage: {\n bucket: window.env.COGNITO_BUCKET,\n },\n });\n\nexport default initAmplify;\n","import { clsx } from \"@alpacahq/ui\";\nimport React, {\n InputHTMLAttributes,\n ReactNode,\n forwardRef,\n cloneElement,\n} from \"react\";\n\ninterface MessageProps {\n errorMsg?: ReactNode;\n successMsg?: ReactNode;\n}\n\ntype BaseInputProps = InputHTMLAttributes<HTMLInputElement> &\n MessageProps & {\n label?: string;\n helpMsg?: ReactNode;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n status?: \"success\" | \"error\" | \"neutral\";\n };\n\ntype SuccessInputProps = BaseInputProps & {\n successMsg: ReactNode;\n errorMsg?: never;\n};\n\ntype ErrorInputProps = BaseInputProps & {\n errorMsg: ReactNode;\n successMsg?: never;\n};\n\nexport type InputProps = BaseInputProps | SuccessInputProps | ErrorInputProps;\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n label,\n disabled,\n successMsg,\n errorMsg,\n helpMsg,\n leftIcon,\n rightIcon,\n status = \"neutral\",\n className,\n ...props\n },\n ref\n ) => {\n // determine the status of the input\n const autoStatus = errorMsg ? \"error\" : successMsg ? \"success\" : \"neutral\";\n const finalStatus = status === \"neutral\" ? autoStatus : status;\n\n // styles for each status\n const styles = {\n error: {\n label: \"text-red-600\",\n input:\n \"bg-white border border-red-500 text-red-900 placeholder-red-600 focus:ring-1 focus:ring-red-500 focus:border-red-500\",\n icon: \"text-red-600\",\n },\n success: {\n label: \"text-emerald-600 dark:text-emerald-400\",\n input:\n \"bg-white border border-emerald-500 text-emerald-900 placeholder-emerald-600 focus:ring-1 focus:ring-emerald-500 focus:border-emerald-500\",\n icon: \"text-emerald-500\",\n },\n neutral: {\n label: \"text-zinc-900\",\n input:\n \"bg-white border border-zinc-300 text-zinc-900 placeholder-zinc-500 focus:ring-1 focus:ring-yellow-400 focus:border-yellow-400\",\n icon: \"text-gray-500\",\n },\n };\n\n // get the style based on status for the input\n const style = styles[finalStatus];\n\n // wrapper for icon with position classes\n const IconWrapper = ({ children, position }: any) => {\n if (!children) {\n return null;\n }\n\n return cloneElement(children, {\n className: clsx(\n \"absolute top-1/2 -translate-y-1/2 transform\",\n children.props.className,\n style.icon,\n position === \"left\" ? \"left-3.5\" : \"right-3.5\"\n ),\n });\n };\n\n return (\n <div className=\"text-base\">\n {label && (\n <label htmlFor={props.id} className={clsx(\"mb-2 block\", style.label)}>\n {label}\n </label>\n )}\n <div className=\"relative\">\n {leftIcon && <IconWrapper position=\"left\">{leftIcon}</IconWrapper>}\n {rightIcon && <IconWrapper position=\"right\">{rightIcon}</IconWrapper>}\n <input\n ref={ref}\n style={{\n // for some reason, the outline is not removed by the tailwind class\n outline: \"unset\",\n }}\n className={clsx(\n \"block h-10 w-full rounded-lg px-[14.5px] text-base\",\n disabled && \"cursor-not-allowed opacity-50\",\n leftIcon && \"pl-[42.5px]\",\n rightIcon && \"pr-[42.5px]\",\n style.input,\n className\n )}\n disabled={disabled}\n {...props}\n />\n </div>\n {\n // if the input is not neutral and there is a success or error message\n finalStatus !== \"neutral\" && (!!successMsg || !!errorMsg) && (\n <p className={clsx(\"mt-2\", style.label)}>\n {errorMsg || successMsg}\n </p>\n )\n }\n {\n // if the input is neutral and there is a help message\n finalStatus === \"neutral\" && helpMsg && (\n <p className=\"mt-2 text-zinc-500\">{helpMsg}</p>\n )\n }\n </div>\n );\n }\n);\n","import { clsx } from \"@alpacahq/ui\";\nimport React, { ButtonHTMLAttributes, forwardRef, ReactNode } from \"react\";\n\ntype BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n leftIcon?: ReactNode;\n loading?: boolean;\n loadingPlaceholder?: string;\n};\n\ntype DefaultButtonProps = BaseButtonProps & {\n variant?: \"default\";\n};\ntype SecondaryButtonProps = BaseButtonProps & {\n variant?: \"secondary\";\n};\n\ntype AltButtonProps = BaseButtonProps & {\n variant: \"alternate\";\n};\n\ntype GhosButtonProps = BaseButtonProps & {\n variant: \"ghost\";\n};\n\ntype GreenButtonProps = BaseButtonProps & {\n variant: \"green\";\n};\n\ntype RedButtonProps = BaseButtonProps & {\n variant: \"red\";\n};\n\nexport type ButtonProps =\n | DefaultButtonProps\n | SecondaryButtonProps\n | AltButtonProps\n | GhosButtonProps\n | GreenButtonProps\n | RedButtonProps;\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n children,\n disabled,\n variant = \"default\",\n leftIcon,\n loading = false,\n loadingPlaceholder = \"Loading...\",\n className,\n ...props\n },\n ref\n ) => {\n // styles for each variant of the button\n const styles = {\n default:\n \"text-yellow-900 bg-yellow-400 focus:ring-2 focus:ring-yellow-200\",\n secondary:\n \"text-zinc-900 focus:outline-none bg-zinc-200 hover:text-zinc-900 focus:z-10 focus:ring-2 focus:ring-zinc-300\",\n alternate:\n \"text-zinc-900 focus:outline-none bg-white border border-zinc-300 hover:text-zinc-900 focus:z-10 focus:ring-2 focus:ring-zinc-100\",\n ghost: \"text-gray-900 hover:text-gray-500\",\n green: \"text-white bg-emerald-500 focus:ring-4 focus:ring-emerald-200\",\n red: \"text-white bg-rose-500 focus:ring-1 focus:ring-rose-200\",\n };\n\n // get the style based on variant for the button\n const style = styles[variant];\n\n // this is the spinner that will be shown when loading is true\n const spinner = (\n <svg\n className=\"mr-2 h-4 w-4 animate-spin\"\n viewBox=\"0 0 100 101\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z\"\n fill=\"currentColor\"\n opacity=\"0.4\"\n />\n <path\n d=\"M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n\n return (\n <button\n {...props}\n ref={ref}\n disabled={disabled || loading}\n onFocus={(event) => disabled && event.currentTarget.blur()}\n className={clsx(\n \"flex items-center justify-center h-10 space-x-2 rounded-lg p-2.5 text-center text-base focus:outline-none\",\n disabled && \"cursor-not-allowed opacity-50\",\n style,\n className\n )}\n style={{ fontWeight: 450 }}\n >\n {loading ? (\n <>\n {spinner}\n {loadingPlaceholder}\n </>\n ) : (\n <>\n {leftIcon}\n {children}\n </>\n )}\n </button>\n );\n }\n);\n","import { Icon, clsx } from \"@alpacahq/ui\";\nimport React, { useState, useEffect, useRef } from \"react\";\n\nexport enum CheckboxState {\n Checked = \"checked\",\n Unchecked = \"unchecked\",\n Indeterminate = \"indeterminate\",\n}\n\nexport interface CheckboxProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n defaultState?: CheckboxState;\n state?: CheckboxState;\n onChange?: (state: CheckboxState) => void;\n disabled?: boolean;\n}\n\nexport const Checkbox: React.FC<CheckboxProps> = ({\n defaultState = CheckboxState.Unchecked,\n state: externalState,\n onChange,\n disabled = false,\n ...props\n}) => {\n const checkboxRef = useRef(null);\n\n const [internalState, setInternalState] = useState(defaultState);\n const [focused, setFocused] = useState(false);\n\n const state = externalState !== undefined ? externalState : internalState;\n\n useEffect(() => {\n setInternalState(defaultState);\n }, [defaultState]);\n\n const handleStateChange = () => {\n if (disabled) {\n return;\n }\n\n let nextState: CheckboxState;\n\n switch (state) {\n case CheckboxState.Unchecked:\n nextState = CheckboxState.Checked;\n break;\n case CheckboxState.Checked:\n nextState = CheckboxState.Indeterminate;\n break;\n default:\n nextState = CheckboxState.Unchecked;\n }\n\n setInternalState(nextState);\n\n if (onChange) {\n onChange(nextState);\n }\n };\n\n // default classes\n const baseClass = clsx(\n \"min-h-4 min-w-4 h-4 w-4 cursor-pointer flex items-center justify-center rounded-[5px]\",\n disabled && \"opacity-50\"\n );\n\n // state-specific classes for the checkbox\n const stateClass = clsx(\n state === CheckboxState.Unchecked &&\n \"border border-zinc-300 bg-white focus:ring-yellow-400\",\n state !== CheckboxState.Unchecked &&\n \"border border-yellow-400 bg-yellow-400 text-yellow-900\"\n );\n\n return (\n <div\n tabIndex={0}\n ref={checkboxRef}\n onClick={handleStateChange}\n onBlur={() => setFocused(false)}\n onFocus={() => setFocused(true)}\n className={clsx(baseClass, stateClass)}\n style={{\n boxShadow:\n focused && state !== CheckboxState.Unchecked\n ? \"0 0 0 4px #FEF08A\"\n : undefined,\n }}\n {...props}\n >\n {state === CheckboxState.Checked && (\n <Icon name=\"Check\" className=\"h-3 w-3 stroke-[4px]\" />\n )}\n {state === CheckboxState.Indeterminate && (\n <Icon name=\"MinusSmall\" className=\"h-3 w-3 stroke-[4px]\" />\n )}\n </div>\n );\n};\n\nexport default Checkbox;\n","import Joi from \"joi\";\nimport initAmplify from \"../../../api/auth/config\";\n\nimport React, { FC, useEffect, useState, useContext } from \"react\";\n\nimport { CheckboxState, Text, Icon } from \"@alpacahq/ui\";\n\nimport { toast } from \"react-hot-toast\";\nimport { useForm } from \"react-hook-form\";\nimport { joiResolver } from \"@hookform/resolvers/joi\";\nimport { AuthService } from \"../../../api/auth\";\nimport { TOAST_THEME } from \"../../../theme\";\nimport { AuthContext, AuthState } from \"..\";\nimport { Input } from \"src/v2/components/common/Input\";\nimport { Button } from \"src/v2/components/common/Button\";\nimport Checkbox from \"src/v2/components/Checkbox\";\n\nexport const DEFAULT_PATHS = [\"/\", \"/login\"];\n\nconst MFA_CHALLENGE_TYPES = [\"SMS_MFA\", \"SOFTWARE_TOKEN_MFA\"];\nconst FORM_VALIDATION_SCHEMA = Joi.object({\n email: Joi.string()\n .email({ tlds: { allow: false } })\n .required()\n .messages({\n \"string.empty\": \"Please enter an email\",\n \"string.email\": \"Must be a valid email\",\n }),\n password: Joi.string().required().messages({\n \"string.empty\": \"Please enter a password\",\n }),\n});\n\ntype AuthCardLoginFields = {\n email: string;\n password: string;\n};\n\nexport const Login: FC = () => {\n const { setAuthState, setCognitoUser } = useContext(AuthContext);\n\n const [rememberMe, setRememberMe] = useState(false);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [passwordVisible, setPasswordVisible] = useState(false);\n const [status, setStatus] = useState<\"success\" | \"error\" | \"neutral\">(\n \"neutral\"\n );\n\n const rememberMeEmail = localStorage.getItem(\"email\");\n\n const {\n register,\n handleSubmit,\n formState: { errors },\n } = useForm<AuthCardLoginFields>({\n resolver: joiResolver(FORM_VALIDATION_SCHEMA),\n defaultValues: { email: rememberMeEmail || \"\" },\n mode: \"onBlur\",\n reValidateMode: \"onChange\",\n });\n\n useEffect(() => {\n // set the email value from local storage if it exists\n if (rememberMeEmail) {\n setRememberMe(true);\n }\n }, [rememberMeEmail]);\n\n const clearAuthCookies = () => {\n // get all cookies and split into an array\n const cookies = document.cookie.split(\";\");\n\n for (let i = 0; i < cookies.length; i++) {\n // current cookie in the loop\n const cookie = cookies[i];\n\n // find the position of '=' in the cookie\n // this separates the cookie name and its value\n const eqPos = cookie.indexOf(\"=\");\n\n // extract the name of the cookie\n // if \"=\" is present, get the name part, else take the whole cookie string\n const name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;\n\n // check if the cookie name is exactly \"dashboard.authtoken\"\n if (name.trim() === \"dashboard.authtoken\") {\n // expire the cookie by setting it in the past\n document.cookie = name + \"=; expires=Thu, 01 Jan 1970 00:00:01 GMT;\";\n }\n }\n };\n\n const onSubmit = async (data: AuthCardLoginFields) => {\n // prevent multiple submissions\n if (isSubmitting) {\n return;\n }\n\n // to avoid possible session issues, clear all auth cookies before logging in\n clearAuthCookies();\n setIsSubmitting(true);\n initAmplify();\n\n // sleep for 500ms to allow the loading state to show\n await new Promise((r) => setTimeout(r, 500));\n\n try {\n const userOrChallenge = await AuthService.login(\n data.email.toLowerCase(),\n data.password\n );\n\n if (\n // if the user is not null and the challenge name is in the list of MFA challenge types\n !!userOrChallenge.challengeName &&\n MFA_CHALLENGE_TYPES.includes(userOrChallenge.challengeName)\n ) {\n // set the cognito user in the auth context\n setCognitoUser(userOrChallenge);\n\n // this will prompt the user to enter their MFA code\n setAuthState(AuthState.MFA);\n } else {\n setCognitoUser(userOrChallenge);\n // if signIn was successful, oauth knows that the user has logged in\n window.sessionStorage.setItem(\"oauth_login\", \"1\");\n\n // show a success toast\n toast.success(\"Success! Logging you in...\", { ...TOAST_THEME });\n\n // highlight the inputs green\n setStatus(\"success\");\n\n // sleep for 1.5 seconds to allow the success toast to show\n await new Promise((r) => setTimeout(r, 1500));\n\n const requestedPathVal =\n window.sessionStorage.getItem(\"requested_path\") || \"\";\n\n // send the user to the requested path if it exists or the home page\n window.location.href = DEFAULT_PATHS.includes(requestedPathVal)\n ? \"/\"\n : requestedPathVal;\n }\n } catch (err) {\n // remove email if remember me is not checked\n localStorage.removeItem(\"email\");\n\n // handle any login errors here\n const error = err as Error;\n toast.error(error.message || \"An error occurred during login\", {\n ...TOAST_THEME,\n });\n } finally {\n if (!rememberMe) {\n localStorage.removeItem(\"email\");\n }\n\n setIsSubmitting(false);\n }\n };\n\n return (\n <>\n <form onSubmit={handleSubmit(onSubmit)} className=\"space-y-4\">\n <Input\n label=\"Email\"\n type=\"email\"\n placeholder=\"me@example.com\"\n status={status}\n errorMsg={errors.email?.message}\n {...register(\"email\")}\n />\n <Input\n label=\"Password\"\n placeholder=\"••••••••••••••••\"\n status={status}\n errorMsg={errors.password?.message}\n type={passwordVisible ? \"text\" : \"password\"}\n rightIcon={\n <Icon\n className=\"cursor-pointer stroke-2\"\n name={passwordVisible ? \"Eye\" : \"EyeSlash\"}\n onClick={() => setPasswordVisible(!passwordVisible)}\n />\n }\n {...register(\"password\")}\n />\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-start items-center space-x-2\">\n <Checkbox\n id=\"rememberMe\"\n onChange={() => setRememberMe(!rememberMe)}\n state={\n rememberMe ? CheckboxState.Checked : CheckboxState.Unchecked\n }\n />\n <label\n className=\"text-zinc-900 cursor-pointer\"\n onClick={() => document.getElementById(\"rememberMe\")?.click()}\n >\n Remember me\n </label>\n </div>\n <Text\n onClick={() => setAuthState(AuthState.FORGOT_PASSWORD)}\n className=\"text-zinc-900 underline text-base cursor-pointer\"\n style={{ fontWeight: 450 }}\n >\n Forgot password?\n </Text>\n </div>\n <input type=\"submit\" className=\"hidden\" />\n </form>\n <div>\n <Button\n className=\"w-full mb-4\"\n loading={isSubmitting}\n disabled={isSubmitting}\n onClick={handleSubmit(onSubmit)}\n >\n Continue\n </Button>\n <Text className=\"text-base text-zinc-500\">\n Don't have an account yet?{\" \"}\n <a\n href=\"/signup\"\n className=\"text-zinc-900 text-base underline hover:underline\"\n style={{ fontWeight: 450 }}\n >\n Create an account\n </a>\n </Text>\n </div>\n </>\n );\n};\n","import Joi from \"joi\";\n\nimport React, { FC, useEffect, useRef, useContext, useState } from \"react\";\n\nimport { sleep } from \"../../../helpers\";\nimport { toast } from \"react-hot-toast\";\nimport { Input } from \"src/v2/components/common/Input\";\nimport { Button } from \"src/v2/components/common/Button\";\nimport { useForm } from \"react-hook-form\";\nimport { AuthService } from \"../../../api/auth\";\nimport { joiResolver } from \"@hookform/resolvers/joi\";\nimport { TOAST_THEME } from \"../../../theme\";\nimport { DEFAULT_PATHS } from \"./Login\";\nimport { AuthContext, AuthState } from \"..\";\nimport { Checkbox, CheckboxState, Text } from \"@alpacahq/ui\";\n\nconst CODE_LENGTH = 6;\nconst FORM_VALIDATION_SCHEMA = Joi.object({\n code: Joi.array()\n .items(Joi.string().regex(/^\\d+$/).length(1))\n .length(CODE_LENGTH)\n .required(),\n});\n\nexport const MFA: FC = () => {\n const { cognitoUser, setCognitoUser, setAuthState } = useContext(AuthContext);\n\n const [lastResend, setLastResend] = useState(0);\n const [isVerifying, setIsVerifying] = useState(false);\n const [status, setStatus] = useState<\"success\" | \"error\" | \"neutral\">(\n \"neutral\"\n );\n const [rememberDevice, setRememberDevice] = useState<CheckboxState>(\n CheckboxState.Checked\n );\n\n const onRememberDeviceChange = (state: CheckboxState) =>\n setRememberDevice(\n state === CheckboxState.Indeterminate ? CheckboxState.Unchecked : state\n );\n\n const {\n register,\n handleSubmit,\n setValue,\n trigger,\n formState: { errors, isSubmitted },\n } = useForm<{ code: string[] }>({\n mode: \"onChange\",\n resolver: joiResolver(FORM_VALIDATION_SCHEMA),\n defaultValues: {\n code: Array(CODE_LENGTH).fill(\"\"),\n },\n });\n\n const isSMS = cognitoUser?.challengeName === \"SMS_MFA\";\n\n // array of refs for the inputs\n const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\n\n // set up the input refs\n useEffect(() => {\n inputRefs.current = inputRefs.current.slice(0, CODE_LENGTH);\n }, []);\n\n // generate the key for a given code input index\n const getKeyForIndex = (index: number): `code.${number}` => `code.${index}`;\n\n const onChange = (e: React.ChangeEvent<HTMLInputElement>, index: number) => {\n // set the status to neutral\n setStatus(\"neutral\");\n\n const value = e.target.value;\n\n // check if the value is a number\n if (isNaN(Number(value)) || value.includes(\".\")) {\n // do nothing\n return;\n }\n\n // trigger validation\n trigger(getKeyForIndex(index));\n\n // set the value in the form state for the given input\n setValue(getKeyForIndex(index), value);\n\n // focus the next input if this input has been filled\n if (value && inputRefs.current[index + 1]) {\n inputRefs.current[index + 1]?.focus();\n }\n\n // focus the previous input if this input is empty\n if (!value && inputRefs.current[index - 1]) {\n inputRefs.current[index - 1]?.focus();\n }\n\n // auto-submit when all fields are filled\n if (inputRefs.current.every((ref) => ref && ref.value)) {\n handleSubmit(onSubmit)();\n }\n };\n\n const onKeyDown = (\n { key, currentTarget }: React.KeyboardEvent<HTMLInputElement>,\n index: number\n ) => {\n // if the user presses backspace on an empty input\n const isBackspaceOnEmpty =\n key === \"Backspace\" && currentTarget.value === \"\";\n\n // check if the previous input exists\n const previousInputExists = !!inputRefs.current[index - 1];\n\n // focus the previous input if the user pressed backspace on an empty input\n if (isBackspaceOnEmpty && previousInputExists) {\n inputRefs.current[index - 1]?.focus();\n }\n };\n\n const onSubmit = async ({ code }: { code: string[] }) => {\n // if already in progress, return\n if (isVerifying) {\n return;\n }\n\n // check if all the fields are filled\n const isFormComplete = code.every((field) => field !== \"\");\n\n // if the form is not complete, set the status to \"error\", show an error message, and return\n if (!isFormComplete) {\n setStatus(\"error\");\n toast.error(\"Please fill in all fields\", { ...TOAST_THEME });\n return;\n }\n\n // this is to prevent the user from spamming the \"Verify\" button\n setIsVerifying(true);\n\n // delay for .5s to show loading state\n await sleep(500);\n\n // if the cognito user does not exist, set the status to \"error\", show an error message, stop verifying, and return\n if (!cognitoUser) {\n setStatus(\"error\");\n toast.error(\"User not available\", { ...TOAST_THEME });\n setIsVerifying(false);\n return;\n }\n\n try {\n // try to confirm MFA\n await AuthService.confirmMFA(\n cognitoUser,\n code.join(\"\"),\n cognitoUser?.challengeName || \"\"\n );\n\n // remember device if the user has checked the checkbox\n if (rememberDevice === CheckboxState.Checked) {\n await AuthService.rememberDevice();\n }\n\n toast.success(\"You are now logged in\", { ...TOAST_THEME });\n\n // set the status to \"success\" for all inputs\n setStatus(\"success\");\n\n // if confirmMFA was successful, oauth knows that the user has logged in\n window.sessionStorage.setItem(\"oauth_login\", \"1\");\n\n // delay for 1.5 seconds to allow the success toast to show\n await sleep(1500);\n\n // take the user to the requested path if it exists, otherwise take them to the home page\n const requestedPathVal =\n window.sessionStorage.getItem(\"requested_path\") || \"\";\n\n window.location.href = DEFAULT_PATHS.includes(requestedPathVal)\n ? \"/\"\n : requestedPathVal;\n } catch (err) {\n setStatus(\"error\");\n\n const errorMessage =\n err instanceof Error\n ? err.message\n : \"An unexpected error has occurred.\";\n\n toast.error(errorMessage, { ...TOAST_THEME });\n } finally {\n // regardless of whether MFA confirmation succeeded or failed, stop the verification process\n setIsVerifying(false);\n }\n };\n\n const handleCancel = () => {\n // go back to login\n setAuthState(AuthState.LOGIN);\n\n // reset the cognito user\n setCognitoUser(undefined);\n };\n\n const handleRecovery = () => {\n // go to the MFA recovery screen\n setAuthState(AuthState.MFA_RECOVERY);\n };\n\n const handleResend = () => {\n if (!cognitoUser) {\n toast.error(\"User not available\", { ...TOAST_THEME });\n return;\n }\n\n // get current timestamp\n const now = Date.now();\n\n // calculate milliseconds since the last resend\n const msSinceLastResend = now - lastResend;\n\n // set a throttle limit of 5 seconds to prevent spamming\n const throttleLimit = 5000;\n\n // if the time since the last resend is less than the throttle limit, show an error toast and exit\n if (msSinceLastResend < throttleLimit) {\n const secondsLeft = Math.ceil((throttleLimit - msSinceLastResend) / 1000);\n\n toast.error(\n `Please wait ${secondsLeft} more second(s) before resending.`,\n { ...TOAST_THEME }\n );\n\n return;\n }\n\n // update the timestamp of the last resend\n setLastResend(now);\n\n // request to resend the confirmation code\n cognitoUser.resendConfirmationCode((err) => {\n // determine the toast message and function\n const message = err ? err.message : \"Code resent successfully\";\n const toastFunction = err ? toast.error : toast.success;\n\n toastFunction(message, { ...TOAST_THEME });\n });\n };\n\n useEffect(() => {\n const handlePaste = async (event: ClipboardEvent) => {\n const paste = event.clipboardData?.getData(\"text\") || \"\";\n const pasteLength = paste.length;\n\n // if the paste is a number and the length is equal to the code length, prevent the default paste behavior\n if (pasteLength === CODE_LENGTH && !isNaN(Number(paste))) {\n event.preventDefault();\n\n for (let i = 0; i < CODE_LENGTH; i++) {\n const inputRef = inputRefs.current[i];\n if (inputRef) {\n inputRef.value = paste.charAt(i);\n setValue(getKeyForIndex(i), paste.charAt(i));\n }\n }\n\n // un-focus the last input field after pasting\n inputRefs.current[CODE_LENGTH - 1]?.blur();\n\n if (inputRefs.current.every((ref) => ref && ref.value)) {\n handleSubmit(onSubmit)();\n }\n }\n };\n\n document.addEventListener(\"paste\", handlePaste);\n return () => document.removeEventListener(\"paste\", handlePaste);\n }, [handleSubmit, onSubmit]);\n\n useEffect(() => {\n // handle when the key pressed is a number\n const handleNumberKey = (key: string) => {\n // loop through all the input references\n for (let i = 0; i < inputRefs.current.length; i++) {\n // get the current input reference\n const ref = inputRefs.current[i];\n\n // if the current input reference exists and its value is empty\n if (ref && !ref.value) {\n // set the value of the input field corresponding to the pressed key\n setValue(getKeyForIndex(i), key);\n\n // set the focus on the current input field\n ref.focus();\n\n // break the loop once the first empty input field is found and handled\n break;\n }\n }\n };\n\n // handle when the key pressed is a backspace\n const handleBackspaceKey = () => {\n // loop through all the input references in reverse order\n for (let i = inputRefs.current.length - 1; i >= 0; i--) {\n // get the current input reference\n const ref = inputRefs.current[i];\n\n // if the current input reference exists and its value is not empty\n if (ref && ref.value) {\n // clear the value of the current input field\n setValue(getKeyForIndex(i), \"\");\n\n // set the focus of the current input field\n ref.focus();\n\n // break the loop once the first filled input field (from the end) is found and handled\n break;\n }\n }\n };\n\n // handle key down events\n const keyDownListener = (e: KeyboardEvent) => {\n // if the key pressed is a number\n if (!isNaN(Number(e.key))) {\n // call the function to handle number keys\n handleNumberKey(e.key);\n }\n\n // if the key pressed is a backspace\n if (e.key === \"Backspace\") {\n // call the function to handle backspace key\n handleBackspaceKey();\n }\n };\n\n window.addEventListener(\"keydown\", keyDownListener);\n return () => window.removeEventListener(\"keydown\", keyDownListener);\n }, []);\n\n // prevent the user from entering non-numeric characters\n const onKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {\n const keyCode = event.keyCode || event.which;\n const keyValue = String.fromCharCode(keyCode);\n\n if (!/^\\d+$/.test(keyValue)) {\n event.preventDefault();\n }\n };\n\n return (\n // <AuthCard title={isSMS ? \"Enter your SMS code\" : \"Enter your 2FA code\"}>\n <>\n <form onSubmit={handleSubmit(onSubmit)}>\n <div className=\"flex justify-between space-x-2 overflow-x-auto\">\n {Array(CODE_LENGTH)\n .fill(\"\")\n .map((digit, index) => (\n <Input\n key={index}\n className=\"w-14 h-14 text-2xl text-center\"\n maxLength={1}\n pattern=\"[0-9]*\"\n inputMode=\"numeric\"\n // register the input field with the useForm hook\n {...register(`code.${index}`)}\n // create a ref for each input field to control focus\n ref={(ref) => (inputRefs.current[index] = ref)}\n // on focus, select the text inside the `Input` field\n onFocus={(e) => e.target.select()}\n // determine the status of the input field\n // if there's an error related to this input field and form is submitted, set the status to \"error\"\n // otherwise, use the overall form status\n status={\n errors.code && errors.code[index] && isSubmitted\n ? \"error\"\n : status\n }\n onKeyPress={onKeyPress}\n onChange={(e) => onChange(e, index)}\n onKeyDown={(e) => onKeyDown(e, index)}\n // prevent typing into the input field while the form submission is in progress\n disabled={isVerifying}\n />\n ))}\n </div>\n <input type=\"submit\" className=\"hidden\" />\n </form>\n <div className=\"w-full space-y-6\">\n <div>\n <label className=\"flex\">\n <span className=\"block mr-4\">Remember this device?</span>\n <Checkbox\n state={rememberDevice}\n onChange={onRememberDeviceChange}\n />\n </label>\n <Text className=\"font-bold text-xs\">\n Uncheck if using a shared device\n </Text>\n </div>\n\n <div className=\"flex space-x-2\">\n <Button\n className=\"flex-1\"\n variant=\"secondary\"\n type=\"button\"\n onClick={handleCancel}\n >\n Cancel\n </Button>\n <Button\n className=\"flex-1\"\n loading={isVerifying}\n disabled={isVerifying}\n onClick={handleSubmit(onSubmit)}\n >\n Verify\n </Button>\n </div>\n <div className=\"text-center\">\n {isSMS ? (\n <>\n A code was sent via SMS to{\" \"}\n {cognitoUser?.challengeParam?.CODE_DELIVERY_DESTINATION}.{\" \"}\n <div\n className=\"text-zinc-900 font-medium underline hover:text-zinc-500 cursor-pointer inline-block\"\n onClick={handleResend}\n >\n Resend?\n </div>\n </>\n ) : (\n <>Find the code in your authenticator app.</>\n )}\n <br />\n <div\n className=\"text-zinc-900 font-medium underline hover:text-zinc-500 cursor-pointer inline-block\"\n onClick={handleRecovery}\n >\n Use recovery code?\n </div>\n </div>\n </div>\n </>\n );\n};\n","import React from \"react\";\n\nexport const Logo = ({ props }: any) => (\n <img\n className=\"hover:cursor-pointer h-[41.75px] w-[41.75px] rounded-lg\"\n src=\"data:image/png;base64,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\"\n alt=\"\"\n {...props}\n />\n);\n","import React from \"react\";\n\nimport { Path } from \"../../path\";\nimport { FiAlertCircle } from \"react-icons/fi\";\n\nexport const Disclosure = () => {\n const year = new Date().getFullYear();\n\n return (\n <footer className=\"w-full space-y-4 md:max-w-5xl my-0 mx-auto text-sm leading-5 transition-all ease-in-out\">\n <div className=\"space-y-4 text-zinc-400\">\n <p>\n <div>© {year} AlpacaDB, Inc. All rights reserved.</div>\n <div>© {year} Alpaca Securities LLC All rights reserved.</div>\n <div>© {year} Alpaca Crypto LLC All rights reserved.</div>\n </p>\n <p>\n Securities Brokerage services are provided by Alpaca Securities ,\n member FINRA/SIPC, a wholly-owned subsidiary of AlpacaDB, Inc.\n Technology and services are offered by AlpacaDB, Inc.\n </p>\n <p>\n Cryptocurrency services are made available by Alpaca Crypto LLC\n (\"Alpaca Crypto\"), a FinCEN registered money services business (NMLS #\n 2160858), and a wholly-owned subsidiary of AlpacaDB, Inc. Alpaca\n Crypto is not a member of SIPC or FINRA. Cryptocurrencies are not\n stocks and your cryptocurrency investments are not protected by either\n FDIC or SIPC. Please see the Disclosure Library for more information.\n </p>\n <p>\n This is not an offer, solicitation of an offer, or advice to buy or\n sell securities or cryptocurrencies, or open a brokerage account or\n cryptocurrency account in any jurisdiction where Alpaca Securities,\n Alpaca Crypto, are not registered or licensed, as applicable.\n </p>\n </div>\n <div className=\"flex items-center space-x-2 text-zinc-500\">\n <FiAlertCircle className=\"h-5 w-5\" />\n <div\n className=\"cursor-pointer underline\"\n onClick={() => window.open(Path.URL_DISCLOSURES, \"_blank\")}\n style={{\n fontWeight: 450,\n }}\n >\n View important disclosures\n </div>\n </div>\n </footer>\n );\n};\n","import Joi from \"joi\";\n\nimport React, { useContext, FC, useState } from \"react\";\n\nimport { sleep } from \"../../../helpers\";\nimport { toast } from \"react-hot-toast\";\nimport { Input } from \"src/v2/components/common/Input\";\nimport { Button } from \"src/v2/components/common/Button\";\nimport { useForm } from \"react-hook-form\";\nimport { joiResolver } from \"@hookform/resolvers/joi\";\nimport { UserActions } from \"../../../api/auth\";\nimport { TOAST_THEME } from \"../../../theme\";\nimport { AuthContext, AuthState } from \"..\";\n\nconst RECOVERY_CODE_VALIDATION_SCHEMA = Joi.object({\n recoveryCode: Joi.string().length(36).required().messages({\n \"string.empty\": \"Please enter a recovery code\",\n \"string.length\": \"Recovery code must be exactly 36 characters\",\n }),\n});\n\ntype RecoveryFields = {\n recoveryCode: string;\n};\n\nexport const MFARecovery: FC = () => {\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [status, setStatus] = useState<\"success\" | \"error\" | \"neutral\">(\n \"neutral\"\n );\n\n const { cognitoUser, setAuthState, setCognitoUser } = useContext(AuthContext);\n\n const {\n register,\n handleSubmit,\n formState: { errors },\n } = useForm<RecoveryFields>({\n mode: \"onBlur\",\n reValidateMode: \"onChange\",\n resolver: joiResolver(RECOVERY_CODE_VALIDATION_SCHEMA),\n });\n\n // reset the auth state and clear the user\n const handleCancel = () => {\n // go back to login\n setAuthState(AuthState.LOGIN);\n\n // reset the cognito user\n setCognitoUser(undefined);\n };\n\n const onSubmit = async (data: RecoveryFields) => {\n setIsSubmitting(true);\n\n // wait for the loading state to be reflected\n await sleep(500);\n\n try {\n // attempt to verify the recovery code with cognito\n await UserActions.verifyRecoveryCode(\n cognitoUser?.username || \"\",\n data.recoveryCode,\n window.env.COGNITO_USER_POOL_ID\n );\n\n toast.success(\"MFA has been disabled\", {\n ...TOAST_THEME,\n });\n\n // highlight the success state on the input\n setStatus(\"success\");\n\n // wait for the toast to finish before redirecting\n await sleep(1500);\n\n // send the user back to log in\n window.location.href = \"/\";\n } catch (err) {\n const error = err as Error;\n toast.error(\n error.message || \"An error occurred during recovery code verification\",\n { ...TOAST_THEME }\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <>\n <form onSubmit={handleSubmit(onSubmit)} className=\"space-y-4\">\n <Input\n type=\"text\"\n label=\"Recovery Code\"\n placeholder=\"Enter your 32 character recovery code\"\n status={errors.recoveryCode ? \"error\" : status}\n errorMsg={errors.recoveryCode?.message}\n {...register(\"recoveryCode\")}\n />\n <input type=\"submit\" className=\"hidden\" />\n </form>\n <div className=\"space-y-6\">\n <div className=\"flex space-x-2\">\n <Button\n className=\"flex-1\"\n variant=\"secondary\"\n type=\"button\"\n onClick={handleCancel}\n >\n Cancel\n </Button>\n <Button\n className=\"flex-1\"\n loading={isSubmitting}\n disabled={isSubmitting}\n onClick={handleSubmit(onSubmit)}\n >\n Continue\n </Button>\n </div>\n <div className=\"text-base text-zinc-500\">\n Don't have a recovery code?{\" \"}\n <a\n href=\"mailto:support@alpaca.markets\"\n className=\"text-zinc-900 text-base underline hover:underline\"\n >\n Contact support\n </a>\n </div>\n </div>\n </>\n );\n};\n","import Joi from \"joi\";\n\nimport React, { FC, useContext, useState } from \"react\";\n\nimport { Icon } from \"@alpacahq/ui\";\nimport { Auth } from \"@aws-amplify/auth\";\nimport { joiResolver } from \"@hookform/resolvers/joi\";\nimport { useForm } from \"react-hook-form\";\nimport { toast } from \"react-hot-toast\";\nimport { Button } from \"src/v2/components/common/Button\";\nimport { Input } from \"src/v2/components/common/Input\";\nimport { AuthContext, AuthState } from \"..\";\nimport { initAmplify } from \"../../../../reducers/auth/common\";\nimport { TOAST_THEME } from \"../../../theme\";\n\nconst PASSWORD_RESET_SCHEMA = Joi.object({\n verificationCode: Joi.string().required().messages({\n \"string.empty\": \"Verification code is required\",\n }),\n newPassword: Joi.string()\n .required()\n .min(12)\n .pattern(/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\\$%\\^&\\*])/)\n .messages({\n \"string.empty\": \"New password is required\",\n \"string.min\": \"Password must contain at least 12 characters\",\n \"string.pattern.base\":\n \"Password must contain both uppercase and lowercase letters, at least one number or symbol\",\n }),\n confirmPassword: Joi.string()\n .valid(Joi.ref(\"newPassword\"))\n .required()\n .messages({\n \"string.empty\": \"Confirmation of the new password is required\",\n \"any.only\": \"New password and confirmation must match\",\n }),\n}).with(\"newPassword\", \"confirmPassword\");\n\nconst EMAIL_VALIDATION_SCHEMA = Joi.object({\n email: Joi.string()\n .email({ tlds: { allow: false } })\n .required()\n .messages({\n \"string.empty\": \"Please enter an email\",\n \"string.email\": \"Must be a valid email\",\n }),\n});\n\ntype EmailFields = {\n email: string;\n};\n\ntype ResetFields = {\n verificationCode: string;\n newPassword: string;\n confirmPassword: string;\n};\n\nexport const ForgotPassword: FC = () => {\n const { setAuthState } = useContext(AuthContext);\n\n const [email, setEmail] = useState(\"\");\n const [codeSent, setCodeSent] = useState(false);\n const [lastResend, setLastResend] = useState(0);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [passwordVisible, setPasswordVisible] = useState(false);\n const [status, setStatus] = useState<\"neutral\" | \"error\" | \"success\">(\n \"neutral\"\n );\n\n const {\n register: registerReset,\n handleSubmit: handleSubmitReset,\n formState: { errors: errorsReset },\n reset: resetResetForm,\n } = useForm<ResetFields>({\n mode: \"onBlur\",\n reValidateMode: \"onChange\",\n resolver: joiResolver(PASSWORD_RESET_SCHEMA),\n });\n\n const {\n register: registerEmail,\n handleSubmit: handleSubmitEmail,\n formState: { errors: errorsEmail },\n } = useForm<EmailFields>({\n mode: \"onBlur\",\n reValidateMode: \"onChange\",\n resolver: joiResolver(EMAIL_VALIDATION_SCHEMA),\n });\n\n const handleCancel = () => setAuthState(AuthState.LOGIN);\n\n const sendResetCode = async (data: EmailFields) => {\n setIsSubmitting(true);\n initAmplify();\n\n try {\n // send the password reset request\n await Auth.forgotPassword(data.email.toLowerCase());\n\n setCodeSent(true);\n setEmail(data.email.toLowerCase());\n\n toast.success(\"Password reset code has been sent to your email\", {\n ...TOAST_THEME,\n });\n } catch (err) {\n const error = err as Error;\n\n setStatus(\"error\");\n\n toast.error(\n error.message || \"An error occurred during password reset request\",\n { ...TOAST_THEME }\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const resetPassword = async (data: ResetFields) => {\n setIsSubmitting(true);\n initAmplify();\n\n try {\n await Auth.forgotPasswordSubmit(\n email.toLowerCase(),\n data.verificationCode,\n data.newPassword\n );\n\n toast.success(\"Password reset successful!\", {\n ...TOAST_THEME,\n });\n\n // highlight the inputs green\n setStatus(\"success\");\n\n // sleep for 1.5 seconds to allow the success toast to show\n await new Promise((r) => setTimeout(r, 1500));\n\n // redirect\n setAuthState(AuthState.LOGIN);\n } catch (err) {\n const error = err as Error;\n\n setStatus(\"error\");\n toast.error(error.message || \"An error occurred during password reset\", {\n ...TOAST_THEME,\n });\n } finally {\n resetResetForm();\n setIsSubmitting(false);\n }\n };\n\n const resendCode = async () => {\n // get current timestamp\n const now = Date.now();\n\n // calculate milliseconds since the last resend\n const msSinceLastResend = now - lastResend;\n\n // set a throttle limit of 5 seconds to prevent spamming\n const throttleLimit = 5000;\n\n // if the time since the last resend is less than the throttle limit, show an error toast and exit\n if (msSinceLastResend < throttleLimit) {\n const secondsLeft = Math.ceil((throttleLimit - msSinceLastResend) / 1000);\n\n toast.error(\n `Please wait ${secondsLeft} more second(s) before resending.`,\n { ...TOAST_THEME }\n );\n\n return;\n }\n\n setLastResend(now);\n setIsSubmitting(true);\n initAmplify();\n\n try {\n await Auth.forgotPassword(email.toLowerCase());\n\n toast.success(\"Password reset code has been re-sent to your email\", {\n ...TOAST_THEME,\n });\n } catch (err) {\n const error = err as Error;\n\n toast.error(\n error.message || \"An error occurred during password reset request\",\n { ...TOAST_THEME }\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <>\n <form\n className=\"space-y-4\"\n onSubmit={\n codeSent\n ? handleSubmitReset(resetPassword)\n : handleSubmitEmail(sendResetCode)\n }\n >\n <Input\n type=\"email\"\n label=\"Email\"\n placeholder=\"me@example.com\"\n status={errorsEmail.email ? \"error\" : \"neutral\"}\n errorMsg={errorsEmail.email?.message}\n {...registerEmail(\"email\")}\n disabled={codeSent}\n />\n {codeSent && (\n <>\n <Input\n type=\"text\"\n label=\"Verification Code\"\n placeholder=\"Enter your code\"\n status={errorsReset.verificationCode ? \"error\" : status}\n errorMsg={errorsReset.verificationCode?.message}\n {...registerReset(\"verificationCode\")}\n />\n <Input\n type={passwordVisible ? \"text\" : \"password\"}\n label=\"New Password\"\n placeholder=\"••••••••••••••••\"\n status={errorsReset.newPassword ? \"error\" : status}\n errorMsg={errorsReset.newPassword?.message}\n {...registerReset(\"newPassword\")}\n rightIcon={\n <Icon\n className=\"cursor-pointer stroke-2\"\n name={passwordVisible ? \"Eye\" : \"EyeSlash\"}\n onClick={() => setPasswordVisible(!passwordVisible)}\n />\n }\n />\n <Input\n type={passwordVisible ? \"text\" : \"password\"}\n label=\"Confirm Password\"\n placeholder=\"••••••••••••••••\"\n status={errorsReset.confirmPassword ? \"error\" : status}\n errorMsg={errorsReset.confirmPassword?.message}\n {...registerReset(\"confirmPassword\")}\n />\n </>\n )}\n <input type=\"submit\" className=\"hidden\" />\n </form>\n <div className=\"space-y-6\">\n <div className=\"flex space-x-2\">\n <Button\n className=\"flex-1\"\n variant=\"secondary\"\n type=\"button\"\n onClick={handleCancel}\n >\n Cancel\n </Button>\n <Button\n className=\"flex-1\"\n loading={isSubmitting}\n disabled={isSubmitting}\n onClick={\n codeSent\n ? handleSubmitReset(resetPassword)\n : handleSubmitEmail(sendResetCode)\n }\n >\n {codeSent ? \"Reset Password\" : \"Send Code\"}\n </Button>\n </div>\n {codeSent && (\n <div className=\"text-base text-zinc-500\">\n Didn't receive a code?{\" \"}\n <a\n onClick={resendCode}\n className=\"text-zinc-900 text-base underline hover:underline\"\n style={{ fontWeight: 450 }}\n >\n Resend\n </a>\n </div>\n )}\n </div>\n </>\n );\n};\n","import React, { useState, useEffect } from \"react\";\n\nimport { MFA } from \"./forms/MFA\";\nimport { Logo } from \"src/v2/components/Logo\";\nimport { Login } from \"./forms/Login\";\nimport { titleCase } from \"../../helpers\";\nimport { Disclosure } from \"./Disclosure\";\nimport { MFARecovery } from \"./forms/MFARecovery\";\nimport { CognitoUser } from \"amazon-cognito-identity-js\";\nimport { ForgotPassword } from \"./forms/ForgotPassword\";\nimport { CognitoUserExtended } from \"../../api/auth\";\n\nexport enum AuthState {\n LOGIN = \"LOGIN\",\n SIGNUP = \"SIGNUP\", // todo: implement signup flow\n FORGOT_PASSWORD = \"FORGOT_PASSWORD\",\n MFA = \"MFA\",\n MFA_RECOVERY = \"MFA_RECOVERY\",\n}\n\ntype AuthStateContextProps = {\n authState: AuthState;\n cognitoUser?: CognitoUserExtended;\n setAuthState: React.Dispatch<React.SetStateAction<AuthState>>;\n setCognitoUser: React.Dispatch<React.SetStateAction<CognitoUser | undefined>>;\n};\n\nexport const AuthContext = React.createContext<AuthStateContextProps>(\n {} as any\n);\n\nexport default function Auth() {\n const [authState, setAuthState] = useState(AuthState.LOGIN);\n const [cognitoUser, setCognitoUser] = useState<CognitoUser | undefined>();\n\n useEffect(() => {\n document.title = `Alpaca - ${titleCase(authState)}`;\n }, [authState]);\n\n const forms = {\n [AuthState.LOGIN]: {\n title: \"Login\",\n subtitle: \"Enter your email and password to login.\",\n form: <Login />,\n },\n [AuthState.SIGNUP]: {\n title: \"Sign Up\",\n subtitle: \"Sign up for a new account.\",\n form: null, // @todo: implement signup flow\n },\n [AuthState.FORGOT_PASSWORD]: {\n title: \"Forgot Password\",\n subtitle: \"Enter your email to reset your password.\",\n form: <ForgotPassword />,\n },\n [AuthState.MFA]: {\n title: \"MFA\",\n subtitle: \"Enter your MFA code.\",\n form: <MFA />,\n },\n [AuthState.MFA_RECOVERY]: {\n title: \"MFA Recovery\",\n subtitle: \"Enter your MFA recovery code.\",\n form: <MFARecovery />,\n },\n };\n\n const { title, subtitle, form } = forms[authState] || {};\n\n return (\n <AuthContext.Provider\n value={{ authState, cognitoUser, setAuthState, setCognitoUser }}\n >\n <div className=\"p-6 md:py-28 space-y-6 md:space-y-28\">\n <div className=\"transition-all ease-in-out\">\n <div className=\"space-y-4 min-w-fit w-full md:w-[400px] mx-auto transition-all ease-in-out\">\n <Logo onClick={() => setAuthState(AuthState.LOGIN)} />\n <div>\n <h1 className=\"font-semibold text-2xl mb-4\">{title}</h1>\n <div className=\"text-md text-zinc-500\">{subtitle}</div>\n </div>\n {form}\n </div>\n </div>\n <Disclosure />\n </div>\n </AuthContext.Provider>\n );\n}\n"],"sourceRoot":""}