Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why emailVerified is forced to null on user creation ? #7218

Closed
super-ienien opened this issue Apr 11, 2023 · 8 comments
Closed

Why emailVerified is forced to null on user creation ? #7218

super-ienien opened this issue Apr 11, 2023 · 8 comments
Labels
question Ask how to do something or how something works

Comments

@super-ienien
Copy link

Question 💬

Hi,

I would like to know if it is possible to not force emailVerified to null on user creation ?

In my case I wan't to trust some providers on their email verification. For that I wan't the emailVerified attribute on the profile object from the provider to be preserved when the user is created for the fisrt time. But in this file : core/src/lib/callback-handler.ts. We see that at the line 213, the emailVerified property is overrriden with null.

Maybe this is done for security reasons ?

Thanks a lot.

How to reproduce ☕️

nothing to reproduce

Contributing 🙌🏽

Yes, I am willing to help answer this question in a PR

@super-ienien super-ienien added the question Ask how to do something or how something works label Apr 11, 2023
@balazsorban44
Copy link
Member

balazsorban44 commented Apr 13, 2023

We do not know upfront if your provider can be trusted, so it's set to null by default. You can update it afterward though, the easiest way to do this is via the built-in Email provider, which will mark the user's email as verified.

I believe this is common practice. Whenever you sign up to any website, they don't mark your email verified by default either.

@aw1875
Copy link

aw1875 commented Jun 20, 2023

This is a little confusing to me. I understand that the provider can't automatically be trusted but I feel like it would make a lot more sense to allow us to overwrite the default functionality fairly simply.

const { id: _, ...newUser } = { ...profile, emailVerified: null }

Could very easily reverse the order of the object so if we wanted to manually set the emailVerified value in the callback we could do so:

 const { id: _, ...newUser } = { emailVerified: null, ...profile  } 

For example, a provider like the GoogleProvider:

In the profile callback, we can see that Google does let us know if the email is verified:

{
  ...
  email: '...',
  email_verified: true,
  ...
}

And then in my GoogleProvider:

GoogleProvider({
  clientId: ...,
  clientSecret: ...,
  profile: (profile, tokens) => {
    ...

    return {
      ...
      email: profile.email,
      emailVerified: profile.email_verified,
      ...
    };
  }
}),

I may be thinking about this completely wrong but I feel l like that would be a suitable approach.


You can update it afterward though, the easiest way to do this is via the built-in Email provider, which will mark the user's email as verified.

You also mention this approach which seems interesting but also a little odd. I can't think of any time that I've used OAuth to sign into an application where I needed to then verify my email afterwards externally. I'd love to hear your approach to that though if possible as like I said, I may be thinking about this all wrong.

Thanks!

@FahimFaisalKhan
Copy link

Any update on this ?

@octavian-regatun
Copy link

Any updates?

@aw1875
Copy link

aw1875 commented Jan 18, 2024

@FahimFaisalKhan @octavian-regatun You should actually be able to handle this logic in the LinkAccount Event now which is pretty great. I currently do something like this in my project:

  events: {
    linkAccount: async ({ user }) => {
      // Update user
      await prisma.user.update({
        where: { id: user.id },
        data: {
          emailVerified: new Date(), // or if emailVerified is a boolean then true
          ... anything else you want to update
        }
      });

      return;
    }
  },

This seems to work great for my use cases

@mdtausifiqbal
Copy link

Same Issue here, any updates? I am using GoogleProvider and CredentialsProvider.

@guydumais
Copy link

guydumais commented Jun 24, 2024

Good catch @aw1875!

And thanks a lot, I've been looking for this one for a while.

@FahimFaisalKhan @octavian-regatun You should actually be able to handle this logic in the LinkAccount Event now which is pretty great. I currently do something like this in my project:

  events: {
    linkAccount: async ({ user }) => {
      // Update user
      await prisma.user.update({
        where: { id: user.id },
        data: {
          emailVerified: new Date(), // or if emailVerified is a boolean then true
          ... anything else you want to update
        }
      });

      return;
    }
  },

This seems to work great for my use cases

And I fully agree with you here, this would be more useful and can easily be fixed by reversing the order:

This is a little confusing to me. I understand that the provider can't automatically be trusted but I feel like it would make a lot more sense to allow us to overwrite the default functionality fairly simply.

const { id: _, ...newUser } = { ...profile, emailVerified: null }

Could very easily reverse the order of the object so if we wanted to manually set the emailVerified value in the callback we could do so:

 const { id: _, ...newUser } = { emailVerified: null, ...profile  } 

For example, a provider like the GoogleProvider:

In the profile callback, we can see that Google does let us know if the email is verified:

{
  ...
  email: '...',
  email_verified: true,
  ...
}

And then in my GoogleProvider:

GoogleProvider({
  clientId: ...,
  clientSecret: ...,
  profile: (profile, tokens) => {
    ...

    return {
      ...
      email: profile.email,
      emailVerified: profile.email_verified,
      ...
    };
  }
}),

I may be thinking about this completely wrong but I feel l like that would be a suitable approach.

You can update it afterward though, the easiest way to do this is via the built-in Email provider, which will mark the user's email as verified.

You also mention this approach which seems interesting but also a little odd. I can't think of any time that I've used OAuth to sign into an application where I needed to then verify my email afterwards externally. I'd love to hear your approach to that though if possible as like I said, I may be thinking about this all wrong.

Thanks!

But in the GoogleProvider profile I did it this way instead:

return {
      ...
      email: profile.email,
      emailVerified: profile.email_verified ? new Date() : null,
      ...
    };

@MohammedAslam106
Copy link

### If you are using Drizzle you can follow this setup, I wanted to update this field for OAuth sign-in providers as those emails are already verified by the big companies like Google and Git Hub.

events:{
    linkAccount:async({user,account,profile})=>{
        const partialUser:Partial<AdapterUser> & Pick<AdapterUser, "id">={
            id:user.id as string,
            emailVerified: new Date()
        }
        if (adapter && adapter.updateUser) {
            await adapter.updateUser(partialUser);
        } else {
            console.error("Adapter or updateUser function is undefined");
        }
        return
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Ask how to do something or how something works
Projects
None yet
Development

No branches or pull requests

8 participants