Commit Graph
1048 Commits
Author SHA1 Message Date
Jannis Braun 1260f69ed0 fix(web): fix type errors in dmFormatters PreviewAttachment handling 2026-04-02 17:57:44 +02:00
Jannis Braun b77aad61eb refactor(web): unify DM sorting with sortDmChannels across all triggers 2026-04-02 17:56:26 +02:00
Jannis Braun afa583df1d feat(server): include attachment metadata in GET /api/dm lastMessage 2026-04-02 17:53:14 +02:00
Jannis Braun 6e5792ff72 feat(server): include attachment metadata in ready payload DM lastMessage 2026-04-02 17:51:37 +02:00
Jannis Braun b82733868b feat(web): add formatDmPreview utility with attachment-aware previews
Supports text-only, attachment-only (with type-specific icons), and
mixed messages. PreviewAttachment accepts both type/filename (ready
payload) and mimetype/originalName (Attachment type) field shapes.
2026-04-02 17:48:28 +02:00
Jannis Braun 68fe04ef58 feat(web): add sortDmChannels utility with unread-first sorting 2026-04-02 17:48:24 +02:00
Jannis Braun 03667947aa feat(web): add formatDmTimestamp utility with smart date formatting 2026-04-02 17:47:18 +02:00
Jannis Braun 416636530a feat(shared): add DmLastMessagePreview type with attachment metadata
Introduces a lightweight DmLastMessagePreview interface for the ready
payload and GET /api/dm response, and widens DmChannel.lastMessage to
accept either DmLastMessagePreview or DmMessageWithUser so both the
static preview path and real-time WS events can coexist without casts.
2026-04-02 17:45:23 +02:00
Jannis Braun 1d81838868 feat(server): filter DM read states from ready payload for federated users 2026-04-02 11:33:59 +02:00
Jannis Braun b1ba7b35d2 feat(server): skip DM channel queries in ready payload for federated users 2026-04-02 11:33:51 +02:00
Jannis Braun 54bce681f9 feat(server): add isFederated flag and visibleChannelIdSet to ready payload builder 2026-04-02 11:33:43 +02:00
Jannis Braun c94e1644a8 feat(server): add WS federation gating for DM events and shared handlers 2026-04-02 10:51:20 +02:00
Jannis Braun 7200ccd7e4 feat(server): centralize DM auth via plugin-scoped hooks, add federation gating 2026-04-02 10:48:45 +02:00
Jannis Braun 32d9f16a15 feat(server): cache isFederated flag at WS auth, pass to event handler 2026-04-02 10:47:52 +02:00
Jannis Braun 8f2f494ffd test(server): add unit tests for requireLocalUser guard 2026-04-02 10:47:43 +02:00
Jannis Braun 017256162b feat(server): add homeInstance to authenticate, add requireLocalUser guard 2026-04-02 10:45:50 +02:00
Jannis Braun cc90b5fa65 fix(web): reauthenticateInstance works without existing live instance (stale disconnected entries) 2026-04-02 08:50:35 +02:00
Jannis Braun 7a3945e2f1 fix(web): disconnect keeps token alive — reconnect without re-auth 2026-04-02 08:44:05 +02:00
Jannis Braun b8ab162570 fix(server): add registry size/duplicate validation; update database and API docs 2026-04-01 18:25:24 +02:00
Jannis Braun 839197d4b8 fix(web): add re-authenticate flow, safe URL parsing, and minor UI fixes 2026-04-01 18:23:27 +02:00
Jannis Braun 7135990340 fix(web): critical fixes — preserve tokens on disconnect, clean up forceRemoveEntry, update registry on reconnect failure
- disconnectInstance: save cached tokens BEFORE filtering the instance out, so
  reconnectInstance can restore disconnected entries from localStorage
- reconnectInstance: if instance is not in active instances array, attempt to
  restore it from cached localStorage token before proceeding with reconnect
- reconnectInstance: update registry to unreachable/auth_expired on failure
- forceRemoveEntry: now tears down WS, removes from instances array, purges
  token from localStorage, and cleans up space store (was registry-only before)
