verifyOTP method

Future<LoginOTPResponse> verifyOTP({
  1. required String email,
  2. required String code,
  3. String? tenantId,
})

Verify OTP and login

Implementation

Future<LoginOTPResponse> verifyOTP({
  required String email,
  required String code,
  String? tenantId,
}) async {
  try {
    final response = await _apiClient.post<Map<String, dynamic>>(
      '/api/v1/auth/verify-otp',
      data: {
        'email': email,
        'code': code,
        if (tenantId != null) 'tenantId': tenantId,
      },
    );

    final loginResponse = LoginOTPResponse.fromJson(response);

    // Store tokens securely if login successful
    if (loginResponse.success && loginResponse.data != null) {
      await _storeTokens(
        accessToken: loginResponse.data!.session.accessToken,
        refreshToken: loginResponse.data!.refreshToken,
        expiresAt: loginResponse.data!.session.expiresAt,
      );

      // Store user data
      await _storeUserData(loginResponse.data!.user);

      // Update API client with new token
      _apiClient.setAuthToken(loginResponse.data!.session.accessToken);

      // Store organization context if available
      if (loginResponse.data!.tenantMemberships?.isNotEmpty ?? false) {
        final membership = loginResponse.data!.tenantMemberships!.first;
        _apiClient.setOrganization(membership.tenantId);
        final prefs = await _prefsInstance;
        await prefs.setString(_orgKey, membership.tenantId);
      }
    }

    return loginResponse;
  } on ProdobitException {
    rethrow;
  } catch (e) {
    throw AuthException(
      'OTP verification failed: $e',
      code: 'OTP_VERIFY_ERROR',
    );
  }
}