Files
enaklo-flutter/lib/common/api/interceptors/unauthorized_interceptor.dart
T
efrilm 38850b281f
Build & Deploy iOS to TestFlight / build-and-deploy (push) Waiting to run
feat: integrate enakgame and voucher
2026-10-10 02:33:16 +07:00

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()]);
}
}