Skip to main content
New Expensify supports multiple authentication methods to provide a secure and flexible sign-in experience.

Sign-In Methods

Magic Code

Email or SMS code-based authentication

SSO

Google, Apple, and Microsoft sign-in

SAML

Enterprise single sign-on

Getting Started

Basic Sign-In Flow

1

Enter Your Email or Phone Number

On the sign-in page, enter your email address or phone number:
src/pages/signin/LoginForm/BaseLoginForm.tsx
// The login form accepts both email and phone numbers
const phoneLogin = appendCountryCode(
  getPhoneNumberWithoutSpecialChars(loginTrim), 
  countryCode
);
const parsedPhoneNumber = parsePhoneNumber(phoneLogin);

if (!Str.isValidEmail(loginTrim) && !parsedPhoneNumber.possible) {
  // Show appropriate error message
}
Phone numbers are automatically formatted with your country code.
2

Receive Your Magic Code

After entering your login, New Expensify will:
  • Check if your account exists
  • Determine if SAML is required for your domain
  • Send a magic code to your email or phone
src/libs/actions/Session/index.ts
function beginSignIn(email: string) {
  const optimisticData: OnyxUpdate[] = [
    {
      onyxMethod: Onyx.METHOD.MERGE,
      key: ONYXKEYS.ACCOUNT,
      value: {
        ...CONST.DEFAULT_ACCOUNT_DATA,
        isLoading: true,
        loadingForm: 'login',
      },
    },
  ];
  
  API.write(WRITE_COMMANDS.BEGIN_SIGN_IN, { email }, {
    optimisticData,
    successData,
    failureData,
  });
}
3

Enter the Magic Code

Check your email or SMS for the magic code and enter it to complete sign-in.The validate code form handles:
  • Magic code validation
  • Two-factor authentication (if enabled)
  • Recovery code entry
4

Complete Authentication

Once validated, you’ll be signed in and redirected to the app.

SSO Authentication

New Expensify supports sign-in with Google and Apple accounts.

Google Authentication

Sign in with your Google account for quick access:
src/pages/signin/LoginForm/BaseLoginForm.tsx
<GoogleSignIn
  onPress={handleSignIn}
  onPointerDown={handleSignIn}
/>
Google sign-in is available on all platforms and uses the @react-native-google-signin/google-signin package.
What happens during Google sign-in:
  1. User clicks the Google sign-in button
  2. Google OAuth flow opens in a browser/modal
  3. User authenticates with Google
  4. Google returns an authentication token
  5. New Expensify validates the token and creates/signs into the account

Two-Factor Authentication (2FA)

Add an extra layer of security to your account with two-factor authentication.

Setting Up 2FA

1

Navigate to Security Settings

Go to SettingsSecurityTwo-factor authentication
2

Enable 2FA

  1. Scan the QR code with your authenticator app (Google Authenticator, Authy, etc.)
  2. Enter the 6-digit code from your authenticator app
  3. Save your recovery codes in a safe place
3

Verify Setup

The next time you sign in, you’ll be prompted for your authenticator code after entering your magic code.

2FA Sign-In Flow

When 2FA is enabled:
src/pages/signin/SignInPage.tsx
// After magic code validation, check if 2FA is required
const isTwoFactorStage = 
  account?.requiresTwoFactorAuth && 
  !!credentials?.validateCode;

if (isTwoFactorStage) {
  welcomeText = isUsingRecoveryCode 
    ? translate('validateCodeForm.enterRecoveryCode') 
    : translate('validateCodeForm.enterAuthenticatorCode');
}
1

Enter Magic Code

First, enter the magic code sent to your email/phone
2

Enter Authenticator Code

Then, enter the 6-digit code from your authenticator app
3

Alternative: Use Recovery Code

If you don’t have access to your authenticator app, you can use one of your recovery codes instead.
Each recovery code can only be used once. Generate new codes after using them.

Recovery Codes

Recovery codes are backup codes that can be used when you don’t have access to your authenticator app:
  • Each code is single-use
  • You receive 10 codes when setting up 2FA
  • Store them securely (password manager, printed copy, etc.)
  • Generate new codes in your security settings
If you lose both your authenticator app and recovery codes, you’ll need to contact support to regain access to your account.

Session Management

New Expensify manages your session securely with authentication tokens.

Session Lifecycle

src/libs/actions/Session/index.ts
// Session data stored in Onyx
let session: Session = {};

Onyx.connect({
  key: ONYXKEYS.SESSION,
  callback: (value) => {
    session = value ?? {};
    
    if (!session.creationDate) {
      session.creationDate = new Date().getTime();
    }
  },
});
Session Properties:
  • authToken: JWT token for API authentication
  • authTokenType: Type of auth (normal, anonymous, support)
  • accountID: Your unique account identifier
  • email: Your email address
  • creationDate: When the session was created

Session Expiration

Sessions expire after a period of inactivity:
src/libs/actions/Session/index.ts
function isExpiredSession(sessionCreationDate: number): boolean {
  return new Date().getTime() - sessionCreationDate 
    >= CONST.SESSION_EXPIRATION_TIME_MS;
}
You’ll be automatically signed out when your session expires. Your work is saved, and you can sign back in to continue.

Signing Out

To sign out of your account:
src/libs/actions/Session/index.ts
function signOut(params: {
  autoGeneratedLogin?: string;
  signedInWithSAML?: boolean;
  authToken?: string;
} = {}): Promise<void | Response<never>> {
  Log.info('Flushing logs before signing out', true, {}, true);
  
  const logOutParams: LogOutParams = {
    authToken: params.authToken ?? null,
    partnerUserID: params.autoGeneratedLogin ?? '',
    shouldRetry: false,
    skipReauthentication: true,
  };

  if (params.signedInWithSAML && params.authToken) {
    return callSAMLSignOut(logOutParams, params.authToken);
  }

  return API.makeRequestWithSideEffects(
    SIDE_EFFECT_REQUEST_COMMANDS.LOG_OUT, 
    logOutParams, 
    {}
  );
}
What happens when you sign out:
  1. Local data is cleared (except specific preserved keys)
  2. API call invalidates the session token
  3. You’re redirected to the sign-in page
  4. For SAML users, the identity provider is also logged out

Security Best Practices

Enable 2FA

Add two-factor authentication for enhanced security

Use Strong Passwords

If using email sign-in, ensure your email has a strong password

Keep Recovery Codes Safe

Store 2FA recovery codes securely

Sign Out on Shared Devices

Always sign out when using shared computers

Troubleshooting

If you’re not receiving your magic code:
  1. Check your spam/junk folder
  2. Verify the email address or phone number is correct
  3. Wait a few minutes and try again
  4. Check your SMS delivery settings (for phone login)
Magic codes expire after 10 minutes. Request a new code if needed.
If you’re getting an “Invalid code” error:
  1. Ensure you’re entering the most recent code
  2. Check for typos
  3. Request a new code if the current one is expired
  4. Clear your browser cache and try again
If you’ve lost access to your authenticator app:
  1. Use one of your recovery codes to sign in
  2. Once signed in, disable and re-enable 2FA with a new authenticator
  3. If you don’t have recovery codes, contact support
If SAML sign-in isn’t working:
  1. Contact your IT administrator to verify SAML is configured
  2. Ensure you’re using your work email address
  3. Check with IT that your account has access to the application
  4. Try signing in through your identity provider directly

Next Steps

Create a Workspace

Set up your first workspace to start managing expenses

Invite Team Members

Add colleagues to collaborate on expenses

Configure Settings

Customize your account preferences

Security Settings

Manage your 2FA and security options

Build docs developers (and LLMs) love