feat: support two-phase non-interactive firebase login#10777
Conversation
### Description Allows headless tools and AI agents to log the Firebase CLI into Google/Firebase in non-interactive environments using a two-phase login flow. - Initiating `firebase login --non-interactive` generates a PKCE `codeVerifier` and `sessionId`, writes it to the local `configstore`, and outputs a login URL with a verification code instructions. - Exchanging the code via `firebase login <auth_code>` retrieves the stored PKCE state, performs the remote token exchange, and records the active user session. ### Before and After Command Outputs #### Before Running `firebase login --non-interactive` threw an error immediately: ``` Cannot run login in non-interactive mode. See login:ci to generate a token for use in non-interactive environments. ``` #### After 1. Initiating the login: ``` $ firebase login --non-interactive To sign in to the Firebase CLI: 1. Take note of your session ID: 97548 2. Visit the URL below on any device and follow the instructions to get your code: https://auth.firebase.tools/login?code_challenge=MgMej1pXyJBOCEl4o5VQ1zPAEF4JRgW6WCNHnH1lBfA&session=97548b2c-fe34-4813-9d9d-93827425952a&attest=lWAgfQyI5wQ491SwVqsd8JCGXKWgKacAab60RXJMSqQ 3. Complete the login by running: firebase login <authorizationCode> ``` 2. Completing the login with the authorization code: ``` $ firebase login 4/0AdkVLPyTQOoo2mMMCsGpTl9ks_ozOmRGapvrd24bFQHaBmZ376AmaRNYx4nTs-HzU4Jnug ✔ Success! Logged in as joehanley@google.com ``` ### Scenarios Tested - Initiating the login flow in non-interactive mode. - Exchanging code with correct/matching state successfully. - Exchanging code when no login state is present or state fails verification. - Verified that full project listing commands (`projects:list`) works successfully post-authentication. ### Sample Commands `firebase login --non-interactive` `firebase login <authCode>`
There was a problem hiding this comment.
Code Review
This pull request introduces support for a two-phase non-interactive authentication flow to firebase login using login [auth_code], allowing headless tools and agents to log in. It refactors the remote login logic in src/auth.ts into start and complete phases, updates the login command in src/commands/login.ts to handle these phases, and adds corresponding unit tests in src/commands/login.spec.ts. Feedback on the changes highlights a potential crash when accessing result.user.email without a truthiness check, and multiple violations of the repository style guide regarding the use of any as an escape hatch in error catch blocks and test assertions.
| } catch (e: any) { | ||
| configstore.delete("tempLoginState"); | ||
| throw new FirebaseError(`Login failed: ${e.message}`, { exit: 1 }); | ||
| } |
There was a problem hiding this comment.
Using any as an escape hatch in the catch block violates the repository style guide. We should catch the error as unknown and safely extract the message.
} catch (e: unknown) {
configstore.delete("tempLoginState");
const message = e instanceof Error ? e.message : String(e);
throw new FirebaseError("Login failed: " + message, { exit: 1 });
}References
- Never use
anyorunknownas an escape hatch. Define proper interfaces/types or use type guards. (link)
Description
Allows headless tools and AI agents to log the Firebase CLI into Google/Firebase in non-interactive environments using a two-phase login flow.
firebase login --non-interactivegenerates a PKCEcodeVerifierandsessionId, writes it to the localconfigstore, and outputs a login URL with a verification code instructions.firebase login <auth_code>retrieves the stored PKCE state, performs the remote token exchange, and records the active user session.Before and After Command Outputs
Before
Running
firebase login --non-interactivethrew an error immediately:After
Scenarios Tested
projects:list) works successfully post-authentication.Sample Commands
firebase login --non-interactivefirebase login <authCode>