Commit Graph
761 Commits
Author SHA1 Message Date
Jannis Braun 3464e9d991 feat(web): filter remote DMs from populateFromReady, remove dedup and dead code
DMs now come exclusively from the home instance's ready payload.
Remote origins' DM channels are ignored. The deduplication logic
that preferred home copies over remote copies is no longer needed.
Removed dead loadDmChannels() (zero call sites).
2026-04-01 12:47:12 +02:00
Jannis Braun 7f3ca4e6d1 feat(web): route DM creation to home instance with federated identity
All DM creation and add-member call sites now use the home api client
and pass homeUserId/homeInstance instead of routing to the remote instance.
Also updates addMember in the API client to accept AddDmMemberRequest.
2026-04-01 12:45:13 +02:00
Jannis Braun 4d7a777ae4 feat(federation): POST /api/dm/:id/members accepts homeUserId+homeInstance
Extend the add-member endpoint to resolve federated identity via
resolveOrCreateReplicatedUser() when homeUserId+homeInstance are provided,
falling back to the existing local userId lookup.
2026-04-01 12:40:57 +02:00
Jannis Braun 5c02bff2d2 feat(federation): POST /api/dm accepts homeUserId+homeInstance for federated DM creation 2026-04-01 12:38:50 +02:00
Jannis Braun 518b3eb786 feat(shared): extend CreateDmRequest and AddDmMemberRequest with federated identity fields 2026-04-01 12:36:20 +02:00
Jannis Braun 73583a4b61 fix(migration): stop ownerId ping-pong on group DMs with 2 members
migrateFixOneOnOneOwnerIds was too aggressive — it set owner_id=NULL
on any 2-member channel, including group DMs that happened to have 2
members. The group DM repair then restored owner_id, creating noisy
logs every restart.

Now only targets channels with NULL or 32-char hex federatedId
(true 1-on-1 DMs), skipping UUID-format group DMs.
2026-04-01 04:00:07 +02:00
Jannis Braun e40a63ba9b fix(federation): assign deterministic federatedId on 1-on-1 DM creation
POST /api/dm created channels with federatedId=NULL, so when the S2S
reply arrived, processCreateEvent couldn't find the channel and created
a duplicate. Now computes the deterministic SHA256 hash at creation time
when either participant is federated.
2026-04-01 03:57:42 +02:00
Jannis Braun 4b596afae5 fix(federation): allow homeward relay in attribution check
Client-federation users (e.g., youruser@nova logged into orbit)
send DMs on the remote server. The S2S relay forwards these back to the
author's home instance, but verifyAttribution rejected them because the
author's homeInstance didn't match the sourceInstance.

