feat: add authentication test page and API testing scripts; implement debug auth endpoint and enhance task route with read permissions
This commit is contained in:
206
test-logged-in-flow.mjs
Normal file
206
test-logged-in-flow.mjs
Normal file
@@ -0,0 +1,206 @@
|
||||
// Test authenticated flow without external dependencies
|
||||
|
||||
const BASE_URL = 'http://localhost:3000';
|
||||
|
||||
// Test data
|
||||
const TEST_CREDENTIALS = {
|
||||
email: 'admin@localhost.com',
|
||||
password: 'admin123456'
|
||||
};
|
||||
|
||||
// Helper function to extract cookies from response
|
||||
function extractCookies(response) {
|
||||
const cookies = response.headers.raw()['set-cookie'];
|
||||
if (!cookies) return '';
|
||||
|
||||
return cookies
|
||||
.map(cookie => cookie.split(';')[0])
|
||||
.join('; ');
|
||||
}
|
||||
|
||||
// Helper function to make authenticated requests
|
||||
async function makeAuthenticatedRequest(url, options = {}, cookies = '') {
|
||||
return fetch(url, {
|
||||
...options,
|
||||
headers: {
|
||||
'Cookie': cookies,
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function testCompleteAuthenticatedFlow() {
|
||||
console.log('🔐 Testing Complete Authenticated Flow\n');
|
||||
|
||||
try {
|
||||
// Step 1: Get CSRF token from sign-in page
|
||||
console.log('1️⃣ Getting CSRF token...');
|
||||
const signinResponse = await fetch(`${BASE_URL}/auth/signin`);
|
||||
const signinHtml = await signinResponse.text();
|
||||
|
||||
// Extract CSRF token (NextAuth.js typically includes it in the form)
|
||||
const csrfMatch = signinHtml.match(/name="csrfToken" value="([^"]+)"/);
|
||||
const csrfToken = csrfMatch ? csrfMatch[1] : null;
|
||||
|
||||
if (!csrfToken) {
|
||||
console.log('❌ Could not extract CSRF token');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('✅ CSRF token extracted');
|
||||
const initialCookies = extractCookies(signinResponse);
|
||||
|
||||
// Step 2: Attempt login
|
||||
console.log('\n2️⃣ Attempting login...');
|
||||
const loginResponse = await fetch(`${BASE_URL}/api/auth/callback/credentials`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Cookie': initialCookies
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
csrfToken,
|
||||
email: TEST_CREDENTIALS.email,
|
||||
password: TEST_CREDENTIALS.password,
|
||||
callbackUrl: `${BASE_URL}/projects`,
|
||||
json: 'true'
|
||||
}),
|
||||
redirect: 'manual'
|
||||
});
|
||||
|
||||
console.log(`Login response status: ${loginResponse.status}`);
|
||||
|
||||
if (loginResponse.status === 200) {
|
||||
const loginResult = await loginResponse.json();
|
||||
console.log('Login result:', loginResult);
|
||||
|
||||
if (loginResult.url) {
|
||||
console.log('✅ Login successful, redirecting to:', loginResult.url);
|
||||
} else if (loginResult.error) {
|
||||
console.log('❌ Login failed:', loginResult.error);
|
||||
return;
|
||||
}
|
||||
} else if (loginResponse.status === 302) {
|
||||
console.log('✅ Login successful (redirect)');
|
||||
} else {
|
||||
console.log('❌ Login failed with status:', loginResponse.status);
|
||||
const errorText = await loginResponse.text();
|
||||
console.log('Error response:', errorText.substring(0, 500));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get session cookies
|
||||
const sessionCookies = extractCookies(loginResponse) || initialCookies;
|
||||
console.log('Session cookies:', sessionCookies ? 'Present' : 'Missing');
|
||||
|
||||
// Step 3: Test session endpoint
|
||||
console.log('\n3️⃣ Testing session endpoint...');
|
||||
const sessionResponse = await makeAuthenticatedRequest(
|
||||
`${BASE_URL}/api/auth/session`,
|
||||
{},
|
||||
sessionCookies
|
||||
);
|
||||
|
||||
if (sessionResponse.ok) {
|
||||
const session = await sessionResponse.json();
|
||||
console.log('✅ Session data:', JSON.stringify(session, null, 2));
|
||||
} else {
|
||||
console.log('❌ Session check failed:', sessionResponse.status);
|
||||
}
|
||||
|
||||
// Step 4: Test protected pages
|
||||
console.log('\n4️⃣ Testing protected pages...');
|
||||
const protectedPages = ['/projects', '/contracts', '/tasks'];
|
||||
|
||||
for (const page of protectedPages) {
|
||||
const pageResponse = await makeAuthenticatedRequest(
|
||||
`${BASE_URL}${page}`,
|
||||
{},
|
||||
sessionCookies
|
||||
);
|
||||
|
||||
if (pageResponse.ok) {
|
||||
console.log(`✅ ${page} - accessible`);
|
||||
} else if (pageResponse.status === 302) {
|
||||
console.log(`⚠️ ${page} - redirected (status: 302)`);
|
||||
} else {
|
||||
console.log(`❌ ${page} - failed (status: ${pageResponse.status})`);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 5: Test API endpoints
|
||||
console.log('\n5️⃣ Testing API endpoints...');
|
||||
const apiEndpoints = [
|
||||
{ url: '/api/projects', method: 'GET' },
|
||||
{ url: '/api/contracts', method: 'GET' },
|
||||
{ url: '/api/tasks', method: 'GET' },
|
||||
{ url: '/api/tasks/templates', method: 'GET' }
|
||||
];
|
||||
|
||||
for (const endpoint of apiEndpoints) {
|
||||
const apiResponse = await makeAuthenticatedRequest(
|
||||
`${BASE_URL}${endpoint.url}`,
|
||||
{ method: endpoint.method },
|
||||
sessionCookies
|
||||
);
|
||||
|
||||
if (apiResponse.ok) {
|
||||
const data = await apiResponse.json();
|
||||
console.log(`✅ ${endpoint.method} ${endpoint.url} - success (${Array.isArray(data) ? data.length : 'object'} items)`);
|
||||
} else if (apiResponse.status === 401) {
|
||||
console.log(`❌ ${endpoint.method} ${endpoint.url} - unauthorized (status: 401)`);
|
||||
} else {
|
||||
console.log(`❌ ${endpoint.method} ${endpoint.url} - failed (status: ${apiResponse.status})`);
|
||||
const errorText = await apiResponse.text();
|
||||
console.log(` Error: ${errorText.substring(0, 200)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 6: Test creating data
|
||||
console.log('\n6️⃣ Testing data creation...');
|
||||
|
||||
// Test creating a project
|
||||
const projectData = {
|
||||
name: 'Test Project Auth',
|
||||
description: 'Testing authentication flow',
|
||||
deadline: '2025-12-31',
|
||||
status: 'active'
|
||||
};
|
||||
|
||||
const createProjectResponse = await makeAuthenticatedRequest(
|
||||
`${BASE_URL}/api/projects`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(projectData)
|
||||
},
|
||||
sessionCookies
|
||||
);
|
||||
|
||||
if (createProjectResponse.ok) {
|
||||
const newProject = await createProjectResponse.json();
|
||||
console.log('✅ Project creation successful:', newProject.name);
|
||||
|
||||
// Clean up - delete the test project
|
||||
const deleteResponse = await makeAuthenticatedRequest(
|
||||
`${BASE_URL}/api/projects/${newProject.id}`,
|
||||
{ method: 'DELETE' },
|
||||
sessionCookies
|
||||
);
|
||||
|
||||
if (deleteResponse.ok) {
|
||||
console.log('✅ Test project cleaned up');
|
||||
}
|
||||
} else {
|
||||
console.log('❌ Project creation failed:', createProjectResponse.status);
|
||||
const errorText = await createProjectResponse.text();
|
||||
console.log(' Error:', errorText.substring(0, 200));
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Test failed with error:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Run the test
|
||||
testCompleteAuthenticatedFlow();
|
||||
Reference in New Issue
Block a user