Andrey Antukh 225eb98de2 🐛 Refuse dead teams in resolve-team-id (PR #12189 review)
Second review round on PR #12189 (pabloalba).

The file re-check added in 87ca7aca53 stops at the file row, but the
organization-owner fallback grants read-only access to non-member org
owners via Nitrate over HTTP, which knows nothing about Penpot
soft-deletion. resolve-team-id resolved the team from unfiltered SQL,
so an expelled org owner kept the file subscription open for an
indefinitely soft-deleted file, project or team. Now both SQL lookups
filter deleted_at, and resolve-team-id checks the team row itself
(db/get*, which filters soft-deleted rows) for every caller — teams,
projects and files alike.

Also from the same review:

- file-readable? now uses the same sql:get-minimal-file as the
  subscribe gate (non-throwing via throw-if-not-exists false), and
  team-readable? projects id and deleted-at, so db/get* can filter.
- The test suite extracts the thrice-duplicated raw delete into
  delete-team-membership!; a sibling of the fail-open pin now redefs
  the existence probe to throw; memory and docstring aligned with the
  code.
- docs/technical-guide/developer/architecture/backend.md attributed
  the websocket to notifications.clj; it now names app.http.websocket
  as the owner and notifications.clj as the revocation publisher.
- mem:backend/auth-permissions-product-domains documents the fallback
  mechanism and the resolve-team-id contract.

Closes #12155

AI-assisted-by: inkling-2-small-free
2026-11-10 12:38:45 +00:00
..
2026-09-09 17:58:09 +02:00
2026-09-29 09:07:34 +02:00
2026-09-09 17:58:09 +02:00