write/server/routes/auth.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

41 lines
1.5 KiB
JavaScript

import { Router } from 'express'
import bcrypt from 'bcryptjs'
import jwt from 'jsonwebtoken'
import db from '../db.js'
import { auth, JWT_SECRET } from '../middleware/auth.js'
const router = Router()
router.post('/login', (req, res) => {
const { username, password } = req.body || {}
if (!username || !password) return res.status(400).json({ error: 'Username and password required' })
const user = db.prepare('SELECT * FROM users WHERE username = ?').get(username)
if (!user || !bcrypt.compareSync(password, user.password)) {
return res.status(401).json({ error: 'Wrong username or password' })
}
const token = jwt.sign(
{ id: user.id, username: user.username, name: user.name },
JWT_SECRET,
{ expiresIn: '30d' }
)
res.json({ token, user: { id: user.id, username: user.username, name: user.name } })
})
router.put('/password', auth, (req, res) => {
const { current, newPassword } = req.body || {}
if (!current || !newPassword) return res.status(400).json({ error: 'Current and new password required' })
if (newPassword.length < 6) return res.status(400).json({ error: 'New password must be at least 6 characters' })
const user = db.prepare('SELECT * FROM users WHERE id = ?').get(req.user.id)
if (!bcrypt.compareSync(current, user.password)) {
return res.status(401).json({ error: 'Current password is incorrect' })
}
db.prepare('UPDATE users SET password = ? WHERE id = ?').run(bcrypt.hashSync(newPassword, 10), req.user.id)
res.json({ ok: true })
})
export default router