Now also accepts when the author's home matches the receiving instance
(getOurOrigin()), covering the homeward relay case.
2026-04-01 03:56:12 +02:00
Jannis Braun 42cf8afddd fix(federation): raise relay rate limit from 30 to 90 req/min per peer
The outbox worker interval was reduced from 10s to 1s in FED-009,
so a busy sender can now hit 60 req/min during sustained traffic.
90 gives 50% headroom.
2026-04-01 02:00:19 +02:00
Jannis Braun f55238f8e5 feat(web): wire up confirm dialogs and action handlers for peer management 2026-04-01 01:53:32 +02:00
Jannis Braun a91f7b5df1 feat(web): implement expandable peer details with stats, rotation, and actions 2026-04-01 01:41:11 +02:00
Jannis Braun 72dba1c03e feat(web): add peer list with filtering, sorting, and compact rows 2026-04-01 01:39:19 +02:00
Jannis Braun 74ed5c44ce feat(web): implement FederationPanel global settings section 2026-04-01 01:26:18 +02:00
Jannis Braun 5ca5db7122 refactor(web): extract federation section from GeneralPanel 2026-04-01 01:25:26 +02:00
Jannis Braun f94b3b93f7 feat(web): add federation API client methods for rotation, peer update, and permanent delete 2026-04-01 01:24:15 +02:00
Jannis Braun f49c2b5488 feat(web): register Federation tab in instance settings 2026-04-01 01:23:56 +02:00
Jannis Braun 3265670047 feat(server): add PATCH peer and permanent delete endpoints for federation admin 2026-04-01 01:22:41 +02:00
Jannis Braun 83074e40ef feat(server): add defaultAutoRotateIntervalDays to instance settings schema and API 2026-04-01 01:22:41 +02:00
Jannis Braun df0608d744 feat(shared): add defaultAutoRotateIntervalDays to InstanceAdminSettings 2026-04-01 01:21:54 +02:00
Jannis Braun 626fbfdba8 fix(federation): address code review findings for FED-009
- Resolve homeUserId from DB in sendFederatedCallStart/End (not raw userId)
- Clear existing timeout in createFederatedCall before overwriting
- Clear federatedCallToken/Url in leaveVoice and handleForceDisconnect
- Remove unnecessary `as any` cast in relay processor
2026-03-31 23:58:27 +02:00
Jannis Braun aff2a403d7 fix(federation): reduce outbox worker interval from 10s to 1s for lower relay latency 2026-03-31 23:42:31 +02:00
Jannis Braun 2f211e0588 feat(federation): useLiveKit connects to remote LiveKit for federated calls (FED-009) 2026-03-31 23:41:50 +02:00
Jannis Braun 24571edc34 feat(federation): client voice store handles federated call data (FED-009) 2026-03-31 23:40:11 +02:00
Jannis Braun 09916917f1 fix(federation): include livekitUrl/livekitToken in dm_call_incoming relay event (FED-009) 2026-03-31 23:37:24 +02:00
Jannis Braun 1f4c2bbeed feat(federation): add relay processors for dm_call_start/accept/reject/end (FED-009) 2026-03-31 23:35:43 +02:00
Jannis Braun 2f47d32136 feat(federation): handleDmCallAccept/Reject/End with federated call support (FED-009) 2026-03-31 23:30:27 +02:00
Jannis Braun f2affb0f1d feat(federation): handleDmCallStart sends S2S to remote instances (FED-009) 2026-03-31 23:27:42 +02:00
Jannis Braun cbcb324e24 feat(federation): add federated call registry with ringing timeout (FED-009) 2026-03-31 23:24:45 +02:00
Jannis Braun 75b84c6ecb feat(federation): add sendCallRelay for direct S2S delivery (FED-009) 2026-03-31 23:22:06 +02:00
Jannis Braun 8de27fd39c feat(federation): add generateFederatedCallToken and federated room naming (FED-009) 2026-03-31 23:20:08 +02:00
Jannis Braun 06d2c972b9 feat(federation): add shared types for FED-009 federated DM calls 2026-03-31 23:17:31 +02:00
Jannis Braun abdaf99bb4 fix(federation): address code review findings for FED-011
- Fix race window: store pendingHmacSecret AFTER remote peer confirms,
  not before (admin endpoint + auto-rotation worker)
- Add hex validation on newSecret at /peer/rotate endpoint
- Use pending-secret-aware signing in initial sync worker
- Add test for corrupt state (pendingHmacSecret set, secretRotationAt null)
2026-03-31 21:01:02 +02:00
Jannis Braun 0c09a58d61 feat(federation): add grace period finalization and auto-rotation to health worker (FED-011) 2026-03-31 20:49:15 +02:00
Jannis Braun 1f6605b801 feat(federation): outbox worker signs with pending secret during rotation (FED-011) 2026-03-31 20:48:00 +02:00
Jannis Braun d529ff20c2 feat(federation): add admin rotation endpoint and expose rotation state (FED-011) 2026-03-31 20:46:41 +02:00
Jannis Braun bd9a598b36 feat(federation): add /peer/rotate endpoint for secret rotation (FED-011) 2026-03-31 20:44:17 +02:00
Jannis Braun 2ceea5e474 feat(federation): switch relay+sync handlers to verifyPeerSignature (FED-011) 2026-03-31 20:43:41 +02:00
Jannis Braun dcf0bc1857 feat(federation): add verifyPeerSignature with dual-secret grace period (FED-011) 2026-03-31 20:40:38 +02:00
Jannis Braun 0ac140bf51 feat(federation): add secret rotation columns to federation_peers (FED-011) 2026-03-31 20:40:06 +02:00
Jannis Braun 720a5de945 fix(federation): add strict origin enforcement for user attribution (FED-010)
Prevent malicious peers from forging events attributed to users on other
instances. Every relay event processor now verifies the acting user's
homeInstance (from payload) matches X-Federation-Origin (from HMAC-verified
header) via verifyAttribution(), normalized to bare domain.

