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:
142
public/test-auth.html
Normal file
142
public/test-auth.html
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Authentication Test Page</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: Arial, sans-serif; margin: 20px; }
|
||||||
|
.test-section { margin: 20px 0; padding: 20px; border: 1px solid #ccc; border-radius: 5px; }
|
||||||
|
.result { margin: 10px 0; padding: 10px; border-radius: 3px; }
|
||||||
|
.success { background-color: #d4edda; border: 1px solid #c3e6cb; color: #155724; }
|
||||||
|
.error { background-color: #f8d7da; border: 1px solid #f5c6cb; color: #721c24; }
|
||||||
|
.info { background-color: #d1ecf1; border: 1px solid #bee5eb; color: #0c5460; }
|
||||||
|
button { padding: 10px 20px; margin: 5px; cursor: pointer; }
|
||||||
|
pre { background: #f8f9fa; padding: 10px; border-radius: 3px; overflow-x: auto; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Authentication & API Test Page</h1>
|
||||||
|
|
||||||
|
<div class="test-section">
|
||||||
|
<h2>Authentication Status</h2>
|
||||||
|
<button onclick="checkAuthStatus()">Check Authentication Status</button>
|
||||||
|
<div id="authStatus"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-section">
|
||||||
|
<h2>API Endpoint Tests</h2>
|
||||||
|
<button onclick="testAllEndpoints()">Test All API Endpoints</button>
|
||||||
|
<div id="apiResults"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-section">
|
||||||
|
<h2>Manual Login Instructions</h2>
|
||||||
|
<div class="info">
|
||||||
|
<p><strong>Test Credentials:</strong></p>
|
||||||
|
<p>Email: <code>admin@localhost.com</code></p>
|
||||||
|
<p>Password: <code>admin123456</code></p>
|
||||||
|
<p><a href="/auth/signin" target="_blank">Open Sign-in Page</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async function checkAuthStatus() {
|
||||||
|
const statusDiv = document.getElementById('authStatus');
|
||||||
|
statusDiv.innerHTML = '<div class="info">Checking authentication status...</div>';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/auth/session');
|
||||||
|
const session = await response.json();
|
||||||
|
|
||||||
|
if (session && session.user) {
|
||||||
|
statusDiv.innerHTML = `
|
||||||
|
<div class="success">
|
||||||
|
<h3>✅ Authenticated</h3>
|
||||||
|
<pre>${JSON.stringify(session, null, 2)}</pre>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
statusDiv.innerHTML = `
|
||||||
|
<div class="error">
|
||||||
|
<h3>❌ Not Authenticated</h3>
|
||||||
|
<p>Please <a href="/auth/signin">sign in</a> first.</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
statusDiv.innerHTML = `
|
||||||
|
<div class="error">
|
||||||
|
<h3>❌ Error checking authentication</h3>
|
||||||
|
<p>${error.message}</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testAllEndpoints() {
|
||||||
|
const resultsDiv = document.getElementById('apiResults');
|
||||||
|
resultsDiv.innerHTML = '<div class="info">Testing API endpoints...</div>';
|
||||||
|
|
||||||
|
const endpoints = [
|
||||||
|
{ url: '/api/debug-auth', method: 'GET', name: 'Debug Auth' },
|
||||||
|
{ url: '/api/projects', method: 'GET', name: 'Projects' },
|
||||||
|
{ url: '/api/contracts', method: 'GET', name: 'Contracts' },
|
||||||
|
{ url: '/api/tasks', method: 'GET', name: 'Tasks' },
|
||||||
|
{ url: '/api/tasks/templates', method: 'GET', name: 'Task Templates' },
|
||||||
|
{ url: '/api/project-tasks', method: 'GET', name: 'Project Tasks' }
|
||||||
|
];
|
||||||
|
|
||||||
|
let results = '';
|
||||||
|
|
||||||
|
for (const endpoint of endpoints) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(endpoint.url, {
|
||||||
|
method: endpoint.method,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
const count = Array.isArray(data) ? data.length : 'object';
|
||||||
|
results += `
|
||||||
|
<div class="success">
|
||||||
|
<strong>✅ ${endpoint.name}</strong> (${endpoint.method} ${endpoint.url})
|
||||||
|
<br>Status: ${response.status} | Data: ${count} items
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
} else if (response.status === 401) {
|
||||||
|
results += `
|
||||||
|
<div class="error">
|
||||||
|
<strong>🔒 ${endpoint.name}</strong> (${endpoint.method} ${endpoint.url})
|
||||||
|
<br>Status: ${response.status} - Unauthorized (Please sign in)
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
results += `
|
||||||
|
<div class="error">
|
||||||
|
<strong>❌ ${endpoint.name}</strong> (${endpoint.method} ${endpoint.url})
|
||||||
|
<br>Status: ${response.status} - ${response.statusText}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
results += `
|
||||||
|
<div class="error">
|
||||||
|
<strong>💥 ${endpoint.name}</strong> (${endpoint.method} ${endpoint.url})
|
||||||
|
<br>Error: ${error.message}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resultsDiv.innerHTML = results;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-check authentication status on page load
|
||||||
|
window.addEventListener('load', checkAuthStatus);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
37
src/app/api/debug-auth/route.js
Normal file
37
src/app/api/debug-auth/route.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { auth } from "@/lib/auth"
|
||||||
|
import { NextResponse } from "next/server"
|
||||||
|
|
||||||
|
export const GET = auth(async (req) => {
|
||||||
|
try {
|
||||||
|
console.log("=== DEBUG AUTH ENDPOINT ===")
|
||||||
|
console.log("Request URL:", req.url)
|
||||||
|
console.log("Auth object:", req.auth)
|
||||||
|
|
||||||
|
if (!req.auth?.user) {
|
||||||
|
return NextResponse.json({
|
||||||
|
error: "No session found",
|
||||||
|
debug: {
|
||||||
|
hasAuth: !!req.auth,
|
||||||
|
authKeys: req.auth ? Object.keys(req.auth) : [],
|
||||||
|
}
|
||||||
|
}, { status: 401 })
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
message: "Authenticated",
|
||||||
|
user: req.auth.user,
|
||||||
|
debug: {
|
||||||
|
authKeys: Object.keys(req.auth),
|
||||||
|
userKeys: Object.keys(req.auth.user)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Auth debug error:", error)
|
||||||
|
return NextResponse.json({
|
||||||
|
error: "Auth error",
|
||||||
|
message: error.message,
|
||||||
|
stack: error.stack
|
||||||
|
}, { status: 500 })
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import db from "@/lib/db";
|
import db from "@/lib/db";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import { withUserAuth } from "@/lib/middleware/auth";
|
import { withUserAuth, withReadAuth } from "@/lib/middleware/auth";
|
||||||
|
import { getAllTaskTemplates } from "@/lib/queries/tasks";
|
||||||
|
|
||||||
// POST: create new template
|
// POST: create new template
|
||||||
async function createTaskHandler(req) {
|
async function createTaskHandler(req) {
|
||||||
@@ -20,5 +21,12 @@ async function createTaskHandler(req) {
|
|||||||
return NextResponse.json({ success: true });
|
return NextResponse.json({ success: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET: Get all task templates
|
||||||
|
async function getTasksHandler(req) {
|
||||||
|
const templates = getAllTaskTemplates();
|
||||||
|
return NextResponse.json(templates);
|
||||||
|
}
|
||||||
|
|
||||||
// Protected routes - require authentication
|
// Protected routes - require authentication
|
||||||
|
export const GET = withReadAuth(getTasksHandler);
|
||||||
export const POST = withUserAuth(createTaskHandler);
|
export const POST = withUserAuth(createTaskHandler);
|
||||||
|
|||||||
@@ -10,20 +10,21 @@ const ROLE_HIERARCHY = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function withAuth(handler, options = {}) {
|
export function withAuth(handler, options = {}) {
|
||||||
return async (req, context) => {
|
return auth(async (req) => {
|
||||||
try {
|
try {
|
||||||
const session = await auth(req)
|
|
||||||
|
|
||||||
// Check if user is authenticated
|
// Check if user is authenticated
|
||||||
if (!session?.user) {
|
if (!req.auth?.user) {
|
||||||
|
console.log("No session found for request to:", req.url)
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "Authentication required" },
|
{ error: "Authentication required" },
|
||||||
{ status: 401 }
|
{ status: 401 }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("Session found for user:", req.auth.user.email)
|
||||||
|
|
||||||
// Check role-based permissions (without database access)
|
// Check role-based permissions (without database access)
|
||||||
if (options.requiredRole && !hasPermission(session.user.role, options.requiredRole)) {
|
if (options.requiredRole && !hasPermission(req.auth.user.role, options.requiredRole)) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "Insufficient permissions" },
|
{ error: "Insufficient permissions" },
|
||||||
{ status: 403 }
|
{ status: 403 }
|
||||||
@@ -32,14 +33,14 @@ export function withAuth(handler, options = {}) {
|
|||||||
|
|
||||||
// Add user info to request
|
// Add user info to request
|
||||||
req.user = {
|
req.user = {
|
||||||
id: session.user.id,
|
id: req.auth.user.id,
|
||||||
email: session.user.email,
|
email: req.auth.user.email,
|
||||||
name: session.user.name,
|
name: req.auth.user.name,
|
||||||
role: session.user.role
|
role: req.auth.user.role
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the original handler
|
// Call the original handler
|
||||||
return await handler(req, context)
|
return await handler(req)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Auth middleware error:", error)
|
console.error("Auth middleware error:", error)
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@@ -47,7 +48,7 @@ export function withAuth(handler, options = {}) {
|
|||||||
{ status: 500 }
|
{ status: 500 }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hasPermission(userRole, requiredRole) {
|
export function hasPermission(userRole, requiredRole) {
|
||||||
@@ -64,12 +65,12 @@ export function withUserAuth(handler) {
|
|||||||
return withAuth(handler, { requiredRole: 'user' })
|
return withAuth(handler, { requiredRole: 'user' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper for admin-level operations
|
||||||
|
export function withAdminAuth(handler) {
|
||||||
|
return withAuth(handler, { requiredRole: 'admin' })
|
||||||
|
}
|
||||||
|
|
||||||
// Helper for project manager operations
|
// Helper for project manager operations
|
||||||
export function withManagerAuth(handler) {
|
export function withManagerAuth(handler) {
|
||||||
return withAuth(handler, { requiredRole: 'project_manager' })
|
return withAuth(handler, { requiredRole: 'project_manager' })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for admin operations
|
|
||||||
export function withAdminAuth(handler) {
|
|
||||||
return withAuth(handler, { requiredRole: 'admin' })
|
|
||||||
}
|
|
||||||
|
|||||||
109
test-auth-api.mjs
Normal file
109
test-auth-api.mjs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
// Test authenticated API access using NextAuth.js client-side approach
|
||||||
|
|
||||||
|
const BASE_URL = 'http://localhost:3000';
|
||||||
|
|
||||||
|
async function testAuthenticatedAPI() {
|
||||||
|
console.log('🔐 Testing Authenticated API Access\n');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Test 1: Check if server is running
|
||||||
|
console.log('1️⃣ Checking server status...');
|
||||||
|
const healthResponse = await fetch(`${BASE_URL}/api/auth/session`);
|
||||||
|
console.log(`Server status: ${healthResponse.status}`);
|
||||||
|
|
||||||
|
if (!healthResponse.ok) {
|
||||||
|
console.log('❌ Server not responding properly');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 2: Test unauthenticated access to protected endpoints
|
||||||
|
console.log('\n2️⃣ Testing unauthenticated access...');
|
||||||
|
const protectedEndpoints = [
|
||||||
|
'/api/projects',
|
||||||
|
'/api/contracts',
|
||||||
|
'/api/tasks',
|
||||||
|
'/api/project-tasks'
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const endpoint of protectedEndpoints) {
|
||||||
|
const response = await fetch(`${BASE_URL}${endpoint}`);
|
||||||
|
console.log(`${endpoint}: ${response.status} ${response.status === 401 ? '✅ (properly protected)' : '❌ (not protected)'}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 3: Check protected pages
|
||||||
|
console.log('\n3️⃣ Testing protected pages...');
|
||||||
|
const protectedPages = ['/projects', '/contracts', '/tasks'];
|
||||||
|
|
||||||
|
for (const page of protectedPages) {
|
||||||
|
const response = await fetch(`${BASE_URL}${page}`, {
|
||||||
|
redirect: 'manual'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.status === 302) {
|
||||||
|
const location = response.headers.get('location');
|
||||||
|
if (location && location.includes('/auth/signin')) {
|
||||||
|
console.log(`${page}: ✅ Properly redirects to sign-in`);
|
||||||
|
} else {
|
||||||
|
console.log(`${page}: ⚠️ Redirects to: ${location}`);
|
||||||
|
}
|
||||||
|
} else if (response.status === 200) {
|
||||||
|
console.log(`${page}: ❌ Accessible without authentication`);
|
||||||
|
} else {
|
||||||
|
console.log(`${page}: ❓ Status ${response.status}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 4: Test sign-in page accessibility
|
||||||
|
console.log('\n4️⃣ Testing sign-in page...');
|
||||||
|
const signinResponse = await fetch(`${BASE_URL}/auth/signin`);
|
||||||
|
if (signinResponse.ok) {
|
||||||
|
console.log('✅ Sign-in page accessible');
|
||||||
|
const content = await signinResponse.text();
|
||||||
|
const hasEmailField = content.includes('name="email"') || content.includes('id="email"');
|
||||||
|
const hasPasswordField = content.includes('name="password"') || content.includes('id="password"');
|
||||||
|
console.log(` Email field: ${hasEmailField ? '✅' : '❌'}`);
|
||||||
|
console.log(` Password field: ${hasPasswordField ? '✅' : '❌'}`);
|
||||||
|
} else {
|
||||||
|
console.log('❌ Sign-in page not accessible');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 5: Check NextAuth.js providers endpoint
|
||||||
|
console.log('\n5️⃣ Testing NextAuth.js configuration...');
|
||||||
|
const providersResponse = await fetch(`${BASE_URL}/api/auth/providers`);
|
||||||
|
if (providersResponse.ok) {
|
||||||
|
const providers = await providersResponse.json();
|
||||||
|
console.log('✅ NextAuth.js providers endpoint accessible');
|
||||||
|
console.log('Available providers:', Object.keys(providers));
|
||||||
|
} else {
|
||||||
|
console.log('❌ NextAuth.js providers endpoint failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 6: Check CSRF token endpoint
|
||||||
|
console.log('\n6️⃣ Testing CSRF token...');
|
||||||
|
const csrfResponse = await fetch(`${BASE_URL}/api/auth/csrf`);
|
||||||
|
if (csrfResponse.ok) {
|
||||||
|
const csrf = await csrfResponse.json();
|
||||||
|
console.log('✅ CSRF token endpoint accessible');
|
||||||
|
console.log('CSRF token available:', !!csrf.csrfToken);
|
||||||
|
} else {
|
||||||
|
console.log('❌ CSRF token endpoint failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n🎯 Manual Testing Instructions:');
|
||||||
|
console.log('1. Open browser to: http://localhost:3000/auth/signin');
|
||||||
|
console.log('2. Use credentials:');
|
||||||
|
console.log(' Email: admin@localhost.com');
|
||||||
|
console.log(' Password: admin123456');
|
||||||
|
console.log('3. After login, test these pages:');
|
||||||
|
protectedPages.forEach(page => {
|
||||||
|
console.log(` - http://localhost:3000${page}`);
|
||||||
|
});
|
||||||
|
console.log('4. Test API endpoints with browser dev tools or Postman');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Test failed with error:', error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the test
|
||||||
|
testAuthenticatedAPI();
|
||||||
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