@signalapp/libsignal-client 0.78.1 → 0.78.3

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
@@ -282,8 +282,6 @@ export function CreateCallLinkCredentialRequest_IssueDeterministic(requestBytes:
282
282
  export function CreateCallLinkCredentialResponse_CheckValidContents(responseBytes: Uint8Array): void;
283
283
  export function CreateCallLinkCredential_CheckValidContents(paramsBytes: Uint8Array): void;
284
284
  export function CreateCallLinkCredential_PresentDeterministic(credentialBytes: Uint8Array, roomId: Uint8Array, userId: Uint8Array, serverParamsBytes: Uint8Array, callLinkParamsBytes: Uint8Array, randomness: Uint8Array): Uint8Array;
285
- export function CreateOTP(username: string, secret: Uint8Array): string;
286
- export function CreateOTPFromBase64(username: string, secret: string): string;
287
285
  export function DecryptionErrorMessage_Deserialize(data: Uint8Array): DecryptionErrorMessage;
288
286
  export function DecryptionErrorMessage_ExtractFromSerializedContent(bytes: Uint8Array): DecryptionErrorMessage;
289
287
  export function DecryptionErrorMessage_ForOriginalMessage(originalBytes: Uint8Array, originalType: number, originalTimestamp: Timestamp, originalSenderDeviceId: number): DecryptionErrorMessage;
@@ -353,7 +351,7 @@ export function IncrementalMac_Update(mac: Wrapper<IncrementalMac>, bytes: Uint8
353
351
  export function KeyTransparency_AciSearchKey(aci: Uint8Array): Uint8Array;
354
352
  export function KeyTransparency_Distinguished(asyncRuntime: Wrapper<TokioAsyncContext>, environment: number, chatConnection: Wrapper<UnauthenticatedChatConnection>, lastDistinguishedTreeHead: Uint8Array | null): CancellablePromise<Uint8Array>;
355
353
  export function KeyTransparency_E164SearchKey(e164: string): Uint8Array;
356
- export function KeyTransparency_Monitor(asyncRuntime: Wrapper<TokioAsyncContext>, environment: number, chatConnection: Wrapper<UnauthenticatedChatConnection>, aci: Uint8Array, aciIdentityKey: Wrapper<PublicKey>, e164: string | null, unidentifiedAccessKey: Uint8Array | null, usernameHash: Uint8Array | null, accountData: Uint8Array | null, lastDistinguishedTreeHead: Uint8Array): CancellablePromise<Uint8Array>;
354
+ export function KeyTransparency_Monitor(asyncRuntime: Wrapper<TokioAsyncContext>, environment: number, chatConnection: Wrapper<UnauthenticatedChatConnection>, aci: Uint8Array, aciIdentityKey: Wrapper<PublicKey>, e164: string | null, unidentifiedAccessKey: Uint8Array | null, usernameHash: Uint8Array | null, accountData: Uint8Array | null, lastDistinguishedTreeHead: Uint8Array, isSelfMonitor: boolean): CancellablePromise<Uint8Array>;
357
355
  export function KeyTransparency_Search(asyncRuntime: Wrapper<TokioAsyncContext>, environment: number, chatConnection: Wrapper<UnauthenticatedChatConnection>, aci: Uint8Array, aciIdentityKey: Wrapper<PublicKey>, e164: string | null, unidentifiedAccessKey: Uint8Array | null, usernameHash: Uint8Array | null, accountData: Uint8Array | null, lastDistinguishedTreeHead: Uint8Array): CancellablePromise<Uint8Array>;
358
356
  export function KeyTransparency_UsernameHashSearchKey(hash: Uint8Array): Uint8Array;
359
357
  export function KyberKeyPair_Generate(): KyberKeyPair;
@@ -504,6 +502,7 @@ export function SealedSender_Encrypt(destination: Wrapper<ProtocolAddress>, cont
504
502
  export function SealedSender_MultiRecipientEncrypt(recipients: Wrapper<ProtocolAddress>[], recipientSessions: Wrapper<SessionRecord>[], excludedRecipients: Uint8Array, content: Wrapper<UnidentifiedSenderMessageContent>, identityKeyStore: IdentityKeyStore): Promise<Uint8Array>;
505
503
  export function SealedSender_MultiRecipientMessageForSingleRecipient(encodedMultiRecipientMessage: Uint8Array): Uint8Array;
506
504
  export function SecureValueRecoveryForBackups_CreateNewBackupChain(environment: number, backupKey: Uint8Array): Uint8Array;
505
+ export function SecureValueRecoveryForBackups_RemoveBackup(asyncRuntime: Wrapper<TokioAsyncContext>, connectionManager: Wrapper<ConnectionManager>, username: string, password: string): CancellablePromise<void>;
507
506
  export function SecureValueRecoveryForBackups_RestoreBackupFromServer(asyncRuntime: Wrapper<TokioAsyncContext>, backupKey: Uint8Array, metadata: Uint8Array, connectionManager: Wrapper<ConnectionManager>, username: string, password: string): CancellablePromise<BackupRestoreResponse>;
508
507
  export function SecureValueRecoveryForBackups_StoreBackup(asyncRuntime: Wrapper<TokioAsyncContext>, backupKey: Uint8Array, previousSecretData: Uint8Array, connectionManager: Wrapper<ConnectionManager>, username: string, password: string): CancellablePromise<BackupStoreResponse>;
509
508
  export function SenderCertificate_Deserialize(data: Uint8Array): SenderCertificate;
@@ -619,6 +618,8 @@ export function TESTING_ChatSendErrorConvert(errorDescription: string): void;
619
618
  export function TESTING_ConnectionManager_isUsingProxy(manager: Wrapper<ConnectionManager>): number;
620
619
  export function TESTING_ConnectionManager_newLocalOverride(userAgent: string, chatPort: number, cdsiPort: number, svr2Port: number, svrBPort: number, rootCertificateDer: Uint8Array): ConnectionManager;
621
620
  export function TESTING_ConvertOptionalUuid(present: boolean): Uuid | null;
621
+ export function TESTING_CreateOTP(username: string, secret: Uint8Array): string;
622
+ export function TESTING_CreateOTPFromBase64(username: string, secret: string): string;
622
623
  export function TESTING_ErrorOnBorrowAsync(_input: null): Promise<void>;
623
624
  export function TESTING_ErrorOnBorrowIo(asyncRuntime: Wrapper<NonSuspendingBackgroundThreadRuntime>, _input: null): CancellablePromise<void>;
624
625
  export function TESTING_ErrorOnBorrowSync(_input: null): void;
@@ -686,6 +687,8 @@ export function TESTING_RoundTripU8(input: number): number;
686
687
  export function TESTING_ServerMessageAck_Create(): ServerMessageAck;
687
688
  export function TESTING_SignedPublicPreKey_CheckBridgesCorrectly(sourcePublicKey: Wrapper<PublicKey>, signedPreKey: SignedPublicPreKey): void;
688
689
  export function TESTING_TestingHandleType_getValue(handle: Wrapper<TestingHandleType>): number;
690
+ export function TESTING_TokioAsyncContext_FutureSuccessBytes(asyncRuntime: Wrapper<TokioAsyncContext>, count: number): CancellablePromise<Uint8Array>;
691
+ export function TESTING_TokioAsyncContext_NewSingleThreaded(): TokioAsyncContext;
689
692
  export function TESTING_TokioAsyncFuture(asyncRuntime: Wrapper<TokioAsyncContext>, input: number): CancellablePromise<number>;
690
693
  export function TestingSemaphore_AddPermits(semaphore: Wrapper<TestingSemaphore>, permits: number): void;
691
694
  export function TestingSemaphore_New(initial: number): TestingSemaphore;
package/dist/Errors.d.ts CHANGED
@@ -35,8 +35,8 @@ export declare enum ErrorCode {
35
35
  SvrDataMissing = 31,
36
36
  SvrRequestFailed = 32,
37
37
  SvrRestoreFailed = 33,
38
- SvrMultipleErrors = 34,
39
- SvrAttestationError = 35,
38
+ SvrAttestationError = 34,
39
+ SvrInvalidData = 35,
40
40
  ChatServiceInactive = 36,
41
41
  AppExpired = 37,
42
42
  DeviceDelinked = 38,
@@ -188,12 +188,12 @@ export type SvrRestoreFailedError = LibSignalErrorCommon & {
188
188
  code: ErrorCode.SvrRestoreFailed;
189
189
  readonly triesRemaining: number;
190
190
  };
191
- export type SvrMultipleErrorsError = LibSignalErrorCommon & {
192
- code: ErrorCode.SvrMultipleErrors;
193
- };
194
191
  export type SvrAttestationError = LibSignalErrorCommon & {
195
192
  code: ErrorCode.SvrAttestationError;
196
193
  };
194
+ export type SvrInvalidDataError = LibSignalErrorCommon & {
195
+ code: ErrorCode.SvrInvalidData;
196
+ };
197
197
  export type BackupValidationError = LibSignalErrorCommon & {
198
198
  code: ErrorCode.BackupValidation;
199
199
  readonly unknownFields: ReadonlyArray<string>;
@@ -207,4 +207,4 @@ export type KeyTransparencyError = LibSignalErrorCommon & {
207
207
  export type KeyTransparencyVerificationFailed = LibSignalErrorCommon & {
208
208
  code: ErrorCode.KeyTransparencyVerificationFailed;
209
209
  };
210
- 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 | SvrMultipleErrorsError | SvrAttestationError | UnsupportedMediaInputError | ChatServiceInactive | AppExpiredError | DeviceDelinkedError | ConnectionInvalidatedError | ConnectedElsewhereError | RateLimitedError | RateLimitChallengeError | BackupValidationError | CancellationError | KeyTransparencyError | KeyTransparencyVerificationFailed;
210
+ 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;
package/dist/Errors.js CHANGED
@@ -42,8 +42,8 @@ var ErrorCode;
42
42
  ErrorCode[ErrorCode["SvrDataMissing"] = 31] = "SvrDataMissing";
43
43
  ErrorCode[ErrorCode["SvrRequestFailed"] = 32] = "SvrRequestFailed";
44
44
  ErrorCode[ErrorCode["SvrRestoreFailed"] = 33] = "SvrRestoreFailed";
45
- ErrorCode[ErrorCode["SvrMultipleErrors"] = 34] = "SvrMultipleErrors";
46
- ErrorCode[ErrorCode["SvrAttestationError"] = 35] = "SvrAttestationError";
45
+ ErrorCode[ErrorCode["SvrAttestationError"] = 34] = "SvrAttestationError";
46
+ ErrorCode[ErrorCode["SvrInvalidData"] = 35] = "SvrInvalidData";
47
47
  ErrorCode[ErrorCode["ChatServiceInactive"] = 36] = "ChatServiceInactive";
48
48
  ErrorCode[ErrorCode["AppExpired"] = 37] = "AppExpired";
49
49
  ErrorCode[ErrorCode["DeviceDelinked"] = 38] = "DeviceDelinked";
@@ -41,12 +41,30 @@ export type E164Info = {
41
41
  *
42
42
  */
43
43
  export type Request = {
44
- /** ACI and ACI Identity Key for the account. Required. */
44
+ /** ACI information for the request. Required. */
45
45
  aciInfo: AciInfo;
46
46
  /** Unidentified access key associated with the account. Optional. */
47
47
  e164Info?: E164Info;
48
48
  usernameHash?: Readonly<Uint8Array>;
49
49
  };
50
+ /**
51
+ * Mode of the monitor operation.
52
+ *
53
+ * If the newer version of account data is found in the key transparency
54
+ * log, self-monitor will terminate with an error, but monitor for other
55
+ * account will fall back to a full search and update the locally stored
56
+ * data.
57
+ */
58
+ export declare enum MonitorMode {
59
+ Self = 0,
60
+ Other = 1
61
+ }
62
+ /**
63
+ * An extension of the {@link Request} for the monitor operation.
64
+ */
65
+ export type MonitorRequest = Request & {
66
+ mode: MonitorMode;
67
+ };
50
68
  /**
51
69
  * Typed API to access the key transparency subsystem using an existing
52
70
  * unauthenticated chat connection.
@@ -104,7 +122,7 @@ export interface Client {
104
122
  * verify the data in key transparency server response, such as an incorrect proof or a
105
123
  * wrong signature.
106
124
  * @throws {ChatServiceInactive} if the chat connection has been closed.
107
- * @throws {IoError} if an error occurred while commuicating with the
125
+ * @throws {IoError} if an error occurred while communicating with the
108
126
  * server.
109
127
  * */
110
128
  search(request: Request, store: Store, options?: Readonly<Options>): Promise<void>;
@@ -131,12 +149,14 @@ export interface Client {
131
149
  * different result.
132
150
  * @throws {KeyTransparencyVerificationFailed} when it fails to
133
151
  * verify the data in key transparency server response, such as an incorrect proof or a
134
- * wrong signature.
152
+ * wrong signature. This is also the error thrown when new version
153
+ * of account data is found in the key transparency log when
154
+ * self-monitoring. See {@link MonitorMode}.
135
155
  * @throws {ChatServiceInactive} if the chat connection has been closed.
136
- * @throws {IoError} if an error occurred while commuicating with the
156
+ * @throws {IoError} if an error occurred while communicating with the
137
157
  * server.
138
158
  */
139
- monitor(request: Request, store: Store, options?: Readonly<Options>): Promise<void>;
159
+ monitor(request: MonitorRequest, store: Store, options?: Readonly<Options>): Promise<void>;
140
160
  }
141
161
  export declare class ClientImpl implements Client {
142
162
  private readonly asyncContext;
@@ -144,7 +164,7 @@ export declare class ClientImpl implements Client {
144
164
  private readonly env;
145
165
  constructor(asyncContext: TokioAsyncContext, chatService: Native.Wrapper<Native.UnauthenticatedChatConnection>, env: Environment);
146
166
  search(request: Request, store: Store, options?: Readonly<Options>): Promise<void>;
147
- monitor(request: Request, store: Store, options?: Readonly<Options>): Promise<void>;
167
+ monitor(request: MonitorRequest, store: Store, options?: Readonly<Options>): Promise<void>;
148
168
  private updateDistinguished;
149
169
  private getLatestDistinguished;
150
170
  }
@@ -4,8 +4,21 @@
4
4
  // SPDX-License-Identifier: AGPL-3.0-only
5
5
  //
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.ClientImpl = void 0;
7
+ exports.ClientImpl = exports.MonitorMode = void 0;
8
8
  const Native = require("../../Native");
9
+ /**
10
+ * Mode of the monitor operation.
11
+ *
12
+ * If the newer version of account data is found in the key transparency
13
+ * log, self-monitor will terminate with an error, but monitor for other
14
+ * account will fall back to a full search and update the locally stored
15
+ * data.
16
+ */
17
+ var MonitorMode;
18
+ (function (MonitorMode) {
19
+ MonitorMode[MonitorMode["Self"] = 0] = "Self";
20
+ MonitorMode[MonitorMode["Other"] = 1] = "Other";
21
+ })(MonitorMode || (exports.MonitorMode = MonitorMode = {}));
9
22
  class ClientImpl {
10
23
  constructor(asyncContext, chatService, env) {
11
24
  this.asyncContext = asyncContext;
@@ -26,12 +39,12 @@ class ClientImpl {
26
39
  async monitor(request, store, options) {
27
40
  const distinguished = await this.getLatestDistinguished(store, options ?? {});
28
41
  const { abortSignal } = options ?? {};
29
- const { aciInfo: { aci, identityKey: aciIdentityKey }, e164Info, usernameHash, } = request;
42
+ const { aciInfo: { aci, identityKey: aciIdentityKey }, e164Info, usernameHash, mode, } = request;
30
43
  const { e164, unidentifiedAccessKey } = e164Info ?? {
31
44
  e164: null,
32
45
  unidentifiedAccessKey: null,
33
46
  };
34
- const accountData = await this.asyncContext.makeCancellable(abortSignal, Native.KeyTransparency_Monitor(this.asyncContext, this.env, this.chatService, aci.getServiceIdFixedWidthBinary(), aciIdentityKey, e164, unidentifiedAccessKey, usernameHash ?? null, await store.getAccountData(aci), distinguished));
47
+ const accountData = await this.asyncContext.makeCancellable(abortSignal, Native.KeyTransparency_Monitor(this.asyncContext, this.env, this.chatService, aci.getServiceIdFixedWidthBinary(), aciIdentityKey, e164, unidentifiedAccessKey, usernameHash ?? null, await store.getAccountData(aci), distinguished, mode === MonitorMode.Self));
35
48
  await store.setAccountData(aci, accountData);
36
49
  }
37
50
  async updateDistinguished(store, { abortSignal }) {
@@ -96,10 +96,13 @@ export type RestoreBackupResponse = {
96
96
  * ## Secret handling
97
97
  *
98
98
  * When calling {@link SvrB#store}, the `previousSecretData` parameter must be from the last call to
99
- * {@link SvrB#store} or {@link SvrB#restore} that succeeded. The returned secret from a successful
100
- * store or restore should be persisted until it is overwritten by the value from a subsequent
101
- * successful call. The caller should use {@link SvrB#createNewBackupChain} only for the very first
102
- * backup with a particular backup key.
99
+ * {@link SvrB#store} or {@link SvrB#restore} that succeeded. This "chaining" is used to construct
100
+ * each backup file so that it can be decrypted with either the *previous* token stored in SVR-B, or
101
+ * the *next* one, which is important in case the overall backup upload is ever interrupted.
102
+ *
103
+ * The returned secret from a successful store or restore should be persisted until it is
104
+ * overwritten by the value from a subsequent successful call. The caller should use
105
+ * {@link SvrB#createNewBackupChain} only for the very first backup with a particular backup key.
103
106
  *
104
107
  * ## Restore Flow
105
108
  *
@@ -159,7 +162,15 @@ export declare class SvrB {
159
162
  * @param options.abortSignal An AbortSignal that will cancel the request.
160
163
  * @returns a {@link StoreBackupResponse} containing the forward secrecy token, metadata, and
161
164
  * secret data.
162
- * @throws Error if the previous secret data is malformed, or if processing or upload fail.
165
+ * @throws {SvrInvalidDataError} if the previous secret data is malformed. There's no choice here
166
+ * but to **start a new chain**.
167
+ * @throws {RateLimitedError} if the server is rate limiting this client. This is **retryable**
168
+ * after waiting the designated delay.
169
+ * @throws {IoError} if the network operation fails (connection, service, or timeout errors).
170
+ * These can be **automatically retried** (backoff recommended), but some may indicate a possible
171
+ * bug in libsignal or in the enclave.
172
+ * @throws {SvrAttestationError} if enclave attestation fails. This indicates a possible bug in
173
+ * libsignal or in the enclave.
163
174
  */
164
175
  store(backupKey: BackupKey, previousSecretData: Uint8Array, options?: {
165
176
  abortSignal?: AbortSignal;
@@ -168,8 +179,8 @@ export declare class SvrB {
168
179
  * Fetches the forward secrecy token needed to decrypt a backup.
169
180
  *
170
181
  * This function makes a network call to the SVR-B server to retrieve the forward secrecy token
171
- * associated with a specific backup. The token is required to derive the message backup keys
172
- * for decryption.
182
+ * associated with a specific backup. The token is required to derive the message backup keys for
183
+ * decryption.
173
184
  *
174
185
  * The typical restore flow:
175
186
  * 1. Fetch the backup metadata (stored in a header in the backup file)
@@ -179,15 +190,51 @@ export declare class SvrB {
179
190
  * 5. Store the returned {@link RestoreBackupResponse#nextBackupSecretData} locally.
180
191
  *
181
192
  * @param backupKey The backup key derived from the Account Entropy Pool (AEP).
182
- * @param metadata The metadata that was stored in a header in the backup file during backup creation.
193
+ * @param metadata The metadata that was stored in a header in the backup file during backup
194
+ * creation.
183
195
  * @param options Optional configuration.
184
196
  * @param options.abortSignal An AbortSignal that will cancel the request.
185
197
  * @returns The forward secrecy token needed to derive keys for decrypting the backup.
186
- * @throws Error if the metadata is invalid, the network operation fails, or the
187
- * backup cannot be found.
198
+ * @throws {SvrInvalidDataError} if the previous secret data is malformed. In this case the user's
199
+ * data is **not recoverable**.
200
+ * @throws {SvrRestoreFailedError} if restoration fails (with remaining tries count). This should
201
+ * never happen but if it does the user's data is **not recoverable**.
202
+ * @throws {SvrDataMissingError} if the backup data is not found on the server, indicating an
203
+ * **incorrect backup key** (which may in turn imply the user's data is not recoverable).
204
+ * @throws {RateLimitedError} if the server is rate limiting this client. This is **retryable**
205
+ * after waiting the designated delay.
206
+ * @throws {IoError} if the network operation fails (connection, service, or timeout errors).
207
+ * These can be **automatically retried** (backoff recommended), but some may indicate a possible
208
+ * bug in libsignal or in the enclave.
209
+ * @throws {SvrAttestationError} if enclave attestation fails. This indicates a possible bug in
210
+ * libsignal or in the enclave.
188
211
  */
189
212
  restore(backupKey: BackupKey, metadata: Uint8Array, options?: {
190
213
  abortSignal?: AbortSignal;
191
214
  }): Promise<RestoreBackupResponse>;
215
+ /**
216
+ * Attempts to remove the info stored with SVR-B for this particular username/password pair.
217
+ *
218
+ * This is a best-effort operation; a successful return means the data has been removed from (or
219
+ * never was present in) the current SVR-B enclaves, but may still be present in previous ones
220
+ * that have yet to be decommissioned. Conversely, a thrown error may still have removed
221
+ * information from previous enclaves.
222
+ *
223
+ * This should not typically be needed; rather than explicitly removing an entry, the client
224
+ * should generally overwrite with a new {@link #store} instead.
225
+ *
226
+ * @param options Optional configuration.
227
+ * @param options.abortSignal An AbortSignal that will cancel the request.
228
+ * @throws {RateLimitedError} if the server is rate limiting this client. This is **retryable**
229
+ * after waiting the designated delay.
230
+ * @throws {IoError} if the network operation fails (connection, service, or timeout errors).
231
+ * These can be **automatically retried** (backoff recommended), but some may indicate a possible
232
+ * bug in libsignal or in the enclave.
233
+ * @throws {SvrAttestationError} if enclave attestation fails. This indicates a possible bug in
234
+ * libsignal or in the enclave.
235
+ */
236
+ remove(options?: {
237
+ abortSignal?: AbortSignal;
238
+ }): Promise<void>;
192
239
  }
193
240
  export {};
package/dist/net/SvrB.js CHANGED
@@ -67,10 +67,13 @@ class RestoreBackupResponseImpl {
67
67
  * ## Secret handling
68
68
  *
69
69
  * When calling {@link SvrB#store}, the `previousSecretData` parameter must be from the last call to
70
- * {@link SvrB#store} or {@link SvrB#restore} that succeeded. The returned secret from a successful
71
- * store or restore should be persisted until it is overwritten by the value from a subsequent
72
- * successful call. The caller should use {@link SvrB#createNewBackupChain} only for the very first
73
- * backup with a particular backup key.
70
+ * {@link SvrB#store} or {@link SvrB#restore} that succeeded. This "chaining" is used to construct
71
+ * each backup file so that it can be decrypted with either the *previous* token stored in SVR-B, or
72
+ * the *next* one, which is important in case the overall backup upload is ever interrupted.
73
+ *
74
+ * The returned secret from a successful store or restore should be persisted until it is
75
+ * overwritten by the value from a subsequent successful call. The caller should use
76
+ * {@link SvrB#createNewBackupChain} only for the very first backup with a particular backup key.
74
77
  *
75
78
  * ## Restore Flow
76
79
  *
@@ -130,7 +133,15 @@ class SvrB {
130
133
  * @param options.abortSignal An AbortSignal that will cancel the request.
131
134
  * @returns a {@link StoreBackupResponse} containing the forward secrecy token, metadata, and
132
135
  * secret data.
133
- * @throws Error if the previous secret data is malformed, or if processing or upload fail.
136
+ * @throws {SvrInvalidDataError} if the previous secret data is malformed. There's no choice here
137
+ * but to **start a new chain**.
138
+ * @throws {RateLimitedError} if the server is rate limiting this client. This is **retryable**
139
+ * after waiting the designated delay.
140
+ * @throws {IoError} if the network operation fails (connection, service, or timeout errors).
141
+ * These can be **automatically retried** (backoff recommended), but some may indicate a possible
142
+ * bug in libsignal or in the enclave.
143
+ * @throws {SvrAttestationError} if enclave attestation fails. This indicates a possible bug in
144
+ * libsignal or in the enclave.
134
145
  */
135
146
  async store(backupKey, previousSecretData, options) {
136
147
  const promise = Native.SecureValueRecoveryForBackups_StoreBackup(this.asyncContext, backupKey.serialize(), previousSecretData, this.connectionManager, this.auth.username, this.auth.password);
@@ -141,8 +152,8 @@ class SvrB {
141
152
  * Fetches the forward secrecy token needed to decrypt a backup.
142
153
  *
143
154
  * This function makes a network call to the SVR-B server to retrieve the forward secrecy token
144
- * associated with a specific backup. The token is required to derive the message backup keys
145
- * for decryption.
155
+ * associated with a specific backup. The token is required to derive the message backup keys for
156
+ * decryption.
146
157
  *
147
158
  * The typical restore flow:
148
159
  * 1. Fetch the backup metadata (stored in a header in the backup file)
@@ -152,18 +163,55 @@ class SvrB {
152
163
  * 5. Store the returned {@link RestoreBackupResponse#nextBackupSecretData} locally.
153
164
  *
154
165
  * @param backupKey The backup key derived from the Account Entropy Pool (AEP).
155
- * @param metadata The metadata that was stored in a header in the backup file during backup creation.
166
+ * @param metadata The metadata that was stored in a header in the backup file during backup
167
+ * creation.
156
168
  * @param options Optional configuration.
157
169
  * @param options.abortSignal An AbortSignal that will cancel the request.
158
170
  * @returns The forward secrecy token needed to derive keys for decrypting the backup.
159
- * @throws Error if the metadata is invalid, the network operation fails, or the
160
- * backup cannot be found.
171
+ * @throws {SvrInvalidDataError} if the previous secret data is malformed. In this case the user's
172
+ * data is **not recoverable**.
173
+ * @throws {SvrRestoreFailedError} if restoration fails (with remaining tries count). This should
174
+ * never happen but if it does the user's data is **not recoverable**.
175
+ * @throws {SvrDataMissingError} if the backup data is not found on the server, indicating an
176
+ * **incorrect backup key** (which may in turn imply the user's data is not recoverable).
177
+ * @throws {RateLimitedError} if the server is rate limiting this client. This is **retryable**
178
+ * after waiting the designated delay.
179
+ * @throws {IoError} if the network operation fails (connection, service, or timeout errors).
180
+ * These can be **automatically retried** (backoff recommended), but some may indicate a possible
181
+ * bug in libsignal or in the enclave.
182
+ * @throws {SvrAttestationError} if enclave attestation fails. This indicates a possible bug in
183
+ * libsignal or in the enclave.
161
184
  */
162
185
  async restore(backupKey, metadata, options) {
163
186
  const promise = Native.SecureValueRecoveryForBackups_RestoreBackupFromServer(this.asyncContext, backupKey.serialize(), metadata, this.connectionManager, this.auth.username, this.auth.password);
164
187
  const response = await this.asyncContext.makeCancellable(options?.abortSignal, promise);
165
188
  return new RestoreBackupResponseImpl(response);
166
189
  }
190
+ /**
191
+ * Attempts to remove the info stored with SVR-B for this particular username/password pair.
192
+ *
193
+ * This is a best-effort operation; a successful return means the data has been removed from (or
194
+ * never was present in) the current SVR-B enclaves, but may still be present in previous ones
195
+ * that have yet to be decommissioned. Conversely, a thrown error may still have removed
196
+ * information from previous enclaves.
197
+ *
198
+ * This should not typically be needed; rather than explicitly removing an entry, the client
199
+ * should generally overwrite with a new {@link #store} instead.
200
+ *
201
+ * @param options Optional configuration.
202
+ * @param options.abortSignal An AbortSignal that will cancel the request.
203
+ * @throws {RateLimitedError} if the server is rate limiting this client. This is **retryable**
204
+ * after waiting the designated delay.
205
+ * @throws {IoError} if the network operation fails (connection, service, or timeout errors).
206
+ * These can be **automatically retried** (backoff recommended), but some may indicate a possible
207
+ * bug in libsignal or in the enclave.
208
+ * @throws {SvrAttestationError} if enclave attestation fails. This indicates a possible bug in
209
+ * libsignal or in the enclave.
210
+ */
211
+ async remove(options) {
212
+ const promise = Native.SecureValueRecoveryForBackups_RemoveBackup(this.asyncContext, this.connectionManager, this.auth.username, this.auth.password);
213
+ await this.asyncContext.makeCancellable(options?.abortSignal, promise);
214
+ }
167
215
  }
168
216
  exports.SvrB = SvrB;
169
217
  //# sourceMappingURL=SvrB.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signalapp/libsignal-client",
3
- "version": "0.78.1",
3
+ "version": "0.78.3",
4
4
  "license": "AGPL-3.0-only",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",