add auth
This commit is contained in:
59
src/app/api/auth/register/route.ts
Normal file
59
src/app/api/auth/register/route.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { getSessionOptions, hashPassword, type SessionData } from '@/lib/auth'
|
||||
import { getIronSession } from 'iron-session'
|
||||
import { getUserCount, createUser } from '@/lib/users'
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
let body: { username?: string; password?: string; role?: string }
|
||||
try {
|
||||
body = await request.json()
|
||||
} catch {
|
||||
return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 })
|
||||
}
|
||||
|
||||
const { username, password } = body
|
||||
let { role } = body
|
||||
|
||||
if (!username || !password) {
|
||||
return NextResponse.json({ error: 'username and password are required' }, { status: 400 })
|
||||
}
|
||||
if (username.trim().length < 2) {
|
||||
return NextResponse.json({ error: 'Username must be at least 2 characters' }, { status: 400 })
|
||||
}
|
||||
if (password.length < 8) {
|
||||
return NextResponse.json({ error: 'Password must be at least 8 characters' }, { status: 400 })
|
||||
}
|
||||
|
||||
const userCount = getUserCount()
|
||||
|
||||
if (userCount === 0) {
|
||||
// First user always becomes admin
|
||||
role = 'admin'
|
||||
} else {
|
||||
// Subsequent users require an admin session
|
||||
const res = new NextResponse()
|
||||
const session = await getIronSession<SessionData>(request, res, getSessionOptions())
|
||||
if (!session.userId) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
||||
}
|
||||
if (session.role !== 'admin') {
|
||||
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
|
||||
}
|
||||
if (role !== 'admin' && role !== 'user') {
|
||||
role = 'user'
|
||||
}
|
||||
}
|
||||
|
||||
const passwordHash = await hashPassword(password)
|
||||
|
||||
try {
|
||||
const user = createUser(username.trim(), passwordHash, role as 'admin' | 'user')
|
||||
return NextResponse.json({ id: user.id, username: user.username, role: user.role }, { status: 201 })
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : 'Failed to create user'
|
||||
if (message.includes('UNIQUE constraint failed')) {
|
||||
return NextResponse.json({ error: 'Username already taken' }, { status: 409 })
|
||||
}
|
||||
return NextResponse.json({ error: message }, { status: 400 })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user