fix(federation): close re-attach final-review findings — client/server domain normalization, merge attachment repoint, empty-domain guard, test hardening
This commit is contained in:
@@ -37,6 +37,30 @@ describe('verifyAttachProofWithPeer', () => {
|
||||
expect(await verifyAttachProofWithPeer(PEER, 'a'.repeat(64))).toEqual({ valid: false });
|
||||
});
|
||||
|
||||
it('treats a PRESENT-but-INVALID signature as valid:false (signature must verify against the peer secret)', async () => {
|
||||
// A 200 response with a well-formed signature header that was computed with
|
||||
// the WRONG secret — it must NOT verify against the peer's real secret. This
|
||||
// hardens the core "never trust unauthenticated bodies" gate: a malicious or
|
||||
// misconfigured peer that returns valid:true with a bogus signature is rejected.
|
||||
const wrongSignedResponse = (bodyObj: object): Response => {
|
||||
const body = JSON.stringify(bodyObj);
|
||||
const ts = Date.now();
|
||||
const nonce = 'resp-nonce';
|
||||
const sig = signRequest(body, 'c'.repeat(64) /* wrong secret */, ts, nonce);
|
||||
return new Response(body, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'x-federation-signature': `sha256=${sig}`,
|
||||
'x-federation-timestamp': String(ts),
|
||||
'x-federation-nonce': nonce,
|
||||
},
|
||||
});
|
||||
};
|
||||
vi.stubGlobal('fetch', vi.fn(async () => wrongSignedResponse({ valid: true, homeUserId: 'h1', username: 'youruser' })));
|
||||
const { verifyAttachProofWithPeer } = await import('./federationAttach.js');
|
||||
expect(await verifyAttachProofWithPeer(PEER, 'a'.repeat(64))).toEqual({ valid: false });
|
||||
});
|
||||
|
||||
it('network error → valid:false', async () => {
|
||||
vi.stubGlobal('fetch', vi.fn(async () => { throw new Error('ECONNREFUSED'); }));
|
||||
const { verifyAttachProofWithPeer } = await import('./federationAttach.js');
|
||||
@@ -56,9 +80,15 @@ describe('fetchHomeProfileByHomeId', () => {
|
||||
expect(result?.profile.avatar).toBe('a.webp');
|
||||
});
|
||||
|
||||
it('found:false or network error → null', async () => {
|
||||
it('found:false → null', async () => {
|
||||
vi.stubGlobal('fetch', vi.fn(async () => new Response(JSON.stringify({ found: false }), { status: 200 })));
|
||||
const { fetchHomeProfileByHomeId } = await import('./federationAttach.js');
|
||||
expect(await fetchHomeProfileByHomeId(PEER, 'h1')).toBeNull();
|
||||
});
|
||||
|
||||
it('network error → null', async () => {
|
||||
vi.stubGlobal('fetch', vi.fn(async () => { throw new Error('ECONNREFUSED'); }));
|
||||
const { fetchHomeProfileByHomeId } = await import('./federationAttach.js');
|
||||
expect(await fetchHomeProfileByHomeId(PEER, 'h1')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user