UNPKG

@signalapp/mock-server

Version:
181 lines (180 loc) 6.13 kB
"use strict"; // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Device = void 0; const debug_1 = __importDefault(require("debug")); const libsignal_client_1 = require("@signalapp/libsignal-client"); const zkgroup_1 = require("@signalapp/libsignal-client/zkgroup"); const types_1 = require("../types"); const debug = (0, debug_1.default)('mock:device'); // Technically, it is infinite. const PRE_KEY_ITERATOR_COUNT = 100; class Device { aci; deviceId; address; capabilities; backupLevel = zkgroup_1.BackupLevel.Paid; accessKey; profileKeyCommitment; profileName; keys = new Map(); privPni; privNumber; privPniAddress; registrationId; pniRegistrationId; constructor(options) { this.aci = options.aci; this.deviceId = options.deviceId; this.registrationId = options.registrationId; this.privPni = options.pni; this.privNumber = options.number; this.pniRegistrationId = options.pniRegistrationId; this.address = libsignal_client_1.ProtocolAddress.new(this.aci, this.deviceId); this.privPniAddress = libsignal_client_1.ProtocolAddress.new(this.pni, this.deviceId); this.capabilities = { deleteSync: true, versionedExpirationTimer: true, ssre2: true, }; } get debugId() { return `${this.aci}.${this.deviceId}`; } getRegistrationId(serviceIdKind) { switch (serviceIdKind) { case types_1.ServiceIdKind.ACI: return this.registrationId; case types_1.ServiceIdKind.PNI: return this.pniRegistrationId; } } get pni() { return this.privPni; } get number() { return this.privNumber; } get pniAddress() { return this.privPniAddress; } async changeNumber({ number, pni, pniRegistrationId, }) { this.privNumber = number; this.privPni = pni; this.pniRegistrationId = pniRegistrationId; this.privPniAddress = libsignal_client_1.ProtocolAddress.new(this.pni, this.deviceId); } async setKeys(serviceIdKind, keys) { debug('setting %s keys for %s', serviceIdKind, this.debugId); const existingKeys = this.keys.get(serviceIdKind); const { signedPreKey = existingKeys?.signedPreKey, lastResortKey = existingKeys?.lastResortKey, } = keys; if (!signedPreKey) { throw new Error('setKeys: Missing signedPreKey'); } if (!lastResortKey) { throw new Error('setKeys: Missing lastResortKey'); } this.keys.set(serviceIdKind, { identityKey: keys.identityKey, signedPreKey, preKeys: keys.preKeys?.slice() ?? [], kyberPreKeys: keys.kyberPreKeys?.slice() ?? [], lastResortKey, preKeyIterator: keys.preKeyIterator, kyberPreKeyIterator: keys.kyberPreKeyIterator, }); } async getIdentityKey(serviceIdKind = types_1.ServiceIdKind.ACI) { const keys = this.keys.get(serviceIdKind); if (!keys) { throw new Error('No keys available for device'); } return keys.identityKey; } async popSingleUseKey(serviceIdKind = types_1.ServiceIdKind.ACI) { const keys = this.keys.get(serviceIdKind); if (!keys) { throw new Error('No keys available for device'); } debug('popping single use key for %s', this.debugId); let preKey; if (keys.preKeyIterator) { const { value } = await keys.preKeyIterator.next(); preKey = value; } if (!preKey) { preKey = keys.preKeys.shift(); } let pqPreKey; if (keys.kyberPreKeyIterator) { const { value } = await keys.kyberPreKeyIterator.next(); pqPreKey = value; } if (!pqPreKey) { pqPreKey = keys.kyberPreKeys.shift(); } if (!pqPreKey) { pqPreKey = keys.lastResortKey; } if (!pqPreKey) { throw new Error('popSingleUseKey: Missing pqPreKey; checked iterator/array/lastResort'); } return { identityKey: keys.identityKey, signedPreKey: keys.signedPreKey, preKey, pqPreKey, }; } async getPreKeyCount(serviceIdKind = types_1.ServiceIdKind.ACI) { const keys = this.keys.get(serviceIdKind); if (!keys) { throw new Error('No keys available for device'); } if (keys.preKeyIterator) { return PRE_KEY_ITERATOR_COUNT; } return keys.preKeys.length; } async getKyberPreKeyCount(serviceIdKind = types_1.ServiceIdKind.ACI) { const keys = this.keys.get(serviceIdKind); if (!keys) { throw new Error('No keys available for device'); } if (keys.kyberPreKeyIterator) { return PRE_KEY_ITERATOR_COUNT; } return keys.kyberPreKeys.length; } getServiceIdByKind(serviceIdKind) { switch (serviceIdKind) { case types_1.ServiceIdKind.ACI: return this.aci; case types_1.ServiceIdKind.PNI: return this.pni; } } getServiceIdKind(serviceId) { if (serviceId === this.aci) { return types_1.ServiceIdKind.ACI; } if (serviceId === this.pni) { return types_1.ServiceIdKind.PNI; } throw new Error(`Unknown serviceId: ${serviceId}`); } getAddressByKind(serviceIdKind) { switch (serviceIdKind) { case types_1.ServiceIdKind.ACI: return this.address; case types_1.ServiceIdKind.PNI: return this.pniAddress; } } } exports.Device = Device;