Skip to content

Wire shared chat lifecycle into security notifications#27

Merged
TraderSamwise merged 3 commits into
masterfrom
feat/multi-user-chat-polish
May 24, 2026
Merged

Wire shared chat lifecycle into security notifications#27
TraderSamwise merged 3 commits into
masterfrom
feat/multi-user-chat-polish

Conversation

@TraderSamwise

@TraderSamwise TraderSamwise commented May 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • emit durable security events for shared chat invite acceptance and participant removal/leave
  • deliver owner security email/push with emergency lockdown links on invite acceptance
  • route shared client push registration through the owner relay context

Verification

  • yarn verify
  • yarn --cwd relay typecheck
  • yarn --cwd app typecheck
  • yarn --cwd app test
  • yarn --cwd app lint (existing warnings only)
  • yarn build

Summary by CodeRabbit

  • New Features

    • Enhanced security event tracking for shared chats: invite acceptance, participant leaving, and participant removal now record richer actor/target and share/session metadata.
    • Shared push notifications now carry share and session context and can exclude a specific device from delivery.
  • Bug Fixes

    • Tighter validation and scoping for push token registration in shared scenarios; user-scoped token handling improved.
  • Tests

    • Added tests for push-registration URL generation and shared security event construction/persistence.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1cc65ede-6e47-4986-ab01-d4e90bf92a4e

📥 Commits

Reviewing files that changed from the base of the PR and between 9d02ef2 and 9c31530.

📒 Files selected for processing (3)
  • app/lib/push-registration-url.ts
  • app/lib/push-registration.test.ts
  • relay/src/relay-object.ts

📝 Walkthrough

Walkthrough

Share participant lifecycle events (invite accepted, participant left/removed) are now tracked as security events with push notifications. Push token registration extended to support shared chats via ownerUserId/shareId query parameters. Event recording and delivery centralized in relay; removed participants have active client sockets closed.

Changes

Share Security Events and Push Token Registration

Layer / File(s) Summary
Security event schemas and factory
relay/src/security.ts, app/stores/security.ts
SecurityEventKind and SecurityEventRecord expanded for share events (shared_invite_accepted, shared_participant_left, shared_participant_removed). SecurityPushTokenRecord includes optional userId. New createShareSecurityEvent factory constructs typed share event records with actor/target metadata and human-readable titles/bodies.
Security event delivery and push extensions
relay/src/security-delivery.ts
DeliveryInput device made optional and excludeDeviceId added for push suppression. sendSecurityPush filters tokens by userId and excludes device. renderSecurityEmail conditionally includes device row. Event persistence, client broadcast, and push delivery wired in recordAndDeliverShareSecurityEvent helper.
Client push token registration with share context
app/lib/push-registration-url.ts, app/lib/push-registration.test.ts, app/lib/push-registration.ts, app/app/(main)/_layout.tsx
buildSecurityPushRegistrationUrl normalizes relayUrl and appends ownerUserId/shareId query parameters. registerSecurityPushToken extended to accept optional share context. MainLayout passes activeShare context to registration call. Tests verify URL construction for standard and shared paths and validate partial-shared errors.
Server push token endpoint with share validation
relay/src/index.ts
POST /security/push-token parses ownerUserId and shareId from query parameters, validates both present or both absent, derives relay routing identity from ownerUserId when present, and forwards X-Aimux-Share-Owner-Id and X-Aimux-Share-Id headers to the stub request.
Share participant lifecycle events and recording
relay/src/relay-object.ts
Centralized recordAndDeliverShareSecurityEvent() appends events, optionally creates emergency lockdown tokens, broadcasts to clients/daemon, and delivers push alerts to owner/target. Participant accept/leave/remove flows create corresponding share events; removal closes the removed user’s active sockets. Push-token registration tightened to validate shared participants and user-scope token keys.
Security event construction and persistence tests
relay/src/security.test.ts
Tests verify createShareSecurityEvent produces typed events with metadata and id. Tests verify appendSecurityEvent preserves actor/target fields and generated body text in security feed.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • TraderSamwise/aimux#24: Touches activeSharedSessionAtom usage in MainLayout; related to passing shared context into push registration.
  • TraderSamwise/aimux#17: Previously modified push-token registration and relay push endpoint; this PR extends that flow for share-scoped registration and events.

Poem

🐰 I hop to the relay, a token in paw,
Shared events recorded with nary a flaw,
Owners alerted, targets informed too,
Sockets tuck in when a participant's through,
A tiny rabbit cheers — secure and anew!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately and clearly summarizes the main change: wiring shared chat lifecycle events into the security notification system, which aligns with the PR objectives of emitting security events for invite acceptance and participant removal/leave, plus delivering security notifications.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/multi-user-chat-polish

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

app/lib/push-registration-url.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

app/lib/push-registration.test.ts

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.


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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/lib/push-registration-url.ts`:
- Around line 3-7: The URL builder adds ownerUserId and shareId independently,
which allows invalid single-parameter combinations; update the function in
app/lib/push-registration-url.ts to validate the share scope as an atomic pair:
require that options.ownerUserId and options.shareId are either both present or
both absent before calling url.searchParams.set, and if only one is provided
throw or return an explicit error (or omit both) to avoid constructing a URL the
relay will reject; locate the logic around the new URL(...) to implement this
check.

In `@relay/src/relay-object.ts`:
- Around line 439-446: When storing a push token with the new composite key
(tokenKey = userId ? `${userId}:${deviceId}` : deviceId) ensure any stale legacy
entry keyed by the plain deviceId is removed to avoid duplicate notifications:
after computing tokenKey in the update block for state.pushTokens (where userId,
deviceId, token, platform, createdAt, updatedAt are set), if userId is present
and state.pushTokens[deviceId] exists, delete state.pushTokens[deviceId];
preserve createdAt semantics by using state.pushTokens[tokenKey]?.createdAt when
creating the new entry. This cleanup should occur atomically in the same update
flow that writes the new tokenKey.
- Around line 755-761: The current branch that handles options.deliverToUserId
calls deliverSecurityAlert with pushTokens: [], which prevents push
notifications for participant-targeted alerts; update the branch so it fetches
the target user's push tokens (same way you do for options.ownerUserId) and pass
those tokens into deliverSecurityAlert instead of an empty array—locate the
conditional using options.deliverToUserId and options.ownerUserId and replace
the hardcoded pushTokens: [] with the actual user's push token list retrieved
from the user/token lookup used elsewhere in this module.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 17e9cc2e-7db6-4da5-a478-afbd1218b4ef

📥 Commits

Reviewing files that changed from the base of the PR and between 66f88fc and 9d02ef2.

📒 Files selected for processing (10)
  • app/app/(main)/_layout.tsx
  • app/lib/push-registration-url.ts
  • app/lib/push-registration.test.ts
  • app/lib/push-registration.ts
  • app/stores/security.ts
  • relay/src/index.ts
  • relay/src/relay-object.ts
  • relay/src/security-delivery.ts
  • relay/src/security.test.ts
  • relay/src/security.ts

Comment thread app/lib/push-registration-url.ts Outdated
Comment thread relay/src/relay-object.ts
Comment thread relay/src/relay-object.ts
@TraderSamwise
TraderSamwise merged commit 79401d1 into master May 24, 2026
1 check passed
@TraderSamwise
TraderSamwise deleted the feat/multi-user-chat-polish branch May 24, 2026 12:03
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