- Add fe80::/10 (IPv6 link-local) detection to isPrivateIP()
- Update error message to match specification: 'URL resolves to a private/internal IP address'
- Existing protections already covered all required IPv4 ranges and IPv6 localhost
- Update sitemap.xml to include /v1/health endpoint
- Add proper 404 handling (JSON for API paths, HTML for browser paths)
- Create optimized nginx config with gzip, cache headers, specific locations
- Add logrotate configuration for DocFast logs
- Add security headers and static asset caching
- Full backup of PostgreSQL, Docker volumes, nginx config, SSL certs, crontabs, OpenDKIM
- Daily backups at 03:00 UTC with 7d/4w/3m retention
- Local storage at /opt/borg-backups/docfast
- Restore testing verified
- Documentation for disaster recovery procedures
- Add .forgejo/workflows/deploy.yml for automated deployment
- Include rollback mechanism with image tagging
- Add health check verification (http://127.0.0.1:3100/health)
- Create manual rollback script for emergency use
- Add deployment documentation and setup instructions
- Supports auto-rollback on deployment failure
- Replace JSON file storage with PostgreSQL (pg package)
- Add db.ts service for connection pool and schema init
- Rewrite keys.ts, verification.ts, usage.ts for async PostgreSQL
- Update all routes for async function signatures
- Add migration script (scripts/migrate-to-postgres.mjs)
- Update docker-compose.yml with DATABASE_* env vars
- Change SLA from 99.9% to 99.5% in landing page
Safety net: provisions pro API key on successful checkout via webhook,
in case user doesn't reach the success page. Idempotent with existing
createProKey logic. Gracefully handles missing STRIPE_WEBHOOK_SECRET.
- Extract customer email from session.customer_details?.email
- Check if Pro key already exists for that email (idempotent)
- Create Pro key only if one does not exist
- Add comprehensive logging for debugging
- Ensures webhook and success page work together without duplicates
Fix BUG-032: Add 375px mobile breakpoint for terminal gap issues
- Reduced container padding to 12px on smallest screens
- Optimized code-section margins and padding
- Improved terminal header and code-block spacing
- Enhanced hero section padding for mobile
Inline script was already extracted to swagger-init.js (BUG-004/005).
Helmet defaults allow style-src unsafe-inline and font-src https,
so Google Fonts and inline styles work without custom directives.
- Fix swagger-ui symlink in Dockerfile (was pointing to /opt/docfast instead of /app)
- Add CSP directives to allow inline scripts/styles and Google Fonts
- Add email-change.ts route with rate limiting (3/hr) and verification
- Add updateKeyEmail to keys service
- Add email-change route to index.ts with CORS support
- Launch BROWSER_COUNT separate Chromium instances (default: 2)
- Each with PAGES_PER_BROWSER pages (default: 8, 16 total)
- Round-robin distribution across browser instances
- Independent restart scheduling per browser
- Updated health endpoint to show per-browser stats
- docker-compose: added BROWSER_COUNT and PAGES_PER_BROWSER env vars
Investor Directive 1: Key recovery now shows key in browser after email verification code.
- Removed sendRecoveryEmail function entirely
- Recovery endpoint returns apiKey in JSON response (shown once in browser)
- Added full recovery modal UI (email → code → key displayed)
- Added "Lost your API key?" links throughout signup flow
Investor Directive 3: Rate limits adjusted to match server capacity.
- Global rate limit: 100/min → 30/min (server handles ~28 PDFs/min)
- CORS: recover routes now restricted to docfast.dev origin
- POST /v1/recover: request recovery code
- POST /v1/recover/verify: verify code, receive key via email
- Key sent via email only (not in API response) for security
- Rate limited to 3 attempts per hour
- Non-enumerable: same response whether email exists or not
- DKIM-signed emails via postfix/opendkim
- Replace Resend email service with nodemailer via local postfix relay
- Remove code field from POST /v1/signup/free response
- Send 6-digit verification code via email only (noreply@docfast.dev)
- Add extra_hosts for Docker-to-host SMTP relay
- Fire-and-forget email sending to avoid blocking API response
- POST /v1/signup/free now returns verification code (temp in response)
- New POST /v1/signup/verify endpoint to verify code and get API key
- Codes expire after 15 minutes, max 3 attempts
- Frontend updated with 2-step signup modal (email → code → key)
- Legacy token verification kept for existing links
- Signup now requires email verification before API key is revealed
- Verification token sent via email (Resend) with console fallback
- GET /verify?token=xxx shows API key in styled HTML page
- Handles expired (24h), invalid, and already-verified tokens
- Frontend modal shows 'check your email' instead of key
- Keeps existing rate limiting
- Add !important declarations to override any conflicting styles
- Force overflow-x: hidden on html and body globally
- Apply universal max-width: 100% on mobile
- Specifically target code blocks with word-break and overflow fixes
- Reduce container padding to prevent width issues
This should definitively resolve horizontal scrolling on 375px viewports.
- Add overflow-x: hidden on body and container for mobile viewports
- Improve code block responsive behavior with pre-wrap and word-break
- Constrain code-section width to prevent viewport overflow
- Fix trust-grid horizontal overflow on small screens
This fixes the QA-reported issue where pages scroll horizontally
to 488px on 375px mobile viewports.
BUG-007: Unwrap req.body.data for template endpoint (docs show wrapped format)
BUG-008: Default PDF margins set to 0 (user can override via request body)
BUG-006: Copy button shows Copied! for 2s then reverts