Commit graph

56 commits

Author SHA1 Message Date
OpenClaw Deployer
97744897f0 fix: move /docs route before express.static to fix CSP headers
All checks were successful
Promote to Production / Deploy to Production (push) Successful in 1m15s
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 9m8s
express.static was serving docs.html before the /docs route handler,
causing Helmet default CSP to be used instead of the custom Swagger UI CSP.
This blocked unsafe-eval and blob: workers needed by Swagger UI.
2026-02-18 13:51:35 +00:00
OpenClaw Deployer
a45d7704ab fix: relax CSP for /docs page — allow unsafe-eval for Swagger UI 5.x (ajv)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 8m41s
Swagger UI 5.x uses new Function() via ajv for JSON schema validation.
Helmet default CSP (script-src self) blocks this in Firefox, causing
TypeError: NetworkError when attempting to fetch resource on Try It.
Override CSP on /docs route to allow unsafe-eval.
2026-02-18 13:33:26 +00:00
OpenClaw Deployer
0902e1e437 feat: add SMTP auth support for K3s migration
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 11m3s
Promote to Production / Deploy to Production (push) Successful in 3m23s
- Support SMTP_USER/SMTP_PASS env vars for authenticated SMTP
- Support SMTP_FROM env var for configurable sender address
- Auto-detect secure mode for port 465
- Backwards compatible: falls back to unauthenticated local relay
2026-02-18 12:47:33 +00:00
DocFast Bot
f5cea97adf security: remove Change Email feature (leaked key = account hijack)
All checks were successful
Deploy to Production / Deploy to Server (push) Successful in 1m7s
2026-02-17 11:40:27 +00:00
DocFast Bot
1702abdeb8 fix: add /change-email route in index.ts + fix SQL query escaping in keys.ts
All checks were successful
Deploy to Production / Deploy to Server (push) Successful in 1m36s
- Register GET /change-email route in src/index.ts (serves change-email.html)
- Fix updateKeyEmail() SQL query string (dollar signs were stripped by heredoc)
- Fix updateEmailByCustomer() SQL query string
- Rebuild TypeScript dist/
2026-02-17 11:34:21 +00:00
DocFast Bot
8f3b1a9660 feat: convert change-email from modal to standalone page + Stripe customer.updated webhook
All checks were successful
Deploy to Production / Deploy to Server (push) Successful in 1m8s
- Add /change-email as a proper standalone page (public/src/change-email.html)
  with API key input, new email input, verification code flow, and success state
- Update footer partial: change "/#change-email" link to "/change-email" on all pages
- Remove email change modal HTML and hash-handler JS from index page source
- Add /change-email to sitemap.xml
- Rebuild all HTML files via build-html.cjs

- Add updateEmailByCustomer() to src/services/keys.ts
- Add customer.updated webhook handler in src/routes/billing.ts
  to sync email changes made via Stripe dashboard back to DocFast
2026-02-17 11:31:37 +00:00
DocFast Bot
855068a011 fix: downgrade instead of delete key on subscription cancel
All checks were successful
Deploy to Production / Deploy to Server (push) Successful in 2m43s
- Replace revokeByCustomer with downgradeByCustomer in keys.ts
  - Sets tier='free' in cache and DB (UPDATE, not DELETE)
- Add isDocFastSubscription() product filter helper in billing.ts
  - Filters all subscription events by prod_TygeG8tQPtEAdE
- Handle customer.subscription.updated event
  - Downgrades on status=canceled/past_due/unpaid or cancel_at_period_end=true
- Handle customer.subscription.deleted with product filter
  - Downgrades to free (was incorrectly deleting the key)

Fixes revenue integrity bug: cancelled Pro subscribers kept Pro access.
2026-02-17 10:46:12 +00:00
DocFast Agent
a0d4ba964c fix: audit #18 rate limit cleanup (.unref), audit #25 consistent error shapes
All checks were successful
Deploy to Production / Deploy to Server (push) Successful in 1m4s
Audit #18 - Rate limit store memory growth:
- rateLimitStore already had cleanup via cleanupExpiredEntries() per-request + 60s interval
- Added .unref() to the setInterval timer for clean graceful shutdown behaviour

