auth-js icon indicating copy to clipboard operation
auth-js copied to clipboard

email_change_current and email_change_new do not work as expected in supabase-js gotrue library.

Open ndejoma opened this issue 2 years ago • 0 comments

Bug report

Describe the bug

Check this comment I created here on the gotrue pull 560 I have highlighted the issue I bumped into while using supabse-js to generate email_change_newandemal_change_current`links.

Hello folks is this change supported in the Supbase client libraries:

I am using Supabase in a project I am working on, I am getting weird errors when I try to generate the link using this API route what could be the problem?

import supabaseServer from '../../lib/supabaseServer';

const handler = async (req, res) => {
	const resData = await supabaseServer.auth.api.generateLink(
		'email_change_current',
		'[email protected]'
	);
	console.log(resData);
	return res.status(200).send({
		message: 'It was successful'
	});
};

export default handler;

When I hit the above API route I get the following errors based on the email provided, both registered(current) and unregisted(new_email).

  • When I pass the second argument to the generateLink function as my new email, I get the following error
  {
    "code": 404,
    "msg": "User not found"
  }
  • When I pass the second argument to the generateLink function as my current email: I get the following error
{
 "code": 422,
 "msg": "The new email address provided is invalid"
}

Seeing the above errors made me look at the node_modules/@supabase/gotrue-js/src/lib/GoTrueApi.ts and found the generateLink method which does not provide a way to provide the new_email as an argument or an option. Which is the cause of the two weird errors seen above.

async generateLink(
    type:
      | 'signup'
      | 'magiclink'
      | 'recovery'
      | 'invite'
      | 'email_change_current'
      | 'email_change_new',
    email: string,
    options: {
      password?: string
      data?: object
      redirectTo?: string
    } = {}
  ): Promise<{ data: Session | User | null; error: ApiError | null }> {
    try {
      const data: any = await post(
        this.fetch,
        `${this.url}/admin/generate_link`,
        {
          type,
          email,
          password: options.password,
          data: options.data,
          redirect_to: options.redirectTo,
        },
        { headers: this.headers }
      )
      return { data, error: null }
    } catch (e) {
      return { data: null, error: e as ApiError }
    }
  }

Having the above I tested the following code on the same API route and it worked seamlessly. Take note the example given above in the What is new behavior cURL example is incomplete as it does not provide an apikey in the header for the request to work successfully. Below is the same using Axios library,

import axios from 'axios';

//the request options
const  options = {
  method: 'POST',
  url: 'https://<project>.supabase.co/auth/v1/admin/generate_link',
  headers: {
    apikey: '<service_role_key_goes_here>',
    Authorization: 'Bearer <service_role_key_goes_here>',
  },
  data: {
    type: 'email_change_new', //or 'email_change_current' for the second link to be returned
    new_email: '[email protected]',
    email: '[email protected]'
  }
};

axios.request(options).then(function (response) {
  console.log(response.data);
}).catch(function (error) {
  console.error(error);
});

I think the major problem is with the @supabase-js library which does not provide the mechanism to provide the second email. If the above info is not clear please let me know. Thanks in advance.

To Reproduce

I have highlighted all the steps in that comment.

ndejoma avatar Sep 05 '22 08:09 ndejoma