Fix stale VPS URL and token expiration when switching servers
This commit is contained in:
1 parent
9c97d2db8a
commit
7681aa4c1f
15 files changed
+39
-20
No files matched your search
@@ -1,3 +1,6 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
class ApiConstants {
|
||||
static const int port = 18484;
|
||||
static const String vpsUrl = 'http://198.252.107.197:$port/api';
|
||||
@@ -12,6 +15,26 @@ class ApiConstants {
|
||||
static void setBaseUrl(String url) {
|
||||
// Strip trailing slash then append /api
|
||||
final clean = url.replaceAll(RegExp(r'/+$'), '');
|
||||
_baseUrl = clean.endsWith('/api') ? clean : '$clean/api';
|
||||
final newUrl = clean.endsWith('/api') ? clean : '$clean/api';
|
||||
if (_baseUrl != newUrl) {
|
||||
_baseUrl = newUrl;
|
||||
// Clear stored JWT token whenever server URL changes to prevent "token expired" on different server
|
||||
const FlutterSecureStorage().delete(key: 'jwt_token');
|
||||
const FlutterSecureStorage().delete(key: 'remember_me');
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a Dio client that dynamically uses the active [baseUrl] on every request.
|
||||
static Dio createDio([BaseOptions? options]) {
|
||||
final dio = Dio(options ?? BaseOptions(baseUrl: _baseUrl));
|
||||
dio.interceptors.add(
|
||||
InterceptorsWrapper(
|
||||
onRequest: (options, handler) {
|
||||
options.baseUrl = _baseUrl;
|
||||
return handler.next(options);
|
||||
},
|
||||
),
|
||||
);
|
||||
return dio;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import '../entities/dashboard_models.dart';
|
||||
|
||||
/// Repository for paginated user history (admin-only).
|
||||
class ActivityRepository {
|
||||
final Dio _dio = Dio(BaseOptions(baseUrl: ApiConstants.baseUrl));
|
||||
final Dio _dio = ApiConstants.createDio();
|
||||
final FlutterSecureStorage _storage = const FlutterSecureStorage();
|
||||
|
||||
Future<Options> _getAuthOptions() async {
|
||||
|
||||
@@ -35,7 +35,7 @@ class ArchivePage {
|
||||
}
|
||||
|
||||
class ArchiveRepository {
|
||||
final Dio _dio = Dio(BaseOptions(baseUrl: ApiConstants.baseUrl));
|
||||
final Dio _dio = ApiConstants.createDio();
|
||||
final FlutterSecureStorage _storage = const FlutterSecureStorage();
|
||||
|
||||
Future<Options> _getAuthOptions() async {
|
||||
|
||||
@@ -4,7 +4,7 @@ import '../../domain/entities/user_model.dart';
|
||||
import '../../core/network/api_constants.dart';
|
||||
|
||||
class AuthRepository {
|
||||
final Dio _dio = Dio(BaseOptions(baseUrl: ApiConstants.baseUrl));
|
||||
final Dio _dio = ApiConstants.createDio();
|
||||
final FlutterSecureStorage _storage = const FlutterSecureStorage();
|
||||
|
||||
static const _tokenKey = 'jwt_token';
|
||||
|
||||
@@ -4,9 +4,8 @@ import '../../core/network/api_constants.dart';
|
||||
import 'dart:io';
|
||||
|
||||
class BackupRepository {
|
||||
final Dio _dio = Dio(
|
||||
final Dio _dio = ApiConstants.createDio(
|
||||
BaseOptions(
|
||||
baseUrl: ApiConstants.baseUrl,
|
||||
connectTimeout: const Duration(seconds: 120),
|
||||
receiveTimeout: const Duration(seconds: 120), // Zipping might take time
|
||||
),
|
||||
|
||||
@@ -4,7 +4,7 @@ import '../../core/network/api_constants.dart';
|
||||
import '../entities/dashboard_models.dart';
|
||||
|
||||
class DashboardRepository {
|
||||
final Dio _dio = Dio(BaseOptions(baseUrl: ApiConstants.baseUrl));
|
||||
final Dio _dio = ApiConstants.createDio();
|
||||
final FlutterSecureStorage _storage = const FlutterSecureStorage();
|
||||
|
||||
Future<Options> _getAuthOptions() async {
|
||||
|
||||
@@ -195,7 +195,7 @@ class MissingRequirements {
|
||||
}
|
||||
|
||||
class DocumentRepository {
|
||||
final Dio _dio = Dio(BaseOptions(baseUrl: ApiConstants.baseUrl));
|
||||
final Dio _dio = ApiConstants.createDio();
|
||||
final FlutterSecureStorage _storage = const FlutterSecureStorage();
|
||||
|
||||
Future<Options> _getAuthOptions() async {
|
||||
|
||||
@@ -4,7 +4,7 @@ import '../../core/network/api_constants.dart';
|
||||
import '../entities/notification_model.dart';
|
||||
|
||||
class NotificationRepository {
|
||||
final Dio _dio = Dio(BaseOptions(baseUrl: ApiConstants.baseUrl));
|
||||
final Dio _dio = ApiConstants.createDio();
|
||||
final FlutterSecureStorage _storage = const FlutterSecureStorage();
|
||||
|
||||
Future<Options> _getAuthOptions() async {
|
||||
|
||||
@@ -5,9 +5,8 @@ import '../../core/network/api_constants.dart';
|
||||
import '../entities/ocr_result_model.dart';
|
||||
|
||||
class OcrRepository {
|
||||
final Dio _dio = Dio(
|
||||
final Dio _dio = ApiConstants.createDio(
|
||||
BaseOptions(
|
||||
baseUrl: ApiConstants.baseUrl,
|
||||
connectTimeout: const Duration(seconds: 60), // OCR takes time
|
||||
receiveTimeout: const Duration(seconds: 60),
|
||||
),
|
||||
|
||||
@@ -4,7 +4,7 @@ import '../../core/network/api_constants.dart';
|
||||
import '../entities/report_models.dart';
|
||||
|
||||
class ReportRepository {
|
||||
final Dio _dio = Dio(BaseOptions(baseUrl: ApiConstants.baseUrl));
|
||||
final Dio _dio = ApiConstants.createDio();
|
||||
final FlutterSecureStorage _storage = const FlutterSecureStorage();
|
||||
|
||||
Future<Options> _authOptions() async {
|
||||
|
||||
@@ -4,7 +4,7 @@ import '../../core/network/api_constants.dart';
|
||||
import '../entities/setup_models.dart';
|
||||
|
||||
class SetupRepository {
|
||||
final Dio _dio = Dio(BaseOptions(baseUrl: ApiConstants.baseUrl));
|
||||
final Dio _dio = ApiConstants.createDio();
|
||||
final FlutterSecureStorage _storage = const FlutterSecureStorage();
|
||||
|
||||
Future<Options> _getAuthOptions() async {
|
||||
|
||||
@@ -36,7 +36,7 @@ class StudentPage {
|
||||
}
|
||||
|
||||
class StudentRepository {
|
||||
final Dio _dio = Dio(BaseOptions(baseUrl: ApiConstants.baseUrl));
|
||||
final Dio _dio = ApiConstants.createDio();
|
||||
final FlutterSecureStorage _storage = const FlutterSecureStorage();
|
||||
|
||||
IO.Socket? _socket;
|
||||
|
||||
@@ -4,7 +4,7 @@ import '../../core/network/api_constants.dart';
|
||||
import '../entities/system_user.dart';
|
||||
|
||||
class UserRepository {
|
||||
final Dio _dio = Dio(BaseOptions(baseUrl: ApiConstants.baseUrl));
|
||||
final Dio _dio = ApiConstants.createDio();
|
||||
final FlutterSecureStorage _storage = const FlutterSecureStorage();
|
||||
|
||||
Future<Options> _getAuthOptions() async {
|
||||
|
||||
@@ -44,7 +44,7 @@ final academicYearsProvider = FutureProvider.autoDispose<List<AcademicYear>>((
|
||||
) async {
|
||||
final storage = const FlutterSecureStorage();
|
||||
final token = await storage.read(key: 'jwt_token');
|
||||
final dio = Dio(BaseOptions(baseUrl: ApiConstants.baseUrl));
|
||||
final dio = ApiConstants.createDio();
|
||||
|
||||
try {
|
||||
final response = await dio.get(
|
||||
|
||||
@@ -185,8 +185,7 @@ class _UploadOcrModalState extends ConsumerState<UploadOcrModal> {
|
||||
try {
|
||||
final storage = const FlutterSecureStorage();
|
||||
final token = await storage.read(key: 'jwt_token');
|
||||
final dio = Dio(BaseOptions(
|
||||
baseUrl: ApiConstants.baseUrl,
|
||||
final dio = ApiConstants.createDio(BaseOptions(
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
));
|
||||
|
||||
@@ -396,8 +395,7 @@ class _UploadOcrModalState extends ConsumerState<UploadOcrModal> {
|
||||
try {
|
||||
final storage = const FlutterSecureStorage();
|
||||
final token = await storage.read(key: 'jwt_token');
|
||||
final dio = Dio(BaseOptions(
|
||||
baseUrl: ApiConstants.baseUrl,
|
||||
final dio = ApiConstants.createDio(BaseOptions(
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
));
|
||||
|
||||
|
||||
Reference in new issue
Block a user