@@ -237,15 +237,15 @@ ${outputToken.json(applications)}
237237 if ( validationResult === 'needs_full_auth' ) {
238238 await throwOnNoPrompt ( noPrompt )
239239 outputDebug ( outputContent `Initiating the full authentication flow...` )
240- newSession = await executeCompleteFlow ( applications , currentSession ?. identity . alias )
240+ newSession = await executeCompleteFlow ( applications , currentSession ?. identity )
241241 } else if ( validationResult === 'needs_refresh' || forceRefresh ) {
242242 outputDebug ( outputContent `The current session is valid but needs refresh. Refreshing...` )
243243 try {
244244 newSession = await refreshTokens ( currentSession ! , applications )
245245 } catch ( error ) {
246246 if ( error instanceof InvalidGrantError ) {
247247 await throwOnNoPrompt ( noPrompt )
248- newSession = await executeCompleteFlow ( applications , currentSession ?. identity . alias )
248+ newSession = await executeCompleteFlow ( applications , currentSession ?. identity )
249249 } else if ( error instanceof InvalidRequestError ) {
250250 await sessionStore . remove ( )
251251 throw new AbortError ( '\nError validating auth session' , "We've cleared the current session, please try again" )
@@ -295,9 +295,12 @@ The CLI is currently unable to prompt for reauthentication.`,
295295 * Execute the full authentication flow.
296296 *
297297 * @param applications - An object containing the applications we need to be authenticated with.
298- * @param existingAlias - Optional alias from a previous session to preserve if the email fetch fails .
298+ * @param existingIdentity - Optional identity from the previous session.
299299 */
300- async function executeCompleteFlow ( applications : OAuthApplications , existingAlias ?: string ) : Promise < Session > {
300+ async function executeCompleteFlow (
301+ applications : OAuthApplications ,
302+ existingIdentity ?: IdentityToken ,
303+ ) : Promise < Session > {
301304 const scopes = getFlattenScopes ( applications )
302305 const exchangeScopes = getExchangeScopes ( applications )
303306 const store = applications . adminApi ?. storeFqdn
@@ -320,14 +323,19 @@ async function executeCompleteFlow(applications: OAuthApplications, existingAlia
320323 outputDebug ( outputContent `CLI token received. Exchanging it for application tokens...` )
321324 const result = await exchangeAccessForApplicationTokens ( identityToken , exchangeScopes , store )
322325
323- // Preserve existing alias if available, otherwise try fetching email
326+ // Preserve existing alias if available, otherwise try fetching email.
324327 const businessPlatformToken = result [ applicationId ( 'business-platform' ) ] ?. accessToken
325- const alias = existingAlias ?? ( await fetchEmail ( businessPlatformToken ) ) ?? identityToken . userId
328+ const existingAlias = existingIdentity ?. alias
329+ // A cached email belongs to its user ID, even when reauthentication selects another account.
330+ const existingEmail = existingIdentity ?. userId === identityToken . userId ? existingIdentity . email : undefined
331+ const email = existingAlias === undefined ? await fetchEmail ( businessPlatformToken ) : existingEmail
332+ const alias = existingAlias ?? email ?? identityToken . userId
326333
327334 const session : Session = {
328335 identity : {
329336 ...identityToken ,
330337 alias,
338+ email,
331339 } ,
332340 applications : result ,
333341 }
@@ -354,7 +362,11 @@ async function refreshTokens(session: Session, applications: OAuthApplications):
354362 )
355363
356364 return {
357- identity : { ...identityToken , alias : session . identity . alias } ,
365+ identity : {
366+ ...identityToken ,
367+ alias : session . identity . alias ,
368+ email : identityToken . userId === session . identity . userId ? session . identity . email : undefined ,
369+ } ,
358370 applications : applicationTokens ,
359371 }
360372}
0 commit comments