Unlock your account with NextJs Supabase Email verification token for resetting your password

I'm currently utilizing NextJs and Supabase to handle the process of resetting a user's password.

Below is the server action in which I invoke the resetPasswordForEmail function to send an email to the client's mailbox:

export const resetPasswordWithEmail = async (email: string) => {
  'use server';

  const foundUser = await getUserByEmail(email);
  if (!foundUser) {
    return {
          error: [
            {
              id: '1',
              message: 'This email does not exist in our database',
            },
          ],
        };
  }

  const { error} = await supabaseClient.auth.resetPasswordForEmail(email);
  if (error) {
    return {
      error: [
        {
          id: '1',
          message: error.message,
        },
      ],
    };
  }
  return {
    success: 'An email has been successfully sent to your mailbox'
  };
}

This is the email template provided by Supabase:

<a href="{{.ConfirmationURL}}/api/auth/callback?next=/auth/reset-password" style="display: inline-block; padding: 10px 20px; background-color: #FDAC04; color: #000000; text-decoration: none; border-radius: 5px;">Click here to reset your password</a>

The resent link contains the API from my Next.js and Supabase, automatically adding two parameters, 'code' & 'hash_token'. I pass the 'code' parameter to the supabase function supabase.auth.exchangeCodeForSession for validation, redirecting from the API to the reset-password page.

Here is the code snippet:

export async function GET(request: Request) {
  // The `/auth/callback` route is required for the server-side auth flow implemented
  // by the Auth Helpers package. It exchanges an auth code for the user's session.
  // https://supabase.com/docs/guides/auth/auth-helpers/nextjs#managing-sign-in-with-code-exchange
  const requestUrl = new URL(request.url);
  const code = requestUrl.searchParams.get('code');
  const next = requestUrl.searchParams.get('next');

  if (code) {
    const cookieStore = cookies();
    const supabase = createClientServer(cookieStore);
    await supabase.auth.exchangeCodeForSession(code);
  }

  // URL to redirect to after sign in process completes
  if (next) return NextResponse.redirect(next);
  else return NextResponse.redirect(requestUrl.origin);
}

This exchangeCodeForSession function is throwing an error:

Error: 'AuthApiError: invalid request: both auth code and code verifier should be non-empty'

Any insights on this issue?

Answer №1

Dealing with a similar issue, I found myself in a ridiculous situation that I'm willing to share for the benefit of other developers:

While running my application locally on localhost:3000, I encountered an unforeseen redirection to 127.0.0.1:3000 within the email environment. To make matters worse, a code was inexplicably stored in the local browser's storage under the name "auth-token-code-verifier."

It took me two whole days to uncover this seemingly trivial mistake, and my "aha" moment only arrived when I reached the conclusion of a particular webpage: :

"That means the code exchange must be initiated on the same browser and device where the flow was started."

I sincerely hope that sharing this experience can assist others who might find themselves in a similar predicament.

Wishing you all a fantastic day ahead!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for ensuring that the DOM is fully rendered before executing any code

