'use server' import type { UpdateEmailResult } from './types' import { getAuditRequestMetadata } from '@admin/actions/audit/get-audit-request-metadata' import { auth } from '@admin/auth' import { getSession } from '@admin/auth/middleware' import db from '@admin/db' import { user } from '@admin/db/schema' import { runAdminEventHooks } from '@admin/lib/lifecycle-hooks' import { toActionError } from '@admin/utils/error/to-action-error' import { eq } from 'drizzle-orm' import { headers } from 'next/headers' import { invalidateUsersCache } from './invalidate-users-cache' export async function updateEmail( newEmail: string, currentPassword: string ): Promise { try { const session = await getSession({ disableCookieCache: true }) if (!session?.user) { return { success: false, error: 'Not authenticated' } } const now = new Date().toISOString() const auditRequestMetadata = await getAuditRequestMetadata() const verification = await auth.api .verifyPassword({ body: { password: currentPassword }, headers: await headers() }) .catch(() => null) if (!verification?.status) { return { success: false, error: 'Incorrect password' } } const existing = await db .select({ id: user.id }) .from(user) .where(eq(user.email, newEmail)) .limit(1) if (existing.length > 0) { return { success: false, error: 'Email already in use' } } await db .update(user) .set({ email: newEmail, updatedAt: new Date() }) .where(eq(user.id, session.user.id)) await invalidateUsersCache() runAdminEventHooks({ category: 'auth', action: 'update', targetType: 'user', targetId: session.user.id, targetLabel: session.user.email, user: session.user, timestamp: now, sourceType: 'admin_ui' as const, changedFields: ['email'], metadata: { operation: 'email_change' }, ...auditRequestMetadata }) return { success: true } } catch (error) { return { success: false, error: toActionError(error, 'Failed to update email') } } }