fix(server): canonicalize spaceInstanceOrigin before storing payload

Empty-string (local) origin is now stored as the absolute home origin
so relayed DM space-invite cards carry the correct value to remote
recipients instead of resolving against the wrong instance.
This commit is contained in:
Jannis Braun
2026-04-29 22:35:34 +02:00
parent 44e9a4234c
commit bc66ddc633
2 changed files with 37 additions and 1 deletions
@@ -248,6 +248,11 @@ describe('POST /api/dm/space-invite', () => {
expect(parsed.snapshot.avatarColor).toBe('mint');
expect(parsed.snapshot.description).toBe('desc');
expect(parsed.snapshot.instanceName).toBe('Backspace');
// Canonicalization: empty origin (local) must be stored as the absolute home
// origin so relayed messages carry the correct value to remote recipients.
expect(parsed.spaceInstanceOrigin).toBe('https://local.test');
expect(parsed.spaceInstanceOrigin).not.toBe('');
});
it('reuses an existing 1-on-1 DM rather than creating a new one', async () => {
@@ -386,4 +391,35 @@ describe('POST /api/dm/space-invite', () => {
expect(fetchSpaceInviteSnapshot).toHaveBeenCalledWith('https://remote.example', 'abc');
expect(getLocalInviteSnapshot).not.toHaveBeenCalled();
});
it('preserves explicit remote spaceInstanceOrigin in stored payload', async () => {
(fetchSpaceInviteSnapshot as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
spaceId: 'S1',
spaceName: 'Remote',
description: null,
icon: null,
avatarColor: null,
memberCount: 5,
instanceName: 'OtherHost',
});
const res = await app.inject({
method: 'POST',
url: '/api/dm/space-invite',
payload: {
target: { userId: 'bob' },
spaceId: 'S1',
spaceInstanceOrigin: 'https://other.example',
inviteCode: 'abc',
},
});
expect(res.statusCode).toBe(200);
const body = JSON.parse(res.body) as { messageId: string };
const stored = testDb.select()
.from(schema.dmMessages)
.where(eq(schema.dmMessages.id, body.messageId))
.get();
const parsed = JSON.parse(stored!.content!);
expect(parsed.spaceInstanceOrigin).toBe('https://other.example');
});
});
+1 -1
View File
@@ -1757,7 +1757,7 @@ export async function dmRoutes(app: FastifyInstance): Promise<void> {
const payload: SpaceInviteSystemPayload = {
event: 'space_invite',
spaceId: body.spaceId,
spaceInstanceOrigin: body.spaceInstanceOrigin,
spaceInstanceOrigin: spaceOrigin,
inviteCode: body.inviteCode,
snapshot: {
spaceName: snapshot.spaceName,