Disable auto-login after password reset using clerk

138 Views Asked by At

I want to implement a "forgot password" page in my Next.js project using Clerk. I am following Clerk's official documentation for this feature. However, I am encountering an issue where, upon successfully resetting the password, the user is automatically logged in. How can I prevent this behavior? Below is the code for my "forgot password" page, which is based on Clerk's docs

import React, { SyntheticEvent, useState } from 'react';
import { useSignIn } from '@clerk/nextjs';
import type { NextPage } from 'next';
 
const SignInPage: NextPage = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [code, setCode] = useState('');
  const [successfulCreation, setSuccessfulCreation] = useState(false);
  const [complete, setComplete] = useState(false);
  const [secondFactor, setSecondFactor] = useState(false);
 
  const { isLoaded, signIn, setActive } = useSignIn();
 
  if (!isLoaded) {
    return null;
  }
 
  async function create(e: SyntheticEvent) {
    e.preventDefault();
    await signIn
      ?.create({
        strategy: 'reset_password_email_code',
        identifier: email,
      })
      .then(_ => {
        setSuccessfulCreation(true);
      })
      .catch(err => console.error('error', err.errors[0].longMessage));
  }
 
  async function reset(e: SyntheticEvent) {
    e.preventDefault();
    await signIn
      ?.attemptFirstFactor({
        strategy: 'reset_password_email_code',
        code,
        password,
      })
      .then(result => {
        if (result.status === 'needs_second_factor') {
          setSecondFactor(true);
        } else if (result.status === 'complete') {
          setActive({ session: result.createdSessionId });
          setComplete(true);
        } else {
          console.log(result);
        }
      })
      .catch(err => console.error('error', err.errors[0].longMessage));
  }
 
  return (
    <div
      style={{
        margin: 'auto',
        maxWidth: '500px',
      }}
    >
      <h1>Forgot Password ?</h1>
      <form
        style={{
          display: 'flex',
          flexDirection: 'column',
          gap: '1em',
        }}
        onSubmit={!successfulCreation ? create : reset}
      >
        {!successfulCreation && !complete && (
          <>
            <label htmlFor='email'>Please provide identifier</label>
            <input
              type='email'
              placeholder='e.g [email protected]'
              value={email}
              onChange={e => setEmail(e.target.value)}
            />
 
            <button>Sign in</button>
          </>
        )}
 
        {successfulCreation && !complete && (
          <>
            <label htmlFor='password'>New password</label>
            <input
              type='password'
              value={password}
              onChange={e => setPassword(e.target.value)}
            />
 
            <label htmlFor='password'>Reset password code</label>
            <input
              type='text'
              value={code}
              onChange={e => setCode(e.target.value)}
            />
 
            <button>Reset</button>
          </>
        )}
 
        {complete && 'You successfully changed you password'}
        {secondFactor && '2FA is required, this UI does not handle that'}
      </form>
    </div>
  );
};
 
export default SignInPage;
1

There are 1 best solutions below

0
On

I would just remove the part of login logic in your reset function this exact part

setActive({ session: result.createdSessionId });
setComplete(true);

instead show a toast then redirect the user or just show success message.