feat: Implement comprehensive member management with user accounts, roles, and password handling for admin and mobile applications.
This commit is contained in:
@@ -2,12 +2,11 @@
|
||||
|
||||
import { auth, getSanitizedHeaders } from '@/lib/auth'
|
||||
import { prisma } from '@innungsapp/shared'
|
||||
import { headers } from 'next/headers'
|
||||
import { revalidatePath } from 'next/cache'
|
||||
import { redirect } from 'next/navigation'
|
||||
// @ts-ignore
|
||||
import { hashPassword } from 'better-auth/crypto'
|
||||
|
||||
export async function changePasswordAndDisableMustChange(prevState: any, formData: FormData) {
|
||||
const currentPassword = formData.get('currentPassword') as string
|
||||
const newPassword = formData.get('newPassword') as string
|
||||
const confirmPassword = formData.get('confirmPassword') as string
|
||||
|
||||
@@ -25,42 +24,45 @@ export async function changePasswordAndDisableMustChange(prevState: any, formDat
|
||||
return { success: false, error: 'Nicht authentifiziert.' }
|
||||
}
|
||||
|
||||
let redirectUrl: string | null = null
|
||||
const userId = session.user.id
|
||||
const slug = formData.get('slug') as string
|
||||
|
||||
// Hash and save new password directly — user is already authenticated so no old password needed
|
||||
const newHash = await hashPassword(newPassword)
|
||||
|
||||
const credAccount = await prisma.account.findFirst({
|
||||
where: { userId, providerId: 'credential' },
|
||||
})
|
||||
|
||||
if (credAccount) {
|
||||
await prisma.account.update({
|
||||
where: { id: credAccount.id },
|
||||
data: { password: newHash },
|
||||
})
|
||||
} else {
|
||||
await prisma.account.create({
|
||||
data: {
|
||||
id: crypto.randomUUID(),
|
||||
accountId: userId,
|
||||
providerId: 'credential',
|
||||
userId,
|
||||
password: newHash,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Clear mustChangePassword
|
||||
await prisma.user.update({
|
||||
where: { id: userId },
|
||||
data: { mustChangePassword: false },
|
||||
})
|
||||
|
||||
// Sign out so the user logs in fresh with the new password
|
||||
try {
|
||||
// Update password using better-auth
|
||||
// This will throw if the current password is invalid or other error occurs
|
||||
await auth.api.changePassword({
|
||||
headers: sanitizedHeaders,
|
||||
body: {
|
||||
newPassword,
|
||||
currentPassword,
|
||||
}
|
||||
})
|
||||
|
||||
// Update mustChangePassword flag in database
|
||||
await prisma.user.update({
|
||||
where: { id: session.user.id },
|
||||
data: { mustChangePassword: false }
|
||||
})
|
||||
|
||||
const slug = formData.get('slug') as string
|
||||
|
||||
// Sign out so the user has to re-login with the new password
|
||||
await auth.api.signOut({ headers: sanitizedHeaders })
|
||||
|
||||
redirectUrl = `/login?message=password_changed&callbackUrl=/${slug}/dashboard`
|
||||
} catch (e: any) {
|
||||
console.error('Password reset exception:', e)
|
||||
// BetterAuth errors often have a message or code
|
||||
const errorMessage = e?.message?.toLowerCase() || ''
|
||||
if (errorMessage.includes('invalid') && errorMessage.includes('password')) {
|
||||
return { success: false, error: 'Das aktuelle Passwort ist nicht korrekt.' }
|
||||
}
|
||||
return { success: false, error: 'Ein unerwarteter Fehler ist aufgetreten.' }
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (redirectUrl) {
|
||||
redirect(redirectUrl)
|
||||
}
|
||||
redirect(`/login?message=password_changed&callbackUrl=/${slug}/dashboard`)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user