fix: skip 2FA preflight when using OAuth tokens (#846)

The CLI's 2FA preflight (validate_two_factor_if_enabled) was running
for OAuth-authenticated requests even though backboard's
hasTwoFactorVerification authScope exempts OAuth from 2FA enforcement.

For users with 2FA enabled, the twoFactorInfo query would report
isVerified: true, prompting for a 2FA code. The CLI then calls the
twoFactorInfoValidate mutation, whose resolver explicitly requires
ctx.sessionId != null and throws BadAccessError otherwise. OAuth
requests always have sessionId: null, so the validation is unreachable.

The end-user symptom is: `railway delete` (and any other command
going through the preflight) prompts for a 2FA code on fresh OAuth
logins, then fails with `Bad Access` regardless of whether the code
is correct.

Extend the existing short-circuit to also cover OAuth tokens, mirroring
the behavior for token-based auth and matching the backend's 2FA
exemption.
This commit is contained in:
samaybar 2026-04-21 07:29:35 -04:00 committed by GitHub
parent 1f60c8dafe
commit 4db4ff39c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -9,7 +9,9 @@ use crate::{
};
/// Validates 2FA if enabled for the current user.
/// Skips check entirely for token-based auth (API tokens bypass 2FA on the backend).
/// Skips check for token-based auth (API tokens bypass 2FA on the backend) and for
/// OAuth tokens (backboard exempts OAuth from 2FA, and the twoFactorInfoValidate
/// mutation requires a browser session that OAuth does not have).
/// For session-based auth, prompts for 2FA code if enabled, or uses provided code.
pub async fn validate_two_factor_if_enabled(
client: &reqwest::Client,
@ -17,8 +19,9 @@ pub async fn validate_two_factor_if_enabled(
is_terminal: bool,
two_factor_code: Option<String>,
) -> Result<()> {
// Skip 2FA check for token-based auth (API tokens bypass 2FA on the backend)
if Configs::is_using_token_auth() {
// Skip 2FA check for token-based auth and OAuth tokens — backboard does not
// enforce 2FA for either, and the validate mutation is unreachable without a session.
if Configs::is_using_token_auth() || configs.has_oauth_token() {
return Ok(());
}