added server address
Browse files- backend/app.py +2 -2
- backend/utils/cookies.py +1 -1
- docs/sprint-artifacts/tech-spec-api-url-fix.md +72 -0
- frontend/.env.production +1 -1
- frontend/src/services/apiClient.js +17 -17
- frontend/test-auth-fix.js +37 -37
backend/app.py
CHANGED
|
@@ -120,7 +120,7 @@ def create_app():
|
|
| 120 |
"http://127.0.0.1:3000",
|
| 121 |
"http://127.0.0.1:5000",
|
| 122 |
"http://192.168.1.4:3000",
|
| 123 |
-
"
|
| 124 |
],
|
| 125 |
"methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
| 126 |
"allow_headers": ["Content-Type", "Authorization", "X-Requested-With"],
|
|
@@ -143,7 +143,7 @@ def create_app():
|
|
| 143 |
"http://127.0.0.1:3000",
|
| 144 |
"http://127.0.0.1:5000",
|
| 145 |
"http://192.168.1.4:3000",
|
| 146 |
-
"
|
| 147 |
]
|
| 148 |
|
| 149 |
# Add CORS headers specifically for OAuth callback routes
|
|
|
|
| 120 |
"http://127.0.0.1:3000",
|
| 121 |
"http://127.0.0.1:5000",
|
| 122 |
"http://192.168.1.4:3000",
|
| 123 |
+
"http://46.62.218.169"
|
| 124 |
],
|
| 125 |
"methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
| 126 |
"allow_headers": ["Content-Type", "Authorization", "X-Requested-With"],
|
|
|
|
| 143 |
"http://127.0.0.1:3000",
|
| 144 |
"http://127.0.0.1:5000",
|
| 145 |
"http://192.168.1.4:3000",
|
| 146 |
+
"http://46.62.218.169"
|
| 147 |
]
|
| 148 |
|
| 149 |
# Add CORS headers specifically for OAuth callback routes
|
backend/utils/cookies.py
CHANGED
|
@@ -93,7 +93,7 @@ def configure_jwt_with_cookies(app: Flask):
|
|
| 93 |
'http://127.0.0.1:3000',
|
| 94 |
'http://127.0.0.1:5000',
|
| 95 |
'http://192.168.1.4:3000',
|
| 96 |
-
'
|
| 97 |
]
|
| 98 |
|
| 99 |
@jwt.token_verification_loader
|
|
|
|
| 93 |
'http://127.0.0.1:3000',
|
| 94 |
'http://127.0.0.1:5000',
|
| 95 |
'http://192.168.1.4:3000',
|
| 96 |
+
'http://46.62.218.169'
|
| 97 |
]
|
| 98 |
|
| 99 |
@jwt.token_verification_loader
|
docs/sprint-artifacts/tech-spec-api-url-fix.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Tech-Spec: Fix API URL Configuration Issue
|
| 2 |
+
|
| 3 |
+
**Created:** December 23, 2025
|
| 4 |
+
**Status:** Ready for Development
|
| 5 |
+
|
| 6 |
+
## Overview
|
| 7 |
+
|
| 8 |
+
### Problem Statement
|
| 9 |
+
The frontend application is configured to use a hardcoded Hugging Face Space URL (`https://zelyanoth-lin-cbfcff2.hf.space`) instead of the user's local server IP address (`http://46.62.218.169/`). This causes API requests to fail with 404 errors when users try to access endpoints like `/api/posts/jobs/{jobId}`.
|
| 10 |
+
|
| 11 |
+
### Solution
|
| 12 |
+
Update the frontend environment configuration to use the correct API URL that matches the user's server IP address instead of the hardcoded Hugging Face Space URL.
|
| 13 |
+
|
| 14 |
+
### Scope (In/Out)
|
| 15 |
+
|
| 16 |
+
**In Scope:**
|
| 17 |
+
- Update frontend environment configuration files to use correct API URL
|
| 18 |
+
- Ensure API requests are made to the user's server IP address (`http://46.62.218.169/`)
|
| 19 |
+
- Test that API endpoints work correctly after configuration change
|
| 20 |
+
|
| 21 |
+
**Out Scope:**
|
| 22 |
+
- Backend server modifications
|
| 23 |
+
- Database schema changes
|
| 24 |
+
- UI/UX modifications
|
| 25 |
+
|
| 26 |
+
## Context for Development
|
| 27 |
+
|
| 28 |
+
### Codebase Patterns
|
| 29 |
+
- Frontend uses Vite with environment variables for configuration
|
| 30 |
+
- API calls are made through axios with a base URL configuration
|
| 31 |
+
- The project follows a standard React + Flask architecture
|
| 32 |
+
|
| 33 |
+
### Files to Reference
|
| 34 |
+
- `frontend/.env.production` - Contains the hardcoded Hugging Face Space URL
|
| 35 |
+
- `frontend/src/services/apiClient.js` - Contains the API client configuration logic
|
| 36 |
+
- `frontend/src/services/api.js` - Contains additional API configuration
|
| 37 |
+
|
| 38 |
+
### Technical Decisions
|
| 39 |
+
- The API URL should be configurable via environment variables to support different deployment environments
|
| 40 |
+
- The production environment file should be updated to use the correct server IP address
|
| 41 |
+
- CORS configuration in the backend already supports multiple origins including local addresses
|
| 42 |
+
|
| 43 |
+
## Implementation Plan
|
| 44 |
+
|
| 45 |
+
### Tasks
|
| 46 |
+
|
| 47 |
+
- [x] Update `frontend/.env.production` to use correct API URL
|
| 48 |
+
- [x] Verify that the API client properly handles the new URL configuration
|
| 49 |
+
- [x] Test that API requests are made to the correct server IP address
|
| 50 |
+
- [x] Verify that job polling endpoints work correctly
|
| 51 |
+
|
| 52 |
+
### Acceptance Criteria
|
| 53 |
+
|
| 54 |
+
- [x] AC 1: Given the updated configuration, when a user clicks the button to generate a post, then API requests should be made to `http://46.62.218.169/api/posts/` instead of the Hugging Face Space URL
|
| 55 |
+
- [x] AC 2: Given the updated configuration, when a user polls for job status, then requests to `/api/posts/jobs/{jobId}` should succeed without 404 errors
|
| 56 |
+
- [x] AC 3: Given the updated configuration, when the application runs in production mode, then all API calls should use the correct server IP address
|
| 57 |
+
|
| 58 |
+
## Additional Context
|
| 59 |
+
|
| 60 |
+
### Dependencies
|
| 61 |
+
- Frontend build process needs to be run after environment variable changes
|
| 62 |
+
- Backend server must be accessible at the configured IP address
|
| 63 |
+
|
| 64 |
+
### Testing Strategy
|
| 65 |
+
- Test the post generation flow after configuration changes
|
| 66 |
+
- Verify that job polling works correctly
|
| 67 |
+
- Check that all API endpoints return successful responses
|
| 68 |
+
|
| 69 |
+
### Notes
|
| 70 |
+
- The backend is already configured to accept requests from various origins including local addresses
|
| 71 |
+
- The frontend uses environment variables to determine the API URL based on the environment
|
| 72 |
+
- The hardcoded URL in the production environment file needs to be changed to the user's server IP
|
frontend/.env.production
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
# API Configuration
|
| 2 |
-
VITE_API_URL=
|
| 3 |
|
| 4 |
# Environment
|
| 5 |
VITE_NODE_ENV=production
|
|
|
|
| 1 |
# API Configuration
|
| 2 |
+
VITE_API_URL=http://46.62.218.169/api
|
| 3 |
|
| 4 |
# Environment
|
| 5 |
VITE_NODE_ENV=production
|
frontend/src/services/apiClient.js
CHANGED
|
@@ -4,7 +4,7 @@ import cookieService from '../services/cookieService';
|
|
| 4 |
// Create axios instance with default config
|
| 5 |
const API_BASE_URL = import.meta.env.VITE_API_URL ||
|
| 6 |
(import.meta.env.VITE_NODE_ENV === 'production' ?
|
| 7 |
-
'
|
| 8 |
'http://localhost:5000');
|
| 9 |
console.log('API_BASE_URL:', API_BASE_URL);
|
| 10 |
|
|
@@ -32,7 +32,7 @@ apiClient.interceptors.request.use(
|
|
| 32 |
headers: config.headers,
|
| 33 |
data: config.data
|
| 34 |
});
|
| 35 |
-
|
| 36 |
// Special logging for auth requests to verify field transformation
|
| 37 |
if (config.url?.includes('/auth/register')) {
|
| 38 |
console.log('π [Auth Register] Request data verification:', {
|
|
@@ -43,7 +43,7 @@ apiClient.interceptors.request.use(
|
|
| 43 |
});
|
| 44 |
}
|
| 45 |
}
|
| 46 |
-
|
| 47 |
// Get token from cookie service with fallback to localStorage
|
| 48 |
let token = null;
|
| 49 |
try {
|
|
@@ -53,7 +53,7 @@ apiClient.interceptors.request.use(
|
|
| 53 |
console.warn('πͺ [Cookie] Error getting auth tokens, trying localStorage:', error.message);
|
| 54 |
token = localStorage.getItem('token');
|
| 55 |
}
|
| 56 |
-
|
| 57 |
if (token) {
|
| 58 |
config.headers.Authorization = `Bearer ${token}`;
|
| 59 |
if (isDevelopment) {
|
|
@@ -64,7 +64,7 @@ apiClient.interceptors.request.use(
|
|
| 64 |
console.log('π [Token] No token found for request');
|
| 65 |
}
|
| 66 |
}
|
| 67 |
-
|
| 68 |
return config;
|
| 69 |
},
|
| 70 |
(error) => {
|
|
@@ -91,7 +91,7 @@ apiClient.interceptors.response.use(
|
|
| 91 |
async (error) => {
|
| 92 |
const isDevelopment = import.meta.env.VITE_NODE_ENV === 'development';
|
| 93 |
const originalRequest = error.config;
|
| 94 |
-
|
| 95 |
// Enhanced error logging
|
| 96 |
if (isDevelopment) {
|
| 97 |
console.error('β [API Response Error]', {
|
|
@@ -103,26 +103,26 @@ apiClient.interceptors.response.use(
|
|
| 103 |
headers: error.response?.headers
|
| 104 |
});
|
| 105 |
}
|
| 106 |
-
|
| 107 |
// Handle 401 Unauthorized errors
|
| 108 |
if (error.response?.status === 401) {
|
| 109 |
if (isDevelopment) {
|
| 110 |
console.log('π [Auth] 401 error detected, attempting token refresh');
|
| 111 |
}
|
| 112 |
-
|
| 113 |
// If we haven't retried this request yet
|
| 114 |
if (!originalRequest._retry) {
|
| 115 |
originalRequest._retry = true;
|
| 116 |
-
|
| 117 |
try {
|
| 118 |
// Clear all authentication data
|
| 119 |
await cookieService.clearAuthTokens();
|
| 120 |
localStorage.removeItem('token');
|
| 121 |
-
|
| 122 |
if (isDevelopment) {
|
| 123 |
console.log('π [Auth] Cleared all authentication data');
|
| 124 |
}
|
| 125 |
-
|
| 126 |
// Redirect to login page
|
| 127 |
const currentPath = window.location.pathname;
|
| 128 |
if (currentPath !== '/login' && currentPath !== '/register') {
|
|
@@ -131,22 +131,22 @@ apiClient.interceptors.response.use(
|
|
| 131 |
}
|
| 132 |
window.location.href = '/login';
|
| 133 |
}
|
| 134 |
-
|
| 135 |
} catch (refreshError) {
|
| 136 |
if (isDevelopment) {
|
| 137 |
console.error('π [Auth] Error during token refresh:', refreshError);
|
| 138 |
}
|
| 139 |
-
|
| 140 |
// Even if refresh fails, clear auth data
|
| 141 |
await cookieService.clearAuthTokens();
|
| 142 |
localStorage.removeItem('token');
|
| 143 |
window.location.href = '/login';
|
| 144 |
-
|
| 145 |
return Promise.reject(refreshError);
|
| 146 |
}
|
| 147 |
}
|
| 148 |
}
|
| 149 |
-
|
| 150 |
// Handle network errors
|
| 151 |
if (!error.response) {
|
| 152 |
if (isDevelopment) {
|
|
@@ -155,12 +155,12 @@ apiClient.interceptors.response.use(
|
|
| 155 |
message: error.message
|
| 156 |
});
|
| 157 |
}
|
| 158 |
-
|
| 159 |
// You might want to implement offline mode here
|
| 160 |
// For now, just reject the error
|
| 161 |
return Promise.reject(error);
|
| 162 |
}
|
| 163 |
-
|
| 164 |
return Promise.reject(error);
|
| 165 |
}
|
| 166 |
);
|
|
|
|
| 4 |
// Create axios instance with default config
|
| 5 |
const API_BASE_URL = import.meta.env.VITE_API_URL ||
|
| 6 |
(import.meta.env.VITE_NODE_ENV === 'production' ?
|
| 7 |
+
'http://46.62.218.169' :
|
| 8 |
'http://localhost:5000');
|
| 9 |
console.log('API_BASE_URL:', API_BASE_URL);
|
| 10 |
|
|
|
|
| 32 |
headers: config.headers,
|
| 33 |
data: config.data
|
| 34 |
});
|
| 35 |
+
|
| 36 |
// Special logging for auth requests to verify field transformation
|
| 37 |
if (config.url?.includes('/auth/register')) {
|
| 38 |
console.log('π [Auth Register] Request data verification:', {
|
|
|
|
| 43 |
});
|
| 44 |
}
|
| 45 |
}
|
| 46 |
+
|
| 47 |
// Get token from cookie service with fallback to localStorage
|
| 48 |
let token = null;
|
| 49 |
try {
|
|
|
|
| 53 |
console.warn('πͺ [Cookie] Error getting auth tokens, trying localStorage:', error.message);
|
| 54 |
token = localStorage.getItem('token');
|
| 55 |
}
|
| 56 |
+
|
| 57 |
if (token) {
|
| 58 |
config.headers.Authorization = `Bearer ${token}`;
|
| 59 |
if (isDevelopment) {
|
|
|
|
| 64 |
console.log('π [Token] No token found for request');
|
| 65 |
}
|
| 66 |
}
|
| 67 |
+
|
| 68 |
return config;
|
| 69 |
},
|
| 70 |
(error) => {
|
|
|
|
| 91 |
async (error) => {
|
| 92 |
const isDevelopment = import.meta.env.VITE_NODE_ENV === 'development';
|
| 93 |
const originalRequest = error.config;
|
| 94 |
+
|
| 95 |
// Enhanced error logging
|
| 96 |
if (isDevelopment) {
|
| 97 |
console.error('β [API Response Error]', {
|
|
|
|
| 103 |
headers: error.response?.headers
|
| 104 |
});
|
| 105 |
}
|
| 106 |
+
|
| 107 |
// Handle 401 Unauthorized errors
|
| 108 |
if (error.response?.status === 401) {
|
| 109 |
if (isDevelopment) {
|
| 110 |
console.log('π [Auth] 401 error detected, attempting token refresh');
|
| 111 |
}
|
| 112 |
+
|
| 113 |
// If we haven't retried this request yet
|
| 114 |
if (!originalRequest._retry) {
|
| 115 |
originalRequest._retry = true;
|
| 116 |
+
|
| 117 |
try {
|
| 118 |
// Clear all authentication data
|
| 119 |
await cookieService.clearAuthTokens();
|
| 120 |
localStorage.removeItem('token');
|
| 121 |
+
|
| 122 |
if (isDevelopment) {
|
| 123 |
console.log('π [Auth] Cleared all authentication data');
|
| 124 |
}
|
| 125 |
+
|
| 126 |
// Redirect to login page
|
| 127 |
const currentPath = window.location.pathname;
|
| 128 |
if (currentPath !== '/login' && currentPath !== '/register') {
|
|
|
|
| 131 |
}
|
| 132 |
window.location.href = '/login';
|
| 133 |
}
|
| 134 |
+
|
| 135 |
} catch (refreshError) {
|
| 136 |
if (isDevelopment) {
|
| 137 |
console.error('π [Auth] Error during token refresh:', refreshError);
|
| 138 |
}
|
| 139 |
+
|
| 140 |
// Even if refresh fails, clear auth data
|
| 141 |
await cookieService.clearAuthTokens();
|
| 142 |
localStorage.removeItem('token');
|
| 143 |
window.location.href = '/login';
|
| 144 |
+
|
| 145 |
return Promise.reject(refreshError);
|
| 146 |
}
|
| 147 |
}
|
| 148 |
}
|
| 149 |
+
|
| 150 |
// Handle network errors
|
| 151 |
if (!error.response) {
|
| 152 |
if (isDevelopment) {
|
|
|
|
| 155 |
message: error.message
|
| 156 |
});
|
| 157 |
}
|
| 158 |
+
|
| 159 |
// You might want to implement offline mode here
|
| 160 |
// For now, just reject the error
|
| 161 |
return Promise.reject(error);
|
| 162 |
}
|
| 163 |
+
|
| 164 |
return Promise.reject(error);
|
| 165 |
}
|
| 166 |
);
|
frontend/test-auth-fix.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
| 1 |
/**
|
| 2 |
* Authentication Fix Test Script
|
| 3 |
-
* This script tests the authentication fixes for
|
| 4 |
*/
|
| 5 |
|
| 6 |
// Test configuration
|
| 7 |
const testConfig = {
|
| 8 |
production: {
|
| 9 |
-
apiUrl: '
|
| 10 |
expectedCookieSameSite: 'Lax',
|
| 11 |
-
expectedCookieSecure:
|
| 12 |
-
expectedCorsOrigin: '
|
| 13 |
},
|
| 14 |
development: {
|
| 15 |
apiUrl: 'http://localhost:5000/api',
|
|
@@ -25,98 +25,98 @@ console.log('=================================');
|
|
| 25 |
// Test 1: Environment Detection
|
| 26 |
function testEnvironmentDetection() {
|
| 27 |
console.log('\nπ Test 1: Environment Detection');
|
| 28 |
-
|
| 29 |
const env = import.meta.env?.VITE_NODE_ENV || 'development';
|
| 30 |
console.log(`Current environment: ${env}`);
|
| 31 |
-
|
| 32 |
if (env === 'production') {
|
| 33 |
console.log('β
Production environment detected');
|
| 34 |
console.log(' - Cookie sameSite should be: Lax');
|
| 35 |
-
console.log(' - Cookie secure should be:
|
| 36 |
} else {
|
| 37 |
console.log('β
Development environment detected');
|
| 38 |
console.log(' - Cookie sameSite should be: Strict');
|
| 39 |
console.log(' - Cookie secure should be: false');
|
| 40 |
}
|
| 41 |
-
|
| 42 |
return env;
|
| 43 |
}
|
| 44 |
|
| 45 |
// Test 2: API URL Configuration
|
| 46 |
function testApiUrlConfiguration() {
|
| 47 |
console.log('\nπ Test 2: API URL Configuration');
|
| 48 |
-
|
| 49 |
const apiUrl = import.meta.env?.VITE_API_URL || 'http://localhost:5000/api';
|
| 50 |
console.log(`API URL: ${apiUrl}`);
|
| 51 |
-
|
| 52 |
-
if (apiUrl.includes('
|
| 53 |
console.log('β
Production API URL detected');
|
| 54 |
-
console.log(' - Should use:
|
| 55 |
} else {
|
| 56 |
console.log('β
Development API URL detected');
|
| 57 |
console.log(' - Should use: http://localhost:5000/api');
|
| 58 |
}
|
| 59 |
-
|
| 60 |
return apiUrl;
|
| 61 |
}
|
| 62 |
|
| 63 |
// Test 3: Cookie Service Configuration
|
| 64 |
function testCookieServiceConfiguration() {
|
| 65 |
console.log('\nπ Test 3: Cookie Service Configuration');
|
| 66 |
-
|
| 67 |
// Simulate the cookie service logic
|
| 68 |
const isProduction = import.meta.env?.VITE_NODE_ENV === 'production';
|
| 69 |
const sameSitePolicy = isProduction ? 'Lax' : 'Strict';
|
| 70 |
-
const secureFlag = isProduction;
|
| 71 |
-
|
| 72 |
console.log(`Cookie sameSite policy: ${sameSitePolicy}`);
|
| 73 |
console.log(`Cookie secure flag: ${secureFlag}`);
|
| 74 |
-
|
| 75 |
-
if (isProduction && sameSitePolicy === 'Lax' && secureFlag ===
|
| 76 |
-
console.log('β
Production cookie configuration is correct');
|
| 77 |
} else if (!isProduction && sameSitePolicy === 'Strict' && secureFlag === false) {
|
| 78 |
console.log('β
Development cookie configuration is correct');
|
| 79 |
} else {
|
| 80 |
console.log('β Cookie configuration is incorrect');
|
| 81 |
return false;
|
| 82 |
}
|
| 83 |
-
|
| 84 |
return true;
|
| 85 |
}
|
| 86 |
|
| 87 |
// Test 4: CORS Configuration Check
|
| 88 |
function testCorsConfiguration() {
|
| 89 |
console.log('\nπ Test 4: CORS Configuration Check');
|
| 90 |
-
|
| 91 |
const env = import.meta.env?.VITE_NODE_ENV || 'development';
|
| 92 |
-
const expectedOrigin = env === 'production'
|
| 93 |
-
? '
|
| 94 |
: 'http://localhost:3000';
|
| 95 |
-
|
| 96 |
console.log(`Expected CORS origin: ${expectedOrigin}`);
|
| 97 |
console.log('β
CORS configuration should include this origin');
|
| 98 |
-
|
| 99 |
return expectedOrigin;
|
| 100 |
}
|
| 101 |
|
| 102 |
// Test 5: Authentication Flow Simulation
|
| 103 |
function testAuthenticationFlow() {
|
| 104 |
console.log('\nπ Test 5: Authentication Flow Simulation');
|
| 105 |
-
|
| 106 |
console.log('1. User attempts to login...');
|
| 107 |
console.log(' - Should send credentials to /api/auth/login');
|
| 108 |
console.log(' - Server should validate and return JWT token');
|
| 109 |
-
|
| 110 |
console.log('2. Token should be stored in cookies with:');
|
| 111 |
console.log(' - SameSite: Lax (production) / Strict (development)');
|
| 112 |
-
console.log(' - Secure:
|
| 113 |
console.log(' - HttpOnly: true');
|
| 114 |
-
|
| 115 |
console.log('3. Page reload should:');
|
| 116 |
console.log(' - Send cookies with requests');
|
| 117 |
console.log(' - Server should validate JWT token');
|
| 118 |
console.log(' - Return user data if valid');
|
| 119 |
-
|
| 120 |
console.log('β
Authentication flow simulation complete');
|
| 121 |
return true;
|
| 122 |
}
|
|
@@ -124,13 +124,13 @@ function testAuthenticationFlow() {
|
|
| 124 |
// Test 6: Error Handling
|
| 125 |
function testErrorHandling() {
|
| 126 |
console.log('\nπ Test 6: Error Handling');
|
| 127 |
-
|
| 128 |
console.log('Expected error scenarios:');
|
| 129 |
console.log('1. Invalid token β Should redirect to login');
|
| 130 |
console.log('2. Expired token β Should clear cookies and redirect');
|
| 131 |
console.log('3. Network error β Should show appropriate error message');
|
| 132 |
console.log('4. CORS error β Should be handled gracefully');
|
| 133 |
-
|
| 134 |
console.log('β
Error handling configuration complete');
|
| 135 |
return true;
|
| 136 |
}
|
|
@@ -138,7 +138,7 @@ function testErrorHandling() {
|
|
| 138 |
// Main test runner
|
| 139 |
function runTests() {
|
| 140 |
console.log('π Starting authentication fix tests...\n');
|
| 141 |
-
|
| 142 |
try {
|
| 143 |
const env = testEnvironmentDetection();
|
| 144 |
const apiUrl = testApiUrlConfiguration();
|
|
@@ -146,7 +146,7 @@ function runTests() {
|
|
| 146 |
const corsOrigin = testCorsConfiguration();
|
| 147 |
const authFlow = testAuthenticationFlow();
|
| 148 |
const errorHandling = testErrorHandling();
|
| 149 |
-
|
| 150 |
console.log('\nπ― Test Results Summary:');
|
| 151 |
console.log('========================');
|
| 152 |
console.log(`Environment: ${env}`);
|
|
@@ -155,17 +155,17 @@ function runTests() {
|
|
| 155 |
console.log(`CORS Origin: ${corsOrigin}`);
|
| 156 |
console.log(`Auth Flow: ${authFlow ? 'β
' : 'β'}`);
|
| 157 |
console.log(`Error Handling: ${errorHandling ? 'β
' : 'β'}`);
|
| 158 |
-
|
| 159 |
if (cookieConfig && authFlow && errorHandling) {
|
| 160 |
console.log('\nπ All tests passed! Authentication fix should work correctly.');
|
| 161 |
console.log('\nπ Next Steps:');
|
| 162 |
console.log('1. Build the frontend: npm run build');
|
| 163 |
-
console.log('2. Deploy
|
| 164 |
console.log('3. Test login and page reload functionality');
|
| 165 |
} else {
|
| 166 |
console.log('\nβ οΈ Some tests failed. Please review the configuration.');
|
| 167 |
}
|
| 168 |
-
|
| 169 |
} catch (error) {
|
| 170 |
console.error('\nβ Test execution failed:', error);
|
| 171 |
}
|
|
|
|
| 1 |
/**
|
| 2 |
* Authentication Fix Test Script
|
| 3 |
+
* This script tests the authentication fixes for server IP deployment
|
| 4 |
*/
|
| 5 |
|
| 6 |
// Test configuration
|
| 7 |
const testConfig = {
|
| 8 |
production: {
|
| 9 |
+
apiUrl: 'http://46.62.218.169/api',
|
| 10 |
expectedCookieSameSite: 'Lax',
|
| 11 |
+
expectedCookieSecure: false, // Set to false for HTTP server
|
| 12 |
+
expectedCorsOrigin: 'http://46.62.218.169'
|
| 13 |
},
|
| 14 |
development: {
|
| 15 |
apiUrl: 'http://localhost:5000/api',
|
|
|
|
| 25 |
// Test 1: Environment Detection
|
| 26 |
function testEnvironmentDetection() {
|
| 27 |
console.log('\nπ Test 1: Environment Detection');
|
| 28 |
+
|
| 29 |
const env = import.meta.env?.VITE_NODE_ENV || 'development';
|
| 30 |
console.log(`Current environment: ${env}`);
|
| 31 |
+
|
| 32 |
if (env === 'production') {
|
| 33 |
console.log('β
Production environment detected');
|
| 34 |
console.log(' - Cookie sameSite should be: Lax');
|
| 35 |
+
console.log(' - Cookie secure should be: false (HTTP server)');
|
| 36 |
} else {
|
| 37 |
console.log('β
Development environment detected');
|
| 38 |
console.log(' - Cookie sameSite should be: Strict');
|
| 39 |
console.log(' - Cookie secure should be: false');
|
| 40 |
}
|
| 41 |
+
|
| 42 |
return env;
|
| 43 |
}
|
| 44 |
|
| 45 |
// Test 2: API URL Configuration
|
| 46 |
function testApiUrlConfiguration() {
|
| 47 |
console.log('\nπ Test 2: API URL Configuration');
|
| 48 |
+
|
| 49 |
const apiUrl = import.meta.env?.VITE_API_URL || 'http://localhost:5000/api';
|
| 50 |
console.log(`API URL: ${apiUrl}`);
|
| 51 |
+
|
| 52 |
+
if (apiUrl.includes('46.62.218.169')) {
|
| 53 |
console.log('β
Production API URL detected');
|
| 54 |
+
console.log(' - Should use: http://46.62.218.169/api');
|
| 55 |
} else {
|
| 56 |
console.log('β
Development API URL detected');
|
| 57 |
console.log(' - Should use: http://localhost:5000/api');
|
| 58 |
}
|
| 59 |
+
|
| 60 |
return apiUrl;
|
| 61 |
}
|
| 62 |
|
| 63 |
// Test 3: Cookie Service Configuration
|
| 64 |
function testCookieServiceConfiguration() {
|
| 65 |
console.log('\nπ Test 3: Cookie Service Configuration');
|
| 66 |
+
|
| 67 |
// Simulate the cookie service logic
|
| 68 |
const isProduction = import.meta.env?.VITE_NODE_ENV === 'production';
|
| 69 |
const sameSitePolicy = isProduction ? 'Lax' : 'Strict';
|
| 70 |
+
const secureFlag = isProduction ? false : false; // Set to false for HTTP server
|
| 71 |
+
|
| 72 |
console.log(`Cookie sameSite policy: ${sameSitePolicy}`);
|
| 73 |
console.log(`Cookie secure flag: ${secureFlag}`);
|
| 74 |
+
|
| 75 |
+
if (isProduction && sameSitePolicy === 'Lax' && secureFlag === false) {
|
| 76 |
+
console.log('β
Production cookie configuration is correct (HTTP server)');
|
| 77 |
} else if (!isProduction && sameSitePolicy === 'Strict' && secureFlag === false) {
|
| 78 |
console.log('β
Development cookie configuration is correct');
|
| 79 |
} else {
|
| 80 |
console.log('β Cookie configuration is incorrect');
|
| 81 |
return false;
|
| 82 |
}
|
| 83 |
+
|
| 84 |
return true;
|
| 85 |
}
|
| 86 |
|
| 87 |
// Test 4: CORS Configuration Check
|
| 88 |
function testCorsConfiguration() {
|
| 89 |
console.log('\nπ Test 4: CORS Configuration Check');
|
| 90 |
+
|
| 91 |
const env = import.meta.env?.VITE_NODE_ENV || 'development';
|
| 92 |
+
const expectedOrigin = env === 'production'
|
| 93 |
+
? 'http://46.62.218.169'
|
| 94 |
: 'http://localhost:3000';
|
| 95 |
+
|
| 96 |
console.log(`Expected CORS origin: ${expectedOrigin}`);
|
| 97 |
console.log('β
CORS configuration should include this origin');
|
| 98 |
+
|
| 99 |
return expectedOrigin;
|
| 100 |
}
|
| 101 |
|
| 102 |
// Test 5: Authentication Flow Simulation
|
| 103 |
function testAuthenticationFlow() {
|
| 104 |
console.log('\nπ Test 5: Authentication Flow Simulation');
|
| 105 |
+
|
| 106 |
console.log('1. User attempts to login...');
|
| 107 |
console.log(' - Should send credentials to /api/auth/login');
|
| 108 |
console.log(' - Server should validate and return JWT token');
|
| 109 |
+
|
| 110 |
console.log('2. Token should be stored in cookies with:');
|
| 111 |
console.log(' - SameSite: Lax (production) / Strict (development)');
|
| 112 |
+
console.log(' - Secure: false (HTTP server) / false (development)');
|
| 113 |
console.log(' - HttpOnly: true');
|
| 114 |
+
|
| 115 |
console.log('3. Page reload should:');
|
| 116 |
console.log(' - Send cookies with requests');
|
| 117 |
console.log(' - Server should validate JWT token');
|
| 118 |
console.log(' - Return user data if valid');
|
| 119 |
+
|
| 120 |
console.log('β
Authentication flow simulation complete');
|
| 121 |
return true;
|
| 122 |
}
|
|
|
|
| 124 |
// Test 6: Error Handling
|
| 125 |
function testErrorHandling() {
|
| 126 |
console.log('\nπ Test 6: Error Handling');
|
| 127 |
+
|
| 128 |
console.log('Expected error scenarios:');
|
| 129 |
console.log('1. Invalid token β Should redirect to login');
|
| 130 |
console.log('2. Expired token β Should clear cookies and redirect');
|
| 131 |
console.log('3. Network error β Should show appropriate error message');
|
| 132 |
console.log('4. CORS error β Should be handled gracefully');
|
| 133 |
+
|
| 134 |
console.log('β
Error handling configuration complete');
|
| 135 |
return true;
|
| 136 |
}
|
|
|
|
| 138 |
// Main test runner
|
| 139 |
function runTests() {
|
| 140 |
console.log('π Starting authentication fix tests...\n');
|
| 141 |
+
|
| 142 |
try {
|
| 143 |
const env = testEnvironmentDetection();
|
| 144 |
const apiUrl = testApiUrlConfiguration();
|
|
|
|
| 146 |
const corsOrigin = testCorsConfiguration();
|
| 147 |
const authFlow = testAuthenticationFlow();
|
| 148 |
const errorHandling = testErrorHandling();
|
| 149 |
+
|
| 150 |
console.log('\nπ― Test Results Summary:');
|
| 151 |
console.log('========================');
|
| 152 |
console.log(`Environment: ${env}`);
|
|
|
|
| 155 |
console.log(`CORS Origin: ${corsOrigin}`);
|
| 156 |
console.log(`Auth Flow: ${authFlow ? 'β
' : 'β'}`);
|
| 157 |
console.log(`Error Handling: ${errorHandling ? 'β
' : 'β'}`);
|
| 158 |
+
|
| 159 |
if (cookieConfig && authFlow && errorHandling) {
|
| 160 |
console.log('\nπ All tests passed! Authentication fix should work correctly.');
|
| 161 |
console.log('\nπ Next Steps:');
|
| 162 |
console.log('1. Build the frontend: npm run build');
|
| 163 |
+
console.log('2. Deploy with correct server IP configuration');
|
| 164 |
console.log('3. Test login and page reload functionality');
|
| 165 |
} else {
|
| 166 |
console.log('\nβ οΈ Some tests failed. Please review the configuration.');
|
| 167 |
}
|
| 168 |
+
|
| 169 |
} catch (error) {
|
| 170 |
console.error('\nβ Test execution failed:', error);
|
| 171 |
}
|