Normalize EVENT_VIEWER_URL trailing slash once in env.ts, remove 6 ad-hoc strips
All checks were successful
CI / checks (pull_request) Successful in 35s

EVENT_VIEWER_URL.replace(/\/$/, '') was duplicated across:
- env.ts (BRAND_LOGO, 1x)
- server.ts (settingsUrl in confirm routes, 3x)
- mailer.ts (settingsUrl in sendConfirm/sendDigest, 2x)

Now trailing-slash normalization happens at the export source in env.ts,
so all consumers get a clean URL without ad-hoc stripping.
This commit is contained in:
Agent 2026-09-16 09:28:03 -04:00
parent 0059ec263b
commit dbde1ec02d
3 changed files with 7 additions and 7 deletions

View file

@ -22,11 +22,11 @@ if (!process.env.BASE_URL) throw new Error('BASE_URL is not defined.')
export const MAILSHIP_URL = process.env.MAILSHIP_URL
export const MAILSHIP_NAME = process.env.MAILSHIP_NAME
export const BASE_URL = process.env.BASE_URL
export const EVENT_VIEWER_URL = process.env.EVENT_VIEWER_URL || 'https://app.flotilla.social'
export const EVENT_VIEWER_URL = (process.env.EVENT_VIEWER_URL || 'https://app.flotilla.social').replace(/\/$/, '')
export const BRAND_ACCENT = process.env.BRAND_ACCENT || '#7161FF'
export const BRAND_NAME = process.env.BRAND_NAME || 'Flotilla'
export const BRAND_LOGO =
process.env.BRAND_LOGO || `${EVENT_VIEWER_URL.replace(/\/$/, '')}/logo.png`
process.env.BRAND_LOGO || `${EVENT_VIEWER_URL}/logo.png`
export const appSigner = Nip01Signer.fromSecret(process.env.MAILSHIP_SECRET)
export const DEFAULT_RELAYS = process.env.DEFAULT_RELAYS.split(',').map(normalizeRelayUrl)
export const INDEXER_RELAYS = process.env.INDEXER_RELAYS.split(',').map(normalizeRelayUrl)

View file

@ -29,7 +29,7 @@ const transporter = nodemailer.createTransport({
export const sendConfirm = (sub: Subscription) => {
const href = `${BASE_URL}/confirm?token=${sub.key}`
const settingsUrl = `${EVENT_VIEWER_URL.replace(/\/$/, '')}/settings/alerts`
const settingsUrl = `${EVENT_VIEWER_URL}/settings/alerts`
return transporter
.sendMail({
@ -86,7 +86,7 @@ export const sendDigest = async (sub: Subscription, variables: Record<string, an
brandName: BRAND_NAME,
brandAccent: BRAND_ACCENT,
brandLogo: BRAND_LOGO,
settingsUrl: `${EVENT_VIEWER_URL.replace(/\/$/, '')}/settings/alerts`,
settingsUrl: `${EVENT_VIEWER_URL}/settings/alerts`,
}),
})
.catch(error => {

View file

@ -308,7 +308,7 @@ addRoute('get', '/confirm', async (req: Request, res: Response) => {
brandName: BRAND_NAME,
brandAccent: BRAND_ACCENT,
brandLogo: BRAND_LOGO,
settingsUrl: `${EVENT_VIEWER_URL.replace(/\/$/, '')}/settings/alerts`,
settingsUrl: `${EVENT_VIEWER_URL}/settings/alerts`,
})
)
}
@ -320,7 +320,7 @@ addRoute('get', '/confirm', async (req: Request, res: Response) => {
brandName: BRAND_NAME,
brandAccent: BRAND_ACCENT,
brandLogo: BRAND_LOGO,
settingsUrl: `${EVENT_VIEWER_URL.replace(/\/$/, '')}/settings/alerts`,
settingsUrl: `${EVENT_VIEWER_URL}/settings/alerts`,
}))
} catch (error) {
const isActionError = error instanceof ActionError
@ -331,7 +331,7 @@ addRoute('get', '/confirm', async (req: Request, res: Response) => {
brandName: BRAND_NAME,
brandAccent: BRAND_ACCENT,
brandLogo: BRAND_LOGO,
settingsUrl: `${EVENT_VIEWER_URL.replace(/\/$/, '')}/settings/alerts`,
settingsUrl: `${EVENT_VIEWER_URL}/settings/alerts`,
}))
if (!isActionError) {