Add host welcome/reset emails, email field, and /host URL; v2.0.7
- Host accounts now have an optional email field - Creating a host with an email sends a welcome email with the portal URL, username, and password via Resend - Resetting a password also emails the new credentials if the host has an email on file; admin sees a confirmation either way - Admin panel shows email column and confirmation messages - Portal URL changed from /host-upload to /host Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
1e396644a9
commit
a12a471c41
5 files changed
+90
-10
No files matched your search
@@ -6,7 +6,7 @@ import rateLimit from 'express-rate-limit'
|
||||
import { createHash, timingSafeEqual } from 'node:crypto'
|
||||
import { parseCookies, cookieSecureFlag } from '../helpers.js'
|
||||
import { requireAdminAuth } from '../auth.js'
|
||||
import { sendNuggetsUploadNotification } from '../email.js'
|
||||
import { sendNuggetsUploadNotification, sendNuggetsHostWelcomeEmail } from '../email.js'
|
||||
import { markSeafileFileSeen } from '../nuggets-seafile-watcher.js'
|
||||
import {
|
||||
NUGGETS_UPLOAD_HOSTS_FILE,
|
||||
@@ -281,6 +281,7 @@ export function register(app) {
|
||||
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() : ''
|
||||
|
||||
if (!name || !username || !password) {
|
||||
res.status(400).json({ message: 'Name, username, and password are required.' })
|
||||
@@ -301,6 +302,7 @@ export function register(app) {
|
||||
id: randomUUID(),
|
||||
name,
|
||||
username,
|
||||
email,
|
||||
passwordHash: hashPassword(password),
|
||||
active: true,
|
||||
createdAt: new Date().toISOString(),
|
||||
@@ -308,8 +310,19 @@ 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))
|
||||
}
|
||||
|
||||
const { passwordHash: _ph, ...safeHost } = host
|
||||
res.json({ ok: true, host: safeHost })
|
||||
res.json({ ok: true, host: safeHost, emailSent: Boolean(email) })
|
||||
})
|
||||
|
||||
app.put('/api/admin/nuggets-upload/hosts/:id', requireAdminAuth, async (req, res) => {
|
||||
@@ -332,11 +345,23 @@ export function register(app) {
|
||||
patch.passwordHash = hashPassword(req.body.password)
|
||||
}
|
||||
|
||||
const newPassword = typeof req.body?.password === 'string' && req.body.password.length > 0 ? req.body.password : null
|
||||
data.hosts[idx] = { ...data.hosts[idx], ...patch }
|
||||
await saveUploadHosts(data)
|
||||
|
||||
// Email the host their new password if they have an address on file
|
||||
if (newPassword && data.hosts[idx].email) {
|
||||
sendNuggetsHostWelcomeEmail({
|
||||
to: data.hosts[idx].email,
|
||||
name: data.hosts[idx].name,
|
||||
username: data.hosts[idx].username,
|
||||
password: newPassword,
|
||||
portalUrl: `${process.env.SITE_URL ?? 'https://versebyversewithnate.us'}/host`,
|
||||
}).catch(err => console.error('[nuggets-host] reset email error:', err))
|
||||
}
|
||||
|
||||
const { passwordHash: _ph, ...safeHost } = data.hosts[idx]
|
||||
res.json({ ok: true, host: safeHost })
|
||||
res.json({ ok: true, host: safeHost, emailSent: Boolean(newPassword && data.hosts[idx].email) })
|
||||
})
|
||||
|
||||
app.delete('/api/admin/nuggets-upload/hosts/:id', requireAdminAuth, async (req, res) => {
|
||||
|
||||
Reference in new issue
Block a user