Fix 11 bugs: restore crash, draft leak, email failures, memory leaks
Critical fixes: - sanitizeLoadedHitStats/VisitorStats: restore full state shape so a snapshot restore no longer crashes hit-counting middleware (missing byPathReal, byPathBot, byDayReal, byDayBot, botReasons, ipHashIndex) - /questions/share/🆔 read state.questions only, not draft questions - inbound-email: validate date with Number.isFinite before toISOString - study-reminders: wrap each send in try/catch so one failure doesn't block remaining users; persist sent-markers after each success Security: - getClientIp: use req.ip (trust-proxy-resolved) instead of raw x-forwarded-for header to prevent IP spoofing - env-snapshot.env: delete immediately after backup tar stream ends so secrets don't linger on disk between exports Correctness / UX: - contact form: email failures no longer 500 the user after the submission is already saved; log and fall through instead - study-account profile: cap data URI avatar at 6 MB - admin enrollment PATCH: validate slug against study catalog - signup: return 503 at MAX_STUDY_USERS instead of silently dropping oldest accounts Memory leaks: - contactHits, downloadHits Maps: prune stale entries at 5000 entries - resendEmailSubmissionIndex: trim to 2000 entries (oldest first) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,8 @@ import {
|
||||
import {
|
||||
hashStudyPassword,
|
||||
getStudyCatalog,
|
||||
normalizeStudySlug,
|
||||
isEnrollableStudySlug,
|
||||
} from '../study-helpers.js'
|
||||
|
||||
export function register(app) {
|
||||
@@ -157,7 +159,10 @@ export function register(app) {
|
||||
}
|
||||
|
||||
if (typeof addEnrollment === 'string' && addEnrollment.trim()) {
|
||||
const slug = addEnrollment.trim()
|
||||
const slug = normalizeStudySlug(addEnrollment)
|
||||
if (!slug || !isEnrollableStudySlug(slug)) {
|
||||
res.status(400).json({ message: `Unknown study slug: ${addEnrollment.trim()}` }); return
|
||||
}
|
||||
if (!Array.isArray(user.enrolledStudySlugs)) user.enrolledStudySlugs = []
|
||||
if (!user.enrolledStudySlugs.includes(slug)) user.enrolledStudySlugs.push(slug)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user