56 lines
2.0 KiB
Dart
56 lines
2.0 KiB
Dart
import 'dart:developer';
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import '../../../injection.dart';
|
|
import '../../../presentation/router/app_router.dart';
|
|
import '../../../presentation/router/app_router.gr.dart';
|
|
import '../../constant/local_storage_key.dart';
|
|
|
|
/// Token login ditolak server: HTTP `401`, atau `304` dengan `entity`
|
|
/// `auth_handler` (ยง2.2). Belum ada refresh token, jadi customer harus login
|
|
/// ulang.
|
|
///
|
|
/// Bukan `403`: `PIN_NOT_SET` dan `TRANSFER_BLOCKED` juga memakai `403`.
|
|
bool isTokenRejected(Response response) {
|
|
if (response.statusCode == 401) return true;
|
|
|
|
final body = response.data;
|
|
if (body is! Map) return false;
|
|
final errors = body['errors'];
|
|
if (errors is! List || errors.isEmpty || errors.first is! Map) return false;
|
|
|
|
final first = errors.first as Map;
|
|
return first['code']?.toString() == '304' &&
|
|
first['entity'] == 'auth_handler';
|
|
}
|
|
|
|
/// Menghapus sesi dan membuka halaman login bila token yang dipakai request
|
|
/// ditolak. `validateStatus` menerima semua status, jadi pengecekan ada di
|
|
/// [onResponse], bukan `onError`.
|
|
class UnauthorizedInterceptor extends Interceptor {
|
|
@override
|
|
void onResponse(Response response, ResponseInterceptorHandler handler) async {
|
|
try {
|
|
if (isTokenRejected(response)) await _handleTokenRejected(response);
|
|
} finally {
|
|
handler.next(response);
|
|
}
|
|
}
|
|
|
|
Future<void> _handleTokenRejected(Response response) async {
|
|
final prefs = getIt<SharedPreferences>();
|
|
final token = prefs.getString(LocalStorageKey.token);
|
|
// Hanya token yang sedang dipakai: abaikan request tanpa login dan jawaban
|
|
// basi dari token lama setelah customer login lagi.
|
|
final sentAuthorization = response.requestOptions.headers['Authorization'];
|
|
if (token == null || sentAuthorization != 'Bearer $token') return;
|
|
|
|
log('token rejected', name: 'UnauthorizedInterceptor');
|
|
await prefs.remove(LocalStorageKey.token);
|
|
await prefs.remove(LocalStorageKey.user);
|
|
getIt<AppRouter>().replaceAll([LoginRoute()]);
|
|
}
|
|
}
|