- Add verifyAttribution() helper using extractDomain normalization
- Guard all 13 event processors before any user resolution or DB writes
- Add homeInstance to FederationRelayReaction type + outbound payloads
- Replace unnormalized string equality in friend handlers
- Log mismatched values on rejection for debugging
2026-03-31 19:16:48 +02:00
Jannis Braun d0ed43cf58 fix(federation): add nonce length validation and fix verification flow docs (FED-008) 2026-03-31 18:18:50 +02:00
Jannis Braun 5c5d41e462 feat(federation): wire nonce verification into relay and sync handlers (FED-008)
Pass nonce through to verifySignature and enforce replay protection in
both /api/federation/relay and /api/federation/sync: reject duplicate
nonces (409), reject nonce-less requests from peers that previously sent
nonces (401), warn for legacy peers, and auto-ratchet nonceSupported flag.
2026-03-31 18:12:16 +02:00
Jannis Braun 2f9cce9d38 feat(federation): add nonceSupported column to federation_peers (FED-008)
Adds nonce_supported INTEGER column to the federation_peers table in both
the Drizzle schema definition and via a safe ALTER TABLE migration, enabling
the auto-ratchet mechanism for replay attack protection.
2026-03-31 18:09:40 +02:00
Jannis Braun d2073efdd7 feat(federation): add in-memory nonce store with TTL eviction (FED-008) 2026-03-31 18:08:53 +02:00
Jannis Braun d7c30f2c50 feat(federation): add nonce to HMAC sign/verify and header build/parse (FED-008)
- signRequest now accepts optional nonce; payload becomes `${timestamp}.${nonce}.${body}` when present, falling back to `${timestamp}.${body}` for legacy peers
- verifySignature accepts matching nonce parameter and passes it through
- buildFederationHeaders generates a UUID nonce per request and includes X-Federation-Nonce header
- parseFederationHeaders extracts X-Federation-Nonce into nonce field (null when absent)
2026-03-31 18:07:19 +02:00
Jannis Braun 75504e07c0 fix(federation): add per-peer rate limiting to relay endpoint (FED-007)
Sliding-window rate limiter (30 req/min per peer origin) on POST
/api/federation/relay, matching the existing accept endpoint pattern.
Returns 429 when exceeded — outbox workers retry with backoff. Check
runs before HMAC verification to avoid wasted computation on floods.
2026-03-31 17:33:57 +02:00
Jannis Braun 2cac39a460 fix(federation): replace DNS hairpin self-POST with direct function call (FED-005)
Extract processRelayEvents() from the relay HTTP handler and call it
directly in runInitialSyncForNewPeers(), eliminating the HTTP round-trip
through public DNS that failed on networks without hairpin NAT.
2026-03-31 05:20:16 +02:00
Jannis Braun 37fc52d85b fix(migration): require at least one stub in merge pair to prevent false positives
Two real accounts from the same remote instance sharing a 1-on-1 DM
are different people, not duplicates. The shared DM is a legitimate
relay. Only merge when at least one user has passwordHash =
'!federation-replicated' (a relay-created stub).
2026-03-31 05:08:22 +02:00
Jannis Braun 373989aa44 fix(migration): detect and merge duplicate federated user stubs 2026-03-31 04:54:15 +02:00
Jannis Braun d2e4f9240e fix(migration): normalize homeInstance to bare domain for consistent identity matching 2026-03-31 04:53:53 +02:00