Skip to content

Commit 4a33e58

Browse files
authored
Add unit test for device de-/rehydration (#2821)
1 parent 6ee185e commit 4a33e58

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed

spec/unit/crypto/dehydration.spec.ts

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import '../../olm-loader';
18+
import { TestClient } from '../../TestClient';
19+
import { logger } from '../../../src/logger';
20+
import { DEHYDRATION_ALGORITHM } from '../../../src/crypto/dehydration';
21+
22+
const Olm = global.Olm;
23+
24+
describe("Dehydration", () => {
25+
if (!global.Olm) {
26+
logger.warn('Not running dehydration unit tests: libolm not present');
27+
return;
28+
}
29+
30+
beforeAll(function() {
31+
return global.Olm.init();
32+
});
33+
34+
it("should rehydrate a dehydrated device", async () => {
35+
const key = new Uint8Array([1, 2, 3]);
36+
const alice = new TestClient(
37+
"@alice:example.com", "Osborne2", undefined, undefined,
38+
{
39+
cryptoCallbacks: {
40+
getDehydrationKey: async t => key,
41+
},
42+
},
43+
);
44+
45+
const dehydratedDevice = new Olm.Account();
46+
dehydratedDevice.create();
47+
48+
alice.httpBackend.when("GET", "/dehydrated_device").respond(200, {
49+
device_id: "ABCDEFG",
50+
device_data: {
51+
algorithm: DEHYDRATION_ALGORITHM,
52+
account: dehydratedDevice.pickle(new Uint8Array(key)),
53+
},
54+
});
55+
alice.httpBackend.when("POST", "/dehydrated_device/claim").respond(200, {
56+
success: true,
57+
});
58+
59+
expect((await Promise.all([
60+
alice.client.rehydrateDevice(),
61+
alice.httpBackend.flushAllExpected(),
62+
]))[0])
63+
.toEqual("ABCDEFG");
64+
65+
expect(alice.client.getDeviceId()).toEqual("ABCDEFG");
66+
});
67+
68+
it("should dehydrate a device", async () => {
69+
const key = new Uint8Array([1, 2, 3]);
70+
const alice = new TestClient(
71+
"@alice:example.com", "Osborne2", undefined, undefined,
72+
{
73+
cryptoCallbacks: {
74+
getDehydrationKey: async t => key,
75+
},
76+
},
77+
);
78+
79+
await alice.client.initCrypto();
80+
81+
alice.httpBackend.when("GET", "/room_keys/version").respond(404, {
82+
errcode: "M_NOT_FOUND",
83+
});
84+
85+
let pickledAccount = "";
86+
87+
alice.httpBackend.when("PUT", "/dehydrated_device")
88+
.check((req) => {
89+
expect(req.data.device_data).toMatchObject({
90+
algorithm: DEHYDRATION_ALGORITHM,
91+
account: expect.any(String),
92+
});
93+
pickledAccount = req.data.device_data.account;
94+
})
95+
.respond(200, {
96+
device_id: "ABCDEFG",
97+
});
98+
alice.httpBackend.when("POST", "/keys/upload/ABCDEFG")
99+
.check((req) => {
100+
expect(req.data).toMatchObject({
101+
"device_keys": expect.objectContaining({
102+
algorithms: expect.any(Array),
103+
device_id: "ABCDEFG",
104+
user_id: "@alice:example.com",
105+
keys: expect.objectContaining({
106+
"ed25519:ABCDEFG": expect.any(String),
107+
"curve25519:ABCDEFG": expect.any(String),
108+
}),
109+
signatures: expect.objectContaining({
110+
"@alice:example.com": expect.objectContaining({
111+
"ed25519:ABCDEFG": expect.any(String),
112+
}),
113+
}),
114+
}),
115+
"one_time_keys": expect.any(Object),
116+
"org.matrix.msc2732.fallback_keys": expect.any(Object),
117+
});
118+
})
119+
.respond(200, {});
120+
121+
try {
122+
const deviceId =
123+
(await Promise.all([
124+
alice.client.createDehydratedDevice(new Uint8Array(key), {}),
125+
alice.httpBackend.flushAllExpected(),
126+
]))[0];
127+
128+
expect(deviceId).toEqual("ABCDEFG");
129+
expect(deviceId).not.toEqual("");
130+
131+
// try to rehydrate the dehydrated device
132+
const rehydrated = new Olm.Account();
133+
try {
134+
rehydrated.unpickle(new Uint8Array(key), pickledAccount);
135+
} finally {
136+
rehydrated.free();
137+
}
138+
} finally {
139+
alice.client?.crypto?.dehydrationManager?.stop();
140+
alice.client?.crypto?.deviceList.stop();
141+
}
142+
});
143+
});

0 commit comments

Comments
 (0)