pow-auth / pow_assent

Multi-provider authentication for your Pow enabled app
https://powauth.com
MIT License
321 stars 50 forks source link

Flow for connecting provider with existing user when not signed in #115

Open danschultzer opened 4 years ago

danschultzer commented 4 years ago

Found this interesting, this is how CBS handles the exact flow (connect w/ email, then try and connect w/ an account w/ that email)

image

ie

1) Require a password; don't let them chose a new email 2) Upon entering the password, your accounts are linked so you can log in either way.

_Originally posted by @coladarci in https://github.com/pow-auth/pow_assent/issues/113#issuecomment-565142847_

danschultzer commented 4 years ago

This makes a lot of sense. I’ll see if it’s possible with Pow. It ties in with the custom with flow planned with https://github.com/danschultzer/pow/issues/6

danschultzer commented 4 years ago

Related: https://github.com/pow-auth/pow_assent/issues/18

sveredyuk commented 4 years ago

Hi, @danhunsaker. I have a combination of all user issues. I am using Pow and PowAssent for API-bases authentication with my frontend client.

  1. Users registered with email/password can not register via OAuth (I am using Google and GitHub)
  2. Only new users can register with OAuth
  3. Users registered with Google can't log in with Github even if the same email been used.

Do you need any help with issues to resolve this blocker?

danschultzer commented 4 years ago

Hi @sveredyuk sorry I missed this comment.

So this issue would only resolve how the flow works on web rather than API, though it may make it easier to work with the plug methods.

To make this work I'll have to figure out the users current available auth methods. In your case, if the user has previously used Google and there's now a conflict on user id (email) trying to auth with Github, it should probably present the above dialog with an "Sign in with Google" method.

I also think in many cases it makes sense to bypass this if the email from the provider has been verified, though I don't want this to be enabled by default (email isn't a secure channel). I would like to update the docs on how you can sign in the user automatically if the verified email exists in the system already. This would apply to custom controllers as well (so can work in API).

Currently when there's a constraint error on the user id field, it's treated the same way as if the user id was invalid or missing, and you have to enter a new one. So you can listen for the :invalid_user_id_field error after calling PowAssent.Plug.callback_upsert/4 and then look up and upsert.

Alternatively you can bypass all this by having a custom user identities context with a create_user method where you look up the user first based on the user params.

caspg commented 2 years ago

@danschultzer Is there any plan for how to solve this challenge? Maybe there is some example for that?

Thanks for this library 👍 👍

EDIT:

I'm playing with custom user identities context. I've added create_user method as suggested that look up the user first and then creates user_identitity using upsert. Does it look ok?

def create_user(user_identity_params, user_params, user_id_params) do
    case VelomapEx.Users.get_by(%{email: email}) do
      nil ->
        pow_assent_create_user(user_identity_params, user_params, user_id_params)

      user ->
        case pow_assent_upsert(user, user_identity_params) do
          {:ok, _} -> {:ok, user}
          err -> err
        end
    end
  end