Commit graph

270 commits

Author SHA1 Message Date
OpenClaw Subagent
4057bd9d91 chore: update nodemailer 8.0.2→8.0.3, swagger-ui-dist 5.32.0→5.32.1
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m3s
2026-03-18 20:12:23 +01:00
OpenClaw Subagent
392fc029fe fix: swagger apis path to src/ + update stale signup/verify test refs
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
- swagger.ts: changed apis glob from dist/routes/*.js to src/routes/*.ts
  so OpenAPI spec includes demo endpoints during tests (fixes 6 test failures)
- Dockerfile: copy src/ to final stage for runtime swagger-jsdoc
- Updated stale /v1/signup/verify test refs to /v1/signup/free (endpoint
  was removed when free tier was discontinued)
2026-03-18 20:11:17 +01:00
OpenClaw Subagent
9e1d4d86fb fix: sanitize path traversal in filename (TDD)
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Failing after 2m0s
2026-03-18 17:03:56 +01:00
OpenClaw Subagent
f0cb83a901 Add rate limit headers to OpenAPI generation script
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Failing after 2m11s
- Update generate-openapi.mjs to include header components
- Ensure public/openapi.json has rate limit headers
- Update rate limits description in generation script
2026-03-18 11:08:05 +01:00
OpenClaw Subagent
70eb6908e3 Document rate limit headers in OpenAPI spec
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
- Add reusable header components (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After)
- Reference headers in 200 responses on all conversion and demo endpoints
- Add Retry-After header to 429 responses
- Update Rate Limits section in API description to mention response headers
- Add comprehensive tests for header documentation (21 new tests)
- All 809 tests passing
2026-03-18 11:06:22 +01:00
OpenClaw Subagent
a3bba8f0d5 fix: add global error handler + try/catch in recover & email-change routes (BUG-112)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m57s
2026-03-17 17:10:36 +01:00
OpenClaw Subagent
2dfb0ac784 chore: update nanoid 5.1.7, terser 5.46.1
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Failing after 4m2s
2026-03-17 11:06:03 +01:00
OpenClaw Subagent
f7a999276b test: add HTTP rewrite and block-other-host SSRF branch tests for browser.ts
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Failing after 17m40s
2026-03-15 11:13:49 +01:00
OpenClaw Subagent
bbc106f518 test: improve health.ts and browser.ts coverage
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Failing after 17m7s
- health.ts: Added tests for timeout race, version regex edge cases, non-Error catch blocks
- browser.ts: Added comprehensive edge case test for buildPdfOptions with all fields
- Branch coverage: health.ts improved from 50% to 83.33%
- Function coverage: health.ts improved from 75% to 100%
- Overall function coverage improved from 84.46% to 84.95%
- Total tests: 772 → 776 (+4 new tests)
2026-03-15 08:06:39 +01:00
OpenClaw Subagent
1363c61e39 test: improve billing.ts and demo.ts branch coverage
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 21m45s
2026-03-14 17:13:36 +01:00
OpenClaw Subagent
3aae96fd8a test: improve keys.ts branch coverage — cache-hit paths for createProKey, downgradeByCustomer, findKeyByCustomerId
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Failing after 2m56s
2026-03-14 14:18:50 +01:00
OpenClaw Subagent
f5ec837e20 test: improve branch coverage for billing.ts and keys.ts
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Failing after 17m26s
billing.ts branches: 78.66% → 82.66%
- isDocFastSubscription expanded product object (not just string)
- isDocFastSubscription error handling path
- getOrCreateProPrice: new product + price creation
- getOrCreateProPrice: existing product, no active prices

keys.ts:
- createProKey UPSERT ON CONFLICT path (DB-only key)
- downgradeByCustomer customer not found in cache or DB
- updateKeyEmail DB fallback not-found path
- updateEmailByCustomer DB fallback not-found path

14 new tests, all 743 passing.
2026-03-14 11:09:01 +01:00
OpenClaw Subagent
2bdf93d09f feat(tests): improve pdfRateLimit middleware test coverage
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m54s
- Add tests for per-key queue fairness rejection path (MAX_QUEUED_PER_KEY)
- Add tests for cleanupExpiredEntries behavior and automatic cleanup
- Cover edge cases with unknown API keys
- Tests improve branch coverage for lines around 103, 116-117, 149
2026-03-14 08:12:20 +01:00
OpenClaw Subagent
14181d17a7 fix: override yauzl to 3.2.1 to resolve moderate vulnerability
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
yauzl <3.2.1 has an off-by-one error (GHSA-gmq8-994r-jv83).
Transitive dependency via puppeteer → @puppeteer/browsers → extract-zip.
npm overrides pins yauzl@3.2.1 without changing puppeteer version.
npm audit now reports 0 vulnerabilities.
2026-03-14 08:02:50 +01:00
OpenClaw Subagent
8f70a32f77 test: improve coverage for health.ts and email-change.ts
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 20m41s
- Add test for health.ts: client.query() error path with client.release(true)
- Add test for email-change.ts: sendVerificationEmail failure (fire-and-forget)
- Add test for email-change.ts verify: invalid API key (403 response)

Coverage improvements:
- health.ts: 87.09% → 100% lines (covered lines 84-85)
- email-change.ts: 94.33% → 100% lines, 80% → 100% functions (covered lines 112, 176-177)
- Overall: 92.73% → 93.13% lines (+0.40%)
- Total tests: 722 → 725 (+3)
2026-03-13 20:08:14 +01:00
OpenClaw Subagent
99b67f2584 test: improve keys.ts coverage — cache-hit paths for createFreeKey, updateKeyEmail, updateEmailByCustomer
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m37s
2026-03-13 17:10:13 +01:00
OpenClaw Subagent
97ad01b133 chore: bump puppeteer, improve recover.ts coverage
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m7s
2026-03-13 14:08:44 +01:00
OpenClaw Subagent
bb3286b1ad test: improve browser.ts coverage (scheduleRestart, HTTPS SSRF, releasePage error paths)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m35s
2026-03-13 11:06:42 +01:00
OpenClaw Subagent
44707d9247 test: improve usage.ts coverage (getUsageForKey, retry exhaustion)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m49s
2026-03-13 08:06:46 +01:00
OpenClaw Subagent
bbd7e53060 test: add 404 handler coverage for index.ts
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
2026-03-13 08:05:41 +01:00
OpenClaw Subagent
4e0ea6425b chore: bump vitest 4.0.18 → 4.1.0, @types/node 25.4.0 → 25.5.0
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 20m36s
- Fix recover-db-fallback test: remove conflicting vi.unmock before vi.mock
  (vitest 4.1 changed unmock/mock ordering behavior)
- All 705 tests pass, 0 vulnerabilities
2026-03-12 20:15:29 +01:00
OpenClaw Subagent
ae8b32e1c4 test: improve db.ts and keys.ts coverage
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
2026-03-12 20:08:23 +01:00
OpenClaw Subagent
db35a0e521 test: add integration tests for admin.ts and pages.ts routes
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m33s
- admin-integration.test.ts: 14 tests covering /v1/usage/me, /v1/usage,
  /v1/concurrency, /admin/cleanup, auth middleware (401/403/503)
- pages-integration.test.ts: 10 tests covering favicon, openapi.json,
  docs, landing page, static pages, status, /api

Both files now at 100% function/statement/branch/line coverage.
All 696 tests pass.
2026-03-12 17:10:05 +01:00
OpenClaw Subagent
fb68cf5546 add @vitest/coverage-v8 for test coverage reporting
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m27s
2026-03-12 14:13:32 +01:00
OpenClaw Subagent
39fb8e01e7 Revert "add coverage reporting + improve test coverage for undertested files"
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
This reverts commit 0a17e27fcd.
2026-03-12 14:12:23 +01:00
OpenClaw Subagent
0a17e27fcd add coverage reporting + improve test coverage for undertested files
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Failing after 2m10s
2026-03-12 14:09:54 +01:00
55172856b1 chore: upgrade vitest 3.2.4 → 4.0.18
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m42s
Breaking changes addressed:
- vi.fn() mock factories: arrow → regular functions for constructor support
- Exclude dist/ from test resolution (vitest 4 simplified defaults)
- 672 tests pass, 0 tsc errors
2026-03-12 11:21:03 +01:00
7fffd404e9 chore: upgrade express-rate-limit 7.5.1 → 8.3.1 (IPv6 security fix)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m10s
- Fixes IPv6 rate limit bypass vulnerability (GHSA-46wh-pxpv-q5gq)
- IPv6 addresses now masked to /56 subnet by default
- Updated custom keyGenerators to use ipKeyGenerator() helper
- 5 new TDD tests for v8 features (ipKeyGenerator, IPv6 masking)
- 672 tests passing, 0 TS errors, 0 npm audit vulnerabilities
2026-03-11 20:06:44 +01:00
603cbd7061 Migrate from Express 4 to Express 5
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m30s
- Upgraded express from ^4.22.1 to ^5.2.1
- Added comprehensive Express 5 migration tests with TDD approach
- All 667 tests passing (663 existing + 4 new migration tests)
- No breaking changes detected in the codebase
- Express 5's native async error handling now active
- TypeScript compilation successful with @types/express ^5.0.6

Express 5 features now available:
- Automatic async error catching in route handlers
- Improved performance and stricter path matching
- Default export import style already in use
2026-03-11 17:08:07 +01:00
a55c306514 chore: update dependencies (express 4.22, helmet 8.1, nanoid 5.1, swagger-ui-dist 5.32, tsx 4.21, typescript 5.9, vitest 3.2, @types/*)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m16s
2026-03-11 14:07:11 +01:00
Hoid
cc7de5ef49 feat: add periodic database cleanup every 6 hours (TDD)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m15s
- Cleans expired verifications and orphaned usage rows
- Previously only ran once on startup (13d+ uptime = accumulation)
- Interval uses .unref() to not block graceful shutdown
- Stopped during shutdown before pool.end()
- Idempotent start (safe to call multiple times)
- 6 TDD tests added (periodic-cleanup.test.ts)
- 663 tests total, all passing
2026-03-11 11:06:09 +01:00
75c6a6ce58 chore: upgrade marked 15→17 (ReDoS fix, list rendering improvements)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 17m28s
2026-03-11 08:07:05 +01:00
af3391d05a chore: update puppeteer 24.39.0, nodemailer 8.0.2
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m57s
2026-03-10 20:09:05 +01:00
b491052f69 refactor: extract billing HTML templates into billing-templates.ts (TDD)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m0s
- Extract renderSuccessPage() and renderAlreadyProvisionedPage() from billing.ts
- Share common styles via SHARED_STYLES constant
- 11 TDD tests: content rendering, XSS escaping, structure validation
- billing.ts: 369 → 334 lines (-35 lines, inline HTML removed)
- 647 tests passing (59 files), 0 tsc errors
2026-03-10 17:03:44 +01:00
DocFast CEO
25cb5e2e94 refactor: extract findKeyInCacheOrDb to DRY up DB fallback pattern (TDD)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 20m17s
- New shared helper findKeyInCacheOrDb(column, value) for DB lookups
- Refactored downgradeByCustomer, updateKeyEmail, updateEmailByCustomer,
  and findKeyByCustomerId to use the shared helper
- Eliminated ~60 lines of duplicated SELECT/row-mapping code
- 3 TDD tests added (keys-db-fallback-helper.test.ts)
- 636 tests passing, 0 tsc errors
2026-03-10 14:06:44 +01:00
DocFast CEO
4e00feb860 refactor: extract buildPdfOptions to DRY up renderPdf/renderUrlPdf (TDD)
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
- Extract shared PDF options construction into buildPdfOptions()
- Both renderPdf and renderUrlPdf now use the shared builder
- 5 TDD tests added (pdf-options-builder.test.ts)
- 633 tests passing, 0 tsc errors
2026-03-10 14:04:19 +01:00
DocFast Backend Agent
b1a09f7b3f refactor(demo): Use handlePdfRoute to reduce boilerplate
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m8s
- Refactored demo routes to use shared handlePdfRoute utility
- Added handleDemoPdfRoute wrapper to preserve attachment disposition
- Preserved watermark injection and demo.pdf default filename
- Added comprehensive TDD tests for Content-Disposition behavior
- Reduced demo.ts from 269 to 238 lines (31 lines removed)
- All 628 tests pass including 6 new behavioral tests

Fixes duplicated error handling, validation, and concurrency logic
while maintaining existing demo route behavior.
2026-03-10 11:06:34 +01:00
7ae20ea280 refactor: extract static page routes into routes/pages.ts (TDD)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m9s
- Created src/routes/pages.ts with pagesRouter consolidating all page-serving
  routes: /, /docs, /impressum, /privacy, /terms, /examples, /status,
  /favicon.ico, /openapi.json, /api
- Reduced index.ts from 391 to 314 lines (20% reduction)
- Removed unused imports (createRequire, APP_VERSION, swaggerSpec) from index.ts
- 4 TDD tests verifying router exports and route definitions
- 622 tests passing, 0 tsc errors
2026-03-10 08:04:22 +01:00
76b2179be9 refactor: extract shared PDF route handler to eliminate convert route duplication
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m19s
- New src/utils/pdf-handler.ts with handlePdfRoute() helper
- Handles: content-type validation, PDF option validation, slot acquire/release, error mapping, response headers
- Refactored convert.ts from 388 to 233 lines (40% reduction)
- 10 TDD tests for the new helper (RED→GREEN verified)
- All 618 tests passing, zero tsc --noEmit errors
2026-03-09 20:07:27 +01:00
54316d45cf fix: resolve all TypeScript strict-mode errors in test files
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 21m52s
- convert-sanitized: use 'as Record' cast for optional mock call args
- error-responses: fix module path (database.js → db.js) and mock return type
- recover-initial-db-fallback: fix mock return type (undefined → true)
- render-timing: remove non-existent .prepare property check
- usage-flush: cast mock request objects to any for test setup

Zero tsc --noEmit errors. 608 tests passing.
2026-03-09 17:12:22 +01:00
Hoid
c52dec2380 type safety: complete catch(err:unknown) migration + extract admin routes
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 17m50s
- All remaining catch(err) and catch(error) blocks now use : unknown
  across keys.ts, email.ts, usage.ts, index.ts (shutdown handlers)
- Extract admin/usage routes from index.ts (459→391 lines) into
  new src/routes/admin.ts with authMiddleware + adminAuth per-route
- Remove unused imports from index.ts (getConcurrencyStats, isProKey,
  getUsageForKey, getUsageStats, NextFunction)
- 10 new TDD tests (7 error helper, 3 admin router)
- 608 total tests, all passing
2026-03-09 14:09:12 +01:00
5a7ee79316 refactor: eliminate all catch(err: any) with proper unknown typing + type email transport
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m10s
- Replace all catch(err: any) with catch(err: unknown) across 8 source files
- Add errorMessage() and errorCode() helpers for safe error property access
- Type nodemailer transport config as SMTPTransport.Options (was any)
- Type health endpoint databaseStatus (was any)
- Type convert route margin param (was any)
- Change queryWithRetry params from any[] to unknown[]
- Update isTransientError to require Error instances (was accepting plain objects)
- 19 new TDD tests (error-type-safety.test.ts)
- Updated existing tests to use proper Error instances
- 598 tests total, all passing, zero type errors
2026-03-09 11:10:58 +01:00
Hoid
da049b77e3 fix(cors): dynamic origin for staging support (BUG-111) + eliminate all 'as any' casts
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 17m51s
- CORS middleware now allows both docfast.dev and staging.docfast.dev origins
  for auth/billing routes, with Vary: Origin header for proper caching
- Unknown origins fall back to production origin (not reflected)
- 13 TDD tests added for CORS behavior

Type safety improvements:
- Augment Express.Request with requestId, acquirePdfSlot, releasePdfSlot
- Use Puppeteer's PaperFormat and PuppeteerLifeCycleEvent types in browser.ts
- Use 'as const' for format literals in convert/demo/templates routes
- Replace Stripe apiVersion 'as any' with @ts-expect-error
- Zero 'as any' casts remaining in production code

579 tests passing (13 new), 51 test files
2026-03-09 08:08:37 +01:00
a60d379e66 Add AuthenticatedRequest type, eliminate apiKeyInfo 'as any' casts
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m6s
- Created src/types.ts with AuthenticatedRequest interface extending Express Request
- Replaced (req as any).apiKeyInfo with typed AuthenticatedRequest cast in:
  - auth.ts, usage.ts, pdfRateLimit.ts middleware
  - index.ts route handlers (usage/me, admin auth, admin usage, admin cleanup, concurrency)
- 4 TDD tests added. 566 tests passing (50 files).
2026-03-08 20:03:15 +01:00
Hoid
b70ed49c15 fix: add X-Robots-Tag noindex for staging, remove dead comment (TDD)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m3s
2026-03-08 17:03:37 +01:00
Hoid
7206cb518d Remove dead signup router, unused verification functions, and legacy cleanup query
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 18m37s
- Delete src/routes/signup.ts (dead code, 410 handler in index.ts remains)
- Remove isEmailVerified() and getVerifiedApiKey() from verification.ts (only used by signup)
- Remove stale-key cleanup from cleanupStaleData() that queried legacy verifications table
- Update usage middleware message: 'Free tier limit' → 'Account limit'
- TDD: 8 new tests, removed signup.test.ts (dead), net 556 tests passing
2026-03-08 14:07:50 +01:00
DocFast Dev
921562750f Optimize Dockerfile with multi-stage build
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 19m42s
- Added multi-stage build to reduce final image size
- Stage 1 (builder): Installs all deps, compiles TS, generates OpenAPI, builds HTML
- Stage 2 (production): Fresh base image with only production deps and compiled artifacts
- Final image no longer contains src/, tsconfig.json, or dev dependencies
- Added TDD test (dockerfile-build.test.ts) to verify build artifacts exist
- All 561 tests pass

Reduces image size by excluding TypeScript source, build tools, and dev dependencies.
2026-03-08 11:05:59 +01:00
DocFast CEO
da57f57299 chore: update pg 8.20, puppeteer 24.38, stripe 20.4.1, @types/node 22.19.15
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
Safe patch/minor dependency updates. npm audit: 0 vulnerabilities.
559 tests passing.
2026-03-08 11:02:57 +01:00
Hoid
2793207b39 Remove dead token-based verification system
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 12m26s
- Remove verificationsCache array and loadVerifications() function from verification.ts
- Remove verifyToken() and verifyTokenSync() functions (multi-replica unsafe, never used)
- Remove createVerification() function (stores unused data)
- Remove GET /verify route and verifyPage() helper function
- Remove loadVerifications() call from startup
- Remove createVerification() usage from signup route
- Update imports and test mocks to match removed functions
- Keep active 6-digit code system intact (createPendingVerification, verifyCode, etc.)

All 559 tests passing. The active verification system using pending_verifications
table and 6-digit codes continues to work normally.
2026-03-08 08:07:20 +01:00
d376d586fe fix(keys): add DB fallback to updateEmailByCustomer, updateKeyEmail, and recover route (BUG-108, BUG-109, BUG-110)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 13m8s
- updateEmailByCustomer: DB fallback when stripe_customer_id not in cache
- updateKeyEmail: DB fallback when key not in cache
- POST /v1/recover: DB fallback when email not in cache (was only on verify)
- 6 TDD tests added (keys-email-update.test.ts, recover-initial-db-fallback.test.ts)
- 547 tests total, all passing
2026-03-07 20:06:13 +01:00