Create and use organization on first login

Ready to post? :mag: First, try searching for your answer.
Hey all, our use case is that we need to create an organization for each user when they first login. This has been easy enough to do with the onExecutePostLogin action, but the problem we are running into is that for the session the org was create, auth0 is not adding the org_id to the token, the user has to logout then back in. Would love some pointers on a better way to do this!

Right now, the best solution we’ve found is to add a custom claim on the ID Token after creating the organization ( api.idToken.setCustomClaim(${namespace}, org.data.id);, then having a useEffect in our React layout that checks for a user without a org_id, and if so calls loginWithPopup passing the org_id from the custom claim.

useEffect(() => {
		if (user) {
			console.log(user)
			const refreshToken = async () => {
				if (!user.org_id) {
					const token = await loginWithPopup({
						authorizationParams: {
							organization: user['https://doohickey.ai/org_id']
						}
					})
				}
			}
			refreshToken()
		}
	}, [user])

This works, but results in screen flashing and a slow login. Additionally, we haven’t gotten this to work with anything but the Organizations->Both->Prompt for Credentials Universal Login setting. Which means that a user with a single org still has to select the org from the org list on subsequent logins, which is a bad user experience.

Our ideal flow would be user first login → action creates org → login flow resumes, user picks org → user authenticated and org_id on token.

I’ve also experimented with clearing the session and redirected back to the authorize flow in the action, but this seems to lead to redirect loops (sample code from failed experiments below)

 await api.session.revoke("set org manually")
  api.redirect.sendUserTo(`https://dev-mhrta5blmbkurat0.us.auth0.com/authorize`,
  {
    query: {
      client_id: client_id
      audience: audience,
      response_type: 'token',
      redirect_uri: `http://localhost:5173/callback`,
      org_id: org.data.id,
      organization: org.data.id,
      scope: "openid profile email user_metadata"
    }
  });

For reference, this is the current state of our action:

const ManagementClient = require('auth0').ManagementClient;
const generate = require("random-words");

exports.onExecutePostLogin = async (event, api) => {
const management = new ManagementClient({
      domain: event.secrets.domain,
      clientId: event.secrets.clientID,
      clientSecret: event.secrets.clientSecret
  });
  
  const user = event.user.user_id
  
  const orgs = await management.users.getUserOrganizations({id: user})

  if(orgs?.data?.length) {
    api.idToken.setCustomClaim(event.secrets.namespace, orgs.data[0].id);
    return;
  }


  let name = ""
  let tries = 3

  while(tries > 0) {
    name = generate({ exactly: 3, minLength: 3, join: "-" })
    tries--
    try {
      const existing = await management.organizations.getByName({
        "name": name
      })
      if (!existing?.data?.name) break;
    } catch (_e) {
      break
    }
  }

  const data = {"name": name}

  const org = await management.organizations.create(data)
  var params =  { id : org.data.id}
  await management.organizations.addEnabledConnection(params, {
    connection_id: event.secrets.connId
  })

  var dataOrg = { members: [ user ] }

  await management.organizations.addMembers(params, dataOrg)
  api.idToken.setCustomClaim(event.secrets.namespace, org.data.id);
  
}

Thanks for any help!