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

[Bug]: Custom OAuth Providers Do Not Properly Determine If a User's Email isVerified #954

Open
ITenthusiasm opened this issue Oct 19, 2024 · 1 comment

Comments

@ITenthusiasm
Copy link
Contributor

ITenthusiasm commented Oct 19, 2024

TL;DR

The isVerified property derived from fromUserInfoAPI is always unconditionally overridden by fromIdTokenPayload.

Background

The userInfoMap config for a Custom Provider is always given default values for the fromIdTokenPayload and fromUserInfoAPI objects. Because the developer's input values are always spread into these default objects, it's impossible to remove the default values by passing undefined or {} to fromIdTokenPayload or fromUserInfoAPI. And, of course, it's impossible to remove these defaults by excluding those properties from the Custom Provider's config. (Technically, a developer could to pass { [key: string]: undefined | null } to override the defaults. But this is unintuitive, so it's unlikely that any developer would ever do this naturally.)

Because fromIdTokenPayload and fromUserInfoAPI are always given default values, the two checks that try to derive the isVerified value will always run. This, in turn, means that fromUserInfoAPI.emailVerified's value will always be overridden by fromIdTokenPayload.isVerified. This produces a confusing/buggy DX. (Yes, developers can technically circumvent this problem as I mentioned earlier. But the only way they would know how to do that is by scrutinizing the source code. So the workaround I mentioned is not valid/practical for users.)

It seems that we might need to put some logic in place to prevent this issue from happening. Ideally, if a user only supplies a fromUserInfoAPI object, then that should be the sole source of truth for deriving user information. Or, if a user only supplies a fromIdTokenPayload object, then that should be the sole source of truth.

Potential Solutions

Here are some non-exhaustive ideas about how to solve this problem:

  1. Keep the default values, and write documentation to bring clarity to developers. The existing OAuth Documentation would need to be updated to tell developers to pass { [key: string]: undefined | null } to whichever userInfoMap config they don't want to use. Admittedly, this produces an undesirable developer experience, and it also leaks the implementation details of supertokens-node.

  2. Remove the default values, and write documentation to show devs good default values. In this case, the documentation's Node.js code block would stay the same. (The code block would not need to supply an object of undefineds to fromIdTokenPayload, as would be required if the first solution was pursued.) And the page's documentation would be updated to suggest good default values for fromIdTokenPayload and/or fromUserInfoAPI. This would likely be a (small) breaking change; but it would produce a more intuitive developer experience and save supertokens-node from having to change its logic.

  3. Tinker with the conditional statements. Currently, the userId and email checks do not perform variable assignment if undefined is returned from the object property lookup (i.e., accessField). Perhaps something similar could be done for isVerified? However, it's worth noting that relying on this logic could end badly if a Custom Provider does somehow provide a value for these properties that the developer does not want to use.

  4. Provide a way for developers to cancel the default values. This could be something like excludeDefaultsForUserInfoMap: true. However, this would bloat the Custom Provider config's options more, and it still might be something that leaks implementation details.

I'm sure there are other valid solutions as well. But this is probably a concern worth addressing in some way or another to prevent developers from experiencing unexpected behavior.

ITenthusiasm added a commit to ITenthusiasm/remix-supertokens that referenced this issue Oct 19, 2024
There are some minor oddities that come with setting up a Custom
OAuth Provider. See supertokens/supertokens-node#954 for the details.
@ITenthusiasm
Copy link
Contributor Author

Another option is to only provide the default values if the developer expressed interest in using a given config. Something like:

if ("fromIdTokenPayload" in input.config.userInfoMap) {
  // ... Combine default values with developer's values
}

// Do the same for `fromUserInfoAPI`

However, if this approach is chosen, it would probably still be best to inform developers of the default values used for these config objects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant