Handle AppMember.email conflicts and make user connection optional
Description
Problems
Our login flows for apps have 2 problems currently.
-
Login to an app can result in conflicts due to the fact that apps often have more than 1 login flow.
-
Login flows using external providers result in Appsemble users without email or password (anonymous users).
2.1. TheUser.primaryEmail
is not unique.
Solutions
- Login to an app can result in conflicts due to the fact that apps often have more than 1 login flow.
We can handle the conflicts in the following way (based on https://auth0.com/docs/manage-users/user-accounts/user-account-linking#scenarios).
Scenario | Conflict (on new connection) | Created from (connections are tracked via our Authorization tables) | Has User record |
Solution (linking to the existing app member to resolve conflict for good) |
---|---|---|---|---|
Appsemble OAuth2 login 1 |
AppMember.email conflict |
external provider | No | Suggest login to selected external provider(s), filtered with AppMember.email
|
Appsemble OAuth2 login 2 |
AppMember.email conflict |
password login, or user.invite / user.create actions |
No | Suggest password login |
External OAuth2 login 1 |
AppMember.email conflict |
studio | Yes | Suggest login to Appsemble with matching User.primaryEmail
|
External OAuth2 login 2 |
AppMember.email conflict |
external provider | No | Suggest login to selected external provider(s), filtered with AppMember.email
|
External OAuth2.0 login 3 |
AppMember.email conflict |
password login, or user.invite / user.create actions |
No | Suggest password login |
External SAML2.0 login 1 |
AppMember.email conflict |
studio | Yes | Suggest login to Appsemble with matching User.primaryEmail
|
External SAML2.0 login 2 |
AppMember.email conflict |
external provider | No | Suggest login to selected external provider(s), filtered with AppMember.email
|
External SAML2.0 login 3 |
AppMember.email conflict |
password login, or user.invite / user.create actions |
No | Suggest password login |
External SCIM account provisioning | ??? | (Uses our SAML2.0 flow) | No | handled by returning 409, based on the RFC |
App password login 1 |
AppMember.email conflict |
studio | Yes | Suggest login to Appsemble with matching User.primaryEmail
|
App password login 2 |
AppMember.email conflict |
external provider | No | Suggest login to selected external provider(s), filtered with AppMember.email
|
App invite 1 (see #1520) |
AppMember.email conflict |
studio | Yes | Suggest login to Appsemble with matching User.primaryEmail
|
App invite 2 (see #1520) |
AppMember.email conflict |
external provider | No | Suggest login to selected external provider(s), filtered with AppMember.email
|
App invite 3 (see #1520) |
AppMember.email conflict |
password login, or user.invite / user.create actions |
No | Suggest password login |
user.create action 1 |
AppMember.email conflict |
User.primaryEmail |
||
user.create action 2 |
AppMember.email conflict |
selected external provider(s), filtered with AppMember.email |
||
user.create action 3 |
AppMember.email conflict |
user.invite / user.create actions |
||
user.register action |
AppMember.email conflict |
studio | Yes | Suggest login to Appsemble with matching User.primaryEmail
|
user.register action |
AppMember.email conflict |
external provider | No | Suggest login to selected external provider(s), filtered with AppMember.email
|
user.register action |
AppMember.email conflict |
password login, or user.invite / user.create actions |
No | Show "account already exists" and suggest reset-password |
Appsemble demo login | N.A. -> anyone is able to login | N.A. | N.A. | N.A. |
Multiple connections |
AppMember.email conflict |
* | * | Suggest all login flow options from connections available through Authorizations |
- Login flows using external providers result in Appsemble users without email or password (anonymous users).
2.1. TheUser.primaryEmail
is not unique.
We can make the connection to a User
via AppMember.UserId
optional, and make the User.primaryEmail
column unique, however this will result in further potential conflicts when changing User.primaryEmail
.
Requirements
-
App member should not require an Appsemble user to be present. -
Users must be informed that an account already exists, and asked whether they want to connect them. -
The server must always prompt the user for authentication before connecting accounts. -
The documentation should explain the app member concept (including refs to related docs) and the login flow conflict resolution scheme (update https://appsemble.app/en/docs/03-guide/oauth2#login-flow, https://appsemble.app/en/docs/03-guide/saml#login-flow).
-
Update related tests and cover new changes -
Must include E2E tests covering all scenarios using mocks
-
Write migrations that remove all "anonymized" users (and duplicate if any -> check with prod) -
Test migrations against anonymized data of prod
-
Verify all login flows still work as expected: -
Verify with SCIM validator -
Verify app OAuth2 flow with external provider -
Verify app SAML2.0 flow with external provider -
Verify Appsemble app OAuth2 flow -
Verify Appsemble app password flow -
Verify Appsemble app invite flow -
Verify Appsemble demo app login flow -
Verify user.create action -
Verify user.register action
-
-
Should close #1180 (closed) -
Should close #1308 (closed) -
Should close #1253 (closed)
The following discussion from !3551 (merged) should be addressed:
-
@Ekhorn started a discussion: Not needed to resolve now, but it should be at some point.