diff --git a/.eslintrc.js b/.eslintrc.js index 14afc41c07..caeeca403d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -108,7 +108,6 @@ module.exports = { "!matrix-js-sdk/src/extensible_events_v1/PollEndEvent", "!matrix-js-sdk/src/extensible_events_v1/InvalidEventError", "!matrix-js-sdk/src/crypto", - "!matrix-js-sdk/src/crypto/algorithms", "!matrix-js-sdk/src/crypto/aes", "!matrix-js-sdk/src/crypto/olmlib", "!matrix-js-sdk/src/crypto/crypto", diff --git a/package.json b/package.json index 4b3a9d08e6..267594d226 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "opus-recorder": "^8.0.3", "pako": "^2.0.3", "png-chunks-extract": "^1.0.0", - "posthog-js": "1.121.2", + "posthog-js": "1.126.0", "proposal-temporal": "^0.9.0", "qrcode": "1.5.3", "re-resizable": "^6.9.0", diff --git a/src/DecryptionFailureTracker.ts b/src/DecryptionFailureTracker.ts index f9afec0daa..9914704550 100644 --- a/src/DecryptionFailureTracker.ts +++ b/src/DecryptionFailureTracker.ts @@ -14,9 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { DecryptionError } from "matrix-js-sdk/src/crypto/algorithms"; import { 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"; import { PosthogAnalytics } from "./PosthogAnalytics"; @@ -25,17 +25,15 @@ export class DecryptionFailure { public constructor( public readonly failedEventId: string, - public readonly errorCode: string, + public readonly errorCode: DecryptionFailureCode, ) { this.ts = Date.now(); } } -type ErrorCode = "OlmKeysNotSentError" | "OlmIndexError" | "UnknownError" | "OlmUnspecifiedError"; - +type ErrorCode = ErrorEvent["name"]; type TrackingFn = (count: number, trackedErrCode: ErrorCode, rawError: string) => void; - -export type ErrCodeMapFn = (errcode: string) => ErrorCode; +export type ErrCodeMapFn = (errcode: DecryptionFailureCode) => ErrorCode; export class DecryptionFailureTracker { private static internalInstance = new DecryptionFailureTracker( @@ -52,12 +50,14 @@ export class DecryptionFailureTracker { (errorCode) => { // Map JS-SDK error codes to tracker codes for aggregation switch (errorCode) { - case "MEGOLM_UNKNOWN_INBOUND_SESSION_ID": + case DecryptionFailureCode.MEGOLM_UNKNOWN_INBOUND_SESSION_ID: return "OlmKeysNotSentError"; - case "OLM_UNKNOWN_MESSAGE_INDEX": + case DecryptionFailureCode.OLM_UNKNOWN_MESSAGE_INDEX: return "OlmIndexError"; - case undefined: - return "OlmUnspecifiedError"; + case DecryptionFailureCode.HISTORICAL_MESSAGE_NO_KEY_BACKUP: + case DecryptionFailureCode.HISTORICAL_MESSAGE_BACKUP_UNCONFIGURED: + case DecryptionFailureCode.HISTORICAL_MESSAGE_WORKING_BACKUP: + return "HistoricalMessage"; default: return "UnknownError"; } @@ -76,11 +76,11 @@ export class DecryptionFailureTracker { // accumulated in `failureCounts`. public visibleFailures: Map = new Map(); - // A histogram of the number of failures that will be tracked at the next tracking - // interval, split by failure error code. - public failureCounts: Record = { - // [errorCode]: 42 - }; + /** + * A histogram of the number of failures that will be tracked at the next tracking + * interval, split by failure error code. + */ + private failureCounts: Map = new Map(); // Event IDs of failures that were tracked previously public trackedEvents: Set = new Set(); @@ -108,10 +108,10 @@ export class DecryptionFailureTracker { * * @param {function} fn The tracking function, which will be called when failures * are tracked. The function should have a signature `(count, trackedErrorCode) => {...}`, - * where `count` is the number of failures and `errorCode` matches the `.code` of - * provided DecryptionError errors (by default, unless `errorCodeMapFn` is specified. - * @param {function?} errorCodeMapFn The function used to map error codes to the - * trackedErrorCode. If not provided, the `.code` of errors will be used. + * where `count` is the number of failures and `errorCode` matches the output of `errorCodeMapFn`. + * + * @param {function} errorCodeMapFn The function used to map decryption failure reason codes to the + * `trackedErrorCode`. */ private constructor( private readonly fn: TrackingFn, @@ -138,13 +138,15 @@ export class DecryptionFailureTracker { // localStorage.setItem('mx-decryption-failure-event-ids', JSON.stringify([...this.trackedEvents])); // } - public eventDecrypted(e: MatrixEvent, err: DecryptionError): void { - // for now we only track megolm decrytion failures + public eventDecrypted(e: MatrixEvent): void { + // for now we only track megolm decryption failures if (e.getWireContent().algorithm != "m.megolm.v1.aes-sha2") { return; } - if (err) { - this.addDecryptionFailure(new DecryptionFailure(e.getId()!, err.code)); + + const errCode = e.decryptionFailureReason; + if (errCode !== null) { + this.addDecryptionFailure(new DecryptionFailure(e.getId()!, errCode)); } else { // Could be an event in the failures, remove it this.removeDecryptionFailuresForEvent(e); @@ -205,7 +207,7 @@ export class DecryptionFailureTracker { this.failures = new Map(); this.visibleEvents = new Set(); this.visibleFailures = new Map(); - this.failureCounts = {}; + this.failureCounts = new Map(); } /** @@ -236,7 +238,7 @@ export class DecryptionFailureTracker { private aggregateFailures(failures: Set): void { for (const failure of failures) { const errorCode = failure.errorCode; - this.failureCounts[errorCode] = (this.failureCounts[errorCode] || 0) + 1; + this.failureCounts.set(errorCode, (this.failureCounts.get(errorCode) ?? 0) + 1); } } @@ -245,12 +247,12 @@ export class DecryptionFailureTracker { * function with the number of failures that should be tracked. */ public trackFailures(): void { - for (const errorCode of Object.keys(this.failureCounts)) { - if (this.failureCounts[errorCode] > 0) { + for (const [errorCode, count] of this.failureCounts.entries()) { + if (count > 0) { const trackedErrorCode = this.errorCodeMapFn(errorCode); - this.fn(this.failureCounts[errorCode], trackedErrorCode, errorCode); - this.failureCounts[errorCode] = 0; + this.fn(count, trackedErrorCode, errorCode); + this.failureCounts.set(errorCode, 0); } } } diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 47a5ac1b12..2574156279 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -32,7 +32,6 @@ import { defer, IDeferred, QueryDict } from "matrix-js-sdk/src/utils"; import { logger } from "matrix-js-sdk/src/logger"; import { throttle } from "lodash"; import { CryptoEvent } from "matrix-js-sdk/src/crypto"; -import { DecryptionError } from "matrix-js-sdk/src/crypto/algorithms"; import { IKeyBackupInfo } from "matrix-js-sdk/src/crypto/keybackup"; // what-input helps improve keyboard accessibility @@ -1597,7 +1596,7 @@ export default class MatrixChat extends React.PureComponent { // When logging out, stop tracking failures and destroy state cli.on(HttpApiEvent.SessionLoggedOut, () => dft.stop()); - cli.on(MatrixEventEvent.Decrypted, (e, err) => dft.eventDecrypted(e, err as DecryptionError)); + cli.on(MatrixEventEvent.Decrypted, (e) => dft.eventDecrypted(e)); cli.on(ClientEvent.Room, (room) => { if (cli.isCryptoEnabled()) { diff --git a/src/stores/room-list/MessagePreviewStore.ts b/src/stores/room-list/MessagePreviewStore.ts index 62dfa6f0f1..647300f99c 100644 --- a/src/stores/room-list/MessagePreviewStore.ts +++ b/src/stores/room-list/MessagePreviewStore.ts @@ -32,6 +32,7 @@ import { UPDATE_EVENT } from "../AsyncStore"; import { IPreview } from "./previews/IPreview"; import { VoiceBroadcastInfoEventType } from "../../voice-broadcast"; import { VoiceBroadcastPreview } from "./previews/VoiceBroadcastPreview"; +import shouldHideEvent from "../../shouldHideEvent"; // Emitted event for when a room's preview has changed. First argument will the room for which // the change happened. @@ -184,21 +185,6 @@ export class MessagePreviewStore extends AsyncStoreWithClient { return previewDef?.previewer.getTextFor(event, undefined, true) ?? ""; } - private shouldSkipPreview(event: MatrixEvent, previousEvent?: MatrixEvent): boolean { - if (event.isRelation(RelationType.Replace)) { - if (previousEvent !== undefined) { - // Ignore edits if they don't apply to the latest event in the room to keep the preview on the latest event - const room = this.matrixClient?.getRoom(event.getRoomId()!); - const relatedEvent = room?.findEventById(event.relationEventId!); - if (relatedEvent !== previousEvent) { - return true; - } - } - } - - return false; - } - private async generatePreview(room: Room, tagId?: TagID): Promise { const events = [...room.getLiveTimeline().getEvents()]; @@ -221,8 +207,6 @@ export class MessagePreviewStore extends AsyncStoreWithClient { this.previews.set(room.roomId, map); } - const previousEventInAny = map.get(TAG_ANY)?.event; - // Set the tags so we know what to generate if (!map.has(TAG_ANY)) map.set(TAG_ANY, null); if (tagId && !map.has(tagId)) map.set(tagId, null); @@ -237,7 +221,8 @@ export class MessagePreviewStore extends AsyncStoreWithClient { const event = events[i]; await this.matrixClient?.decryptEventIfNeeded(event); - + const shouldHide = shouldHideEvent(event); + if (shouldHide) continue; const previewDef = PREVIEWS[event.getType()]; if (!previewDef) continue; if (previewDef.isState && isNullOrUndefined(event.getStateKey())) continue; @@ -245,16 +230,11 @@ export class MessagePreviewStore extends AsyncStoreWithClient { const anyPreviewText = previewDef.previewer.getTextFor(event); if (!anyPreviewText) continue; // not previewable for some reason - if (!this.shouldSkipPreview(event, previousEventInAny)) { - changed = changed || anyPreviewText !== map.get(TAG_ANY)?.text; - map.set(TAG_ANY, mkMessagePreview(anyPreviewText, event)); - } + changed = changed || anyPreviewText !== map.get(TAG_ANY)?.text; + map.set(TAG_ANY, mkMessagePreview(anyPreviewText, event)); const tagsToGenerate = Array.from(map.keys()).filter((t) => t !== TAG_ANY); // we did the any tag above for (const genTagId of tagsToGenerate) { - const previousEventInTag = map.get(genTagId)?.event; - if (this.shouldSkipPreview(event, previousEventInTag)) continue; - const realTagId = genTagId === TAG_ANY ? undefined : genTagId; const preview = previewDef.previewer.getTextFor(event, realTagId); diff --git a/test/DecryptionFailureTracker-test.ts b/test/DecryptionFailureTracker-test.ts index 553d4f4d74..7a0bf65f81 100644 --- a/test/DecryptionFailureTracker-test.ts +++ b/test/DecryptionFailureTracker-test.ts @@ -19,21 +19,11 @@ import { DecryptionFailureCode } from "matrix-js-sdk/src/crypto-api"; import { DecryptionFailureTracker } from "../src/DecryptionFailureTracker"; -class MockDecryptionError extends Error { - public readonly code: string; - - constructor(code?: string) { - super(); - - this.code = code || "MOCK_DECRYPTION_ERROR"; - } -} - -async function createFailedDecryptionEvent() { +async function createFailedDecryptionEvent(code?: DecryptionFailureCode) { return await mkDecryptionFailureMatrixEvent({ roomId: "!room:id", sender: "@alice:example.com", - code: DecryptionFailureCode.UNKNOWN_ERROR, + code: code ?? DecryptionFailureCode.UNKNOWN_ERROR, msg: ":(", }); } @@ -50,9 +40,7 @@ describe("DecryptionFailureTracker", function () { ); tracker.addVisibleEvent(failedDecryptionEvent); - - const err = new MockDecryptionError(); - tracker.eventDecrypted(failedDecryptionEvent, err); + tracker.eventDecrypted(failedDecryptionEvent); // Pretend "now" is Infinity tracker.checkFailures(Infinity); @@ -65,7 +53,9 @@ describe("DecryptionFailureTracker", function () { }); it("tracks a failed decryption with expected raw error for a visible event", async function () { - const failedDecryptionEvent = await createFailedDecryptionEvent(); + const failedDecryptionEvent = await createFailedDecryptionEvent( + DecryptionFailureCode.OLM_UNKNOWN_MESSAGE_INDEX, + ); let count = 0; let reportedRawCode = ""; @@ -79,9 +69,7 @@ describe("DecryptionFailureTracker", function () { ); tracker.addVisibleEvent(failedDecryptionEvent); - - const err = new MockDecryptionError("INBOUND_SESSION_MISMATCH_ROOM_ID"); - tracker.eventDecrypted(failedDecryptionEvent, err); + tracker.eventDecrypted(failedDecryptionEvent); // Pretend "now" is Infinity tracker.checkFailures(Infinity); @@ -93,7 +81,7 @@ describe("DecryptionFailureTracker", function () { expect(count).not.toBe(0); // Should add the rawCode to the event context - expect(reportedRawCode).toBe("INBOUND_SESSION_MISMATCH_ROOM_ID"); + expect(reportedRawCode).toBe("OLM_UNKNOWN_MESSAGE_INDEX"); }); it("tracks a failed decryption for an event that becomes visible later", async function () { @@ -106,9 +94,7 @@ describe("DecryptionFailureTracker", function () { () => "UnknownError", ); - const err = new MockDecryptionError(); - tracker.eventDecrypted(failedDecryptionEvent, err); - + tracker.eventDecrypted(failedDecryptionEvent); tracker.addVisibleEvent(failedDecryptionEvent); // Pretend "now" is Infinity @@ -131,8 +117,7 @@ describe("DecryptionFailureTracker", function () { () => "UnknownError", ); - const err = new MockDecryptionError(); - tracker.eventDecrypted(failedDecryptionEvent, err); + tracker.eventDecrypted(failedDecryptionEvent); // Pretend "now" is Infinity tracker.checkFailures(Infinity); @@ -156,9 +141,7 @@ describe("DecryptionFailureTracker", function () { ); tracker.addVisibleEvent(decryptedEvent); - - const err = new MockDecryptionError(); - tracker.eventDecrypted(decryptedEvent, err); + tracker.eventDecrypted(decryptedEvent); // Indicate successful decryption. await decryptExistingEvent(decryptedEvent, { @@ -188,15 +171,14 @@ describe("DecryptionFailureTracker", function () { () => "UnknownError", ); - const err = new MockDecryptionError(); - tracker.eventDecrypted(decryptedEvent, err); + tracker.eventDecrypted(decryptedEvent); // Indicate successful decryption. await decryptExistingEvent(decryptedEvent, { plainType: "m.room.message", plainContent: { body: "success" }, }); - tracker.eventDecrypted(decryptedEvent, null); + tracker.eventDecrypted(decryptedEvent); tracker.addVisibleEvent(decryptedEvent); @@ -222,16 +204,15 @@ describe("DecryptionFailureTracker", function () { tracker.addVisibleEvent(decryptedEvent); // Arbitrary number of failed decryptions for both events - const err = new MockDecryptionError(); - tracker.eventDecrypted(decryptedEvent, err); - tracker.eventDecrypted(decryptedEvent, err); - tracker.eventDecrypted(decryptedEvent, err); - tracker.eventDecrypted(decryptedEvent, err); - tracker.eventDecrypted(decryptedEvent, err); - tracker.eventDecrypted(decryptedEvent2, err); - tracker.eventDecrypted(decryptedEvent2, err); + tracker.eventDecrypted(decryptedEvent); + tracker.eventDecrypted(decryptedEvent); + tracker.eventDecrypted(decryptedEvent); + tracker.eventDecrypted(decryptedEvent); + tracker.eventDecrypted(decryptedEvent); + tracker.eventDecrypted(decryptedEvent2); + tracker.eventDecrypted(decryptedEvent2); tracker.addVisibleEvent(decryptedEvent2); - tracker.eventDecrypted(decryptedEvent2, err); + tracker.eventDecrypted(decryptedEvent2); // Pretend "now" is Infinity tracker.checkFailures(Infinity); @@ -259,8 +240,7 @@ describe("DecryptionFailureTracker", function () { tracker.addVisibleEvent(decryptedEvent); // Indicate decryption - const err = new MockDecryptionError(); - tracker.eventDecrypted(decryptedEvent, err); + tracker.eventDecrypted(decryptedEvent); // Pretend "now" is Infinity tracker.checkFailures(Infinity); @@ -268,7 +248,7 @@ describe("DecryptionFailureTracker", function () { tracker.trackFailures(); // Indicate a second decryption, after having tracked the failure - tracker.eventDecrypted(decryptedEvent, err); + tracker.eventDecrypted(decryptedEvent); tracker.trackFailures(); @@ -292,8 +272,7 @@ describe("DecryptionFailureTracker", function () { tracker.addVisibleEvent(decryptedEvent); // Indicate decryption - const err = new MockDecryptionError(); - tracker.eventDecrypted(decryptedEvent, err); + tracker.eventDecrypted(decryptedEvent); // Pretend "now" is Infinity // NB: This saves to localStorage specific to DFT @@ -312,7 +291,7 @@ describe("DecryptionFailureTracker", function () { //secondTracker.loadTrackedEvents(); - secondTracker.eventDecrypted(decryptedEvent, err); + secondTracker.eventDecrypted(decryptedEvent); secondTracker.checkFailures(Infinity); secondTracker.trackFailures(); @@ -326,25 +305,27 @@ describe("DecryptionFailureTracker", function () { // @ts-ignore access to private constructor const tracker = new DecryptionFailureTracker( (total: number, errorCode: string) => (counts[errorCode] = (counts[errorCode] || 0) + total), - (error: string) => (error === "UnknownError" ? "UnknownError" : "OlmKeysNotSentError"), + (error: DecryptionFailureCode) => + error === DecryptionFailureCode.UNKNOWN_ERROR ? "UnknownError" : "OlmKeysNotSentError", ); - const decryptedEvent1 = await createFailedDecryptionEvent(); - const decryptedEvent2 = await createFailedDecryptionEvent(); - const decryptedEvent3 = await createFailedDecryptionEvent(); - - const error1 = new MockDecryptionError("UnknownError"); - const error2 = new MockDecryptionError("OlmKeysNotSentError"); + const decryptedEvent1 = await createFailedDecryptionEvent(DecryptionFailureCode.UNKNOWN_ERROR); + const decryptedEvent2 = await createFailedDecryptionEvent( + DecryptionFailureCode.MEGOLM_UNKNOWN_INBOUND_SESSION_ID, + ); + const decryptedEvent3 = await createFailedDecryptionEvent( + DecryptionFailureCode.MEGOLM_UNKNOWN_INBOUND_SESSION_ID, + ); tracker.addVisibleEvent(decryptedEvent1); tracker.addVisibleEvent(decryptedEvent2); tracker.addVisibleEvent(decryptedEvent3); // One failure of ERROR_CODE_1, and effectively two for ERROR_CODE_2 - tracker.eventDecrypted(decryptedEvent1, error1); - tracker.eventDecrypted(decryptedEvent2, error2); - tracker.eventDecrypted(decryptedEvent2, error2); - tracker.eventDecrypted(decryptedEvent3, error2); + tracker.eventDecrypted(decryptedEvent1); + tracker.eventDecrypted(decryptedEvent2); + tracker.eventDecrypted(decryptedEvent2); + tracker.eventDecrypted(decryptedEvent3); // Pretend "now" is Infinity tracker.checkFailures(Infinity); @@ -364,21 +345,19 @@ describe("DecryptionFailureTracker", function () { (_errorCode: string) => "OlmUnspecifiedError", ); - const decryptedEvent1 = await createFailedDecryptionEvent(); - const decryptedEvent2 = await createFailedDecryptionEvent(); - const decryptedEvent3 = await createFailedDecryptionEvent(); - - const error1 = new MockDecryptionError("ERROR_CODE_1"); - const error2 = new MockDecryptionError("ERROR_CODE_2"); - const error3 = new MockDecryptionError("ERROR_CODE_3"); + const decryptedEvent1 = await createFailedDecryptionEvent( + DecryptionFailureCode.MEGOLM_UNKNOWN_INBOUND_SESSION_ID, + ); + const decryptedEvent2 = await createFailedDecryptionEvent(DecryptionFailureCode.OLM_UNKNOWN_MESSAGE_INDEX); + const decryptedEvent3 = await createFailedDecryptionEvent(DecryptionFailureCode.UNKNOWN_ERROR); tracker.addVisibleEvent(decryptedEvent1); tracker.addVisibleEvent(decryptedEvent2); tracker.addVisibleEvent(decryptedEvent3); - tracker.eventDecrypted(decryptedEvent1, error1); - tracker.eventDecrypted(decryptedEvent2, error2); - tracker.eventDecrypted(decryptedEvent3, error3); + tracker.eventDecrypted(decryptedEvent1); + tracker.eventDecrypted(decryptedEvent2); + tracker.eventDecrypted(decryptedEvent3); // Pretend "now" is Infinity tracker.checkFailures(Infinity); @@ -397,13 +376,9 @@ describe("DecryptionFailureTracker", function () { (errorCode: string) => Array.from(errorCode).reverse().join(""), ); - const decryptedEvent = await createFailedDecryptionEvent(); - - const error = new MockDecryptionError("ERROR_CODE_1"); - + const decryptedEvent = await createFailedDecryptionEvent(DecryptionFailureCode.OLM_UNKNOWN_MESSAGE_INDEX); tracker.addVisibleEvent(decryptedEvent); - - tracker.eventDecrypted(decryptedEvent, error); + tracker.eventDecrypted(decryptedEvent); // Pretend "now" is Infinity tracker.checkFailures(Infinity); @@ -411,6 +386,6 @@ describe("DecryptionFailureTracker", function () { tracker.trackFailures(); // should track remapped error code - expect(counts["1_EDOC_RORRE"]).toBe(1); + expect(counts["XEDNI_EGASSEM_NWONKNU_MLO"]).toBe(1); }); }); diff --git a/test/stores/room-list/MessagePreviewStore-test.ts b/test/stores/room-list/MessagePreviewStore-test.ts index fb6207ed52..cbb045e6e9 100644 --- a/test/stores/room-list/MessagePreviewStore-test.ts +++ b/test/stores/room-list/MessagePreviewStore-test.ts @@ -126,6 +126,62 @@ describe("MessagePreviewStore", () => { ); }); + it("should not display a redacted edit", async () => { + const firstMessage = mkMessage({ + user: "@sender:server", + event: true, + room: room.roomId, + msg: "First message", + }); + await addEvent(store, room, firstMessage, false); + + expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot( + `"@sender:server: First message"`, + ); + + const secondMessage = mkMessage({ + user: "@sender:server", + event: true, + room: room.roomId, + msg: "Second message", + }); + await addEvent(store, room, secondMessage); + + expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot( + `"@sender:server: Second message"`, + ); + + const secondMessageEdit = mkEvent({ + event: true, + type: EventType.RoomMessage, + user: "@sender:server", + room: room.roomId, + content: { + "body": "* Second Message Edit", + "m.new_content": { + body: "Second Message Edit", + }, + "m.relates_to": { + rel_type: RelationType.Replace, + event_id: secondMessage.getId()!, + }, + }, + }); + await addEvent(store, room, secondMessageEdit); + + expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot( + `"@sender:server: Second Message Edit"`, + ); + + secondMessage.makeRedacted(secondMessage, room); + + await addEvent(store, room, secondMessage); + + expect((await store.getPreviewForRoom(room, DefaultTagID.Untagged))?.text).toMatchInlineSnapshot( + `"@sender:server: First message"`, + ); + }); + it("should ignore edits to unknown events", async () => { await expect(store.getPreviewForRoom(room, DefaultTagID.DM)).resolves.toBeNull(); diff --git a/yarn.lock b/yarn.lock index 37492ce54a..ac7384ec15 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7724,10 +7724,10 @@ postcss@^8.4.38: picocolors "^1.0.0" source-map-js "^1.2.0" -posthog-js@1.121.2: - version "1.121.2" - resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.121.2.tgz#1e72c0a8ce3a26241378f3f1cbafb9bd1780dc69" - integrity sha512-2rhPgzeOaSR7Ztf77fGxGnUavBJCV3+tR5O1UHsnygxKL+XIt+Vr9i/hYYgu9Gz9/eq2Y7sxpszjxSTDMZprRQ== +posthog-js@1.126.0: + version "1.126.0" + resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.126.0.tgz#52ca294505d3ddc3ba34aeaafe388676113ff82f" + integrity sha512-8qCdPE9RZkyXI3kKCnkXWxK0jn2mLZg6g5a6KezDPqH7mHTG66v7ANU31hcwzQGV5F5UW1GXw0xL0PaC3HkA6g== dependencies: fflate "^0.4.8" preact "^10.19.3" @@ -8652,16 +8652,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -8755,14 +8746,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -9555,7 +9539,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -9573,15 +9557,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"