Before proceeding to the next functions, it is necessary to wait for the DOM to finish rendering. The flow or lifecycle of this process is outlined below: Adding an item to the Array: this.someFormArray.push((this.createForm({ name: 'Name& ...

Is it possible to alter the data type of a property in a third-party React component?

I am currently working on a component that is functioning properly, but one of the props is designated as type "string" and I would like to either pass a component or change the data type to "any." Is there a way to accomplish this? For clarification, my ...

How to conceal the side navigation bar on specific pages or components within an Angular application

Currently immersed in developing a web application with Jhipster and Angular. I've managed to set up a side navbar along with a top navbar on every page. However, I'm struggling to hide the side navbar on specific pages and could use some guidanc ...

Unable to iterate over a 2D array using 'rows' in JavaScript or TypeScript

Imagine I need to generate a 2D array with this specific structure: [0, 1, 1, 1] [1, 0, 0, 0] [1, 0, 0, 0] To achieve this, I first initialized a 2D array with 0 values: function createGrid(m: number, n: number): number { let grid: number[][] = new Ar ...

The SideNav SpyOn feature failed to locate the specified method

In the test project I am working on, there is a side navigation menu. I need to create a simple test to verify that when I click the button, the sidenav opens or closes. The AppComponent interacts with the sidebar through its dependency, sidenavbar. it(&a ...

Limiting click event to only Image component in Next.js

Is there a way to trigger a click event only on the image itself, rather than the entire parent div? When setting width and height for the parent div, the click event seems to encompass the entire area. For instance, if the image is 600 pixels wide by 300 ...

Clearing out all records from a Firestore collection

I attempted to implement the following method: deleteMessages(){ this.firestore.collection("MESSAGES") .get() .then(res => {res.forEach(element => {element.ref.delete();}); }); } However, I encountered the following err ...

Using Typescript to create a generic return type that is determined by the type of a property within an object union

Consider the following scenario: type Setting = { key: "option_one", value: number, } | { key: "option_two", value: string, } export type SettingKey = Setting["key"]; // "option_one"|"option_two ...

Tips for adjusting the radio button value similarly to a checkbox in Angular 2 using *ngFor

my checkbox and radio button implementation: <input id="{{k.group_name}}_{{i}}" name="{{k.group_name}}" type="checkbox" class="hide" name="{{k.group_name}}" [value]="m.details" (change)="change($event, m , k.item_ingredient_group_key,false,k.maximum)"& ...

A versatile function that can process any data type without losing its structural details

Is it possible to create a function that accepts any type as an argument while still retaining the original type information of the input? const preserveType = (input: any) => input // using 'any' for flexibility const data = { foo: ' ...

Do ES6 features get transpiled into ES5 when utilized in TypeScript?

After implementing ES6 features such as template strings, arrow functions, and destructuring in a TypeScript file, I compile the code to regular JavaScript... Does the TypeScript compiler also compile the ES6 syntax, or do I need to utilize another compil ...

Utilizing ngModel with an uninitialized object

What is the most effective way to populate an empty instance of a class with values? For example, I have a User Class and need to create a new user. In my component, I initialize an empty User Object "user: User;". The constructor sets some properties, w ...

Is it possible to specify the timing for executing Typescript decorators?

One issue I've encountered is that when I define a parameterized decorator for a method, the decorator runs before the method itself. Ideally, I'd like the decorator to run after the method has been called. function fooDecorator(value: boolean) ...

Is it normal that aws-eventbridge-lambda does not generate a Lambda function?

I've been experimenting with the AWS CDK (Typescript) to enhance my knowledge. I'm interested in setting up a lambda function to run daily at a specific time or at intervals of N minutes. Since I anticipate having multiple functions, it would be ...

Setting up Jest to run in WebStorm for a Vue project with TypeScript can be done through

I am struggling to run all my tests within WebStorm. I set up a project with Babel, TypeScript, and Vue using vue-cli 3.0.0-rc3. My run configuration looks like this: https://i.stack.imgur.com/7H0x3.png Unfortunately, I encountered the following error: ...

Nested validation schema featuring conditional validation - yes, we've got it covered!

In my Formik object, I have set initial values as follows: {customerDetails: {id: "", name: "", mobileNumber: ""}, notes: {id: "", text: "", type: ""}} How can I create a conditional Yup validati ...

Issue Deleting Cookies in Next.js Middleware

I am currently developing a Next.js application that utilizes middleware to verify if a user's token has expired. If the token is no longer valid, my intention is to clear and delete the cookies before redirecting the user to the login page. Below is ...

How to set the default option in a select dropdown using Angular and Types

It's been a while since I last worked with Angular and now I'm tasked with working on an existing system. I introduced an NgModal dialog to send text messages, designed as shown here: https://i.sstatic.net/67U1M.png Below is the code snippet I ...

The term "is" in the output type of a TypeScript function

Within the source code of VSCode, you will find various functions that have a specific return type declaration, such as the following: export function isString(str: any): str is string { if (typeof (str) === _typeof.string || str instanceof String) { ...

Creating a Cordova application from the ground up, evaluating the options of using ngCordova, Ionic framework, and

With the goal of creating a multiplatform Cordova app for Android, iOS, and Windows, I have been exploring different approaches. My plan is to build an application with 4 or 5 features focused on service consumption (listing, adding, and editing items) wh ...