@signalapp/libsignal-client 0.84.0 → 0.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Native.d.ts CHANGED
@@ -642,13 +642,11 @@ export function TESTING_FakeChatConnection_TakeAuthenticatedChat(chat: Wrapper<F
642
642
  export function TESTING_FakeChatConnection_TakeRemote(chat: Wrapper<FakeChatConnection>): FakeChatRemoteEnd;
643
643
  export function TESTING_FakeChatConnection_TakeUnauthenticatedChat(chat: Wrapper<FakeChatConnection>): UnauthenticatedChatConnection;
644
644
  export function TESTING_FakeChatRemoteEnd_InjectConnectionInterrupted(chat: Wrapper<FakeChatRemoteEnd>): void;
645
- export function TESTING_FakeChatRemoteEnd_ReceiveIncomingRequest(asyncRuntime: Wrapper<TokioAsyncContext>, chat: Wrapper<FakeChatRemoteEnd>): CancellablePromise<FakeChatSentRequest | null>;
645
+ export function TESTING_FakeChatRemoteEnd_ReceiveIncomingRequest(asyncRuntime: Wrapper<TokioAsyncContext>, chat: Wrapper<FakeChatRemoteEnd>): CancellablePromise<[HttpRequest, bigint] | null>;
646
646
  export function TESTING_FakeChatRemoteEnd_SendRawServerRequest(chat: Wrapper<FakeChatRemoteEnd>, bytes: Uint8Array): void;
647
647
  export function TESTING_FakeChatRemoteEnd_SendRawServerResponse(chat: Wrapper<FakeChatRemoteEnd>, bytes: Uint8Array): void;
648
648
  export function TESTING_FakeChatRemoteEnd_SendServerResponse(chat: Wrapper<FakeChatRemoteEnd>, response: Wrapper<FakeChatResponse>): void;
649
649
  export function TESTING_FakeChatResponse_Create(id: bigint, status: number, message: string, headers: string[], body: Uint8Array | null): FakeChatResponse;
650
- export function TESTING_FakeChatSentRequest_RequestId(request: Wrapper<FakeChatSentRequest>): bigint;
651
- export function TESTING_FakeChatSentRequest_TakeHttpRequest(request: Wrapper<FakeChatSentRequest>): HttpRequest;
652
650
  export function TESTING_FakeChatServer_Create(): FakeChatServer;
653
651
  export function TESTING_FakeChatServer_GetNextRemote(asyncRuntime: Wrapper<TokioAsyncContext>, server: Wrapper<FakeChatServer>): CancellablePromise<FakeChatRemoteEnd>;
654
652
  export function TESTING_FakeRegistrationSession_CreateSession(asyncRuntime: Wrapper<TokioAsyncContext>, createSession: RegistrationCreateSessionRequest, chat: Wrapper<FakeChatServer>): CancellablePromise<RegistrationService>;
@@ -714,6 +712,7 @@ export function UnauthenticatedChatConnection_info(chat: Wrapper<Unauthenticated
714
712
  export function UnauthenticatedChatConnection_init_listener(chat: Wrapper<UnauthenticatedChatConnection>, listener: ChatListener): void;
715
713
  export function UnauthenticatedChatConnection_look_up_username_hash(asyncRuntime: Wrapper<TokioAsyncContext>, chat: Wrapper<UnauthenticatedChatConnection>, hash: Uint8Array): CancellablePromise<Uuid | null>;
716
714
  export function UnauthenticatedChatConnection_send(asyncRuntime: Wrapper<TokioAsyncContext>, chat: Wrapper<UnauthenticatedChatConnection>, httpRequest: Wrapper<HttpRequest>, timeoutMillis: number): CancellablePromise<ChatResponse>;
715
+ export function UnauthenticatedChatConnection_send_multi_recipient_message(asyncRuntime: Wrapper<TokioAsyncContext>, chat: Wrapper<UnauthenticatedChatConnection>, payload: Uint8Array, timestamp: Timestamp, auth: Uint8Array|null, onlineOnly: boolean, isUrgent: boolean): CancellablePromise<Uint8Array[]>;
717
716
  export function UnidentifiedSenderMessageContent_Deserialize(data: Uint8Array): UnidentifiedSenderMessageContent;
718
717
  export function UnidentifiedSenderMessageContent_GetContentHint(m: Wrapper<UnidentifiedSenderMessageContent>): number;
719
718
  export function UnidentifiedSenderMessageContent_GetContents(obj: Wrapper<UnidentifiedSenderMessageContent>): Uint8Array;
@@ -731,7 +730,7 @@ export function Username_Proof(username: string, randomness: Uint8Array): Uint8A
731
730
  export function Username_Verify(proof: Uint8Array, hash: Uint8Array): void;
732
731
  export function UuidCiphertext_CheckValidContents(buffer: Uint8Array): void;
733
732
  export function ValidatingMac_Finalize(mac: Wrapper<ValidatingMac>): number;
734
- export function ValidatingMac_Initialize(key: Uint8Array, chunkSize: number, digests: Uint8Array): ValidatingMac;
733
+ export function ValidatingMac_Initialize(key: Uint8Array, chunkSize: number, digests: Uint8Array): ValidatingMac | null;
735
734
  export function ValidatingMac_Update(mac: Wrapper<ValidatingMac>, bytes: Uint8Array, offset: number, length: number): number;
736
735
  export function WebpSanitizer_Sanitize(input: SyncInputStream): void;
737
736
  export function initLogger(maxLevel: LogLevel, callback: (level: LogLevel, target: string, file: string | null, line: number | null, message: string) => void): void
@@ -754,7 +753,6 @@ interface ExpiringProfileKeyCredentialResponse { readonly __type: unique symbol;
754
753
  interface FakeChatConnection { readonly __type: unique symbol; }
755
754
  interface FakeChatRemoteEnd { readonly __type: unique symbol; }
756
755
  interface FakeChatResponse { readonly __type: unique symbol; }
757
- interface FakeChatSentRequest { readonly __type: unique symbol; }
758
756
  interface FakeChatServer { readonly __type: unique symbol; }
759
757
  interface Fingerprint { readonly __type: unique symbol; }
760
758
  interface GroupMasterKey { readonly __type: unique symbol; }
package/dist/Errors.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ProtocolAddress } from './Address.js';
1
+ import { ProtocolAddress, ServiceId } from './Address.js';
2
2
  import Native from '../Native.js';
3
3
  export declare enum ErrorCode {
4
4
  Generic = 0,
@@ -46,7 +46,33 @@ export declare enum ErrorCode {
46
46
  Cancelled = 42,
47
47
  KeyTransparencyError = 43,
48
48
  KeyTransparencyVerificationFailed = 44,
49
- IncrementalMacVerificationFailed = 45
49
+ IncrementalMacVerificationFailed = 45,
50
+ RequestUnauthorized = 46,
51
+ MismatchedDevices = 47
52
+ }
53
+ /** Called out as a separate type so it's not confused with a normal ServiceIdBinary. */
54
+ type ServiceIdFixedWidthBinary = Uint8Array;
55
+ /**
56
+ * A failure sending to a recipient on account of not being up to date on their devices.
57
+ *
58
+ * An entry in {@link MismatchedDevicesError}. Each entry represents a recipient that has either
59
+ * added, removed, or relinked some devices in their account (potentially including their primary
60
+ * device), as represented by the {@link MismatchedDevicesEntry#missingDevices},
61
+ * {@link MismatchedDevicesEntry#extraDevices}, and {@link MismatchedDevicesEntry#staleDevices}
62
+ * arrays, respectively. Handling the exception involves removing the "extra" devices and
63
+ * establishing new sessions for the "missing" and "stale" devices.
64
+ */
65
+ export declare class MismatchedDevicesEntry {
66
+ account: ServiceId;
67
+ missingDevices: number[];
68
+ extraDevices: number[];
69
+ staleDevices: number[];
70
+ constructor({ account, missingDevices, extraDevices, staleDevices, }: {
71
+ account: ServiceId | ServiceIdFixedWidthBinary;
72
+ missingDevices?: number[];
73
+ extraDevices?: number[];
74
+ staleDevices?: number[];
75
+ });
50
76
  }
51
77
  export declare class LibSignalErrorBase extends Error {
52
78
  readonly code: ErrorCode;
@@ -211,4 +237,12 @@ export type KeyTransparencyVerificationFailed = LibSignalErrorCommon & {
211
237
  export type IncrementalMacVerificationFailed = LibSignalErrorCommon & {
212
238
  code: ErrorCode.IncrementalMacVerificationFailed;
213
239
  };
214
- export type LibSignalError = GenericError | DuplicatedMessageError | SealedSenderSelfSendError | UntrustedIdentityError | InvalidRegistrationIdError | InvalidProtocolAddress | VerificationFailedError | InvalidSessionError | InvalidSenderKeySessionError | NicknameCannotBeEmptyError | CannotStartWithDigitError | MissingSeparatorError | BadNicknameCharacterError | NicknameTooShortError | NicknameTooLongError | DiscriminatorCannotBeEmptyError | DiscriminatorCannotBeZeroError | DiscriminatorCannotBeSingleDigitError | DiscriminatorCannotHaveLeadingZerosError | BadDiscriminatorCharacterError | DiscriminatorTooLargeError | InputDataTooLong | InvalidEntropyDataLength | InvalidUsernameLinkEncryptedData | IoError | CdsiInvalidTokenError | InvalidUriError | InvalidMediaInputError | SvrDataMissingError | SvrRestoreFailedError | SvrRequestFailedError | SvrAttestationError | SvrInvalidDataError | UnsupportedMediaInputError | ChatServiceInactive | AppExpiredError | DeviceDelinkedError | ConnectionInvalidatedError | ConnectedElsewhereError | RateLimitedError | RateLimitChallengeError | BackupValidationError | CancellationError | KeyTransparencyError | KeyTransparencyVerificationFailed | IncrementalMacVerificationFailed;
240
+ export type RequestUnauthorizedError = LibSignalErrorCommon & {
241
+ code: ErrorCode.RequestUnauthorized;
242
+ };
243
+ export type MismatchedDevicesError = LibSignalErrorCommon & {
244
+ code: ErrorCode.MismatchedDevices;
245
+ readonly entries: MismatchedDevicesEntry[];
246
+ };
247
+ export type LibSignalError = GenericError | DuplicatedMessageError | SealedSenderSelfSendError | UntrustedIdentityError | InvalidRegistrationIdError | InvalidProtocolAddress | VerificationFailedError | InvalidSessionError | InvalidSenderKeySessionError | NicknameCannotBeEmptyError | CannotStartWithDigitError | MissingSeparatorError | BadNicknameCharacterError | NicknameTooShortError | NicknameTooLongError | DiscriminatorCannotBeEmptyError | DiscriminatorCannotBeZeroError | DiscriminatorCannotBeSingleDigitError | DiscriminatorCannotHaveLeadingZerosError | BadDiscriminatorCharacterError | DiscriminatorTooLargeError | InputDataTooLong | InvalidEntropyDataLength | InvalidUsernameLinkEncryptedData | IoError | CdsiInvalidTokenError | InvalidUriError | InvalidMediaInputError | SvrDataMissingError | SvrRestoreFailedError | SvrRequestFailedError | SvrAttestationError | SvrInvalidDataError | UnsupportedMediaInputError | ChatServiceInactive | AppExpiredError | DeviceDelinkedError | ConnectionInvalidatedError | ConnectedElsewhereError | RateLimitedError | RateLimitChallengeError | BackupValidationError | CancellationError | KeyTransparencyError | KeyTransparencyVerificationFailed | IncrementalMacVerificationFailed | RequestUnauthorizedError | MismatchedDevicesError;
248
+ export {};
package/dist/Errors.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // Copyright 2021 Signal Messenger, LLC.
3
3
  // SPDX-License-Identifier: AGPL-3.0-only
4
4
  //
5
- import { ProtocolAddress } from './Address.js';
5
+ import { ProtocolAddress, ServiceId } from './Address.js';
6
6
  export var ErrorCode;
7
7
  (function (ErrorCode) {
8
8
  ErrorCode[ErrorCode["Generic"] = 0] = "Generic";
@@ -51,7 +51,30 @@ export var ErrorCode;
51
51
  ErrorCode[ErrorCode["KeyTransparencyError"] = 43] = "KeyTransparencyError";
52
52
  ErrorCode[ErrorCode["KeyTransparencyVerificationFailed"] = 44] = "KeyTransparencyVerificationFailed";
53
53
  ErrorCode[ErrorCode["IncrementalMacVerificationFailed"] = 45] = "IncrementalMacVerificationFailed";
54
+ ErrorCode[ErrorCode["RequestUnauthorized"] = 46] = "RequestUnauthorized";
55
+ ErrorCode[ErrorCode["MismatchedDevices"] = 47] = "MismatchedDevices";
54
56
  })(ErrorCode || (ErrorCode = {}));
57
+ /**
58
+ * A failure sending to a recipient on account of not being up to date on their devices.
59
+ *
60
+ * An entry in {@link MismatchedDevicesError}. Each entry represents a recipient that has either
61
+ * added, removed, or relinked some devices in their account (potentially including their primary
62
+ * device), as represented by the {@link MismatchedDevicesEntry#missingDevices},
63
+ * {@link MismatchedDevicesEntry#extraDevices}, and {@link MismatchedDevicesEntry#staleDevices}
64
+ * arrays, respectively. Handling the exception involves removing the "extra" devices and
65
+ * establishing new sessions for the "missing" and "stale" devices.
66
+ */
67
+ export class MismatchedDevicesEntry {
68
+ constructor({ account, missingDevices, extraDevices, staleDevices, }) {
69
+ this.account =
70
+ account instanceof ServiceId
71
+ ? account
72
+ : ServiceId.parseFromServiceIdFixedWidthBinary(account);
73
+ this.missingDevices = missingDevices ?? [];
74
+ this.extraDevices = extraDevices ?? [];
75
+ this.staleDevices = staleDevices ?? [];
76
+ }
77
+ }
55
78
  export class LibSignalErrorBase extends Error {
56
79
  constructor(message, name, operation, extraProps) {
57
80
  super(message);
@@ -73,7 +73,14 @@ class ValidatingWritable extends stream.Writable {
73
73
  constructor(key, sizeChoice, digest) {
74
74
  super();
75
75
  this._validatedBytes = 0;
76
- this._nativeHandle = Native.ValidatingMac_Initialize(key, chunkSizeInBytes(sizeChoice), digest);
76
+ const handle = Native.ValidatingMac_Initialize(key, chunkSizeInBytes(sizeChoice), digest);
77
+ if (!handle) {
78
+ // Not sure why eslint isn't treating IncrementalMacVerificationFailed as an Error;
79
+ // standalone examples are not reproducing.
80
+ // eslint-disable-next-line @typescript-eslint/only-throw-error
81
+ throw makeVerificationError('Invalid configuration data');
82
+ }
83
+ this._nativeHandle = handle;
77
84
  }
78
85
  validatedSize() {
79
86
  return this._validatedBytes;
@@ -0,0 +1,48 @@
1
+ import { ServiceId } from '../../Address.js';
2
+ import { RequestOptions } from '../Chat.js';
3
+ import { GroupSendFullToken } from '../../zkgroup/index.js';
4
+ declare module '../Chat' {
5
+ interface UnauthenticatedChatConnection extends UnauthMessagesService {
6
+ }
7
+ }
8
+ /** See {@link UnauthMessagesService#sendMultiRecipientMessage}. */
9
+ export type MultiRecipientMessageRequest = Readonly<{
10
+ payload: Uint8Array;
11
+ timestamp: number;
12
+ auth: 'story' | GroupSendFullToken;
13
+ onlineOnly: boolean;
14
+ urgent: boolean;
15
+ }>;
16
+ /**
17
+ * Successful response for {@link UnauthMessagesService#sendMultiRecipientMessage}.
18
+ *
19
+ * When authenticating using a {@link GroupSendFullToken}, the server will report which recipients
20
+ * are currently unregistered. For `story` auth the list will always be empty.
21
+ */
22
+ export declare class MultiRecipientMessageResponse {
23
+ unregisteredIds: ServiceId[];
24
+ constructor(unregisteredIds: ServiceId[]);
25
+ }
26
+ export interface UnauthMessagesService {
27
+ /**
28
+ * Sends a multi-recipient message encrypted with Sealed Sender v2.
29
+ *
30
+ * Messages to accounts that have been unregistered will be dropped by the server and (if using
31
+ * {@link GroupSendFullToken}-based auth) reported in the resulting
32
+ * {@link MultiRecipientMessageResponse}.
33
+ *
34
+ * @throws {RequestUnauthorizedError} if `auth` is not valid for the recipients specified in
35
+ * `payload`. (This cannot happen when `auth` is `'story'`.)
36
+ * @throws {MismatchedDevicesError} if the recipient devices specified in `payload` are out of
37
+ * date in some way. This is not a "partial success" result; the message has not been sent to
38
+ * anybody.
39
+ * @throws {ChatServiceInactive} if the chat connection has been closed.
40
+ * @throws {IoError} if an error occurred while communicating with the server.
41
+ * @throws {RateLimitedError} if the server is rate limiting this client. This is **retryable**
42
+ * after waiting the designated delay.
43
+ *
44
+ * @see `sealedSenderMultiRecipientEncrypt`
45
+ * @see {@link MismatchedDevicesEntry}
46
+ */
47
+ sendMultiRecipientMessage: (request: MultiRecipientMessageRequest, options?: RequestOptions) => Promise<MultiRecipientMessageResponse>;
48
+ }
@@ -0,0 +1,24 @@
1
+ //
2
+ // Copyright 2025 Signal Messenger, LLC.
3
+ // SPDX-License-Identifier: AGPL-3.0-only
4
+ //
5
+ import Native from '../../../Native.js';
6
+ import { ServiceId } from '../../Address.js';
7
+ import { UnauthenticatedChatConnection } from '../Chat.js';
8
+ /**
9
+ * Successful response for {@link UnauthMessagesService#sendMultiRecipientMessage}.
10
+ *
11
+ * When authenticating using a {@link GroupSendFullToken}, the server will report which recipients
12
+ * are currently unregistered. For `story` auth the list will always be empty.
13
+ */
14
+ export class MultiRecipientMessageResponse {
15
+ constructor(unregisteredIds) {
16
+ this.unregisteredIds = unregisteredIds;
17
+ }
18
+ }
19
+ UnauthenticatedChatConnection.prototype.sendMultiRecipientMessage =
20
+ async function ({ payload, timestamp, auth, onlineOnly, urgent, }, options) {
21
+ const response = await this._asyncContext.makeCancellable(options?.abortSignal, Native.UnauthenticatedChatConnection_send_multi_recipient_message(this._asyncContext, this._chatService, payload, timestamp, auth === 'story' ? null : auth.getContents(), onlineOnly, urgent));
22
+ return new MultiRecipientMessageResponse(response.map((raw) => ServiceId.parseFromServiceIdFixedWidthBinary(raw)));
23
+ };
24
+ //# sourceMappingURL=UnauthMessagesService.js.map
package/dist/net.d.ts CHANGED
@@ -6,6 +6,7 @@ import { RegistrationService } from './net/Registration.js';
6
6
  import { SvrB } from './net/SvrB.js';
7
7
  export * from './net/CDSI.js';
8
8
  export * from './net/Chat.js';
9
+ export * from './net/chat/UnauthMessagesService.js';
9
10
  export * from './net/chat/UnauthUsernamesService.js';
10
11
  export * from './net/Registration.js';
11
12
  export * from './net/SvrB.js';
package/dist/net.js CHANGED
@@ -10,6 +10,7 @@ import { SvrB } from './net/SvrB.js';
10
10
  import { BridgedStringMap, newNativeHandle } from './internal.js';
11
11
  export * from './net/CDSI.js';
12
12
  export * from './net/Chat.js';
13
+ export * from './net/chat/UnauthMessagesService.js';
13
14
  export * from './net/chat/UnauthUsernamesService.js';
14
15
  export * from './net/Registration.js';
15
16
  export * from './net/SvrB.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signalapp/libsignal-client",
3
- "version": "0.84.0",
3
+ "version": "0.85.0",
4
4
  "license": "AGPL-3.0-only",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",