UNPKG

matrix-react-sdk

Version:
160 lines (159 loc) 6.8 kB
import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix"; import { Error as ErrorEvent } from "@matrix-org/analytics-events/types/typescript/Error"; import { DecryptionFailureCode } from "matrix-js-sdk/src/crypto-api"; export declare class DecryptionFailure { readonly failedEventId: string; readonly errorCode: DecryptionFailureCode; /** * The time that we failed to decrypt the event. If we failed to decrypt * multiple times, this will be the time of the first failure. */ readonly ts: number; /** * Is the sender on a different server from us? */ readonly isFederated: boolean | undefined; /** * Was the failed event ever visible to the user? */ wasVisibleToUser: boolean; /** * Has the user verified their own cross-signing identity, as of the most * recent decryption attempt for this event? */ userTrustsOwnIdentity: boolean | undefined; /** * The time between our initial failure to decrypt and our successful * decryption (if we managed to decrypt). */ timeToDecryptMillis?: number; constructor(failedEventId: string, errorCode: DecryptionFailureCode, /** * The time that we failed to decrypt the event. If we failed to decrypt * multiple times, this will be the time of the first failure. */ ts: number, /** * Is the sender on a different server from us? */ isFederated: boolean | undefined, /** * Was the failed event ever visible to the user? */ wasVisibleToUser: boolean, /** * Has the user verified their own cross-signing identity, as of the most * recent decryption attempt for this event? */ userTrustsOwnIdentity: boolean | undefined); } type ErrorCode = ErrorEvent["name"]; /** Properties associated with decryption errors, for classifying the error. */ export type ErrorProperties = Omit<ErrorEvent, "eventName" | "domain" | "name" | "context">; export type ErrCodeMapFn = (errcode: DecryptionFailureCode) => ErrorCode; export declare class DecryptionFailureTracker { private readonly fn; private readonly errorCodeMapFn; private readonly checkReportedEvents; private static internalInstance; /** Map of event IDs to `DecryptionFailure` items. * * Every `CHECK_INTERVAL_MS`, this map is checked for failures that happened > * `MAXIMUM_LATE_DECRYPTION_PERIOD` ago (considered undecryptable), or * decryptions that took > `GRACE_PERIOD_MS` (considered late decryptions). * * Any such events are then reported via the `TrackingFn`. */ failures: Map<string, DecryptionFailure>; /** Set of event IDs that have been visible to the user. * * This will only contain events that are not already in `reportedEvents`. */ visibleEvents: Set<string>; /** Bloom filter tracking event IDs of failures that were reported previously */ private reportedEvents; /** Set to an interval ID when `start` is called */ checkInterval: number | null; trackInterval: number | null; /** Call `checkFailures` every `CHECK_INTERVAL_MS`. */ static CHECK_INTERVAL_MS: number; /** If the event is successfully decrypted in less than 4s, we don't report. */ static GRACE_PERIOD_MS: number; /** Maximum time for an event to be decrypted to be considered a late * decryption. If it takes longer, we consider it undecryptable. */ static MAXIMUM_LATE_DECRYPTION_PERIOD: number; /** Properties that will be added to all reported events (mainly reporting * information about the Matrix client). */ private baseProperties?; /** The user's domain (homeserver name). */ private userDomain?; /** Whether the user has verified their own cross-signing keys. */ private userTrustsOwnIdentity; /** Whether we are currently checking our own verification status. */ private checkingVerificationStatus; /** Whether we should retry checking our own verification status after we're * done our current check. i.e. we got notified that our keys changed while * we were already checking, so the result could be out of date. */ private retryVerificationStatus; /** * Create a new DecryptionFailureTracker. * * Call `start(client)` to start the tracker. The tracker will listen for * decryption events on the client and track decryption failures, and will * automatically stop tracking when the client logs out. * * @param {function} fn The tracking function, which will be called when failures * are tracked. The function should have a signature `(trackedErrorCode, rawError, properties) => {...}`, * where `errorCode` matches the output of `errorCodeMapFn`, `rawError` is the original * error (that is, the input to `errorCodeMapFn`), and `properties` is a map of the * error properties for classifying the error. * * @param {function} errorCodeMapFn The function used to map decryption failure reason codes to the * `trackedErrorCode`. * * @param {boolean} checkReportedEvents Check if we have already reported an event. * Defaults to `true`. This is only used for tests, to avoid possible false positives from * the Bloom filter. This should be set to `false` for all tests except for those * that specifically test the `reportedEvents` functionality. */ private constructor(); static get instance(): DecryptionFailureTracker; private loadReportedEvents; private saveReportedEvents; /** Callback for when an event is decrypted. * * This function is called by our `MatrixEventEvent.Decrypted` event * handler after a decryption attempt on an event, whether the decryption * is successful or not. * * @param e the event that was decrypted * * @param nowTs the current timestamp */ private eventDecrypted; addVisibleEvent(e: MatrixEvent): void; removeDecryptionFailuresForEvent(e: MatrixEvent, nowTs: number): void; private handleKeysChanged; /** * Start checking for and tracking failures. */ start(client: MatrixClient): Promise<void>; private calculateClientProperties; private registerHandlers; /** * Clear state and stop checking for and tracking failures. */ private stop; /** * Mark failures as undecryptable or late. Only mark one failure per event ID. * * @param {number} nowTs the timestamp that represents the time now. */ checkFailures(nowTs: number): void; /** * If there are failures that should be tracked, call the given trackDecryptionFailure * function with the failures that should be tracked. */ private reportFailure; } export {};