write/server/routes/admin.js
chris 9afb1dd4c5 Switch from email to username, add password change and admin reset
- Login now uses username instead of email
- DB migration renames email -> username on existing databases
- Users can change their own password from the Stories page
- Admin can reset any user's password from the admin panel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 12:11:27 -04:00

47 lines
1.5 KiB
JavaScript

import { Router } from 'express'
import bcrypt from 'bcryptjs'
import db from '../db.js'
import { adminAuth } from '../middleware/auth.js'
const router = Router()
router.use(adminAuth)
router.get('/users', (req, res) => {
const users = db.prepare(
'SELECT id, name, username, created_at FROM users ORDER BY created_at DESC'
).all()
res.json(users)
})
router.post('/users', (req, res) => {
const { name, username, password } = req.body || {}
if (!name || !username || !password)
return res.status(400).json({ error: 'Name, username, and password are all required' })
try {
const hash = bcrypt.hashSync(password, 10)
const { lastInsertRowid } = db.prepare(
'INSERT INTO users (name, username, password) VALUES (?, ?, ?)'
).run(name, username.toLowerCase(), hash)
res.json({ id: lastInsertRowid, name, username })
} catch {
res.status(400).json({ error: 'That username is already taken' })
}
})
router.put('/users/:id/password', (req, res) => {
const { password } = req.body || {}
if (!password) return res.status(400).json({ error: 'Password required' })
if (password.length < 6) return res.status(400).json({ error: 'Password must be at least 6 characters' })
db.prepare('UPDATE users SET password = ? WHERE id = ?').run(bcrypt.hashSync(password, 10), req.params.id)
res.json({ ok: true })
})
router.delete('/users/:id', (req, res) => {
db.prepare('DELETE FROM users WHERE id = ?').run(req.params.id)
res.json({ ok: true })
})
export default router