Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@signalapp/mock-server

Package Overview
Dependencies
Maintainers
8
Versions
115
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@signalapp/mock-server - npm Package Compare versions

Comparing version 8.3.1 to 9.0.0

4

package.json
{
"name": "@signalapp/mock-server",
"version": "8.3.1",
"version": "9.0.0",
"description": "Mock Signal Server for writing tests",

@@ -46,3 +46,3 @@ "main": "src/index.js",

"@indutny/parallel-prettier": "^3.0.0",
"@signalapp/libsignal-client": "^0.58.2",
"@signalapp/libsignal-client": "^0.60.0",
"@tus/file-store": "^1.4.0",

@@ -49,0 +49,0 @@ "@tus/server": "^1.7.0",

@@ -171,4 +171,7 @@ /// <reference types="node" />

readonly secondaryDevices: Device[];
readonly accountEntropyPool: string;
readonly masterKey: Buffer;
readonly mediaRootBackupKey: Buffer;
ephemeralBackupKey: Buffer | undefined;
storageRecordIkm: Buffer | undefined;
readonly userAgent = "OWI";

@@ -175,0 +178,0 @@ constructor(device: Device, config: Config);

@@ -37,2 +37,3 @@ "use strict";

const SignalClient = __importStar(require("@signalapp/libsignal-client"));
const AccountKeys_1 = require("@signalapp/libsignal-client/dist/AccountKeys");
const debug_1 = __importDefault(require("debug"));

@@ -232,5 +233,9 @@ const zkgroup_1 = require("@signalapp/libsignal-client/zkgroup");

secondaryDevices = new Array();
masterKey = crypto_1.default.randomBytes(32);
accountEntropyPool = AccountKeys_1.AccountEntropyPool.generate();
masterKey = (0, crypto_2.deriveMasterKey)(this.accountEntropyPool);
mediaRootBackupKey = crypto_1.default.randomBytes(32);
// Forwarded in provisioning envelope
ephemeralBackupKey;
// Overridable to test legacy encryption modes
storageRecordIkm = crypto_1.default.randomBytes(32);
// TODO(indutny): make primary device type configurable

@@ -553,3 +558,7 @@ userAgent = 'OWI';

async setStorageState(state, previousState) {
const writeOperation = state.createWriteOperation(this.storageKey, previousState);
const writeOperation = state.createWriteOperation({
storageKey: this.storageKey,
recordIkm: this.storageRecordIkm,
previous: previousState,
});
(0, assert_1.default)(writeOperation.manifest, 'write operation without manifest');

@@ -989,3 +998,7 @@ const { updated, error } = await this.config.applyStorageWrite(writeOperation, false);

response = {
keys: { master: this.masterKey },
keys: {
master: this.masterKey,
mediaRootBackupKey: this.mediaRootBackupKey,
accountEntropyPool: this.accountEntropyPool,
},
};

@@ -1240,5 +1253,9 @@ stateChange = SyncState.Keys;

key: keyBuffer,
record: (0, crypto_2.decryptStorageItem)(this.storageKey, {
key,
value: item,
record: (0, crypto_2.decryptStorageItem)({
storageKey: this.storageKey,
recordIkm: this.storageRecordIkm,
item: {
key,
value: item,
},
}),

@@ -1245,0 +1262,0 @@ };

@@ -332,2 +332,4 @@ "use strict";

ephemeralBackupKey: primaryDevice.ephemeralBackupKey,
mediaRootBackupKey: primaryDevice.mediaRootBackupKey,
accountEntropyPool: primaryDevice.accountEntropyPool,
}).finish();

@@ -334,0 +336,0 @@ const { body, ephemeralKey } = (0, crypto_1.encryptProvisionMessage)(Buffer.from(envelopeData), publicKey);

@@ -20,2 +20,11 @@ /// <reference types="node" />

}>;
export type ToStorageItemOptions = Readonly<{
storageKey: Buffer;
recordIkm: Buffer | undefined;
}>;
export type CreateWriteOperationOptions = Readonly<{
storageKey: Buffer;
recordIkm: Buffer | undefined;
previous?: StorageState;
}>;
export declare class StorageState {

@@ -49,3 +58,3 @@ readonly version: number;

hasKey(storageKey: Buffer): boolean;
createWriteOperation(storageKey: Buffer, previous?: StorageState): Proto.IWriteOperation;
createWriteOperation({ storageKey, recordIkm, previous, }: CreateWriteOperationOptions): Proto.IWriteOperation;
inspect(): string;

@@ -52,0 +61,0 @@ diff(oldState: StorageState): DiffResult;

@@ -29,4 +29,9 @@ "use strict";

}
toStorageItem(storageKey) {
return (0, crypto_2.encryptStorageItem)(storageKey, this.key, this.record);
toStorageItem({ storageKey, recordIkm, }) {
return (0, crypto_2.encryptStorageItem)({
storageKey,
recordIkm,
key: this.key,
record: this.record,
});
}

@@ -259,3 +264,3 @@ toIdentifier() {

//
createWriteOperation(storageKey, previous) {
createWriteOperation({ storageKey, recordIkm, previous, }) {
const newVersion = long_1.default.fromNumber(previous ? previous.version + 1 : this.version + 1);

@@ -268,3 +273,3 @@ const keysToDelete = new Set((previous?.items ?? []).map((item) => {

if (!keysToDelete.delete(item.getKeyString())) {
insertItem.push(item.toStorageItem(storageKey));
insertItem.push(item.toStorageItem({ storageKey, recordIkm }));
}

@@ -275,2 +280,3 @@ }

keys: this.items.map((item) => item.toIdentifier()),
recordIkm,
});

@@ -277,0 +283,0 @@ return {

@@ -33,7 +33,25 @@ /// <reference types="node" />

export declare function deriveAccessKey(profileKey: Buffer): Buffer;
export declare function deriveMasterKey(accountEntropyPool: string): Buffer;
export declare function deriveStorageKey(masterKey: Buffer): Buffer;
export type DeriveStorageItemKeyOptions = Readonly<{
storageKey: Buffer;
recordIkm: Buffer | undefined;
key: Buffer;
}>;
export declare function deriveStorageItemKey({ storageKey, recordIkm, key, }: DeriveStorageItemKeyOptions): Buffer;
export declare function decryptStorageManifest(storageKey: Buffer, manifest: Proto.IStorageManifest): Proto.IManifestRecord;
export declare function encryptStorageManifest(storageKey: Buffer, manifestRecord: Proto.IManifestRecord): Proto.IStorageManifest;
export declare function decryptStorageItem(storageKey: Buffer, item: Proto.IStorageItem): Proto.IStorageRecord;
export declare function encryptStorageItem(storageKey: Buffer, key: Buffer, record: Proto.IStorageRecord): Proto.IStorageItem;
export type DecryptStorageItemOptions = Readonly<{
storageKey: Buffer;
recordIkm: Buffer | undefined;
item: Proto.IStorageItem;
}>;
export declare function decryptStorageItem({ storageKey, recordIkm, item, }: DecryptStorageItemOptions): Proto.IStorageRecord;
export type EncryptStorageItemOptions = Readonly<{
storageKey: Buffer;
key: Buffer;
recordIkm: Buffer | undefined;
record: Proto.IStorageRecord;
}>;
export declare function encryptStorageItem({ storageKey, key, recordIkm, record, }: EncryptStorageItemOptions): Proto.IStorageItem;
export declare function encryptProfileName(profileKey: Buffer, name: string): Buffer;

@@ -40,0 +58,0 @@ export declare function generateAccessKeyVerifier(accessKey: Buffer): Buffer;

@@ -8,3 +8,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeKyberPreKey = exports.decodeSignedPreKey = exports.decodePreKey = exports.generateAccessKeyVerifier = exports.encryptProfileName = exports.encryptStorageItem = exports.decryptStorageItem = exports.encryptStorageManifest = exports.decryptStorageManifest = exports.deriveStorageKey = exports.deriveAccessKey = exports.generateSenderCertificate = exports.generateServerCertificate = exports.encryptAttachment = exports.encryptProvisionMessage = void 0;
exports.decodeKyberPreKey = exports.decodeSignedPreKey = exports.decodePreKey = exports.generateAccessKeyVerifier = exports.encryptProfileName = exports.encryptStorageItem = exports.decryptStorageItem = exports.encryptStorageManifest = exports.decryptStorageManifest = exports.deriveStorageItemKey = exports.deriveStorageKey = exports.deriveMasterKey = exports.deriveAccessKey = exports.generateSenderCertificate = exports.generateServerCertificate = exports.encryptAttachment = exports.encryptProvisionMessage = void 0;
const crypto_1 = __importDefault(require("crypto"));

@@ -20,2 +20,3 @@ const buffer_1 = require("buffer");

const AUTH_TAG_SIZE = 16;
const MASTER_KEY_SIZE = 32;
function encryptProvisionMessage(data, remotePubKey) {

@@ -104,2 +105,7 @@ const privateKey = libsignal_client_1.PrivateKey.generate();

exports.deriveAccessKey = deriveAccessKey;
function deriveMasterKey(accountEntropyPool) {
const hkdf = libsignal_client_1.HKDF.new(3);
return hkdf.deriveSecrets(MASTER_KEY_SIZE, buffer_1.Buffer.from(accountEntropyPool), buffer_1.Buffer.from('20240801_SIGNAL_SVR_MASTER_KEY'), null);
}
exports.deriveMasterKey = deriveMasterKey;
function deriveStorageKey(masterKey) {

@@ -116,7 +122,14 @@ const hash = crypto_1.default.createHmac('sha256', masterKey);

}
function deriveStorageItemKey(storageKey, itemKey) {
const hash = crypto_1.default.createHmac('sha256', storageKey);
hash.update(`Item_${itemKey.toString('base64')}`);
return hash.digest();
const STORAGE_SERVICE_ITEM_KEY_INFO_PREFIX = '20240801_SIGNAL_STORAGE_SERVICE_ITEM_';
const STORAGE_SERVICE_ITEM_KEY_LEN = 32;
function deriveStorageItemKey({ storageKey, recordIkm, key, }) {
if (recordIkm === undefined) {
const hash = crypto_1.default.createHmac('sha256', storageKey);
hash.update(`Item_${key.toString('base64')}`);
return hash.digest();
}
const hkdf = libsignal_client_1.HKDF.new(3);
return hkdf.deriveSecrets(STORAGE_SERVICE_ITEM_KEY_LEN, recordIkm, buffer_1.Buffer.concat([buffer_1.Buffer.from(STORAGE_SERVICE_ITEM_KEY_INFO_PREFIX), key]), buffer_1.Buffer.alloc(0));
}
exports.deriveStorageItemKey = deriveStorageItemKey;
function decryptAESGCM(ciphertext, key) {

@@ -167,3 +180,3 @@ const iv = ciphertext.slice(0, AESGCM_IV_SIZE);

exports.encryptStorageManifest = encryptStorageManifest;
function decryptStorageItem(storageKey, item) {
function decryptStorageItem({ storageKey, recordIkm, item, }) {
if (!item.key) {

@@ -175,8 +188,16 @@ throw new Error('Missing item.key');

}
const itemKey = deriveStorageItemKey(storageKey, buffer_1.Buffer.from(item.key));
const itemKey = deriveStorageItemKey({
storageKey,
recordIkm,
key: buffer_1.Buffer.from(item.key),
});
return compiled_1.signalservice.StorageRecord.decode(decryptAESGCM(buffer_1.Buffer.from(item.value), itemKey));
}
exports.decryptStorageItem = decryptStorageItem;
function encryptStorageItem(storageKey, key, record) {
const itemKey = deriveStorageItemKey(storageKey, key);
function encryptStorageItem({ storageKey, key, recordIkm, record, }) {
const itemKey = deriveStorageItemKey({
storageKey,
recordIkm,
key,
});
const encrypted = encryptAESGCM(buffer_1.Buffer.from(compiled_1.signalservice.StorageRecord.encode(record).finish()), itemKey);

@@ -183,0 +204,0 @@ return {

@@ -40,2 +40,3 @@ /// <reference types="node" />

versionedExpirationTimer: boolean;
ssre2: boolean;
};

@@ -42,0 +43,0 @@ backupLevel: BackupLevel;

@@ -21,3 +21,3 @@ "use strict";

capabilities;
backupLevel = zkgroup_1.BackupLevel.Media;
backupLevel = zkgroup_1.BackupLevel.Paid;
accessKey;

@@ -44,2 +44,3 @@ profileKeyCommitment;

versionedExpirationTimer: true,
ssre2: true,
};

@@ -46,0 +47,0 @@ }

@@ -1,2 +0,1 @@

/// <reference types="node" />
import z from 'zod';

@@ -438,7 +437,10 @@ import { AciString, DeviceId, PniString, RegistrationId } from '../types';

export declare const SetBackupIdSchema: z.ZodObject<{
backupAuthCredentialRequest: z.ZodEffects<z.ZodString, Buffer, string>;
messagesBackupAuthCredentialRequest: z.ZodEffects<z.ZodString, Buffer, string>;
mediaBackupAuthCredentialRequest: z.ZodEffects<z.ZodString, Buffer, string>;
}, "strip", z.ZodTypeAny, {
backupAuthCredentialRequest: Buffer;
messagesBackupAuthCredentialRequest: Buffer;
mediaBackupAuthCredentialRequest: Buffer;
}, {
backupAuthCredentialRequest: string;
messagesBackupAuthCredentialRequest: string;
mediaBackupAuthCredentialRequest: string;
}>;

@@ -471,7 +473,7 @@ export type SetBackupId = z.infer<typeof SetBackupIdSchema>;

}, "strip", z.ZodTypeAny, {
cdn: number;
key: string;
}, {
cdn: number;
}, {
key: string;
cdn: number;
}>;

@@ -485,4 +487,4 @@ objectLength: z.ZodNumber;

sourceAttachment: {
cdn: number;
key: string;
cdn: number;
};

@@ -496,4 +498,4 @@ objectLength: number;

sourceAttachment: {
cdn: number;
key: string;
cdn: number;
};

@@ -509,4 +511,4 @@ objectLength: number;

sourceAttachment: {
cdn: number;
key: string;
cdn: number;
};

@@ -522,4 +524,4 @@ objectLength: number;

sourceAttachment: {
cdn: number;
key: string;
cdn: number;
};

@@ -526,0 +528,0 @@ objectLength: number;

@@ -106,3 +106,4 @@ "use strict";

exports.SetBackupIdSchema = zod_1.default.object({
backupAuthCredentialRequest: zod_1.default.string().transform(util_1.fromBase64),
messagesBackupAuthCredentialRequest: zod_1.default.string().transform(util_1.fromBase64),
mediaBackupAuthCredentialRequest: zod_1.default.string().transform(util_1.fromBase64),
});

@@ -109,0 +110,0 @@ exports.BackupHeadersSchema = zod_1.default.object({

@@ -40,2 +40,6 @@ /// <reference types="node" />

}>;
export type BackupCredentials = Readonly<{
MESSAGES: Credentials;
MEDIA: Credentials;
}>;
export type ChallengeResponse = Readonly<{

@@ -264,3 +268,3 @@ code: number;

issueExpiringProfileKeyCredential({ aci, profileKeyCommitment }: Device, request: ProfileKeyCredentialRequest): Promise<Buffer | undefined>;
setBackupId({ aci }: Device, { backupAuthCredentialRequest }: SetBackupId): Promise<void>;
setBackupId({ aci }: Device, { messagesBackupAuthCredentialRequest, mediaBackupAuthCredentialRequest, }: SetBackupId): Promise<void>;
setBackupKey(headers: BackupHeaders, { backupIdPublicKey }: SetBackupKey): Promise<void>;

@@ -275,3 +279,3 @@ refreshBackup(headers: BackupHeaders): Promise<void>;

authorizeBackupCDN(backupId: string, password: string): Promise<boolean>;
getBackupCredentials({ aci, backupLevel }: Device, range: CredentialsRange): Promise<Credentials | undefined>;
getBackupCredentials({ aci, backupLevel }: Device, range: CredentialsRange): Promise<BackupCredentials | undefined>;
protected onNewBackupMediaObject(backupId: string, media: BackupMediaObject): Promise<void>;

@@ -278,0 +282,0 @@ protected abstract backupTransitAttachments(backupId: string, batch: BackupMediaBatch): Promise<Array<BackupMediaBatchResponse>>;

@@ -11,2 +11,4 @@ "use strict";

const zkgroup_1 = require("@signalapp/libsignal-client/zkgroup");
// TODO(indutny): wait for libsignal release
const BackupCredentialType_1 = __importDefault(require("@signalapp/libsignal-client/dist/zkgroup/backups/BackupCredentialType"));
const assert_1 = __importDefault(require("assert"));

@@ -788,5 +790,7 @@ const crypto_1 = __importDefault(require("crypto"));

}
async setBackupId({ aci }, { backupAuthCredentialRequest }) {
const req = new zkgroup_1.BackupAuthCredentialRequest(backupAuthCredentialRequest);
this.backupAuthReqByAci.set(aci, req);
async setBackupId({ aci }, { messagesBackupAuthCredentialRequest, mediaBackupAuthCredentialRequest, }) {
this.backupAuthReqByAci.set(aci, {
messages: new zkgroup_1.BackupAuthCredentialRequest(messagesBackupAuthCredentialRequest),
media: new zkgroup_1.BackupAuthCredentialRequest(mediaBackupAuthCredentialRequest),
});
}

@@ -890,5 +894,12 @@ async setBackupKey(headers, { backupIdPublicKey }) {

}
return this.issueCredentials(range, (redemptionTime) => {
return req.issueCredential(redemptionTime, backupLevel, this.backupServerSecret);
const messages = this.issueCredentials(range, (redemptionTime) => {
return req.messages.issueCredential(redemptionTime, zkgroup_1.BackupLevel.Free, BackupCredentialType_1.default.Messages, this.backupServerSecret);
});
const media = this.issueCredentials(range, (redemptionTime) => {
return req.media.issueCredential(redemptionTime, backupLevel, BackupCredentialType_1.default.Media, this.backupServerSecret);
});
return {
MESSAGES: messages,
MEDIA: media,
};
}

@@ -895,0 +906,0 @@ async onNewBackupMediaObject(backupId, media) {

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc