Skip to content

Conversation

@KevLehman
Copy link
Member

@KevLehman KevLehman commented Nov 20, 2025

Proposed changes (including videos or screenshots)

Issue(s)

https://rocketchat.atlassian.net/browse/ABAC-24

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • New Features

    • Paginated ABAC audit API to view attribute/room/subject events with time-range and actor filtering; ABAC operations now accept actor context and emit audit events.
    • New auditing facility to log ABAC events and expose event names/payloads.
  • Tests

    • Expanded end-to-end and unit tests for actor-aware flows, auditing, attribute updates/deletions, and room scenarios.
  • Types & Schemas

    • Added audit-related typings and request/response schemas.
  • Utilities

    • Added a utility to compute semantic diffs of attribute sets.
  • Models/Exports

    • Exposed server-audit model and actor type in public exports.

✏️ Tip: You can customize this high-level summary in your review settings.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Nov 20, 2025

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Nov 20, 2025

⚠️ No Changeset found

Latest commit: 4a34e00

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 20, 2025

Walkthrough

Threads an optional minimal actor through ABAC APIs and service methods, adds a centralized Audit module emitting typed ServerEvents, introduces audit schemas and a GET /abac/audit endpoint, extends core typings/exports and models registration, and updates tests to be actor-aware and assert audit emissions.

Changes

