diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index ce42bd0..b2482c8 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -107,7 +107,7 @@ jobs: SUDO="" fi $SUDO apt-get update - $SUDO apt-get install -y unzip xz-utils zip libstdc++6 libglu1-mesa clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev curl jq + $SUDO apt-get install -y unzip xz-utils zip libstdc++6 libglu1-mesa clang cmake ninja-build pkg-config libgtk-3-dev libsecret-1-dev liblzma-dev curl jq - name: Setup Flutter uses: subosito/flutter-action@v2 diff --git a/lib/main.dart b/lib/main.dart index 2ce66ad..0ef41c1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -37,6 +37,7 @@ void main() { ProxyProvider( update: (_, auth, __) { api.setTokenProvider(() => auth.token); + api.setUnauthorizedHandler(() => auth.handleTokenExpired()); }, ), ChangeNotifierProxyProvider( diff --git a/lib/services/apiService.dart b/lib/services/apiService.dart index 442d5e1..bfb9893 100644 --- a/lib/services/apiService.dart +++ b/lib/services/apiService.dart @@ -2,10 +2,12 @@ import 'dart:convert'; import 'package:http/http.dart' as http; typedef TokenProvider = String? Function(); +typedef UnauthorizedHandler = Future Function(); class ApiService { final String baseUrl; TokenProvider? _getToken; + UnauthorizedHandler? _onUnauthorized; ApiService({required this.baseUrl}); @@ -13,6 +15,10 @@ class ApiService { _getToken = provider; } + void setUnauthorizedHandler(UnauthorizedHandler handler) { + _onUnauthorized = handler; + } + Map _buildHeaders(Map? extra) { final token = _getToken?.call(); final headers = {'accept': 'application/json', ...?extra}; @@ -85,12 +91,19 @@ class ApiService { return {'Content-Type': 'application/json', if (extra != null) ...extra}; } - dynamic _processResponse(http.Response res) { + Future _processResponse(http.Response res) async { final body = res.body.isNotEmpty ? jsonDecode(res.body) : null; if (res.statusCode >= 200 && res.statusCode < 300) { return body; - } else { - throw Exception('API error ${res.statusCode}: $body'); } + + if (res.statusCode == 401 && + body is Map && + body['detail'] == 'Not authenticated' && + _onUnauthorized != null) { + await _onUnauthorized!(); + } + + throw Exception('API error ${res.statusCode}: $body'); } }