BounceTribe / bouncetribe

The bounce tribe repository!
https://www.test.bouncetribe.com/
3 stars 2 forks source link

Authflow and adding password to accounts created with facebook #26

Open JakeIwen opened 6 years ago

JakeIwen commented 6 years ago

In the graphQL DB, BT users who signed up with an email address have field auth0UserId='auth0|17dc6865cd47dc65dc4dsc534 and those who signed up with facebook have something like auth0UserId=facebook|879066578568512

first of all I am curious about the design intent of not storing the auth0 ID at all for facebook users.

In order to add a separate password, allowing FB users to login with their email, the auth0 ID is required. I was able to manually add a password to my BT-facebook account, but when I log in using my email and newly created password, I end up getting kicked out with this message, despite the the auth0 logs showing a successful login attempt:

image

This error is meant to occur on the SIGN-IN part of the lock screen, when a user tries to sign up with an existing BT email address. It obviously doesn't make sense to receive this error after pressing the LOGIN button. The console also shows an attempt to create a new user.

This error and the attempt to create an account stem from a rejected signIn mutation (towards the bottom). Can you help identify what the issue is, and how to allow our signIn mutation to work properly in this scenario?

A general explanation of this authFlow would be appreciated as well.

  authFlow = (result) => {
    console.log('authflow result', result);
    let { exp, email, sub }             = result.idTokenPayload
    let { idToken, accessToken, state } = result

    if (!email) {

    } else if (state !== 'default') {
      let primaryAuth0UserId = state
      let primaryToken = localStorage.getItem('idToken')
      let secondaryToken = result.idToken
      connectAuth0Accounts({
        primaryAuth0UserId,
        primaryToken,
        secondaryToken
      }).then(result=>{
        accessToken = localStorage.getItem('accessToken')
        this.signinUser({
          idToken: primaryToken,
          accessToken,
          email,
          exp
        }).then(
          userId => {
            this.getUserInfo(accessToken).then(profile=>{
              profile = {
                ...profile,
                userId: sub
              }
              this.updateUser(userId, profile)
            })
          },
          rejected => rejected
        )
      })
    } else {
      this.signinUser({
        idToken,
        accessToken,
        email,
        exp
      }).then(
        userId => userId,
        rejected => {
          generateHandle(email).then(
            handle => {
              this.createUser({
                idToken,
                email,
                handle,
                exp,
                accessToken
              }).then(
                userId => {
                  this.getUserInfo(accessToken).then(profile=>{
                    console.log('profile', profile)
                    this.updateUser(userId, profile)
                  })
                },
                rejected => {
                  console.log('Sorry a user already exists with that email', rejected)
                  window.alert('Sorry a user already exists with that email. You may already have an account. Try logging in again using your original credentials.')
                }
              )
            }
          )
        }
      )
    }
  }
import Relay from 'react-relay'

export default class SigninUserMutation extends Relay.Mutation {

  getVariables() {
    return {
      auth0: {
        idToken: this.props.idToken,
      },
    }
  }

  getMutation() {
    return Relay.QL`mutation {signinUser}`
  }

  getFatQuery() {
    return Relay.QL`fragment on SigninPayload {
      token
      viewer { user }
      user
    }`
  }

  getConfigs() {
    return [
      {
        type: 'FIELDS_CHANGE',
        fieldIDs: {
          viewer: "viewer-fixed"
         },
      },
      {
        type: 'REQUIRED_CHILDREN',
        children: [
          Relay.QL`
            fragment on SigninPayload {
              token
              viewer {
                user {
                  id
                  handle
                  friends (first: 1) {
                    edges {
                      node { handle }
                    }
                  }
                }
                id
              }
              user {
                id
                handle
              }
            }
          `,
        ],
      },
    ]
  }
}
JakeIwen commented 6 years ago

note for talking about this at meeting: would also like potential instruction on how to use logic in GraphQL data migration for new User field auth0FBId.

How can I do this with ALL users in the database:

if (user.auth0UserId.includes('facebook')) {
  user.auth0FBId = user.auth0UserId
}
carlpeaslee commented 6 years ago

So re: the data stored in auth0UserId, I believe that that is all done by Graphql and we don't get a say in it. I believe to remedy this, I made another field that holds facebookId if we don't have it?

Re: the error. You've come across some of the major troubles in authentication. I think you should call me today and I can explain it to you. At the heart of the problem is this: Graph.Cool and Auth0, at the time these files were created, did not automatically reconcile or combine accounts that had the same email address and were essentially duplicates –– but they also handled them differently.

carlpeaslee commented 6 years ago

Also re: data migration, I'm afraid I've never done a data migration with GraphQL so I'm not sure that I could be of much help.

JakeIwen commented 6 years ago

No problem about the migration' I'll figure it out.

Maybe we can chat at today's meeting via skype about the auth issues. A walkthruough of the authFlow would be cool, but maybe it would be more beneficial to add comments instead/first.