Scrum4Me/lib/auth.ts
Scrum4Me Agent a19ae89e37 feat(ST-l9kkxh2m): /reset-password pagina + resetPasswordAction + hashPassword
- lib/auth.ts: hashPassword(password) geëxporteerd (bcrypt, rounds=12)
- actions/auth.ts: resetPasswordAction met Zod-validatie (min 8, superRefine gelijkheid),
  prisma.user.update (password_hash + must_reset_password=false), redirect /dashboard
- app/(auth)/reset-password/page.tsx: server guard (userId check + must_reset_password check)
- app/(auth)/reset-password/reset-form.tsx: client form (nieuw wachtwoord + bevestiging)
- __tests__/actions/auth.test.ts: 3 tests voor resetPasswordAction
2026-05-05 14:30:59 +02:00

72 lines
2.1 KiB
TypeScript

import bcrypt from 'bcryptjs'
import { getIronSession } from 'iron-session'
import { cookies } from 'next/headers'
import { prisma } from '@/lib/prisma'
import { SessionData, sessionOptions } from '@/lib/session'
import { getAccessibleProduct } from '@/lib/product-access'
export async function getSession() {
return getIronSession<SessionData>(await cookies(), sessionOptions)
}
export async function requireUser() {
const session = await getSession()
if (!session.userId) throw new Error('Niet ingelogd')
return session
}
export async function requireWriter() {
const session = await requireUser()
if (session.isDemo) throw new Error('Niet beschikbaar in demo-modus')
return session.userId
}
export async function requireProductAccess(productId: string) {
const session = await requireUser()
const product = await getAccessibleProduct(productId, session.userId)
if (!product) throw new Error('Product niet gevonden of geen toegang')
return product
}
export async function requireProductWriter(productId: string) {
const userId = await requireWriter()
const product = await getAccessibleProduct(productId, userId)
if (!product) throw new Error('Product niet gevonden of geen toegang')
return product
}
export async function registerUser(username: string, password: string) {
const existing = await prisma.user.findUnique({ where: { username } })
if (existing) {
return { error: 'Gebruikersnaam is al in gebruik' }
}
if (password.length < 8) {
return { error: 'Wachtwoord moet minimaal 8 tekens bevatten' }
}
const password_hash = await bcrypt.hash(password, 12)
const user = await prisma.user.create({
data: {
username,
password_hash,
roles: { create: [{ role: 'DEVELOPER' }] },
},
})
return { user }
}
export async function verifyUser(username: string, password: string) {
const user = await prisma.user.findUnique({ where: { username } })
if (!user) return null
const valid = await bcrypt.compare(password, user.password_hash)
if (!valid) return null
return user
}
export async function hashPassword(password: string): Promise<string> {
return bcrypt.hash(password, 12)
}