mirror of
https://github.com/Myzel394/kleckrelay-website.git
synced 2025-06-19 15:55:26 +02:00
fixed password setup not working; general improvements & bugfixes
This commit is contained in:
parent
4ab7303071
commit
934a071f81
@ -11,13 +11,13 @@ export enum EncryptionStatus {
|
|||||||
interface AuthContextTypeBase {
|
interface AuthContextTypeBase {
|
||||||
user: ServerUser | User | null
|
user: ServerUser | User | null
|
||||||
isAuthenticated: boolean
|
isAuthenticated: boolean
|
||||||
login: (user: ServerUser | User) => void
|
login: (user: ServerUser | User, callback?: () => void) => void
|
||||||
logout: () => void
|
logout: () => void
|
||||||
encryptionStatus: EncryptionStatus
|
encryptionStatus: EncryptionStatus
|
||||||
_decryptUsingMasterPassword: (content: string) => string
|
_decryptUsingMasterPassword: (content: string) => string
|
||||||
_encryptUsingMasterPassword: (content: string) => string
|
_encryptUsingMasterPassword: (content: string) => string
|
||||||
_decryptUsingPrivateKey: (message: string) => Promise<string>
|
_decryptUsingPrivateKey: (message: string) => Promise<string>
|
||||||
_setDecryptionPassword: (decryptionPassword: string) => boolean
|
_setDecryptionPassword: (decryptionPassword: string, callback?: () => void) => boolean
|
||||||
_updateUser: (user: ServerUser | User) => void
|
_updateUser: (user: ServerUser | User) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {ReactElement, ReactNode, useCallback} from "react"
|
import {ReactElement, ReactNode, useCallback} from "react"
|
||||||
import {useLocalStorage} from "react-use"
|
import {useLocalStorage} from "react-use"
|
||||||
import fastHashCode from "fast-hash-code";
|
import fastHashCode from "fast-hash-code"
|
||||||
|
|
||||||
import {ServerUser, User} from "~/server-types"
|
import {ServerUser, User} from "~/server-types"
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ import PasswordShareConfirmationDialog from "./PasswordShareConfirmationDialog"
|
|||||||
import useContextValue from "./use-context-value"
|
import useContextValue from "./use-context-value"
|
||||||
import useExtensionHandler from "./use-extension-handler"
|
import useExtensionHandler from "./use-extension-handler"
|
||||||
import useMasterPassword from "./use-master-password"
|
import useMasterPassword from "./use-master-password"
|
||||||
import useUser from "./use-user";
|
import useUser from "./use-user"
|
||||||
|
|
||||||
export interface AuthContextProviderProps {
|
export interface AuthContextProviderProps {
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
@ -26,9 +26,11 @@ export default function AuthContextProvider({children}: AuthContextProviderProps
|
|||||||
decryptUsingMasterPassword,
|
decryptUsingMasterPassword,
|
||||||
decryptUsingPrivateKey,
|
decryptUsingPrivateKey,
|
||||||
setDecryptionPassword,
|
setDecryptionPassword,
|
||||||
|
decryptionPasswordHash,
|
||||||
_masterPassword,
|
_masterPassword,
|
||||||
logout: logoutMasterPassword,
|
logout: logoutMasterPassword,
|
||||||
} = useMasterPassword(user || null)
|
} = useMasterPassword(user || null)
|
||||||
|
const passwordHash = _masterPassword ? fastHashCode(_masterPassword).toString() : null
|
||||||
const {sharePassword, closeDialog, showDialog, dispatchPasswordStatus} = useExtensionHandler(
|
const {sharePassword, closeDialog, showDialog, dispatchPasswordStatus} = useExtensionHandler(
|
||||||
_masterPassword!,
|
_masterPassword!,
|
||||||
user as User,
|
user as User,
|
||||||
@ -39,10 +41,11 @@ export default function AuthContextProvider({children}: AuthContextProviderProps
|
|||||||
}, [logoutMasterPassword])
|
}, [logoutMasterPassword])
|
||||||
|
|
||||||
const contextValue = useContextValue({
|
const contextValue = useContextValue({
|
||||||
decryptUsingPrivateKey,
|
_decryptUsingPrivateKey: decryptUsingPrivateKey,
|
||||||
encryptUsingMasterPassword,
|
_encryptUsingMasterPassword: encryptUsingMasterPassword,
|
||||||
decryptUsingMasterPassword,
|
_decryptUsingMasterPassword: decryptUsingMasterPassword,
|
||||||
setDecryptionPassword,
|
_setDecryptionPassword: setDecryptionPassword,
|
||||||
|
decryptionPasswordHash,
|
||||||
logout,
|
logout,
|
||||||
login: setUser,
|
login: setUser,
|
||||||
user: user || null,
|
user: user || null,
|
||||||
@ -53,7 +56,7 @@ export default function AuthContextProvider({children}: AuthContextProviderProps
|
|||||||
decryptUsingMasterPassword,
|
decryptUsingMasterPassword,
|
||||||
user: user || null,
|
user: user || null,
|
||||||
updateUser: setUser,
|
updateUser: setUser,
|
||||||
masterPasswordHash: _masterPassword ? fastHashCode(_masterPassword).toString() : null,
|
masterPasswordHash: passwordHash,
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,49 +1,86 @@
|
|||||||
|
import {useMemo, useRef} from "react"
|
||||||
|
import {useUpdateEffect} from "react-use"
|
||||||
|
|
||||||
import {AuthContextType, EncryptionStatus} from "~/AuthContext/AuthContext"
|
import {AuthContextType, EncryptionStatus} from "~/AuthContext/AuthContext"
|
||||||
import {ServerUser, User} from "~/server-types"
|
import {ServerUser, User} from "~/server-types"
|
||||||
|
|
||||||
export interface UseContextValueData {
|
export type UseContextValueData = Pick<
|
||||||
user: User | ServerUser | null
|
AuthContextType,
|
||||||
|
| "user"
|
||||||
|
| "logout"
|
||||||
|
| "_encryptUsingMasterPassword"
|
||||||
|
| "_decryptUsingMasterPassword"
|
||||||
|
| "_decryptUsingPrivateKey"
|
||||||
|
> & {
|
||||||
|
decryptionPasswordHash: string
|
||||||
|
_setDecryptionPassword: (password: string) => boolean
|
||||||
login: (user: User | ServerUser) => void
|
login: (user: User | ServerUser) => void
|
||||||
logout: () => void
|
|
||||||
encryptUsingMasterPassword: (content: string) => string
|
|
||||||
decryptUsingMasterPassword: (content: string) => string
|
|
||||||
decryptUsingPrivateKey: (message: string) => Promise<string>
|
|
||||||
setDecryptionPassword: (password: string) => boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function useContextValue({
|
export default function useContextValue({
|
||||||
user,
|
user,
|
||||||
login,
|
login,
|
||||||
logout,
|
logout,
|
||||||
encryptUsingMasterPassword,
|
_encryptUsingMasterPassword,
|
||||||
decryptUsingMasterPassword,
|
_decryptUsingMasterPassword,
|
||||||
setDecryptionPassword,
|
_setDecryptionPassword,
|
||||||
decryptUsingPrivateKey,
|
_decryptUsingPrivateKey,
|
||||||
|
decryptionPasswordHash,
|
||||||
}: UseContextValueData): AuthContextType {
|
}: UseContextValueData): AuthContextType {
|
||||||
return {
|
const $decryptionPasswordChangeCallback = useRef<(() => void) | null>(null)
|
||||||
user,
|
const $userChangeCallback = useRef<(() => void) | null>(null)
|
||||||
login,
|
|
||||||
logout,
|
|
||||||
isAuthenticated: Boolean(user),
|
|
||||||
encryptionStatus: (() => {
|
|
||||||
if (!user) {
|
|
||||||
return EncryptionStatus.Unavailable
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user.encryptedPassword) {
|
useUpdateEffect(() => {
|
||||||
return EncryptionStatus.Unavailable
|
$decryptionPasswordChangeCallback.current?.()
|
||||||
}
|
}, [decryptionPasswordHash, user])
|
||||||
|
|
||||||
if (user.isDecrypted) {
|
return useMemo(
|
||||||
return EncryptionStatus.Available
|
() => ({
|
||||||
}
|
user,
|
||||||
|
login: (user, callback) => {
|
||||||
|
if (callback) {
|
||||||
|
$userChangeCallback.current = callback
|
||||||
|
}
|
||||||
|
|
||||||
return EncryptionStatus.PasswordRequired
|
return login(user)
|
||||||
})(),
|
},
|
||||||
_updateUser: login,
|
logout,
|
||||||
_setDecryptionPassword: setDecryptionPassword,
|
isAuthenticated: Boolean(user),
|
||||||
_encryptUsingMasterPassword: encryptUsingMasterPassword,
|
encryptionStatus: (() => {
|
||||||
_decryptUsingMasterPassword: decryptUsingMasterPassword,
|
if (!user) {
|
||||||
_decryptUsingPrivateKey: decryptUsingPrivateKey,
|
return EncryptionStatus.Unavailable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!user.encryptedPassword) {
|
||||||
|
return EncryptionStatus.Unavailable
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.isDecrypted) {
|
||||||
|
return EncryptionStatus.Available
|
||||||
|
}
|
||||||
|
|
||||||
|
return EncryptionStatus.PasswordRequired
|
||||||
|
})(),
|
||||||
|
_updateUser: login,
|
||||||
|
_setDecryptionPassword: (password, callback) => {
|
||||||
|
if (callback) {
|
||||||
|
$decryptionPasswordChangeCallback.current = callback
|
||||||
|
}
|
||||||
|
|
||||||
|
return _setDecryptionPassword(password)
|
||||||
|
},
|
||||||
|
_encryptUsingMasterPassword,
|
||||||
|
_decryptUsingMasterPassword,
|
||||||
|
_decryptUsingPrivateKey,
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
user,
|
||||||
|
login,
|
||||||
|
logout,
|
||||||
|
_setDecryptionPassword,
|
||||||
|
_encryptUsingMasterPassword,
|
||||||
|
_decryptUsingMasterPassword,
|
||||||
|
_decryptUsingPrivateKey,
|
||||||
|
],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import {useLocalStorage} from "react-use"
|
import {useLocalStorage} from "react-use"
|
||||||
import {useCallback, useMemo} from "react"
|
import {useCallback, useMemo} from "react"
|
||||||
import {decrypt, readMessage, readPrivateKey} from "openpgp";
|
import {decrypt, readMessage, readPrivateKey} from "openpgp"
|
||||||
|
import fastHashCode from "fast-hash-code"
|
||||||
|
|
||||||
import {decryptString, encryptString} from "~/utils"
|
import {decryptString, encryptString} from "~/utils"
|
||||||
import {ServerUser, User} from "~/server-types";
|
import {ServerUser, User} from "~/server-types"
|
||||||
|
|
||||||
export interface UseMasterPasswordResult {
|
export interface UseMasterPasswordResult {
|
||||||
encryptUsingMasterPassword: (content: string) => string
|
encryptUsingMasterPassword: (content: string) => string
|
||||||
@ -12,13 +13,12 @@ export interface UseMasterPasswordResult {
|
|||||||
|
|
||||||
setDecryptionPassword: (password: string) => boolean
|
setDecryptionPassword: (password: string) => boolean
|
||||||
logout: () => void
|
logout: () => void
|
||||||
|
decryptionPasswordHash: string
|
||||||
// Use this cautiously
|
// Use this cautiously
|
||||||
_masterPassword: string
|
_masterPassword: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function useMasterPassword(
|
export default function useMasterPassword(user: User | ServerUser | null): UseMasterPasswordResult {
|
||||||
user: User | ServerUser | null,
|
|
||||||
): UseMasterPasswordResult {
|
|
||||||
const [decryptionPassword, setDecryptionPassword] = useLocalStorage<string | null>(
|
const [decryptionPassword, setDecryptionPassword] = useLocalStorage<string | null>(
|
||||||
"_global-context-auth-decryption-password",
|
"_global-context-auth-decryption-password",
|
||||||
null,
|
null,
|
||||||
@ -78,21 +78,23 @@ export default function useMasterPassword(
|
|||||||
[user],
|
[user],
|
||||||
)
|
)
|
||||||
|
|
||||||
const updateDecryptionPassword = useCallback((password: string) => {
|
const updateDecryptionPassword = useCallback(
|
||||||
if (!user || !user.encryptedPassword) {
|
(password: string) => {
|
||||||
throw new Error("User not set.")
|
if (user?.encryptedPassword) {
|
||||||
}
|
try {
|
||||||
|
const masterPassword = decryptString(user.encryptedPassword, password)
|
||||||
|
JSON.parse(decryptString((user as ServerUser).encryptedNotes, masterPassword))
|
||||||
|
} catch (e) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
const masterPassword = decryptString(user.encryptedPassword, password)
|
|
||||||
JSON.parse(decryptString((user as ServerUser).encryptedNotes, masterPassword))
|
|
||||||
setDecryptionPassword(password)
|
setDecryptionPassword(password)
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true
|
||||||
}, [user, masterPassword])
|
},
|
||||||
|
[user, masterPassword],
|
||||||
|
)
|
||||||
|
|
||||||
const logout = useCallback(() => {
|
const logout = useCallback(() => {
|
||||||
setDecryptionPassword(null)
|
setDecryptionPassword(null)
|
||||||
@ -105,5 +107,6 @@ export default function useMasterPassword(
|
|||||||
logout,
|
logout,
|
||||||
setDecryptionPassword: updateDecryptionPassword,
|
setDecryptionPassword: updateDecryptionPassword,
|
||||||
_masterPassword: masterPassword!,
|
_masterPassword: masterPassword!,
|
||||||
|
decryptionPasswordHash: fastHashCode(decryptionPassword || "").toString(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,77 +1,74 @@
|
|||||||
import {Dispatch, SetStateAction, useEffect} from "react";
|
import {Dispatch, SetStateAction, useEffect} from "react"
|
||||||
import {AxiosError} from "axios";
|
import {AxiosError} from "axios"
|
||||||
|
|
||||||
import {useMutation, useQuery} from "@tanstack/react-query";
|
import {useMutation, useQuery} from "@tanstack/react-query"
|
||||||
|
|
||||||
import {REFRESH_TOKEN_URL, RefreshTokenResult, getMe, refreshToken} from "~/apis"
|
import {REFRESH_TOKEN_URL, RefreshTokenResult, getMe, refreshToken} from "~/apis"
|
||||||
import {AuthenticationDetails, ServerUser, User} from "~/server-types";
|
import {AuthenticationDetails, ServerUser, User} from "~/server-types"
|
||||||
import {client} from "~/constants/axios-client";
|
import {client} from "~/constants/axios-client"
|
||||||
|
|
||||||
export interface UseAuthData {
|
export interface UseAuthData {
|
||||||
logout: () => void
|
logout: () => void
|
||||||
masterPasswordHash: string | null
|
masterPasswordHash: string | null
|
||||||
decryptUsingMasterPassword: (content: string) => string
|
decryptUsingMasterPassword: (content: string) => string
|
||||||
user: User | ServerUser | null
|
user: User | ServerUser | null
|
||||||
updateUser: Dispatch<SetStateAction<User | ServerUser | null | undefined>>
|
updateUser: Dispatch<SetStateAction<User | ServerUser | null | undefined>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function useUser({
|
export default function useUser({
|
||||||
logout,
|
logout,
|
||||||
masterPasswordHash,
|
masterPasswordHash,
|
||||||
decryptUsingMasterPassword,
|
decryptUsingMasterPassword,
|
||||||
user,
|
user,
|
||||||
updateUser,
|
updateUser,
|
||||||
}: UseAuthData) {
|
}: UseAuthData) {
|
||||||
const {mutateAsync: refresh} = useMutation<RefreshTokenResult, AxiosError, void>(refreshToken, {
|
const {mutateAsync: refresh} = useMutation<RefreshTokenResult, AxiosError, void>(refreshToken, {
|
||||||
onError: () => logout(),
|
onError: () => logout(),
|
||||||
})
|
})
|
||||||
|
|
||||||
useQuery<AuthenticationDetails, AxiosError>(["get_me"], getMe, {
|
useQuery<AuthenticationDetails, AxiosError>(["get_me"], getMe, {
|
||||||
refetchOnWindowFocus: "always",
|
refetchOnWindowFocus: "always",
|
||||||
refetchOnReconnect: "always",
|
refetchOnReconnect: "always",
|
||||||
retry: 2,
|
retry: 2,
|
||||||
enabled: user !== null,
|
enabled: user !== null,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Decrypt user notes
|
// Decrypt user notes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (user && !user.isDecrypted && user.encryptedPassword && masterPasswordHash) {
|
if (user && !user.isDecrypted && user.encryptedPassword && masterPasswordHash) {
|
||||||
const note = JSON.parse(decryptUsingMasterPassword(user.encryptedNotes!))
|
const note = JSON.parse(decryptUsingMasterPassword(user.encryptedNotes!))
|
||||||
|
|
||||||
updateUser(
|
updateUser({
|
||||||
prevUser =>
|
...user,
|
||||||
({
|
notes: note,
|
||||||
...(prevUser || {}),
|
isDecrypted: true,
|
||||||
notes: note,
|
} as User)
|
||||||
isDecrypted: true,
|
}
|
||||||
} as User),
|
}, [user, decryptUsingMasterPassword, updateUser, masterPasswordHash])
|
||||||
)
|
|
||||||
}
|
|
||||||
}, [user, decryptUsingMasterPassword, updateUser, masterPasswordHash])
|
|
||||||
|
|
||||||
// Refresh token and logout user if needed
|
// Refresh token and logout user if needed
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const interceptor = client.interceptors.response.use(
|
const interceptor = client.interceptors.response.use(
|
||||||
response => response,
|
response => response,
|
||||||
async (error: AxiosError) => {
|
async (error: AxiosError) => {
|
||||||
if (error.isAxiosError) {
|
if (error.isAxiosError) {
|
||||||
if (error.response?.status === 401) {
|
if (error.response?.status === 401) {
|
||||||
// Check if error comes from refreshing the token.
|
// Check if error comes from refreshing the token.
|
||||||
// If yes, the user has been logged out completely.
|
// If yes, the user has been logged out completely.
|
||||||
const request: XMLHttpRequest = error.request
|
const request: XMLHttpRequest = error.request
|
||||||
|
|
||||||
if (request.responseURL === REFRESH_TOKEN_URL) {
|
if (request.responseURL === REFRESH_TOKEN_URL) {
|
||||||
await logout()
|
await logout()
|
||||||
} else {
|
} else {
|
||||||
await refresh()
|
await refresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error
|
throw error
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
return () => client.interceptors.response.eject(interceptor)
|
return () => client.interceptors.response.eject(interceptor)
|
||||||
}, [logout, refresh])
|
}, [logout, refresh])
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import passwordGenerator from "secure-random-password"
|
|||||||
import {PasswordField, SimpleForm} from "~/components"
|
import {PasswordField, SimpleForm} from "~/components"
|
||||||
import {buildEncryptionPassword, encryptString} from "~/utils"
|
import {buildEncryptionPassword, encryptString} from "~/utils"
|
||||||
import {isDev} from "~/constants/development"
|
import {isDev} from "~/constants/development"
|
||||||
import {useExtensionHandler, useSystemPreferredTheme, useUser} from "~/hooks"
|
import {useExtensionHandler, useNavigateToNext, useSystemPreferredTheme, useUser} from "~/hooks"
|
||||||
import {MASTER_PASSWORD_LENGTH} from "~/constants/values"
|
import {MASTER_PASSWORD_LENGTH} from "~/constants/values"
|
||||||
import {AuthenticationDetails, UserNote} from "~/server-types"
|
import {AuthenticationDetails, UserNote} from "~/server-types"
|
||||||
import {UpdateAccountData, updateAccount} from "~/apis"
|
import {UpdateAccountData, updateAccount} from "~/apis"
|
||||||
@ -34,6 +34,7 @@ export default function PasswordForm({onDone}: PasswordFormProps): ReactElement
|
|||||||
const user = useUser()
|
const user = useUser()
|
||||||
const theme = useSystemPreferredTheme()
|
const theme = useSystemPreferredTheme()
|
||||||
|
|
||||||
|
const navigateToNext = useNavigateToNext()
|
||||||
const $password = useRef<HTMLInputElement | null>(null)
|
const $password = useRef<HTMLInputElement | null>(null)
|
||||||
const $passwordConfirmation = useRef<HTMLInputElement | null>(null)
|
const $passwordConfirmation = useRef<HTMLInputElement | null>(null)
|
||||||
const schema = yup.object().shape({
|
const schema = yup.object().shape({
|
||||||
@ -65,12 +66,6 @@ export default function PasswordForm({onDone}: PasswordFormProps): ReactElement
|
|||||||
)
|
)
|
||||||
const {mutateAsync} = useMutation<AuthenticationDetails, AxiosError, UpdateAccountData>(
|
const {mutateAsync} = useMutation<AuthenticationDetails, AxiosError, UpdateAccountData>(
|
||||||
updateAccount,
|
updateAccount,
|
||||||
{
|
|
||||||
onSuccess: ({user}) => {
|
|
||||||
login(user)
|
|
||||||
setTimeout(onDone, 0)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
const formik = useFormik<Form>({
|
const formik = useFormik<Form>({
|
||||||
validationSchema: schema,
|
validationSchema: schema,
|
||||||
@ -97,19 +92,25 @@ export default function PasswordForm({onDone}: PasswordFormProps): ReactElement
|
|||||||
}
|
}
|
||||||
const encryptedNotes = encryptUserNote(note, masterPassword)
|
const encryptedNotes = encryptUserNote(note, masterPassword)
|
||||||
|
|
||||||
_setDecryptionPassword(encryptionPassword)
|
await mutateAsync(
|
||||||
|
{
|
||||||
await mutateAsync({
|
encryptedPassword: encryptedMasterPassword,
|
||||||
encryptedPassword: encryptedMasterPassword,
|
publicKey: (
|
||||||
publicKey: (
|
await readKey({
|
||||||
await readKey({
|
armoredKey: keyPair.publicKey,
|
||||||
armoredKey: keyPair.publicKey,
|
})
|
||||||
})
|
)
|
||||||
)
|
.toPublic()
|
||||||
.toPublic()
|
.armor(),
|
||||||
.armor(),
|
encryptedNotes,
|
||||||
encryptedNotes,
|
},
|
||||||
})
|
{
|
||||||
|
onSuccess: ({user: newUser}) => {
|
||||||
|
login(newUser)
|
||||||
|
_setDecryptionPassword(encryptionPassword, navigateToNext)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setErrors({detail: t("general.defaultError")})
|
setErrors({detail: t("general.defaultError")})
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ export default function ConfirmCodeForm({
|
|||||||
sameRequestToken,
|
sameRequestToken,
|
||||||
}: ConfirmCodeFormProps): ReactElement {
|
}: ConfirmCodeFormProps): ReactElement {
|
||||||
const settings = useLoaderData() as ServerSettings
|
const settings = useLoaderData() as ServerSettings
|
||||||
const expirationTime = isDev ? 9 : settings.emailLoginExpirationInSeconds
|
const expirationTime = isDev ? 70 : settings.emailLoginExpirationInSeconds
|
||||||
const {t} = useTranslation()
|
const {t} = useTranslation()
|
||||||
const requestDate = useMemo(() => new Date(), [])
|
const requestDate = useMemo(() => new Date(), [])
|
||||||
const [isExpiringSoon, setIsExpiringSoon] = useState<boolean>(false)
|
const [isExpiringSoon, setIsExpiringSoon] = useState<boolean>(false)
|
||||||
|
@ -36,15 +36,14 @@ export default function EnterDecryptionPassword(): ReactElement {
|
|||||||
onSubmit: async ({password}, {setErrors}) => {
|
onSubmit: async ({password}, {setErrors}) => {
|
||||||
const decryptionPassword = buildEncryptionPassword(password, user.email.address)
|
const decryptionPassword = buildEncryptionPassword(password, user.email.address)
|
||||||
|
|
||||||
console.log("decryptionPassword", decryptionPassword)
|
const isPasswordCorrect = _setDecryptionPassword(decryptionPassword, navigateToNext)
|
||||||
if (!_setDecryptionPassword(decryptionPassword)) {
|
|
||||||
|
if (!isPasswordCorrect) {
|
||||||
setErrors({
|
setErrors({
|
||||||
password: t(
|
password: t(
|
||||||
"components.EnterDecryptionPassword.form.password.errors.invalidPassword",
|
"components.EnterDecryptionPassword.form.password.errors.invalidPassword",
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
setTimeout(navigateToNext, 0)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user