/** * Message backup validation routines. * * @module MessageBackup */ import * as Native from './Native.js'; import { BackupForwardSecrecyToken, BackupKey } from './AccountKeys.js'; import { Aci } from './Address.js'; import { InputStream } from './io.js'; export type InputStreamFactory = () => InputStream; /** * Result of validating a message backup bundle. */ export declare class ValidationOutcome { /** * A developer-facing message about the error encountered during validation, * if any. */ errorMessage: string | null; /** * Information about unknown fields encountered during validation. */ unknownFieldMessages: string[]; /** * `true` if the backup is valid, `false` otherwise. * * If this is `true`, there might still be messages about unknown fields. */ get ok(): boolean; constructor(outcome: Native.MessageBackupValidationOutcome); } export type MessageBackupKeyInput = Readonly<{ accountEntropy: string; aci: Aci; forwardSecrecyToken?: BackupForwardSecrecyToken; } | { backupKey: BackupKey | Uint8Array; backupId: Uint8Array; forwardSecrecyToken?: BackupForwardSecrecyToken; }>; /** * Key used to encrypt and decrypt a message backup bundle. * * @see {@link BackupKey} */ export declare class MessageBackupKey { readonly _nativeHandle: Native.MessageBackupKey; /** * Create a backup bundle key from an account entropy pool and ACI. * * ...or from a backup key and ID, used when reading from a local backup, which may have been * created with a different ACI. * * The account entropy pool must be **validated**; passing an arbitrary string here is considered * a programmer error. Similarly, passing a backup key or ID of the wrong length is also an error. */ constructor(input: MessageBackupKeyInput); /** An HMAC key used to sign a backup file. */ get hmacKey(): Uint8Array; /** An AES-256-CBC key used to encrypt a backup file. */ get aesKey(): Uint8Array; } export declare enum Purpose { DeviceTransfer = 0, RemoteBackup = 1, TakeoutExport = 2 } /** * Validate a backup file * * @param backupKey The key to use to decrypt the backup contents. * @param purpose Whether the backup is intended for device-to-device transfer or remote storage. * @param inputFactory A function that returns new input streams that read the backup contents. * @param length The exact length of the input stream. * @returns The outcome of validation, including any errors and warnings. * @throws IoError If an IO error on the input occurs. * * @see OnlineBackupValidator */ export declare function validate(backupKey: MessageBackupKey, purpose: Purpose, inputFactory: InputStreamFactory, length: bigint): Promise; /** * An alternative to {@link validate()} that validates a backup frame-by-frame. * * This is much faster than using `validate()` because it bypasses the decryption and decompression * steps, but that also means it's validating less. Don't forget to call `finalize()`! * * Unlike `validate()`, unknown fields are treated as "soft" errors and logged, rather than * collected and returned to the app for processing. * * # Example * * ``` * const validator = new OnlineBackupValidator( * backupInfoProto.serialize(), * Purpose.deviceTransfer) * repeat { * // ...generate Frames... * validator.addFrame(frameProto.serialize()) * } * validator.finalize() // don't forget this! * ``` */ export declare class OnlineBackupValidator { readonly _nativeHandle: Native.OnlineBackupValidator; /** * Initializes an OnlineBackupValidator from the given BackupInfo protobuf message. * * "Soft" errors will be logged, including unrecognized fields in the protobuf. * * @throws BackupValidationError on error */ constructor(backupInfo: Uint8Array, purpose: Purpose); /** * Processes a single Frame protobuf message. * * "Soft" errors will be logged, including unrecognized fields in the protobuf. * * @throws BackupValidationError on error */ addFrame(frame: Uint8Array): void; /** * Marks that a backup is complete, and does any final checks that require whole-file knowledge. * * "Soft" errors will be logged. * * @throws BackupValidationError on error */ finalize(): void; } /** * An in-memory representation of a backup file used to compare contents. * * When comparing the contents of two backups: * 1. Create a `ComparableBackup` instance for each of the inputs. * 2. Check the `unknownFields()` value; if it's not empty, some parts of the * backup weren't parsed and won't be compared. * 3. Produce a canonical string for each backup with `comparableString()`. * 4. Compare the canonical string representations. * * The diff of the canonical strings (which may be rather large) will show the * differences between the logical content of the input backup files. */ export declare class ComparableBackup { readonly _nativeHandle: Native.ComparableBackup; constructor(handle: Native.ComparableBackup); /** * Read an unencrypted backup file into memory for comparison. * * @param purpose Whether the backup is intended for device-to-device transfer or remote storage. * @param input An input stream that reads the backup contents. * @param length The exact length of the input stream. * @returns The in-memory representation. * @throws BackupValidationError If an IO error occurs or the input is invalid. */ static fromUnencrypted(purpose: Purpose, input: InputStream, length: bigint): Promise; /** * Produces a string representation of the contents. * * The returned strings for two backups will be equal if the backups contain * the same logical content. If two backups' strings are not equal, the diff * will show what is different between them. * * @returns a canonical string representation of the backup */ comparableString(): string; /** * Unrecognized protobuf fields present in the backup. * * If this is not empty, some parts of the backup were not recognized and * won't be present in the string representation. */ get unknownFields(): Array; } /** * The output from processing a single frame for JSON export. * * There are four possibilities: * - `line` present, `errorMessage` absent - the common case, a frame converted (and possibly sanitized) * with no problems. * - `line` present, `errorMessage` present - the frame has been converted, but would have failed * validation. * - `line` absent, `errorMessage` absent - the frame has been filtered out wholesale. * - `line` absent, `errorMessage` present - the frame has been filtered out wholesale, but would have * failed validation had it not been filtered out. */ export type BackupJsonFrameResult = { line?: string; errorMessage?: string; }; export type BackupJsonFinishResult = { errorMessage?: string; }; /** * Streaming exporter that produces a human-readable JSON representation of a backup. * * Validation feedback returned by this exporter is best-effort and intended for logging or * diagnostics. Even when a frame reports a validation error, the serialized line is still * produced so consumers can continue streaming the export. */ export declare class BackupJsonExporter { readonly _nativeHandle: Native.BackupJsonExporter; private constructor(); /** * Initializes the streaming exporter and returns the first set of output lines. * @param backupInfo The serialized BackupInfo protobuf without a varint header. * @param [options] Additional configuration for the exporter. * @param [options.validate=true] Whether to run semantic validation on the backup. * @returns An object containing the exporter and the first chunk of output, containing the backup info. * @throws Error if the input is invalid. */ static start(backupInfo: Uint8Array, options?: { validate?: boolean; }): { exporter: BackupJsonExporter; chunk: string; }; /** * Validates and exports a human-readable JSON representation of backup frames. * @param frames One or more varint delimited Frame serialized protobuf messages. * @returns An array containing the line and any validation error for each frame. * Frames that report validation errors still include their serialized `line`, so consumers * should continue processing the export and surface the errors for observability rather than * aborting. * @throws Error if the input data cannot be parsed. */ exportFrames(frames: Uint8Array): BackupJsonFrameResult[]; /** * Completes the validation and export of the previously exported frames. * * Per-frame validation errors are reported via `exportFrames`, so callers * should inspect earlier results even if this returns with no error. * @returns The outcome of the final validation stage. */ finish(): BackupJsonFinishResult; }