Audit #25 - Consistent error response shapes:
- billing.ts: Fixed 409 plain-text response -> JSON { error: "..." }
- index.ts: Simplified 404 from 4-field object to { error: "Not Found: METHOD path" }
- signup.ts: Removed extra retryAfter field from rate-limit message object
- pdfRateLimit.ts: Merged limit/tier/retryAfter into single error message string
- usage.ts: Merged limit/used/upgrade fields into single error message string
- convert.ts: Merged detail field into error message (3 occurrences)

All error responses now consistently use {"error": "message"} shape.
2026-02-17 08:10:14 +00:00
OpenClaw
e7d28bc62b fix: batch usage writes (#10), retry divergence (#12), per-key queue fairness (#15)
All checks were successful
Deploy to Production / Deploy to Server (push) Successful in 3m9s
2026-02-16 20:07:11 +00:00
OpenClaw
09c6feb06e Fix audit #14 (body size limits), #17 (duplicate session_id), #22 (unused import)
All checks were successful
Deploy to Production / Deploy to Server (push) Successful in 2m53s
2026-02-16 19:51:24 +00:00
OpenClaw
6cc30db5c6 Add styled /status page, update footer/terms links from /health to /status
All checks were successful
Deploy to Production / Deploy to Server (push) Successful in 2m49s
2026-02-16 19:48:25 +00:00
OpenClaw
59cc8f3d0e Session 45: support email, audit fixes (template validation, content-type, admin auth, waitUntil)
All checks were successful
Deploy to Production / Deploy to Server (push) Successful in 2m20s
- Added support@docfast.dev to footer, impressum, terms, landing page, openapi.json
- Fixed audit #6: Template render validates required fields (400 on missing)
- Fixed audit #7: Content-Type check on markdown/URL routes (415)
- Fixed audit #11: /v1/usage and /v1/concurrency now require ADMIN_API_KEY
- Fixed audit Critical #3: URL convert uses domcontentloaded instead of networkidle0
2026-02-16 19:30:21 +00:00
OpenClaw
8a86e34f91 fix: critical and high-severity security fixes
All checks were successful
Deploy to Production / Deploy to Server (push) Successful in 2m52s
- CRITICAL: DNS rebinding SSRF - pin DNS resolution via request interception
- CRITICAL: XSS in billing success - use data-attribute instead of JS string
- HIGH: Webhook signature bypass - refuse unverified webhooks (500)
- HIGH: Filename header injection - sanitize Content-Disposition filename
- HIGH: Verification code timing attack - use crypto.timingSafeEqual()
- HIGH: Remove duplicate unreachable 404 handler
- HIGH: Add IPv6 unique local (fc00::/7) to SSRF private IP check
- HIGH: Replace console.warn with structured logger
2026-02-16 18:56:21 +00:00
c903860917 Enforce Pro plan limit of 5,000 PDFs/month
Some checks failed
Deploy to Production / Deploy to Server (push) Has been cancelled
2026-02-16 18:41:57 +00:00
OpenClaw
b98e8bc253 fix: BUG-046 usage endpoint data leak, BUG-047 copy button, BUG-048 email change links
All checks were successful
Deploy to Production / Deploy to Server (push) Successful in 1m18s
BUG-046 (CRITICAL): getUsageStats() now accepts apiKey param and returns
only that key usage instead of all users. Route passes req.apiKeyInfo.key.

BUG-047: Added visible Copy button to Pro key success page in billing.ts.

BUG-048: Added class="open-email-change" to Change Email links in all
HTML pages so the JS modal opener can find them.
2026-02-16 18:06:52 +00:00
DocFast Bot
d7b0a0eaa6 fix(landing): BUG-045 — Pro tier says Unlimited instead of 10,000 PDFs
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 22s
The Pro tier has no limit in code (unlimited). Fixed landing page copy
and JSON-LD structured data to match.
2026-02-16 16:07:26 +00:00
DocFast Bot
b1135edcca security: disable JavaScript execution in Puppeteer for PDF generation
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 21s
2026-02-16 15:32:34 +00:00
openclawd
5ef8f34133 feat: Add EU compliance pages and EU hosting marketing
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 20s
- Add footer links for Impressum, Privacy Policy, Terms of Service
- Create legal pages: /impressum, /privacy, /terms (Austrian/EU compliant)
- Add EU hosting badge highlighting GDPR compliance and EU data residency
- Add Express routes for legal pages with caching headers
- All pages use consistent dark theme design matching landing page
2026-02-16 13:07:24 +00:00
openclawd
03dd6c17df Fix three critical issues: Docker healthcheck, USD->EUR pricing, static asset caching
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 22s
- Docker healthcheck: Use Node.js instead of curl (not installed in slim image)
- Pricing: Change from USD ($) to EUR (€) in frontend and backend Stripe integration
- Static assets: Add Cache-Control headers (1 day) for /public and /docs files
2026-02-16 13:04:47 +00:00
openclawd
76714d799e Fix: nginx duplicate MIME type, update version to 0.2.1, improve log rotation
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 22s
- Remove duplicate text/html from nginx gzip_types (fixes nginx -t warning)
- Update hardcoded API version from 0.2.0 to 0.2.1 to match package.json
- Update logrotate config: daily rotation, 7 days retention, improved postrotate
- Add Docker logging configuration with size/file limits
2026-02-16 08:36:55 +00:00
openclawd
7b55a1ddc6 Fix SSRF vulnerability: Add IPv6 link-local blocking and update error message
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 20s
- 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
2026-02-16 08:36:08 +00:00
DocFast CEO
86f8da62ec v0.2.1: request logging, 404 handler, permissions-policy, SEO improvements, typo fix
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 20s
2026-02-16 08:32:57 +00:00
openclawd
210e71e3d8 feat: SEO + Nginx optimization
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 21s
- 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
2026-02-16 08:30:14 +00:00
OpenClaw
9541ae1826 Backend hardening: structured logging, timeouts, memory leak fixes, compression, XSS fix
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 20s
- Add pino structured logging with request IDs (X-Request-Id header)
- Add 30s timeout to acquirePage() and renderPdf/renderUrlPdf
- Add verification cache cleanup (every 15min) and rate limit cleanup (every 60s)
- Read version from package.json in health endpoint
- Add compression middleware
- Escape currency in templates (XSS fix)
- Add static asset caching (1h maxAge)
- Remove deprecated docker-compose version field
- Replace all console.log/error with pino logger
2026-02-16 08:27:42 +00:00
OpenClaw
7e74f22ea3 Update backup system and local changes
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 21s
- BorgBackup disaster recovery system
- Health endpoint updates
- Merged with remote changes
2026-02-15 11:04:58 +00:00
openclawd
302c4b372a Merge remote changes with CI/CD pipeline additions
Some checks failed
Deploy to Production / Deploy to Server (push) Has been cancelled
Resolved minor conflict in rate limiting comment.
Maintains CI/CD deployment setup with latest backend changes.
2026-02-15 11:03:40 +00:00
DocFast Bot
ebdeb74094 BUG-037: Filter webhook by product_id prod_TygeG8tQPtEAdE
Shared Stripe account - only process checkout events for DocFast product.
Retrieves session with expanded line_items to check product ID.
2026-02-15 10:44:09 +00:00
DocFast Bot
e9d16bf2a3 Migrate from JSON to PostgreSQL, update SLA to 99.5%
- 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
2026-02-15 10:18:25 +00:00
OpenClaw
bb1881af61 feat: add checkout.session.completed webhook handler for pro key provisioning
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.
2026-02-15 09:52:48 +00:00
OpenClaw
aa23d4ae2a Add checkout.session.completed webhook handler for Pro key creation
- 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
2026-02-15 09:52:25 +00:00
OpenClaw
f5a85c6fc3 feat: data-backed rate limits, concurrency limiter, copy button fix (BUG-025, BUG-022) 2026-02-15 08:14:39 +00:00
OpenClaw Agent
73917551bd Fix rate limits, concurrency control, copy button
- DATA-BACKED RATE LIMITS:
  * Reduce global rate limit from 10,000/min to 100/min
  * Add PDF conversion rate limits: 10/min free, 30/min pro
  * Set recovery rate limit to 3/hour (was 5/hour)
  * Add concurrency limiter: max 3 simultaneous PDFs, queue rest
  * Return 429 if queue > 10

- BUG-025: Fix copy button functionality
  * Improve fallback handling for execCommand
  * Add better error handling and user feedback
  * Fix secure context detection

- Add concurrency monitoring endpoint /v1/concurrency
2026-02-15 08:04:56 +00:00
OpenClaw
922230c108 fix: revert custom CSP - Helmet defaults are correct
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.
2026-02-14 22:31:18 +00:00
OpenClaw
6aa1fa4d84 fix: swagger UI symlink, CSP headers, email-change route, updateKeyEmail
- 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
2026-02-14 22:29:56 +00:00
OpenClaw
efa39661cf feat: multi-browser pooling (2 Chromium instances × 8 pages)
- 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
2026-02-14 21:55:29 +00:00
a177020186 Security: never send API keys via email, add browser-based recovery UI, adjust rate limits
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
2026-02-14 19:42:53 +00:00
1af1b07fb3 fix: update key recovery messaging across all pages 2026-02-14 19:27:21 +00:00
87a49d8e93 feat: key recovery via email verification (BUG-014)
- 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
2026-02-14 19:26:47 +00:00
210fb26ec1 fix(BUG-021): remove verification code from API response, send via email
- 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
2026-02-14 19:10:45 +00:00
OpenClaw
a67c16cd0f fix: BUG-022 check duplicate email before rate limit, BUG-024 support X-API-Key header 2026-02-14 18:41:46 +00:00
f59b99203e feat: add 6-digit code email verification to signup flow
- 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
2026-02-14 18:25:55 +00:00
OpenClaw
1b20665b0d feat: email verification for free tier signup
- 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
2026-02-14 18:12:25 +00:00
OpenClaw
3c0bac889a fix: BUG-012 remove email requirement from free signup + fix 429 handling 2026-02-14 17:24:03 +00:00
73bb041513 Security fixes: non-root user, signup rate limiting, differentiated CORS, persistent usage tracking 2026-02-14 17:04:55 +00:00
6a38ba4adc fix: critical security issues - webhook bypass, SSRF, XSS 2026-02-14 16:19:48 +00:00
53bebc0119 fix: BUG-006 copy feedback, BUG-008 white border CSS reset, BUG-010 CORS allow all origins 2026-02-14 15:41:22 +00:00
d8bc3fd8e6 fix: BUG-009 setTimeout syntax, BUG-010 CORS helmet policy, BUG-011 content-type validation 2026-02-14 15:34:21 +00:00
6891e488b6 fix(BUG-006,007,008): copy feedback, invoice data unwrap, zero margins
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
2026-02-14 15:28:00 +00:00
6276d61aa3 fix: add CORS headers and trust proxy for rate limiter
- Added CORS middleware allowing docfast.dev origin
- Added app.set('trust proxy', 1) to fix ERR_ERL_UNEXPECTED_X_FORWARDED_FOR
- The rate limiter was crashing on every proxied request through nginx
2026-02-14 14:37:28 +00:00
7f04789997 Add proper API docs page, fix Stripe lazy init, update docs links 2026-02-14 14:31:44 +00:00