Fix auth errors, CORS, control center login, and stale session handling
- Mitra auth: parse DioException response for proper error messages (ACCOUNT_NOT_FOUND, ACCOUNT_INACTIVE) instead of generic "OTP invalid" - Backend: add CORS to internal app (port 3001) for control center - Control center: fix login race condition (wait for AuthContext verify before navigating), fix MitraActivityPage fetching paginated data - Stale session goodbye: both apps detect SESSION_NOT_ACTIVE/409 and move to complete state instead of retrying endlessly Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
@@ -91,8 +92,10 @@ class MitraAuth extends _$MitraAuth {
|
||||
await _auth.signInWithCredential(credential);
|
||||
}
|
||||
state = AsyncData(await _verifyAndReturn());
|
||||
} catch (e) {
|
||||
} on FirebaseAuthException {
|
||||
state = AsyncError('OTP tidak valid. Coba lagi.', StackTrace.current);
|
||||
} catch (e) {
|
||||
state = AsyncError(e.toString().replaceFirst('Exception: ', ''), StackTrace.current);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,15 +108,18 @@ class MitraAuth extends _$MitraAuth {
|
||||
try {
|
||||
final response = await _apiClient.post('/api/mitra/auth/verify');
|
||||
return MitraAuthAuthenticatedData(response['data'] as Map<String, dynamic>);
|
||||
} on Exception catch (e) {
|
||||
} on DioException catch (e) {
|
||||
await _auth.signOut();
|
||||
final msg = e.toString();
|
||||
if (msg.contains('ACCOUNT_NOT_FOUND')) {
|
||||
final code = e.response?.data?['error']?['code'] as String?;
|
||||
if (code == 'ACCOUNT_NOT_FOUND' || e.response?.statusCode == 404) {
|
||||
throw Exception('Akun tidak ditemukan. Hubungi administrator.');
|
||||
} else if (msg.contains('ACCOUNT_INACTIVE')) {
|
||||
} else if (code == 'ACCOUNT_INACTIVE' || e.response?.statusCode == 403) {
|
||||
throw Exception('Akun tidak aktif. Hubungi administrator.');
|
||||
}
|
||||
throw Exception('Gagal masuk. Coba lagi.');
|
||||
} on Exception {
|
||||
await _auth.signOut();
|
||||
throw Exception('Gagal masuk. Coba lagi.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ part of 'auth_notifier.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$mitraAuthHash() => r'65235a41cde3a37feef0b3004a0a48b508bf9ac9';
|
||||
String _$mitraAuthHash() => r'ddb09225b47b4e7683c9f8ad46abc21d9fb7a37b';
|
||||
|
||||
/// See also [MitraAuth].
|
||||
@ProviderFor(MitraAuth)
|
||||
|
||||
@@ -68,6 +68,13 @@ class MitraExtension extends _$MitraExtension {
|
||||
'message': message,
|
||||
});
|
||||
state = const ExtensionCompleteData();
|
||||
} on DioException catch (e) {
|
||||
final code = e.response?.data?['error']?['code'];
|
||||
if (code == 'SESSION_NOT_ACTIVE' || e.response?.statusCode == 409) {
|
||||
state = const ExtensionCompleteData();
|
||||
} else {
|
||||
state = const ExtensionErrorData('Gagal mengirim pesan penutup.');
|
||||
}
|
||||
} catch (e) {
|
||||
state = const ExtensionErrorData('Gagal mengirim pesan penutup.');
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ part of 'status_notifier.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$onlineStatusHash() => r'6b42328eaba0f7934b0e3eaa54eb6b764f1c4e53';
|
||||
String _$onlineStatusHash() => r'26f86241ddbe8534b8ab700d3dcaa22c5f17eb76';
|
||||
|
||||
/// See also [OnlineStatus].
|
||||
@ProviderFor(OnlineStatus)
|
||||
|
||||
Reference in New Issue
Block a user