Move file transfer restriction into network settings

This commit is contained in:
2026-10-15 13:51:36 +09:00
parent 328fad2e36
commit 9cda9cbe84
20 changed files with 456 additions and 88 deletions

View File

@@ -274,7 +274,7 @@ test('resumable offsets and completion honor the accepted manifest after reducin
'upload-offset': String(offset),
});
assert.equal((await put(0, bytes.subarray(0, CHUNK_BYTES))).statusCode, 200);
await patch(f, admin, { perFileBytes: 1, accountBytes: 1 });
await patch(f, admin, { perFileBytes: 1, accountBytes: 1, uploadsPaused: true });
assert.equal(
(await put(CHUNK_BYTES, bytes.subarray(CHUNK_BYTES))).statusCode,
200,
@@ -283,7 +283,7 @@ test('resumable offsets and completion honor the accepted manifest after reducin
const completed = await f.call(user, `/uploads/resumable/${id}/complete`, 'POST', {});
assert.equal(completed.statusCode, 200, completed.body);
assert.equal((await f.call(user, '/account/storage')).json().usedBytes, bytes.length);
assert.equal((await own(f, user)).json().code, 'TRANSFER_LIMIT');
assert.equal((await own(f, user)).json().code, 'UPLOADS_PAUSED');
} finally {
await f.close();
}
@@ -364,3 +364,119 @@ test('offline transfer reset removes only transfer/guest data and keeps accounts
await rm(folder, { recursive: true, force: true });
}
});
test(
'file-only ban publishes a minimal live policy, blocks new uploads, stored-file forwarding and pending acceptance while allowing clipboard and accepted uploads',
{ timeout: 20000 },
async () => {
const f = await fixture();
try {
const admin = await signed(f, 'hello@noname.company'),
a = await f.create(),
b = await f.create(),
c = await f.create(),
d = await f.create();
await f.space(a, b);
await f.space(a, admin);
await f.space(c, d);
const original = await own(f, admin);
assert.equal(
(await upload(f, admin, original.json().requestId, Buffer.from('12345678'))).statusCode,
200,
);
const stored = (await f.call(admin, '/vault')).json().items[0];
const pending = await request(f, a, b),
accepted = await accept(f, d, await request(f, c, d));
assert.equal(pending.statusCode, 200, pending.body);
const event = new Promise((resolve) => a.socket.once('service:policy', resolve));
const settings = await patch(f, admin, { uploadsPaused: true });
assert.deepEqual(await event, { fileTransfersAllowed: false, revision: settings.revision });
const snapshot = (await f.call(a, '/device/snapshot')).json();
assert.deepEqual(snapshot.servicePolicy, {
fileTransfersAllowed: false,
revision: settings.revision,
});
assert.equal('blockedIps' in snapshot.servicePolicy, false);
assert.equal((await request(f, a, b)).json().code, 'UPLOADS_PAUSED');
assert.equal((await own(f, admin)).json().code, 'UPLOADS_PAUSED');
assert.equal(
(
await f.call(
b,
`/transfer-requests/${pending.json().requestId}/accept`,
'POST',
{},
randomUUID(),
)
).json().code,
'UPLOADS_PAUSED',
);
assert.equal(
(
await f.call(
admin,
`/vault/${stored.accessId}/send`,
'POST',
{ targetDeviceId: b.deviceId },
randomUUID(),
)
).json().code,
'UPLOADS_PAUSED',
);
assert.deepEqual(
(await f.call(admin, `/access/${stored.accessId}/download`)).rawPayload,
Buffer.from('12345678'),
);
assert.equal((await upload(f, c, accepted, Buffer.from('12345678'))).statusCode, 200);
await f.call(
a,
`/transfer-requests/${pending.json().requestId}/cancel`,
'POST',
{},
randomUUID(),
);
await f.complete(a, b, 'https://example.test/allowed');
for (const body of [
{ kind: 'url', urls: ['https://example.test/clipboard'] },
{ kind: 'text', text: '한글 日本語 😀\n 공백 유지' },
]) {
const saved = await f.call(admin, '/vault', 'POST', body, randomUUID());
assert.equal(saved.statusCode, 200, saved.body);
const item = (await f.call(admin, '/vault'))
.json()
.items.find((item) => item.kind === body.kind);
const forwarded = await f.call(
admin,
`/vault/${item.accessId}/send`,
'POST',
{ targetDeviceId: b.deviceId },
randomUUID(),
);
assert.equal(forwarded.statusCode, 200, forwarded.body);
const received = await f.call(
b,
`/transfer-requests/${forwarded.json().requestId}/accept`,
'POST',
{},
randomUUID(),
);
assert.equal(received.statusCode, 200, received.body);
}
const reconnected = new Promise((resolve) => a.socket.once('service:policy', resolve));
a.socket.disconnect();
a.socket.connect();
assert.deepEqual(await reconnected, {
fileTransfersAllowed: false,
revision: settings.revision,
});
await patch(f, admin, { uploadsPaused: false });
assert.equal((await request(f, a, b)).statusCode, 200);
assert.equal(
(await f.call(a, '/device/snapshot')).json().servicePolicy.fileTransfersAllowed,
true,
);
} finally {
await f.close();
}
},
);