switchUser method

Future<AuthUserSession> switchUser({
  1. required String userId,
  2. String? merchantId,
  3. String? businessId,
  4. bool refresh = false,
  5. bool setBaseSession = false,
  6. String? pin,
})

Switches the current user session. Used to switch users without a full sign-out/sign-in flow. Fetches or creates a session for the target userId and sets it as active. If refresh is true, all existing sessions for the user will be deleted before creating a new one. merchantId and businessId can be provided to scope the session to a specific context. Requires session tokens to be enabled. pin Optional PIN for session creation when PIN verification is required.

Implementation

Future<AuthUserSession> switchUser({
  required String userId,
  String? merchantId,
  String? businessId,
  bool refresh = false,
  bool setBaseSession = false,
  String? pin,
}) async {
  return monitoringService.monitorAction<AuthUserSession>(
    actionName: 'switchUser',
    provider: _authProviderName,
    resultParser: (result) => {'new_session_user_id': result.userId},
    action: (trace) async {
      _ensureInitialized();

      if (!sessionTokensEnabled) {
        logger.error(
          this,
          'Cannot switch user: session tokens are disabled.',
        );
        throw AuthException(
          AuthenticationErrorCodes.sessionManagerNotInitialized,
        );
      }

      await _ensureSessionManagerReady();

      logger.info(this, 'Attempting to switch to user: $userId');
      if (user == null) {
        throw AuthException(AuthenticationErrorCodes.userNotFoundForSwitch);
      }

      // Preserve base session before deleteAllSessions so we can restore
      // it if session creation fails — prevents permanent _baseSession loss.
      final savedBaseSession = sessionManager.baseSession;

      try {
        if (refresh) {
          logger.info(this, 'Refreshing session for user: $userId');
          await sessionManager.deleteAllSessions(
            businessId: user?.currentBusiness?.id ?? '',
            mid: merchantId,
          );
        }

        final newSession = await sessionManager.switchSession(
          userId: userId,
          mid: merchantId,
          refresh: refresh,
          businessId: businessId,
          pin: pin,
        );

        _assignSession(user!, newSession);

        if (setBaseSession) {
          _captureBaseSession(newSession);
        }
        logger.info(this, 'Successfully switched to user: $userId');
        return newSession;
      } catch (e, st) {
        if (savedBaseSession != null &&
            sessionManager.baseSession == null) {
          sessionManager.restoreBaseSession(savedBaseSession);
          logger.warning(
            this,
            'Restored base session after switchUser failure. '
            'Base user: ${savedBaseSession.userInfo.userId}',
            error: e,
            stackTrace: st,
          );
        }
        rethrow;
      }
    },
  );
}