Use email as host login credential; remove separate username field; v2.0.8
Publish Container / docker (push) Failing after 10m44s

- Login form now asks for email + password (no username)
- Admin creates hosts with name + email + password; email is always
  required and welcome email always sends on creation
- Duplicate email check replaces duplicate username check
- Admin table shows Email (login) column only; username field removed
  throughout data model, routes, and UI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 4.6 committed 2026-09-08 14:05:02 -04:00
1 parent a12a471c41
commit 684181c34c
5 files changed
+33 -46

No files matched your search

+18 -23
View File
@@ -159,18 +159,18 @@ export function register(app) {
})
app.post('/api/nuggets-upload/login', loginRateLimiter, async (req, res) => {
const username = typeof req.body?.username === 'string' ? req.body.username.trim() : ''
const email = typeof req.body?.email === 'string' ? req.body.email.trim().toLowerCase() : ''
const password = typeof req.body?.password === 'string' ? req.body.password : ''
if (!username || !password) {
res.status(400).json({ message: 'Username and password are required.' })
if (!email || !password) {
res.status(400).json({ message: 'Email and password are required.' })
return
}
const data = await loadUploadHosts()
const host = data.hosts.find(h => h.username === username && h.active)
const host = data.hosts.find(h => h.email === email && h.active)
if (!host || !passwordsMatch(password, host.passwordHash)) {
res.status(401).json({ message: 'Invalid username or password.' })
res.status(401).json({ message: 'Invalid email or password.' })
return
}
@@ -279,12 +279,11 @@ export function register(app) {
app.post('/api/admin/nuggets-upload/hosts', requireAdminAuth, async (req, res) => {
const name = typeof req.body?.name === 'string' ? req.body.name.trim() : ''
const username = typeof req.body?.username === 'string' ? req.body.username.trim().toLowerCase() : ''
const password = typeof req.body?.password === 'string' ? req.body.password : ''
const email = typeof req.body?.email === 'string' ? req.body.email.trim().toLowerCase() : ''
const password = typeof req.body?.password === 'string' ? req.body.password : ''
if (!name || !username || !password) {
res.status(400).json({ message: 'Name, username, and password are required.' })
if (!name || !email || !password) {
res.status(400).json({ message: 'Name, email, and password are required.' })
return
}
if (password.length < 8) {
@@ -293,15 +292,14 @@ export function register(app) {
}
const data = await loadUploadHosts()
if (data.hosts.some(h => h.username === username)) {
res.status(409).json({ message: 'Username already taken.' })
if (data.hosts.some(h => h.email === email)) {
res.status(409).json({ message: 'An account with that email already exists.' })
return
}
const host = {
id: randomUUID(),
name,
username,
email,
passwordHash: hashPassword(password),
active: true,
@@ -310,19 +308,16 @@ export function register(app) {
data.hosts.push(host)
await saveUploadHosts(data)
// Send welcome email if an address was provided
if (email) {
sendNuggetsHostWelcomeEmail({
to: email,
name,
username,
password,
portalUrl: `${process.env.SITE_URL ?? 'https://versebyversewithnate.us'}/host`,
}).catch(err => console.error('[nuggets-host] welcome email error:', err))
}
sendNuggetsHostWelcomeEmail({
to: email,
name,
username: email,
password,
portalUrl: `${process.env.SITE_URL ?? 'https://versebyversewithnate.us'}/host`,
}).catch(err => console.error('[nuggets-host] welcome email error:', err))
const { passwordHash: _ph, ...safeHost } = host
res.json({ ok: true, host: safeHost, emailSent: Boolean(email) })
res.json({ ok: true, host: safeHost, emailSent: true })
})
app.put('/api/admin/nuggets-upload/hosts/:id', requireAdminAuth, async (req, res) => {