headplane/src/pages/api/auth/profile.ts

146 lines
3.6 KiB
TypeScript
Raw Normal View History

// 🤠 Heady User Profile Endpoint - Current User Information
/**
* Returns current authenticated user's profile and session information
* Used by Alpine.js frontend for authentication state management
*/
import type { APIRoute } from 'astro';
import { getCapabilitiesForRole } from '../../../lib/auth/role-mapper.js';
import { getSessionManager } from '../../../lib/auth/session-manager.js';
// Force SSR — this route reads env vars and must not be prerendered
export const prerender = false;
export const GET: APIRoute = async ({ cookies }) => {
try {
const sessionMgr = getSessionManager();
// Check for authentication
const validationResult = await sessionMgr.validateSession({ cookies });
if (!validationResult.valid || !validationResult.user) {
// Not authenticated - return minimal info
return new Response(
JSON.stringify({
authenticated: false,
user: null,
login_url: '/api/auth/login',
}),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
},
);
}
// Return full user profile
const user = validationResult.user;
const userProfile = {
authenticated: true,
user: {
email: user.email,
name: user.name,
picture: user.picture,
role: user.role,
role_description: user.role_description,
groups: user.groups,
capabilities: user.capabilities,
session: user.session,
},
logout_url: '/api/auth/logout',
};
console.log(`✓ Profile request for ${user.email} (${user.role})`);
return new Response(JSON.stringify(userProfile), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
console.error('❌ Profile endpoint error:', error);
return new Response(
JSON.stringify({
authenticated: false,
error: 'Profile fetch failed',
message: error instanceof Error ? error.message : 'Unknown error',
login_url: '/api/auth/login',
}),
{
status: 500,
headers: { 'Content-Type': 'application/json' },
},
);
}
};
/**
* Update user profile (limited fields)
*/
export const PATCH: APIRoute = async ({ request, cookies }) => {
try {
const sessionMgr = getSessionManager();
// Require authentication for profile updates
const validationResult = await sessionMgr.validateSession({ cookies });
if (!validationResult.valid || !validationResult.user) {
return new Response(
JSON.stringify({
authenticated: false,
error: 'Authentication required',
login_url: '/api/auth/login',
}),
{
status: 401,
headers: { 'Content-Type': 'application/json' },
},
);
}
const user = validationResult.user;
// Parse request body
const updateData = await request.json();
console.log(
`✓ Profile update request for ${user.email}:`,
Object.keys(updateData),
);
// For now, profile updates are limited (most data comes from Authentik)
// In a full implementation, you might allow updating preferences, etc.
const updatedProfile = {
success: true,
message: 'Profile update successful',
user: {
email: user.email,
name: user.name,
role: user.role,
// Updated fields would go here
},
};
return new Response(JSON.stringify(updatedProfile), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
console.error('❌ Profile update error:', error);
return new Response(
JSON.stringify({
success: false,
error: 'Profile update failed',
message: error instanceof Error ? error.message : 'Unknown error',
}),
{
status: 500,
headers: { 'Content-Type': 'application/json' },
},
);
}
};