Invite flow error => User already exists { one connection, one application, multiple organisations }

We are using auth0 multi-tenant approach i.e. having multiple organizations where each act as a single tenant, to allow a user to use the same credentials(same email with username-password-connection) to log in to different organizations: Multiple Organization Architecture

Error: Invitation flow breaks when we send an invitation to a user that already exists(user exists in org-1, an invitation sent from org-2). Auth0 says “User already exists” on the signup page. Auth0 should take the user directly to the login screen instead of signup by referring to the details against the invitation code and connection id. Or we should(being consumers) be able to send a flag to the /authorize flow to open the login screen instead of the signup screen. The steps to reproduce this are explained below.

Flow

  1. Send an invitation to test-email@email.com, from ORG-1

  2. test-email@email.com clicks on the invitation link to signup

  3. From our app we call auth0 /authorize endpoint with the invitation code and org information attached, this completes the flow(i.e. user got registered).

  4. Send another invitation to test-email@email.com from ORG-2 this time

  5. test-email@email.com clicks on the invitation link to signup

  6. From our app we call auth0 /authorize endpoint with the invitation code and org information attached. When the user tries to register him/herself the auth0 flow throws an error “User already exists”.

Expected:

  1. Auth0 should match the email against the selected database connection, if email exists open the “log in section” instead of the “signup section”

  2. or the consumer of the /authorize API must be allowed to pass the parameter to default section to “log in”

Did you find a solution to this @dhiraj.saini?

We have the exact same issue. Users receiving an invite who already have an account being taken to the signup flow. I expected Auth0 would have handled this automatically for us.

I came up with a solution that works for us but I’m not 100% sure if this is the best solution.

Please note, this example does NOT send an email.

/**
 * Invite a user to join an organization. Not as simple as it sounds since
 * there are two use cases that must be handled.
 * * user does not belong to tenant, create an invitation asking them to sign up
 * * user belongs to tenant, simply add to organization
 * For security reasons, the organization administrators will not be allowed
 * to see tenant users.
 * @param clientId application client id
 * @param auth0OrganizationId auth0 organization id (eg: org_D0GiHe44ef4AWgC31)
 * @param email user email
 * @param roles array of auth0 roles id (eg: rol_xP45Cd9KJ6D7Ef)
 * @returns an invitation to login to organization or sign up to tenant
 */
const createInvitation = async (clientId, auth0OrganizationId, email, roles) => {
  const organization = await getOrganization(auth0OrganizationId)
  const management = await getManagementAPI()
  const members = await management.getUsersByEmail(email)
  if (members.length) {
    // if user is already signed up to tenant, add member to organization
    const response = await management
      .organizations
      .addMembers({ id: auth0OrganizationId }, { members: members.map(member => member.user_id) })
    console.log('addMembers', response)
    const client = await management.getClient({ client_id: clientId })
    return {
      inviter: {
        name: organization.display_name
      },
      invitee: {
        email: email
      },
      invitation_url: client.web_origins,
      organization_id: auth0OrganizationId
    }
  } else {
    // invite user to sign up to tenant
    const data = {
      client_id: clientId,
      inviter: {
        name: organization.display_name
      },
      invitee: {
        email: email
      },
      roles: roles,
      ttl_sec: 604800,
      send_invitation_email: false
    }
    const response = await management
      .organizations
      .createInvitation({ id: auth0OrganizationId }, data)
    return response
  }
}
1 Like

Thanks for sharing it with the rest of community!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.