Files
dockhand/routes/api/profile/+server.ts
Jarek Krochmalski 62e3c6439e Initial commit
2025-12-28 21:16:03 +01:00

118 lines
3.5 KiB
TypeScript

import { json } from '@sveltejs/kit';
import type { RequestHandler } from '@sveltejs/kit';
import { getUser, updateUser as dbUpdateUser, deleteUserSessions, userHasAdminRole } from '$lib/server/db';
import { validateSession, hashPassword, isAuthEnabled } from '$lib/server/auth';
// GET /api/profile - Get current user's profile
export const GET: RequestHandler = async ({ cookies }) => {
if (!(await isAuthEnabled())) {
return json({ error: 'Authentication is not enabled' }, { status: 400 });
}
const currentUser = await validateSession(cookies);
if (!currentUser) {
return json({ error: 'Not authenticated' }, { status: 401 });
}
try {
const user = await getUser(currentUser.id);
if (!user) {
return json({ error: 'User not found' }, { status: 404 });
}
// Derive isAdmin from role assignment
const isAdmin = await userHasAdminRole(user.id);
return json({
id: user.id,
username: user.username,
email: user.email,
displayName: user.displayName,
avatar: user.avatar,
mfaEnabled: user.mfaEnabled,
isAdmin,
provider: currentUser.provider || 'local',
lastLogin: user.lastLogin,
createdAt: user.createdAt,
updatedAt: user.updatedAt
});
} catch (error) {
console.error('Failed to get profile:', error);
return json({ error: 'Failed to get profile' }, { status: 500 });
}
};
// PUT /api/profile - Update current user's profile
export const PUT: RequestHandler = async ({ request, cookies }) => {
if (!(await isAuthEnabled())) {
return json({ error: 'Authentication is not enabled' }, { status: 400 });
}
const currentUser = await validateSession(cookies);
if (!currentUser) {
return json({ error: 'Not authenticated' }, { status: 401 });
}
try {
const data = await request.json();
const existingUser = await getUser(currentUser.id);
if (!existingUser) {
return json({ error: 'User not found' }, { status: 404 });
}
// Build update object - users can only update certain fields
const updateData: any = {};
if (data.email !== undefined) updateData.email = data.email;
if (data.displayName !== undefined) updateData.displayName = data.displayName;
// Handle password change - require current password
if (data.newPassword) {
if (!data.currentPassword) {
return json({ error: 'Current password is required' }, { status: 400 });
}
if (data.newPassword.length < 8) {
return json({ error: 'Password must be at least 8 characters' }, { status: 400 });
}
// Verify current password
const { verifyPassword } = await import('$lib/server/auth');
const isValid = await verifyPassword(data.currentPassword, existingUser.passwordHash);
if (!isValid) {
return json({ error: 'Current password is incorrect' }, { status: 400 });
}
updateData.passwordHash = await hashPassword(data.newPassword);
// Invalidate other sessions on password change
deleteUserSessions(currentUser.id);
}
const user = await dbUpdateUser(currentUser.id, updateData);
if (!user) {
return json({ error: 'Failed to update profile' }, { status: 500 });
}
// Derive isAdmin from role assignment
const isAdmin = await userHasAdminRole(user.id);
return json({
id: user.id,
username: user.username,
email: user.email,
displayName: user.displayName,
avatar: user.avatar,
mfaEnabled: user.mfaEnabled,
isAdmin,
lastLogin: user.lastLogin,
createdAt: user.createdAt,
updatedAt: user.updatedAt
});
} catch (error: any) {
console.error('Failed to update profile:', error);
return json({ error: 'Failed to update profile' }, { status: 500 });
}
};