Skip to content

Fix/api hardening - #778

Merged
sajanv88 merged 5 commits into
mainfrom
fix/api-hardening
Nov 1, 2026
Merged

sajanv88 merged 5 commits into
mainfrom
fix/api-hardening

Conversation

@sajanv88

@sajanv88 sajanv88 commented Nov 1, 2026

Copy link
Copy Markdown
Owner

No description provided.

Tenant isolation
- Route each request to its tenant database through a ContextVar instead
  of process-wide Beanie state.
- Only accept a tenant id that exists, and take it from the request
  context rather than the request body.
- Scope the response cache by verified token and tenant.

Access control
- Grant host permissions only outside of a tenant, and keep tenant roles
  from holding them.
- Apply self access to the {user_id} path parameter, not to the caller.
- Require permissions for role changes, plan management, and tenant
  settings, and restrict tenant endpoints to the caller's own tenant.

Authentication
- Rate limit login and password reset requests.
- Generate random secrets for SSO accounts and password reset tokens.
- Validate passwords on every path that sets one.
- Express the refresh token lifetime in days and use it for the cookie.
- Require a signed in owner to register a passkey, and verify against
  the credential that was actually used.

Logging
- Add LOG_LEVEL, defaulting to INFO outside of development.
- Stop logging tokens, user documents and SSO settings.
API
- Return one JSON error shape from every handler, and map forbidden and
  rate limited errors to 403 and 429.
- Answer unknown API routes with a 404 instead of the SPA shell.
- Add security headers and a /health/ready probe for MongoDB and Redis.

Billing
- Serve the Stripe webhook from its own router, authenticated by
  signature instead of a user session.
- Record each invoice once, answer unsupported events with a 200, and
  let storage failures surface so that Stripe retries.
- Fix the checkout success and cancel lookups.

Storage and branding
- Give uploads unique object keys and sign Azure SAS tokens.
- Stop blocking the event loop on S3 uploads.
- Rewind logo uploads before storing them, drop SVG logos, and keep the
  app available when a logo url can't be resolved.

Data
- Evaluate timestamp defaults per document instead of once at import.
- Treat malformed ids as not found.
- Fix AI chat history lookups and scope sessions to their user.
Registering a passkey now needs a signed in account, so the login form
no longer offers it and points people to their profile instead.

- Add an "Add a passkey" action to Manage Security.
- Recover when the remembered tenant no longer exists.
- Read error messages from ApiError without assuming a body.
- Declare typescript as a dev dependency and fix the input event types.
- Rebuild the bundled UI.
- Cover authentication, access control, tenant isolation, billing,
  features, the cache middleware and the API contract.
- Snapshot the OpenAPI document in backend/openapi.json and fail when
  the API drifts from it.
- Force test settings in conftest so that a local .env is never used.
- Run the backend tests and the frontend build in CI.
- Document how to run the tests and update the snapshot.
The v4 bump removed PanelGroup and PanelResizeHandle, which failed the
type check in pnpm build. Move to Group and Separator, and style the
handle from aria-orientation, which replaces data-panel-group-direction.
@sajanv88
sajanv88 merged commit 1307d76 into main Nov 1, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant