mirror of
https://github.com/bretzel-app/crumbs.git
synced 2026-10-12 12:06:57 +02:00
Admins can now reset the password of an OAuth-only user, which creates their credentials and enables password login; the new 'Disable password login' row action removes those credentials again. Resetting a password revokes all existing sessions. - add users.password_login_enabled column (migration 0005) - admin reset: set password, enable login, revoke sessions - disable action: clear password, disable login (only on OAuth-linked rows) - account endpoint: refuse password updates on OAuth-linked users - e2e: wipe the test DB before the webServer starts (Playwright starts the server before globalSetup, so wiping there orphaned the DB file) - row-actions strip test: five square actions, wrap on phone widths
43 lines
1.5 KiB
TypeScript
43 lines
1.5 KiB
TypeScript
import { json, error } from '@sveltejs/kit';
|
|
import type { RequestHandler } from './$types.js';
|
|
import { getUserId } from '$lib/server/api-utils.js';
|
|
import { verifyPassword, deleteUser, deleteSession, getUser } from '$lib/server/auth.js';
|
|
import { isEmailConfigured, sendAccountDeletedEmail } from '$lib/server/email.js';
|
|
import { requiresPasswordForAccountDeletion } from '$lib/utils/auth-methods.js';
|
|
|
|
export const DELETE: RequestHandler = async ({ request, cookies, ...event }) => {
|
|
const userId = getUserId(event);
|
|
const user = getUser(userId);
|
|
if (!user) throw error(404, 'User not found');
|
|
|
|
const body = await request.json();
|
|
|
|
// Password required for pure password accounts; OAuth-linked accounts may delete
|
|
// with their active SSO session even when password login was admin-enabled.
|
|
if (requiresPasswordForAccountDeletion(user)) {
|
|
if (!body.password) throw error(400, 'Password is required');
|
|
const verified = await verifyPassword(user.email, body.password);
|
|
if (!verified) throw error(401, 'Invalid password');
|
|
}
|
|
|
|
// Capture email/name before deletion
|
|
const { email: userEmail, displayName: userName } = user;
|
|
|
|
// Delete user and all associated data
|
|
await deleteUser(userId);
|
|
|
|
// Clear session cookie
|
|
const token = cookies.get('session');
|
|
if (token) {
|
|
await deleteSession(token);
|
|
cookies.delete('session', { path: '/' });
|
|
}
|
|
|
|
// Send deletion confirmation email (fire-and-forget)
|
|
if (isEmailConfigured() && userEmail) {
|
|
sendAccountDeletedEmail(userEmail, userName).catch(() => {});
|
|
}
|
|
|
|
return json({ success: true });
|
|
};
|