Cohort / File(s) Summary
ABAC API endpoints
apps/meteor/ee/server/api/abac/index.ts
Extract actor from current user and pass it into Abac service calls; add public GET /abac/audit endpoint with auth/license/permission checks, pagination, and query/response schemas.
ABAC API schemas
apps/meteor/ee/server/api/abac/schemas.ts
Add GETAbacAuditEventsQuerySchema and GETAbacAuditEventsResponseSchema validators; import IAuditServerActor/IServerEvent.
ABAC audit core
ee/packages/abac/src/audit.ts
New centralized Audit module mapping ABAC event keys to payload types and emitting typed ServerEvents via ServerEvents.createAuditServerEvent.
ABAC service implementation
ee/packages/abac/src/index.ts
Thread optional actor through public methods, replace ad-hoc logs with Audit.* calls, and use diffAttributes for change detection and auditing.
ABAC helpers
ee/packages/abac/src/helper.ts
Add diffAttributes(a, b) utility to compute semantic diffs of attribute definitions.
ABAC tests & mocks
ee/packages/abac/src/*.spec.ts, ee/packages/abac/src/index.spec.ts, ee/packages/abac/src/can-access-object.spec.ts, ee/packages/abac/src/subject-attributes-validations.spec.ts, ee/packages/abac/src/user-auto-removal.spec.ts
Make tests actor-aware (fakeActor), add mocks/spies for ServerEvents.createAuditServerEvent and Audit, seed dummy DB records, and update expectations to validate audit emissions.
End-to-end tests
apps/meteor/tests/end-to-end/api/abac.ts
Add tests for key updates and deletion scenarios; remove unused console.log and adapt flows to actor/audit semantics.
Core typings (audit)
packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts, packages/core-typings/src/index.ts
Add ABAC audit event typings (MinimalUser/MinimalRoom/reason/change types/diffs and event interfaces), augment server event mappings, and export/register them.
Service interface & exports
packages/core-services/src/types/IAbacService.ts, packages/core-services/src/index.ts
Add AbacActor type and make actor? optional on many IAbacService methods; re-export AbacActor from core-services index.
Models registration
packages/models/src/index.ts
Register ServerEventsRaw in model registration so ServerEvents model is available for audit storage and querying.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API as ABAC Endpoint
    participant Service as AbacService
    participant Audit as Audit Module
    participant SE as ServerEvents Model

    Client->>API: HTTP request (session user)
    API->>API: getActorFromUser(this.user) → actor
    API->>Service: Abac.method(..., actor)
    Service->>Service: perform ABAC operation
    Service->>Audit: Audit.<event>(payload, actor)
    Audit->>SE: ServerEvents.createAuditServerEvent(event, payload, actor)
    SE-->>Audit: persisted (async)
    Audit-->>Service: resolved
    Service-->>API: operation result
    API-->>Client: HTTP response

    alt Query audit events
        Client->>API: GET /abac/audit?start=&end=&offset=&count=&actor=...
        API->>SE: ServerEvents.findPaginated(filter by time/type/actor, pagination, sort)
        SE-->>API: paginated events
        API-->>Client: events + pagination
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • Actor propagation across API → service → audit calls and optional vs required actor parameters.
    • Audit payload shapes vs new core-typings (ensure fields align with IServerEvent interfaces).
    • ServerEvents model registration and async semantics (createAuditServerEvent / findPaginated).
    • Test updates/mocks that replace logging with Audit assertions and seeded DB setup.

Possibly related PRs

Suggested labels

stat: QA assured

Suggested reviewers

  • tassoevan
  • MartinSchoeler

Poem

🐰 I hopped through modules, soft and spry,

I threaded actors, watched logs fly by,
I nudged diffs gently, left no unknown,
Now every ABAC change is shown,
🥕 — from a happy coding rabbit.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: Audit ABAC actions' is concise, clear, and directly summarizes the main objective of implementing ABAC audit logging.
Linked Issues check ✅ Passed The pull request implements the core requirements from ABAC-24: adds central Audit helper in ABAC package, threads actor context through all ABAC operations, emits structured audit events for attribute CRUD and room attribute changes, and exposes an audit endpoint with actor filtering.
Out of Scope Changes check ✅ Passed All changes are directly aligned with implementing ABAC auditing: audit event types, Audit helper, actor parameter threading, audit endpoint, and supporting test infrastructure. No unrelated refactoring or scope creep detected.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/audit-events

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 84e7662 and 4a34e00.

📒 Files selected for processing (1)
  • ee/packages/abac/src/audit.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • ee/packages/abac/src/audit.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 20, 2025

📦 Docker Image Size Report

📈 Changes

Service Current Baseline Change Percent
sum of all images 1.2GiB 1.2GiB +12MiB
rocketchat 358MiB 346MiB +12MiB
omnichannel-transcript-service 132MiB 132MiB +13KiB
queue-worker-service 132MiB 132MiB +11KiB
ddp-streamer-service 127MiB 127MiB +10KiB
account-service 114MiB 114MiB +12KiB
authorization-service 111MiB 111MiB +60KiB
stream-hub-service 111MiB 111MiB +8.7KiB
presence-service 111MiB 111MiB +9.4KiB

📊 Historical Trend

---
config:
  theme: "dark"
  xyChart:
    width: 900
    height: 400
---
xychart
  title "Image Size Evolution by Service (Last 30 Days + This PR)"
  x-axis ["11/15 22:28", "11/16 01:28", "11/17 23:50", "11/18 22:53", "11/19 23:02", "11/21 16:49", "11/24 17:34", "11/27 22:32", "11/28 14:39 (PR)"]
  y-axis "Size (GB)" 0 --> 0.5
  line "account-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "authorization-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "ddp-streamer-service" [0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13]
  line "presence-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "queue-worker-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13]
  line "rocketchat" [0.36, 0.36, 0.35, 0.35, 0.35, 0.34, 0.34, 0.34, 0.35]
  line "stream-hub-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
Loading

Statistics (last 8 days):

  • 📊 Average: 1.5GiB
  • ⬇️ Minimum: 1.2GiB
  • ⬆️ Maximum: 1.6GiB
  • 🎯 Current PR: 1.2GiB
ℹ️ About this report

This report compares Docker image sizes from this build against the develop baseline.

  • Tag: pr-37565
  • Baseline: develop
  • Timestamp: 2025-11-28 14:39:34 UTC
  • Historical data points: 8

Updated: Fri, 28 Nov 2025 14:39:35 GMT

@codecov
Copy link

codecov bot commented Nov 20, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 54.03%. Comparing base (d852553) to head (4a34e00).
⚠️ Report is 1 commits behind head on feat/abac.

Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##           feat/abac   #37565      +/-   ##
=============================================
- Coverage      54.07%   54.03%   -0.04%     
=============================================
  Files           2661     2661              
  Lines          50149    50149              
  Branches       11213    11213              
=============================================
- Hits           27116    27098      -18     
- Misses         20903    20918      +15     
- Partials        2130     2133       +3     
Flag Coverage Δ
e2e 57.32% <ø> (-0.05%) ⬇️
e2e-api 42.28% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@KevLehman KevLehman force-pushed the chore/audit-events branch 2 times, most recently from d416b1c to 7ecc215 Compare November 24, 2025 17:13
@KevLehman KevLehman marked this pull request as ready for review November 26, 2025 14:35
@KevLehman KevLehman requested review from a team as code owners November 26, 2025 14:35
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/meteor/tests/end-to-end/api/abac.ts (1)

260-310: Remove duplicate test.

Lines 260-277 and 279-310 both test updating only the key of an attribute, with nearly identical test names ("PUT should update key only" vs "PUT should update key only (key-updated)"). The second test (279-310) creates a new attribute and performs the same verification as the first. This duplication reduces test suite maintainability.

Apply this diff to remove the duplicate:

-
-		it('PUT should update key only (key-updated)', async () => {
-			const testKey = `${initialKey}_update_test`;
-			await request
-				.post(`${v1}/abac/attributes`)
-				.set(credentials)
-				.send({ key: testKey, values: ['val1', 'val2'] })
-				.expect(200);
-
-			const listRes = await request.get(`${v1}/abac/attributes`).query({ key: testKey }).set(credentials).expect(200);
-
-			const attr = listRes.body.attributes.find((a: any) => a.key === testKey);
-			expect(attr).to.exist;
-			const attrId = attr._id;
-
-			const newKey = `${initialKey}_update_test_renamed`;
-			await request
-				.put(`${v1}/abac/attributes/${attrId}`)
-				.set(credentials)
-				.send({ key: newKey })
-				.expect(200)
-				.expect((res) => {
-					expect(res.body).to.have.property('success', true);
-				});
-
-			await request
-				.get(`${v1}/abac/attributes/${attrId}`)
-				.set(credentials)
-				.expect(200)
-				.expect((res) => {
-					expect(res.body).to.have.property('key', newKey);
-				});
-		});
ee/packages/abac/src/index.ts (1)

310-316: Audit emits before confirming attribute change occurred.

Audit.objectAttributeChanged is called at Line 311 unconditionally, but the actual change detection happens at Lines 314-316. If didAttributesChange returns false, an audit entry is still emitted even though no effective change occurred. Consider moving the audit inside the conditional or adjusting the change type.

 		const updated = await Rooms.setAbacAttributesById(rid, normalized);
-		void Audit.objectAttributeChanged({ _id: room._id }, room.abacAttributes || [], normalized, 'updated', actor);

 		const previous: IAbacAttributeDefinition[] = room.abacAttributes || [];
 		if (this.didAttributesChange(previous, normalized)) {
+			void Audit.objectAttributeChanged({ _id: room._id }, previous, normalized, 'updated', actor);
 			await this.onRoomAttributesChanged(room, (updated?.abacAttributes as IAbacAttributeDefinition[] | undefined) ?? normalized);
 		}
🧹 Nitpick comments (5)
apps/meteor/tests/end-to-end/api/abac.ts (1)

144-144: Consider removing the unused request call.

This line makes a request but discards the response. If the intention is to verify the endpoint doesn't crash, consider adding an expectation or removing the call entirely.

apps/meteor/ee/server/api/abac/schemas.ts (1)

201-233: Consider adding success to the required fields array.

The response schema includes success in properties but doesn't list it in required. While the API wrapper may handle this, aligning the schema with the actual response contract would be more precise.

-	required: ['events', 'count', 'offset', 'total'],
+	required: ['success', 'events', 'count', 'offset', 'total'],
ee/packages/abac/src/audit.ts (1)

39-39: Hardcoded IP and empty useragent reduce audit trail value.

The actor's IP is hardcoded as '0.0.0.0' and useragent as ''. If this information is available from the request context, threading it through would improve forensic value of audit logs.

Consider whether the AbacActor type could be extended to include ip and useragent fields populated from the API request context in getActorFromUser().

packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts (2)

25-53: Consider adding previous to IServerEventAbacAttributeChanged for consistency.

IServerEventAbacObjectAttributeChanged includes both previous and current attribute definitions, but IServerEventAbacAttributeChanged (Lines 44-53) only has current and diff. For attribute CRUD operations (especially deletions and updates), having previous would align with the linked issue's requirement for "before/after diffs for value changes."

 interface IServerEventAbacAttributeChanged
 	extends IAuditServerEventType<
 		| { key: 'attributeKey'; value: string }
 		| { key: 'reason'; value: AbacAuditReason }
 		| { key: 'change'; value: AbacAttributeDefinitionChangeType }
+		| { key: 'previous'; value: IAbacAttributeDefinition | null | undefined }
 		| { key: 'current'; value: IAbacAttributeDefinition | null | undefined }
 		| { key: 'diff'; value: IAbacAttributeDefinition | undefined }
 	> {
 	t: 'abac.attribute.changed';
 }

55-70: ValidAbacEvents includes 'abac.object.attributes.removed' but lacks a dedicated interface.

The union type at Line 70 lists 'abac.object.attributes.removed', and Line 78 maps it to IServerEventAbacObjectAttributeChanged. This reuse is intentional (per AI summary), but the discrepancy could cause confusion. Consider adding a brief comment or type alias clarifying that abac.object.attributes.removed reuses the same payload structure.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 009716e and fafa44d.

📒 Files selected for processing (15)
  • apps/meteor/ee/server/api/abac/index.ts (13 hunks)
  • apps/meteor/ee/server/api/abac/schemas.ts (2 hunks)
  • apps/meteor/tests/end-to-end/api/abac.ts (4 hunks)
  • ee/packages/abac/src/audit.ts (1 hunks)
  • ee/packages/abac/src/can-access-object.spec.ts (1 hunks)
  • ee/packages/abac/src/helper.ts (1 hunks)
  • ee/packages/abac/src/index.spec.ts (34 hunks)
  • ee/packages/abac/src/index.ts (22 hunks)
  • ee/packages/abac/src/subject-attributes-validations.spec.ts (1 hunks)
  • ee/packages/abac/src/user-auto-removal.spec.ts (14 hunks)
  • packages/core-services/src/index.ts (1 hunks)
  • packages/core-services/src/types/IAbacService.ts (1 hunks)
  • packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts (1 hunks)
  • packages/core-typings/src/index.ts (2 hunks)
  • packages/models/src/index.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
  • ee/packages/abac/src/can-access-object.spec.ts
  • packages/core-services/src/index.ts
  • packages/core-typings/src/index.ts
  • ee/packages/abac/src/helper.ts
  • packages/models/src/index.ts
  • apps/meteor/tests/end-to-end/api/abac.ts
  • apps/meteor/ee/server/api/abac/schemas.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
  • packages/core-services/src/types/IAbacService.ts
  • apps/meteor/ee/server/api/abac/index.ts
  • packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts
  • ee/packages/abac/src/index.spec.ts
  • ee/packages/abac/src/index.ts
  • ee/packages/abac/src/audit.ts
**/*.spec.ts

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.spec.ts: Use descriptive test names that clearly communicate expected behavior in Playwright tests
Use .spec.ts extension for test files (e.g., login.spec.ts)