2026-04-01 18:20:53 +02:00
Jannis Braun 95e4dd9fa8 feat(web): overhaul ConnectedInstances with persistent registry list, filters, expandable rows, and delete identity dialog 2026-04-01 18:08:14 +02:00
Jannis Braun 05d8285f9d feat(web): hydrate federation registry from server in autoConnectAll with localStorage migration 2026-04-01 18:03:59 +02:00
Jannis Braun c22d568605 feat(web): wire federation registry into connectToRemote, loginToRemote, and reconnectInstance flows 2026-04-01 18:01:48 +02:00
Jannis Braun d7e2f25c31 refactor(web): rename removeInstance to disconnectInstance, wire up registry on disconnect 2026-04-01 18:00:08 +02:00
Jannis Braun ce5c164958 feat(web): add federation registry state, syncRegistry, and helper actions to instanceStore 2026-04-01 17:58:17 +02:00
Jannis Braun b89dcb9f2c feat(web): add federation registry API client methods 2026-04-01 17:56:02 +02:00
Jannis Braun 7db9459f11 feat(server): add GET & PUT federation registry API endpoints
Adds persistent federation registry storage endpoints under
/api/users/@me/federation-registry. GET returns all registry entries
with the stored updatedAt timestamp. PUT replaces the full registry via
LWW (409 on stale write) in an atomic transaction.
2026-04-01 17:54:46 +02:00
Jannis Braun 9586ac2f9c feat(server): add user_federation_registry table and federationRegistryUpdatedAt column 2026-04-01 17:52:42 +02:00
Jannis Braun a16da375a8 feat(shared): add FederationRegistryEntry type for persistent federation registry 2026-04-01 17:51:15 +02:00
Jannis Braun 6de56edba0 fix(web): clear hasMore when removing channel states on DM close
removeChannelStates cleared messages and readStates but not hasMore.
When a closed DM was reopened with the same channel ID, loadMessages
saw the stale hasMore entry and skipped loading — showing an empty
chat. Now clears hasMore so messages reload on reopen.
2026-04-01 13:19:41 +02:00
Jannis Braun b1efeda1f3 perf(deploy): parallel deploys, preserve build cache, prod-only runtime deps
Three changes to cut deploy time:
1. deploy.sh: Pi and VM deploy concurrently (wall time = max, not sum)
2. deploy.sh: Build cache capped at 2GB instead of nuked after 24h,
   so pnpm install layer is reused between deploys
3. Dockerfile: runtime stage uses --prod (skip devDeps). Moved tsx
   from devDependencies to dependencies since it's used in CMD.
2026-04-01 13:13:17 +02:00
Jannis Braun f2ca7295d0 chore(server): add vitest as dev dependency with test scripts
Test files existed but vitest wasn't installed. Adds vitest v4,
"test" and "test:watch" scripts. All 22 existing tests pass.
2026-04-01 13:03:03 +02:00
Jannis Braun e1ece8a5b6 feat(federation): inbound typing relay processors + implicit clear on message relay
processDmTypingStartEvent and processDmTypingStopEvent handle
typing indicator relay from peers. Uses federatedId for channel
lookup, resolveLocalUser for ephemeral identity (no stub creation).
Also clears typing indicator in processCreateEvent when a relayed
message arrives — belt-and-suspenders for dropped relay packets.
2026-04-01 12:56:44 +02:00
Jannis Braun b3011fb3da feat(federation): add fire-and-forget S2S typing relay
sendTypingRelay() mirrors sendCallRelay() — direct POST to peers,
no outbox, no retry. Uses federatedId for cross-instance channel
identification. Wired into handleDmTypingStart() for typing_start
and broadcastDmMessage() for typing_stop.
2026-04-01 12:53:55 +02:00
Jannis Braun b5fbc9d90e feat(shared): add dm_typing_start and dm_typing_stop to FederationRelayEvent 2026-04-01 12:50:57 +02:00
Jannis Braun 187f71e68e feat: add dm_typing_stop event to clear typing indicator on message send
Broadcasts dm_typing_stop to DM members before dm_message_created,
so the typing indicator clears immediately when a message arrives
instead of lingering for up to 3 seconds after delivery.
2026-04-01 12:50:03 +02:00
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