feat(federation): receiver guard — never create replicated stubs homed at our own domain (dead-incarnation spec §3.1)
This commit is contained in:
@@ -24,6 +24,11 @@ vi.mock('../utils/snowflake.js', () => ({
|
||||
setWorkerId: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('../utils/federationAuth.js', async (importActual) => {
|
||||
const actual = await importActual<typeof import('../utils/federationAuth.js')>();
|
||||
return { ...actual, getOurOrigin: () => 'https://home.test' };
|
||||
});
|
||||
|
||||
// federation.ts also imports connectionManager/ws — stub minimal surface so
|
||||
// the route module loads at test time. The function under test doesn't touch any of these.
|
||||
vi.mock('../ws/handler.js', () => ({
|
||||
@@ -84,3 +89,46 @@ describe('resolveOrCreateReplicatedUser — stub username', () => {
|
||||
expect(created!.username).toBe('310002371434024960@orbit.ddns.net');
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolveOrCreateReplicatedUser — self-homed identity guard', () => {
|
||||
it('refuses to create a stub homed at our own domain (dead incarnation)', async () => {
|
||||
const { resolveOrCreateReplicatedUser } = await import('./federation.js');
|
||||
const result = resolveOrCreateReplicatedUser(
|
||||
'dead-incarnation-id',
|
||||
'home.test',
|
||||
testDb,
|
||||
{ username: 'youruser' },
|
||||
);
|
||||
expect(result).toBeNull();
|
||||
const rows = testDb.select().from(schema.users).all();
|
||||
expect(rows).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('refuses self-homed creation regardless of homeInstance URL shape', async () => {
|
||||
const { resolveOrCreateReplicatedUser } = await import('./federation.js');
|
||||
expect(resolveOrCreateReplicatedUser('dead-1', 'https://home.test', testDb, { username: 'x' })).toBeNull();
|
||||
expect(resolveOrCreateReplicatedUser('dead-2', 'HOME.TEST', testDb, { username: 'x' })).toBeNull();
|
||||
expect(testDb.select().from(schema.users).all()).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('still resolves a LIVE native user referenced by self-domain identity (tier 1)', async () => {
|
||||
testDb.insert(schema.users).values({
|
||||
id: 'native-1',
|
||||
username: 'alice',
|
||||
passwordHash: 'real-hash',
|
||||
homeInstance: null,
|
||||
createdAt: 1,
|
||||
}).run();
|
||||
const { resolveOrCreateReplicatedUser } = await import('./federation.js');
|
||||
const result = resolveOrCreateReplicatedUser('native-1', 'https://home.test', testDb, { username: 'alice' });
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.id).toBe('native-1');
|
||||
});
|
||||
|
||||
it('still creates stubs for remote-domain identities (unchanged behavior)', async () => {
|
||||
const { resolveOrCreateReplicatedUser } = await import('./federation.js');
|
||||
const result = resolveOrCreateReplicatedUser('remote-1', 'orbit.ddns.net', testDb, { username: 'bob' });
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.username).toBe('bob@orbit.ddns.net');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user