UNPKG

@signalapp/mock-server

Version:
120 lines (119 loc) 4.72 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.Group = void 0; const assert_1 = __importDefault(require("assert")); const zkgroup_1 = require("@signalapp/libsignal-client/zkgroup"); const libsignal_client_1 = require("@signalapp/libsignal-client"); const compiled_1 = require("../../protos/compiled"); const group_1 = require("../data/group"); const AccessRequired = compiled_1.signalservice.AccessControl.AccessRequired; function encryptBlob(cipher, proto) { const plaintext = compiled_1.signalservice.GroupAttributeBlob.encode(proto); return Buffer.from(cipher.encryptBlob(plaintext)); } function decryptBlob(cipher, ciphertext) { const plaintext = cipher.decryptBlob(Buffer.from(ciphertext)); return compiled_1.signalservice.GroupAttributeBlob.decode(plaintext); } class Group extends group_1.Group { secretParams; title; constructor({ secretParams, groupState }) { super(); assert_1.default.ok(groupState.title, 'Group must have a title blob'); this.secretParams = secretParams; const cipher = new zkgroup_1.ClientZkGroupCipher(secretParams); const decrypted = decryptBlob(cipher, groupState.title); (0, assert_1.default)(decrypted.content?.title != null, 'expected title'); this.title = decrypted.content.title; this.privPublicParams = this.secretParams.getPublicParams(); // Build group log this.privChanges = { groupChanges: [ { groupState, groupChange: null, }, ], groupSendEndorsementsResponse: null, }; } static fromConfig({ secretParams, title, members, }) { const cipher = new zkgroup_1.ClientZkGroupCipher(secretParams); const groupState = { publicKey: secretParams.getPublicParams().serialize(), version: 0, title: encryptBlob(cipher, { content: { title } }), // TODO(indutny): make it configurable accessControl: { attributes: AccessRequired.MEMBER, members: AccessRequired.MEMBER, addFromInviteLink: AccessRequired.UNSATISFIABLE, memberLabel: AccessRequired.MEMBER, }, members: members.map(({ presentation }) => { return { role: compiled_1.signalservice.Member.Role.ADMINISTRATOR, presentation: presentation.serialize(), userId: null, profileKey: null, joinedAtVersion: null, labelEmoji: null, labelString: null, }; }), avatarUrl: null, disappearingMessagesTimer: null, membersPendingProfileKey: null, membersPendingAdminApproval: null, inviteLinkPassword: null, description: null, announcementsOnly: null, membersBanned: null, terminated: null, }; return new Group({ secretParams, groupState, }); } get masterKey() { return Buffer.from(this.secretParams.getMasterKey().serialize()); } toContext() { const masterKey = this.masterKey; return { masterKey, revision: this.revision, groupChange: null, }; } encryptServiceId(serviceId) { const cipher = new zkgroup_1.ClientZkGroupCipher(this.secretParams); return Buffer.from(cipher .encryptServiceId(libsignal_client_1.ServiceId.parseFromServiceIdString(serviceId)) .serialize()); } decryptServiceId(ciphertext) { const cipher = new zkgroup_1.ClientZkGroupCipher(this.secretParams); const uuidCiphertext = new zkgroup_1.UuidCiphertext(Buffer.from(ciphertext)); return cipher .decryptServiceId(uuidCiphertext) .getServiceIdString(); } getMemberByServiceId(serviceId) { return this.getMember(new zkgroup_1.UuidCiphertext(this.encryptServiceId(serviceId))); } getPendingMemberByServiceId(serviceId) { return this.getPendingMember(new zkgroup_1.UuidCiphertext(this.encryptServiceId(serviceId))); } encryptBlob(proto) { return encryptBlob(new zkgroup_1.ClientZkGroupCipher(this.secretParams), proto); } } exports.Group = Group;