Stop a page load from persisting the entitlement projection

Fixkamo-shared-library
Shipped
August 9, 2026 at 1:46 AM UTC
Author
Kamo
Commit
45c38ff

computeEffectiveFeatures added the caller's Hibernate-managed OrgFeature rows straight to its output and then flipped isActive on them. Its own javadoc calls the result display-only, but GET /api/security/org/domain/{host} is @Transactional, public and unauthenticated, and flushes right after — so Hibernate dirty-checked the mutation and wrote it. Harmless while fail-open was true and everything resolved entitled. Once the flag went false it turned 'this app is not in your plan' from a read-time verdict into an irreversible UPDATE: the first anonymous hit on a Free-tier org's host would switch MEET, VOIP, EMAIL, ESIG, SUPPORT, HRS and AI_SUPPORT off in the database, and restoring the plan would not bring them back because the row was already off. Entitlement is computed on read by design — losing it is meant to hide an app, not delete the grant. No damage had occurred yet: the only rows deactivated today predate the flag by twelve hours. The projection now returns detached copies with no id, so an accidental merge fails loudly instead of overwriting. Also makes the platform app catalog alias-safe. **************** is written through the id-based converter into a UNIQUE column, and retired constants share an id with the app that replaced them (DOC_MANAGER with DOCS on 8, AI_CHAT with AI_SUPPORT on 17), so an alias resolves onto the live app's row. Editing the greyed-out 'AI Chat' entry rewrote AI Support's override, and since a save nulls every field the client omitted, opening and saving it could blank that override or set available=false and withhold the app platform-wide. Aliases are no longer catalog keys: they are skipped on read and rejected on write. AppCatalogAliasKeyTest works in converted ids rather than enum constants, because the collision only exists after the converter has flattened them. 1134 tests pass.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing