|
import 'package:http/http.dart' as http;
|
|
import 'package:sunnex/core/constants/urls.dart';
|
|
import 'package:sunnex/core/utils/client.dart';
|
|
import 'package:sunnex/data/contracts/database_contract.dart';
|
|
import 'package:sunnex/errors/invalid_access_token_exception.dart';
|
|
import 'package:sunnex/repository/auth_repository.dart';
|
|
|
|
class AuthenticatedApiClient extends ApiClient {
|
|
final AuthRepository authRepository;
|
|
final DatabaseContract databaseService;
|
|
|
|
AuthenticatedApiClient({
|
|
required this.authRepository,
|
|
required this.databaseService,
|
|
});
|
|
|
|
bool _refreshInProgress = false;
|
|
|
|
@override
|
|
Future<http.Response> sendRequest(
|
|
String partOfUrl, {
|
|
required String method,
|
|
String? body,
|
|
required bool retryOn401,
|
|
required bool isFirebaseCall,
|
|
}) async {
|
|
http.Response response = http.Response('{}', 408);
|
|
|
|
try {
|
|
final accessToken = await databaseService.getAccessToken();
|
|
|
|
final headers = {
|
|
'Accept-Encoding': 'gzip',
|
|
'Accept-Language': 'en',
|
|
if (method != 'GET') 'Content-Type': 'application/json',
|
|
if (accessToken != null) 'Authorization': 'Bearer $accessToken',
|
|
};
|
|
|
|
final baseUrl = URLs.fullApiUrl;
|
|
final url = partOfUrl.contains(URLs.version)
|
|
? partOfUrl
|
|
: (baseUrl + partOfUrl);
|
|
|
|
response = await executeRequest(url, method, headers, body: body);
|
|
|
|
if (response.statusCode == 401 && retryOn401) {
|
|
throw InvalidAccessTokenException();
|
|
}
|
|
|
|
return response;
|
|
} on InvalidAccessTokenException {
|
|
if (_refreshInProgress) rethrow;
|
|
|
|
_refreshInProgress = true;
|
|
|
|
try {
|
|
await authRepository.refreshTokens();
|
|
|
|
// retry once with new token
|
|
final newAccessToken = await databaseService.getAccessToken();
|
|
|
|
final retryHeaders = {
|
|
'Accept-Encoding': 'gzip',
|
|
'Accept-Language': 'en',
|
|
if (method != 'GET') 'Content-Type': 'application/json',
|
|
if (newAccessToken != null) 'Authorization': 'Bearer $newAccessToken',
|
|
};
|
|
|
|
final baseUrl = URLs.fullApiUrl;
|
|
final url = partOfUrl.contains(URLs.version)
|
|
? partOfUrl
|
|
: (baseUrl + partOfUrl);
|
|
|
|
return await executeRequest(url, method, retryHeaders, body: body);
|
|
} finally {
|
|
_refreshInProgress = false;
|
|
}
|
|
}
|
|
}
|
|
}
|