Skip to content

refactor: extract CryptoFacade, introduce RoomMemberCache#10

Merged
ThomasHalwax merged 19 commits intomainfrom
refactor/crypto-facade
Mar 20, 2026
Merged

refactor: extract CryptoFacade, introduce RoomMemberCache#10
ThomasHalwax merged 19 commits intomainfrom
refactor/crypto-facade

Conversation

@axel-krapotke
Copy link
Copy Markdown
Contributor

Motivation

The CryptoManager was directly injected into TimelineAPI, CommandAPI, and Project — each module contained its own copy of the crypto orchestration ceremony. This violated separation of concerns and made the code fragile and hard to maintain.

Changes

CryptoFacade (src/crypto-facade.mjs)

  • New facade that encapsulates all crypto orchestration in one place
  • Owns the CryptoManager and HttpAPI references
  • The 7-step encrypt ceremony (trackUsers → queryKeys → claimSessions → shareRoomKey → encrypt → processOutgoing) exists exactly once
  • Historical key sharing ceremony exists exactly once

RoomMemberCache (src/room-members.mjs)

  • Self-sufficient cache: fetches members from the server on cache miss via a constructor-provided callback
  • Updated by sync stream membership events (addMember/removeMember)
  • Guards against network errors on cache miss (returns empty array)
  • Eliminates per-message HTTP lookups for room members during encryption

API Changes

  • TimelineAPI: Constructor takes options with onSyncResponse and decryptEvent callbacks instead of a crypto object
  • CommandAPI: Constructor takes memberCache (RoomMemberCache) as second parameter; optional encryptEvent in options
  • Project: Takes memberCache and crypto options object with isEnabled, registerRoom, shareHistoricalKeys
  • HttpAPI: processOutgoingCryptoRequests() removed (moved to facade)
  • index.mjs: Single composition root wiring everything together

Principles Applied

  • No module except CryptoFacade and index.mjs knows CryptoManager exists
  • Cache is a proper collaborator, not a callback trio
  • Membership events: filter once, then update cache, then notify handler (separate steps, no side effects during mapping)

E2E Tests

All test files updated for the new API signatures. Test logic and assertions unchanged.

axel-krapotke and others added 19 commits March 19, 2026 17:35
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* required for invitations
The parameter was passed through the entire call chain
(project → crypto-facade → crypto) but never used — the algorithm
is hardcoded to MegolmV1AesSha2 via RoomSettings.

Also fixed sync-gated-content unit tests: mocks used wrong property
name (cryptoManager instead of crypto) and wrong method
(setRoomEncryption instead of registerRoom), so the encryption
registration path was never actually tested.
@ThomasHalwax ThomasHalwax merged commit 01d19cf into main Mar 20, 2026
@ThomasHalwax ThomasHalwax deleted the refactor/crypto-facade branch March 20, 2026 09:59
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.

2 participants