Codebase audit: remove dead code, fix broken patterns, consolidate duplicates; v2.0.27
Publish Container / docker (push) Failing after 10m40s

- Remove unused prop-types dep, deprecated useOutboundLinkTracking export
- Fix missing linkClicks key in analyticsEvents initial state (B-01)
- Export ADMIN_SESSION_COOKIE from auth.js; remove local copy in admin-auth.js (D-02)
- Remove cookieFlags() wrapper in auth.js and study-helpers.js; use cookieSecureFlag() directly (U-04)
- Remove ADMIN_SESSION_TTL_MS duplicate from config.js (D-01)
- Remove DEFAULT_SEO/DEFAULT_LEGAL/DEFAULT_REDIRECT_RULES/DEFAULT_PODCAST_FEATURED_LINKS/DEFAULT_PUBLISH_STATE
  duplicates from config.js; re-export from helpers.js (D-04, fixes sitemapPaths divergence)
- Fix email.js hardcoded fallback strings to use DEFAULT_RESEND_TO/DEFAULT_RESEND_REPLY_TO (M-02)
- Remove duplicate normalizeIp, isPrivateOrLocalIp, normalizeRedirectPath, sanitizeUrl,
  sanitizeRedirectRules bodies from study-helpers.js; re-export from helpers.js (D-03)
- Fix pruneStatsByDays to import VISITOR_RETENTION_DAYS_DEFAULT from config.js (B-02)
- Fix createTitusDownloadToken to use DOWNLOAD_TOKEN_TTL_MS constant (B-03)
- Remove normalizeMessageType duplicate from study-helpers.js (U-03/D-08)
- Remove dead wantsWelcome variable in contact.js; use shouldSendWelcome (B-04)
- Replace dynamic imports in contact.js with static imports (B-07)
- Remove dead wantsWelcome=true in study-auth.js (B-05)
- Merge duplicate import blocks in analytics.js and public.js (D-05, D-06)
- Replace dynamic readFile re-import in nuggets-host-upload.js (B-06)
- Replace hardcoded SITE_URL fallbacks with getCanonicalBaseUrl() (M-06)
- Replace raw resend.emails.send in study-account.js with sendResendEmailWithRetry (M-01)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 4.6 committed 2026-09-17 16:10:31 -04:00
1 parent 1ddb8ee7be
commit e158e1e53a
14 files changed
+58 -185

No files matched your search