Files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
  • ee/packages/abac/src/can-access-object.spec.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `test.beforeAll()` and `test.afterAll()` for setup/teardown in Playwright tests

Applied to files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
  • apps/meteor/tests/end-to-end/api/abac.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure clean state for each test execution in Playwright tests

Applied to files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Maintain test isolation between test cases in Playwright tests

Applied to files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `test.step()` for complex test scenarios to improve organization in Playwright tests

Applied to files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (`test`, `page`, `expect`) for consistency in test files

Applied to files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • ee/packages/abac/src/subject-attributes-validations.spec.ts
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • apps/meteor/tests/end-to-end/api/abac.ts
  • apps/meteor/ee/server/api/abac/schemas.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
  • packages/core-services/src/types/IAbacService.ts
  • apps/meteor/ee/server/api/abac/index.ts
  • ee/packages/abac/src/index.ts
  • ee/packages/abac/src/audit.ts
📚 Learning: 2025-10-24T17:32:05.348Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.

Applied to files:

  • apps/meteor/tests/end-to-end/api/abac.ts
  • apps/meteor/ee/server/api/abac/schemas.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
  • packages/core-services/src/types/IAbacService.ts
  • apps/meteor/ee/server/api/abac/index.ts
  • ee/packages/abac/src/index.spec.ts
  • ee/packages/abac/src/index.ts
📚 Learning: 2025-10-06T20:30:45.540Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37152
File: packages/apps-engine/tests/test-data/storage/storage.ts:101-122
Timestamp: 2025-10-06T20:30:45.540Z
Learning: In `packages/apps-engine/tests/test-data/storage/storage.ts`, the stub methods (updatePartialAndReturnDocument, updateStatus, updateSetting, updateAppInfo, updateMarketplaceInfo) intentionally throw "Method not implemented." Tests using these methods must stub them using `SpyOn` from the test library rather than relying on actual implementations.

Applied to files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.

Applied to files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.

Applied to files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `expect` matchers for assertions (`toEqual`, `toContain`, `toBeTruthy`, `toHaveLength`, etc.) instead of `assert` statements in Playwright tests

Applied to files:

  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,spec.ts} : Follow Page Object Model pattern consistently in Playwright tests

Applied to files:

  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-11-04T16:49:19.107Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37377
File: apps/meteor/ee/server/hooks/federation/index.ts:86-88
Timestamp: 2025-11-04T16:49:19.107Z
Learning: In Rocket.Chat's federation system (apps/meteor/ee/server/hooks/federation/), permission checks follow two distinct patterns: (1) User-initiated federation actions (creating rooms, adding users to federated rooms, joining from invites) should throw MeteorError to inform users they lack 'access-federation' permission. (2) Remote server-initiated federation events should silently skip/ignore when users lack permission. The beforeAddUserToRoom hook only executes for local user-initiated actions, so throwing an error there is correct. Remote federation events are handled separately by the federation Matrix package with silent skipping logic.

Applied to files:

  • ee/packages/abac/src/index.ts
📚 Learning: 2025-10-28T16:53:42.761Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.

Applied to files:

  • ee/packages/abac/src/index.ts
🧬 Code graph analysis (5)
ee/packages/abac/src/helper.ts (1)
packages/core-typings/src/IAbacAttribute.ts (1)
  • IAbacAttributeDefinition (3-14)
ee/packages/abac/src/user-auto-removal.spec.ts (2)
ee/packages/abac/src/index.ts (1)
  • AbacService (17-846)
ee/packages/abac/src/audit.ts (1)
  • Audit (29-146)
packages/core-services/src/types/IAbacService.ts (4)
packages/core-services/src/index.ts (2)
  • AbacActor (56-56)
  • IAbacService (56-56)
packages/core-typings/src/IUser.ts (1)
  • IUser (187-258)
packages/core-typings/src/IAbacAttribute.ts (2)
  • IAbacAttributeDefinition (3-14)
  • IAbacAttribute (16-16)
packages/core-typings/src/IRoom.ts (1)
  • IRoom (22-98)
packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts (3)
packages/core-typings/src/IUser.ts (1)
  • IUser (187-258)
packages/core-typings/src/IRoom.ts (1)
  • IRoom (22-98)
packages/core-typings/src/IAbacAttribute.ts (1)
  • IAbacAttributeDefinition (3-14)
ee/packages/abac/src/index.ts (3)
ee/packages/abac/src/helper.ts (1)
  • diffAttributes (36-78)
ee/packages/abac/src/audit.ts (1)
  • Audit (29-146)
packages/core-services/src/types/IAbacService.ts (1)
  • AbacActor (11-11)
🪛 GitHub Check: 🔎 Code Check / Code Lint
ee/packages/abac/src/audit.ts

[warning] 116-116:
Forbidden non-null assertion


