import 'package:common/services/msal_service.dart';
import 'package:comwell_key_app/presentation/screens/login/login_route.dart';
import 'package:comwell_key_app/services/exceptions.dart';
import 'package:common/utils/env_utils.dart';
import 'package:comwell_key_app/utils/locator.dart';
import 'package:comwell_key_app/utils/secure_storage.dart';
import 'package:dio/dio.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter/material.dart';
class ResponseHandleInterceptor extends Interceptor {
final ComwellPreferences _comwellPreferences;
final MSALService _msalService;
ResponseHandleInterceptor(this._msalService, this._comwellPreferences);
BuildContext? get context {
final navigatorKey = locator<GlobalKey<NavigatorState>>();
return navigatorKey.currentContext;
}
Future<void> checkAuth(RequestOptions requestOptions) async {
try {
final accessToken = await _msalService.acquireTokenSilent();
requestOptions.headers['Authorization'] = accessToken;
} catch (e, _) {
debugPrint("checkAuthError=$e");
throw UnauthorizedException();
}
}
void addUserAgentHeader(RequestOptions requestOptions) {
requestOptions.headers['User-Agent'] = _comwellPreferences.userAgent;
}
@override
Future<dynamic> onRequest(
RequestOptions options,
RequestInterceptorHandler handler,
) async {
try {
await checkAuth(options);
options.headers['Ocp-Apim-Subscription-Key'] = dotenv.OCP_APIM_SUBSCRIPTION_KEY;
addUserAgentHeader(options);
return handler.next(options);
} on UnauthorizedException catch (e, st) {
final exc = DioException(requestOptions: options, error: e, stackTrace: st);
handler.reject(exc);
logOut();
} catch (e, st) {
handler.reject(DioException(requestOptions: options, error: e, stackTrace: st));
}
}
void logOut() {
if (context != null) const LoginRoute().go(context!);
}
@override
Future<dynamic> onError(
DioException err,
ErrorInterceptorHandler handler,
) async {
final response = err.response;
if (response == null) {
debugPrint('Error: No response received');
return handler.reject(err);
}
debugPrint('Error: ${_extractErrorMessage(response.data, "No data")}');
switch (response.statusCode) {
case 401:
case 426:
logOut();
}
return handler.reject(err);
}
String _extractErrorMessage(dynamic data, String fallback) {
if (data == null) return fallback;
if (data is String) return data;
if (data is Map) {
return data['detail']?.toString() ??
data['message']?.toString() ??
data['error']?.toString() ??
fallback;
}
return fallback;
}
}