Creating a Reddit Clone Using React and GraphQL - 12

rasikag

Rasika Gayan Gunarathna

Posted on March 16, 2021

Creating a Reddit Clone Using React and GraphQL - 12

This blog post originally posted on my blog site and you can find it here.

As I said in an earlier post we have to manage 2 scenarios here.

  1. Refresh the cache for forgot password
  2. Error handle for token errors.

Add below code lines to handle the token errors. We are using states here.

const [tokenError, setTokenError] = useState("");
Enter fullscreen mode Exit fullscreen mode

Then we are adding the below code to check that token error exist. If so we are. adding it to state.

// take out toErrorMap first
const errorMap = toErrorMap(response.data.changePassword.errors);
if ("token" in errorMap) {
  // this is because we defined filed as token in user.ts in backend
  setTokenError(errorMap.token);
}
Enter fullscreen mode Exit fullscreen mode

Let’s display this error.

{
  tokenError ? <Box color="red">{tokenError}</Box> : null;
}
Enter fullscreen mode Exit fullscreen mode

Add this moment if you try, you will get 404 error. The issue in here, that we didn't wrap this with withUrqlClient. Let’s cover the component with it.

export default withUrqlClient(createUrqlClient)(ChangePassword);
Enter fullscreen mode Exit fullscreen mode

Now, we need to delete the token from the back-end once we use this token. Let’s do that next.

// in resolvers/user.ts file
// first get the key out
const key = FORGET_PASSWORD_PREFIX + token;
const userId = await redis.get(key);
// then delete the key
await redis.del(key);
req.session.userId = user.id;
Enter fullscreen mode Exit fullscreen mode

Now if you try to use the token 2nd time to change the password, you will get the token expired error. Cool. All working fine now.

Okay, now we only left here, if the token expired your need to get a new token. Let’s add that. First, we are adding a link to get a new token page.

// update code to below code block in [token].tsx file.
{
  tokenError ? (
    <Box>
      <Box color="red">{tokenError}</Box>
      <NextLink href="/forgot-password">
        <Link>Click here to get a new token.</Link>
      </NextLink>
    </Box>
  ) : null;
}
Enter fullscreen mode Exit fullscreen mode

Once you click on the link it will bring you to forgot-password page. Let’s quickly add that page.

import React from "react";
const ForgotPassword: React.FC<{}> = ({}) => {
  return <div>Forgot Password</div>;
};
export default ForgotPassword;
Enter fullscreen mode Exit fullscreen mode

This also needs to add to Login page.

// under to inputfield add this code
<Flex mt={2}>
  <NextLink href="/forgot-password">
    <Link ml="auto">forgot password?</Link>
  </NextLink>
</Flex>
Enter fullscreen mode Exit fullscreen mode

As the last for this forgot-passward page, we need the user to insert an email address. Let’s copy from from Login page and add it here. Also, we need to create a mutation for forgot-password.This will only return a boolean value.

mutation ForgotPassword($email: String!) {
  forgotPassword(email: $email)
}

Enter fullscreen mode Exit fullscreen mode

In forgot-password.tsx page, we use state to set a success message.

const [complete, setComplete] = userState(false);
Enter fullscreen mode Exit fullscreen mode

Here is the full code for forgot-password.tsx file.

const [complete, setComplete] = userState(false);
const [, forgotPassword] = useForgotPasswordMutation();
return (
  <Wrapper variant="small">
    <Formik
      initialValues={{ email: "" }}
      onSubmit={async (values) => {
        await forgotPassword(values);
        setComplete(true);
      }}
    >
      {({ isSubmitting }) =>
        complete ? (
          <Box>we sent a password reset link to your email. Please check.</Box>
        ) : (
          <Form>
            <InputField
              name="email"
              placeholder="email"
              label="Email"
              type="email"
            />

            <Button
              isLoading={isSubmitting}
              mt={4}
              type="submit"
              colorScheme="teal"
            >
              Forgot Password
            </Button>
          </Form>
        )
      }
    </Formik>
  </Wrapper>
);
Enter fullscreen mode Exit fullscreen mode

At this point, we have done almost everything with user management and authentication tasks of this application. From the next blog post, let’s work on adding posts to the Reddit clone.


Thanks for reading this. If you have anything to ask regarding this please leave a comment here. Also, I wrote this according to my understanding. So if any point is wrong, don’t hesitate to correct me. I really appreciate you.
That’s for today friends. See you soon. Thank you.

References:

This article series based on the Ben Award - Fullstack React GraphQL TypeScript Tutorial. This is an amazing tutorial and I highly recommend you to check that out.

Main image credit

💖 💪 🙅 🚩
rasikag
Rasika Gayan Gunarathna

Posted on March 16, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related