+1 -2
View File
@@ -3,6 +3,7 @@ import qrcode from 'qrcode'
import { parseCookies } from '../helpers.js'
import { APP_VERSION, GIT_COMMIT } from '../config.js'
import {
ADMIN_SESSION_COOKIE,
isAdminPasswordConfigured,
isValidAdminSession,
requireAdminAuth,
@@ -24,8 +25,6 @@ import {
consumePendingSession,
} from '../auth.js'
const ADMIN_SESSION_COOKIE = 'vbn_admin_session'
const loginRateLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 10,
+1 -1
View File
@@ -19,8 +19,8 @@ import {
buildLastNDaysStats,
shouldCountHit,
recordHit,
getStudyCatalog,
} from '../study-helpers.js'
import { getStudyCatalog } from '../study-helpers.js'
async function resolveGeo(ip) {
if (!ip || isPrivateOrLocalIp(ip)) {
+5 -7
View File
@@ -1,12 +1,13 @@
import { randomUUID } from 'node:crypto'
import { Resend } from 'resend'
import { requireAdminAuth } from '../auth.js'
import { escapeHtml, splitName } from '../helpers.js'
import { escapeHtml, splitName, buildAbsoluteUrl } from '../helpers.js'
import {
MAX_CONTACT_SUBMISSIONS,
MAX_QUESTIONS,
USE_RESEND_AUTOMATION_WELCOME,
DEFAULT_SEO,
DATA_FILE,
} from '../config.js'
import { state } from '../state.js'
import {
@@ -16,6 +17,7 @@ import {
normalizeContactEmailStatus,
normalizeMessageType,
fireWebhooks,
loadSiteContentFile,
} from '../data.js'
import {
noteContactEmailCooldown,
@@ -130,7 +132,6 @@ export function register(app) {
const submittedAt = new Date().toLocaleString('en-US', { dateStyle: 'medium', timeStyle: 'short' })
const shouldSendWelcome = shouldSendWelcomeEmail({ subscribe })
const wantsWelcome = subscribe === true
const submission = {
id: randomUUID(),
submittedAt: new Date().toISOString(),
@@ -138,9 +139,9 @@ export function register(app) {
email: trimmedEmail,
message: trimmedMessage,
messageType: normalizedMessageType,
subscribe: wantsWelcome,
subscribe: shouldSendWelcome,
archived: false,
emailStatus: normalizeContactEmailStatus(null, wantsWelcome),
emailStatus: normalizeContactEmailStatus(null, shouldSendWelcome),
}
state.contactSubmissions.unshift(submission)
state.contactSubmissions = state.contactSubmissions.slice(0, MAX_CONTACT_SUBMISSIONS)
@@ -187,8 +188,6 @@ export function register(app) {
let publishedSiteContent = state.cachedSiteContent
if (!publishedSiteContent) {
try {
const { loadSiteContentFile } = await import('../data.js')
const { DATA_FILE } = await import('../config.js')
const published = await loadSiteContentFile(DATA_FILE)
publishedSiteContent = published?.siteContent ?? null
} catch { publishedSiteContent = null }
@@ -200,7 +199,6 @@ export function register(app) {
: DEFAULT_SEO.canonicalUrl
const welcomeSubject = process.env.RESEND_WELCOME_SUBJECT ?? emailConfig.welcomeEmailSubject ?? 'Welcome to Verse by Verse with Nate'
const welcomeGreetingPrefix = emailConfig.welcomeEmailGreetingPrefix?.trim() || "Glad you're here"
const { buildAbsoluteUrl } = await import('../helpers.js')
const welcomeTemplate = buildContactWelcomeEmailTemplate({
greetingName,
welcomeGreetingPrefix,
+4 -4
View File
@@ -10,6 +10,7 @@ import {
sendNuggetsUploadNotification,
sendNuggetsHostWelcomeEmail,
sendNuggetsHostOtpEmail,
getCanonicalBaseUrl,
} from '../email.js'
import { markSeafileFileSeen } from '../nuggets-seafile-watcher.js'
import {
@@ -414,8 +415,7 @@ export function register(app) {
}
try {
const { readFile: rf } = await import('node:fs/promises')
const fileBuffer = await rf(tempPath)
const fileBuffer = await readFile(tempPath)
// Upload audio to /Episode Upload/
const audioLink = await getSeafileUploadLink(SEAFILE_EPISODE_UPLOAD_DIR)
@@ -553,7 +553,7 @@ export function register(app) {
name,
username: email,
password,
portalUrl: `${process.env.SITE_URL ?? 'https://versebyversewithnate.us'}/host`,
portalUrl: `${getCanonicalBaseUrl().replace(/\/$/, '')}/host`,
}).catch(err => console.error('[nuggets-host] welcome email error:', err))
const { passwordHash: _ph, ...safeHost } = host
@@ -591,7 +591,7 @@ export function register(app) {
name: data.hosts[idx].name,
username: data.hosts[idx].email,
password: newPassword,
portalUrl: `${process.env.SITE_URL ?? 'https://versebyversewithnate.us'}/host`,
portalUrl: `${getCanonicalBaseUrl().replace(/\/$/, '')}/host`,
}).catch(err => console.error('[nuggets-host] reset email error:', err))
}
+1 -1
View File
@@ -11,10 +11,10 @@ import {
DEFAULT_SEO,
APP_VERSION,
GIT_COMMIT,
DATA_FILE,
} from '../config.js'
import { state } from '../state.js'
import { loadSiteContentFile } from '../data.js'
import { DATA_FILE } from '../config.js'
import { sanitizeRedirectRules } from '../study-helpers.js'
import { fetchAllEpisodes } from './episodes.js'
import { fetchNuggetsEpisodes } from './nuggets.js'
+19 -19
View File
@@ -37,6 +37,7 @@ import {
buildBrandedEmailHtml,
getCanonicalBaseUrl,
getResendFromAddress,
sendResendEmailWithRetry,
} from '../email.js'
import { Resend } from 'resend'
@@ -381,27 +382,26 @@ export function register(app) {
const emailChangeSubject = cfg.emailChangeSubject?.trim() || 'Confirm your new email address'
const emailChangeBody = cfg.emailChangeBody?.trim() || 'Click the link below to confirm your new account email. If you did not request this change, ignore this message.'
const emailChangeCtaLabel = cfg.emailChangeCtaLabel?.trim() || 'Confirm Email Change'
const { error } = await resend.emails.send({
from: getResendFromAddress(),
to: [newEmail],
subject: emailChangeSubject,
text: `${emailChangeBody}\n\n${verifyUrl}`,
html: buildBrandedEmailHtml({
title: emailChangeSubject,
eyebrow: 'Account Security',
bodyHtml: `<p style="margin:0 0 16px;">${escapeHtml(emailChangeBody)}</p>`,
ctaLabel: emailChangeCtaLabel,
ctaUrl: verifyUrl,
footerHtml: `<p style="margin:0;font-family:Georgia,serif;font-size:12px;color:#7a7060;">Verse by Verse with Nate</p>`,
}),
await sendResendEmailWithRetry({
resend,
context: 'study-account-email-change',
payload: {
from: getResendFromAddress(),
to: [newEmail],
subject: emailChangeSubject,
text: `${emailChangeBody}\n\n${verifyUrl}`,
html: buildBrandedEmailHtml({
title: emailChangeSubject,
eyebrow: 'Account Security',
bodyHtml: `<p style="margin:0 0 16px;">${escapeHtml(emailChangeBody)}</p>`,
ctaLabel: emailChangeCtaLabel,
ctaUrl: verifyUrl,
footerHtml: `<p style="margin:0;font-family:Georgia,serif;font-size:12px;color:#7a7060;">Verse by Verse with Nate</p>`,
}),
},
})
if (error) {
console.error('[study-account] email change send error:', error)
res.status(503).json({ message: 'Could not send verification email right now.' })
return
}
} catch (err) {
console.error('[study-account] email change send exception:', err)
console.error('[study-account] email change send error:', err)
res.status(503).json({ message: 'Could not send verification email right now.' })
return
}
+2 -3
View File
@@ -105,7 +105,6 @@ export function register(app) {
queueStudyUsersWrite()
if (subscribe) {
const wantsWelcome = true
const submission = {
id: randomUUID(),
submittedAt: now,
@@ -113,9 +112,9 @@ export function register(app) {
email: username,
message: '',
messageType: 'general',
subscribe: wantsWelcome,
subscribe: true,
archived: false,
emailStatus: normalizeContactEmailStatus(null, wantsWelcome),
emailStatus: normalizeContactEmailStatus(null, true),
}
state.contactSubmissions.unshift(submission)
state.contactSubmissions = state.contactSubmissions.slice(0, MAX_CONTACT_SUBMISSIONS)