From b04d23c7a4a9bc3772e8e1c25881600cead4b1b8 Mon Sep 17 00:00:00 2001 From: Deep Koluguri Date: Mon, 10 Nov 2025 18:34:48 -0500 Subject: [PATCH] auth token fix --- backend/public/api-tester.html | 393 +++++++++++++++++++ backend/src/server.js | 3 + luckychit/lib/core/services/api_service.dart | 60 ++- 3 files changed, 449 insertions(+), 7 deletions(-) create mode 100644 backend/public/api-tester.html diff --git a/backend/public/api-tester.html b/backend/public/api-tester.html new file mode 100644 index 0000000..b31e49a --- /dev/null +++ b/backend/public/api-tester.html @@ -0,0 +1,393 @@ + + + + + + API Tester - ChitFund + + + +
+
+

🔧 ChitFund API Tester

+

Test your API endpoints with authentication

+
+ +
+ +
+

🔐 Step 1: Login

+
+ +
+ + +
+ +
+ + +
+ + + + +
+ + +
+

🚀 Step 2: Test API Endpoints

+
+ +
+ + + +
+ +
+ + + +
+ +
+ +
+
+ + +
+

📦 Response

+
+No response yet. Login and test an endpoint! +
+
+
+
+ + + + + diff --git a/backend/src/server.js b/backend/src/server.js index feb23a2..66f31a4 100644 --- a/backend/src/server.js +++ b/backend/src/server.js @@ -48,6 +48,9 @@ if (process.env.NODE_ENV === 'development') { app.use(morgan('dev')); } +// Serve static files (for API tester) +app.use('/test', express.static('public')); + // Health check endpoint app.get('/health', (req, res) => { res.json({ diff --git a/luckychit/lib/core/services/api_service.dart b/luckychit/lib/core/services/api_service.dart index fb4bf00..3916f9a 100644 --- a/luckychit/lib/core/services/api_service.dart +++ b/luckychit/lib/core/services/api_service.dart @@ -8,7 +8,12 @@ static const String tokenKey = 'auth_token'; late Dio _dio; - ApiService() { + // Singleton pattern + static final ApiService _instance = ApiService._internal(); + factory ApiService() => _instance; + + ApiService._internal() { + print('🏗️ [ApiService] Creating singleton instance'); _dio = Dio(BaseOptions( baseUrl: baseUrl, connectTimeout: const Duration(seconds: 30), @@ -23,13 +28,20 @@ static const String tokenKey = 'auth_token'; _dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) async { final token = await _getToken(); + print('🔐 [ApiService] Token retrieved: ${token != null ? "YES (${token.substring(0, 20)}...)" : "NO - NULL!"}'); + print('🔐 [ApiService] Request: ${options.method} ${options.path}'); if (token != null) { options.headers['Authorization'] = 'Bearer $token'; + print('🔐 [ApiService] Authorization header added'); + } else { + print('⚠️ [ApiService] WARNING: No token found! Request will fail!'); } handler.next(options); }, onError: (error, handler) { + print('❌ [ApiService] Error: ${error.response?.statusCode} - ${error.message}'); if (error.response?.statusCode == 401) { + print('❌ [ApiService] 401 Unauthorized - Clearing token'); // Token expired or invalid _clearToken(); } @@ -40,18 +52,41 @@ static const String tokenKey = 'auth_token'; // Token management Future _getToken() async { - final prefs = await SharedPreferences.getInstance(); - return prefs.getString(tokenKey); + try { + final prefs = await SharedPreferences.getInstance(); + final token = prefs.getString(tokenKey); + print('🔑 [ApiService._getToken] Looking for key: "$tokenKey"'); + print('🔑 [ApiService._getToken] Token found: ${token != null}'); + if (token != null) { + print('🔑 [ApiService._getToken] Token length: ${token.length}'); + print('🔑 [ApiService._getToken] Token starts with: ${token.substring(0, token.length > 20 ? 20 : token.length)}...'); + } + return token; + } catch (e) { + print('❌ [ApiService._getToken] Error: $e'); + return null; + } } Future _saveToken(String token) async { - final prefs = await SharedPreferences.getInstance(); - await prefs.setString(tokenKey, token); + try { + final prefs = await SharedPreferences.getInstance(); + await prefs.setString(tokenKey, token); + print('✅ [ApiService._saveToken] Token saved with key: "$tokenKey"'); + print('✅ [ApiService._saveToken] Token length: ${token.length}'); + } catch (e) { + print('❌ [ApiService._saveToken] Error: $e'); + } } Future _clearToken() async { - final prefs = await SharedPreferences.getInstance(); - await prefs.remove(tokenKey); + try { + final prefs = await SharedPreferences.getInstance(); + await prefs.remove(tokenKey); + print('🗑️ [ApiService._clearToken] Token cleared'); + } catch (e) { + print('❌ [ApiService._clearToken] Error: $e'); + } } // Authentication APIs @@ -510,6 +545,17 @@ static const String tokenKey = 'auth_token'; Future logout() async { await _clearToken(); } + + // Debug: Check if token exists + Future hasToken() async { + final token = await _getToken(); + return token != null; + } + + // Debug: Get current token (for debugging) + Future getCurrentToken() async { + return await _getToken(); + } // Error handling Map _handleError(DioException e) {