Skip to content

Commit

Permalink
Fix invalid secret key error message
Browse files Browse the repository at this point in the history
  • Loading branch information
OKendigelyan committed May 22, 2024
1 parent 93c7039 commit 9baa572
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ describe("<RestoreSecretKey />", () => {
it("requires the password when the secret key is encrypted", async () => {
render(fixture());

fireEvent.change(screen.getByTestId("secret-key"), { target: { value: "edesk..." } });
fireEvent.change(screen.getByTestId("secret-key"), {
target: { value: "edesk..." },
});
await screen.findByTestId("password");

fireEvent.blur(screen.getByTestId("password"));
Expand Down Expand Up @@ -75,9 +77,9 @@ describe("<RestoreSecretKey />", () => {
await act(() => user.type(screen.getByTestId("password"), password));
}

expect(screen.getByRole("button")).toBeEnabled();
expect(screen.getByTestId("restore-continue-button")).toBeEnabled();

await act(() => user.click(screen.getByRole("button", { name: "Continue" })));
await act(() => user.click(screen.getByTestId("restore-continue-button")));

expect(goToStepMock).toHaveBeenCalledWith({
type: "nameAccount",
Expand All @@ -96,9 +98,9 @@ describe("<RestoreSecretKey />", () => {

await act(() => user.type(screen.getByTestId("password"), "wrong password"));

expect(screen.getByRole("button")).toBeEnabled();
expect(screen.getByTestId("restore-continue-button")).toBeEnabled();

await act(() => user.click(screen.getByRole("button", { name: "Continue" })));
await act(() => user.click(screen.getByTestId("restore-continue-button")));

expect(mockToast).toHaveBeenCalledWith({
description: "Key-password pair is invalid",
Expand All @@ -112,9 +114,9 @@ describe("<RestoreSecretKey />", () => {

await act(() => user.type(screen.getByTestId("secret-key"), UNENCRYPTED_SECRET_KEY + "asdasd"));

expect(screen.getByRole("button")).toBeEnabled();
expect(screen.getByTestId("restore-continue-button")).toBeEnabled();

await act(() => user.click(screen.getByRole("button", { name: "Continue" })));
await act(() => user.click(screen.getByTestId("restore-continue-button")));

expect(mockToast).toHaveBeenCalledWith({
description: "Invalid secret key: checksum doesn't match",
Expand All @@ -128,9 +130,9 @@ describe("<RestoreSecretKey />", () => {

await act(() => user.type(screen.getByTestId("secret-key"), "something invalid"));

expect(screen.getByRole("button")).toBeEnabled();
expect(screen.getByTestId("restore-continue-button")).toBeEnabled();

await act(() => user.click(screen.getByRole("button", { name: "Continue" })));
await act(() => user.click(screen.getByTestId("restore-continue-button")));

expect(mockToast).toHaveBeenCalledWith({
description:
Expand Down
91 changes: 43 additions & 48 deletions src/components/Onboarding/restoreSecretKey/RestoreSecretKey.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@
import {
Button,
FormControl,
FormErrorMessage,
FormLabel,
Input,
Textarea,
} from "@chakra-ui/react";
import { Button, FormControl, FormErrorMessage, FormLabel, Textarea } from "@chakra-ui/react";
import { InMemorySigner } from "@taquito/signer";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { FormProvider, useForm } from "react-hook-form";

import { KeyIcon } from "../../../assets/icons";
import colors from "../../../style/colors";
import { useAsyncActionHandler } from "../../../utils/hooks/useAsyncActionHandler";
import { isEncryptedSecretKeyPrefix } from "../../../utils/redux/thunks/secretKeyAccount";
import { PasswordInput } from "../../PasswordInput";
import { ModalContentWrapper } from "../ModalContentWrapper";
import { OnboardingStep } from "../OnboardingStep";

export const RestoreSecretKey = ({ goToStep }: { goToStep: (step: OnboardingStep) => void }) => {
const [isEncrypted, setIsEncrypted] = useState(false);
const { handleAsyncAction } = useAsyncActionHandler();

const form = useForm<{ secretKey: string; password: string }>({
mode: "onBlur",
defaultValues: { password: "" },
});

const {
register,
handleSubmit,
formState: { errors, isValid },
} = useForm<{ secretKey: string; password: string }>({
mode: "onBlur",
defaultValues: { password: "" },
});
} = form;

const onSubmit = async ({
secretKey: rawSecretKey,
Expand All @@ -51,7 +47,7 @@ export const RestoreSecretKey = ({ goToStep }: { goToStep: (step: OnboardingStep
const message = error.message || "";

// if the password doesn't match taquito throws this error
if (message.includes("Cannot read properties of null (reading 'slice')")) {
if (message.includes("Cannot read properties of null")) {
throw new Error("Key-password pair is invalid");
}

Expand All @@ -68,44 +64,43 @@ export const RestoreSecretKey = ({ goToStep }: { goToStep: (step: OnboardingStep
icon={<KeyIcon width="24px" height="24px" stroke={colors.gray[450]} />}
title="Insert Secret Key"
>
<form onSubmit={handleSubmit(onSubmit)} style={{ width: "100%" }}>
<FormControl isInvalid={!!errors.secretKey}>
<FormLabel>Secret Key</FormLabel>
<Textarea
minHeight="130px"
data-testid="secret-key"
{...register("secretKey", {
required: "Secret key is required",
// taken from https://github.com/ecadlabs/taquito/blob/master/packages/taquito-signer/src/taquito-signer.ts#L95
onChange: event =>
setIsEncrypted(isEncryptedSecretKeyPrefix(event.target.value.trim())),
})}
placeholder="Your secret key"
/>
{errors.secretKey && <FormErrorMessage>{errors.secretKey.message}</FormErrorMessage>}
</FormControl>

{isEncrypted && (
<FormControl marginTop="20px" isInvalid={!!errors.password}>
<FormLabel>Password</FormLabel>
<Input
data-testid="password"
{...register("password", {
validate: value => {
if (!value.trim()) {
return "Password is required";
}
},
<FormProvider {...form}>
<form onSubmit={handleSubmit(onSubmit)} style={{ width: "100%" }}>
<FormControl isInvalid={!!errors.secretKey}>
<FormLabel>Secret Key</FormLabel>
<Textarea
minHeight="130px"
data-testid="secret-key"
{...register("secretKey", {
required: "Secret key is required",
// taken from https://github.com/ecadlabs/taquito/blob/master/packages/taquito-signer/src/taquito-signer.ts#L95
onChange: event =>
setIsEncrypted(isEncryptedSecretKeyPrefix(event.target.value.trim())),
})}
placeholder="Your secret key"
/>
{errors.password && <FormErrorMessage>{errors.password.message}</FormErrorMessage>}
{errors.secretKey && <FormErrorMessage>{errors.secretKey.message}</FormErrorMessage>}
</FormControl>
)}

<Button width="100%" marginTop="32px" isDisabled={!isValid} size="lg" type="submit">
Continue
</Button>
</form>
{isEncrypted && (
<FormControl marginTop="20px" isInvalid={!!errors.password}>
<PasswordInput data-testid="password" inputName="password" minLength={0} />
{errors.password && <FormErrorMessage>{errors.password.message}</FormErrorMessage>}
</FormControl>
)}

<Button
width="100%"
marginTop="32px"
data-testid="restore-continue-button"
isDisabled={!isValid}
size="lg"
type="submit"
>
Continue
</Button>
</form>
</FormProvider>
</ModalContentWrapper>
);
};
14 changes: 10 additions & 4 deletions src/components/PasswordInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type PasswordInputProps<T extends FieldValues, U extends Path<T>> = {
label?: string;
placeholder?: string;
required?: string | boolean;
minLength?: RegisterOptions<T, U>["minLength"];
validate?: RegisterOptions<T, U>["validate"];
} & InputProps;

Expand All @@ -29,11 +30,13 @@ export const PasswordInput = <T extends FieldValues, U extends Path<T>>({
label = "Password",
placeholder = "Enter your password",
required = "Password is required",
minLength = MIN_LENGTH,
validate,
...rest
}: PasswordInputProps<T, U>) => {
const { register } = useFormContext<T>();
const [showPassword, setShowPassword] = useState<boolean>(false);

return (
<>
<FormLabel>{label}</FormLabel>
Expand All @@ -45,10 +48,13 @@ export const PasswordInput = <T extends FieldValues, U extends Path<T>>({
type={showPassword ? "text" : "password"}
{...register(inputName, {
required,
minLength: {
value: required ? MIN_LENGTH : 0,
message: `Your password must be at least ${MIN_LENGTH} characters long`,
},
minLength:
minLength && required
? {
value: minLength,
message: `Your password must be at least ${minLength} characters long`,
}
: undefined,
validate,
})}
{...rest}
Expand Down

0 comments on commit 9baa572

Please sign in to comment.