Page MenuHomePhabricator

D12067.diff
No OneTemporary

D12067.diff

diff --git a/lib/shared/device-list-utils.js b/lib/shared/device-list-utils.js
--- a/lib/shared/device-list-utils.js
+++ b/lib/shared/device-list-utils.js
@@ -6,7 +6,10 @@
SignedDeviceList,
} from '../types/identity-service-types.js';
import { getConfig } from '../utils/config.js';
-import { rawDeviceListFromSignedList } from '../utils/device-list-utils.js';
+import {
+ composeRawDeviceList,
+ rawDeviceListFromSignedList,
+} from '../utils/device-list-utils.js';
export type DeviceListVerificationResult =
| { +valid: true, +deviceList: RawDeviceList }
@@ -118,4 +121,17 @@
return { valid: true, deviceList };
}
-export { verifyAndGetDeviceList };
+async function createAndSignInitialDeviceList(
+ primaryDeviceID: string,
+): Promise<SignedDeviceList> {
+ const initialDeviceList = composeRawDeviceList([primaryDeviceID]);
+ const rawDeviceList = JSON.stringify(initialDeviceList);
+ const { olmAPI } = getConfig();
+ const curPrimarySignature = await olmAPI.signMessage(rawDeviceList);
+ return {
+ rawDeviceList,
+ curPrimarySignature,
+ };
+}
+
+export { verifyAndGetDeviceList, createAndSignInitialDeviceList };
diff --git a/lib/shared/device-list-utils.test.js b/lib/shared/device-list-utils.test.js
--- a/lib/shared/device-list-utils.test.js
+++ b/lib/shared/device-list-utils.test.js
@@ -1,12 +1,16 @@
// @flow
-import { verifyAndGetDeviceList } from './device-list-utils.js';
+import {
+ createAndSignInitialDeviceList,
+ verifyAndGetDeviceList,
+} from './device-list-utils.js';
import type {
RawDeviceList,
SignedDeviceList,
IdentityServiceClient,
} from '../types/identity-service-types.js';
import * as config from '../utils/config.js';
+import { rawDeviceListFromSignedList } from '../utils/device-list-utils.js';
// mockOlmAPIVerification replaces OlmAPI with a mock
// save original to avoid affecting other test suites
@@ -146,6 +150,21 @@
});
});
+describe(createAndSignInitialDeviceList, () => {
+ it('creates initial device list', async () => {
+ const signMessage = jest
+ .fn<[string], string>()
+ .mockResolvedValue('mock_signature');
+ mockOlmAPISign(signMessage);
+
+ const payload = await createAndSignInitialDeviceList('device1');
+ expect(payload.curPrimarySignature).toStrictEqual('mock_signature');
+
+ const raw = rawDeviceListFromSignedList(payload);
+ expect(raw.devices).toStrictEqual(['device1']);
+ });
+});
+
function createDeviceList(
rawList: RawDeviceList,
curPrimarySignature?: string,
@@ -176,3 +195,11 @@
const cfg: any = { olmAPI };
config.registerConfig(cfg);
}
+
+function mockOlmAPISign(func: JestMockFn<[string], Promise<string>>) {
+ const olmAPI: any = {
+ signMessage: func,
+ };
+ const cfg: any = { olmAPI };
+ config.registerConfig(cfg);
+}
diff --git a/lib/utils/device-list-utils.js b/lib/utils/device-list-utils.js
--- a/lib/utils/device-list-utils.js
+++ b/lib/utils/device-list-utils.js
@@ -9,6 +9,13 @@
} from '../types/identity-service-types.js';
import { rawDeviceListValidator } from '../types/identity-service-types.js';
+function composeRawDeviceList(devices: $ReadOnlyArray<string>): RawDeviceList {
+ return {
+ devices,
+ timestamp: Date.now(),
+ };
+}
+
function convertSignedDeviceListsToRawDeviceLists(
signedDeviceLists: UsersSignedDeviceLists,
): UsersRawDeviceLists {
@@ -34,4 +41,5 @@
export {
convertSignedDeviceListsToRawDeviceLists,
rawDeviceListFromSignedList,
+ composeRawDeviceList,
};
diff --git a/native/identity-service/identity-service-context-provider.react.js b/native/identity-service/identity-service-context-provider.react.js
--- a/native/identity-service/identity-service-context-provider.react.js
+++ b/native/identity-service/identity-service-context-provider.react.js
@@ -3,6 +3,7 @@
import * as React from 'react';
import { getOneTimeKeyValues } from 'lib/shared/crypto-utils.js';
+import { createAndSignInitialDeviceList } from 'lib/shared/device-list-utils.js';
import { IdentityClientContext } from 'lib/shared/identity-client-context.js';
import {
type IdentityKeysBlob,
@@ -325,6 +326,9 @@
commCoreModule.getOneTimeKeys(ONE_TIME_KEYS_NUMBER),
commCoreModule.validateAndGetPrekeys(),
]);
+ const initialDeviceList = await createAndSignInitialDeviceList(
+ primaryIdentityPublicKeys.ed25519,
+ );
const registrationResult = await commRustModule.registerPasswordUser(
username,
password,
@@ -337,7 +341,7 @@
getOneTimeKeyValues(contentOneTimeKeys),
getOneTimeKeyValues(notificationsOneTimeKeys),
fid ?? '',
- '', // initialDeviceList
+ JSON.stringify(initialDeviceList),
);
const { userID, accessToken: token } = JSON.parse(registrationResult);
const identityAuthResult = { accessToken: token, userID, username };
@@ -404,6 +408,9 @@
commCoreModule.getOneTimeKeys(ONE_TIME_KEYS_NUMBER),
commCoreModule.validateAndGetPrekeys(),
]);
+ const initialDeviceList = await createAndSignInitialDeviceList(
+ primaryIdentityPublicKeys.ed25519,
+ );
const registrationResult = await commRustModule.registerWalletUser(
siweMessage,
siweSignature,
@@ -416,7 +423,7 @@
getOneTimeKeyValues(contentOneTimeKeys),
getOneTimeKeyValues(notificationsOneTimeKeys),
fid ?? '',
- '', // initialDeviceList
+ JSON.stringify(initialDeviceList),
);
const { userID, accessToken: token } = JSON.parse(registrationResult);
const identityAuthResult = {
diff --git a/native/profile/secondary-device-qr-code-scanner.react.js b/native/profile/secondary-device-qr-code-scanner.react.js
--- a/native/profile/secondary-device-qr-code-scanner.react.js
+++ b/native/profile/secondary-device-qr-code-scanner.react.js
@@ -13,7 +13,6 @@
backupKeysValidator,
type BackupKeys,
} from 'lib/types/backup-types.js';
-import type { RawDeviceList } from 'lib/types/identity-service-types.js';
import {
tunnelbrokerMessageTypes,
type TunnelbrokerMessage,
@@ -24,6 +23,10 @@
type PeerToPeerMessage,
} from 'lib/types/tunnelbroker/peer-to-peer-message-types.js';
import { qrCodeAuthMessageTypes } from 'lib/types/tunnelbroker/qr-code-auth-message-types.js';
+import {
+ composeRawDeviceList,
+ rawDeviceListFromSignedList,
+} from 'lib/utils/device-list-utils.js';
import { assertWithValidator } from 'lib/utils/validation-utils.js';
import type { ProfileNavigationProp } from './profile.react.js';
@@ -72,9 +75,7 @@
invariant(deviceLists.length > 0, 'received empty device list history');
const lastSignedDeviceList = deviceLists[deviceLists.length - 1];
- const deviceList: RawDeviceList = JSON.parse(
- lastSignedDeviceList.rawDeviceList,
- );
+ const deviceList = rawDeviceListFromSignedList(lastSignedDeviceList);
const promises = deviceList.devices.map(recipient =>
tunnelbrokerContext.sendMessage({
@@ -109,19 +110,14 @@
invariant(deviceLists.length > 0, 'received empty device list history');
const lastSignedDeviceList = deviceLists[deviceLists.length - 1];
- const deviceList: RawDeviceList = JSON.parse(
- lastSignedDeviceList.rawDeviceList,
- );
+ const deviceList = rawDeviceListFromSignedList(lastSignedDeviceList);
const { devices } = deviceList;
if (devices.includes(newDeviceID)) {
return;
}
- const newDeviceList: RawDeviceList = {
- devices: [...devices, newDeviceID],
- timestamp: Date.now(),
- };
+ const newDeviceList = composeRawDeviceList([...devices, newDeviceID]);
const signedDeviceList = await signDeviceListUpdate(newDeviceList);
await updateDeviceList(signedDeviceList);
},

File Metadata

Mime Type
text/plain
Expires
Sun, Sep 29, 7:26 PM (20 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2202404
Default Alt Text
D12067.diff (7 KB)

Event Timeline