feat(api): bind encrypted workspaces to accounts and devices

This commit is contained in:
justme committed 2026-10-13 01:38:19 +08:00
1 parent 019b15041a
commit c7d8ef15bc
49 files changed
+1904 -278

No files matched your search

+12 -10
View File
@@ -315,29 +315,30 @@ describe('设备名', () => {
});
describe('raw 模式往返', () => {
it('单帧:负载就是内容,没有加密标志', async () => {
it('单帧:保留统一元数据,没有加密标志', async () => {
const { session: owner } = await ChannelSession.create({ mode: 'raw' });
const member = await ChannelSession.open(owner.link(ORIGIN));
const [frame] = await collectFrames(owner.encryptText('明文内容'));
expect(frame!.bytes[1]! & 8).toBe(0); // 没有 ENC 标志
expect(new TextDecoder().decode(frame!.bytes.slice(26))).toBe('明文内容');
expect(new TextDecoder().decode(frame!.bytes.slice(26))).toContain('明文内容');
const item = itemOf(await member.createItemReader().pushFrame(frame!.bytes));
expect(item.kind).toBe('raw');
expect(item.meta).toBeUndefined();
expect(item.kind).toBe('text');
expect(item.meta?.kind).toBe('text');
expect(itemText(item)).toBe('明文内容');
});
it('大内容拆成 GATED 多帧', async () => {
const { session } = await ChannelSession.create({ mode: 'raw' });
const content = pseudoRandom(100, 5);
const plan = session.encryptBytes(content, {}, { maxFrameData: 40 });
const plan = session.encryptBytes(content, {}, { maxFrameData: 80 });
const frames = await collectFrames(plan);
expect(plan.gated).toBe(true);
expect(frames.map((f) => f.bytes.length - 26)).toEqual([40, 40, 20]);
expect(frames.map((f) => f.final)).toEqual([false, false, true]);
expect(frames.length).toBeGreaterThan(1);
expect(frames.every((f) => f.bytes.length - 26 <= 80)).toBe(true);
expect(frames.at(-1)?.final).toBe(true);
const reader = session.createItemReader();
let last: ReceivedItem | undefined;
@@ -346,10 +347,11 @@ describe('raw 模式往返', () => {
expect(toHex(last!.content)).toBe(toHex(content));
});
it('label 放进第 0 帧的附加请求头', async () => {
it('名称使用与加密条目一致的元数据', async () => {
const { session } = await ChannelSession.create({ mode: 'raw' });
const plan = session.encryptBytes(new Uint8Array(3), {}, { label: 'note.txt' });
expect(plan.frame0Headers['X-WD-Label']).toBe('note.txt');
const plan = session.encryptBytes(new Uint8Array(3), { name: 'note.txt' });
const [frame] = await collectFrames(plan);
expect(itemOf(await session.createItemReader().pushFrame(frame!.bytes)).meta?.name).toBe('note.txt');
});
});