chore: auth verification (#2867) [skip e2e]

This commit is contained in:
Mo
2024-04-08 10:52:56 -05:00
committed by GitHub
parent a37e095907
commit b6eda707bd
30 changed files with 516 additions and 205 deletions

View File

@@ -2,10 +2,13 @@ import Button from '@/Components/Button/Button'
import { WebApplication } from '@/Application/WebApplication'
import { PurchaseFlowPane } from '@/Controllers/PurchaseFlow/PurchaseFlowPane'
import { observer } from 'mobx-react-lite'
import { ChangeEventHandler, FunctionComponent, useEffect, useRef, useState } from 'react'
import { ChangeEventHandler, FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
import FloatingLabelInput from '@/Components/Input/FloatingLabelInput'
import { isEmailValid } from '@/Utils'
import { BlueDotIcon, CircleIcon, DiamondIcon, CreateAccountIllustration } from '@standardnotes/icons'
import { useCaptcha } from '@/Hooks/useCaptcha'
import { AccountMenuPane } from '../../AccountMenu/AccountMenuPane'
import { isErrorResponse } from '@standardnotes/snjs'
type Props = {
application: WebApplication
@@ -20,6 +23,61 @@ const CreateAccount: FunctionComponent<Props> = ({ application }) => {
const [isEmailInvalid, setIsEmailInvalid] = useState(false)
const [isPasswordNotMatching, setIsPasswordNotMatching] = useState(false)
const [hvmToken, setHVMToken] = useState('')
const [captchaURL, setCaptchaURL] = useState('')
const register = useCallback(() => {
setIsCreatingAccount(true)
application
.register(email, password, hvmToken)
.then(() => {
application.accountMenuController.closeAccountMenu()
application.accountMenuController.setCurrentPane(AccountMenuPane.GeneralMenu)
})
.catch((err) => {
console.error(err)
application.alerts.alert(err as string).catch(console.error)
})
.finally(() => {
setIsCreatingAccount(false)
})
}, [application, email, hvmToken, password])
const captchaIframe = useCaptcha(captchaURL, (token) => {
setHVMToken(token)
setCaptchaURL('')
})
useEffect(() => {
if (!hvmToken) {
return
}
register()
}, [hvmToken, register])
const checkIfCaptchaRequiredAndRegister = useCallback(() => {
application
.getCaptchaUrl()
.then((response) => {
if (isErrorResponse(response)) {
throw new Error()
}
const { captchaUIUrl } = response.data
if (captchaUIUrl) {
setCaptchaURL(captchaUIUrl)
} else {
setCaptchaURL('')
register()
}
})
.catch((error) => {
console.error(error)
setCaptchaURL('')
register()
})
}, [application, register])
const emailInputRef = useRef<HTMLInputElement>(null)
const passwordInputRef = useRef<HTMLInputElement>(null)
const confirmPasswordInputRef = useRef<HTMLInputElement>(null)
@@ -81,21 +139,52 @@ const CreateAccount: FunctionComponent<Props> = ({ application }) => {
return
}
setIsCreatingAccount(true)
try {
await application.register(email, password)
application.purchaseFlowController.closePurchaseFlow()
void application.purchaseFlowController.openPurchaseFlow()
} catch (err) {
console.error(err)
application.alerts.alert(err as string).catch(console.error)
} finally {
setIsCreatingAccount(false)
}
checkIfCaptchaRequiredAndRegister()
}
const CreateAccountForm = (
<form onSubmit={handleCreateAccount}>
<div className="flex flex-col">
<FloatingLabelInput
className={`min-w-auto md:min-w-90 ${isEmailInvalid ? 'mb-2' : 'mb-4'}`}
id="purchase-sign-in-email"
type="email"
label="Email"
value={email}
onChange={handleEmailChange}
ref={emailInputRef}
disabled={isCreatingAccount}
isInvalid={isEmailInvalid}
/>
{isEmailInvalid ? <div className="mb-4 text-danger">Please provide a valid email.</div> : null}
<FloatingLabelInput
className="min-w-auto mb-4 md:min-w-90"
id="purchase-create-account-password"
type="password"
label="Password"
value={password}
onChange={handlePasswordChange}
ref={passwordInputRef}
disabled={isCreatingAccount}
/>
<FloatingLabelInput
className={`min-w-auto md:min-w-90 ${isPasswordNotMatching ? 'mb-2' : 'mb-4'}`}
id="create-account-confirm"
type="password"
label="Repeat password"
value={confirmPassword}
onChange={handleConfirmPasswordChange}
ref={confirmPasswordInputRef}
disabled={isCreatingAccount}
isInvalid={isPasswordNotMatching}
/>
{isPasswordNotMatching ? (
<div className="mb-4 text-danger">Passwords don't match. Please try again.</div>
) : null}
</div>
</form>
)
return (
<div className="flex items-center">
<CircleIcon className="absolute -left-28 top-[40%] h-8 w-8" />
@@ -109,46 +198,7 @@ const CreateAccount: FunctionComponent<Props> = ({ application }) => {
<div className="mr-0 lg:mr-12">
<h1 className="mb-2 mt-0 text-2xl font-bold">Create your free account</h1>
<div className="mb-4 text-sm font-medium">to continue to Standard Notes.</div>
<form onSubmit={handleCreateAccount}>
<div className="flex flex-col">
<FloatingLabelInput
className={`min-w-auto md:min-w-90 ${isEmailInvalid ? 'mb-2' : 'mb-4'}`}
id="purchase-sign-in-email"
type="email"
label="Email"
value={email}
onChange={handleEmailChange}
ref={emailInputRef}
disabled={isCreatingAccount}
isInvalid={isEmailInvalid}
/>
{isEmailInvalid ? <div className="mb-4 text-danger">Please provide a valid email.</div> : null}
<FloatingLabelInput
className="min-w-auto mb-4 md:min-w-90"
id="purchase-create-account-password"
type="password"
label="Password"
value={password}
onChange={handlePasswordChange}
ref={passwordInputRef}
disabled={isCreatingAccount}
/>
<FloatingLabelInput
className={`min-w-auto md:min-w-90 ${isPasswordNotMatching ? 'mb-2' : 'mb-4'}`}
id="create-account-confirm"
type="password"
label="Repeat password"
value={confirmPassword}
onChange={handleConfirmPasswordChange}
ref={confirmPasswordInputRef}
disabled={isCreatingAccount}
isInvalid={isPasswordNotMatching}
/>
{isPasswordNotMatching ? (
<div className="mb-4 text-danger">Passwords don't match. Please try again.</div>
) : null}
</div>
</form>
{captchaURL ? captchaIframe : CreateAccountForm}
<div className="flex flex-col-reverse items-start justify-between md:flex-row md:items-center">
<div className="flex flex-col">
<button