UUID-keyed lookups in SignalProtocolStore
This commit is contained in:
parent
6323aedd9b
commit
c7e7d55af4
46 changed files with 2094 additions and 1447 deletions
30
ts/types/Address.ts
Normal file
30
ts/types/Address.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { strictAssert } from '../util/assert';
|
||||
|
||||
import { UUID, UUIDStringType } from './UUID';
|
||||
|
||||
export type AddressStringType = `${UUIDStringType}.${number}`;
|
||||
|
||||
const ADDRESS_REGEXP = /^([0-9a-f-]+).(\d+)$/i;
|
||||
|
||||
export class Address {
|
||||
constructor(public readonly uuid: UUID, public readonly deviceId: number) {}
|
||||
|
||||
public toString(): AddressStringType {
|
||||
return `${this.uuid.toString()}.${this.deviceId}`;
|
||||
}
|
||||
|
||||
public static parse(value: string): Address {
|
||||
const match = value.match(ADDRESS_REGEXP);
|
||||
strictAssert(match !== null, `Invalid Address: ${value}`);
|
||||
const [whole, uuid, deviceId] = match;
|
||||
strictAssert(whole === value, 'Integrity check');
|
||||
return Address.create(uuid, parseInt(deviceId, 10));
|
||||
}
|
||||
|
||||
public static create(uuid: string, deviceId: number): Address {
|
||||
return new Address(new UUID(uuid), deviceId);
|
||||
}
|
||||
}
|
48
ts/types/QualifiedAddress.ts
Normal file
48
ts/types/QualifiedAddress.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { strictAssert } from '../util/assert';
|
||||
|
||||
import { UUID, UUIDStringType } from './UUID';
|
||||
import { Address, AddressStringType } from './Address';
|
||||
|
||||
const QUALIFIED_ADDRESS_REGEXP = /^([0-9a-f-]+):([0-9a-f-]+).(\d+)$/i;
|
||||
|
||||
export type QualifiedAddressCreateOptionsType = Readonly<{
|
||||
ourUuid: string;
|
||||
uuid: string;
|
||||
deviceId: number;
|
||||
}>;
|
||||
|
||||
export type QualifiedAddressStringType = `${UUIDStringType}:${AddressStringType}`;
|
||||
|
||||
export class QualifiedAddress {
|
||||
constructor(
|
||||
public readonly ourUuid: UUID,
|
||||
public readonly address: Address
|
||||
) {}
|
||||
|
||||
public get uuid(): UUID {
|
||||
return this.address.uuid;
|
||||
}
|
||||
|
||||
public get deviceId(): number {
|
||||
return this.address.deviceId;
|
||||
}
|
||||
|
||||
public toString(): QualifiedAddressStringType {
|
||||
return `${this.ourUuid.toString()}:${this.address.toString()}`;
|
||||
}
|
||||
|
||||
public static parse(value: string): QualifiedAddress {
|
||||
const match = value.match(QUALIFIED_ADDRESS_REGEXP);
|
||||
strictAssert(match !== null, `Invalid QualifiedAddress: ${value}`);
|
||||
const [whole, ourUuid, uuid, deviceId] = match;
|
||||
strictAssert(whole === value, 'Integrity check');
|
||||
|
||||
return new QualifiedAddress(
|
||||
new UUID(ourUuid),
|
||||
Address.create(uuid, parseInt(deviceId, 10))
|
||||
);
|
||||
}
|
||||
}
|
12
ts/types/Storage.d.ts
vendored
12
ts/types/Storage.d.ts
vendored
|
@ -30,6 +30,14 @@ export type ThemeSettingType = 'system' | 'light' | 'dark';
|
|||
|
||||
export type NotificationSettingType = 'message' | 'name' | 'count' | 'off';
|
||||
|
||||
export type IdentityKeyMap = Record<
|
||||
string,
|
||||
{
|
||||
privKey: string;
|
||||
pubKey: string;
|
||||
}
|
||||
>;
|
||||
|
||||
// This should be in sync with `STORAGE_UI_KEYS` in `ts/types/StorageUIKeys.ts`.
|
||||
export type StorageAccessType = {
|
||||
'always-relay-calls': boolean;
|
||||
|
@ -55,7 +63,7 @@ export type StorageAccessType = {
|
|||
customColors: CustomColorsItemType;
|
||||
device_name: string;
|
||||
hasRegisterSupportForUnauthenticatedDelivery: boolean;
|
||||
identityKey: KeyPairType;
|
||||
identityKeyMap: IdentityKeyMap;
|
||||
lastHeartbeat: number;
|
||||
lastStartup: number;
|
||||
lastAttemptedToRefreshProfilesAt: number;
|
||||
|
@ -64,7 +72,7 @@ export type StorageAccessType = {
|
|||
password: string;
|
||||
profileKey: ArrayBuffer;
|
||||
regionCode: string;
|
||||
registrationId: number;
|
||||
registrationIdMap: Record<string, number>;
|
||||
remoteBuildExpiration: number;
|
||||
sessionResets: SessionResetsType;
|
||||
showStickerPickerHint: boolean;
|
||||
|
|
44
ts/types/UUID.ts
Normal file
44
ts/types/UUID.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { strictAssert } from '../util/assert';
|
||||
import { isValidGuid } from '../util/isValidGuid';
|
||||
|
||||
export type UUIDStringType = `${string}-${string}-${string}-${string}-${string}`;
|
||||
|
||||
export class UUID {
|
||||
constructor(protected readonly value: string) {
|
||||
strictAssert(isValidGuid(value), `Invalid UUID: ${value}`);
|
||||
}
|
||||
|
||||
public toString(): UUIDStringType {
|
||||
return (this.value as unknown) as UUIDStringType;
|
||||
}
|
||||
|
||||
public isEqual(other: UUID): boolean {
|
||||
return this.value === other.value;
|
||||
}
|
||||
|
||||
public static parse(value: string): UUID {
|
||||
return new UUID(value);
|
||||
}
|
||||
|
||||
public static lookup(identifier: string): UUID | undefined {
|
||||
const conversation = window.ConversationController.get(identifier);
|
||||
const uuid = conversation?.get('uuid');
|
||||
if (uuid === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return new UUID(uuid);
|
||||
}
|
||||
|
||||
public static checkedLookup(identifier: string): UUID {
|
||||
const uuid = UUID.lookup(identifier);
|
||||
strictAssert(
|
||||
uuid !== undefined,
|
||||
`Conversation ${identifier} not found or has no uuid`
|
||||
);
|
||||
return uuid;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue