LibreChat/api/server
Danny Avila 74de989bde
🚪 fix: Keep Owners From Being Locked Out of Their Own Resource When Sharing (#14347)
* 🔒 fix: Skip revoke for principals also being granted (owner-lockout guard)

bulkUpdateResourcePermissions flushes grants (upserts) before revokes (deletes).
If a principal appears in both updatedPrincipals and revokedPrincipals, the ACL
entry is granted and then immediately deleted, stripping access the caller just
set. This can strip a resource owner's own grant when the share dialog places
the owner in both lists from a client id/idOnTheSource mismatch (OpenID/Entra).

Add a server-side guard: track principals granted in the same request and skip
any revoke for the same principal, so granting wins and owner lockout is
impossible regardless of how the client computes the share diff. Complements the
client-side keying fix in #14317.

Refs #14316

* 🔒 fix: Exclude PUBLIC from grant-wins guard so public-disable is honored

The grant-wins guard must not apply to PrincipalType.PUBLIC. An explicit
public: false disable adds the public principal to the revoke list; a
contradictory payload that also grants public (public in the updated list) would
otherwise skip the revoke and leave the resource public. Disabling public access
must always win. User/group owner-lockout protection is unchanged.

Addresses Codex P2 on #14347.

* 🔒 fix: Move revoke guard inside per-principal try (tolerate malformed entries)

The grant-wins guard read principal.type before the per-principal try/catch, so
a malformed revoke entry (e.g. removed: [null]) would throw out of
bulkUpdateResourcePermissions after grants were already flushed on
non-transactional MongoDB, leaving partial permission changes. Move the guard
inside the try so a malformed entry is recorded in results.errors and skipped,
matching prior behavior.

Addresses Codex P2 on #14347.
2026-07-20 22:27:25 -04:00
..
controllers 🙊 refactor: Clarify Ask Question Schema Errors and Retry Guidance (#14279) 2026-07-15 11:06:29 -04:00
middleware 🔍 refactor: Surface primary OpenID JWT failure reason in auth failure log (#14346) 2026-07-20 21:05:20 -04:00
routes 🧭 feat: Mid-Run Steering and Queued Messages for Agent Runs (#14220) 2026-07-14 10:11:10 -04:00
services 🚪 fix: Keep Owners From Being Locked Out of Their Own Resource When Sharing (#14347) 2026-07-20 22:27:25 -04:00
utils 🔄 feat: Continue Shared Conversations as Personal Copies (#13714) 2026-06-24 16:27:01 -04:00
cleanup.js
experimental.js 🧹 feat: Eager HITL Checkpoint Cleanup (Expiry + Deletion) & Full-Wiring E2E (#14123) 2026-07-05 11:29:30 -04:00
index.js 🧹 feat: Eager HITL Checkpoint Cleanup (Expiry + Deletion) & Full-Wiring E2E (#14123) 2026-07-05 11:29:30 -04:00
index.metrics.spec.js ⚖️ feat: Add Operational Prometheus Metrics (#13265) 2026-05-22 20:47:41 -04:00
index.spec.js ⚙️ refactor: lazy-load React Query Devtools (#13639) 2026-06-10 13:06:20 -04:00
socialLogins.js ⏳ feat: Make OpenID Token Reuse Window Configurable (#13546) 2026-06-06 15:15:58 -04:00
socialLogins.spec.js ⏳ feat: Make OpenID Token Reuse Window Configurable (#13546) 2026-06-06 15:15:58 -04:00
telemetry.js 📡 feat: Add Backend OpenTelemetry Tracing (#12909) 2026-05-14 09:08:55 -04:00
telemetry.spec.js 📡 feat: Add Backend OpenTelemetry Tracing (#12909) 2026-05-14 09:08:55 -04:00