[warning] 103-103:
Forbidden non-null assertion


[warning] 84-84:
Forbidden non-null assertion


[warning] 65-65:
Forbidden non-null assertion


[warning] 52-52:
Forbidden non-null assertion


[warning] 39-39:
Forbidden non-null assertion

🔇 Additional comments (39)
packages/core-services/src/types/IAbacService.ts (2)

11-11: LGTM! Clean actor type definition.

The AbacActor type appropriately captures the minimal user context needed for auditing ABAC operations.


14-49: LGTM! Consistent actor parameter addition.

The optional actor?: AbacActor parameter has been consistently added to all ABAC mutation methods, enabling actor-aware auditing across the service surface. Note that canAccessObject correctly omits the actor parameter as it's a query operation rather than an audited mutation.

ee/packages/abac/src/can-access-object.spec.ts (1)

24-26: LGTM! Necessary mock for audit functionality.

The ServerEvents.createAuditServerEvent mock is correctly added to support the audit event creation introduced by this PR.

packages/core-typings/src/index.ts (1)

3-3: LGTM! Correct public API exposure.

The import and export of IAuditServerAbacAction correctly exposes ABAC audit event types to the public API, following the established pattern for other audit event types in this file.

Also applies to: 154-154

ee/packages/abac/src/subject-attributes-validations.spec.ts (1)

17-19: LGTM! Test collection initialization.

The dummy collection initialization ensures the database has at least one collection before registering service models, which is a reasonable test setup pattern. The @ts-expect-error directive is appropriate here since this is test-only scaffolding outside the production schema.

packages/models/src/index.ts (1)

123-123: LGTM! ServerEvents model registration.

The import and registration of ServerEventsRaw correctly wires the ServerEvents model into the public model surface, following the established pattern for other models in this file.

Also applies to: 268-268

packages/core-services/src/index.ts (1)

56-56: LGTM! AbacActor public export.

Adding AbacActor to the public exports enables consumers to properly type actor parameters when calling ABAC service methods, completing the actor-aware ABAC integration.

apps/meteor/ee/server/api/abac/schemas.ts (2)

1-1: LGTM!

Import addition for IAuditServerActor is appropriate for the new audit event query schema.


152-199: LGTM!

The query schema correctly validates audit event filters with date-time formatted strings, pagination fields, and actor filtering. The additionalProperties: false ensures strict validation.

ee/packages/abac/src/user-auto-removal.spec.ts (5)

7-7: LGTM!

Import of Audit module enables proper mocking and verification of audit events in tests.


32-32: LGTM!

The fakeActor constant provides a consistent actor context for all test cases, properly typed with _id, username, and type fields matching the AbacActor interface.


81-96: LGTM!

Test setup correctly initializes the audit spy with mockResolvedValue() for the async Audit.actionPerformed method, and properly clears it in beforeEach.


136-142: LGTM!

Audit assertions correctly verify that Audit.actionPerformed is called with expected parameters: audited users, room ID, and the 'room-attributes-change' reason. The extraction of user IDs and use of Set for room/action verification is clean.


274-289: LGTM!

Multi-attribute test properly verifies AND semantics enforcement with audit logging for all non-compliant users (u2, u3, u5).

ee/packages/abac/src/audit.ts (2)

119-134: LGTM!

The actionPerformed method correctly uses { type: 'system' } as the actor for automated membership revocation actions, which is appropriate since these are triggered by system-level ABAC enforcement rather than direct user actions.


135-145: LGTM!

The subjectAttributeChanged method properly logs LDAP-sync-triggered attribute changes with a system actor context.

ee/packages/abac/src/index.spec.ts (4)

5-6: LGTM!

The fakeActor constant provides consistent actor context for unit tests, matching the AbacActor interface structure.


25-25: LGTM!

New mock for findOneAndUpdate supports the updated ABAC attribute update flow.


57-59: LGTM!

The ServerEvents.createAuditServerEvent mock prevents audit calls from failing tests while allowing the service logic to be tested in isolation.


386-416: LGTM!

The addAbacAttribute tests properly include fakeActor in all service calls while maintaining the existing behavior verification for valid insertions, error handling, and duplicate detection.

apps/meteor/ee/server/api/abac/index.ts (5)

32-39: LGTM!

The getActorFromUser helper cleanly extracts actor context with proper handling of undefined/null users. The optional chaining and ternary provide safe fallback.


66-66: LGTM!

Actor context is now properly threaded to setRoomAbacAttributes for audit logging.


360-409: Audit endpoint implementation looks solid with a few observations.

The endpoint correctly:

  • Requires authentication and abac-management permission
  • Requires both abac and auditing licenses
  • Filters by event types, time range, and optional actor
  • Uses allowDiskUse: true for large result sets
  • Defaults sort to descending timestamp

Minor consideration: The event type strings are hardcoded. If these are defined as constants elsewhere (e.g., in core-typings), referencing them would reduce duplication.


384-387: Verify the date range filter behavior when start or end is undefined.

When start is undefined, it defaults to new Date(0) (epoch). When end is undefined, it defaults to new Date() (now). This seems intentional but verify this matches expected behavior - querying all events from epoch to now when no filters are provided could return a very large dataset.

Consider whether this default behavior aligns with UX expectations, or if a reasonable default window (e.g., last 30 days) would be more appropriate for the common case.


375-377: Validate that this.queryParams type casting is necessary.

The cast this.queryParams as Record<string, string | number | null | undefined> differs from similar casts elsewhere in the file that include string[]. Verify this is intentional and won't cause type-related issues with array query parameters.

packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts (2)

1-4: LGTM!

The imports and minimal type definitions are appropriate for audit event payloads—picking only essential fields (_id, username for users; _id for rooms) minimizes log size while retaining identifiability.


6-23: LGTM!

The type definitions cover the expected audit reasons and change types comprehensively. The diff structure with optional added, removed, and renamedFrom fields supports flexible change tracking.

ee/packages/abac/src/index.ts (12)

11-12: LGTM!

The new imports for Audit and diffAttributes are correctly added to support the audit functionality.


68-72: LGTM!

Proper diff-based audit for subject attribute changes. The conditional check ensures audits are only emitted when there are meaningful diffs, avoiding noise.


74-88: LGTM!

Actor threading and audit call for attribute creation are correctly implemented. Using void for fire-and-forget async audit is appropriate per the requirements (non-blocking).


241-254: LGTM!

Actor threading and audit call for attribute deletion are correctly implemented.


300-304: LGTM!

Proper early-return audit when clearing all room ABAC attributes.


389-437: LGTM!

Actor threading and differentiated audit calls for key-added vs key-updated are correctly implemented. The early return at Lines 426-428 properly skips audit when values are unchanged.


463-477: LGTM!

