add changes

This commit is contained in:
AD2025
2025-12-26 23:56:32 +02:00
parent 410c3d725f
commit e7d26bc981
127 changed files with 36162 additions and 0 deletions

314
tests/test-logout-verify.js Normal file
View File

@@ -0,0 +1,314 @@
/**
* Manual Test Script for Logout and Token Verification
* Task 14: User Logout & Token Verification
*
* Run this script with: node test-logout-verify.js
* Make sure the server is running on http://localhost:3000
*/
const axios = require('axios');
const API_BASE = 'http://localhost:3000/api';
let testToken = null;
let testUserId = null;
// Helper function for test output
function logTest(testNumber, description) {
console.log(`\n${'='.repeat(60)}`);
console.log(`${testNumber} Testing ${description}`);
console.log('='.repeat(60));
}
function logSuccess(message) {
console.log(`✅ SUCCESS: ${message}`);
}
function logError(message, error = null) {
console.log(`❌ ERROR: ${message}`);
if (error) {
if (error.response && error.response.data) {
console.log(`Response status: ${error.response.status}`);
console.log(`Response data:`, JSON.stringify(error.response.data, null, 2));
} else if (error.message) {
console.log(`Error details: ${error.message}`);
} else {
console.log(`Error:`, error);
}
}
}
// Test 1: Register a test user to get a token
async function test1_RegisterUser() {
logTest('1⃣', 'POST /api/auth/register - Get test token');
try {
const userData = {
username: `testuser${Date.now()}`,
email: `test${Date.now()}@example.com`,
password: 'Test@123'
};
console.log('Request:', JSON.stringify(userData, null, 2));
const response = await axios.post(`${API_BASE}/auth/register`, userData);
console.log('Response:', JSON.stringify(response.data, null, 2));
if (response.data.success && response.data.data.token) {
testToken = response.data.data.token;
testUserId = response.data.data.user.id;
logSuccess('User registered successfully, token obtained');
console.log('Token:', testToken.substring(0, 50) + '...');
} else {
logError('Failed to get token from registration');
}
} catch (error) {
logError('Registration failed', error);
}
}
// Test 2: Verify the token
async function test2_VerifyValidToken() {
logTest('2⃣', 'GET /api/auth/verify - Verify valid token');
if (!testToken) {
logError('No token available. Skipping test.');
return;
}
try {
const response = await axios.get(`${API_BASE}/auth/verify`, {
headers: {
'Authorization': `Bearer ${testToken}`
}
});
console.log('Response:', JSON.stringify(response.data, null, 2));
if (response.data.success && response.data.data.user) {
logSuccess('Token verified successfully');
console.log('User ID:', response.data.data.user.id);
console.log('Username:', response.data.data.user.username);
console.log('Email:', response.data.data.user.email);
console.log('Password exposed?', response.data.data.user.password ? 'YES ❌' : 'NO ✅');
} else {
logError('Token verification returned unexpected response');
}
} catch (error) {
logError('Token verification failed', error.response?.data || error.message);
}
}
// Test 3: Verify without token
async function test3_VerifyWithoutToken() {
logTest('3⃣', 'GET /api/auth/verify - Without token (should fail)');
try {
const response = await axios.get(`${API_BASE}/auth/verify`);
console.log('Response:', JSON.stringify(response.data, null, 2));
logError('Should have rejected request without token');
} catch (error) {
if (error.response && error.response.status === 401) {
console.log('Response:', JSON.stringify(error.response.data, null, 2));
logSuccess('Correctly rejected request without token (401)');
} else {
logError('Unexpected error', error.message);
}
}
}
// Test 4: Verify with invalid token
async function test4_VerifyInvalidToken() {
logTest('4⃣', 'GET /api/auth/verify - Invalid token (should fail)');
try {
const response = await axios.get(`${API_BASE}/auth/verify`, {
headers: {
'Authorization': 'Bearer invalid_token_here'
}
});
console.log('Response:', JSON.stringify(response.data, null, 2));
logError('Should have rejected invalid token');
} catch (error) {
if (error.response && error.response.status === 401) {
console.log('Response:', JSON.stringify(error.response.data, null, 2));
logSuccess('Correctly rejected invalid token (401)');
} else {
logError('Unexpected error', error.message);
}
}
}
// Test 5: Verify with malformed Authorization header
async function test5_VerifyMalformedHeader() {
logTest('5⃣', 'GET /api/auth/verify - Malformed header (should fail)');
if (!testToken) {
logError('No token available. Skipping test.');
return;
}
try {
const response = await axios.get(`${API_BASE}/auth/verify`, {
headers: {
'Authorization': testToken // Missing "Bearer " prefix
}
});
console.log('Response:', JSON.stringify(response.data, null, 2));
logError('Should have rejected malformed header');
} catch (error) {
if (error.response && error.response.status === 401) {
console.log('Response:', JSON.stringify(error.response.data, null, 2));
logSuccess('Correctly rejected malformed header (401)');
} else {
logError('Unexpected error', error.message);
}
}
}
// Test 6: Logout
async function test6_Logout() {
logTest('6⃣', 'POST /api/auth/logout - Logout');
try {
const response = await axios.post(`${API_BASE}/auth/logout`);
console.log('Response:', JSON.stringify(response.data, null, 2));
if (response.data.success) {
logSuccess('Logout successful (stateless JWT approach)');
} else {
logError('Logout returned unexpected response');
}
} catch (error) {
logError('Logout failed', error.response?.data || error.message);
}
}
// Test 7: Verify token still works after logout (JWT is stateless)
async function test7_VerifyAfterLogout() {
logTest('7⃣', 'GET /api/auth/verify - After logout (should still work)');
if (!testToken) {
logError('No token available. Skipping test.');
return;
}
try {
const response = await axios.get(`${API_BASE}/auth/verify`, {
headers: {
'Authorization': `Bearer ${testToken}`
}
});
console.log('Response:', JSON.stringify(response.data, null, 2));
if (response.data.success) {
logSuccess('Token still valid after logout (expected for stateless JWT)');
console.log('Note: In production, client should delete the token on logout');
} else {
logError('Token verification failed unexpectedly');
}
} catch (error) {
logError('Token verification failed', error.response?.data || error.message);
}
}
// Test 8: Login and verify new token
async function test8_LoginAndVerify() {
logTest('8⃣', 'POST /api/auth/login + GET /api/auth/verify - Full flow');
try {
// First, we need to use the registered user's credentials
// Get the email from the first test
const loginData = {
email: `test_${testUserId ? testUserId.split('-')[0] : ''}@example.com`,
password: 'Test@123'
};
// This might fail if we don't have the exact email, so let's just create a new user
const registerData = {
username: `logintest${Date.now()}`,
email: `logintest${Date.now()}@example.com`,
password: 'Test@123'
};
console.log('Registering new user for login test...');
const registerResponse = await axios.post(`${API_BASE}/auth/register`, registerData);
const userEmail = registerResponse.data.data.user.email;
console.log('Logging in...');
const loginResponse = await axios.post(`${API_BASE}/auth/login`, {
email: userEmail,
password: 'Test@123'
});
console.log('Login Response:', JSON.stringify(loginResponse.data, null, 2));
const loginToken = loginResponse.data.data.token;
console.log('\nVerifying login token...');
const verifyResponse = await axios.get(`${API_BASE}/auth/verify`, {
headers: {
'Authorization': `Bearer ${loginToken}`
}
});
console.log('Verify Response:', JSON.stringify(verifyResponse.data, null, 2));
if (verifyResponse.data.success) {
logSuccess('Login and token verification flow completed successfully');
} else {
logError('Token verification failed after login');
}
} catch (error) {
logError('Login and verify flow failed', error);
}
}
// Run all tests
async function runAllTests() {
console.log('\n');
console.log('╔════════════════════════════════════════════════════════════╗');
console.log('║ Logout & Token Verification Endpoint Tests (Task 14) ║');
console.log('╚════════════════════════════════════════════════════════════╝');
console.log('\nMake sure the server is running on http://localhost:3000\n');
await test1_RegisterUser();
await new Promise(resolve => setTimeout(resolve, 500)); // Small delay
await test2_VerifyValidToken();
await new Promise(resolve => setTimeout(resolve, 500));
await test3_VerifyWithoutToken();
await new Promise(resolve => setTimeout(resolve, 500));
await test4_VerifyInvalidToken();
await new Promise(resolve => setTimeout(resolve, 500));
await test5_VerifyMalformedHeader();
await new Promise(resolve => setTimeout(resolve, 500));
await test6_Logout();
await new Promise(resolve => setTimeout(resolve, 500));
await test7_VerifyAfterLogout();
await new Promise(resolve => setTimeout(resolve, 500));
await test8_LoginAndVerify();
console.log('\n');
console.log('╔════════════════════════════════════════════════════════════╗');
console.log('║ All Tests Completed ║');
console.log('╚════════════════════════════════════════════════════════════╝');
console.log('\n');
}
// Run tests
runAllTests().catch(error => {
console.error('\n❌ Fatal error running tests:', error);
process.exit(1);
});