Correct differentiation between removing the last attribute (objectAttributesRemoved) and removing one of many (objectAttributeRemoved).


536-544: LGTM!

Audit correctly placed after the DB update, using the updated room attributes from the DB result.


646-654: LGTM!

Audit for action performed correctly records each user removal with room context and reason.


729-731: LGTM!

Audit for realtime policy evaluation correctly records access revocation when user is non-compliant.


776-786: LGTM!

Audit calls for LDAP-sync triggered removals are correctly placed with appropriate reason. Both the no-attributes and non-compliant attribute paths are covered.

Also applies to: 800-810


507-512: Audit log may record incomplete state when concurrent ABAC attribute additions occur.

The concern is partially valid. While a check at line 503-504 prevents the exact duplicate-key race condition, a different-key race condition remains:

  1. Thread A and B both call addRoomAbacAttributeByKey with different keys
  2. Both read room.abacAttributes into previous at roughly the same time
  3. Thread A's insertAbacAttributeIfNotExistsById succeeds and persists key1
  4. Thread B's insertAbacAttributeIfNotExistsById succeeds and persists key2
  5. If Thread B's read happened before Thread A's write was visible, previous won't include key1
  6. The fallback [...previous, { key: key2, values }] used for the Audit log won't reflect the actual DB state (which includes both key1 and key2)

The Audit record will show an incomplete state. Use updated?.abacAttributes unconditionally or re-fetch the room state from the database to ensure log accuracy:

const updated = await Rooms.insertAbacAttributeIfNotExistsById(rid, key, values);
const next = updated?.abacAttributes ?? (await Rooms.findOneById(rid, { projection: { abacAttributes: 1 } }))?.abacAttributes ?? [...previous, { key, values }];

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ee/packages/abac/src/index.ts (1)

27-72: Subject-attribute audit misses full-removal cases

addSubjectAttributes only calls Audit.subjectAttributeChanged when finalAttributes.length > 0, and diffAttributes(user?.abacAttributes, finalAttributes) currently returns [] when finalAttributes is empty. As a result, a user losing all ABAC attributes after LDAP sync is never logged via abac.subject.attribute.changed, even though you log the resulting room removals.

If the intent of subjectAttributeChanged is to track LDAP diffs, consider:

  • Emitting an event also when finalAttributes is empty (e.g., passing the previous attributes as the diff for “all removed”), and/or
  • Adjusting diffAttributes so (a ≠ [], b = []) yields a non-empty diff representing the removed keys.

This keeps subject-level audit trails consistent with room/definition diffs.

♻️ Duplicate comments (4)
apps/meteor/tests/end-to-end/api/abac.ts (1)

644-673: Misplaced and potentially duplicate “DELETE attribute definition” test

This it('DELETE attribute definition should remove the key (key-removed)'...) lives under “Default and Team Default Room Restrictions”, but it validates plain attribute‑definition deletion semantics (create attribute → delete by id → GET fails). That behavior is unrelated to default/team restriction logic and is already covered in the more focused “Usage & Deletion” section.

Consider moving this test next to the other attribute CRUD/deletion tests (or removing it if it’s redundant with an existing “key-removed” test) to keep suites organized and avoid duplicated coverage.

ee/packages/abac/src/index.ts (1)

74-88: Attribute CRUD audit uses pre-update “current” and a partial modifier as diff

In updateAbacAttributeById you call:

await AbacAttributes.updateOne({ _id }, { $set: modifier });
void Audit.attributeUpdated(existing, modifier as IAbacAttributeDefinition, actor);

Issues:

  • existing is the pre-update document, but Audit.attributeUpdated’s current parameter is meant to represent the post-update state.
  • modifier may contain only key or only values, so casting it to IAbacAttributeDefinition can produce incomplete or inconsistent shapes for the diff field.

This makes it hard for consumers of abac.attribute.changed events to reconstruct accurate before/after state or field-level diffs.

A more precise pattern would be:

  • Use findOneAndUpdate with { returnDocument: 'after' } (or a follow-up findOneById) to obtain the updated document.
  • Pass current as the updated attribute and diff as a properly-computed diff (e.g., via a helper).

Illustrative change:

- await AbacAttributes.updateOne({ _id }, { $set: modifier });
- void Audit.attributeUpdated(existing, modifier as IAbacAttributeDefinition, actor);
+ const updated = await AbacAttributes.findOneAndUpdate(
+   { _id },
+   { $set: modifier },
+   { returnDocument: 'after', projection: { key: 1, values: 1 } },
+ );
+ if (updated) {
+   void Audit.attributeUpdated(updated as IAbacAttributeDefinition, {
+     key: updated.key,
+     values: updated.values,
+   }, actor);
+ }

Also applies to: 189-239, 241-254

ee/packages/abac/src/helper.ts (1)

36-77: diffAttributes drops “all-removed” cases and still returns an ambiguous flat diff shape

  • When a is non‑empty and b is empty, this returns [], so addSubjectAttributes will not emit Audit.subjectAttributeChanged when a user loses all ABAC attributes. That seems at odds with having a dedicated subject diff event and with ABAC‑24’s goal of auditing attribute changes, especially LDAP‑driven removals.
  • The returned IAbacAttributeDefinition[] still conflates:
    • keys only in a (removals, using a’s values),
    • keys in both with differing sets (changes, using b’s values),
    • keys only in b (additions, using b’s values),
      with no way for consumers to distinguish which is which.

Consider:

  • Treating b empty as “all keys removed” and returning a in that case, so subject‑attribute removal is auditable; and
  • Either:
    • introducing a structured diff type (e.g. { added: IAbacAttributeDefinition[]; removed: ...; changed: ... }), or
    • clearly documenting the current conventions at the type/JSdoc level so audit consumers can interpret entries correctly.

Example change for the all‑removed case:

 export function diffAttributes(a: IAbacAttributeDefinition[] = [], b: IAbacAttributeDefinition[] = []): IAbacAttributeDefinition[] {
-	if (!a?.length && b?.length) {
-		return b;
-	}
-
-	if (!b?.length) {
-		return [];
-	}
+	if (!a?.length && b?.length) {
+		return b;
+	}
+
+	if (!b?.length) {
+		// everything from `a` was removed
+		return a;
+	}
ee/packages/abac/src/audit.ts (1)

30-41: Avoid actor.username! and factor a shared audit-actor helper

All user-actor payloads here use a non-null assertion on actor.username and duplicate the same literal object:

{ type: 'user', _id: actor._id, username: actor.username!, ip: '0.0.0.0', useragent: '' }

This both violates the lint rule already reported on this file and is brittle if AbacActor['username'] is ever absent.

Consider centralizing the mapping and handling the optional username once:

const toAuditUserActor = (actor: AbacActor): IAuditServerActor => ({
	type: 'user',
	_id: actor._id,
	username: actor.username ?? 'unknown', // or make username required on AbacActor
	ip: '0.0.0.0',
	useragent: '',
});

Then each method can just call toAuditUserActor(actor) instead of repeating the object and using !.

Also applies to: 42-54, 55-67, 68-86, 87-105, 106-118

🧹 Nitpick comments (4)
apps/meteor/tests/end-to-end/api/abac.ts (1)

143-153: Avoid redundant key‑update coverage and unused pre‑flight GET

  • The GET at Line 144 doesn’t feed assertions; it can be dropped unless you’re intentionally sanity‑checking the listing path here.
  • You now have two very similar tests:
    • it('PUT should update key only', ...) using attributeId, and
    • it('PUT should update key only (key-updated)', ...) creating a fresh attribute.
      Both assert that a single PUT renames the key and that a subsequent GET by id returns the new key. Unless you need two distinct flows for some reason (e.g., one for initial attribute and one for later‑created definitions), consider merging them to avoid extra test time and maintenance surface.

Also applies to: 279-310

ee/packages/abac/src/index.ts (1)

613-669: Fire-and-forget Audit calls may surface as unhandled rejections

Across onRoomAttributesChanged, canAccessObject, and onSubjectAttributesChanged you fire audit calls as void Audit.actionPerformed(...) without awaiting or catching:

  • If Audit.* (or ServerEvents.createAuditServerEvent) ever rejects (e.g., transient DB issues), these promises will be unhandled, which in modern Node.js can terminate the process depending on configuration.

To keep audits non-blocking but safe, consider wrapping them in a catch:

void Audit.actionPerformed(...).catch((err) => {
	this.logger.error({ msg: 'ABAC audit emission failed', err });
});

Same pattern could be applied to the other void Audit.* sites.

Also applies to: 671-737, 758-821

ee/packages/abac/src/audit.ts (1)

119-134: actionPerformed is hard‑coded to revocations despite its generic name

Audit.actionPerformed always emits action: 'revoked-object-access', but the name suggests it could cover other ABAC actions (e.g., approved manual access, policy evaluation outcomes).

If you expect additional ABAC membership actions, consider either:

  • Adding an action parameter (with a string literal union in IServerEventAbacActionPerformed), or
  • Renaming this helper to something like accessRevoked and adding separate helpers for other actions later.
packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts (1)

65-79: Align t literal for 'abac.object.attributes.removed' with its event name

In the IServerEvents augmentation, 'abac.object.attributes.removed' is mapped to IServerEventAbacObjectAttributeChanged, whose t is declared as:

t: 'abac.object.attribute.changed';

This means IServerEvents['abac.object.attributes.removed']['t'] will still be typed as 'abac.object.attribute.changed', which is misleading and may break code that narrows on t.

It would be clearer to either introduce a dedicated interface or widen the literal:

+interface IServerEventAbacObjectAttributesRemoved
+  extends IAuditServerEventType<
+    | { key: 'room'; value: MinimalRoom }
+    | { key: 'reason'; value: AbacAuditReason }
+    | { key: 'previous'; value: IAbacAttributeDefinition[] }
+    | { key: 'current'; value: IAbacAttributeDefinition[] | null }
+    | { key: 'change'; value: AbacAttributeDefinitionChangeType }
+  > {
+  t: 'abac.object.attributes.removed';
+}
...
 declare module '../IServerEvent' {
   interface IServerEvents {
     'abac.subject.attribute.changed': IServerEventAbacSubjectAttributeChanged;
     'abac.object.attribute.changed': IServerEventAbacObjectAttributeChanged;
     'abac.attribute.changed': IServerEventAbacAttributeChanged;
     'abac.action.performed': IServerEventAbacActionPerformed;
-    'abac.object.attributes.removed': IServerEventAbacObjectAttributeChanged;
+    'abac.object.attributes.removed': IServerEventAbacObjectAttributesRemoved;
   }
 }

This keeps the event key and the t literal in sync for both variants.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fafa44d and 045f829.

📒 Files selected for processing (15)
  • apps/meteor/ee/server/api/abac/index.ts (13 hunks)
  • apps/meteor/ee/server/api/abac/schemas.ts (2 hunks)
  • apps/meteor/tests/end-to-end/api/abac.ts (4 hunks)
  • ee/packages/abac/src/audit.ts (1 hunks)
  • ee/packages/abac/src/can-access-object.spec.ts (1 hunks)
  • ee/packages/abac/src/helper.ts (1 hunks)
  • ee/packages/abac/src/index.spec.ts (34 hunks)
  • ee/packages/abac/src/index.ts (22 hunks)
  • ee/packages/abac/src/subject-attributes-validations.spec.ts (1 hunks)
  • ee/packages/abac/src/user-auto-removal.spec.ts (14 hunks)
  • packages/core-services/src/index.ts (1 hunks)
  • packages/core-services/src/types/IAbacService.ts (1 hunks)
  • packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts (1 hunks)
  • packages/core-typings/src/index.ts (2 hunks)
  • packages/models/src/index.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • ee/packages/abac/src/subject-attributes-validations.spec.ts
  • packages/core-services/src/index.ts
  • packages/core-typings/src/index.ts
  • ee/packages/abac/src/can-access-object.spec.ts
  • packages/models/src/index.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/ee/server/api/abac/schemas.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/helper.ts
  • ee/packages/abac/src/index.spec.ts
  • ee/packages/abac/src/index.ts
  • apps/meteor/tests/end-to-end/api/abac.ts
  • packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts
  • apps/meteor/ee/server/api/abac/index.ts
  • ee/packages/abac/src/audit.ts
  • packages/core-services/src/types/IAbacService.ts
**/*.spec.ts

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.spec.ts: Use descriptive test names that clearly communicate expected behavior in Playwright tests
Use .spec.ts extension for test files (e.g., login.spec.ts)

Files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
📚 Learning: 2025-11-07T14:50:33.544Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37423
File: packages/i18n/src/locales/en.i18n.json:18-18
Timestamp: 2025-11-07T14:50:33.544Z
Learning: Rocket.Chat settings: in apps/meteor/ee/server/settings/abac.ts, the Abac_Cache_Decision_Time_Seconds setting uses invalidValue: 0 as the fallback when ABAC is unlicensed. With a valid license, admins can still set the value to 0 to intentionally disable the ABAC decision cache.

Applied to files:

  • apps/meteor/ee/server/api/abac/schemas.ts
📚 Learning: 2025-10-24T17:32:05.348Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.

Applied to files:

  • apps/meteor/ee/server/api/abac/schemas.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
  • ee/packages/abac/src/index.ts
  • apps/meteor/tests/end-to-end/api/abac.ts
  • apps/meteor/ee/server/api/abac/index.ts
  • ee/packages/abac/src/audit.ts
  • packages/core-services/src/types/IAbacService.ts
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • apps/meteor/ee/server/api/abac/schemas.ts
  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.ts
  • apps/meteor/tests/end-to-end/api/abac.ts
  • apps/meteor/ee/server/api/abac/index.ts
  • ee/packages/abac/src/audit.ts
  • packages/core-services/src/types/IAbacService.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `test.beforeAll()` and `test.afterAll()` for setup/teardown in Playwright tests

Applied to files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Maintain test isolation between test cases in Playwright tests

Applied to files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure clean state for each test execution in Playwright tests

Applied to files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
  • apps/meteor/tests/end-to-end/api/abac.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (`test`, `page`, `expect`) for consistency in test files

Applied to files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-10-06T20:30:45.540Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37152
File: packages/apps-engine/tests/test-data/storage/storage.ts:101-122
Timestamp: 2025-10-06T20:30:45.540Z
Learning: In `packages/apps-engine/tests/test-data/storage/storage.ts`, the stub methods (updatePartialAndReturnDocument, updateStatus, updateSetting, updateAppInfo, updateMarketplaceInfo) intentionally throw "Method not implemented." Tests using these methods must stub them using `SpyOn` from the test library rather than relying on actual implementations.

Applied to files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.

Applied to files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.

Applied to files:

  • ee/packages/abac/src/user-auto-removal.spec.ts
  • ee/packages/abac/src/index.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `expect` matchers for assertions (`toEqual`, `toContain`, `toBeTruthy`, `toHaveLength`, etc.) instead of `assert` statements in Playwright tests

Applied to files:

  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,spec.ts} : Follow Page Object Model pattern consistently in Playwright tests

Applied to files:

  • ee/packages/abac/src/index.spec.ts
📚 Learning: 2025-11-04T16:49:19.107Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37377
File: apps/meteor/ee/server/hooks/federation/index.ts:86-88
Timestamp: 2025-11-04T16:49:19.107Z
Learning: In Rocket.Chat's federation system (apps/meteor/ee/server/hooks/federation/), permission checks follow two distinct patterns: (1) User-initiated federation actions (creating rooms, adding users to federated rooms, joining from invites) should throw MeteorError to inform users they lack 'access-federation' permission. (2) Remote server-initiated federation events should silently skip/ignore when users lack permission. The beforeAddUserToRoom hook only executes for local user-initiated actions, so throwing an error there is correct. Remote federation events are handled separately by the federation Matrix package with silent skipping logic.

Applied to files:

  • ee/packages/abac/src/index.ts
📚 Learning: 2025-10-28T16:53:42.761Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.

Applied to files:

  • ee/packages/abac/src/index.ts
📚 Learning: 2025-10-30T19:30:46.541Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37244
File: apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.spec.tsx:125-146
Timestamp: 2025-10-30T19:30:46.541Z
Learning: In the AdminABACRoomAttributesForm component (apps/meteor/client/views/admin/ABAC/AdminABACRoomAttributesForm.tsx), the first attribute value field is mandatory and does not have a Remove button. Only additional values beyond the first have Remove buttons. This means trashButtons[0] corresponds to the second value's Remove button, not the first value's.

Applied to files:

  • apps/meteor/tests/end-to-end/api/abac.ts
🧬 Code graph analysis (5)
ee/packages/abac/src/helper.ts (1)
packages/core-typings/src/IAbacAttribute.ts (1)
  • IAbacAttributeDefinition (3-14)
ee/packages/abac/src/index.ts (3)
ee/packages/abac/src/helper.ts (1)
  • diffAttributes (36-78)
ee/packages/abac/src/audit.ts (1)
  • Audit (29-146)
packages/core-services/src/types/IAbacService.ts (1)
  • AbacActor (11-11)
apps/meteor/tests/end-to-end/api/abac.ts (2)
apps/meteor/tests/data/api-data.ts (2)
  • request (10-10)
  • credentials (39-42)
packages/core-typings/src/IRoom.ts (1)
  • IRoom (22-98)
packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts (3)
packages/core-typings/src/IUser.ts (1)
  • IUser (187-258)
packages/core-typings/src/IRoom.ts (1)
  • IRoom (22-98)
packages/core-typings/src/IAbacAttribute.ts (1)
  • IAbacAttributeDefinition (3-14)
packages/core-services/src/types/IAbacService.ts (3)
packages/core-typings/src/IUser.ts (1)
  • IUser (187-258)
packages/core-typings/src/IAbacAttribute.ts (2)
  • IAbacAttributeDefinition (3-14)
  • IAbacAttribute (16-16)
packages/core-typings/src/IRoom.ts (1)
  • IRoom (22-98)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (6)
apps/meteor/tests/end-to-end/api/abac.ts (1)

409-461: Dedicated-room delete test is well‑scoped and isolated

The “DELETE room attribute key (dedicated room)” block correctly sets up its own room, attributes, and user, asserts only the targeted key is removed, and cleans up the room in after. No issues from an isolation or correctness standpoint.

apps/meteor/ee/server/api/abac/schemas.ts (1)

1-1: Audit events query/response schemas align with /abac/audit usage

Importing IAuditServerActor and defining GETAbacAuditEventsQuerySchema/GETAbacAuditEventsResponseSchema is consistent with the new /abac/audit endpoint: query supports optional actor/start/end/offset/count and the response enforces events, count, offset, and total with a success: true wrapper. No structural issues spotted.

Also applies to: 152-233

ee/packages/abac/src/user-auto-removal.spec.ts (1)

7-8: Actor-aware auto-removal tests exercise audit semantics thoroughly

Threading fakeActor through the AbacService calls and spying on Audit.actionPerformed gives good coverage of when removals should and should not be audited (single/multi-attribute additions, idempotency, edge cases, and larger populations). The MongoMemoryServer + registerServiceModels setup keeps tests realistic without hitting external services.

Also applies to: 32-33, 80-82, 88-90, 128-143, 164-170, 190-196, 216-219, 274-289, 314-331, 350-383, 410-424

ee/packages/abac/src/index.spec.ts (1)

5-6: Unit tests correctly updated for actor-aware service API and new models surface

  • fakeActor is consistently passed into all mutating AbacService methods that now expect an actor, keeping the tests compiling and representative of real usage.
  • The additional AbacAttributes.findOneAndUpdate mock and ServerEvents.createAuditServerEvent stub future‑proof the tests against audit internals without over-coupling expectations.
  • Existing business-logic assertions (validation, in-use checks, error mapping, limit enforcement, etc.) remain intact.

No issues spotted here.

Also applies to: 25-26, 45-59, 386-417, 519-668, 671-817, 868-933, 935-1179

ee/packages/abac/src/index.ts (1)

285-317: Room attribute audits look consistent with behavior; no functional issues spotted

  • setRoomAbacAttributes, updateRoomAbacAttributeValues, removeRoomAbacAttribute, addRoomAbacAttributeByKey, and replaceRoomAbacAttributeByKey all:
    • Enforce default/teamDefault restrictions before mutating.
    • Validate definitions and limits via ensureAttributeDefinitionsExist and simple cardinality checks.
    • Emit appropriate audit events (objectAttributeChanged, objectAttributeRemoved, objectAttributesRemoved) with previous/current snapshots and change types (updated, key-added, key-updated, key-removed).
    • Only call onRoomAttributesChanged when constraints are tightened (new keys or added values), matching the tests’ expectations.

This matches the ABAC-24 requirement to audit room attribute mutations and membership reevaluation triggers.

Also applies to: 389-437, 444-478, 480-555

apps/meteor/ee/server/api/abac/index.ts (1)

2-7: Actor threading and /abac/audit endpoint wiring look consistent

  • getActorFromUser correctly maps IUser into the AbacActor shape and is passed to all mutating and listing Abac calls from this module, giving the service layer the context it needs for auditing.
  • The new /abac/audit endpoint:
    • Uses the Ajv query/response schemas you added.
    • Applies pagination and optional sort.ts handling.
    • Filters ServerEvents by time window, actor (via convertSubObjectsIntoPaths), and ABAC event types.
    • Gates access by authRequired, abac-management permission, and ['abac', 'auditing'] licenses.

This matches the intended read side for the new ABAC audit events.

Also applies to: 32-40, 64-67, 88-89, 115-116, 142-143, 162-163, 185-195, 244-245, 269-270, 288-289, 307-308, 347-355, 360-409

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
ee/packages/abac/src/audit.ts (3)

68-105: objectAttributeChanged and objectAttributeRemoved are identical.

These two methods have identical implementations (same event name, same payload structure, same actor construction). If they're meant to serve different purposes, they should either:

  • Use different event names, or
  • Be consolidated into a single method

Otherwise, this duplication creates maintenance burden and potential confusion.


Note: These methods also have the hardcoded IP/useragent issue (lines 84, 103) and non-null assertions (lines 84, 103) flagged in other comments.


106-118: Note: This method shares the hardcoded IP/useragent issue (line 116) and non-null assertion issue (line 116) flagged in other comments.


29-67: Hardcoded IP and user agent reduce audit trail quality.

Lines 39, 52, and 65 hardcode ip: '0.0.0.0' and useragent: '' for audit logs. For effective security auditing, these fields should capture actual request metadata (IP address and user agent from the HTTP request context). Consider threading the request context through the actor parameter or adding these as separate parameters.


Note: The non-null assertions on actor.username! at lines 39, 52, 65 were already flagged in a previous review.

🧹 Nitpick comments (2)
ee/packages/abac/src/audit.ts (2)

135-146: Hardcoded reason: 'ldap-sync' limits reusability.

The method name subjectAttributeChanged is generic, but the reason is hardcoded to 'ldap-sync'. If subject attributes can change from other sources (e.g., API updates, other sync mechanisms), consider accepting reason as a parameter with 'ldap-sync' as the default.


38-38: Remove redundant type assertion.

The explicit as EventPayload<'abac.attribute.changed'> cast is unnecessary—TypeScript infers the type from the audit function's generic parameter. Remove it for consistency with other methods (lines 45-51, 58-63, etc.).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cb53785 and 9998ea7.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (2)
  • ee/packages/abac/src/audit.ts (1 hunks)
  • packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core-typings/src/ServerAudit/IAuditServerAbacAction.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • ee/packages/abac/src/audit.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.
📚 Learning: 2025-11-27T17:56:26.027Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37557
File: apps/meteor/client/views/admin/ABAC/AdminABACRooms.tsx:115-116
Timestamp: 2025-11-27T17:56:26.027Z
Learning: In Rocket.Chat, the GET /v1/abac/rooms endpoint (implemented in ee/packages/abac/src/index.ts) only returns rooms where abacAttributes exists and is not an empty array (query: { abacAttributes: { $exists: true, $ne: [] } }). Therefore, in components consuming this endpoint (like AdminABACRooms.tsx), room.abacAttributes is guaranteed to be defined for all returned rooms, and optional chaining before calling array methods like .join() is sufficient without additional null coalescing.

Applied to files:

  • ee/packages/abac/src/audit.ts
📚 Learning: 2025-10-27T14:38:46.994Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37303
File: apps/meteor/tests/end-to-end/api/abac.ts:1125-1137
Timestamp: 2025-10-27T14:38:46.994Z
Learning: In Rocket.Chat ABAC feature, when ABAC is disabled globally (ABAC_Enabled setting is false), room-level ABAC attributes are not evaluated when changing room types. This means converting a private room to public will succeed even if the room has ABAC attributes, as long as the global ABAC setting is disabled.

Applied to files:

  • ee/packages/abac/src/audit.ts
📚 Learning: 2025-10-24T17:32:05.348Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37299
File: apps/meteor/ee/server/lib/ldap/Manager.ts:438-454
Timestamp: 2025-10-24T17:32:05.348Z
Learning: In Rocket.Chat, ABAC attributes can only be set on private rooms and teams (type 'p'), not on public rooms (type 'c'). Therefore, when checking for ABAC-protected rooms/teams during LDAP sync or similar operations, it's sufficient to query only private rooms using methods like `findPrivateRoomsByIdsWithAbacAttributes`.

Applied to files:

  • ee/packages/abac/src/audit.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (2)
ee/packages/abac/src/audit.ts (2)

1-23: LGTM: Clean type definitions for audit events.

The imports and type definitions establish a type-safe foundation for ABAC audit events, with minimal public API surface.


25-27: LGTM: Clean audit helper.

The internal helper cleanly delegates to ServerEvents with proper typing.

@KevLehman KevLehman requested a review from tassoevan November 28, 2025 16:50
@tassoevan tassoevan merged commit ca4cc2c into feat/abac Nov 28, 2025
88 of 91 checks passed
@tassoevan tassoevan deleted the chore/audit-events branch November 28, 2025 17:38
@coderabbitai coderabbitai bot mentioned this pull request Nov 28, 2025
KevLehman added a commit that referenced this pull request Dec 1, 2025
Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
KevLehman added a commit that referenced this pull request Dec 2, 2025
Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
@coderabbitai coderabbitai bot mentioned this pull request Dec 3, 2025
KevLehman added a commit that referenced this pull request Dec 8, 2025
Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
KevLehman added a commit that referenced this pull request Dec 10, 2025
Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
KevLehman added a commit that referenced this pull request Dec 15, 2025
Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
MartinSchoeler pushed a commit that referenced this pull request Dec 17, 2025
Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
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.

3 participants