From 30dd28960cbdd872b654f76661022564c4d88f3c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 7 Jul 2023 08:43:17 +0100 Subject: [PATCH 01/59] Update IUnsigned type to be extensible (#3547) --- src/models/event.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/models/event.ts b/src/models/event.ts index 55e923c6f14..3ed1957f4a1 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -63,10 +63,12 @@ export interface IContent { type StrippedState = Required>; export interface IUnsigned { + [key: string]: any; "age"?: number; "prev_sender"?: string; "prev_content"?: IContent; "redacted_because"?: IEvent; + "replaces_state"?: string; "transaction_id"?: string; "invite_room_state"?: StrippedState[]; "m.relations"?: Record; // No common pattern for aggregated relations From cd7c519dc435af4b8cf4600e03a4e58706d789d6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 7 Jul 2023 09:48:09 +0100 Subject: [PATCH 02/59] Prevent threads code from making identical simultaneous API hits (#3541) --- .../matrix-client-event-timeline.spec.ts | 107 +----------------- spec/test-utils/thread.ts | 2 +- spec/unit/models/thread.spec.ts | 12 +- spec/unit/room.spec.ts | 2 +- src/models/thread.ts | 55 +++++++-- 5 files changed, 58 insertions(+), 120 deletions(-) diff --git a/spec/integ/matrix-client-event-timeline.spec.ts b/spec/integ/matrix-client-event-timeline.spec.ts index cba141f988a..9a8f7b3058f 100644 --- a/spec/integ/matrix-client-event-timeline.spec.ts +++ b/spec/integ/matrix-client-event-timeline.spec.ts @@ -598,12 +598,6 @@ describe("MatrixClient event timelines", function () { await client.stopClient(); // we don't need the client to be syncing at this time const room = client.getRoom(roomId)!; - httpBackend - .when("GET", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!)) - .respond(200, function () { - return THREAD_ROOT; - }); - httpBackend .when("GET", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!)) .respond(200, function () { @@ -634,12 +628,6 @@ describe("MatrixClient event timelines", function () { const thread = room.createThread(THREAD_ROOT.event_id!, undefined, [], false); await httpBackend.flushAllExpected(); const timelineSet = thread.timelineSet; - httpBackend - .when("GET", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!)) - .respond(200, function () { - return THREAD_ROOT; - }); - await flushHttp(emitPromise(thread, ThreadEvent.Update)); const timeline = await client.getEventTimeline(timelineSet, THREAD_REPLY.event_id!); @@ -1510,7 +1498,8 @@ describe("MatrixClient event timelines", function () { }, event: true, }); - THREAD_REPLY2.localTimestamp += 1000; + // this has to come after THREAD_REPLY which hasn't been instantiated by us + THREAD_REPLY2.localTimestamp += 10000000; // Test data for the first thread, with the second reply const THREAD_ROOT_UPDATED = { @@ -1570,9 +1559,6 @@ describe("MatrixClient event timelines", function () { thread.initialEventsFetched = true; const prom = emitPromise(room, ThreadEvent.NewReply); respondToEvent(THREAD_ROOT_UPDATED); - respondToEvent(THREAD_ROOT_UPDATED); - respondToEvent(THREAD_ROOT_UPDATED); - respondToEvent(THREAD_ROOT_UPDATED); respondToEvent(THREAD2_ROOT); await room.addLiveEvents([THREAD_REPLY2]); await httpBackend.flushAllExpected(); @@ -1699,13 +1685,11 @@ describe("MatrixClient event timelines", function () { thread.initialEventsFetched = true; const prom = emitPromise(room, ThreadEvent.Update); respondToEvent(THREAD_ROOT_UPDATED); - respondToEvent(THREAD_ROOT_UPDATED); - respondToEvent(THREAD_ROOT_UPDATED); respondToEvent(THREAD2_ROOT); await room.addLiveEvents([THREAD_REPLY_REACTION]); await httpBackend.flushAllExpected(); await prom; - expect(thread.length).toBe(2); + expect(thread.length).toBe(1); // reactions don't count towards the length of a thread // Test thread order is unchanged expect(timeline!.getEvents().map((it) => it.event.event_id)).toEqual([ THREAD_ROOT.event_id, @@ -2021,25 +2005,6 @@ describe("MatrixClient event timelines", function () { .respond(200, function () { return THREAD_ROOT; }); - httpBackend - .when("GET", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!)) - .respond(200, function () { - return THREAD_ROOT; - }); - httpBackend - .when( - "GET", - "/_matrix/client/v1/rooms/!foo%3Abar/relations/" + - encodeURIComponent(THREAD_ROOT.event_id!) + - "/" + - encodeURIComponent(THREAD_RELATION_TYPE.name) + - buildRelationPaginationQuery({ dir: Direction.Backward, limit: 1 }), - ) - .respond(200, function () { - return { - chunk: [THREAD_REPLY], - }; - }); await Promise.all([httpBackend.flushAllExpected(), utils.syncPromise(client)]); const room = client.getRoom(roomId)!; @@ -2047,71 +2012,7 @@ describe("MatrixClient event timelines", function () { expect(thread.initialEventsFetched).toBeTruthy(); const timelineSet = thread.timelineSet; - httpBackend - .when("GET", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!)) - .respond(200, function () { - return THREAD_ROOT; - }); - httpBackend - .when("GET", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!)) - .respond(200, function () { - return THREAD_ROOT; - }); - httpBackend - .when("GET", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!)) - .respond(200, function () { - return THREAD_ROOT; - }); - httpBackend - .when("GET", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!)) - .respond(200, function () { - return THREAD_ROOT; - }); - httpBackend - .when("GET", "/rooms/!foo%3Abar/context/" + encodeURIComponent(THREAD_ROOT.event_id!)) - .respond(200, function () { - return { - start: "start_token", - events_before: [], - event: THREAD_ROOT, - events_after: [], - end: "end_token", - state: [], - }; - }); - httpBackend - .when( - "GET", - "/_matrix/client/v1/rooms/!foo%3Abar/relations/" + - encodeURIComponent(THREAD_ROOT.event_id!) + - "/" + - encodeURIComponent(THREAD_RELATION_TYPE.name) + - buildRelationPaginationQuery({ - dir: Direction.Backward, - from: "start_token", - }), - ) - .respond(200, function () { - return { - chunk: [], - }; - }); - httpBackend - .when( - "GET", - "/_matrix/client/v1/rooms/!foo%3Abar/relations/" + - encodeURIComponent(THREAD_ROOT.event_id!) + - "/" + - encodeURIComponent(THREAD_RELATION_TYPE.name) + - buildRelationPaginationQuery({ dir: Direction.Forward, from: "end_token" }), - ) - .respond(200, function () { - return { - chunk: [THREAD_REPLY], - }; - }); - - const timeline = await flushHttp(client.getEventTimeline(timelineSet, THREAD_ROOT.event_id!)); + const timeline = await client.getEventTimeline(timelineSet, THREAD_ROOT.event_id!); httpBackend.when("GET", "/sync").respond(200, { next_batch: "s_5_5", diff --git a/spec/test-utils/thread.ts b/spec/test-utils/thread.ts index ebca5720fe4..bed1b235e87 100644 --- a/spec/test-utils/thread.ts +++ b/spec/test-utils/thread.ts @@ -157,7 +157,7 @@ export const mkThread = ({ room?.reEmitter.reEmit(evt, [MatrixEventEvent.BeforeRedaction]); } - const thread = room.createThread(rootEvent.getId() ?? "", rootEvent, events, true); + const thread = room.createThread(rootEvent.getId() ?? "", rootEvent, [rootEvent, ...events], true); return { thread, rootEvent, events }; }; diff --git a/spec/unit/models/thread.spec.ts b/spec/unit/models/thread.spec.ts index d8dd88809b4..0847bc8f054 100644 --- a/spec/unit/models/thread.spec.ts +++ b/spec/unit/models/thread.spec.ts @@ -18,7 +18,7 @@ import { mocked } from "jest-mock"; import { MatrixClient, PendingEventOrdering } from "../../../src/client"; import { Room, RoomEvent } from "../../../src/models/room"; -import { Thread, THREAD_RELATION_TYPE, ThreadEvent, FeatureSupport } from "../../../src/models/thread"; +import { FeatureSupport, Thread, THREAD_RELATION_TYPE, ThreadEvent } from "../../../src/models/thread"; import { makeThreadEvent, mkThread } from "../../test-utils/thread"; import { TestClient } from "../../TestClient"; import { emitPromise, mkEdit, mkMessage, mkReaction, mock } from "../../test-utils/test-utils"; @@ -43,6 +43,7 @@ describe("Thread", () => { const myUserId = "@bob:example.org"; const testClient = new TestClient(myUserId, "DEVICE", "ACCESS_TOKEN", undefined, { timelineSupport: false }); const client = testClient.client; + client.supportsThreads = jest.fn().mockReturnValue(true); const room = new Room("123", client, myUserId, { pendingEventOrdering: PendingEventOrdering.Detached, }); @@ -300,6 +301,7 @@ describe("Thread", () => { timelineSupport: false, }); const client = testClient.client; + client.supportsThreads = jest.fn().mockReturnValue(true); const room = new Room("123", client, myUserId, { pendingEventOrdering: PendingEventOrdering.Detached, }); @@ -354,6 +356,7 @@ describe("Thread", () => { timelineSupport: false, }); const client = testClient.client; + client.supportsThreads = jest.fn().mockReturnValue(true); const room = new Room("123", client, myUserId, { pendingEventOrdering: PendingEventOrdering.Detached, }); @@ -405,6 +408,7 @@ describe("Thread", () => { timelineSupport: false, }); const client = testClient.client; + client.supportsThreads = jest.fn().mockReturnValue(true); const room = new Room("123", client, myUserId, { pendingEventOrdering: PendingEventOrdering.Detached, }); @@ -699,11 +703,7 @@ async function createThread(client: MatrixClient, user: string, roomId: string): root.setThreadId(root.getId()); await room.addLiveEvents([root]); - // Create the thread and wait for it to be initialised - const thread = room.createThread(root.getId()!, root, [], false); - await new Promise((res) => thread.once(RoomEvent.TimelineReset, () => res())); - - return thread; + return room.createThread(root.getId()!, root, [], false); } /** diff --git a/spec/unit/room.spec.ts b/spec/unit/room.spec.ts index 150f2c30cb7..777d46c469f 100644 --- a/spec/unit/room.spec.ts +++ b/spec/unit/room.spec.ts @@ -2787,10 +2787,10 @@ describe("Room", function () { let prom = emitPromise(room, ThreadEvent.New); await room.addLiveEvents([threadRoot, threadResponse1]); const thread: Thread = await prom; - await emitPromise(room, ThreadEvent.Update); expect(thread.initialEventsFetched).toBeTruthy(); await room.addLiveEvents([threadResponse2]); + await emitPromise(room, ThreadEvent.Update); expect(thread).toHaveLength(2); expect(thread.replyToEvent!.getId()).toBe(threadResponse2.getId()); diff --git a/src/models/thread.ts b/src/models/thread.ts index 62d36ac7947..2966f22a545 100644 --- a/src/models/thread.ts +++ b/src/models/thread.ts @@ -98,6 +98,7 @@ export class Thread extends ReadReceipt; public initialEventsFetched = !Thread.hasServerSideSupport; /** @@ -134,6 +135,7 @@ export class Thread extends ReadReceipt => { + // We hit a gappy sync, ask the server for an update + await this.processRootEventPromise; + this.processRootEventPromise = undefined; + }; + private async fetchRootEvent(): Promise { this.rootEvent = this.room.findEventById(this.id); // If the rootEvent does not exist in the local stores, then fetch it from the server. @@ -197,6 +205,11 @@ export class Thread extends ReadReceipt { this.setEventMetadata(event); + if (!this.initialEventsFetched && !toStartOfTimeline && event.getId() === this.id) { + // We're loading the thread organically + this.initialEventsFetched = true; + } + const lastReply = this.lastReply(); const isNewestReply = !lastReply || event.localTimestamp >= lastReply!.localTimestamp; @@ -351,10 +374,14 @@ export class Thread extends ReadReceipt { - this.updatePendingReplyCount(); - + private async updateThreadFromRootEvent(): Promise { if (Thread.hasServerSideSupport) { // Ensure we show *something* as soon as possible, we'll update it as soon as we get better data, but we // don't want the thread preview to be empty if we can avoid it - if (!this.initialEventsFetched) { + if (!this.initialEventsFetched && !this.lastEvent) { await this.processRootEvent(); } await this.fetchRootEvent(); } await this.processRootEvent(); + } + + private async updateThreadMetadata(): Promise { + this.updatePendingReplyCount(); + + if (!this.processRootEventPromise) { + // We only want to do this once otherwise we end up rolling back to the last unsigned summary we have for the thread + this.processRootEventPromise = this.updateThreadFromRootEvent(); + } + await this.processRootEventPromise; if (!this.initialEventsFetched) { this.initialEventsFetched = true; @@ -572,7 +607,9 @@ export class Thread extends ReadReceipt boolean = (): boolean => true): MatrixEvent | null { + public lastReply( + matches: (ev: MatrixEvent) => boolean = (ev): boolean => ev.isRelation(RelationType.Thread), + ): MatrixEvent | null { for (let i = this.timeline.length - 1; i >= 0; i--) { const event = this.timeline[i]; if (matches(event)) { From b606d1e54b840bc148d6dd35fca7c22f8f30984e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 7 Jul 2023 06:43:25 -0400 Subject: [PATCH 03/59] Don't allow Olm unwedging rate-limiting to race (#3549) * don't allow Olm unwedging rate-limiting to race * apply changes from code review --- src/crypto/index.ts | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 6610f8621e2..4d96216be07 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -130,7 +130,12 @@ export function isCryptoAvailable(): boolean { return Boolean(global.Olm); } -const MIN_FORCE_SESSION_INTERVAL_MS = 60 * 60 * 1000; +// minimum time between attempting to unwedge an Olm session, if we succeeded +// in creating a new session +const MIN_FORCE_SESSION_INTERVAL_MS = 60 * 60 * 1000; // 1 hour +// minimum time between attempting to unwedge an Olm session, if we failed +// to create a new session +const FORCE_SESSION_RETRY_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes interface IInitOpts { exportedOlmDevice?: IExportedDevice; @@ -390,7 +395,7 @@ export class Crypto extends TypedEventEmitter } = {}; - // The timestamp of the last time we forced establishment + // The timestamp of the minimum time at which we will retry forcing establishment // of a new session for each device, in milliseconds. // { // userId: { @@ -398,7 +403,7 @@ export class Crypto extends TypedEventEmitter> = new MapWithDefault( + private forceNewSessionRetryTime: MapWithDefault> = new MapWithDefault( () => new MapWithDefault(() => 0), ); @@ -3592,25 +3597,23 @@ export class Crypto extends TypedEventEmitter Date.now()) { + const forceNewSessionRetryTimeDevices = this.forceNewSessionRetryTime.getOrCreate(sender); + const forceNewSessionRetryTime = forceNewSessionRetryTimeDevices.getOrCreate(deviceKey); + if (forceNewSessionRetryTime > Date.now()) { logger.debug( - "New session already forced with device " + - sender + - ":" + - deviceKey + - " at " + - lastNewSessionForced + - ": not forcing another", + `New session already forced with device ${sender}:${deviceKey}: ` + + `not forcing another until at least ${new Date(forceNewSessionRetryTime).toUTCString()}`, ); await this.olmDevice.recordSessionProblem(deviceKey, "wedged", true); retryDecryption(); return; } + // make sure we don't retry to unwedge too soon even if we fail to create a new session + forceNewSessionRetryTimeDevices.set(deviceKey, Date.now() + FORCE_SESSION_RETRY_INTERVAL_MS); + // establish a new olm session with this device since we're failing to decrypt messages // on a current session. // Note that an undecryptable message from another device could easily be spoofed - @@ -3631,7 +3634,7 @@ export class Crypto extends TypedEventEmitter Date: Mon, 10 Jul 2023 09:19:32 +1200 Subject: [PATCH 04/59] OIDC: use `oidc-client-ts` (#3544) * use oidc-client-ts during oidc discovery * export new type for auth config * deprecate generateAuthorizationUrl in favour of generateOidcAuthorizationUrl * testing util for oidc configurations * test generateOidcAuthorizationUrl * lint * test discovery * dont pass whole client wellknown to oidc validation funcs * add nonce * use client userState for homeserver --- package.json | 1 + spec/test-utils/oidc.ts | 53 +++++++++++++++++++++ spec/unit/autodiscovery.spec.ts | 82 ++++++++++++++++++++++++++++++++ spec/unit/oidc/authorize.spec.ts | 54 ++++++++++++++------- spec/unit/oidc/validate.spec.ts | 35 ++++++-------- src/autodiscovery.ts | 74 ++++++++++++++++++++++++++-- src/oidc/authorize.ts | 53 ++++++++++++++++++++- src/oidc/discovery.ts | 61 ++++++++++++++++++++++++ src/oidc/validate.ts | 54 +++++++++++++++++++-- yarn.lock | 13 +++++ 10 files changed, 432 insertions(+), 48 deletions(-) create mode 100644 spec/test-utils/oidc.ts create mode 100644 src/oidc/discovery.ts diff --git a/package.json b/package.json index 34e3638a6de..95901df5798 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "loglevel": "^1.7.1", "matrix-events-sdk": "0.0.1", "matrix-widget-api": "^1.3.1", + "oidc-client-ts": "^2.2.4", "p-retry": "4", "sdp-transform": "^2.14.1", "unhomoglyph": "^1.0.6", diff --git a/spec/test-utils/oidc.ts b/spec/test-utils/oidc.ts new file mode 100644 index 00000000000..0bd97442daf --- /dev/null +++ b/spec/test-utils/oidc.ts @@ -0,0 +1,53 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { OidcClientConfig } from "../../src"; +import { ValidatedIssuerMetadata } from "../../src/oidc/validate"; + +/** + * Makes a valid OidcClientConfig with minimum valid values + * @param issuer used as the base for all other urls + * @returns OidcClientConfig + */ +export const makeDelegatedAuthConfig = (issuer = "https://auth.org/"): OidcClientConfig => { + const metadata = mockOpenIdConfiguration(issuer); + + return { + issuer, + account: issuer + "account", + registrationEndpoint: metadata.registration_endpoint, + authorizationEndpoint: metadata.authorization_endpoint, + tokenEndpoint: metadata.token_endpoint, + metadata, + }; +}; + +/** + * Useful for mocking /.well-known/openid-configuration + * @param issuer used as the base for all other urls + * @returns ValidatedIssuerMetadata + */ +export const mockOpenIdConfiguration = (issuer = "https://auth.org/"): ValidatedIssuerMetadata => ({ + issuer, + revocation_endpoint: issuer + "revoke", + token_endpoint: issuer + "token", + authorization_endpoint: issuer + "auth", + registration_endpoint: issuer + "registration", + jwks_uri: issuer + "jwks", + response_types_supported: ["code"], + grant_types_supported: ["authorization_code", "refresh_token"], + code_challenge_methods_supported: ["S256"], +}); diff --git a/spec/unit/autodiscovery.spec.ts b/spec/unit/autodiscovery.spec.ts index e2e2c30824f..2ffe9be1a68 100644 --- a/spec/unit/autodiscovery.spec.ts +++ b/spec/unit/autodiscovery.spec.ts @@ -15,10 +15,17 @@ See the License for the specific language governing permissions and limitations under the License. */ +import fetchMock from "fetch-mock-jest"; import MockHttpBackend from "matrix-mock-request"; +import { M_AUTHENTICATION } from "../../src"; import { AutoDiscovery } from "../../src/autodiscovery"; import { OidcError } from "../../src/oidc/error"; +import { makeDelegatedAuthConfig } from "../test-utils/oidc"; + +// keep to reset the fetch function after using MockHttpBackend +// @ts-ignore private property +const realAutoDiscoveryFetch: typeof global.fetch = AutoDiscovery.fetchFn; describe("AutoDiscovery", function () { const getHttpBackend = (): MockHttpBackend => { @@ -27,6 +34,10 @@ describe("AutoDiscovery", function () { return httpBackend; }; + afterAll(() => { + AutoDiscovery.setFetchFn(realAutoDiscoveryFetch); + }); + it("should throw an error when no domain is specified", function () { getHttpBackend(); return Promise.all([ @@ -855,4 +866,75 @@ describe("AutoDiscovery", function () { }), ]); }); + + describe("m.authentication", () => { + const homeserverName = "example.org"; + const homeserverUrl = "https://chat.example.org/"; + const issuer = "https://auth.org/"; + + beforeAll(() => { + // make these tests independent from fetch mocking above + AutoDiscovery.setFetchFn(realAutoDiscoveryFetch); + }); + + beforeEach(() => { + fetchMock.resetBehavior(); + fetchMock.get(`${homeserverUrl}_matrix/client/versions`, { versions: ["r0.0.1"] }); + + fetchMock.get("https://example.org/.well-known/matrix/client", { + "m.homeserver": { + // Note: we also expect this test to trim the trailing slash + base_url: "https://chat.example.org/", + }, + "m.authentication": { + issuer, + }, + }); + }); + + it("should return valid authentication configuration", async () => { + const config = makeDelegatedAuthConfig(issuer); + + fetchMock.get(`${config.metadata.issuer}.well-known/openid-configuration`, config.metadata); + fetchMock.get(`${config.metadata.issuer}jwks`, { + status: 200, + headers: { + "Content-Type": "application/json", + }, + keys: [], + }); + + const result = await AutoDiscovery.findClientConfig(homeserverName); + + expect(result[M_AUTHENTICATION.stable!]).toEqual({ + state: AutoDiscovery.SUCCESS, + ...config, + signingKeys: [], + account: undefined, + error: null, + }); + }); + + it("should set state to error for invalid authentication configuration", async () => { + const config = makeDelegatedAuthConfig(issuer); + // authorization_code is required + config.metadata.grant_types_supported = ["openid"]; + + fetchMock.get(`${config.metadata.issuer}.well-known/openid-configuration`, config.metadata); + fetchMock.get(`${config.metadata.issuer}jwks`, { + status: 200, + headers: { + "Content-Type": "application/json", + }, + keys: [], + }); + + const result = await AutoDiscovery.findClientConfig(homeserverName); + + expect(result[M_AUTHENTICATION.stable!]).toEqual({ + state: AutoDiscovery.FAIL_ERROR, + error: OidcError.OpSupport, + }); + }); + }); }); diff --git a/spec/unit/oidc/authorize.spec.ts b/spec/unit/oidc/authorize.spec.ts index d773954889a..773d7071dd9 100644 --- a/spec/unit/oidc/authorize.spec.ts +++ b/spec/unit/oidc/authorize.spec.ts @@ -1,3 +1,7 @@ +/** + * @jest-environment jsdom + */ + /* Copyright 2023 The Matrix.org Foundation C.I.C. @@ -25,8 +29,10 @@ import { completeAuthorizationCodeGrant, generateAuthorizationParams, generateAuthorizationUrl, + generateOidcAuthorizationUrl, } from "../../../src/oidc/authorize"; import { OidcError } from "../../../src/oidc/error"; +import { makeDelegatedAuthConfig, mockOpenIdConfiguration } from "../../test-utils/oidc"; jest.mock("jwt-decode"); @@ -34,20 +40,16 @@ jest.mock("jwt-decode"); const realSubtleCrypto = crypto.subtleCrypto; describe("oidc authorization", () => { - const issuer = "https://auth.com/"; - const authorizationEndpoint = "https://auth.com/authorization"; - const tokenEndpoint = "https://auth.com/token"; - const delegatedAuthConfig = { - issuer, - registrationEndpoint: issuer + "registration", - authorizationEndpoint: issuer + "auth", - tokenEndpoint, - }; + const delegatedAuthConfig = makeDelegatedAuthConfig(); + const authorizationEndpoint = delegatedAuthConfig.metadata.authorization_endpoint; + const tokenEndpoint = delegatedAuthConfig.metadata.token_endpoint; const clientId = "xyz789"; const baseUrl = "https://test.com"; beforeAll(() => { jest.spyOn(logger, "warn"); + + fetchMock.get(delegatedAuthConfig.issuer + ".well-known/openid-configuration", mockOpenIdConfiguration()); }); afterEach(() => { @@ -97,20 +99,36 @@ describe("oidc authorization", () => { "A secure context is required to generate code challenge. Using plain text code challenge", ); }); + }); + + describe("generateOidcAuthorizationUrl()", () => { + it("should generate url with correct parameters", async () => { + const nonce = "abc123"; + + const metadata = delegatedAuthConfig.metadata; - it("uses a s256 code challenge when crypto is available", async () => { - jest.spyOn(crypto.subtleCrypto, "digest"); - const authorizationParams = generateAuthorizationParams({ redirectUri: baseUrl }); const authUrl = new URL( - await generateAuthorizationUrl(authorizationEndpoint, clientId, authorizationParams), + await generateOidcAuthorizationUrl({ + metadata, + homeserverUrl: baseUrl, + clientId, + redirectUri: baseUrl, + nonce, + }), ); - const codeChallenge = authUrl.searchParams.get("code_challenge"); - expect(crypto.subtleCrypto.digest).toHaveBeenCalledWith("SHA-256", expect.any(Object)); + expect(authUrl.searchParams.get("response_mode")).toEqual("query"); + expect(authUrl.searchParams.get("response_type")).toEqual("code"); + expect(authUrl.searchParams.get("client_id")).toEqual(clientId); + expect(authUrl.searchParams.get("code_challenge_method")).toEqual("S256"); + // scope minus the 10char random device id at the end + expect(authUrl.searchParams.get("scope")!.slice(0, -10)).toEqual( + "openid urn:matrix:org.matrix.msc2967.client:api:* urn:matrix:org.matrix.msc2967.client:device:", + ); + expect(authUrl.searchParams.get("state")).toBeTruthy(); + expect(authUrl.searchParams.get("nonce")).toEqual(nonce); - // didn't use plain text code challenge - expect(authorizationParams.codeVerifier).not.toEqual(codeChallenge); - expect(codeChallenge).toBeTruthy(); + expect(authUrl.searchParams.get("code_challenge")).toBeTruthy(); }); }); diff --git a/spec/unit/oidc/validate.spec.ts b/spec/unit/oidc/validate.spec.ts index 71e4aeb7c0a..f177d0d5a58 100644 --- a/spec/unit/oidc/validate.spec.ts +++ b/spec/unit/oidc/validate.spec.ts @@ -35,7 +35,7 @@ describe("validateWellKnownAuthentication()", () => { }, }; it("should throw not supported error when wellKnown has no m.authentication section", () => { - expect(() => validateWellKnownAuthentication(baseWk)).toThrow(OidcError.NotSupported); + expect(() => validateWellKnownAuthentication(undefined)).toThrow(OidcError.NotSupported); }); it("should throw misconfigured error when authentication issuer is not a string", () => { @@ -45,7 +45,9 @@ describe("validateWellKnownAuthentication()", () => { issuer: { url: "test.com" }, }, }; - expect(() => validateWellKnownAuthentication(wk)).toThrow(OidcError.Misconfigured); + expect(() => validateWellKnownAuthentication(wk[M_AUTHENTICATION.stable!] as any)).toThrow( + OidcError.Misconfigured, + ); }); it("should throw misconfigured error when authentication account is not a string", () => { @@ -56,7 +58,9 @@ describe("validateWellKnownAuthentication()", () => { account: { url: "test" }, }, }; - expect(() => validateWellKnownAuthentication(wk)).toThrow(OidcError.Misconfigured); + expect(() => validateWellKnownAuthentication(wk[M_AUTHENTICATION.stable!] as any)).toThrow( + OidcError.Misconfigured, + ); }); it("should throw misconfigured error when authentication account is false", () => { @@ -67,7 +71,9 @@ describe("validateWellKnownAuthentication()", () => { account: false, }, }; - expect(() => validateWellKnownAuthentication(wk)).toThrow(OidcError.Misconfigured); + expect(() => validateWellKnownAuthentication(wk[M_AUTHENTICATION.stable!] as any)).toThrow( + OidcError.Misconfigured, + ); }); it("should return valid config when wk uses stable m.authentication", () => { @@ -78,7 +84,7 @@ describe("validateWellKnownAuthentication()", () => { account: "account.com", }, }; - expect(validateWellKnownAuthentication(wk)).toEqual({ + expect(validateWellKnownAuthentication(wk[M_AUTHENTICATION.stable!])).toEqual({ issuer: "test.com", account: "account.com", }); @@ -91,7 +97,7 @@ describe("validateWellKnownAuthentication()", () => { issuer: "test.com", }, }; - expect(validateWellKnownAuthentication(wk)).toEqual({ + expect(validateWellKnownAuthentication(wk[M_AUTHENTICATION.stable!])).toEqual({ issuer: "test.com", }); }); @@ -104,22 +110,8 @@ describe("validateWellKnownAuthentication()", () => { somethingElse: "test", }, }; - expect(validateWellKnownAuthentication(wk)).toEqual({ - issuer: "test.com", - }); - }); - - it("should return valid config when wk uses unstable prefix for m.authentication", () => { - const wk = { - ...baseWk, - [M_AUTHENTICATION.unstable!]: { - issuer: "test.com", - account: "account.com", - }, - }; - expect(validateWellKnownAuthentication(wk)).toEqual({ + expect(validateWellKnownAuthentication(wk[M_AUTHENTICATION.stable!])).toEqual({ issuer: "test.com", - account: "account.com", }); }); }); @@ -129,6 +121,7 @@ describe("validateOIDCIssuerWellKnown", () => { authorization_endpoint: "https://test.org/authorize", token_endpoint: "https://authorize.org/token", registration_endpoint: "https://authorize.org/regsiter", + revocation_endpoint: "https://authorize.org/regsiter", response_types_supported: ["code"], grant_types_supported: ["authorization_code"], code_challenge_methods_supported: ["S256"], diff --git a/src/autodiscovery.ts b/src/autodiscovery.ts index f9cf0398c2b..b7a16f10702 100644 --- a/src/autodiscovery.ts +++ b/src/autodiscovery.ts @@ -15,10 +15,18 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { SigningKey } from "oidc-client-ts"; + import { IClientWellKnown, IWellKnownConfig, IDelegatedAuthConfig, IServerVersions, M_AUTHENTICATION } from "./client"; import { logger } from "./logger"; import { MatrixError, Method, timeoutSignal } from "./http-api"; -import { ValidatedIssuerConfig, validateOIDCIssuerWellKnown, validateWellKnownAuthentication } from "./oidc/validate"; +import { discoverAndValidateAuthenticationConfig } from "./oidc/discovery"; +import { + ValidatedIssuerConfig, + ValidatedIssuerMetadata, + validateOIDCIssuerWellKnown, + validateWellKnownAuthentication, +} from "./oidc/validate"; import { OidcError } from "./oidc/error"; // Dev note: Auto discovery is part of the spec. @@ -50,12 +58,26 @@ interface AutoDiscoveryState { } interface WellKnownConfig extends Omit, AutoDiscoveryState {} +/** + * @deprecated in favour of OidcClientConfig + */ interface DelegatedAuthConfig extends IDelegatedAuthConfig, ValidatedIssuerConfig, AutoDiscoveryState {} +/** + * @experimental + */ +export interface OidcClientConfig extends IDelegatedAuthConfig, ValidatedIssuerConfig { + metadata: ValidatedIssuerMetadata; + signingKeys?: SigningKey[]; +} + export interface ClientConfig extends Omit { "m.homeserver": WellKnownConfig; "m.identity_server": WellKnownConfig; - "m.authentication"?: DelegatedAuthConfig | AutoDiscoveryState; + /** + * @experimental + */ + "m.authentication"?: (OidcClientConfig & AutoDiscoveryState) | AutoDiscoveryState; } /** @@ -262,7 +284,7 @@ export class AutoDiscovery { } }); - const authConfig = await this.validateDiscoveryAuthenticationConfig(wellknown); + const authConfig = await this.discoverAndValidateAuthenticationConfig(wellknown); clientConfig[M_AUTHENTICATION.stable!] = authConfig; // Step 8: Give the config to the caller (finally) @@ -271,6 +293,7 @@ export class AutoDiscovery { /** * Validate delegated auth configuration + * @deprecated use discoverAndValidateAuthenticationConfig * - m.authentication config is present and valid * - delegated auth issuer openid-configuration is reachable * - delegated auth issuer openid-configuration is configured correctly for us @@ -284,7 +307,8 @@ export class AutoDiscovery { wellKnown: IClientWellKnown, ): Promise { try { - const homeserverAuthenticationConfig = validateWellKnownAuthentication(wellKnown); + const authentication = M_AUTHENTICATION.findIn(wellKnown) || undefined; + const homeserverAuthenticationConfig = validateWellKnownAuthentication(authentication); const issuerOpenIdConfigUrl = `${this.sanitizeWellKnownUrl( homeserverAuthenticationConfig.issuer, @@ -319,6 +343,48 @@ export class AutoDiscovery { } } + /** + * Validate delegated auth configuration + * - m.authentication config is present and valid + * - delegated auth issuer openid-configuration is reachable + * - delegated auth issuer openid-configuration is configured correctly for us + * When successful, validated authentication metadata and optionally signing keys will be returned + * Any errors are caught, and AutoDiscoveryState returned with error + * @param wellKnown - configuration object as returned + * by the .well-known auto-discovery endpoint + * @returns Config or failure result + */ + public static async discoverAndValidateAuthenticationConfig( + wellKnown: IClientWellKnown, + ): Promise<(OidcClientConfig & AutoDiscoveryState) | AutoDiscoveryState> { + try { + const authentication = M_AUTHENTICATION.findIn(wellKnown) || undefined; + const result = await discoverAndValidateAuthenticationConfig(authentication); + + // include this for backwards compatibility + const validatedIssuerConfig = validateOIDCIssuerWellKnown(result.metadata); + + const response = { + state: AutoDiscoveryAction.SUCCESS, + error: null, + ...validatedIssuerConfig, + ...result, + }; + return response; + } catch (error) { + const errorMessage = (error as Error).message as unknown as OidcError; + const errorType = Object.values(OidcError).includes(errorMessage) ? errorMessage : OidcError.General; + + const state = + errorType === OidcError.NotSupported ? AutoDiscoveryAction.IGNORE : AutoDiscoveryAction.FAIL_ERROR; + + return { + state, + error: errorType, + }; + } + } + /** * Attempts to automatically discover client configuration information * prior to logging in. Such information includes the homeserver URL diff --git a/src/oidc/authorize.ts b/src/oidc/authorize.ts index 9b7fc19a47c..8dca760c5cf 100644 --- a/src/oidc/authorize.ts +++ b/src/oidc/authorize.ts @@ -14,13 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { OidcClient, WebStorageStateStore } from "oidc-client-ts"; + import { IDelegatedAuthConfig } from "../client"; import { Method } from "../http-api"; import { subtleCrypto, TextEncoder } from "../crypto/crypto"; import { logger } from "../logger"; import { randomString } from "../randomstring"; import { OidcError } from "./error"; -import { validateIdToken, ValidatedIssuerConfig } from "./validate"; +import { validateIdToken, ValidatedIssuerConfig, ValidatedIssuerMetadata, UserState } from "./validate"; /** * Authorization parameters which are used in the authentication request of an OIDC auth code flow. @@ -35,6 +37,11 @@ export type AuthorizationParams = { nonce: string; }; +/** + * @experimental + * Generate the scope used in authorization request with OIDC OP + * @returns scope + */ const generateScope = (): string => { const deviceId = randomString(10); return `openid urn:matrix:org.matrix.msc2967.client:api:* urn:matrix:org.matrix.msc2967.client:device:${deviceId}`; @@ -74,6 +81,7 @@ export const generateAuthorizationParams = ({ redirectUri }: { redirectUri: stri }); /** + * @deprecated use generateOidcAuthorizationUrl * Generate a URL to attempt authorization with the OP * See https://openid.net/specs/openid-connect-basic-1_0.html#CodeRequest * @param authorizationUrl - endpoint to attempt authorization with the OP @@ -101,6 +109,49 @@ export const generateAuthorizationUrl = async ( return url.toString(); }; +/** + * @experimental + * Generate a URL to attempt authorization with the OP + * See https://openid.net/specs/openid-connect-basic-1_0.html#CodeRequest + * @param oidcClientSettings - oidc configuration + * @param homeserverName - used as state + * @returns a Promise with the url as a string + */ +export const generateOidcAuthorizationUrl = async ({ + metadata, + redirectUri, + clientId, + homeserverUrl, + identityServerUrl, + nonce, +}: { + clientId: string; + metadata: ValidatedIssuerMetadata; + homeserverUrl: string; + identityServerUrl?: string; + redirectUri: string; + nonce: string; +}): Promise => { + const scope = await generateScope(); + const oidcClient = new OidcClient({ + ...metadata, + client_id: clientId, + redirect_uri: redirectUri, + authority: metadata.issuer, + response_mode: "query", + response_type: "code", + scope, + stateStore: new WebStorageStateStore({ prefix: "mx_oidc_", store: window.sessionStorage }), + }); + const userState: UserState = { homeserverUrl, nonce, identityServerUrl }; + const request = await oidcClient.createSigninRequest({ + state: userState, + nonce, + }); + + return request.url; +}; + /** * The expected response type from the token endpoint during authorization code flow * Normalized to always use capitalized 'Bearer' for token_type diff --git a/src/oidc/discovery.ts b/src/oidc/discovery.ts new file mode 100644 index 00000000000..76aaeea8054 --- /dev/null +++ b/src/oidc/discovery.ts @@ -0,0 +1,61 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { MetadataService, OidcClientSettingsStore, SigningKey } from "oidc-client-ts"; + +import { IDelegatedAuthConfig } from "../client"; +import { isValidatedIssuerMetadata, ValidatedIssuerMetadata, validateWellKnownAuthentication } from "./validate"; + +/** + * @experimental + * Discover and validate delegated auth configuration + * - m.authentication config is present and valid + * - delegated auth issuer openid-configuration is reachable + * - delegated auth issuer openid-configuration is configured correctly for us + * When successful, validated metadata is returned + * @param wellKnown - configuration object as returned + * by the .well-known auto-discovery endpoint + * @returns validated authentication metadata and optionally signing keys + * @throws when delegated auth config is invalid or unreachable + */ +export const discoverAndValidateAuthenticationConfig = async ( + authenticationConfig?: IDelegatedAuthConfig, +): Promise< + IDelegatedAuthConfig & { + metadata: ValidatedIssuerMetadata; + signingKeys?: SigningKey[]; + } +> => { + const homeserverAuthenticationConfig = validateWellKnownAuthentication(authenticationConfig); + + // create a temporary settings store so we can use metadata service for discovery + const settings = new OidcClientSettingsStore({ + authority: homeserverAuthenticationConfig.issuer, + redirect_uri: "", // Not known yet, this is here to make the type checker happy + client_id: "", // Not known yet, this is here to make the type checker happy + }); + const metadataService = new MetadataService(settings); + const metadata = await metadataService.getMetadata(); + const signingKeys = (await metadataService.getSigningKeys()) ?? undefined; + + isValidatedIssuerMetadata(metadata); + + return { + ...homeserverAuthenticationConfig, + metadata, + signingKeys, + }; +}; diff --git a/src/oidc/validate.ts b/src/oidc/validate.ts index 8519b2bf118..1db4ba85491 100644 --- a/src/oidc/validate.ts +++ b/src/oidc/validate.ts @@ -15,8 +15,9 @@ limitations under the License. */ import jwtDecode from "jwt-decode"; +import { OidcMetadata } from "oidc-client-ts"; -import { IClientWellKnown, IDelegatedAuthConfig, M_AUTHENTICATION } from "../client"; +import { IDelegatedAuthConfig } from "../client"; import { logger } from "../logger"; import { OidcError } from "./error"; @@ -39,9 +40,7 @@ export type ValidatedIssuerConfig = { * @returns config - when present and valid * @throws when config is not found or invalid */ -export const validateWellKnownAuthentication = (wellKnown: IClientWellKnown): IDelegatedAuthConfig => { - const authentication = M_AUTHENTICATION.findIn(wellKnown); - +export const validateWellKnownAuthentication = (authentication?: IDelegatedAuthConfig): IDelegatedAuthConfig => { if (!authentication) { throw new Error(OidcError.NotSupported); } @@ -101,6 +100,7 @@ export const validateOIDCIssuerWellKnown = (wellKnown: unknown): ValidatedIssuer const isInvalid = [ requiredStringProperty(wellKnown, "authorization_endpoint"), requiredStringProperty(wellKnown, "token_endpoint"), + requiredStringProperty(wellKnown, "revocation_endpoint"), optionalStringProperty(wellKnown, "registration_endpoint"), requiredArrayValue(wellKnown, "response_types_supported", "code"), requiredArrayValue(wellKnown, "grant_types_supported", "authorization_code"), @@ -119,6 +119,36 @@ export const validateOIDCIssuerWellKnown = (wellKnown: unknown): ValidatedIssuer throw new Error(OidcError.OpSupport); }; +/** + * Metadata from OIDC authority discovery + * With validated properties required in type + */ +export type ValidatedIssuerMetadata = Partial & + Pick< + OidcMetadata, + | "issuer" + | "authorization_endpoint" + | "token_endpoint" + | "registration_endpoint" + | "revocation_endpoint" + | "response_types_supported" + | "grant_types_supported" + | "code_challenge_methods_supported" + >; + +/** + * Wraps validateOIDCIssuerWellKnown in a type assertion + * that asserts expected properties are present + * (Typescript assertions cannot be arrow functions) + * @param metadata - issuer openid-configuration response + * @throws when metadata validation fails + */ +export function isValidatedIssuerMetadata( + metadata: Partial, +): asserts metadata is ValidatedIssuerMetadata { + validateOIDCIssuerWellKnown(metadata); +} + /** * Standard JWT claims. * @@ -199,3 +229,19 @@ export const validateIdToken = (idToken: string | undefined, issuer: string, cli throw new Error(OidcError.InvalidIdToken); } }; + +/** + * State we ask OidcClient to store when starting oidc authorization flow (in `generateOidcAuthorizationUrl`) + * so that we can access it on return from the OP and complete login + */ +export type UserState = { + /** + * Remember which server we were trying to login to + */ + homeserverUrl: string; + identityServerUrl?: string; + /** + * Used to validate id token + */ + nonce: string; +}; diff --git a/yarn.lock b/yarn.lock index f7f8239fe02..677a631df3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3115,6 +3115,11 @@ crypto-browserify@^3.0.0: randombytes "^2.0.0" randomfill "^1.0.3" +crypto-js@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" + integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== + cssom@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" @@ -5920,6 +5925,14 @@ object.values@^1.1.6: define-properties "^1.1.4" es-abstract "^1.20.4" +oidc-client-ts@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/oidc-client-ts/-/oidc-client-ts-2.2.4.tgz#7d86b5efe2248f3637a6f3a0ee1af86764aea125" + integrity sha512-nOZwIomju+AmXObl5Oq5PjrES/qTt8bLsENJCIydVgi9TEWk7SCkOU6X3RNkY7yfySRM1OJJvDKdREZdmnDT2g== + dependencies: + crypto-js "^4.1.1" + jwt-decode "^3.1.2" + once@^1.3.0, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" From 4990bf5ca068d8f8cd8566aced30b273a5376459 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 09:24:08 +0100 Subject: [PATCH 05/59] Bump tough-cookie from 4.1.2 to 4.1.3 (#3560) Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 4.1.2 to 4.1.3. - [Release notes](https://github.com/salesforce/tough-cookie/releases) - [Changelog](https://github.com/salesforce/tough-cookie/blob/master/CHANGELOG.md) - [Commits](https://github.com/salesforce/tough-cookie/compare/v4.1.2...v4.1.3) --- updated-dependencies: - dependency-name: tough-cookie dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 677a631df3f..b4b4b820dd6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7324,9 +7324,9 @@ token-stream@0.0.1: integrity sha512-nfjOAu/zAWmX9tgwi5NRp7O7zTDUD1miHiB40klUnAh9qnL1iXdgzcz/i5dMaL5jahcBAaSfmNOBBJBLJW8TEg== tough-cookie@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" - integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== dependencies: psl "^1.1.33" punycode "^2.1.1" From b5b86bf1b56d91fba922c3775b8b430961725027 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 10 Jul 2023 11:04:38 +0100 Subject: [PATCH 06/59] Fix `TypedEventEmitter::removeAllListeners(void)` not working (#3561) --- src/models/typed-event-emitter.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/models/typed-event-emitter.ts b/src/models/typed-event-emitter.ts index de0dd2b8696..3b0be7066ff 100644 --- a/src/models/typed-event-emitter.ts +++ b/src/models/typed-event-emitter.ts @@ -217,6 +217,10 @@ export class TypedEventEmitter< * @returns a reference to the `EventEmitter`, so that calls can be chained. */ public removeAllListeners(event?: Events | EventEmitterEvents): this { + // EventEmitter::removeAllListeners uses `arguments.length` to determine undefined case + if (event === undefined) { + return super.removeAllListeners(); + } return super.removeAllListeners(event); } From 2751e191d3cd225c92af8e5b0ec8a5994e00d3e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 10:08:16 +0000 Subject: [PATCH 07/59] Lock file maintenance (#3392) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 2644 ++++++++++++++++++++++++++--------------------------- 1 file changed, 1307 insertions(+), 1337 deletions(-) diff --git a/yarn.lock b/yarn.lock index b4b4b820dd6..be55c1d52ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + "@actions/core@^1.4.0": version "1.10.0" resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.10.0.tgz#44551c3c71163949a2f06e94d9ca2157a0cfac4f" @@ -36,9 +41,9 @@ "@jridgewell/trace-mapping" "^0.3.9" "@babel/cli@^7.12.10": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.21.5.tgz#a685a5b50b785f2edfbf6e042c1265c653547d9d" - integrity sha512-TOKytQ9uQW9c4np8F+P7ZfPINy5Kv+pizDIUwSVH8X5zHgYHV4AA8HE5LA450xXeu4jEfmUckTYvv1I4S26M/g== + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.22.6.tgz#63f5be2a0abd587ccfbdc93424fa85f43142cc53" + integrity sha512-Be3/RfEDmkMRGT1+ru5nTkfcvWz5jDOYg1V9rXqTz2u9Qt96O1ryboGvxVBp7wOnYWDB8DNHIWb6DThrpudfOw== dependencies: "@jridgewell/trace-mapping" "^0.3.17" commander "^4.0.1" @@ -51,304 +56,293 @@ "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents.3" chokidar "^3.4.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" - integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" + integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== dependencies: - "@babel/highlight" "^7.18.6" + "@babel/highlight" "^7.22.5" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.21.5": - version "7.21.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.7.tgz#61caffb60776e49a57ba61a88f02bedd8714f6bc" - integrity sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA== +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.6.tgz#15606a20341de59ba02cd2fcc5086fcbe73bf544" + integrity sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg== "@babel/core@^7.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.7.5": - version "7.21.8" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.8.tgz#2a8c7f0f53d60100ba4c32470ba0281c92aa9aa4" - integrity sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ== + version "7.22.8" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.8.tgz#386470abe884302db9c82e8e5e87be9e46c86785" + integrity sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.21.5" - "@babel/helper-compilation-targets" "^7.21.5" - "@babel/helper-module-transforms" "^7.21.5" - "@babel/helpers" "^7.21.5" - "@babel/parser" "^7.21.8" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.5" - "@babel/types" "^7.21.5" + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.7" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helpers" "^7.22.6" + "@babel/parser" "^7.22.7" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.8" + "@babel/types" "^7.22.5" + "@nicolo-ribaudo/semver-v6" "^6.3.3" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.2" - semver "^6.3.0" "@babel/eslint-parser@^7.12.10": - version "7.21.8" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz#59fb6fc4f3b017ab86987c076226ceef7b2b2ef2" - integrity sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ== + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.22.7.tgz#d2807fbd1fa4376162716da63dfd3c69a2249fed" + integrity sha512-LH6HJqjOyu/Qtp7LuSycZXK/CYXQ4ohdkliEaL1QTdtOXVdOVpTBKVxAo/+eeyt+x/2SRzB+zUPduVl+xiEvdg== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" + "@nicolo-ribaudo/semver-v6" "^6.3.3" eslint-visitor-keys "^2.1.0" - semver "^6.3.0" "@babel/eslint-plugin@^7.12.10": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/eslint-plugin/-/eslint-plugin-7.19.1.tgz#8bfde4b6e4380ea038e7947a765fe536c3057a4c" - integrity sha512-ElGPkQPapKMa3zVqXHkZYzuL7I5LbRw9UWBUArgWsdWDDb9XcACqOpBib5tRPA9XvbVZYrFUkoQPbiJ4BFvu4w== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/eslint-plugin/-/eslint-plugin-7.22.5.tgz#47407d8c9e527b62ff75ee11e4baa6de3da7cf0e" + integrity sha512-lDXW06rf1sXywWWw+UdS/iYxRjrqhH4AXdPeKE4+fEgEoGBXcdIDQ+uCJOUcvCb0jCTvfwHOSXkwnfd24EAkLQ== dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.12.11", "@babel/generator@^7.21.5", "@babel/generator@^7.7.2": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.5.tgz#c0c0e5449504c7b7de8236d99338c3e2a340745f" - integrity sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w== +"@babel/generator@^7.12.11", "@babel/generator@^7.22.7", "@babel/generator@^7.7.2": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.7.tgz#a6b8152d5a621893f2c9dacf9a4e286d520633d5" + integrity sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ== dependencies: - "@babel/types" "^7.21.5" + "@babel/types" "^7.22.5" "@jridgewell/gen-mapping" "^0.3.2" "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" - integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.22.5" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.21.5.tgz#817f73b6c59726ab39f6ba18c234268a519e5abb" - integrity sha512-uNrjKztPLkUk7bpCNC0jEKDJzzkvel/W+HguzbN8krA+LPfC1CEobJEvAvGka2A/M+ViOqXdcRL0GqPUJSjx9g== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz#a3f4758efdd0190d8927fcffd261755937c71878" + integrity sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw== dependencies: - "@babel/types" "^7.21.5" + "@babel/types" "^7.22.5" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz#631e6cc784c7b660417421349aac304c94115366" - integrity sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w== +"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz#e30d61abe9480aa5a83232eb31c111be922d2e52" + integrity sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA== dependencies: - "@babel/compat-data" "^7.21.5" - "@babel/helper-validator-option" "^7.21.0" - browserslist "^4.21.3" + "@babel/compat-data" "^7.22.6" + "@babel/helper-validator-option" "^7.22.5" + "@nicolo-ribaudo/semver-v6" "^6.3.3" + browserslist "^4.21.9" lru-cache "^5.1.1" - semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0": - version "7.21.8" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.8.tgz#205b26330258625ef8869672ebca1e0dee5a0f02" - integrity sha512-+THiN8MqiH2AczyuZrnrKL6cAxFRRQDKW9h1YkBvbgKmAm6mwiacig1qT73DHIWMGo40GRnsEfN3LA+E6NtmSw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.21.5" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-member-expression-to-functions" "^7.21.5" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.21.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/helper-split-export-declaration" "^7.18.6" - semver "^6.3.0" - -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5": - version "7.21.8" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.8.tgz#a7886f61c2e29e21fd4aaeaf1e473deba6b571dc" - integrity sha512-zGuSdedkFtsFHGbexAvNuipg1hbtitDLo2XE8/uf6Y9sOQV1xsYX/2pNbtedp/X0eU1pIt+kGvaqHCowkRbS5g== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.5": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.6.tgz#58564873c889a6fea05a538e23f9f6d201f10950" + integrity sha512-iwdzgtSiBxF6ni6mzVnZCF3xt5qE6cEA0J7nFt8QOAWZ0zjCFceEgpn3vtb2V7WFR6QzP2jmIFOHMTRo7eNJjQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@nicolo-ribaudo/semver-v6" "^6.3.3" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.6.tgz#87afd63012688ad792de430ceb3b6dc28e4e7a40" + integrity sha512-nBookhLKxAWo/TUCmhnaEJyLz2dekjQvv5SRpE9epWQBcpedWLKt8aZdsuT9XV5ovzR3fENLjRXVT0GsSlGGhA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@nicolo-ribaudo/semver-v6" "^6.3.3" regexpu-core "^5.3.1" - semver "^6.3.0" -"@babel/helper-define-polyfill-provider@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" - integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== +"@babel/helper-define-polyfill-provider@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.1.tgz#af1429c4a83ac316a6a8c2cc8ff45cb5d2998d3a" + integrity sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A== dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" debug "^4.1.1" lodash.debounce "^4.0.8" resolve "^1.14.2" - semver "^6.1.2" - -"@babel/helper-environment-visitor@^7.18.9", "@babel/helper-environment-visitor@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz#c769afefd41d171836f7cb63e295bedf689d48ba" - integrity sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ== - -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0", "@babel/helper-function-name@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" - integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== - dependencies: - "@babel/template" "^7.20.7" - "@babel/types" "^7.21.0" - -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-member-expression-to-functions@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.5.tgz#3b1a009af932e586af77c1030fba9ee0bde396c0" - integrity sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg== - dependencies: - "@babel/types" "^7.21.5" - -"@babel/helper-module-imports@^7.18.6", "@babel/helper-module-imports@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz#ac88b2f76093637489e718a90cec6cf8a9b029af" - integrity sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg== - dependencies: - "@babel/types" "^7.21.4" -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz#d937c82e9af68d31ab49039136a222b17ac0b420" - integrity sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw== - dependencies: - "@babel/helper-environment-visitor" "^7.21.5" - "@babel/helper-module-imports" "^7.21.4" - "@babel/helper-simple-access" "^7.21.5" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.5" - "@babel/types" "^7.21.5" - -"@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" - integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.21.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz#345f2377d05a720a4e5ecfa39cbf4474a4daed56" - integrity sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg== - -"@babel/helper-remap-async-to-generator@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" - integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-wrap-function" "^7.18.9" - "@babel/types" "^7.18.9" - -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7", "@babel/helper-replace-supers@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.21.5.tgz#a6ad005ba1c7d9bc2973dfde05a1bba7065dde3c" - integrity sha512-/y7vBgsr9Idu4M6MprbOVUfH3vs7tsIfnVWv/Ml2xgwvyH6LTngdfbf5AdsKwkJy4zgy1X/kuNrEKvhhK28Yrg== - dependencies: - "@babel/helper-environment-visitor" "^7.21.5" - "@babel/helper-member-expression-to-functions" "^7.21.5" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.5" - "@babel/types" "^7.21.5" - -"@babel/helper-simple-access@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz#d697a7971a5c39eac32c7e63c0921c06c8a249ee" - integrity sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg== - dependencies: - "@babel/types" "^7.21.5" - -"@babel/helper-skip-transparent-expression-wrappers@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" - integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== - dependencies: - "@babel/types" "^7.20.0" - -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-string-parser@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz#2b3eea65443c6bdc31c22d037c65f6d323b6b2bd" - integrity sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w== - -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/helper-validator-option@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" - integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== - -"@babel/helper-wrap-function@^7.18.9": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz#75e2d84d499a0ab3b31c33bcfe59d6b8a45f62e3" - integrity sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q== - dependencies: - "@babel/helper-function-name" "^7.19.0" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.5" - "@babel/types" "^7.20.5" - -"@babel/helpers@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.5.tgz#5bac66e084d7a4d2d9696bdf0175a93f7fb63c08" - integrity sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA== - dependencies: - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.5" - "@babel/types" "^7.21.5" - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== + +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== + dependencies: + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-member-expression-to-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz#0a7c56117cad3372fbf8d2fb4bf8f8d64a1e76b2" + integrity sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-transforms@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz#0f65daa0716961b6e96b164034e737f60a80d2ef" + integrity sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-remap-async-to-generator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz#14a38141a7bf2165ad38da61d61cf27b43015da2" + integrity sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-wrap-function" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-replace-supers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz#71bc5fb348856dea9fdc4eafd7e2e49f585145dc" + integrity sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.5", "@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.19.1", "@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helper-wrap-function@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz#44d205af19ed8d872b4eefb0d2fa65f45eb34f06" + integrity sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helpers@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.6.tgz#8e61d3395a4f0c5a8060f309fb008200969b5ecd" + integrity sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.6" + "@babel/types" "^7.22.5" + +"@babel/highlight@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" + integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.2.3", "@babel/parser@^7.20.7", "@babel/parser@^7.21.5", "@babel/parser@^7.21.8": - version "7.21.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.8.tgz#642af7d0333eab9c0ad70b14ac5e76dbde7bfdf8" - integrity sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA== - -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" - integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.2.3", "@babel/parser@^7.20.7", "@babel/parser@^7.22.5", "@babel/parser@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" + integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz#d9c85589258539a22a901033853101a6198d4ef1" - integrity sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e" + integrity sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/plugin-proposal-optional-chaining" "^7.20.7" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-proposal-async-generator-functions@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz#bfb7276d2d573cb67ba379984a2334e262ba5326" - integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz#fef09f9499b1f1c930da8a0c419db42167d792ca" + integrity sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-remap-async-to-generator" "^7.18.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.5" -"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.18.6": +"@babel/plugin-proposal-class-properties@^7.12.1": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== @@ -356,56 +350,7 @@ "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-class-static-block@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz#77bdd66fb7b605f3a61302d224bdfacf5547977d" - integrity sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-proposal-dynamic-import@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" - integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" - integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-json-strings@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" - integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz#dfbcaa8f7b4d37b51e8bfb46d94a5aea2bb89d83" - integrity sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" - integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-proposal-numeric-separator@^7.12.7", "@babel/plugin-proposal-numeric-separator@^7.18.6": +"@babel/plugin-proposal-numeric-separator@^7.12.7": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== @@ -413,7 +358,7 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.20.7": +"@babel/plugin-proposal-object-rest-spread@^7.12.1": version "7.20.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== @@ -424,42 +369,12 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.20.7" -"@babel/plugin-proposal-optional-catch-binding@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" - integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.20.7", "@babel/plugin-proposal-optional-chaining@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" - integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-proposal-private-methods@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" - integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== -"@babel/plugin-proposal-private-property-in-object@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz#19496bd9883dd83c23c7d7fc45dcd9ad02dfa1dc" - integrity sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": +"@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== @@ -509,12 +424,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-import-assertions@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4" - integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== +"@babel/plugin-syntax-import-assertions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz#07d252e2aa0bc6125567f742cd58619cb14dce98" + integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-attributes@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz#ab840248d834410b829f569f5262b9e517555ecb" + integrity sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-import-meta@^7.10.4", "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" @@ -530,12 +452,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.21.4", "@babel/plugin-syntax-jsx@^7.7.2": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz#f264ed7bf40ffc9ec239edabc17a50c4f5b6fea2" - integrity sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ== +"@babel/plugin-syntax-jsx@^7.22.5", "@babel/plugin-syntax-jsx@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" + integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" @@ -593,318 +515,450 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.20.0", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz#2751948e9b7c6d771a8efa59340c15d4a2891ff8" - integrity sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA== +"@babel/plugin-syntax-typescript@^7.22.5", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" + integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-arrow-functions@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.21.5.tgz#9bb42a53de447936a57ba256fbf537fc312b6929" - integrity sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA== +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== dependencies: - "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-async-to-generator@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz#dfee18623c8cb31deb796aa3ca84dda9cea94354" - integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q== +"@babel/plugin-transform-arrow-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" + integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-remap-async-to-generator" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-block-scoped-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" - integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== +"@babel/plugin-transform-async-generator-functions@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.7.tgz#053e76c0a903b72b573cb1ab7d6882174d460a1b" + integrity sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" + "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-transform-block-scoping@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz#e737b91037e5186ee16b76e7ae093358a5634f02" - integrity sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ== +"@babel/plugin-transform-async-to-generator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" + integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" -"@babel/plugin-transform-classes@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz#f469d0b07a4c5a7dbb21afad9e27e57b47031665" - integrity sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ== +"@babel/plugin-transform-block-scoped-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" + integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-block-scoping@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz#8bfc793b3a4b2742c0983fadc1480d843ecea31b" + integrity sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz#97a56e31ad8c9dc06a0b3710ce7803d5a48cca77" + integrity sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-static-block@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz#3e40c46f048403472d6f4183116d5e46b1bff5ba" + integrity sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-transform-classes@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz#e04d7d804ed5b8501311293d1a0e6d43e94c3363" + integrity sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.21.5.tgz#3a2d8bb771cd2ef1cd736435f6552fe502e11b44" - integrity sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q== +"@babel/plugin-transform-computed-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" + integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== dependencies: - "@babel/helper-plugin-utils" "^7.21.5" - "@babel/template" "^7.20.7" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.5" -"@babel/plugin-transform-destructuring@^7.21.3": - version "7.21.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz#73b46d0fd11cd6ef57dea8a381b1215f4959d401" - integrity sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA== +"@babel/plugin-transform-destructuring@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz#d3aca7438f6c26c78cdd0b0ba920a336001b27cc" + integrity sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" - integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== +"@babel/plugin-transform-dotall-regex@^7.22.5", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz#dbb4f0e45766eb544e193fb00e65a1dd3b2a4165" + integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-duplicate-keys@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" - integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== +"@babel/plugin-transform-duplicate-keys@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285" + integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-exponentiation-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" - integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== +"@babel/plugin-transform-dynamic-import@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz#d6908a8916a810468c4edff73b5b75bda6ad393e" + integrity sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-transform-exponentiation-operator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" + integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-for-of@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.5.tgz#e890032b535f5a2e237a18535f56a9fdaa7b83fc" - integrity sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ== +"@babel/plugin-transform-export-namespace-from@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz#57c41cb1d0613d22f548fddd8b288eedb9973a5b" + integrity sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg== dependencies: - "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-transform-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" - integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== +"@babel/plugin-transform-for-of@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz#ab1b8a200a8f990137aff9a084f8de4099ab173f" + integrity sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A== dependencies: - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" - integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== +"@babel/plugin-transform-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" + integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-member-expression-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" - integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== +"@babel/plugin-transform-json-strings@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz#14b64352fdf7e1f737eed68de1a1468bd2a77ec0" + integrity sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-transform-modules-amd@^7.20.11": - version "7.20.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz#3daccca8e4cc309f03c3a0c4b41dc4b26f55214a" - integrity sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g== +"@babel/plugin-transform-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" + integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== dependencies: - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-commonjs@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.5.tgz#d69fb947eed51af91de82e4708f676864e5e47bc" - integrity sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ== +"@babel/plugin-transform-logical-assignment-operators@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz#66ae5f068fd5a9a5dc570df16f56c2a8462a9d6c" + integrity sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA== dependencies: - "@babel/helper-module-transforms" "^7.21.5" - "@babel/helper-plugin-utils" "^7.21.5" - "@babel/helper-simple-access" "^7.21.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-transform-modules-systemjs@^7.20.11": - version "7.20.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz#467ec6bba6b6a50634eea61c9c232654d8a4696e" - integrity sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw== +"@babel/plugin-transform-member-expression-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" + integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== dependencies: - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-umd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" - integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== +"@babel/plugin-transform-modules-amd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz#4e045f55dcf98afd00f85691a68fc0780704f526" + integrity sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-named-capturing-groups-regex@^7.20.5": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz#626298dd62ea51d452c3be58b285d23195ba69a8" - integrity sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA== +"@babel/plugin-transform-modules-commonjs@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz#7d9875908d19b8c0536085af7b053fd5bd651bfa" + integrity sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.20.5" - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" -"@babel/plugin-transform-new-target@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" - integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== +"@babel/plugin-transform-modules-systemjs@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz#18c31410b5e579a0092638f95c896c2a98a5d496" + integrity sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" -"@babel/plugin-transform-object-super@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" - integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== +"@babel/plugin-transform-modules-umd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz#4694ae40a87b1745e3775b6a7fe96400315d4f98" + integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.6" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.21.3": - version "7.21.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz#18fc4e797cf6d6d972cb8c411dbe8a809fa157db" - integrity sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ== +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-property-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" - integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== +"@babel/plugin-transform-new-target@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz#1b248acea54ce44ea06dfd37247ba089fcf9758d" + integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz#f8872c65776e0b552e0849d7596cddd416c3e381" + integrity sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-transform-numeric-separator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz#57226a2ed9e512b9b446517ab6fa2d17abb83f58" + integrity sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-transform-object-rest-spread@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz#9686dc3447df4753b0b2a2fae7e8bc33cdc1f2e1" + integrity sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ== + dependencies: + "@babel/compat-data" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.22.5" + +"@babel/plugin-transform-object-super@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" + integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + +"@babel/plugin-transform-optional-catch-binding@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz#842080be3076703be0eaf32ead6ac8174edee333" + integrity sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-transform-optional-chaining@^7.22.5", "@babel/plugin-transform-optional-chaining@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz#4bacfe37001fe1901117672875e931d439811564" + integrity sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz#c3542dd3c39b42c8069936e48717a8d179d63a18" + integrity sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-methods@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" + integrity sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-property-in-object@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz#07a77f28cbb251546a43d175a1dda4cf3ef83e32" + integrity sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" + integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-regenerator@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz#576c62f9923f94bcb1c855adc53561fd7913724e" - integrity sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w== +"@babel/plugin-transform-regenerator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz#cd8a68b228a5f75fa01420e8cc2fc400f0fc32aa" + integrity sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw== dependencies: - "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-plugin-utils" "^7.22.5" regenerator-transform "^0.15.1" -"@babel/plugin-transform-reserved-words@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" - integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== +"@babel/plugin-transform-reserved-words@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz#832cd35b81c287c4bcd09ce03e22199641f964fb" + integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-runtime@^7.12.10": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.4.tgz#2e1da21ca597a7d01fc96b699b21d8d2023191aa" - integrity sha512-1J4dhrw1h1PqnNNpzwxQ2UBymJUF8KuPjAAnlLwZcGhHAIqUigFW7cdK6GHoB64ubY4qXQNYknoUeks4Wz7CUA== + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.7.tgz#eb9094b5fb756cc2d98d398b2c88aeefa9205de9" + integrity sha512-o02xM7iY7mSPI+TvaYDH0aYl+lg3+KT7qrD705JlsB/GrZSNaYO/4i+aDFKPiJ7ubq3hgv8NNLCdyB5MFxT8mg== dependencies: - "@babel/helper-module-imports" "^7.21.4" - "@babel/helper-plugin-utils" "^7.20.2" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - semver "^6.3.0" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@nicolo-ribaudo/semver-v6" "^6.3.3" + babel-plugin-polyfill-corejs2 "^0.4.4" + babel-plugin-polyfill-corejs3 "^0.8.2" + babel-plugin-polyfill-regenerator "^0.5.1" -"@babel/plugin-transform-shorthand-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" - integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== +"@babel/plugin-transform-shorthand-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" + integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-spread@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz#c2d83e0b99d3bf83e07b11995ee24bf7ca09401e" - integrity sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw== +"@babel/plugin-transform-spread@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" + integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" -"@babel/plugin-transform-sticky-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" - integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== +"@babel/plugin-transform-sticky-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" + integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-template-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" - integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== +"@babel/plugin-transform-template-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" + integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-typeof-symbol@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" - integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== +"@babel/plugin-transform-typeof-symbol@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz#5e2ba478da4b603af8673ff7c54f75a97b716b34" + integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-typescript@^7.21.3": - version "7.21.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.3.tgz#316c5be579856ea890a57ebc5116c5d064658f2b" - integrity sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw== +"@babel/plugin-transform-typescript@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.5.tgz#5c0f7adfc1b5f38c4dbc8f79b1f0f8074134bd7d" + integrity sha512-SMubA9S7Cb5sGSFFUlqxyClTA9zWJ8qGQrppNUm05LtFuN1ELRFNndkix4zUJrC9F+YivWwa1dHMSyo0e0N9dA== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-typescript" "^7.20.0" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.22.5" -"@babel/plugin-transform-unicode-escapes@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.21.5.tgz#1e55ed6195259b0e9061d81f5ef45a9b009fb7f2" - integrity sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg== +"@babel/plugin-transform-unicode-escapes@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz#ce0c248522b1cb22c7c992d88301a5ead70e806c" + integrity sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg== dependencies: - "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-unicode-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" - integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== +"@babel/plugin-transform-unicode-property-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz#098898f74d5c1e86660dc112057b2d11227f1c81" + integrity sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" + integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-sets-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz#77788060e511b708ffc7d42fdfbc5b37c3004e91" + integrity sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/preset-env@^7.12.11": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.21.5.tgz#db2089d99efd2297716f018aeead815ac3decffb" - integrity sha512-wH00QnTTldTbf/IefEVyChtRdw5RJvODT/Vb4Vcxq1AZvtXj6T0YeX0cAcXhI6/BdGuiP3GcNIL4OQbI2DVNxg== - dependencies: - "@babel/compat-data" "^7.21.5" - "@babel/helper-compilation-targets" "^7.21.5" - "@babel/helper-plugin-utils" "^7.21.5" - "@babel/helper-validator-option" "^7.21.0" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.20.7" - "@babel/plugin-proposal-async-generator-functions" "^7.20.7" - "@babel/plugin-proposal-class-properties" "^7.18.6" - "@babel/plugin-proposal-class-static-block" "^7.21.0" - "@babel/plugin-proposal-dynamic-import" "^7.18.6" - "@babel/plugin-proposal-export-namespace-from" "^7.18.9" - "@babel/plugin-proposal-json-strings" "^7.18.6" - "@babel/plugin-proposal-logical-assignment-operators" "^7.20.7" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" - "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.20.7" - "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" - "@babel/plugin-proposal-optional-chaining" "^7.21.0" - "@babel/plugin-proposal-private-methods" "^7.18.6" - "@babel/plugin-proposal-private-property-in-object" "^7.21.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.7.tgz#a1ef34b64a80653c22ce4d9c25603cfa76fc168a" + integrity sha512-1whfDtW+CzhETuzYXfcgZAh8/GFMeEbz0V5dVgya8YeJyCU6Y/P2Gnx4Qb3MylK68Zu9UiwUvbPMPTpFAOJ+sQ== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.5" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.5" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.20.0" + "@babel/plugin-syntax-import-assertions" "^7.22.5" + "@babel/plugin-syntax-import-attributes" "^7.22.5" "@babel/plugin-syntax-import-meta" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" @@ -915,45 +969,62 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.21.5" - "@babel/plugin-transform-async-to-generator" "^7.20.7" - "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.21.0" - "@babel/plugin-transform-classes" "^7.21.0" - "@babel/plugin-transform-computed-properties" "^7.21.5" - "@babel/plugin-transform-destructuring" "^7.21.3" - "@babel/plugin-transform-dotall-regex" "^7.18.6" - "@babel/plugin-transform-duplicate-keys" "^7.18.9" - "@babel/plugin-transform-exponentiation-operator" "^7.18.6" - "@babel/plugin-transform-for-of" "^7.21.5" - "@babel/plugin-transform-function-name" "^7.18.9" - "@babel/plugin-transform-literals" "^7.18.9" - "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.20.11" - "@babel/plugin-transform-modules-commonjs" "^7.21.5" - "@babel/plugin-transform-modules-systemjs" "^7.20.11" - "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.20.5" - "@babel/plugin-transform-new-target" "^7.18.6" - "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.21.3" - "@babel/plugin-transform-property-literals" "^7.18.6" - "@babel/plugin-transform-regenerator" "^7.21.5" - "@babel/plugin-transform-reserved-words" "^7.18.6" - "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.20.7" - "@babel/plugin-transform-sticky-regex" "^7.18.6" - "@babel/plugin-transform-template-literals" "^7.18.9" - "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.21.5" - "@babel/plugin-transform-unicode-regex" "^7.18.6" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.22.5" + "@babel/plugin-transform-async-generator-functions" "^7.22.7" + "@babel/plugin-transform-async-to-generator" "^7.22.5" + "@babel/plugin-transform-block-scoped-functions" "^7.22.5" + "@babel/plugin-transform-block-scoping" "^7.22.5" + "@babel/plugin-transform-class-properties" "^7.22.5" + "@babel/plugin-transform-class-static-block" "^7.22.5" + "@babel/plugin-transform-classes" "^7.22.6" + "@babel/plugin-transform-computed-properties" "^7.22.5" + "@babel/plugin-transform-destructuring" "^7.22.5" + "@babel/plugin-transform-dotall-regex" "^7.22.5" + "@babel/plugin-transform-duplicate-keys" "^7.22.5" + "@babel/plugin-transform-dynamic-import" "^7.22.5" + "@babel/plugin-transform-exponentiation-operator" "^7.22.5" + "@babel/plugin-transform-export-namespace-from" "^7.22.5" + "@babel/plugin-transform-for-of" "^7.22.5" + "@babel/plugin-transform-function-name" "^7.22.5" + "@babel/plugin-transform-json-strings" "^7.22.5" + "@babel/plugin-transform-literals" "^7.22.5" + "@babel/plugin-transform-logical-assignment-operators" "^7.22.5" + "@babel/plugin-transform-member-expression-literals" "^7.22.5" + "@babel/plugin-transform-modules-amd" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.22.5" + "@babel/plugin-transform-modules-systemjs" "^7.22.5" + "@babel/plugin-transform-modules-umd" "^7.22.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.22.5" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.5" + "@babel/plugin-transform-numeric-separator" "^7.22.5" + "@babel/plugin-transform-object-rest-spread" "^7.22.5" + "@babel/plugin-transform-object-super" "^7.22.5" + "@babel/plugin-transform-optional-catch-binding" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.6" + "@babel/plugin-transform-parameters" "^7.22.5" + "@babel/plugin-transform-private-methods" "^7.22.5" + "@babel/plugin-transform-private-property-in-object" "^7.22.5" + "@babel/plugin-transform-property-literals" "^7.22.5" + "@babel/plugin-transform-regenerator" "^7.22.5" + "@babel/plugin-transform-reserved-words" "^7.22.5" + "@babel/plugin-transform-shorthand-properties" "^7.22.5" + "@babel/plugin-transform-spread" "^7.22.5" + "@babel/plugin-transform-sticky-regex" "^7.22.5" + "@babel/plugin-transform-template-literals" "^7.22.5" + "@babel/plugin-transform-typeof-symbol" "^7.22.5" + "@babel/plugin-transform-unicode-escapes" "^7.22.5" + "@babel/plugin-transform-unicode-property-regex" "^7.22.5" + "@babel/plugin-transform-unicode-regex" "^7.22.5" + "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.21.5" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - core-js-compat "^3.25.1" - semver "^6.3.0" + "@babel/types" "^7.22.5" + "@nicolo-ribaudo/semver-v6" "^6.3.3" + babel-plugin-polyfill-corejs2 "^0.4.4" + babel-plugin-polyfill-corejs3 "^0.8.2" + babel-plugin-polyfill-regenerator "^0.5.1" + core-js-compat "^3.31.0" "@babel/preset-modules@^0.1.5": version "0.1.5" @@ -967,20 +1038,20 @@ esutils "^2.0.2" "@babel/preset-typescript@^7.12.7": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.21.5.tgz#68292c884b0e26070b4d66b202072d391358395f" - integrity sha512-iqe3sETat5EOrORXiQ6rWfoOg2y68Cs75B9wNxdPW4kixJxh7aXQE1KPdWLDniC24T/6dSnguF33W9j/ZZQcmA== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.22.5.tgz#16367d8b01d640e9a507577ed4ee54e0101e51c8" + integrity sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ== dependencies: - "@babel/helper-plugin-utils" "^7.21.5" - "@babel/helper-validator-option" "^7.21.0" - "@babel/plugin-syntax-jsx" "^7.21.4" - "@babel/plugin-transform-modules-commonjs" "^7.21.5" - "@babel/plugin-transform-typescript" "^7.21.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.22.5" + "@babel/plugin-transform-typescript" "^7.22.5" "@babel/register@^7.12.10": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.21.0.tgz#c97bf56c2472e063774f31d344c592ebdcefa132" - integrity sha512-9nKsPmYDi5DidAqJaQooxIhsLJiNMkGr8ypQ8Uic7cIox7UCDsM7HuUGxdGT7mSDTYbqzIdsOWzfBton/YJrMw== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.5.tgz#e4d8d0f615ea3233a27b5c6ada6750ee59559939" + integrity sha512-vV6pm/4CijSQ8Y47RH5SopXzursN35RQINfGJkmOlcpAtGuf94miFvIPhCKGQN7WGIcsgG1BHEX2KVdTYwTwUQ== dependencies: clone-deep "^4.0.1" find-cache-dir "^2.0.0" @@ -994,44 +1065,44 @@ integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== "@babel/runtime@^7.0.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" - integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" + integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== dependencies: regenerator-runtime "^0.13.11" -"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.3.3": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" - integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - -"@babel/traverse@^7.1.6", "@babel/traverse@^7.20.5", "@babel/traverse@^7.21.5", "@babel/traverse@^7.7.2": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.5.tgz#ad22361d352a5154b498299d523cf72998a4b133" - integrity sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw== - dependencies: - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.21.5" - "@babel/helper-environment-visitor" "^7.21.5" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.21.5" - "@babel/types" "^7.21.5" +"@babel/template@^7.22.5", "@babel/template@^7.3.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/traverse@^7.1.6", "@babel/traverse@^7.22.5", "@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": + version "7.22.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" + integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.7" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.7" + "@babel/types" "^7.22.5" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.4", "@babel/types@^7.21.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.5.tgz#18dfbd47c39d3904d5db3d3dc2cc80bedb60e5b6" - integrity sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q== +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" + integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== dependencies: - "@babel/helper-string-parser" "^7.21.5" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -1077,13 +1148,13 @@ integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== "@eslint/eslintrc@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.0.tgz#82256f164cc9e0b59669efc19d57f8092706841d" + integrity sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.5.2" + espree "^9.6.0" globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -1143,28 +1214,28 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.5.0.tgz#593a6c5c0d3f75689835f1b3b4688c4f8544cb57" - integrity sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ== +"@jest/console@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.6.1.tgz#b48ba7b9c34b51483e6d590f46e5837f1ab5f639" + integrity sha512-Aj772AYgwTSr5w8qnyoJ0eDYvN6bMsH3ORH1ivMotrInHLKdUz6BDlaEXHdM6kODaBIkNIyQGzsMvRdOv7VG7Q== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^29.5.0" - jest-util "^29.5.0" + jest-message-util "^29.6.1" + jest-util "^29.6.1" slash "^3.0.0" -"@jest/core@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.5.0.tgz#76674b96904484e8214614d17261cc491e5f1f03" - integrity sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ== - dependencies: - "@jest/console" "^29.5.0" - "@jest/reporters" "^29.5.0" - "@jest/test-result" "^29.5.0" - "@jest/transform" "^29.5.0" - "@jest/types" "^29.5.0" +"@jest/core@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.6.1.tgz#fac0d9ddf320490c93356ba201451825231e95f6" + integrity sha512-CcowHypRSm5oYQ1obz1wfvkjZZ2qoQlrKKvlfPwh5jUXVU12TWr2qMeH8chLMuTFzHh5a1g2yaqlqDICbr+ukQ== + dependencies: + "@jest/console" "^29.6.1" + "@jest/reporters" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" @@ -1172,32 +1243,32 @@ exit "^0.1.2" graceful-fs "^4.2.9" jest-changed-files "^29.5.0" - jest-config "^29.5.0" - jest-haste-map "^29.5.0" - jest-message-util "^29.5.0" + jest-config "^29.6.1" + jest-haste-map "^29.6.1" + jest-message-util "^29.6.1" jest-regex-util "^29.4.3" - jest-resolve "^29.5.0" - jest-resolve-dependencies "^29.5.0" - jest-runner "^29.5.0" - jest-runtime "^29.5.0" - jest-snapshot "^29.5.0" - jest-util "^29.5.0" - jest-validate "^29.5.0" - jest-watcher "^29.5.0" + jest-resolve "^29.6.1" + jest-resolve-dependencies "^29.6.1" + jest-runner "^29.6.1" + jest-runtime "^29.6.1" + jest-snapshot "^29.6.1" + jest-util "^29.6.1" + jest-validate "^29.6.1" + jest-watcher "^29.6.1" micromatch "^4.0.4" - pretty-format "^29.5.0" + pretty-format "^29.6.1" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.5.0.tgz#9152d56317c1fdb1af389c46640ba74ef0bb4c65" - integrity sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ== +"@jest/environment@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.6.1.tgz#ee358fff2f68168394b4a50f18c68278a21fe82f" + integrity sha512-RMMXx4ws+Gbvw3DfLSuo2cfQlK7IwGbpuEWXCqyYDcqYTI+9Ju3a5hDnXaxjNsa6uKh9PQF2v+qg+RLe63tz5A== dependencies: - "@jest/fake-timers" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/fake-timers" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" - jest-mock "^29.5.0" + jest-mock "^29.6.1" "@jest/expect-utils@^28.1.3": version "28.1.3" @@ -1206,54 +1277,54 @@ dependencies: jest-get-type "^28.0.2" -"@jest/expect-utils@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.5.0.tgz#f74fad6b6e20f924582dc8ecbf2cb800fe43a036" - integrity sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg== +"@jest/expect-utils@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.6.1.tgz#ab83b27a15cdd203fe5f68230ea22767d5c3acc5" + integrity sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw== dependencies: jest-get-type "^29.4.3" -"@jest/expect@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.5.0.tgz#80952f5316b23c483fbca4363ce822af79c38fba" - integrity sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g== +"@jest/expect@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.6.1.tgz#fef18265188f6a97601f1ea0a2912d81a85b4657" + integrity sha512-N5xlPrAYaRNyFgVf2s9Uyyvr795jnB6rObuPx4QFvNJz8aAjpZUDfO4bh5G/xuplMID8PrnuF1+SfSyDxhsgYg== dependencies: - expect "^29.5.0" - jest-snapshot "^29.5.0" + expect "^29.6.1" + jest-snapshot "^29.6.1" -"@jest/fake-timers@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.5.0.tgz#d4d09ec3286b3d90c60bdcd66ed28d35f1b4dc2c" - integrity sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg== +"@jest/fake-timers@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.6.1.tgz#c773efddbc61e1d2efcccac008139f621de57c69" + integrity sha512-RdgHgbXyosCDMVYmj7lLpUwXA4c69vcNzhrt69dJJdf8azUrpRh3ckFCaTPNjsEeRi27Cig0oKDGxy5j7hOgHg== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^29.5.0" - jest-mock "^29.5.0" - jest-util "^29.5.0" + jest-message-util "^29.6.1" + jest-mock "^29.6.1" + jest-util "^29.6.1" -"@jest/globals@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.5.0.tgz#6166c0bfc374c58268677539d0c181f9c1833298" - integrity sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ== +"@jest/globals@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.6.1.tgz#c8a8923e05efd757308082cc22893d82b8aa138f" + integrity sha512-2VjpaGy78JY9n9370H8zGRCFbYVWwjY6RdDMhoJHa1sYfwe6XM/azGN0SjY8kk7BOZApIejQ1BFPyH7FPG0w3A== dependencies: - "@jest/environment" "^29.5.0" - "@jest/expect" "^29.5.0" - "@jest/types" "^29.5.0" - jest-mock "^29.5.0" + "@jest/environment" "^29.6.1" + "@jest/expect" "^29.6.1" + "@jest/types" "^29.6.1" + jest-mock "^29.6.1" -"@jest/reporters@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.5.0.tgz#985dfd91290cd78ddae4914ba7921bcbabe8ac9b" - integrity sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA== +"@jest/reporters@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.6.1.tgz#3325a89c9ead3cf97ad93df3a427549d16179863" + integrity sha512-9zuaI9QKr9JnoZtFQlw4GREQbxgmNYXU6QuWtmuODvk5nvPUeBYapVR/VYMyi2WSx3jXTLJTJji8rN6+Cm4+FA== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.5.0" - "@jest/test-result" "^29.5.0" - "@jest/transform" "^29.5.0" - "@jest/types" "^29.5.0" - "@jridgewell/trace-mapping" "^0.3.15" + "@jest/console" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" + "@jridgewell/trace-mapping" "^0.3.18" "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" @@ -1265,9 +1336,9 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^29.5.0" - jest-util "^29.5.0" - jest-worker "^29.5.0" + jest-message-util "^29.6.1" + jest-util "^29.6.1" + jest-worker "^29.6.1" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" @@ -1280,58 +1351,58 @@ dependencies: "@sinclair/typebox" "^0.24.1" -"@jest/schemas@^29.4.3": - version "29.4.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" - integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== +"@jest/schemas@^29.6.0": + version "29.6.0" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040" + integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ== dependencies: - "@sinclair/typebox" "^0.25.16" + "@sinclair/typebox" "^0.27.8" -"@jest/source-map@^29.4.3": - version "29.4.3" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.3.tgz#ff8d05cbfff875d4a791ab679b4333df47951d20" - integrity sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w== +"@jest/source-map@^29.6.0": + version "29.6.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.0.tgz#bd34a05b5737cb1a99d43e1957020ac8e5b9ddb1" + integrity sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA== dependencies: - "@jridgewell/trace-mapping" "^0.3.15" + "@jridgewell/trace-mapping" "^0.3.18" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.5.0.tgz#7c856a6ca84f45cc36926a4e9c6b57f1973f1408" - integrity sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ== +"@jest/test-result@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.6.1.tgz#850e565a3f58ee8ca6ec424db00cb0f2d83c36ba" + integrity sha512-Ynr13ZRcpX6INak0TPUukU8GWRfm/vAytE3JbJNGAvINySWYdfE7dGZMbk36oVuK4CigpbhMn8eg1dixZ7ZJOw== dependencies: - "@jest/console" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/console" "^29.6.1" + "@jest/types" "^29.6.1" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz#34d7d82d3081abd523dbddc038a3ddcb9f6d3cc4" - integrity sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ== +"@jest/test-sequencer@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.6.1.tgz#e3e582ee074dd24ea9687d7d1aaf05ee3a9b068e" + integrity sha512-oBkC36PCDf/wb6dWeQIhaviU0l5u6VCsXa119yqdUosYAt7/FbQU2M2UoziO3igj/HBDEgp57ONQ3fm0v9uyyg== dependencies: - "@jest/test-result" "^29.5.0" + "@jest/test-result" "^29.6.1" graceful-fs "^4.2.9" - jest-haste-map "^29.5.0" + jest-haste-map "^29.6.1" slash "^3.0.0" -"@jest/transform@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.5.0.tgz#cf9c872d0965f0cbd32f1458aa44a2b1988b00f9" - integrity sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw== +"@jest/transform@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.6.1.tgz#acb5606019a197cb99beda3c05404b851f441c92" + integrity sha512-URnTneIU3ZjRSaf906cvf6Hpox3hIeJXRnz3VDSw5/X93gR8ycdfSIEy19FlVx8NFmpN7fe3Gb1xF+NjXaQLWg== dependencies: "@babel/core" "^7.11.6" - "@jest/types" "^29.5.0" - "@jridgewell/trace-mapping" "^0.3.15" + "@jest/types" "^29.6.1" + "@jridgewell/trace-mapping" "^0.3.18" babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" convert-source-map "^2.0.0" fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.9" - jest-haste-map "^29.5.0" + jest-haste-map "^29.6.1" jest-regex-util "^29.4.3" - jest-util "^29.5.0" + jest-util "^29.6.1" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" @@ -1349,12 +1420,12 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jest/types@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.5.0.tgz#f59ef9b031ced83047c67032700d8c807d6e1593" - integrity sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog== +"@jest/types@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.1.tgz#ae79080278acff0a6af5eb49d063385aaa897bf2" + integrity sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw== dependencies: - "@jest/schemas" "^29.4.3" + "@jest/schemas" "^29.6.0" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" @@ -1386,9 +1457,9 @@ integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== "@jridgewell/source-map@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.3.tgz#8108265659d4c33e72ffe14e33d6cc5eb59f2fda" - integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== dependencies: "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" @@ -1411,7 +1482,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": version "0.3.18" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== @@ -1433,6 +1504,7 @@ "@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz": version "3.2.14" + uid acd96c00a881d0f462e1f97a56c73742c8dbc984 resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz#acd96c00a881d0f462e1f97a56c73742c8dbc984" "@microsoft/tsdoc-config@0.16.2": @@ -1462,6 +1534,11 @@ dependencies: eslint-scope "5.1.1" +"@nicolo-ribaudo/semver-v6@^6.3.3": + version "6.3.3" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz#ea6d23ade78a325f7a52750aab1526b02b628c29" + integrity sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1590,26 +1667,26 @@ integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== "@pkgr/utils@^2.3.1": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.0.tgz#b6373d2504aedaf2fc7cdf2d13ab1f48fa5f12d5" - integrity sha512-2OCURAmRtdlL8iUDTypMrrxfwe8frXTeXaxGsVOaYtc/wrUyk8Z/0OBetM7cdlsy7ZFWlMX72VogKeh+A4Xcjw== + version "2.4.2" + resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc" + integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw== dependencies: cross-spawn "^7.0.3" - fast-glob "^3.2.12" + fast-glob "^3.3.0" is-glob "^4.0.3" open "^9.1.0" picocolors "^1.0.0" - tslib "^2.5.0" + tslib "^2.6.0" "@sinclair/typebox@^0.24.1": version "0.24.51" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== -"@sinclair/typebox@^0.25.16": - version "0.25.24" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" - integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== "@sinonjs/commons@^3.0.0": version "3.0.0" @@ -1619,9 +1696,9 @@ type-detect "4.0.8" "@sinonjs/fake-timers@^10.0.2": - version "10.1.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.1.0.tgz#3595e42b3f0a7df80a9681cf58d8cb418eac1e99" - integrity sha512-w1qd368vtrwttm1PRJWPW1QHlbmHrVDGs1eBH/jZvRPUFS4MNXV9Q33EQdjOdeAxZ7O8+3wM7zxztm2nfUSyKw== + version "10.3.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== dependencies: "@sinonjs/commons" "^3.0.0" @@ -1656,9 +1733,9 @@ integrity sha512-pkPtJUUY+Vwv6B1inAz55rQvivClHJxc9aVEPPmaq2cbyeMLCiDpbKpcKyX4LAwpNGi+SHBv0tHv6+0gXv0P2A== "@types/babel__core@^7.1.14": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.0.tgz#61bc5a4cae505ce98e1e36c5445e4bee060d8891" - integrity sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ== + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b" + integrity sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw== dependencies: "@babel/parser" "^7.20.7" "@babel/types" "^7.20.7" @@ -1682,11 +1759,11 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.18.5" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.5.tgz#c107216842905afafd3b6e774f6f935da6f5db80" - integrity sha512-enCvTL8m/EHS/zIvJno9nE+ndYPh1/oNFzRYRmtUqJICG2VnCSBzMLW5VN2KCQU91f23tsNKR8v7VJJQMatl7Q== + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz#dd6f1d2411ae677dcb2db008c962598be31d6acf" + integrity sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg== dependencies: - "@babel/types" "^7.3.0" + "@babel/types" "^7.20.7" "@types/babylon@^6.16.2": version "6.16.6" @@ -1785,14 +1862,14 @@ integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== "@types/node@*": - version "20.2.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.5.tgz#26d295f3570323b2837d322180dfbf1ba156fefb" - integrity sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ== + version "20.4.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.1.tgz#a6033a8718653c50ac4962977e14d0f984d9527d" + integrity sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg== "@types/node@18": - version "18.16.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.18.tgz#85da09bafb66d4bc14f7c899185336d0c1736390" - integrity sha512-/aNaQZD0+iSBAGnvvN2Cx92HqE5sZCPZtx2TsK+4nvV23fFe09jVDvpArXr2j9DnYlzuU9WuoykDDc6wqvpNcw== + version "18.16.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.19.tgz#cb03fca8910fdeb7595b755126a8a78144714eea" + integrity sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -1852,135 +1929,87 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.45.0": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz#81382d6ecb92b8dda70e91f9035611cb2fecd1c3" - integrity sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw== + version "5.61.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz#a1a5290cf33863b4db3fb79350b3c5275a7b1223" + integrity sha512-A5l/eUAug103qtkwccSCxn8ZRwT+7RXWkFECdA4Cvl1dOlDUgTpAOfSEElZn2uSUxhdDpnCdetrf0jvU4qrL+g== dependencies: "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.60.1" - "@typescript-eslint/type-utils" "5.60.1" - "@typescript-eslint/utils" "5.60.1" + "@typescript-eslint/scope-manager" "5.61.0" + "@typescript-eslint/type-utils" "5.61.0" + "@typescript-eslint/utils" "5.61.0" debug "^4.3.4" - grapheme-splitter "^1.0.4" + graphemer "^1.4.0" ignore "^5.2.0" natural-compare-lite "^1.4.0" semver "^7.3.7" tsutils "^3.21.0" "@typescript-eslint/parser@^5.45.0": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.60.1.tgz#0f2f58209c0862a73e3d5a56099abfdfa21d0fd3" - integrity sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q== + version "5.61.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.61.0.tgz#7fbe3e2951904bb843f8932ebedd6e0635bffb70" + integrity sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg== dependencies: - "@typescript-eslint/scope-manager" "5.60.1" - "@typescript-eslint/types" "5.60.1" - "@typescript-eslint/typescript-estree" "5.60.1" + "@typescript-eslint/scope-manager" "5.61.0" + "@typescript-eslint/types" "5.61.0" + "@typescript-eslint/typescript-estree" "5.61.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.60.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz#ae511967b4bd84f1d5e179bb2c82857334941c1c" - integrity sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ== - dependencies: - "@typescript-eslint/types" "5.60.0" - "@typescript-eslint/visitor-keys" "5.60.0" - -"@typescript-eslint/scope-manager@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz#35abdb47f500c68c08f2f2b4f22c7c79472854bb" - integrity sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ== +"@typescript-eslint/scope-manager@5.61.0": + version "5.61.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz#b670006d069c9abe6415c41f754b1b5d949ef2b2" + integrity sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw== dependencies: - "@typescript-eslint/types" "5.60.1" - "@typescript-eslint/visitor-keys" "5.60.1" + "@typescript-eslint/types" "5.61.0" + "@typescript-eslint/visitor-keys" "5.61.0" -"@typescript-eslint/type-utils@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz#17770540e98d65ab4730c7aac618003f702893f4" - integrity sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A== +"@typescript-eslint/type-utils@5.61.0": + version "5.61.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.61.0.tgz#e90799eb2045c4435ea8378cb31cd8a9fddca47a" + integrity sha512-kk8u//r+oVK2Aj3ph/26XdH0pbAkC2RiSjUYhKD+PExemG4XSjpGFeyZ/QM8lBOa7O8aGOU+/yEbMJgQv/DnCg== dependencies: - "@typescript-eslint/typescript-estree" "5.60.1" - "@typescript-eslint/utils" "5.60.1" + "@typescript-eslint/typescript-estree" "5.61.0" + "@typescript-eslint/utils" "5.61.0" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.60.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.60.0.tgz#3179962b28b4790de70e2344465ec97582ce2558" - integrity sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA== - -"@typescript-eslint/types@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.60.1.tgz#a17473910f6b8d388ea83c9d7051af89c4eb7561" - integrity sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg== +"@typescript-eslint/types@5.61.0": + version "5.61.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.61.0.tgz#e99ff11b5792d791554abab0f0370936d8ca50c0" + integrity sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ== -"@typescript-eslint/typescript-estree@5.60.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz#4ddf1a81d32a850de66642d9b3ad1e3254fb1600" - integrity sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ== +"@typescript-eslint/typescript-estree@5.61.0": + version "5.61.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz#4c7caca84ce95bb41aa585d46a764bcc050b92f3" + integrity sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw== dependencies: - "@typescript-eslint/types" "5.60.0" - "@typescript-eslint/visitor-keys" "5.60.0" + "@typescript-eslint/types" "5.61.0" + "@typescript-eslint/visitor-keys" "5.61.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz#8c71824b7165b64d5ebd7aa42968899525959834" - integrity sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw== - dependencies: - "@typescript-eslint/types" "5.60.1" - "@typescript-eslint/visitor-keys" "5.60.1" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.60.1.tgz#6861ebedbefba1ac85482d2bdef6f2ff1eb65b80" - integrity sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.60.1" - "@typescript-eslint/types" "5.60.1" - "@typescript-eslint/typescript-estree" "5.60.1" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/utils@^5.10.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.60.0.tgz#4667c5aece82f9d4f24a667602f0f300864b554c" - integrity sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ== +"@typescript-eslint/utils@5.61.0", "@typescript-eslint/utils@^5.10.0": + version "5.61.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.61.0.tgz#5064838a53e91c754fffbddd306adcca3fe0af36" + integrity sha512-mV6O+6VgQmVE6+xzlA91xifndPW9ElFW8vbSF0xCT/czPXVhwDewKila1jOyRwa9AE19zKnrr7Cg5S3pJVrTWQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@types/json-schema" "^7.0.9" "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.60.0" - "@typescript-eslint/types" "5.60.0" - "@typescript-eslint/typescript-estree" "5.60.0" + "@typescript-eslint/scope-manager" "5.61.0" + "@typescript-eslint/types" "5.61.0" + "@typescript-eslint/typescript-estree" "5.61.0" eslint-scope "^5.1.1" semver "^7.3.7" -"@typescript-eslint/visitor-keys@5.60.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz#b48b29da3f5f31dd1656281727004589d2722a66" - integrity sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw== +"@typescript-eslint/visitor-keys@5.61.0": + version "5.61.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz#c79414fa42158fd23bd2bb70952dc5cdbb298140" + integrity sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg== dependencies: - "@typescript-eslint/types" "5.60.0" - eslint-visitor-keys "^3.3.0" - -"@typescript-eslint/visitor-keys@5.60.1": - version "5.60.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz#19a877358bf96318ec35d90bfe6bd1445cce9434" - integrity sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw== - dependencies: - "@typescript-eslint/types" "5.60.1" + "@typescript-eslint/types" "5.61.0" eslint-visitor-keys "^3.3.0" JSONStream@^1.0.3: @@ -1997,9 +2026,9 @@ abab@^2.0.6: integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== ace-builds@^1.4.13: - version "1.21.1" - resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.21.1.tgz#fb73589114725795babac7cedbbb74cd438c715b" - integrity sha512-GHHtz76BnQc5PcAAjJK6tPbuktSKQ+Vu5MDlu2+hDS4NtiofrttGBJHaxcD4741WZwsAO7Dk1I8w2a4n204T+Q== + version "1.23.2" + resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.23.2.tgz#3a08ef9877d66831726c1dbd40b48914849ce163" + integrity sha512-+LegSgEOcQo7xcvlS4JJidoPOs/QmFGoccWJSEKW/XUH4JzFPrxhPuAezg1bIbS3zxrlM1dVHSEWGiJMxPL9RQ== acorn-globals@^3.0.0: version "3.1.0" @@ -2055,15 +2084,10 @@ acorn@^7.0.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.1.0, acorn@^8.4.1, acorn@^8.8.0, acorn@^8.8.1: - version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - -acorn@^8.8.2: - version "8.9.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" - integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== +acorn@^8.1.0, acorn@^8.4.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -2290,12 +2314,12 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -babel-jest@^29.0.0, babel-jest@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.5.0.tgz#3fe3ddb109198e78b1c88f9ebdecd5e4fc2f50a5" - integrity sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q== +babel-jest@^29.0.0, babel-jest@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.6.1.tgz#a7141ad1ed5ec50238f3cd36127636823111233a" + integrity sha512-qu+3bdPEQC6KZSPz+4Fyjbga5OODNcp49j6GKzG1EKbkfyJBxEYGVUmVGpwCSeGouG52R4EgYMLb6p9YeEEQ4A== dependencies: - "@jest/transform" "^29.5.0" + "@jest/transform" "^29.6.1" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" babel-preset-jest "^29.5.0" @@ -2324,29 +2348,29 @@ babel-plugin-jest-hoist@^29.5.0: "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" -babel-plugin-polyfill-corejs2@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" - integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== +babel-plugin-polyfill-corejs2@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz#9f9a0e1cd9d645cc246a5e094db5c3aa913ccd2b" + integrity sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA== dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.3" - semver "^6.1.1" + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.1" + "@nicolo-ribaudo/semver-v6" "^6.3.3" -babel-plugin-polyfill-corejs3@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" - integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== +babel-plugin-polyfill-corejs3@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.2.tgz#d406c5738d298cd9c66f64a94cf8d5904ce4cc5e" + integrity sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - core-js-compat "^3.25.1" + "@babel/helper-define-polyfill-provider" "^0.4.1" + core-js-compat "^3.31.0" -babel-plugin-polyfill-regenerator@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" - integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== +babel-plugin-polyfill-regenerator@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.1.tgz#ace7a5eced6dff7d5060c335c52064778216afd3" + integrity sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" + "@babel/helper-define-polyfill-provider" "^0.4.1" babel-preset-current-node-syntax@^1.0.0: version "1.0.1" @@ -2651,15 +2675,15 @@ browserify@^17.0.0: vm-browserify "^1.0.0" xtend "^4.0.0" -browserslist@^4.21.3, browserslist@^4.21.5: - version "4.21.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== +browserslist@^4.21.9: + version "4.21.9" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" + integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" + caniuse-lite "^1.0.30001503" + electron-to-chromium "^1.4.431" + node-releases "^2.0.12" + update-browserslist-db "^1.0.11" bs58@^5.0.0: version "5.0.0" @@ -2711,9 +2735,9 @@ bundle-name@^3.0.0: run-applescript "^5.0.0" c8@^7.6.0: - version "7.13.0" - resolved "https://registry.yarnpkg.com/c8/-/c8-7.13.0.tgz#a2a70a851278709df5a9247d62d7f3d4bcb5f2e4" - integrity sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA== + version "7.14.0" + resolved "https://registry.yarnpkg.com/c8/-/c8-7.14.0.tgz#f368184c73b125a80565e9ab2396ff0be4d732f3" + integrity sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw== dependencies: "@bcoe/v8-coverage" "^0.2.3" "@istanbuljs/schema" "^0.1.3" @@ -2761,10 +2785,10 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001449: - version "1.0.30001487" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001487.tgz#d882d1a34d89c11aea53b8cdc791931bdab5fe1b" - integrity sha512-83564Z3yWGqXsh2vaH/mhXfEM0wX+NlBCm1jYHOb97TrTWJEmPTccZgeLTPBUUb0PNVo+oomb7wkimZBIERClA== +caniuse-lite@^1.0.30001503: + version "1.0.30001514" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001514.tgz#e2a7e184a23affc9367b7c8d734e7ec4628c1309" + integrity sha512-ENcIpYBmwAAOm/V2cXgM7rZUrKKaqisZl4ZAI520FIkqGXUxJjmaIssbRW5HVVR5tyV6ygTLIm15aU8LUmQSaQ== center-align@^0.1.1: version "0.1.3" @@ -2832,9 +2856,9 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: safe-buffer "^5.0.1" cjs-module-lexer@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" - integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== clean-css@^4.1.11: version "4.2.4" @@ -2911,9 +2935,9 @@ co@^4.6.0: integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== color-convert@^1.9.0: version "1.9.3" @@ -3031,12 +3055,12 @@ convert-source-map@~1.1.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" integrity sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg== -core-js-compat@^3.25.1: - version "3.30.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.30.2.tgz#83f136e375babdb8c80ad3c22d67c69098c1dd8b" - integrity sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA== +core-js-compat@^3.31.0: + version "3.31.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.31.1.tgz#5084ad1a46858df50ff89ace152441a63ba7aae0" + integrity sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA== dependencies: - browserslist "^4.21.5" + browserslist "^4.21.9" core-js@^2.4.0: version "2.6.12" @@ -3044,9 +3068,9 @@ core-js@^2.4.0: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.0.0: - version "3.30.2" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.30.2.tgz#6528abfda65e5ad728143ea23f7a14f0dcf503fc" - integrity sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg== + version "3.31.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.31.1.tgz#f2b0eea9be9da0def2c5fece71064a7e5d687653" + integrity sha512-2sKLtfq1eFST7l7v62zaqXacPc7uG8ZAya8ogijLhTtaKNcpzpB4TMoTw2Si+8GYKRwFPMMtUT0263QFWFfqyQ== core-util-is@~1.0.0: version "1.0.3" @@ -3193,7 +3217,7 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== -deep-is@^0.1.3, deep-is@~0.1.3: +deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== @@ -3260,9 +3284,9 @@ deps-sort@^2.0.1: through2 "^2.0.0" des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" + integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -3379,10 +3403,10 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -electron-to-chromium@^1.4.284: - version "1.4.396" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.396.tgz#3d3664eb58d86376fbe2fece3705f68ca197205c" - integrity sha512-pqKTdqp/c5vsrc0xUPYXTDBo9ixZuGY8es4ZOjjd6HD6bFYbu5QA09VoW3fkY4LF1T0zYk86lN6bZnNlBuOpdQ== +electron-to-chromium@^1.4.431: + version "1.4.454" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.454.tgz#774dc7cb5e58576d0125939ec34a4182f3ccc87d" + integrity sha512-pmf1rbAStw8UEQ0sr2cdJtWl48ZMuPD9Sto8HVQOq9vx9j2WgDEN6lYoaqFvqEHYOmGA9oRGn7LqWI9ta0YugQ== elliptic@^6.5.3: version "6.5.4" @@ -3413,9 +3437,9 @@ emoji-regex@^9.2.2: integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== enhanced-resolve@^5.12.0: - version "5.14.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.14.0.tgz#0b6c676c8a3266c99fa281e4433a706f5c0c61c4" - integrity sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw== + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -3554,14 +3578,13 @@ escape-string-regexp@^4.0.0: integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== dependencies: esprima "^4.0.1" estraverse "^5.2.0" esutils "^2.0.2" - optionator "^0.8.1" optionalDependencies: source-map "~0.6.1" @@ -3634,9 +3657,9 @@ eslint-plugin-jest@^27.1.6: "@typescript-eslint/utils" "^5.10.0" eslint-plugin-jsdoc@^46.0.0: - version "46.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.3.0.tgz#9e19138b108f7289d5a5d5bacdfb75242f5ebcb7" - integrity sha512-nfSvsR8YJRZyKrWwcXPSQyQC8jllfdEjcRhTXFr7RxfB5Wyl7AxrfjCUz72WwalkXMF4u+R6F/oDoW46ah69HQ== + version "46.4.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.4.3.tgz#4a2ad3a01d7ba723acaed3940f746a0a31d1e58e" + integrity sha512-Prc7ol+vCIghPeECpwZq5+P+VZfoi87suywvbYCiCnkI1kTmVSdcOC2M8mioglWxBbd28wbb1OVjg/8OzGzatA== dependencies: "@es-joy/jsdoccomment" "~0.39.4" are-docs-informative "^0.0.2" @@ -3759,12 +3782,12 @@ eslint@8.43.0: strip-json-comments "^3.1.0" text-table "^0.2.0" -espree@^9.5.2: - version "9.5.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== +espree@^9.5.2, espree@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.0.tgz#80869754b1c6560f32e3b6929194a3fe07c5b82f" + integrity sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A== dependencies: - acorn "^8.8.0" + acorn "^8.9.0" acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.1" @@ -3888,16 +3911,17 @@ expect@^28.1.0: jest-message-util "^28.1.3" jest-util "^28.1.3" -expect@^29.0.0, expect@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" - integrity sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg== +expect@^29.0.0, expect@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.6.1.tgz#64dd1c8f75e2c0b209418f2b8d36a07921adfdf1" + integrity sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g== dependencies: - "@jest/expect-utils" "^29.5.0" + "@jest/expect-utils" "^29.6.1" + "@types/node" "*" jest-get-type "^29.4.3" - jest-matcher-utils "^29.5.0" - jest-message-util "^29.5.0" - jest-util "^29.5.0" + jest-matcher-utils "^29.6.1" + jest-message-util "^29.6.1" + jest-util "^29.6.1" ext@^1.1.2: version "1.7.0" @@ -3918,10 +3942,10 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== +fast-glob@^3.2.9, fast-glob@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.0.tgz#7c40cb491e1e2ed5664749e87bfb516dbe8727c0" + integrity sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -3934,7 +3958,7 @@ fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== @@ -4165,9 +4189,11 @@ get-symbol-description@^1.0.0: get-intrinsic "^1.1.1" get-tsconfig@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.5.0.tgz#6d52d1c7b299bd3ee9cd7638561653399ac77b0f" - integrity sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ== + version "4.6.2" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.6.2.tgz#831879a5e6c2aa24fe79b60340e2233a1e0f472e" + integrity sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg== + dependencies: + resolve-pkg-maps "^1.0.0" glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" @@ -4189,15 +4215,15 @@ glob-to-regexp@^0.4.0: integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== glob@^10.2.5: - version "10.2.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.6.tgz#1e27edbb3bbac055cb97113e27a066c100a4e5e1" - integrity sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA== + version "10.3.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.3.tgz#8360a4ffdd6ed90df84aa8d52f21f452e86a123b" + integrity sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw== dependencies: foreground-child "^3.1.0" jackspeak "^2.0.3" minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2" - path-scurry "^1.7.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" glob@^7.1.0, glob@^7.1.3, glob@^7.1.4, glob@^7.2.0: version "7.2.3" @@ -4251,13 +4277,13 @@ globby@^11.1.0: slash "^3.0.0" globby@^13.1.3: - version "13.1.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.4.tgz#2f91c116066bcec152465ba36e5caa4a13c01317" - integrity sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g== + version "13.2.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-13.2.2.tgz#63b90b1bf68619c2135475cbd4e71e66aa090592" + integrity sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w== dependencies: dir-glob "^3.0.1" - fast-glob "^3.2.11" - ignore "^5.2.0" + fast-glob "^3.3.0" + ignore "^5.2.4" merge2 "^1.4.1" slash "^4.0.0" @@ -4273,11 +4299,6 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - graphemer@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" @@ -4431,7 +4452,7 @@ ieee754@^1.1.4: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore@^5.2.0: +ignore@^5.2.0, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== @@ -4574,9 +4595,9 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== is-core-module@^2.1.0, is-core-module@^2.11.0: - version "2.12.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" - integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== + version "2.12.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== dependencies: has "^1.0.3" @@ -4838,75 +4859,75 @@ jest-changed-files@^29.5.0: execa "^5.0.0" p-limit "^3.1.0" -jest-circus@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.5.0.tgz#b5926989449e75bff0d59944bae083c9d7fb7317" - integrity sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA== +jest-circus@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.6.1.tgz#861dab37e71a89907d1c0fabc54a0019738ed824" + integrity sha512-tPbYLEiBU4MYAL2XoZme/bgfUeotpDBd81lgHLCbDZZFaGmECk0b+/xejPFtmiBP87GgP/y4jplcRpbH+fgCzQ== dependencies: - "@jest/environment" "^29.5.0" - "@jest/expect" "^29.5.0" - "@jest/test-result" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/environment" "^29.6.1" + "@jest/expect" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" is-generator-fn "^2.0.0" - jest-each "^29.5.0" - jest-matcher-utils "^29.5.0" - jest-message-util "^29.5.0" - jest-runtime "^29.5.0" - jest-snapshot "^29.5.0" - jest-util "^29.5.0" + jest-each "^29.6.1" + jest-matcher-utils "^29.6.1" + jest-message-util "^29.6.1" + jest-runtime "^29.6.1" + jest-snapshot "^29.6.1" + jest-util "^29.6.1" p-limit "^3.1.0" - pretty-format "^29.5.0" + pretty-format "^29.6.1" pure-rand "^6.0.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-cli@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.5.0.tgz#b34c20a6d35968f3ee47a7437ff8e53e086b4a67" - integrity sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw== +jest-cli@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.6.1.tgz#99d9afa7449538221c71f358f0fdd3e9c6e89f72" + integrity sha512-607dSgTA4ODIN6go9w6xY3EYkyPFGicx51a69H7yfvt7lN53xNswEVLovq+E77VsTRi5fWprLH0yl4DJgE8Ing== dependencies: - "@jest/core" "^29.5.0" - "@jest/test-result" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/core" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/types" "^29.6.1" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^29.5.0" - jest-util "^29.5.0" - jest-validate "^29.5.0" + jest-config "^29.6.1" + jest-util "^29.6.1" + jest-validate "^29.6.1" prompts "^2.0.1" yargs "^17.3.1" -jest-config@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.5.0.tgz#3cc972faec8c8aaea9ae158c694541b79f3748da" - integrity sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA== +jest-config@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.6.1.tgz#d785344509065d53a238224c6cdc0ed8e2f2f0dd" + integrity sha512-XdjYV2fy2xYixUiV2Wc54t3Z4oxYPAELUzWnV6+mcbq0rh742X2p52pii5A3oeRzYjLnQxCsZmp0qpI6klE2cQ== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.5.0" - "@jest/types" "^29.5.0" - babel-jest "^29.5.0" + "@jest/test-sequencer" "^29.6.1" + "@jest/types" "^29.6.1" + babel-jest "^29.6.1" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^29.5.0" - jest-environment-node "^29.5.0" + jest-circus "^29.6.1" + jest-environment-node "^29.6.1" jest-get-type "^29.4.3" jest-regex-util "^29.4.3" - jest-resolve "^29.5.0" - jest-runner "^29.5.0" - jest-util "^29.5.0" - jest-validate "^29.5.0" + jest-resolve "^29.6.1" + jest-runner "^29.6.1" + jest-util "^29.6.1" + jest-validate "^29.6.1" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^29.5.0" + pretty-format "^29.6.1" slash "^3.0.0" strip-json-comments "^3.1.1" @@ -4920,15 +4941,15 @@ jest-diff@^28.1.3: jest-get-type "^28.0.2" pretty-format "^28.1.3" -jest-diff@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63" - integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw== +jest-diff@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.1.tgz#13df6db0a89ee6ad93c747c75c85c70ba941e545" + integrity sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg== dependencies: chalk "^4.0.0" diff-sequences "^29.4.3" jest-get-type "^29.4.3" - pretty-format "^29.5.0" + pretty-format "^29.6.1" jest-docblock@^29.4.3: version "29.4.3" @@ -4937,42 +4958,42 @@ jest-docblock@^29.4.3: dependencies: detect-newline "^3.0.0" -jest-each@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.5.0.tgz#fc6e7014f83eac68e22b7195598de8554c2e5c06" - integrity sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA== +jest-each@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.6.1.tgz#975058e5b8f55c6780beab8b6ab214921815c89c" + integrity sha512-n5eoj5eiTHpKQCAVcNTT7DRqeUmJ01hsAL0Q1SMiBHcBcvTKDELixQOGMCpqhbIuTcfC4kMfSnpmDqRgRJcLNQ== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" chalk "^4.0.0" jest-get-type "^29.4.3" - jest-util "^29.5.0" - pretty-format "^29.5.0" + jest-util "^29.6.1" + pretty-format "^29.6.1" jest-environment-jsdom@^29.0.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.5.0.tgz#cfe86ebaf1453f3297b5ff3470fbe94739c960cb" - integrity sha512-/KG8yEK4aN8ak56yFVdqFDzKNHgF4BAymCx2LbPNPsUshUlfAl0eX402Xm1pt+eoG9SLZEUVifqXtX8SK74KCw== + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.6.1.tgz#480bce658aa31589309c82ca510351fd7c683bbb" + integrity sha512-PoY+yLaHzVRhVEjcVKSfJ7wXmJW4UqPYNhR05h7u/TK0ouf6DmRNZFBL/Z00zgQMyWGMBXn69/FmOvhEJu8cIw== dependencies: - "@jest/environment" "^29.5.0" - "@jest/fake-timers" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/environment" "^29.6.1" + "@jest/fake-timers" "^29.6.1" + "@jest/types" "^29.6.1" "@types/jsdom" "^20.0.0" "@types/node" "*" - jest-mock "^29.5.0" - jest-util "^29.5.0" + jest-mock "^29.6.1" + jest-util "^29.6.1" jsdom "^20.0.0" -jest-environment-node@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.5.0.tgz#f17219d0f0cc0e68e0727c58b792c040e332c967" - integrity sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw== +jest-environment-node@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.6.1.tgz#08a122dece39e58bc388da815a2166c58b4abec6" + integrity sha512-ZNIfAiE+foBog24W+2caIldl4Irh8Lx1PUhg/GZ0odM1d/h2qORAsejiFc7zb+SEmYPn1yDZzEDSU5PmDkmVLQ== dependencies: - "@jest/environment" "^29.5.0" - "@jest/fake-timers" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/environment" "^29.6.1" + "@jest/fake-timers" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" - jest-mock "^29.5.0" - jest-util "^29.5.0" + jest-mock "^29.6.1" + jest-util "^29.6.1" jest-get-type@^28.0.2: version "28.0.2" @@ -4984,32 +5005,32 @@ jest-get-type@^29.4.3: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== -jest-haste-map@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.5.0.tgz#69bd67dc9012d6e2723f20a945099e972b2e94de" - integrity sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA== +jest-haste-map@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.6.1.tgz#62655c7a1c1b349a3206441330fb2dbdb4b63803" + integrity sha512-0m7f9PZXxOCk1gRACiVgX85knUKPKLPg4oRCjLoqIm9brTHXaorMA0JpmtmVkQiT8nmXyIVoZd/nnH1cfC33ig== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" jest-regex-util "^29.4.3" - jest-util "^29.5.0" - jest-worker "^29.5.0" + jest-util "^29.6.1" + jest-worker "^29.6.1" micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz#cf4bdea9615c72bac4a3a7ba7e7930f9c0610c8c" - integrity sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow== +jest-leak-detector@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.6.1.tgz#66a902c81318e66e694df7d096a95466cb962f8e" + integrity sha512-OrxMNyZirpOEwkF3UHnIkAiZbtkBWiye+hhBweCHkVbCgyEy71Mwbb5zgeTNYWJBi1qgDVfPC1IwO9dVEeTLwQ== dependencies: jest-get-type "^29.4.3" - pretty-format "^29.5.0" + pretty-format "^29.6.1" jest-localstorage-mock@^2.4.6: version "2.4.26" @@ -5026,15 +5047,15 @@ jest-matcher-utils@^28.1.3: jest-get-type "^28.0.2" pretty-format "^28.1.3" -jest-matcher-utils@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz#d957af7f8c0692c5453666705621ad4abc2c59c5" - integrity sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw== +jest-matcher-utils@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz#6c60075d84655d6300c5d5128f46531848160b53" + integrity sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA== dependencies: chalk "^4.0.0" - jest-diff "^29.5.0" + jest-diff "^29.6.1" jest-get-type "^29.4.3" - pretty-format "^29.5.0" + pretty-format "^29.6.1" jest-message-util@^28.1.3: version "28.1.3" @@ -5051,29 +5072,29 @@ jest-message-util@^28.1.3: slash "^3.0.0" stack-utils "^2.0.3" -jest-message-util@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.5.0.tgz#1f776cac3aca332ab8dd2e3b41625435085c900e" - integrity sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA== +jest-message-util@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.1.tgz#d0b21d87f117e1b9e165e24f245befd2ff34ff8d" + integrity sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.5.0" + pretty-format "^29.6.1" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.0.0, jest-mock@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.5.0.tgz#26e2172bcc71d8b0195081ff1f146ac7e1518aed" - integrity sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw== +jest-mock@^29.0.0, jest-mock@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.6.1.tgz#049ee26aea8cbf54c764af649070910607316517" + integrity sha512-brovyV9HBkjXAEdRooaTQK42n8usKoSRR3gihzUpYeV/vwqgSoNfrksO7UfSACnPmxasO/8TmHM3w9Hp3G1dgw== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@types/node" "*" - jest-util "^29.5.0" + jest-util "^29.6.1" jest-pnp-resolver@^1.2.2: version "1.2.3" @@ -5085,112 +5106,110 @@ jest-regex-util@^29.4.3: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== -jest-resolve-dependencies@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz#f0ea29955996f49788bf70996052aa98e7befee4" - integrity sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg== +jest-resolve-dependencies@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.1.tgz#b85b06670f987a62515bbf625d54a499e3d708f5" + integrity sha512-BbFvxLXtcldaFOhNMXmHRWx1nXQO5LoXiKSGQcA1LxxirYceZT6ch8KTE1bK3X31TNG/JbkI7OkS/ABexVahiw== dependencies: jest-regex-util "^29.4.3" - jest-snapshot "^29.5.0" + jest-snapshot "^29.6.1" -jest-resolve@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.5.0.tgz#b053cc95ad1d5f6327f0ac8aae9f98795475ecdc" - integrity sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w== +jest-resolve@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.6.1.tgz#4c3324b993a85e300add2f8609f51b80ddea39ee" + integrity sha512-AeRkyS8g37UyJiP9w3mmI/VXU/q8l/IH52vj/cDAyScDcemRbSBhfX/NMYIGilQgSVwsjxrCHf3XJu4f+lxCMg== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^29.5.0" + jest-haste-map "^29.6.1" jest-pnp-resolver "^1.2.2" - jest-util "^29.5.0" - jest-validate "^29.5.0" + jest-util "^29.6.1" + jest-validate "^29.6.1" resolve "^1.20.0" resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.5.0.tgz#6a57c282eb0ef749778d444c1d758c6a7693b6f8" - integrity sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ== - dependencies: - "@jest/console" "^29.5.0" - "@jest/environment" "^29.5.0" - "@jest/test-result" "^29.5.0" - "@jest/transform" "^29.5.0" - "@jest/types" "^29.5.0" +jest-runner@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.6.1.tgz#54557087e7972d345540d622ab5bfc3d8f34688c" + integrity sha512-tw0wb2Q9yhjAQ2w8rHRDxteryyIck7gIzQE4Reu3JuOBpGp96xWgF0nY8MDdejzrLCZKDcp8JlZrBN/EtkQvPQ== + dependencies: + "@jest/console" "^29.6.1" + "@jest/environment" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" chalk "^4.0.0" emittery "^0.13.1" graceful-fs "^4.2.9" jest-docblock "^29.4.3" - jest-environment-node "^29.5.0" - jest-haste-map "^29.5.0" - jest-leak-detector "^29.5.0" - jest-message-util "^29.5.0" - jest-resolve "^29.5.0" - jest-runtime "^29.5.0" - jest-util "^29.5.0" - jest-watcher "^29.5.0" - jest-worker "^29.5.0" + jest-environment-node "^29.6.1" + jest-haste-map "^29.6.1" + jest-leak-detector "^29.6.1" + jest-message-util "^29.6.1" + jest-resolve "^29.6.1" + jest-runtime "^29.6.1" + jest-util "^29.6.1" + jest-watcher "^29.6.1" + jest-worker "^29.6.1" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.5.0.tgz#c83f943ee0c1da7eb91fa181b0811ebd59b03420" - integrity sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw== - dependencies: - "@jest/environment" "^29.5.0" - "@jest/fake-timers" "^29.5.0" - "@jest/globals" "^29.5.0" - "@jest/source-map" "^29.4.3" - "@jest/test-result" "^29.5.0" - "@jest/transform" "^29.5.0" - "@jest/types" "^29.5.0" +jest-runtime@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.6.1.tgz#8a0fc9274ef277f3d70ba19d238e64334958a0dc" + integrity sha512-D6/AYOA+Lhs5e5il8+5pSLemjtJezUr+8zx+Sn8xlmOux3XOqx4d8l/2udBea8CRPqqrzhsKUsN/gBDE/IcaPQ== + dependencies: + "@jest/environment" "^29.6.1" + "@jest/fake-timers" "^29.6.1" + "@jest/globals" "^29.6.1" + "@jest/source-map" "^29.6.0" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^29.5.0" - jest-message-util "^29.5.0" - jest-mock "^29.5.0" + jest-haste-map "^29.6.1" + jest-message-util "^29.6.1" + jest-mock "^29.6.1" jest-regex-util "^29.4.3" - jest-resolve "^29.5.0" - jest-snapshot "^29.5.0" - jest-util "^29.5.0" + jest-resolve "^29.6.1" + jest-snapshot "^29.6.1" + jest-util "^29.6.1" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.5.0.tgz#c9c1ce0331e5b63cd444e2f95a55a73b84b1e8ce" - integrity sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g== +jest-snapshot@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.6.1.tgz#0d083cb7de716d5d5cdbe80d598ed2fbafac0239" + integrity sha512-G4UQE1QQ6OaCgfY+A0uR1W2AY0tGXUPQpoUClhWHq1Xdnx1H6JOrC2nH5lqnOEqaDgbHFgIwZ7bNq24HpB180A== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" "@babel/plugin-syntax-jsx" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.5.0" - "@jest/transform" "^29.5.0" - "@jest/types" "^29.5.0" - "@types/babel__traverse" "^7.0.6" + "@jest/expect-utils" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^29.5.0" + expect "^29.6.1" graceful-fs "^4.2.9" - jest-diff "^29.5.0" + jest-diff "^29.6.1" jest-get-type "^29.4.3" - jest-matcher-utils "^29.5.0" - jest-message-util "^29.5.0" - jest-util "^29.5.0" + jest-matcher-utils "^29.6.1" + jest-message-util "^29.6.1" + jest-util "^29.6.1" natural-compare "^1.4.0" - pretty-format "^29.5.0" - semver "^7.3.5" + pretty-format "^29.6.1" + semver "^7.5.3" jest-util@^28.1.3: version "28.1.3" @@ -5204,63 +5223,63 @@ jest-util@^28.1.3: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-util@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" - integrity sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ== +jest-util@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.1.tgz#c9e29a87a6edbf1e39e6dee2b4689b8a146679cb" + integrity sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.5.0.tgz#8e5a8f36178d40e47138dc00866a5f3bd9916ffc" - integrity sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ== +jest-validate@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.6.1.tgz#765e684af6e2c86dce950aebefbbcd4546d69f7b" + integrity sha512-r3Ds69/0KCN4vx4sYAbGL1EVpZ7MSS0vLmd3gV78O+NAx3PDQQukRU5hNHPXlyqCgFY8XUk7EuTMLugh0KzahA== dependencies: - "@jest/types" "^29.5.0" + "@jest/types" "^29.6.1" camelcase "^6.2.0" chalk "^4.0.0" jest-get-type "^29.4.3" leven "^3.1.0" - pretty-format "^29.5.0" + pretty-format "^29.6.1" -jest-watcher@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.5.0.tgz#cf7f0f949828ba65ddbbb45c743a382a4d911363" - integrity sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA== +jest-watcher@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.6.1.tgz#7c0c43ddd52418af134c551c92c9ea31e5ec942e" + integrity sha512-d4wpjWTS7HEZPaaj8m36QiaP856JthRZkrgcIY/7ISoUWPIillrXM23WPboZVLbiwZBt4/qn2Jke84Sla6JhFA== dependencies: - "@jest/test-result" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/test-result" "^29.6.1" + "@jest/types" "^29.6.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.13.1" - jest-util "^29.5.0" + jest-util "^29.6.1" string-length "^4.0.1" -jest-worker@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.5.0.tgz#bdaefb06811bd3384d93f009755014d8acb4615d" - integrity sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA== +jest-worker@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.6.1.tgz#64b015f0e985ef3a8ad049b61fe92b3db74a5319" + integrity sha512-U+Wrbca7S8ZAxAe9L6nb6g8kPdia5hj32Puu5iOqBCMTMWFHXuK6dOV2IFrpedbTV8fjMFLdWNttQTBL6u2MRA== dependencies: "@types/node" "*" - jest-util "^29.5.0" + jest-util "^29.6.1" merge-stream "^2.0.0" supports-color "^8.0.0" jest@^29.0.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.5.0.tgz#f75157622f5ce7ad53028f2f8888ab53e1f1f24e" - integrity sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ== + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.6.1.tgz#74be1cb719c3abe439f2d94aeb18e6540a5b02ad" + integrity sha512-Nirw5B4nn69rVUZtemCQhwxOBhm0nsp3hmtF4rzCeWD7BkjAXRIji7xWQfnTNbz9g0aVsBX6aZK3n+23LM6uDw== dependencies: - "@jest/core" "^29.5.0" - "@jest/types" "^29.5.0" + "@jest/core" "^29.6.1" + "@jest/types" "^29.6.1" import-local "^3.0.2" - jest-cli "^29.5.0" + jest-cli "^29.6.1" jju@~1.4.0: version "1.4.0" @@ -5446,14 +5465,6 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -5560,10 +5571,10 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^9.1.1: - version "9.1.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.2.tgz#255fdbc14b75589d6d0e73644ca167a8db506835" - integrity sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ== +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" + integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== lru-queue@^0.1.0: version "0.1.0" @@ -5730,17 +5741,10 @@ minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatc dependencies: brace-expansion "^1.1.7" -minimatch@^9.0.0: - version "9.0.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.2.tgz#397e387fff22f6795844d00badc903a3d5de7057" - integrity sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253" - integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== +minimatch@^9.0.0, minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== dependencies: brace-expansion "^2.0.1" @@ -5754,10 +5758,10 @@ minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -"minipass@^5.0.0 || ^6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81" - integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.1" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.1.tgz#dff63464407cd8b83d7f008c0f116fa8c9b77ebf" + integrity sha512-NQ8MCKimInjVlaIqx51RKJJB7mINVkLTJbsZKmto4UAAOC/CWXES8PGaOgoBZyqoUsUA/U3DToGK7GJkkHbjJw== mkdirp-classic@^0.5.2: version "0.5.3" @@ -5836,9 +5840,9 @@ node-dir@^0.1.10: minimatch "^3.0.2" node-fetch@^2.6.7: - version "2.6.11" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" - integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== + version "2.6.12" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" + integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== dependencies: whatwg-url "^5.0.0" @@ -5847,10 +5851,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== +node-releases@^2.0.12: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== normalize-package-data@^2.5.0: version "2.5.0" @@ -5882,9 +5886,9 @@ npm-run-path@^5.1.0: path-key "^4.0.0" nwsapi@^2.2.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.4.tgz#fd59d5e904e8e1f03c25a7d5a15cfa16c714a1e5" - integrity sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g== + version "2.2.7" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" + integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" @@ -5964,29 +5968,17 @@ open@^9.1.0: is-inside-container "^1.0.0" is-wsl "^2.2.0" -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" os-browserify@~0.3.0: version "0.3.0" @@ -6135,13 +6127,13 @@ path-platform@~0.11.15: resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" integrity sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg== -path-scurry@^1.7.0: - version "1.9.2" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.9.2.tgz#90f9d296ac5e37e608028e28a447b11d385b3f63" - integrity sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg== +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== dependencies: - lru-cache "^9.1.1" - minipass "^5.0.0 || ^6.0.2" + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-to-regexp@^2.2.1: version "2.4.0" @@ -6180,9 +6172,9 @@ pify@^4.0.1: integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== pirates@^4.0.4, pirates@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== pkg-dir@^3.0.0: version "3.0.0" @@ -6208,11 +6200,6 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== - prettier@2.8.8: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" @@ -6228,12 +6215,12 @@ pretty-format@^28.1.3: ansi-styles "^5.0.0" react-is "^18.0.0" -pretty-format@^29.0.0, pretty-format@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" - integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw== +pretty-format@^29.0.0, pretty-format@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.1.tgz#ec838c288850b7c4f9090b867c2d4f4edbfb0f3e" + integrity sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog== dependencies: - "@jest/schemas" "^29.4.3" + "@jest/schemas" "^29.6.0" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -6403,12 +6390,7 @@ pug@^2.0.3: pug-runtime "^2.0.5" pug-strip-comments "^1.0.4" -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== - -punycode@^1.3.2: +punycode@^1.3.2, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== @@ -6423,16 +6405,18 @@ pure-rand@^6.0.0: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.2.tgz#a9c2ddcae9b68d736a8163036f088a2781c8b306" integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ== +qs@^6.11.0: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + querystring-es3@~0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== - querystring@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" @@ -6690,6 +6674,11 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve.exports@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" @@ -6823,22 +6812,15 @@ sdp-transform@^2.14.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.5, semver@^7.3.8: - version "7.5.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" - integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.7, semver@^7.5.1: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== +semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.1, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" @@ -7227,9 +7209,9 @@ tapable@^2.2.0: integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== terser@^5.5.1: - version "5.18.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.18.1.tgz#6d8642508ae9fb7b48768e48f16d675c89a78460" - integrity sha512-j1n0Ao919h/Ai5r43VAnfV/7azUYW43GPxK7qSATzrsERfW7+y2QW9Cp9ufnRF5CQUWbnLSo7UJokSWCqg4tsQ== + version "5.18.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.18.2.tgz#ff3072a0faf21ffd38f99acc9a0ddf7b5f07b948" + integrity sha512-Ah19JS86ypbJzTzvUCX7KOsEIhDaRONungA4aYBjEP3JZRf4ocuDzTg4QWZnPn9DEMiMYGJPiSOy7aykoCc70w== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -7420,10 +7402,10 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.1, tslib@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.0.1, tslib@^2.5.0, tslib@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== tsutils@^3.21.0: version "3.21.0" @@ -7449,13 +7431,6 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== - dependencies: - prelude-ls "~1.1.2" - type-detect@4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" @@ -7560,9 +7535,9 @@ typescript@^4.5.4: integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== typescript@^5.0.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" - integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== typeson-registry@^1.0.0-alpha.20: version "1.0.0-alpha.39" @@ -7672,7 +7647,7 @@ untildify@^4.0.0: resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== -update-browserslist-db@^1.0.10: +update-browserslist-db@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== @@ -7696,12 +7671,12 @@ url-parse@^1.5.3: requires-port "^1.0.0" url@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ== + version "0.11.1" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.1.tgz#26f90f615427eca1b9f4d6a28288c147e2302a32" + integrity sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA== dependencies: - punycode "1.3.2" - querystring "0.2.0" + punycode "^1.4.1" + qs "^6.11.0" util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" @@ -7942,11 +7917,6 @@ with@^5.0.0: acorn "^3.1.0" acorn-globals "^3.0.0" -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" From e42dd744263a7ac8c4c913038c6a696433d50e7f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 10 Jul 2023 14:22:10 +0100 Subject: [PATCH 08/59] Add async method for generating a QR code (#3562) The api to generate a QR code is async in rust, and the easiest way to deal with it is to make a new method. --- spec/integ/crypto/verification.spec.ts | 2 +- src/crypto-api/verification.ts | 10 ++++++++++ .../verification/request/VerificationRequest.ts | 14 +++++++++++++- src/rust-crypto/verification.ts | 14 +++++++++++--- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/spec/integ/crypto/verification.spec.ts b/spec/integ/crypto/verification.spec.ts index 8e008ad5c30..5238871d208 100644 --- a/spec/integ/crypto/verification.spec.ts +++ b/spec/integ/crypto/verification.spec.ts @@ -414,7 +414,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st expect(request.phase).toEqual(VerificationPhase.Ready); // we should now have QR data we can display - const qrCodeBuffer = request.getQRCodeBytes()!; + const qrCodeBuffer = (await request.generateQRCode())!; expect(qrCodeBuffer).toBeTruthy(); // https://spec.matrix.org/v1.7/client-server-api/#qr-code-format diff --git a/src/crypto-api/verification.ts b/src/crypto-api/verification.ts index 1d079b8b3a2..12a14bb5092 100644 --- a/src/crypto-api/verification.ts +++ b/src/crypto-api/verification.ts @@ -152,9 +152,19 @@ export interface VerificationRequest * Get the data for a QR code allowing the other device to verify this one, if it supports it. * * Only set after a .ready if the other party can scan a QR code, otherwise undefined. + * + * @deprecated Not supported in Rust Crypto. Use {@link VerificationRequest#generateQRCode} instead. */ getQRCodeBytes(): Buffer | undefined; + /** + * Generate the data for a QR code allowing the other device to verify this one, if it supports it. + * + * Only returns data once `phase` is {@link VerificationPhase.Ready} and the other party can scan a QR code; + * otherwise returns `undefined`. + */ + generateQRCode(): Promise; + /** * If this request has been cancelled, the cancellation code (e.g `m.user`) which is responsible for cancelling * this verification. diff --git a/src/crypto/verification/request/VerificationRequest.ts b/src/crypto/verification/request/VerificationRequest.ts index 7a1a999cf74..7bcb948b4e3 100644 --- a/src/crypto/verification/request/VerificationRequest.ts +++ b/src/crypto/verification/request/VerificationRequest.ts @@ -268,7 +268,7 @@ export class VerificationRequest { + return this.getQRCodeBytes(); + } + /** Checks whether the other party supports a given verification method. * This is useful when setting up the QR code UI, as it is somewhat asymmetrical: * if the other party supports SCAN_QR, we should show a QR code in the UI, and vice versa. diff --git a/src/rust-crypto/verification.ts b/src/rust-crypto/verification.ts index fbf65f64f90..3d8fc48e0ff 100644 --- a/src/rust-crypto/verification.ts +++ b/src/rust-crypto/verification.ts @@ -322,15 +322,23 @@ export class RustVerificationRequest } /** - * Get the data for a QR code allowing the other device to verify this one, if it supports it. - * - * Only set after a .ready if the other party can scan a QR code, otherwise undefined. + * Stub implementation of {@link Crypto.VerificationRequest#getQRCodeBytes}. */ public getQRCodeBytes(): Buffer | undefined { // TODO return undefined; } + /** + * Generate the data for a QR code allowing the other device to verify this one, if it supports it. + * + * Implementation of {@link Crypto.VerificationRequest#generateQRCode}. + */ + public async generateQRCode(): Promise { + // TODO + return undefined; + } + /** * If this request has been cancelled, the cancellation code (e.g `m.user`) which is responsible for cancelling * this verification. From e68a1471c12c6333c3ab5db4987fec6ae8adf470 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 15:38:14 +0100 Subject: [PATCH 09/59] Update all non-major dependencies (#3564) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/cypress.yml | 2 +- .github/workflows/downstream-artifacts.yml | 2 +- package.json | 2 +- yarn.lock | 30 +++++++++++----------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 2724ff37d0c..d87c893a0e6 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -15,7 +15,7 @@ concurrency: jobs: cypress: name: Cypress - uses: matrix-org/matrix-react-sdk/.github/workflows/cypress.yaml@v3.74.0 + uses: matrix-org/matrix-react-sdk/.github/workflows/cypress.yaml@v3.75.0 permissions: actions: read issues: read diff --git a/.github/workflows/downstream-artifacts.yml b/.github/workflows/downstream-artifacts.yml index d2056eac1e5..0d487b8ecd8 100644 --- a/.github/workflows/downstream-artifacts.yml +++ b/.github/workflows/downstream-artifacts.yml @@ -19,7 +19,7 @@ concurrency: jobs: build-element-web: name: Build element-web - uses: matrix-org/matrix-react-sdk/.github/workflows/element-web.yaml@v3.74.0 + uses: matrix-org/matrix-react-sdk/.github/workflows/element-web.yaml@v3.75.0 with: matrix-js-sdk-sha: ${{ github.sha }} react-sdk-repository: matrix-org/matrix-react-sdk diff --git a/package.json b/package.json index 95901df5798..1d8af896c9d 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "debug": "^4.3.4", "docdash": "^2.0.0", "domexception": "^4.0.0", - "eslint": "8.43.0", + "eslint": "8.44.0", "eslint-config-google": "^0.14.0", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^3.5.1", diff --git a/yarn.lock b/yarn.lock index be55c1d52ba..0ef82c1782a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1147,7 +1147,7 @@ resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== -"@eslint/eslintrc@^2.0.3": +"@eslint/eslintrc@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.0.tgz#82256f164cc9e0b59669efc19d57f8092706841d" integrity sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A== @@ -1162,10 +1162,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.43.0": - version "8.43.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.43.0.tgz#559ca3d9ddbd6bf907ad524320a0d14b85586af0" - integrity sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg== +"@eslint/js@8.44.0": + version "8.44.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.44.0.tgz#961a5903c74139390478bdc808bcde3fc45ab7af" + integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw== "@humanwhocodes/config-array@^0.11.10": version "0.11.10" @@ -3737,15 +3737,15 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== -eslint@8.43.0: - version "8.43.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.43.0.tgz#3e8c6066a57097adfd9d390b8fc93075f257a094" - integrity sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q== +eslint@8.44.0: + version "8.44.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.44.0.tgz#51246e3889b259bbcd1d7d736a0c10add4f0e500" + integrity sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.3" - "@eslint/js" "8.43.0" + "@eslint/eslintrc" "^2.1.0" + "@eslint/js" "8.44.0" "@humanwhocodes/config-array" "^0.11.10" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -3757,7 +3757,7 @@ eslint@8.43.0: escape-string-regexp "^4.0.0" eslint-scope "^7.2.0" eslint-visitor-keys "^3.4.1" - espree "^9.5.2" + espree "^9.6.0" esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -3777,12 +3777,12 @@ eslint@8.43.0: lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" + optionator "^0.9.3" strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" -espree@^9.5.2, espree@^9.6.0: +espree@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.0.tgz#80869754b1c6560f32e3b6929194a3fe07c5b82f" integrity sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A== @@ -5968,7 +5968,7 @@ open@^9.1.0: is-inside-container "^1.0.0" is-wsl "^2.2.0" -optionator@^0.9.1: +optionator@^0.9.3: version "0.9.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== From 5df4ebaada192e65a6b9becff464c027cb3bf3a5 Mon Sep 17 00:00:00 2001 From: Kerry Date: Tue, 11 Jul 2023 14:20:19 +1200 Subject: [PATCH 10/59] OIDC: Log in (#3554) * use oidc-client-ts during oidc discovery * export new type for auth config * deprecate generateAuthorizationUrl in favour of generateOidcAuthorizationUrl * testing util for oidc configurations * test generateOidcAuthorizationUrl * lint * test discovery * dont pass whole client wellknown to oidc validation funcs * add nonce * use oidc-client-ts for oidc response * validate user state and update tests * use oidc-client-ts for code exchange * use oidc-client-ts in completing auth grant * use client userState for homeserver * more comments --- spec/unit/oidc/authorize.spec.ts | 244 ++++++++++++++++++++++--------- spec/unit/oidc/validate.spec.ts | 6 +- src/oidc/authorize.ts | 165 +++++++++++---------- src/oidc/error.ts | 1 + src/oidc/validate.ts | 69 ++++++++- 5 files changed, 328 insertions(+), 157 deletions(-) diff --git a/spec/unit/oidc/authorize.spec.ts b/spec/unit/oidc/authorize.spec.ts index 773d7071dd9..ffd22148dd1 100644 --- a/spec/unit/oidc/authorize.spec.ts +++ b/spec/unit/oidc/authorize.spec.ts @@ -46,8 +46,12 @@ describe("oidc authorization", () => { const clientId = "xyz789"; const baseUrl = "https://test.com"; + // 14.03.2022 16:15 + const now = 1647270879403; + beforeAll(() => { jest.spyOn(logger, "warn"); + jest.setSystemTime(now); fetchMock.get(delegatedAuthConfig.issuer + ".well-known/openid-configuration", mockOpenIdConfiguration()); }); @@ -133,7 +137,8 @@ describe("oidc authorization", () => { }); describe("completeAuthorizationCodeGrant", () => { - const codeVerifier = "abc123"; + const homeserverUrl = "https://server.org/"; + const identityServerUrl = "https://id.org/"; const nonce = "test-nonce"; const redirectUri = baseUrl; const code = "auth_code_xyz"; @@ -142,9 +147,11 @@ describe("oidc authorization", () => { access_token: "test_access_token", refresh_token: "test_refresh_token", id_token: "valid.id.token", - expires_in: 12345, + expires_in: 300, }; + const metadata = mockOpenIdConfiguration(); + const validDecodedIdToken = { // nonce matches nonce, @@ -153,131 +160,236 @@ describe("oidc authorization", () => { // audience is this client aud: clientId, // issuer matches - iss: delegatedAuthConfig.issuer, + iss: metadata.issuer, + sub: "123", + }; + + const mockSessionStorage = (state: Record): void => { + jest.spyOn(sessionStorage.__proto__, "getItem").mockImplementation((key: unknown) => { + return state[key as string] ?? null; + }); + jest.spyOn(sessionStorage.__proto__, "setItem").mockImplementation( + // @ts-ignore mock type + (key: string, value: unknown) => (state[key] = value), + ); + jest.spyOn(sessionStorage.__proto__, "removeItem").mockImplementation((key: unknown) => { + const { [key as string]: value, ...newState } = state; + state = newState; + return value; + }); + }; + + const getValueFromStorage = (state: string, key: string): T => { + const storedState = window.sessionStorage.getItem(`mx_oidc_${state}`)!; + return JSON.parse(storedState)[key] as unknown as T; + }; + + /** + * These tests kind of integration test oidc auth, by using `generateOidcAuthorizationUrl` and mocked storage + * to mock the use case of initiating oidc auth, putting state in storage, redirecting to OP, + * then returning and using state to verfiy. + * Returns random state string used to access storage + * @param params + */ + const setupState = async (params = {}): Promise => { + const url = await generateOidcAuthorizationUrl({ + metadata, + redirectUri, + clientId, + homeserverUrl, + identityServerUrl, + nonce, + ...params, + }); + + const state = new URL(url).searchParams.get("state")!; + + // add the scope with correct deviceId to the mocked bearer token response + const scope = getValueFromStorage(state, "scope"); + fetchMock.post(metadata.token_endpoint, { + status: 200, + headers: { + "Content-Type": "application/json", + }, + ...validBearerTokenResponse, + scope, + }); + + return state; }; beforeEach(() => { fetchMock.mockClear(); fetchMock.resetBehavior(); - fetchMock.post(tokenEndpoint, { + fetchMock.get(`${metadata.issuer}.well-known/openid-configuration`, metadata); + fetchMock.get(`${metadata.issuer}jwks`, { status: 200, - body: JSON.stringify(validBearerTokenResponse), + headers: { + "Content-Type": "application/json", + }, + keys: [], }); + mockSessionStorage({}); + mocked(jwtDecode).mockReturnValue(validDecodedIdToken); }); it("should make correct request to the token endpoint", async () => { - await completeAuthorizationCodeGrant(code, { - clientId, - codeVerifier, - redirectUri, - delegatedAuthConfig, - nonce, - }); + const state = await setupState(); + const codeVerifier = getValueFromStorage(state, "code_verifier"); + await completeAuthorizationCodeGrant(code, state); + + expect(fetchMock).toHaveBeenCalledWith( + metadata.token_endpoint, + expect.objectContaining({ + method: Method.Post, + credentials: "same-origin", + headers: { + "Accept": "application/json", + "Content-Type": "application/x-www-form-urlencoded", + }, + }), + ); - expect(fetchMock).toHaveBeenCalledWith(tokenEndpoint, { - method: Method.Post, - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: `grant_type=authorization_code&client_id=${clientId}&code_verifier=${codeVerifier}&redirect_uri=https%3A%2F%2Ftest.com&code=${code}`, - }); + // check body is correctly formed + const queryParams = fetchMock.mock.calls.find(([endpoint]) => endpoint === metadata.token_endpoint)![1]! + .body as URLSearchParams; + expect(queryParams.get("grant_type")).toEqual("authorization_code"); + expect(queryParams.get("client_id")).toEqual(clientId); + expect(queryParams.get("code_verifier")).toEqual(codeVerifier); + expect(queryParams.get("redirect_uri")).toEqual(redirectUri); + expect(queryParams.get("code")).toEqual(code); }); it("should return with valid bearer token", async () => { - const result = await completeAuthorizationCodeGrant(code, { - clientId, - codeVerifier, - redirectUri, - delegatedAuthConfig, - nonce, + const state = await setupState(); + const scope = getValueFromStorage(state, "scope"); + const result = await completeAuthorizationCodeGrant(code, state); + + expect(result).toEqual({ + homeserverUrl, + identityServerUrl, + oidcClientSettings: { + clientId, + issuer: metadata.issuer, + }, + tokenResponse: { + access_token: validBearerTokenResponse.access_token, + id_token: validBearerTokenResponse.id_token, + refresh_token: validBearerTokenResponse.refresh_token, + token_type: validBearerTokenResponse.token_type, + // this value is slightly unstable because it uses the clock + expires_at: result.tokenResponse.expires_at, + scope, + }, }); - - expect(result).toEqual(validBearerTokenResponse); }); it("should return with valid bearer token where token_type is lowercase", async () => { + const state = await setupState(); + const scope = getValueFromStorage(state, "scope"); const tokenResponse = { ...validBearerTokenResponse, + scope, token_type: "bearer", }; fetchMock.post( tokenEndpoint, { - status: 200, - body: JSON.stringify(tokenResponse), + headers: { + "Content-Type": "application/json", + }, + ...tokenResponse, }, { overwriteRoutes: true }, ); - const result = await completeAuthorizationCodeGrant(code, { - clientId, - codeVerifier, - redirectUri, - delegatedAuthConfig, - nonce, + const result = await completeAuthorizationCodeGrant(code, state); + + expect(result).toEqual({ + homeserverUrl, + identityServerUrl, + oidcClientSettings: { + clientId, + issuer: metadata.issuer, + }, + // results in token that uses 'Bearer' token type + tokenResponse: { + access_token: validBearerTokenResponse.access_token, + id_token: validBearerTokenResponse.id_token, + refresh_token: validBearerTokenResponse.refresh_token, + token_type: "Bearer", + // this value is slightly unstable because it uses the clock + expires_at: result.tokenResponse.expires_at, + scope, + }, }); - // results in token that uses 'Bearer' token type - expect(result).toEqual(validBearerTokenResponse); - expect(result.token_type).toEqual("Bearer"); + expect(result.tokenResponse.token_type).toEqual("Bearer"); + }); + + it("should throw when state is not found in storage", async () => { + // don't setup sessionStorage with expected state + const state = "abc123"; + fetchMock.post( + metadata.token_endpoint, + { + status: 500, + }, + { overwriteRoutes: true }, + ); + await expect(() => completeAuthorizationCodeGrant(code, state)).rejects.toThrow( + new Error(OidcError.MissingOrInvalidStoredState), + ); }); it("should throw with code exchange failed error when request fails", async () => { + const state = await setupState(); fetchMock.post( - tokenEndpoint, + metadata.token_endpoint, { status: 500, }, { overwriteRoutes: true }, ); - await expect(() => - completeAuthorizationCodeGrant(code, { - clientId, - codeVerifier, - redirectUri, - delegatedAuthConfig, - nonce, - }), - ).rejects.toThrow(new Error(OidcError.CodeExchangeFailed)); + await expect(() => completeAuthorizationCodeGrant(code, state)).rejects.toThrow( + new Error(OidcError.CodeExchangeFailed), + ); }); it("should throw invalid token error when token is invalid", async () => { + const state = await setupState(); const invalidBearerTokenResponse = { ...validBearerTokenResponse, access_token: null, }; fetchMock.post( - tokenEndpoint, - { status: 200, body: JSON.stringify(invalidBearerTokenResponse) }, + metadata.token_endpoint, + { + headers: { + "Content-Type": "application/json", + }, + ...invalidBearerTokenResponse, + }, { overwriteRoutes: true }, ); - await expect(() => - completeAuthorizationCodeGrant(code, { - clientId, - codeVerifier, - redirectUri, - delegatedAuthConfig, - nonce, - }), - ).rejects.toThrow(new Error(OidcError.InvalidBearerTokenResponse)); + await expect(() => completeAuthorizationCodeGrant(code, state)).rejects.toThrow( + new Error(OidcError.InvalidBearerTokenResponse), + ); }); it("should throw invalid id token error when id_token is invalid", async () => { + const state = await setupState(); mocked(jwtDecode).mockReturnValue({ ...validDecodedIdToken, // invalid audience aud: "something-else", }); - await expect(() => - completeAuthorizationCodeGrant(code, { - clientId, - codeVerifier, - redirectUri, - delegatedAuthConfig, - nonce, - }), - ).rejects.toThrow(new Error(OidcError.InvalidIdToken)); + await expect(() => completeAuthorizationCodeGrant(code, state)).rejects.toThrow( + new Error(OidcError.InvalidIdToken), + ); }); }); }); diff --git a/spec/unit/oidc/validate.spec.ts b/spec/unit/oidc/validate.spec.ts index f177d0d5a58..91b6985f02c 100644 --- a/spec/unit/oidc/validate.spec.ts +++ b/spec/unit/oidc/validate.spec.ts @@ -148,10 +148,8 @@ describe("validateOIDCIssuerWellKnown", () => { response_types_supported: [], }); }).toThrow(OidcError.OpSupport); - expect(logger.error).toHaveBeenCalledWith("OIDC issuer configuration: authorization_endpoint is invalid"); - expect(logger.error).toHaveBeenCalledWith( - "OIDC issuer configuration: response_types_supported is invalid. code is required.", - ); + expect(logger.error).toHaveBeenCalledWith("Missing or invalid property: authorization_endpoint"); + expect(logger.error).toHaveBeenCalledWith("Invalid property: response_types_supported. code is required."); }); it("should return validated issuer config", () => { diff --git a/src/oidc/authorize.ts b/src/oidc/authorize.ts index 8dca760c5cf..df802aa0a4f 100644 --- a/src/oidc/authorize.ts +++ b/src/oidc/authorize.ts @@ -14,15 +14,24 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { OidcClient, WebStorageStateStore } from "oidc-client-ts"; +import { Log, OidcClient, SigninResponse, SigninState, WebStorageStateStore } from "oidc-client-ts"; import { IDelegatedAuthConfig } from "../client"; -import { Method } from "../http-api"; import { subtleCrypto, TextEncoder } from "../crypto/crypto"; import { logger } from "../logger"; import { randomString } from "../randomstring"; import { OidcError } from "./error"; -import { validateIdToken, ValidatedIssuerConfig, ValidatedIssuerMetadata, UserState } from "./validate"; +import { + validateIdToken, + ValidatedIssuerMetadata, + validateStoredUserState, + UserState, + BearerTokenResponse, + validateBearerTokenResponse, +} from "./validate"; + +// reexport for backwards compatibility +export type { BearerTokenResponse }; /** * Authorization parameters which are used in the authentication request of an OIDC auth code flow. @@ -152,37 +161,6 @@ export const generateOidcAuthorizationUrl = async ({ return request.url; }; -/** - * The expected response type from the token endpoint during authorization code flow - * Normalized to always use capitalized 'Bearer' for token_type - * - * See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.4, - * https://openid.net/specs/openid-connect-basic-1_0.html#TokenOK. - */ -export type BearerTokenResponse = { - token_type: "Bearer"; - access_token: string; - scope: string; - refresh_token?: string; - expires_in?: number; - id_token?: string; -}; - -/** - * Expected response type from the token endpoint during authorization code flow - * as it comes over the wire. - * Should be normalized to use capital case 'Bearer' for token_type property - * - * See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.4, - * https://openid.net/specs/openid-connect-basic-1_0.html#TokenOK. - */ -type WireBearerTokenResponse = BearerTokenResponse & { - token_type: "Bearer" | "bearer"; -}; - -const isResponseObject = (response: unknown): response is Record => - !!response && typeof response === "object"; - /** * Normalize token_type to use capital case to make consuming the token response easier * token_type is case insensitive, and it is spec-compliant for OPs to return token_type: "bearer" @@ -192,21 +170,18 @@ const isResponseObject = (response: unknown): response is Record ({ - ...response, - token_type: "Bearer", -}); - -const isValidBearerTokenResponse = (response: unknown): response is WireBearerTokenResponse => - isResponseObject(response) && - typeof response["token_type"] === "string" && - // token_type is case insensitive, some OPs return `token_type: "bearer"` - response["token_type"].toLowerCase() === "bearer" && - typeof response["access_token"] === "string" && - (!("refresh_token" in response) || typeof response["refresh_token"] === "string") && - (!("expires_in" in response) || typeof response["expires_in"] === "number"); +const normalizeBearerTokenResponseTokenType = (response: SigninResponse): BearerTokenResponse => + ({ + id_token: response.id_token, + scope: response.scope, + expires_at: response.expires_at, + refresh_token: response.refresh_token, + access_token: response.access_token, + token_type: "Bearer", + } as BearerTokenResponse); /** + * @experimental * Attempt to exchange authorization code for bearer token. * * Takes the authorization code returned by the OpenID Provider via the authorization URL, and makes a @@ -219,47 +194,71 @@ const isValidBearerTokenResponse = (response: unknown): response is WireBearerTo */ export const completeAuthorizationCodeGrant = async ( code: string, - { - clientId, - codeVerifier, - redirectUri, - delegatedAuthConfig, - nonce, - }: { - clientId: string; - codeVerifier: string; - redirectUri: string; - delegatedAuthConfig: IDelegatedAuthConfig & ValidatedIssuerConfig; - nonce: string; - }, -): Promise => { - const params = new URLSearchParams(); - params.append("grant_type", "authorization_code"); - params.append("client_id", clientId); - params.append("code_verifier", codeVerifier); - params.append("redirect_uri", redirectUri); - params.append("code", code); - const metadata = params.toString(); + state: string, +): Promise<{ + oidcClientSettings: IDelegatedAuthConfig & { clientId: string }; + tokenResponse: BearerTokenResponse; + homeserverUrl: string; + identityServerUrl?: string; +}> => { + /** + * Element Web strips and changes the url on starting the app + * Use the code and state from query params to rebuild a url + * so that oidc-client can parse it + */ + const reconstructedUrl = new URL(window.location.origin); + reconstructedUrl.searchParams.append("code", code); + reconstructedUrl.searchParams.append("state", state); - const headers = { "Content-Type": "application/x-www-form-urlencoded" }; + // set oidc-client to use our logger + Log.setLogger(logger); + try { + const response = new SigninResponse(reconstructedUrl.searchParams); - const response = await fetch(delegatedAuthConfig.tokenEndpoint, { - method: Method.Post, - headers, - body: metadata, - }); + const stateStore = new WebStorageStateStore({ prefix: "mx_oidc_", store: window.sessionStorage }); - if (response.status >= 400) { - throw new Error(OidcError.CodeExchangeFailed); - } + // retrieve the state we put in storage at the start of oidc auth flow + const stateString = await stateStore.get(response.state!); + if (!stateString) { + throw new Error(OidcError.MissingOrInvalidStoredState); + } + + // hydrate the sign in state and create a client + // the stored sign in state includes oidc configuration we set at the start of the oidc login flow + const signInState = SigninState.fromStorageString(stateString); + const client = new OidcClient({ ...signInState, stateStore }); - const token = await response.json(); + // validate the code and state, and attempt to swap the code for tokens + const signinResponse = await client.processSigninResponse(reconstructedUrl.href); - if (isValidBearerTokenResponse(token)) { + // extra values we stored at the start of the login flow + // used to complete login in the client + const userState = signinResponse.userState; + validateStoredUserState(userState); + + // throws when response is invalid + validateBearerTokenResponse(signinResponse); // throws when token is invalid - validateIdToken(token.id_token, delegatedAuthConfig.issuer, clientId, nonce); - return normalizeBearerTokenResponseTokenType(token); - } + validateIdToken(signinResponse.id_token, client.settings.authority, client.settings.client_id, userState.nonce); + const normalizedTokenResponse = normalizeBearerTokenResponseTokenType(signinResponse); - throw new Error(OidcError.InvalidBearerTokenResponse); + return { + oidcClientSettings: { + clientId: client.settings.client_id, + issuer: client.settings.authority, + }, + tokenResponse: normalizedTokenResponse, + homeserverUrl: userState.homeserverUrl, + identityServerUrl: userState.identityServerUrl, + }; + } catch (error) { + logger.error("Oidc login failed", error); + const errorType = (error as Error).message; + + // rethrow errors that we recognise + if (Object.values(OidcError).includes(errorType as any)) { + throw error; + } + throw new Error(OidcError.CodeExchangeFailed); + } }; diff --git a/src/oidc/error.ts b/src/oidc/error.ts index 233ae34c519..c71e80830fb 100644 --- a/src/oidc/error.ts +++ b/src/oidc/error.ts @@ -25,4 +25,5 @@ export enum OidcError { CodeExchangeFailed = "Failed to exchange code for token", InvalidBearerTokenResponse = "Invalid bearer token response", InvalidIdToken = "Invalid ID token", + MissingOrInvalidStoredState = "State required to finish logging in is not found in storage.", } diff --git a/src/oidc/validate.ts b/src/oidc/validate.ts index 1db4ba85491..ef3e7c26e28 100644 --- a/src/oidc/validate.ts +++ b/src/oidc/validate.ts @@ -15,7 +15,7 @@ limitations under the License. */ import jwtDecode from "jwt-decode"; -import { OidcMetadata } from "oidc-client-ts"; +import { OidcMetadata, SigninResponse } from "oidc-client-ts"; import { IDelegatedAuthConfig } from "../client"; import { logger } from "../logger"; @@ -62,14 +62,14 @@ const isRecord = (value: unknown): value is Record => !!value && typeof value === "object" && !Array.isArray(value); const requiredStringProperty = (wellKnown: Record, key: string): boolean => { if (!wellKnown[key] || !optionalStringProperty(wellKnown, key)) { - logger.error(`OIDC issuer configuration: ${key} is invalid`); + logger.error(`Missing or invalid property: ${key}`); return false; } return true; }; const optionalStringProperty = (wellKnown: Record, key: string): boolean => { if (!!wellKnown[key] && typeof wellKnown[key] !== "string") { - logger.error(`OIDC issuer configuration: ${key} is invalid`); + logger.error(`Invalid property: ${key}`); return false; } return true; @@ -77,7 +77,7 @@ const optionalStringProperty = (wellKnown: Record, key: string) const requiredArrayValue = (wellKnown: Record, key: string, value: any): boolean => { const array = wellKnown[key]; if (!array || !Array.isArray(array) || !array.includes(value)) { - logger.error(`OIDC issuer configuration: ${key} is invalid. ${value} is required.`); + logger.error(`Invalid property: ${key}. ${value} is required.`); return false; } return true; @@ -245,3 +245,64 @@ export type UserState = { */ nonce: string; }; +/** + * Validate stored user state exists and is valid + * @param userState - userState returned by oidcClient.processSigninResponse + * @throws when userState is invalid + */ +export function validateStoredUserState(userState: unknown): asserts userState is UserState { + if (!isRecord(userState)) { + logger.error("Stored user state not found"); + throw new Error(OidcError.MissingOrInvalidStoredState); + } + const isInvalid = [ + requiredStringProperty(userState, "homeserverUrl"), + requiredStringProperty(userState, "nonce"), + optionalStringProperty(userState, "identityServerUrl"), + ].some((isValid) => !isValid); + + if (isInvalid) { + throw new Error(OidcError.MissingOrInvalidStoredState); + } +} + +/** + * The expected response type from the token endpoint during authorization code flow + * Normalized to always use capitalized 'Bearer' for token_type + * + * See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.4, + * https://openid.net/specs/openid-connect-basic-1_0.html#TokenOK. + */ +export type BearerTokenResponse = { + token_type: "Bearer"; + access_token: string; + scope: string; + refresh_token?: string; + expires_in?: number; + // from oidc-client-ts + expires_at?: number; + id_token?: string; +}; + +/** + * Make required properties required in type + */ +type ValidSignInResponse = SigninResponse & + BearerTokenResponse & { + token_type: "Bearer" | "bearer"; + }; + +const isValidBearerTokenResponse = (response: unknown): response is ValidSignInResponse => + isRecord(response) && + requiredStringProperty(response, "token_type") && + // token_type is case insensitive, some OPs return `token_type: "bearer"` + (response["token_type"] as string).toLowerCase() === "bearer" && + requiredStringProperty(response, "access_token") && + requiredStringProperty(response, "refresh_token") && + (!("expires_in" in response) || typeof response["expires_in"] === "number"); + +export function validateBearerTokenResponse(response: unknown): asserts response is ValidSignInResponse { + if (!isValidBearerTokenResponse(response)) { + throw new Error(OidcError.InvalidBearerTokenResponse); + } +} From d2b782a2f5850b630fe0612eb79aa2849edf49c3 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 11 Jul 2023 08:26:30 +0100 Subject: [PATCH 11/59] Simplify `MatrixClient::setPowerLevel` API (#3570) * Simplify `MatrixClient::setPowerLevel` API While making it more resilient to causing issues like nuking room state * Handle edge case * Fix tests * Add test coverage --- spec/integ/matrix-client-methods.spec.ts | 82 +++++++++++++++++++++--- src/client.ts | 49 ++++++++++---- 2 files changed, 109 insertions(+), 22 deletions(-) diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index 8bf57124d83..da417b8c22f 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -1386,23 +1386,89 @@ describe("MatrixClient", function () { expectation: {}, }, ])("should modify power levels of $userId correctly", async ({ userId, powerLevel, expectation }) => { - const event = { - getType: () => "m.room.power_levels", - getContent: () => ({ - users: { - "alice@localhost": 50, + httpBackend!.when("GET", "/state/m.room.power_levels/").respond(200, { + users: { + "alice@localhost": 50, + }, + }); + + httpBackend! + .when("PUT", "/state/m.room.power_levels") + .check((req) => { + expect(req.data.users).toStrictEqual(expectation); + }) + .respond(200, {}); + + const prom = client!.setPowerLevel("!room_id:server", userId, powerLevel); + await httpBackend!.flushAllExpected(); + await prom; + }); + + it("should use power level from room state if available", async () => { + client!.clientRunning = true; + client!.isInitialSyncComplete = () => true; + const room = new Room("!room_id:server", client!, client!.getUserId()!); + room.currentState.events.set("m.room.power_levels", new Map()); + room.currentState.events.get("m.room.power_levels")!.set( + "", + new MatrixEvent({ + type: "m.room.power_levels", + state_key: "", + content: { + users: { + "@bob:localhost": 50, + }, }, }), - } as MatrixEvent; + ); + client!.getRoom = () => room; httpBackend! .when("PUT", "/state/m.room.power_levels") .check((req) => { - expect(req.data.users).toStrictEqual(expectation); + expect(req.data).toStrictEqual({ + users: { + "@bob:localhost": 50, + [userId]: 42, + }, + }); + }) + .respond(200, {}); + + const prom = client!.setPowerLevel("!room_id:server", userId, 42); + await httpBackend!.flushAllExpected(); + await prom; + }); + + it("should throw error if state API errors", async () => { + httpBackend!.when("GET", "/state/m.room.power_levels/").respond(500, { + errcode: "ERR_DERP", + }); + + const prom = client!.setPowerLevel("!room_id:server", userId, 42); + await Promise.all([ + expect(prom).rejects.toMatchInlineSnapshot(`[ERR_DERP: MatrixError: [500] Unknown message]`), + httpBackend!.flushAllExpected(), + ]); + }); + + it("should not throw error if /state/ API returns M_NOT_FOUND", async () => { + httpBackend!.when("GET", "/state/m.room.power_levels/").respond(404, { + errcode: "M_NOT_FOUND", + }); + + httpBackend! + .when("PUT", "/state/m.room.power_levels") + .check((req) => { + expect(req.data).toStrictEqual({ + users: { + [userId]: 42, + }, + }); }) .respond(200, {}); - const prom = client!.setPowerLevel("!room_id:server", userId, powerLevel, event); + const prom = client!.setPowerLevel("!room_id:server", userId, 42); await httpBackend!.flushAllExpected(); await prom; }); diff --git a/src/client.ts b/src/client.ts index 87464cf640e..9d9e1d3aa19 100644 --- a/src/client.ts +++ b/src/client.ts @@ -111,7 +111,7 @@ import * as ContentHelpers from "./content-helpers"; import { CrossSigningInfo, DeviceTrustLevel, ICacheCallbacks, UserTrustLevel } from "./crypto/CrossSigning"; import { Room, NotificationCountType, RoomEvent, RoomEventHandlerMap, RoomNameState } from "./models/room"; import { RoomMemberEvent, RoomMemberEventHandlerMap } from "./models/room-member"; -import { RoomStateEvent, RoomStateEventHandlerMap } from "./models/room-state"; +import { IPowerLevelsContent, RoomStateEvent, RoomStateEventHandlerMap } from "./models/room-state"; import { IAddThreePidOnlyBody, IBindThreePidBody, @@ -4256,24 +4256,48 @@ export class MatrixClient extends TypedEventEmitter { - let content = { - users: {} as Record, - }; - if (event?.getType() === EventType.RoomPowerLevels) { - // take a copy of the content to ensure we don't corrupt - // existing client state with a failed power level change - content = utils.deepCopy(event.getContent()); + let content: IPowerLevelsContent | undefined; + if (this.clientRunning && this.isInitialSyncComplete()) { + content = this.getRoom(roomId)?.currentState?.getStateEvents(EventType.RoomPowerLevels, "")?.getContent(); + } + if (!content) { + try { + content = await this.getStateEvent(roomId, EventType.RoomPowerLevels, ""); + } catch (e) { + // It is possible for a Matrix room to not have a power levels event + if (e instanceof MatrixError && e.errcode === "M_NOT_FOUND") { + content = {}; + } else { + throw e; + } + } } + // take a copy of the content to ensure we don't corrupt + // existing client state with a failed power level change + content = utils.deepCopy(content); + + if (!content?.users) { + content.users = {}; + } const users = Array.isArray(userId) ? userId : [userId]; for (const user of users) { if (powerLevel == null) { @@ -4283,10 +4307,7 @@ export class MatrixClient extends TypedEventEmitter Date: Tue, 11 Jul 2023 11:24:57 +0100 Subject: [PATCH 12/59] Throw saner error when peeking has its room pulled out from under it (#3577) --- src/sync.ts | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/sync.ts b/src/sync.ts index 4c78aea89a0..1e80ac76c1a 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -407,6 +407,10 @@ export class SyncApi { const client = this.client; this._peekRoom = this.createRoom(roomId); return this.client.roomInitialSync(roomId, 20).then((response) => { + if (this._peekRoom?.roomId !== roomId) { + throw new Error("Peeking aborted"); + } + // make sure things are init'd response.messages = response.messages || { chunk: [] }; response.messages.chunk = response.messages.chunk || []; @@ -438,31 +442,31 @@ export class SyncApi { // fire off pagination requests in response to the Room.timeline // events. if (response.messages.start) { - this._peekRoom!.oldState.paginationToken = response.messages.start; + this._peekRoom.oldState.paginationToken = response.messages.start; } // set the state of the room to as it was after the timeline executes - this._peekRoom!.oldState.setStateEvents(oldStateEvents); - this._peekRoom!.currentState.setStateEvents(stateEvents); + this._peekRoom.oldState.setStateEvents(oldStateEvents); + this._peekRoom.currentState.setStateEvents(stateEvents); - this.resolveInvites(this._peekRoom!); - this._peekRoom!.recalculate(); + this.resolveInvites(this._peekRoom); + this._peekRoom.recalculate(); // roll backwards to diverge old state. addEventsToTimeline // will overwrite the pagination token, so make sure it overwrites // it with the right thing. - this._peekRoom!.addEventsToTimeline( + this._peekRoom.addEventsToTimeline( messages.reverse(), true, - this._peekRoom!.getLiveTimeline(), + this._peekRoom.getLiveTimeline(), response.messages.start, ); - client.store.storeRoom(this._peekRoom!); - client.emit(ClientEvent.Room, this._peekRoom!); + client.store.storeRoom(this._peekRoom); + client.emit(ClientEvent.Room, this._peekRoom); - this.peekPoll(this._peekRoom!); - return this._peekRoom!; + this.peekPoll(this._peekRoom); + return this._peekRoom; }); } From 77267e393c8fc9ab6921649e05d309478db925b5 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 11 Jul 2023 13:37:16 +0100 Subject: [PATCH 13/59] Prepare changelog for v27.0.0-rc.1 --- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a0e121a4a9..d55d46c52dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +Changes in [27.0.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v27.0.0-rc.1) (2023-07-11) +============================================================================================================ + +## 🚨 BREAKING CHANGES + * Improve types around login, registration, UIA and identity servers ([\#3537](https://github.com/matrix-org/matrix-js-sdk/pull/3537)). + +## 🦖 Deprecations + * **The Browserify artifact is being deprecated, scheduled for removal in the October 10th release cycle. (#3189)** + * Simplify `MatrixClient::setPowerLevel` API ([\#3570](https://github.com/matrix-org/matrix-js-sdk/pull/3570)). Fixes vector-im/element-web#13900 and #1844. + * Deprecate `VerificationRequest.getQRCodeBytes` and replace it with the asynchronous `generateQRCode`. ([\#3562](https://github.com/matrix-org/matrix-js-sdk/pull/3562)). + * Drop support for Node 16 ([\#3533](https://github.com/matrix-org/matrix-js-sdk/pull/3533)). + * Deprecate `VerificationRequest.beginKeyVerification()` in favour of `VerificationRequest.startVerification()`. ([\#3528](https://github.com/matrix-org/matrix-js-sdk/pull/3528)). + * Deprecate `Crypto.VerificationRequest` application event, replacing it with `Crypto.VerificationRequestReceived`. ([\#3514](https://github.com/matrix-org/matrix-js-sdk/pull/3514)). + +## ✨ Features + * Throw saner error when peeking has its room pulled out from under it ([\#3577](https://github.com/matrix-org/matrix-js-sdk/pull/3577)). Fixes vector-im/element-web#18679. + * OIDC: Log in ([\#3554](https://github.com/matrix-org/matrix-js-sdk/pull/3554)). Contributed by @kerryarchibald. + * Prevent threads code from making identical simultaneous API hits ([\#3541](https://github.com/matrix-org/matrix-js-sdk/pull/3541)). Fixes vector-im/element-web#25395. + * Update IUnsigned type to be extensible ([\#3547](https://github.com/matrix-org/matrix-js-sdk/pull/3547)). + * add stop() api to BackupManager for clean shutdown ([\#3553](https://github.com/matrix-org/matrix-js-sdk/pull/3553)). + * Log the message ID of any undecryptable to-device messages ([\#3543](https://github.com/matrix-org/matrix-js-sdk/pull/3543)). + * Ignore thread relations on state events for consistency with edits ([\#3540](https://github.com/matrix-org/matrix-js-sdk/pull/3540)). + * OIDC: validate id token ([\#3531](https://github.com/matrix-org/matrix-js-sdk/pull/3531)). Contributed by @kerryarchibald. + +## 🐛 Bug Fixes + * Fix `TypedEventEmitter::removeAllListeners(void)` not working ([\#3561](https://github.com/matrix-org/matrix-js-sdk/pull/3561)). + * Don't allow Olm unwedging rate-limiting to race ([\#3549](https://github.com/matrix-org/matrix-js-sdk/pull/3549)). Fixes vector-im/element-web#25716. + * Fix an instance of failed to decrypt error when an in flight `/keys/query` fails. ([\#3486](https://github.com/matrix-org/matrix-js-sdk/pull/3486)). + * Use the right anchor emoji for SAS verification ([\#3534](https://github.com/matrix-org/matrix-js-sdk/pull/3534)). + * fix a bug which caused the wrong emoji to be shown during SAS device verification. ([\#3523](https://github.com/matrix-org/matrix-js-sdk/pull/3523)). + Changes in [26.2.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v26.2.0) (2023-07-04) ================================================================================================== From dcf71e0c8fdb4d3afce15042570a89ec210418d4 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 11 Jul 2023 13:37:19 +0100 Subject: [PATCH 14/59] v27.0.0-rc.1 --- package.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 1d8af896c9d..d100887a975 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "26.2.0", + "version": "27.0.0-rc.1", "description": "Matrix Client-Server SDK for Javascript", "engines": { "node": ">=18.0.0" @@ -32,8 +32,8 @@ "keywords": [ "matrix-org" ], - "main": "./src/index.ts", - "browser": "./src/browser-index.ts", + "main": "./lib/index.js", + "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.ts", "matrix_lib_main": "./lib/index.js", @@ -158,5 +158,6 @@ "no-rust-crypto": { "src/rust-crypto/index.ts$": "./src/rust-crypto/browserify-index.ts" } - } + }, + "typings": "./lib/index.d.ts" } From f2471b6dbd5d5fd7304eec480b12c33fce6a7734 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 11 Jul 2023 14:31:12 +0100 Subject: [PATCH 15/59] Add methods to influence set_presence on /sync API calls (#3578) * Add methods to influence set_presence on /sync API calls * Tweak comment * Improve coverage --- spec/integ/matrix-client-methods.spec.ts | 11 +++++++++++ src/client.ts | 12 +++++++++++- src/sliding-sync-sdk.ts | 9 +++++++++ src/sync.ts | 13 ++++++++++++- 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index da417b8c22f..48dcccba963 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -26,6 +26,7 @@ import { IFilterDefinition } from "../../src/filter"; import { ISearchResults } from "../../src/@types/search"; import { IStore } from "../../src/store"; import { CryptoBackend } from "../../src/common-crypto/CryptoBackend"; +import { SetPresence } from "../../src/sync"; describe("MatrixClient", function () { const userId = "@alice:localhost"; @@ -1516,6 +1517,16 @@ describe("MatrixClient", function () { expect(mockBackend.setTrustCrossSignedDevices).toHaveBeenLastCalledWith(false); }); }); + + describe("setSyncPresence", () => { + it("should pass calls through to the underlying sync api", () => { + const setPresence = jest.fn(); + // @ts-ignore + client.syncApi = { setPresence }; + client?.setSyncPresence(SetPresence.Unavailable); + expect(setPresence).toHaveBeenCalledWith(SetPresence.Unavailable); + }); + }); }); function withThreadId(event: MatrixEvent, newThreadId: string): MatrixEvent { diff --git a/src/client.ts b/src/client.ts index 9d9e1d3aa19..601a2746c7d 100644 --- a/src/client.ts +++ b/src/client.ts @@ -21,7 +21,7 @@ limitations under the License. import { Optional } from "matrix-events-sdk"; import type { IDeviceKeys, IMegolmSessionData, IOneTimeKey } from "./@types/crypto"; -import { ISyncStateData, SyncApi, SyncApiOptions, SyncState } from "./sync"; +import { ISyncStateData, SetPresence, SyncApi, SyncApiOptions, SyncState } from "./sync"; import { EventStatus, IContent, @@ -5531,6 +5531,16 @@ export class MatrixClient extends TypedEventEmitter { + this.syncApi?.setPresence(presence); + } + /** * @param opts - Options to apply * @returns Promise which resolves diff --git a/src/sliding-sync-sdk.ts b/src/sliding-sync-sdk.ts index 36eed5d73e2..78014422270 100644 --- a/src/sliding-sync-sdk.ts +++ b/src/sliding-sync-sdk.ts @@ -27,6 +27,7 @@ import { SyncApiOptions, defaultClientOpts, defaultSyncApiOpts, + SetPresence, } from "./sync"; import { MatrixEvent } from "./models/event"; import { Crypto } from "./crypto"; @@ -463,6 +464,14 @@ export class SlidingSyncSdk { // TODO } + /** + * Specify the set_presence value to be used for subsequent calls to the Sync API. + * @param presence - the presence to specify to set_presence of sync calls + */ + public setPresence(presence?: SetPresence): void { + // TODO not possible in sliding sync yet + } + /** * Returns the current state of this sync object * @see MatrixClient#event:"sync" diff --git a/src/sync.ts b/src/sync.ts index 1e80ac76c1a..49bddc045f1 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -168,7 +168,7 @@ export interface ISyncStateData { fromCache?: boolean; } -enum SetPresence { +export enum SetPresence { Offline = "offline", Online = "online", Unavailable = "unavailable", @@ -225,6 +225,7 @@ export class SyncApi { private notifEvents: MatrixEvent[] = []; // accumulator of sync events in the current sync response private failedSyncCount = 0; // Number of consecutive failed /sync requests private storeIsInvalid = false; // flag set if the store needs to be cleared before we can start + private presence?: SetPresence; /** * Construct an entity which is able to sync with a homeserver. @@ -1009,6 +1010,8 @@ export class SyncApi { if (this.opts.disablePresence) { qps.set_presence = SetPresence.Offline; + } else if (this.presence !== undefined) { + qps.set_presence = this.presence; } if (syncToken) { @@ -1031,6 +1034,14 @@ export class SyncApi { return qps; } + /** + * Specify the set_presence value to be used for subsequent calls to the Sync API. + * @param presence - the presence to specify to set_presence of sync calls + */ + public setPresence(presence?: SetPresence): void { + this.presence = presence; + } + private async onSyncError(err: MatrixError): Promise { if (!this.running) { debuglog("Sync no longer running: exiting"); From a5e606a1e7809f8ea5875c8103476d803befbdd0 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 11 Jul 2023 15:11:35 +0100 Subject: [PATCH 16/59] Mark all the rust crypto stuff internal (#3574) ... for the avoidance of doubt. --- src/common-crypto/CryptoBackend.ts | 10 +++++++++- src/rust-crypto/CrossSigningIdentity.ts | 2 ++ src/rust-crypto/KeyClaimManager.ts | 2 ++ src/rust-crypto/OutgoingRequestProcessor.ts | 4 ++++ src/rust-crypto/RoomEncryptor.ts | 2 ++ src/rust-crypto/device-converter.ts | 6 ++++++ src/rust-crypto/index.ts | 2 ++ src/rust-crypto/rust-crypto.ts | 2 ++ src/rust-crypto/secret-storage.ts | 2 ++ src/rust-crypto/verification.ts | 5 +++++ 10 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/common-crypto/CryptoBackend.ts b/src/common-crypto/CryptoBackend.ts index fef3950775b..c6888437d55 100644 --- a/src/common-crypto/CryptoBackend.ts +++ b/src/common-crypto/CryptoBackend.ts @@ -24,6 +24,8 @@ import { IEventDecryptionResult } from "../@types/crypto"; /** * Common interface for the crypto implementations + * + * @internal */ export interface CryptoBackend extends SyncCryptoCallbacks, CryptoApi { /** @@ -90,7 +92,10 @@ export interface CryptoBackend extends SyncCryptoCallbacks, CryptoApi { getStoredCrossSigningForUser(userId: string): CrossSigningInfo | null; } -/** The methods which crypto implementations should expose to the Sync api */ +/** The methods which crypto implementations should expose to the Sync api + * + * @internal + */ export interface SyncCryptoCallbacks { /** * Called by the /sync loop whenever there are incoming to-device messages. @@ -146,6 +151,9 @@ export interface SyncCryptoCallbacks { onSyncCompleted(syncState: OnSyncCompletedData): void; } +/** + * @internal + */ export interface OnSyncCompletedData { /** * The 'next_batch' result from /sync, which will become the 'since' token for the next call to /sync. diff --git a/src/rust-crypto/CrossSigningIdentity.ts b/src/rust-crypto/CrossSigningIdentity.ts index 27eb623100a..5203bd87731 100644 --- a/src/rust-crypto/CrossSigningIdentity.ts +++ b/src/rust-crypto/CrossSigningIdentity.ts @@ -22,6 +22,8 @@ import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProc import { UIAuthCallback } from "../interactive-auth"; /** Manages the cross-signing keys for our own user. + * + * @internal */ export class CrossSigningIdentity { public constructor( diff --git a/src/rust-crypto/KeyClaimManager.ts b/src/rust-crypto/KeyClaimManager.ts index 9df8f89daf9..4b13ef432cf 100644 --- a/src/rust-crypto/KeyClaimManager.ts +++ b/src/rust-crypto/KeyClaimManager.ts @@ -22,6 +22,8 @@ import { OutgoingRequestProcessor } from "./OutgoingRequestProcessor"; * KeyClaimManager: linearises calls to OlmMachine.getMissingSessions to avoid races * * We have one of these per `RustCrypto` (and hence per `MatrixClient`). + * + * @internal */ export class KeyClaimManager { private currentClaimPromise: Promise; diff --git a/src/rust-crypto/OutgoingRequestProcessor.ts b/src/rust-crypto/OutgoingRequestProcessor.ts index 4e98bce8d49..20c0b93fa1b 100644 --- a/src/rust-crypto/OutgoingRequestProcessor.ts +++ b/src/rust-crypto/OutgoingRequestProcessor.ts @@ -34,6 +34,8 @@ import { UIAResponse } from "../@types/uia"; /** * Common interface for all the request types returned by `OlmMachine.outgoingRequests`. + * + * @internal */ export interface OutgoingRequest { readonly id: string | undefined; @@ -49,6 +51,8 @@ export interface OutgoingRequest { * * holding the reference to the `MatrixHttpApi` * * turning `OutgoingRequest`s from the rust backend into HTTP requests, and sending them * * sending the results of such requests back to the rust backend. + * + * @internal */ export class OutgoingRequestProcessor { public constructor( diff --git a/src/rust-crypto/RoomEncryptor.ts b/src/rust-crypto/RoomEncryptor.ts index 1649a69e722..0b51663c2bd 100644 --- a/src/rust-crypto/RoomEncryptor.ts +++ b/src/rust-crypto/RoomEncryptor.ts @@ -26,6 +26,8 @@ import { OutgoingRequestProcessor } from "./OutgoingRequestProcessor"; /** * RoomEncryptor: responsible for encrypting messages to a given room + * + * @internal */ export class RoomEncryptor { private readonly prefixedLogger: PrefixedLogger; diff --git a/src/rust-crypto/device-converter.ts b/src/rust-crypto/device-converter.ts index 54dc838fe1f..56945be830a 100644 --- a/src/rust-crypto/device-converter.ts +++ b/src/rust-crypto/device-converter.ts @@ -23,6 +23,8 @@ import { DeviceKeys } from "../client"; * Convert a {@link RustSdkCryptoJs.Device} to a {@link Device} * @param device - Rust Sdk device * @param userId - owner of the device + * + * @internal */ export function rustDeviceToJsDevice(device: RustSdkCryptoJs.Device, userId: RustSdkCryptoJs.UserId): Device { // Copy rust device keys to Device.keys @@ -84,6 +86,8 @@ export function rustDeviceToJsDevice(device: RustSdkCryptoJs.Device, userId: Rus /** * Convert {@link DeviceKeys} from `/keys/query` request to a `Map` * @param deviceKeys - Device keys object to convert + * + * @internal */ export function deviceKeysToDeviceMap(deviceKeys: DeviceKeys): Map { return new Map( @@ -97,6 +101,8 @@ type QueryDevice = DeviceKeys[keyof DeviceKeys]; /** * Convert `/keys/query` {@link QueryDevice} device to {@link Device} * @param device - Device from `/keys/query` request + * + * @internal */ export function downloadDeviceToJsDevice(device: QueryDevice): Device { const keys = new Map(Object.entries(device.keys)); diff --git a/src/rust-crypto/index.ts b/src/rust-crypto/index.ts index 8697095edff..b606cb6da55 100644 --- a/src/rust-crypto/index.ts +++ b/src/rust-crypto/index.ts @@ -33,6 +33,8 @@ import { ICryptoCallbacks } from "../crypto"; * @param cryptoCallbacks - Crypto callbacks provided by the application * @param storePrefix - the prefix to use on the indexeddbs created by rust-crypto. * If unset, a memory store will be used. + * + * @internal */ export async function initRustCrypto( http: MatrixHttpApi, diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 0146512ed85..0da71c61910 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -58,6 +58,8 @@ import { TypedEventEmitter } from "../models/typed-event-emitter"; /** * An implementation of {@link CryptoBackend} using the Rust matrix-sdk-crypto. + * + * @internal */ export class RustCrypto extends TypedEventEmitter implements CryptoBackend { public globalErrorOnUnknownDevices = false; diff --git a/src/rust-crypto/secret-storage.ts b/src/rust-crypto/secret-storage.ts index 99b6ce00c96..12890b06e81 100644 --- a/src/rust-crypto/secret-storage.ts +++ b/src/rust-crypto/secret-storage.ts @@ -21,6 +21,8 @@ import { ServerSideSecretStorage } from "../secret-storage"; * * @param secretStorage - The secret store using account data * @returns True if the cross-signing keys are all stored and encrypted with the same secret storage key. + * + * @internal */ export async function secretStorageContainsCrossSigningKeys(secretStorage: ServerSideSecretStorage): Promise { // Check if the master cross-signing key is stored in secret storage diff --git a/src/rust-crypto/verification.ts b/src/rust-crypto/verification.ts index 3d8fc48e0ff..7c1b844b1ca 100644 --- a/src/rust-crypto/verification.ts +++ b/src/rust-crypto/verification.ts @@ -33,6 +33,8 @@ import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProc /** * An incoming, or outgoing, request to verify a user or a device via cross-signing. + * + * @internal */ export class RustVerificationRequest extends TypedEventEmitter @@ -357,6 +359,7 @@ export class RustVerificationRequest } } +/** @internal */ export class RustSASVerifier extends TypedEventEmitter implements Verifier { /** A promise which completes when the verification completes (or rejects when it is cancelled/fails) */ private readonly completionPromise: Promise; @@ -507,6 +510,8 @@ const verificationMethodsByIdentifier: Record Date: Tue, 11 Jul 2023 16:13:53 +0200 Subject: [PATCH 17/59] Use `cryptoBackend` in `client.ts` for new rust-crypto implementation (#3576) * Use `cryptoBackend` in `client.ts` for new rust-crypto implementation for backward compatibility * Use `cryptoBackend` in `client.ts` for new rust-crypto implementation for backward compatibility --- src/client.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/client.ts b/src/client.ts index 601a2746c7d..a5343258e5e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2854,12 +2854,14 @@ export class MatrixClient extends TypedEventEmitter { - if (!this.crypto) { + if (!this.cryptoBackend) { throw new Error("End-to-end encryption disabled"); } - return this.crypto.createRecoveryKeyFromPassphrase(password); + return this.cryptoBackend.createRecoveryKeyFromPassphrase(password); } /** @@ -2874,7 +2876,7 @@ export class MatrixClient extends TypedEventEmitter { if (!this.cryptoBackend) { @@ -2896,13 +2898,13 @@ export class MatrixClient extends TypedEventEmitter { - if (!this.crypto) { + if (!this.cryptoBackend) { throw new Error("End-to-end encryption disabled"); } - return this.crypto.bootstrapSecretStorage(opts); + return this.cryptoBackend.bootstrapSecretStorage(opts); } /** From 9db6ce107a0477770eaf45840d131105601fdf6f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 11 Jul 2023 17:00:59 +0100 Subject: [PATCH 18/59] Add support for scanning QR codes during verification, with Rust crypto (#3565) * Offer `m.qr_code.scan.v1` verification method by default Normally, the application specifies the supported verification methods when creating the MatrixClient (and matrix-react-sdk does so). If the application leaves it unset, then the idea is that the js-sdk offers all known verification methods. However, by default, the rust-sdk doesn't specify `m.qr_code.scan.v1`. So basically, we need to set our own list of supported methods, rather than relying on the rust-sdk's defaults. * Factor out base class from `RustSASVerifier` * Implement QR code scanning * Update src/rust-crypto/verification.ts --- spec/integ/crypto/verification.spec.ts | 81 +++++++ spec/unit/rust-crypto/verification.spec.ts | 2 +- src/client.ts | 2 +- src/crypto-api/verification.ts | 15 ++ .../request/VerificationRequest.ts | 4 + src/rust-crypto/rust-crypto.ts | 24 +- src/rust-crypto/verification.ts | 217 ++++++++++++------ 7 files changed, 269 insertions(+), 76 deletions(-) diff --git a/spec/integ/crypto/verification.spec.ts b/spec/integ/crypto/verification.spec.ts index 5238871d208..1a8ce32f116 100644 --- a/spec/integ/crypto/verification.spec.ts +++ b/spec/integ/crypto/verification.spec.ts @@ -85,6 +85,10 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st // Rust backend. Once we have full support in the rust sdk, it will go away. const oldBackendOnly = backend === "rust-sdk" ? test.skip : test; + // newBackendOnly is the opposite to `oldBackendOnly`: it will skip the test if we are running against the legacy + // backend. + const newBackendOnly = backend === "rust-sdk" ? test : test.skip; + /** the client under test */ let aliceClient: MatrixClient; @@ -469,6 +473,64 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st await verificationPromise; expect(request.phase).toEqual(VerificationPhase.Done); }); + + newBackendOnly("can verify another by scanning their QR code", async () => { + aliceClient = await startTestClient(); + // we need cross-signing keys for a QR code verification + e2eKeyResponder.addCrossSigningData(SIGNED_CROSS_SIGNING_KEYS_DATA); + await waitForDeviceList(); + + // Alice sends a m.key.verification.request + const [, request] = await Promise.all([ + expectSendToDeviceMessage("m.key.verification.request"), + aliceClient.getCrypto()!.requestDeviceVerification(TEST_USER_ID, TEST_DEVICE_ID), + ]); + const transactionId = request.transactionId!; + + // The dummy device replies with an m.key.verification.ready, indicating it can show a QR code + returnToDeviceMessageFromSync(buildReadyMessage(transactionId, ["m.qr_code.show.v1", "m.reciprocate.v1"])); + await waitForVerificationRequestChanged(request); + expect(request.phase).toEqual(VerificationPhase.Ready); + expect(request.otherPartySupportsMethod("m.qr_code.show.v1")).toBe(true); + + // the dummy device shows a QR code + const sharedSecret = "SUPERSEKRET"; + const qrCodeBuffer = buildQRCode( + transactionId, + TEST_DEVICE_PUBLIC_ED25519_KEY_BASE64, + MASTER_CROSS_SIGNING_PUBLIC_KEY_BASE64, + sharedSecret, + ); + + // Alice scans the QR code + const sendToDevicePromise = expectSendToDeviceMessage("m.key.verification.start"); + const verifier = await request.scanQRCode(qrCodeBuffer); + + const requestBody = await sendToDevicePromise; + const toDeviceMessage = requestBody.messages[TEST_USER_ID][TEST_DEVICE_ID]; + expect(toDeviceMessage).toEqual({ + from_device: aliceClient.deviceId, + method: "m.reciprocate.v1", + transaction_id: transactionId, + secret: encodeUnpaddedBase64(Buffer.from(sharedSecret)), + }); + + expect(request.phase).toEqual(VerificationPhase.Started); + expect(request.chosenMethod).toEqual("m.reciprocate.v1"); + expect(verifier.getReciprocateQrCodeCallbacks()).toBeNull(); + + const verificationPromise = verifier.verify(); + + // the dummy device confirms that Alice scanned the QR code, by replying with a done + returnToDeviceMessageFromSync(buildDoneMessage(transactionId)); + + // Alice also replies with a 'done' + await expectSendToDeviceMessage("m.key.verification.done"); + + // ... and the whole thing should be done! + await verificationPromise; + expect(request.phase).toEqual(VerificationPhase.Done); + }); }); describe("cancellation", () => { @@ -794,3 +856,22 @@ function buildDoneMessage(transactionId: string) { }, }; } + +function buildQRCode(transactionId: string, key1Base64: string, key2Base64: string, sharedSecret: string): Uint8Array { + // https://spec.matrix.org/v1.7/client-server-api/#qr-code-format + + const qrCodeBuffer = Buffer.alloc(150); // oversize + let idx = 0; + idx += qrCodeBuffer.write("MATRIX", idx, "ascii"); + idx = qrCodeBuffer.writeUInt8(0x02, idx); // version + idx = qrCodeBuffer.writeUInt8(0x02, idx); // mode + idx = qrCodeBuffer.writeInt16BE(transactionId.length, idx); + idx += qrCodeBuffer.write(transactionId, idx, "ascii"); + + idx += Buffer.from(key1Base64, "base64").copy(qrCodeBuffer, idx); + idx += Buffer.from(key2Base64, "base64").copy(qrCodeBuffer, idx); + idx += qrCodeBuffer.write(sharedSecret, idx); + + // truncate to the right length + return qrCodeBuffer.subarray(0, idx); +} diff --git a/spec/unit/rust-crypto/verification.spec.ts b/spec/unit/rust-crypto/verification.spec.ts index d74e8de1a4e..a2f671fdb0b 100644 --- a/spec/unit/rust-crypto/verification.spec.ts +++ b/spec/unit/rust-crypto/verification.spec.ts @@ -87,7 +87,7 @@ function makeTestRequest( ): RustVerificationRequest { inner ??= makeMockedInner(); outgoingRequestProcessor ??= {} as OutgoingRequestProcessor; - return new RustVerificationRequest(inner, outgoingRequestProcessor, undefined); + return new RustVerificationRequest(inner, outgoingRequestProcessor, []); } /** Mock up a rust-side VerificationRequest */ diff --git a/src/client.ts b/src/client.ts index a5343258e5e..e84a19d0e94 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2241,7 +2241,7 @@ export class MatrixClient extends TypedEventEmitter; + /** + * Start a QR code verification by providing a scanned QR code for this verification flow. + * + * Validates the QR code, and if it is ok, sends an `m.key.verification.start` event with `method` set to + * `m.reciprocate.v1`, to tell the other side the scan was successful. + * + * See also {@link VerificationRequest#startVerification} which can be used to start other verification methods. + * + * @param qrCodeData - the decoded QR code. + * @returns A verifier; call `.verify()` on it to wait for the other side to complete the verification flow. + */ + scanQRCode(qrCodeData: Uint8Array): Promise; + /** * The verifier which is doing the actual verification, once the method has been established. * Only defined when the `phase` is Started. diff --git a/src/crypto/verification/request/VerificationRequest.ts b/src/crypto/verification/request/VerificationRequest.ts index 7bcb948b4e3..ffcefc4db0e 100644 --- a/src/crypto/verification/request/VerificationRequest.ts +++ b/src/crypto/verification/request/VerificationRequest.ts @@ -478,6 +478,10 @@ export class VerificationRequest { + throw new Error("QR code scanning not supported by legacy crypto"); + } + /** * sends the initial .request event. * @returns resolves when the event has been sent. diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 0da71c61910..5ca8b7f65dd 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -56,6 +56,8 @@ import { EventType } from "../@types/event"; import { CryptoEvent } from "../crypto"; import { TypedEventEmitter } from "../models/typed-event-emitter"; +const ALL_VERIFICATION_METHODS = ["m.sas.v1", "m.qr_code.scan.v1", "m.qr_code.show.v1", "m.reciprocate.v1"]; + /** * An implementation of {@link CryptoBackend} using the Rust matrix-sdk-crypto. * @@ -560,7 +562,7 @@ export class RustCrypto extends TypedEventEmitter => { // if we now have a `Verification` where we lacked one before, wrap it. - // TODO: QR support if (this._verifier === undefined) { const verification: RustSdkCryptoJs.Qr | RustSdkCryptoJs.Sas | undefined = this.inner.getVerification(); if (verification instanceof RustSdkCryptoJs.Sas) { - this._verifier = new RustSASVerifier(verification, this, outgoingRequestProcessor); + this.setVerifier(new RustSASVerifier(verification, this, outgoingRequestProcessor)); + } else if (verification instanceof RustSdkCryptoJs.Qr) { + this.setVerifier(new RustQrCodeVerifier(verification, outgoingRequestProcessor)); } } @@ -77,6 +78,10 @@ export class RustVerificationRequest inner.registerChangesCallback(onChange); } + private setVerifier(verifier: RustSASVerifier | RustQrCodeVerifier): void { + this._verifier = verifier; + } + /** * Unique ID for this verification request. * @@ -188,6 +193,8 @@ export class RustVerificationRequest // TODO: this isn't quite right. The existence of a Verification doesn't prove that we have .started. if (verification instanceof RustSdkCryptoJs.Sas) { return "m.sas.v1"; + } else if (verification instanceof RustSdkCryptoJs.Qr) { + return "m.reciprocate.v1"; } else { return null; } @@ -225,12 +232,9 @@ export class RustVerificationRequest this._accepting = true; try { - const req: undefined | OutgoingRequest = - this.supportedVerificationMethods === undefined - ? this.inner.accept() - : this.inner.acceptWithMethods( - this.supportedVerificationMethods.map(verificationMethodIdentifierToMethod), - ); + const req: undefined | OutgoingRequest = this.inner.acceptWithMethods( + this.supportedVerificationMethods.map(verificationMethodIdentifierToMethod), + ); if (req) { await this.outgoingRequestProcessor.makeOutgoingRequest(req); } @@ -315,6 +319,32 @@ export class RustVerificationRequest return this._verifier; } + /** + * Start a QR code verification by providing a scanned QR code for this verification flow. + * + * Implementation of {@link Crypto.VerificationRequest#scanQRCode}. + * + * @param qrCodeData - the decoded QR code. + * @returns A verifier; call `.verify()` on it to wait for the other side to complete the verification flow. + */ + public async scanQRCode(uint8Array: Uint8Array): Promise { + const scan = RustSdkCryptoJs.QrCodeScan.fromBytes(new Uint8ClampedArray(uint8Array)); + const verifier: RustSdkCryptoJs.Qr = await this.inner.scanQrCode(scan); + + // this should have triggered the onChange callback, and we should now have a verifier + if (!this._verifier) { + throw new Error("Still no verifier after scanQrCode() call"); + } + + // we can immediately trigger the reciprocate request + const req: undefined | OutgoingRequest = verifier.reciprocate(); + if (req) { + await this.outgoingRequestProcessor.makeOutgoingRequest(req); + } + + return this._verifier; + } + /** * The verifier which is doing the actual verification, once the method has been established. * Only defined when the `phase` is Started. @@ -359,23 +389,28 @@ export class RustVerificationRequest } } -/** @internal */ -export class RustSASVerifier extends TypedEventEmitter implements Verifier { +/** Common base class for `Verifier` implementations which wrap rust classes. + * + * The generic parameter `InnerType` is the type of the rust Verification class which we wrap. + * + * @internal + */ +abstract class BaseRustVerifer extends TypedEventEmitter< + VerifierEvent, + VerifierEventHandlerMap +> { /** A promise which completes when the verification completes (or rejects when it is cancelled/fails) */ - private readonly completionPromise: Promise; - - private callbacks: ShowSasCallbacks | null = null; + protected readonly completionPromise: Promise; public constructor( - private readonly inner: RustSdkCryptoJs.Sas, - _verificationRequest: RustVerificationRequest, - private readonly outgoingRequestProcessor: OutgoingRequestProcessor, + protected readonly inner: InnerType, + protected readonly outgoingRequestProcessor: OutgoingRequestProcessor, ) { super(); this.completionPromise = new Promise((resolve, reject) => { const onChange = async (): Promise => { - this.updateCallbacks(); + this.onChange(); if (this.inner.isDone()) { resolve(undefined); @@ -396,37 +431,12 @@ export class RustSASVerifier extends TypedEventEmitter null); } - /** if we can now show the callbacks, do so */ - private updateCallbacks(): void { - if (this.callbacks === null) { - const emoji: Array | undefined = this.inner.emoji(); - const decimal = this.inner.decimals() as [number, number, number] | undefined; - - if (emoji === undefined && decimal === undefined) { - return; - } - - this.callbacks = { - sas: { - decimal: decimal, - emoji: emoji?.map((e) => [e.symbol, e.description]), - }, - confirm: async (): Promise => { - const requests: Array = await this.inner.confirm(); - for (const m of requests) { - await this.outgoingRequestProcessor.makeOutgoingRequest(m); - } - }, - mismatch: (): void => { - throw new Error("impl"); - }, - cancel: (): void => { - throw new Error("impl"); - }, - }; - this.emit(VerifierEvent.ShowSas, this.callbacks); - } - } + /** + * Hook which is called when the underlying rust class notifies us that there has been a change. + * + * Can be overridden by subclasses to see if we can notify the application about an update. + */ + protected onChange(): void {} /** * Returns true if the verification has been cancelled, either by us or the other side. @@ -442,23 +452,6 @@ export class RustSASVerifier extends TypedEventEmitter { - const req: undefined | OutgoingRequest = this.inner.accept(); - if (req) { - await this.outgoingRequestProcessor.makeOutgoingRequest(req); - } - await this.completionPromise; - } - /** * Cancel a verification. * @@ -482,7 +475,7 @@ export class RustSASVerifier extends TypedEventEmitter implements Verifier { + public constructor(inner: RustSdkCryptoJs.Qr, outgoingRequestProcessor: OutgoingRequestProcessor) { + super(inner, outgoingRequestProcessor); + } + + /** + * Start the key verification, if it has not already been started. + * + * @returns Promise which resolves when the verification has completed, or rejects if the verification is cancelled + * or times out. + */ + public async verify(): Promise { + // Nothing to do here but wait. + await this.completionPromise; + } +} + +/** A Verifier instance which is used if we are exchanging emojis */ +export class RustSASVerifier extends BaseRustVerifer implements Verifier { + private callbacks: ShowSasCallbacks | null = null; + + public constructor( + inner: RustSdkCryptoJs.Sas, + _verificationRequest: RustVerificationRequest, + outgoingRequestProcessor: OutgoingRequestProcessor, + ) { + super(inner, outgoingRequestProcessor); + } + + /** + * Start the key verification, if it has not already been started. + * + * This means sending a `m.key.verification.start` if we are the first responder, or a `m.key.verification.accept` + * if the other side has already sent a start event. + * + * @returns Promise which resolves when the verification has completed, or rejects if the verification is cancelled + * or times out. + */ + public async verify(): Promise { + const req: undefined | OutgoingRequest = this.inner.accept(); + if (req) { + await this.outgoingRequestProcessor.makeOutgoingRequest(req); + } + await this.completionPromise; + } + + /** if we can now show the callbacks, do so */ + protected onChange(): void { + if (this.callbacks === null) { + const emoji: Array | undefined = this.inner.emoji(); + const decimal = this.inner.decimals() as [number, number, number] | undefined; + + if (emoji === undefined && decimal === undefined) { + return; + } + + this.callbacks = { + sas: { + decimal: decimal, + emoji: emoji?.map((e) => [e.symbol, e.description]), + }, + confirm: async (): Promise => { + const requests: Array = await this.inner.confirm(); + for (const m of requests) { + await this.outgoingRequestProcessor.makeOutgoingRequest(m); + } + }, + mismatch: (): void => { + throw new Error("impl"); + }, + cancel: (): void => { + throw new Error("impl"); + }, + }; + this.emit(VerifierEvent.ShowSas, this.callbacks); + } + } + + /** + * Get the details for an SAS verification, if one is in progress + * + * Returns `null`, unless this verifier is for a SAS-based verification and we are waiting for the user to confirm + * the SAS matches. + */ + public getShowSasCallbacks(): ShowSasCallbacks | null { + return this.callbacks; + } +} + /** For each specced verification method, the rust-side `VerificationMethod` corresponding to it */ const verificationMethodsByIdentifier: Record = { "m.sas.v1": RustSdkCryptoJs.VerificationMethod.SasV1, From 3385adf5f6bae29344ae549ca97539736e8f8811 Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 11 Jul 2023 19:27:42 +0200 Subject: [PATCH 19/59] Improve logging of http requests to aid debugging (#3485) * Simple request logging with status and duration * remove url params from logs * superfluous toString() * Add tests * Apply suggestions from code review * update snapshots * update log format * Apply suggestions from code review Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> * update snapshot --------- Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Co-authored-by: Richard van der Hoff --- spec/unit/http-api/fetch.spec.ts | 31 ++++++++++++++++++++++++++++++- src/http-api/fetch.ts | 24 ++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/spec/unit/http-api/fetch.spec.ts b/spec/unit/http-api/fetch.spec.ts index 77ac2e3a4c6..236fbe1c32f 100644 --- a/spec/unit/http-api/fetch.spec.ts +++ b/spec/unit/http-api/fetch.spec.ts @@ -14,11 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { mocked } from "jest-mock"; + import { FetchHttpApi } from "../../../src/http-api/fetch"; import { TypedEventEmitter } from "../../../src/models/typed-event-emitter"; import { ClientPrefix, HttpApiEvent, HttpApiEventHandlerMap, IdentityPrefix, IHttpOpts, Method } from "../../../src"; import { emitPromise } from "../../test-utils/test-utils"; -import { QueryDict } from "../../../src/utils"; +import { defer, QueryDict } from "../../../src/utils"; +import { logger } from "../../../src/logger"; describe("FetchHttpApi", () => { const baseUrl = "http://baseUrl"; @@ -290,4 +293,30 @@ describe("FetchHttpApi", () => { runTests(baseUrlWithTrailingSlash); }); }); + + it("should not log query parameters", async () => { + jest.useFakeTimers(); + const deferred = defer(); + const fetchFn = jest.fn().mockReturnValue(deferred.promise); + jest.spyOn(logger, "debug").mockImplementation(() => {}); + const api = new FetchHttpApi(new TypedEventEmitter(), { baseUrl, prefix, fetchFn }); + const prom = api.requestOtherUrl(Method.Get, "https://server:8448/some/path#fragment?query=param"); + jest.advanceTimersByTime(1234); + deferred.resolve({ ok: true, status: 200, text: () => Promise.resolve("RESPONSE") } as Response); + await prom; + expect(logger.debug).not.toHaveBeenCalledWith("fragment"); + expect(logger.debug).not.toHaveBeenCalledWith("query"); + expect(logger.debug).not.toHaveBeenCalledWith("param"); + expect(logger.debug).toHaveBeenCalledTimes(2); + expect(mocked(logger.debug).mock.calls[0]).toMatchInlineSnapshot(` + [ + "FetchHttpApi: --> GET https://server:8448/some/path", + ] + `); + expect(mocked(logger.debug).mock.calls[1]).toMatchInlineSnapshot(` + [ + "FetchHttpApi: <-- GET https://server:8448/some/path [1234ms 200]", + ] + `); + }); }); diff --git a/src/http-api/fetch.ts b/src/http-api/fetch.ts index 4599b4b615a..c527c8ea7c4 100644 --- a/src/http-api/fetch.ts +++ b/src/http-api/fetch.ts @@ -25,6 +25,7 @@ import { ConnectionError, MatrixError } from "./errors"; import { HttpApiEvent, HttpApiEventHandlerMap, IHttpOpts, IRequestOpts } from "./interface"; import { anySignal, parseErrorResponse, timeoutSignal } from "./utils"; import { QueryDict } from "../utils"; +import { logger } from "../logger"; type Body = Record | BodyInit; @@ -225,6 +226,9 @@ export class FetchHttpApi { body?: Body, opts: Pick = {}, ): Promise> { + const urlForLogs = this.clearUrlParamsForLogs(url); + logger.debug(`FetchHttpApi: --> ${method} ${urlForLogs}`); + const headers = Object.assign({}, opts.headers || {}); const json = opts.json ?? true; // We can't use getPrototypeOf here as objects made in other contexts e.g. over postMessage won't have same ref @@ -260,6 +264,7 @@ export class FetchHttpApi { const { signal, cleanup } = anySignal(signals); let res: Response; + const start = Date.now(); try { res = await this.fetch(url, { signal, @@ -274,7 +279,10 @@ export class FetchHttpApi { credentials: "omit", // we send credentials via headers keepalive: keepAlive, }); + + logger.debug(`FetchHttpApi: <-- ${method} ${urlForLogs} [${Date.now() - start}ms ${res.status}]`); } catch (e) { + logger.debug(`FetchHttpApi: <-- ${method} ${urlForLogs} [${Date.now() - start}ms ${e}]`); if ((e).name === "AbortError") { throw e; } @@ -293,6 +301,22 @@ export class FetchHttpApi { return res as ResponseType; } + private clearUrlParamsForLogs(url: URL | string): string { + try { + let asUrl: URL; + if (typeof url === "string") { + asUrl = new URL(url); + } else { + asUrl = url; + } + // get just the path to remove any potential url param that could have + // some potential secrets + return asUrl.origin + asUrl.pathname; + } catch (error) { + // defensive coding for malformed url + return "??"; + } + } /** * Form and return a homeserver request URL based on the given path params and prefix. * @param path - The HTTP path after the supplied prefix e.g. "/createRoom". From dcf26f3e486e6878fbd5335f53d47189c13716d4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 11 Jul 2023 18:40:39 +0100 Subject: [PATCH 20/59] bump rust-sdk (#3587) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1d8af896c9d..4248cddbfb4 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ ], "dependencies": { "@babel/runtime": "^7.12.5", - "@matrix-org/matrix-sdk-crypto-js": "^0.1.1", + "@matrix-org/matrix-sdk-crypto-js": "^0.1.3", "another-json": "^0.2.0", "bs58": "^5.0.0", "content-type": "^1.0.4", diff --git a/yarn.lock b/yarn.lock index 0ef82c1782a..d0b8e628214 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1497,10 +1497,10 @@ dependencies: lodash "^4.17.21" -"@matrix-org/matrix-sdk-crypto-js@^0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.1.tgz#aed6b7a3942bf9fc46234b7a572b9471a95da15f" - integrity sha512-HsOOi/EnBb0Z+bkIxPuQQLW/9+Kijqkjqbf8xZq0S/fcHQJpIKxDJoZQDrVNpnEEWiIrBBLzVYTszXhMg+PYNw== +"@matrix-org/matrix-sdk-crypto-js@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.3.tgz#19981e7613d3673d07c885a98d39276b5fe74ef0" + integrity sha512-RcRlE3wcMnE5ijACHIHmhXFogEEJdIcb/CbJ4rK1PCMduQ4yvxycVpMxwh7aKxFNitZbHZLCK7TfRzUpzjU2tw== "@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz": version "3.2.14" From 3b88ea19b70a28916eddf9dfaa87466dc5737b08 Mon Sep 17 00:00:00 2001 From: Kerry Date: Wed, 12 Jul 2023 10:04:06 +1200 Subject: [PATCH 21/59] Stabilize support for MSC3952: intentional mentions (#3397) * use stable identifiers for MSC3952: intentional mentions * add matrix version to feature support for intentional mentions --- spec/unit/pushprocessor.spec.ts | 2 +- src/@types/PushRules.ts | 4 ++-- src/feature.ts | 1 + src/models/event.ts | 2 +- src/pushprocessor.ts | 6 +++--- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/spec/unit/pushprocessor.spec.ts b/spec/unit/pushprocessor.spec.ts index c381c5e6406..9aae1eefd6c 100644 --- a/spec/unit/pushprocessor.spec.ts +++ b/spec/unit/pushprocessor.spec.ts @@ -657,7 +657,7 @@ describe("NotificationService", function () { content: { "body": "", "msgtype": "m.text", - "org.matrix.msc3952.mentions": {}, + "m.mentions": {}, }, }); diff --git a/src/@types/PushRules.ts b/src/@types/PushRules.ts index da3b01b6d17..6aebaa617ed 100644 --- a/src/@types/PushRules.ts +++ b/src/@types/PushRules.ts @@ -137,8 +137,8 @@ export enum PushRuleKind { export enum RuleId { Master = ".m.rule.master", - IsUserMention = ".org.matrix.msc3952.is_user_mention", - IsRoomMention = ".org.matrix.msc3952.is_room_mention", + IsUserMention = ".m.rule.is_user_mention", + IsRoomMention = ".m.rule.is_room_mention", ContainsDisplayName = ".m.rule.contains_display_name", ContainsUserName = ".m.rule.contains_user_name", AtRoomNotification = ".m.rule.roomnotif", diff --git a/src/feature.ts b/src/feature.ts index c0d7a341a7e..01cadd8e87c 100644 --- a/src/feature.ts +++ b/src/feature.ts @@ -63,6 +63,7 @@ const featureSupportResolver: Record = { }, [Feature.IntentionalMentions]: { unstablePrefixes: ["org.matrix.msc3952_intentional_mentions"], + matrixVersion: "v1.7", }, }; diff --git a/src/models/event.ts b/src/models/event.ts index 3ed1957f4a1..72c6212db9a 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -57,7 +57,7 @@ export interface IContent { "displayname"?: string; "m.relates_to"?: IEventRelation; - "org.matrix.msc3952.mentions"?: IMentions; + "m.mentions"?: IMentions; } type StrippedState = Required>; diff --git a/src/pushprocessor.ts b/src/pushprocessor.ts index 10dd7f6ba1f..7e63162b4c9 100644 --- a/src/pushprocessor.ts +++ b/src/pushprocessor.ts @@ -78,7 +78,7 @@ const DEFAULT_OVERRIDE_RULES: IPushRule[] = [ conditions: [ { kind: ConditionKind.EventPropertyContains, - key: "content.org\\.matrix\\.msc3952\\.mentions.user_ids", + key: "content.m\\.mentions.user_ids", value: "", // The user ID is dynamically added in rewriteDefaultRules. }, ], @@ -91,7 +91,7 @@ const DEFAULT_OVERRIDE_RULES: IPushRule[] = [ conditions: [ { kind: ConditionKind.EventPropertyIs, - key: "content.org\\.matrix\\.msc3952\\.mentions.room", + key: "content.m\\.mentions.room", value: true, }, { @@ -724,7 +724,7 @@ export class PushProcessor { // Disable the deprecated mentions push rules if the new mentions property exists. if ( this.client.supportsIntentionalMentions() && - ev.getContent()["org.matrix.msc3952.mentions"] !== undefined && + ev.getContent()["m.mentions"] !== undefined && (rule.rule_id === RuleId.ContainsUserName || rule.rule_id === RuleId.ContainsDisplayName || rule.rule_id === RuleId.AtRoomNotification) From e3919fd93bca184ef420ce8cc68493407fd78e91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Jul 2023 02:20:47 +0000 Subject: [PATCH 22/59] Bump semver from 5.7.1 to 5.7.2 (#3575) Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kerry --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index d0b8e628214..f5472c560ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6808,14 +6808,14 @@ sdp-transform@^2.14.1: integrity sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw== "semver@2 || 3 || 4 || 5", semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.1, semver@^7.5.3: version "7.5.4" From 01226e41d9e6d82e7515664ce74242c63fbde74e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 12 Jul 2023 11:01:57 +0100 Subject: [PATCH 23/59] Fix broken DeviceList.spec.ts test (#3590) --- spec/unit/crypto/DeviceList.spec.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/spec/unit/crypto/DeviceList.spec.ts b/spec/unit/crypto/DeviceList.spec.ts index ae96a4812b9..7d3ba5d3d44 100644 --- a/spec/unit/crypto/DeviceList.spec.ts +++ b/spec/unit/crypto/DeviceList.spec.ts @@ -129,7 +129,7 @@ describe("DeviceList", function () { }); }); - it("should have an outdated devicelist on an invalidation while an " + "update is in progress", function () { + it("should have an outdated devicelist on an invalidation while an update is in progress", async function () { const dl = createTestDeviceList(); dl.startTrackingDeviceList("@test1:sw1v.org"); @@ -148,11 +148,8 @@ describe("DeviceList", function () { dl.invalidateUserDeviceList("@test1:sw1v.org"); dl.refreshOutdatedDeviceLists(); - // TODO: Fix this test so we actually await the call and assertions and remove - // the eslint disable, https://github.com/matrix-org/matrix-js-sdk/issues/2977 - // - // eslint-disable-next-line jest/valid-expect-in-promise - dl.saveIfDirty() + await dl + .saveIfDirty() .then(() => { // the first request completes queryDefer1.resolve({ @@ -163,12 +160,13 @@ describe("DeviceList", function () { }); return prom1; }) - .then(() => { + .then(async () => { // uh-oh; user restarts before second request completes. The new instance // should know we never got a complete device list. logger.log("Creating new devicelist to simulate app reload"); downloadSpy.mockReset(); const dl2 = createTestDeviceList(); + await dl2.load(); const queryDefer3 = utils.defer(); downloadSpy.mockReturnValue(queryDefer3.promise); From 1cb5fff5a17771ef0135a70653926ecbfe03c378 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 12 Jul 2023 11:39:33 +0100 Subject: [PATCH 24/59] Improve types (#3589) * Improve types * Improve coverage --- spec/integ/matrix-client-methods.spec.ts | 465 +++++++++++--------- src/client.ts | 56 +-- src/crypto/CrossSigning.ts | 9 +- src/crypto/index.ts | 13 +- src/http-api/fetch.ts | 4 +- src/http-api/interface.ts | 2 + src/rendezvous/MSC3906Rendezvous.ts | 13 +- src/webrtc/stats/media/mediaTrackHandler.ts | 3 +- 8 files changed, 319 insertions(+), 246 deletions(-) diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index 48dcccba963..18e02624fa2 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -33,9 +33,9 @@ describe("MatrixClient", function () { const accessToken = "aseukfgwef"; const idServerDomain = "identity.localhost"; // not a real server const identityAccessToken = "woop-i-am-a-secret"; - let client: MatrixClient | undefined; - let httpBackend: HttpBackend | undefined; - let store: MemoryStore | undefined; + let client: MatrixClient; + let httpBackend: HttpBackend; + let store: MemoryStore; const defaultClientOpts: IStoredClientOpts = { threadSupport: false, @@ -59,8 +59,8 @@ describe("MatrixClient", function () { }); afterEach(function () { - httpBackend!.verifyNoOutstandingExpectation(); - return httpBackend!.stop(); + httpBackend.verifyNoOutstandingExpectation(); + return httpBackend.stop(); }); describe("uploadContent", function () { @@ -72,7 +72,7 @@ describe("MatrixClient", function () { }; it("should upload the file", function () { - httpBackend! + httpBackend .when("POST", "/_matrix/media/r0/upload") .check(function (req) { expect(req.rawData).toEqual(buf); @@ -86,11 +86,11 @@ describe("MatrixClient", function () { }) .respond(200, '{"content_uri": "content"}', true); - const prom = client!.uploadContent(file, opts); + const prom = client.uploadContent(file, opts); expect(prom).toBeTruthy(); - const uploads = client!.getCurrentUploads(); + const uploads = client.getCurrentUploads(); expect(uploads.length).toEqual(1); expect(uploads[0].promise).toBe(prom); expect(uploads[0].loaded).toEqual(0); @@ -98,16 +98,16 @@ describe("MatrixClient", function () { const prom2 = prom.then(function (response) { expect(response.content_uri).toEqual("content"); - const uploads = client!.getCurrentUploads(); + const uploads = client.getCurrentUploads(); expect(uploads.length).toEqual(0); }); - httpBackend!.flush(""); + httpBackend.flush(""); return prom2; }); it("should parse errors into a MatrixError", function () { - httpBackend! + httpBackend .when("POST", "/_matrix/media/r0/upload") .check(function (req) { expect(req.rawData).toEqual(buf); @@ -119,7 +119,7 @@ describe("MatrixClient", function () { error: "broken", }); - const prom = client!.uploadContent(file, opts).then( + const prom = client.uploadContent(file, opts).then( function (response) { throw Error("request not failed"); }, @@ -130,30 +130,30 @@ describe("MatrixClient", function () { }, ); - httpBackend!.flush(""); + httpBackend.flush(""); return prom; }); it("should return a promise which can be cancelled", async () => { - const prom = client!.uploadContent(file, opts); + const prom = client.uploadContent(file, opts); - const uploads = client!.getCurrentUploads(); + const uploads = client.getCurrentUploads(); expect(uploads.length).toEqual(1); expect(uploads[0].promise).toBe(prom); expect(uploads[0].loaded).toEqual(0); - const r = client!.cancelUpload(prom); + const r = client.cancelUpload(prom); expect(r).toBe(true); await expect(prom).rejects.toThrow("Aborted"); - expect(client!.getCurrentUploads()).toHaveLength(0); + expect(client.getCurrentUploads()).toHaveLength(0); }); }); describe("joinRoom", function () { it("should no-op if you've already joined a room", function () { const roomId = "!foo:bar"; - const room = new Room(roomId, client!, userId); - client!.fetchRoomEvent = () => + const room = new Room(roomId, client, userId); + client.fetchRoomEvent = () => Promise.resolve({ type: "test", content: {}, @@ -166,10 +166,10 @@ describe("MatrixClient", function () { event: true, }), ]); - httpBackend!.verifyNoOutstandingRequests(); - store!.storeRoom(room); - client!.joinRoom(roomId); - httpBackend!.verifyNoOutstandingRequests(); + httpBackend.verifyNoOutstandingRequests(); + store.storeRoom(room); + client.joinRoom(roomId); + httpBackend.verifyNoOutstandingRequests(); }); it("should send request to inviteSignUrl if specified", async () => { @@ -183,24 +183,24 @@ describe("MatrixClient", function () { signatures: {}, }; - httpBackend! + httpBackend .when("POST", inviteSignUrl) .check((request) => { - expect(request.queryParams?.mxid).toEqual(client!.getUserId()); + expect(request.queryParams?.mxid).toEqual(client.getUserId()); }) .respond(200, signature); - httpBackend! + httpBackend .when("POST", "/join/" + encodeURIComponent(roomId)) .check((request) => { expect(request.data.third_party_signed).toEqual(signature); }) .respond(200, { room_id: roomId }); - const prom = client!.joinRoom(roomId, { + const prom = client.joinRoom(roomId, { inviteSignUrl, viaServers, }); - await httpBackend!.flushAllExpected(); + await httpBackend.flushAllExpected(); expect((await prom).roomId).toBe(roomId); }); }); @@ -212,10 +212,10 @@ describe("MatrixClient", function () { const filter = Filter.fromJson(userId, filterId, { event_format: "client", }); - store!.storeFilter(filter); - const gotFilter = await client!.getFilter(userId, filterId, true); + store.storeFilter(filter); + const gotFilter = await client.getFilter(userId, filterId, true); expect(gotFilter).toEqual(filter); - httpBackend!.verifyNoOutstandingRequests(); + httpBackend.verifyNoOutstandingRequests(); }); it("should do an HTTP request if !allowCached even if one exists", async () => { @@ -223,15 +223,15 @@ describe("MatrixClient", function () { event_format: "federation", }; - httpBackend! + httpBackend .when("GET", "/user/" + encodeURIComponent(userId) + "/filter/" + filterId) .respond(200, httpFilterDefinition); const storeFilter = Filter.fromJson(userId, filterId, { event_format: "client", }); - store!.storeFilter(storeFilter); - const [gotFilter] = await Promise.all([client!.getFilter(userId, filterId, false), httpBackend!.flush("")]); + store.storeFilter(storeFilter); + const [gotFilter] = await Promise.all([client.getFilter(userId, filterId, false), httpBackend.flush("")]); expect(gotFilter.getDefinition()).toEqual(httpFilterDefinition); }); @@ -239,14 +239,14 @@ describe("MatrixClient", function () { const httpFilterDefinition = { event_format: "federation", }; - expect(store!.getFilter(userId, filterId)).toBe(null); + expect(store.getFilter(userId, filterId)).toBe(null); - httpBackend! + httpBackend .when("GET", "/user/" + encodeURIComponent(userId) + "/filter/" + filterId) .respond(200, httpFilterDefinition); - const [gotFilter] = await Promise.all([client!.getFilter(userId, filterId, true), httpBackend!.flush("")]); + const [gotFilter] = await Promise.all([client.getFilter(userId, filterId, true), httpBackend.flush("")]); expect(gotFilter.getDefinition()).toEqual(httpFilterDefinition); - expect(store!.getFilter(userId, filterId)).toBeTruthy(); + expect(store.getFilter(userId, filterId)).toBeTruthy(); }); }); @@ -254,13 +254,13 @@ describe("MatrixClient", function () { const filterId = "f1llllllerid"; it("should do an HTTP request and then store the filter", async () => { - expect(store!.getFilter(userId, filterId)).toBe(null); + expect(store.getFilter(userId, filterId)).toBe(null); const filterDefinition = { event_format: "client" as IFilterDefinition["event_format"], }; - httpBackend! + httpBackend .when("POST", "/user/" + encodeURIComponent(userId) + "/filter") .check(function (req) { expect(req.data).toEqual(filterDefinition); @@ -269,9 +269,9 @@ describe("MatrixClient", function () { filter_id: filterId, }); - const [gotFilter] = await Promise.all([client!.createFilter(filterDefinition), httpBackend!.flush("")]); + const [gotFilter] = await Promise.all([client.createFilter(filterDefinition), httpBackend.flush("")]); expect(gotFilter.getDefinition()).toEqual(filterDefinition); - expect(store!.getFilter(userId, filterId)).toEqual(gotFilter); + expect(store.getFilter(userId, filterId)).toEqual(gotFilter); }); }); @@ -300,10 +300,10 @@ describe("MatrixClient", function () { }, }; - client!.searchMessageText({ + client.searchMessageText({ query: "monkeys", }); - httpBackend! + httpBackend .when("POST", "/search") .check(function (req) { expect(req.data).toEqual({ @@ -316,7 +316,7 @@ describe("MatrixClient", function () { }) .respond(200, response); - return httpBackend!.flush(""); + return httpBackend.flush(""); }); describe("should filter out context from different timelines (threads)", () => { @@ -386,7 +386,7 @@ describe("MatrixClient", function () { results: [], highlights: [], }; - client!.processRoomEventsSearch(data, response); + client.processRoomEventsSearch(data, response); expect(data.results).toHaveLength(1); expect(data.results[0].context.getTimeline()).toHaveLength(2); @@ -450,7 +450,7 @@ describe("MatrixClient", function () { results: [], highlights: [], }; - client!.processRoomEventsSearch(data, response); + client.processRoomEventsSearch(data, response); expect(data.results).toHaveLength(1); expect(data.results[0].context.getTimeline()).toHaveLength(1); @@ -512,7 +512,7 @@ describe("MatrixClient", function () { results: [], highlights: [], }; - client!.processRoomEventsSearch(data, response); + client.processRoomEventsSearch(data, response); expect(data.results).toHaveLength(1); expect(data.results[0].context.getTimeline()).toHaveLength(1); @@ -530,17 +530,17 @@ describe("MatrixClient", function () { beforeEach(function () { // running initCrypto should trigger a key upload - httpBackend!.when("POST", "/keys/upload").respond(200, {}); - return Promise.all([client!.initCrypto(), httpBackend!.flush("/keys/upload", 1)]); + httpBackend.when("POST", "/keys/upload").respond(200, {}); + return Promise.all([client.initCrypto(), httpBackend.flush("/keys/upload", 1)]); }); afterEach(() => { - client!.stopClient(); + client.stopClient(); }); it("should do an HTTP request and then store the keys", function () { const ed25519key = "7wG2lzAqbjcyEkOP7O4gU7ItYcn+chKzh5sT/5r2l78"; - // ed25519key = client!.getDeviceEd25519Key(); + // ed25519key = client.getDeviceEd25519Key(); const borisKeys = { dev1: { algorithms: ["1"], @@ -580,7 +580,7 @@ describe("MatrixClient", function () { var b = JSON.parse(JSON.stringify(o)); delete(b.signatures); delete(b.unsigned); - return client!.crypto.olmDevice.sign(anotherjson.stringify(b)); + return client.crypto.olmDevice.sign(anotherjson.stringify(b)); }; logger.log("Ed25519: " + ed25519key); @@ -588,7 +588,7 @@ describe("MatrixClient", function () { logger.log("chaz:", sign(chazKeys.dev2)); */ - httpBackend! + httpBackend .when("POST", "/keys/query") .check(function (req) { expect(req.data).toEqual({ @@ -605,7 +605,7 @@ describe("MatrixClient", function () { }, }); - const prom = client!.downloadKeys(["boris", "chaz"]).then(function (res) { + const prom = client.downloadKeys(["boris", "chaz"]).then(function (res) { assertObjectContains(res.get("boris")!.get("dev1")!, { verified: 0, // DeviceVerification.UNVERIFIED keys: { "ed25519:dev1": ed25519key }, @@ -621,7 +621,7 @@ describe("MatrixClient", function () { }); }); - httpBackend!.flush(""); + httpBackend.flush(""); return prom; }); }); @@ -629,16 +629,16 @@ describe("MatrixClient", function () { describe("deleteDevice", function () { const auth = { identifier: 1 }; it("should pass through an auth dict", function () { - httpBackend! + httpBackend .when("DELETE", "/_matrix/client/r0/devices/my_device") .check(function (req) { expect(req.data).toEqual({ auth: auth }); }) .respond(200); - const prom = client!.deleteDevice("my_device", auth); + const prom = client.deleteDevice("my_device", auth); - httpBackend!.flush(""); + httpBackend.flush(""); return prom; }); }); @@ -646,7 +646,7 @@ describe("MatrixClient", function () { describe("partitionThreadedEvents", function () { let room: Room; beforeEach(() => { - room = new Room("!STrMRsukXHtqQdSeHa:matrix.org", client!, userId); + room = new Room("!STrMRsukXHtqQdSeHa:matrix.org", client, userId); }); it("returns empty arrays when given an empty arrays", function () { @@ -658,7 +658,7 @@ describe("MatrixClient", function () { it("copies pre-thread in-timeline vote events onto both timelines", function () { // @ts-ignore setting private property - client!.clientOpts = { + client.clientOpts = { ...defaultClientOpts, threadSupport: true, }; @@ -689,7 +689,7 @@ describe("MatrixClient", function () { it("copies pre-thread in-timeline reactions onto both timelines", function () { // @ts-ignore setting private property - client!.clientOpts = { + client.clientOpts = { ...defaultClientOpts, threadSupport: true, }; @@ -713,7 +713,7 @@ describe("MatrixClient", function () { it("copies post-thread in-timeline vote events onto both timelines", function () { // @ts-ignore setting private property - client!.clientOpts = { + client.clientOpts = { ...defaultClientOpts, threadSupport: true, }; @@ -737,7 +737,7 @@ describe("MatrixClient", function () { it("copies post-thread in-timeline reactions onto both timelines", function () { // @ts-ignore setting private property - client!.clientOpts = { + client.clientOpts = { ...defaultClientOpts, threadSupport: true, }; @@ -761,7 +761,7 @@ describe("MatrixClient", function () { it("sends room state events to the main timeline only", function () { // @ts-ignore setting private property - client!.clientOpts = { + client.clientOpts = { ...defaultClientOpts, threadSupport: true, }; @@ -818,7 +818,7 @@ describe("MatrixClient", function () { it("sends redactions of reactions to thread responses to thread timeline only", () => { // @ts-ignore setting private property - client!.clientOpts = { + client.clientOpts = { ...defaultClientOpts, threadSupport: true, }; @@ -844,7 +844,7 @@ describe("MatrixClient", function () { it("sends reply to reply to thread root outside of thread to main timeline only", () => { // @ts-ignore setting private property - client!.clientOpts = { + client.clientOpts = { ...defaultClientOpts, threadSupport: true, }; @@ -865,7 +865,7 @@ describe("MatrixClient", function () { it("sends reply to thread responses to main timeline only", () => { // @ts-ignore setting private property - client!.clientOpts = { + client.clientOpts = { ...defaultClientOpts, threadSupport: true, }; @@ -894,9 +894,9 @@ describe("MatrixClient", function () { }, ]; - const prom = client!.getThirdpartyUser("irc", {}); - httpBackend!.when("GET", "/thirdparty/user/irc").respond(200, response); - await httpBackend!.flush(""); + const prom = client.getThirdpartyUser("irc", {}); + httpBackend.when("GET", "/thirdparty/user/irc").respond(200, response); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); @@ -911,9 +911,9 @@ describe("MatrixClient", function () { }, ]; - const prom = client!.getThirdpartyLocation("irc", {}); - httpBackend!.when("GET", "/thirdparty/location/irc").respond(200, response); - await httpBackend!.flush(""); + const prom = client.getThirdpartyLocation("irc", {}); + httpBackend.when("GET", "/thirdparty/location/irc").respond(200, response); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); @@ -924,10 +924,10 @@ describe("MatrixClient", function () { pushers: [], }; - const prom = client!.getPushers(); - httpBackend!.when("GET", "/_matrix/client/versions").respond(200, {}); - httpBackend!.when("GET", "/pushers").respond(200, response); - await httpBackend!.flush(""); + const prom = client.getPushers(); + httpBackend.when("GET", "/_matrix/client/versions").respond(200, {}); + httpBackend.when("GET", "/pushers").respond(200, response); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); @@ -939,15 +939,15 @@ describe("MatrixClient", function () { left: [], }; - const prom = client!.getKeyChanges("old", "new"); - httpBackend! + const prom = client.getKeyChanges("old", "new"); + httpBackend .when("GET", "/keys/changes") .check((req) => { expect(req.queryParams?.from).toEqual("old"); expect(req.queryParams?.to).toEqual("new"); }) .respond(200, response); - await httpBackend!.flush(""); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); @@ -958,9 +958,9 @@ describe("MatrixClient", function () { devices: [], }; - const prom = client!.getDevices(); - httpBackend!.when("GET", "/devices").respond(200, response); - await httpBackend!.flush(""); + const prom = client.getDevices(); + httpBackend.when("GET", "/devices").respond(200, response); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); @@ -974,9 +974,9 @@ describe("MatrixClient", function () { last_seen_ts: 1, }; - const prom = client!.getDevice("DEADBEEF"); - httpBackend!.when("GET", "/devices/DEADBEEF").respond(200, response); - await httpBackend!.flush(""); + const prom = client.getDevice("DEADBEEF"); + httpBackend.when("GET", "/devices/DEADBEEF").respond(200, response); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); @@ -987,9 +987,9 @@ describe("MatrixClient", function () { threepids: [], }; - const prom = client!.getThreePids(); - httpBackend!.when("GET", "/account/3pid").respond(200, response); - await httpBackend!.flush(""); + const prom = client.getThreePids(); + httpBackend.when("GET", "/account/3pid").respond(200, response); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); @@ -997,9 +997,9 @@ describe("MatrixClient", function () { describe("deleteAlias", () => { it("should hit the expected API endpoint", async () => { const response = {}; - const prom = client!.deleteAlias("#foo:bar"); - httpBackend!.when("DELETE", "/directory/room/" + encodeURIComponent("#foo:bar")).respond(200, response); - await httpBackend!.flush(""); + const prom = client.deleteAlias("#foo:bar"); + httpBackend.when("DELETE", "/directory/room/" + encodeURIComponent("#foo:bar")).respond(200, response); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); @@ -1007,10 +1007,10 @@ describe("MatrixClient", function () { describe("deleteRoomTag", () => { it("should hit the expected API endpoint", async () => { const response = {}; - const prom = client!.deleteRoomTag("!roomId:server", "u.tag"); + const prom = client.deleteRoomTag("!roomId:server", "u.tag"); const url = `/user/${encodeURIComponent(userId)}/rooms/${encodeURIComponent("!roomId:server")}/tags/u.tag`; - httpBackend!.when("DELETE", url).respond(200, response); - await httpBackend!.flush(""); + httpBackend.when("DELETE", url).respond(200, response); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); @@ -1025,10 +1025,10 @@ describe("MatrixClient", function () { }, }; - const prom = client!.getRoomTags("!roomId:server"); + const prom = client.getRoomTags("!roomId:server"); const url = `/user/${encodeURIComponent(userId)}/rooms/${encodeURIComponent("!roomId:server")}/tags`; - httpBackend!.when("GET", url).respond(200, response); - await httpBackend!.flush(""); + httpBackend.when("GET", url).respond(200, response); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); @@ -1040,12 +1040,12 @@ describe("MatrixClient", function () { submit_url: "https://foobar.matrix/_matrix/matrix", }; - httpBackend!.when("GET", "/_matrix/client/versions").respond(200, { + httpBackend.when("GET", "/_matrix/client/versions").respond(200, { versions: ["r0.6.0"], }); - const prom = client!.requestRegisterEmailToken("bob@email", "secret", 1); - httpBackend! + const prom = client.requestRegisterEmailToken("bob@email", "secret", 1); + httpBackend .when("POST", "/register/email/requestToken") .check((req) => { expect(req.data).toStrictEqual({ @@ -1055,7 +1055,7 @@ describe("MatrixClient", function () { }); }) .respond(200, response); - await httpBackend!.flush(""); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); @@ -1064,11 +1064,11 @@ describe("MatrixClient", function () { it("should supply an id_access_token", async () => { const targetEmail = "gerald@example.org"; - httpBackend!.when("GET", "/_matrix/client/versions").respond(200, { + httpBackend.when("GET", "/_matrix/client/versions").respond(200, { versions: ["r0.6.0"], }); - httpBackend! + httpBackend .when("POST", "/invite") .check((req) => { expect(req.data).toStrictEqual({ @@ -1080,8 +1080,8 @@ describe("MatrixClient", function () { }) .respond(200, {}); - const prom = client!.inviteByThreePid("!room:example.org", "email", targetEmail); - await httpBackend!.flush(""); + const prom = client.inviteByThreePid("!room:example.org", "email", targetEmail); + await httpBackend.flush(""); await prom; // returns empty object, so no validation needed }); }); @@ -1103,11 +1103,11 @@ describe("MatrixClient", function () { ], }; - httpBackend!.when("GET", "/_matrix/client/versions").respond(200, { + httpBackend.when("GET", "/_matrix/client/versions").respond(200, { versions: ["r0.6.0"], }); - httpBackend! + httpBackend .when("POST", "/createRoom") .check((req) => { expect(req.data).toMatchObject({ @@ -1122,57 +1122,57 @@ describe("MatrixClient", function () { }) .respond(200, response); - const prom = client!.createRoom(input); - await httpBackend!.flush(""); + const prom = client.createRoom(input); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); }); describe("requestLoginToken", () => { it("should hit the expected API endpoint with UIA", async () => { - httpBackend! + httpBackend .when("GET", "/capabilities") .respond(200, { capabilities: { "org.matrix.msc3882.get_login_token": { enabled: true } } }); const response = {}; const uiaData = {}; - const prom = client!.requestLoginToken(uiaData); - httpBackend! + const prom = client.requestLoginToken(uiaData); + httpBackend .when("POST", "/unstable/org.matrix.msc3882/login/get_token", { auth: uiaData }) .respond(200, response); - await httpBackend!.flush(""); + await httpBackend.flush(""); expect(await prom).toStrictEqual(response); }); it("should hit the expected API endpoint without UIA", async () => { - httpBackend! + httpBackend .when("GET", "/capabilities") .respond(200, { capabilities: { "org.matrix.msc3882.get_login_token": { enabled: true } } }); const response = { login_token: "xyz", expires_in_ms: 5000 }; - const prom = client!.requestLoginToken(); - httpBackend!.when("POST", "/unstable/org.matrix.msc3882/login/get_token", {}).respond(200, response); - await httpBackend!.flush(""); + const prom = client.requestLoginToken(); + httpBackend.when("POST", "/unstable/org.matrix.msc3882/login/get_token", {}).respond(200, response); + await httpBackend.flush(""); // check that expires_in has been populated for compatibility with r0 expect(await prom).toStrictEqual({ ...response, expires_in: 5 }); }); it("should hit the r1 endpoint when capability is disabled", async () => { - httpBackend! + httpBackend .when("GET", "/capabilities") .respond(200, { capabilities: { "org.matrix.msc3882.get_login_token": { enabled: false } } }); const response = { login_token: "xyz", expires_in_ms: 5000 }; - const prom = client!.requestLoginToken(); - httpBackend!.when("POST", "/unstable/org.matrix.msc3882/login/get_token", {}).respond(200, response); - await httpBackend!.flush(""); + const prom = client.requestLoginToken(); + httpBackend.when("POST", "/unstable/org.matrix.msc3882/login/get_token", {}).respond(200, response); + await httpBackend.flush(""); // check that expires_in has been populated for compatibility with r0 expect(await prom).toStrictEqual({ ...response, expires_in: 5 }); }); it("should hit the r0 endpoint for fallback", async () => { - httpBackend!.when("GET", "/capabilities").respond(200, {}); + httpBackend.when("GET", "/capabilities").respond(200, {}); const response = { login_token: "xyz", expires_in: 5 }; - const prom = client!.requestLoginToken(); - httpBackend!.when("POST", "/unstable/org.matrix.msc3882/login/token", {}).respond(200, response); - await httpBackend!.flush(""); + const prom = client.requestLoginToken(); + httpBackend.when("POST", "/unstable/org.matrix.msc3882/login/token", {}).respond(200, response); + await httpBackend.flush(""); // check that expires_in has been populated for compatibility with r1 expect(await prom).toStrictEqual({ ...response, expires_in_ms: 5000 }); }); @@ -1180,18 +1180,18 @@ describe("MatrixClient", function () { describe("logout", () => { it("should abort pending requests when called with stopClient=true", async () => { - httpBackend!.when("POST", "/logout").respond(200, {}); + httpBackend.when("POST", "/logout").respond(200, {}); const fn = jest.fn(); - client!.http.request(Method.Get, "/test").catch(fn); - client!.logout(true); - await httpBackend!.flush(undefined); + client.http.request(Method.Get, "/test").catch(fn); + client.logout(true); + await httpBackend.flush(undefined); expect(fn).toHaveBeenCalled(); }); }); describe("sendHtmlEmote", () => { it("should send valid html emote", async () => { - httpBackend! + httpBackend .when("PUT", "/send") .check((req) => { expect(req.data).toStrictEqual({ @@ -1202,15 +1202,15 @@ describe("MatrixClient", function () { }); }) .respond(200, { event_id: "$foobar" }); - const prom = client!.sendHtmlEmote("!room:server", "Body", "

Body

"); - await httpBackend!.flush(undefined); + const prom = client.sendHtmlEmote("!room:server", "Body", "

Body

"); + await httpBackend.flush(undefined); await expect(prom).resolves.toStrictEqual({ event_id: "$foobar" }); }); }); describe("sendHtmlMessage", () => { it("should send valid html message", async () => { - httpBackend! + httpBackend .when("PUT", "/send") .check((req) => { expect(req.data).toStrictEqual({ @@ -1221,34 +1221,34 @@ describe("MatrixClient", function () { }); }) .respond(200, { event_id: "$foobar" }); - const prom = client!.sendHtmlMessage("!room:server", "Body", "

Body

"); - await httpBackend!.flush(undefined); + const prom = client.sendHtmlMessage("!room:server", "Body", "

Body

"); + await httpBackend.flush(undefined); await expect(prom).resolves.toStrictEqual({ event_id: "$foobar" }); }); }); describe("forget", () => { it("should remove from store by default", async () => { - const room = new Room("!roomId:server", client!, userId); - client!.store.storeRoom(room); - expect(client!.store.getRooms()).toContain(room); + const room = new Room("!roomId:server", client, userId); + client.store.storeRoom(room); + expect(client.store.getRooms()).toContain(room); - httpBackend!.when("POST", "/forget").respond(200, {}); - await Promise.all([client!.forget(room.roomId), httpBackend!.flushAllExpected()]); - expect(client!.store.getRooms()).not.toContain(room); + httpBackend.when("POST", "/forget").respond(200, {}); + await Promise.all([client.forget(room.roomId), httpBackend.flushAllExpected()]); + expect(client.store.getRooms()).not.toContain(room); }); }); describe("getCapabilities", () => { it("should cache by default", async () => { - httpBackend!.when("GET", "/capabilities").respond(200, { + httpBackend.when("GET", "/capabilities").respond(200, { capabilities: { "m.change_password": false, }, }); - const prom = httpBackend!.flushAllExpected(); - const capabilities1 = await client!.getCapabilities(); - const capabilities2 = await client!.getCapabilities(); + const prom = httpBackend.flushAllExpected(); + const capabilities1 = await client.getCapabilities(); + const capabilities2 = await client.getCapabilities(); await prom; expect(capabilities1).toStrictEqual(capabilities2); @@ -1257,16 +1257,16 @@ describe("MatrixClient", function () { describe("getTerms", () => { it("should return Identity Server terms", async () => { - httpBackend!.when("GET", "/terms").respond(200, { foo: "bar" }); - const prom = client!.getTerms(SERVICE_TYPES.IS, "http://identity.server"); - await httpBackend!.flushAllExpected(); + httpBackend.when("GET", "/terms").respond(200, { foo: "bar" }); + const prom = client.getTerms(SERVICE_TYPES.IS, "http://identity.server"); + await httpBackend.flushAllExpected(); await expect(prom).resolves.toEqual({ foo: "bar" }); }); it("should return Integrations Manager terms", async () => { - httpBackend!.when("GET", "/terms").respond(200, { foo: "bar" }); - const prom = client!.getTerms(SERVICE_TYPES.IM, "http://im.server"); - await httpBackend!.flushAllExpected(); + httpBackend.when("GET", "/terms").respond(200, { foo: "bar" }); + const prom = client.getTerms(SERVICE_TYPES.IM, "http://im.server"); + await httpBackend.flushAllExpected(); await expect(prom).resolves.toEqual({ foo: "bar" }); }); }); @@ -1275,46 +1275,46 @@ describe("MatrixClient", function () { it("should send `user_accepts` via body of POST request", async () => { const terms = ["https://vector.im/notice-1"]; - httpBackend! + httpBackend .when("POST", "/terms") .check((req) => { expect(req.data.user_accepts).toStrictEqual(terms); }) .respond(200, {}); - const prom = client!.agreeToTerms(SERVICE_TYPES.IS, "https://vector.im", "at", terms); - await httpBackend!.flushAllExpected(); + const prom = client.agreeToTerms(SERVICE_TYPES.IS, "https://vector.im", "at", terms); + await httpBackend.flushAllExpected(); await prom; }); }); describe("publicRooms", () => { it("should use GET request if no server or filter is specified", () => { - httpBackend!.when("GET", "/publicRooms").respond(200, {}); - client!.publicRooms({}); - return httpBackend!.flushAllExpected(); + httpBackend.when("GET", "/publicRooms").respond(200, {}); + client.publicRooms({}); + return httpBackend.flushAllExpected(); }); it("should use GET request if only server is specified", () => { - httpBackend! + httpBackend .when("GET", "/publicRooms") .check((request) => { expect(request.queryParams?.server).toBe("server1"); }) .respond(200, {}); - client!.publicRooms({ server: "server1" }); - return httpBackend!.flushAllExpected(); + client.publicRooms({ server: "server1" }); + return httpBackend.flushAllExpected(); }); it("should use POST request if filter is specified", () => { - httpBackend! + httpBackend .when("POST", "/publicRooms") .check((request) => { expect(request.data.filter.generic_search_term).toBe("foobar"); }) .respond(200, {}); - client!.publicRooms({ filter: { generic_search_term: "foobar" } }); - return httpBackend!.flushAllExpected(); + client.publicRooms({ filter: { generic_search_term: "foobar" } }); + return httpBackend.flushAllExpected(); }); }); @@ -1323,17 +1323,17 @@ describe("MatrixClient", function () { const token = "!token&"; const userId = "@m:t"; - httpBackend!.when("POST", "/login").respond(200, { + httpBackend.when("POST", "/login").respond(200, { access_token: token, user_id: userId, }); - const prom = client!.login("fake.login", {}); - await httpBackend!.flushAllExpected(); + const prom = client.login("fake.login", {}); + await httpBackend.flushAllExpected(); const resp = await prom; expect(resp.access_token).toBe(token); expect(resp.user_id).toBe(userId); - expect(client!.getUserId()).toBe(userId); - expect(client!.http.opts.accessToken).toBe(token); + expect(client.getUserId()).toBe(userId); + expect(client.http.opts.accessToken).toBe(token); }); }); @@ -1346,7 +1346,7 @@ describe("MatrixClient", function () { expires_in: 12345, }; - httpBackend! + httpBackend .when("POST", "/account/register") .check((req) => { expect(req.data).toStrictEqual(token); @@ -1356,8 +1356,8 @@ describe("MatrixClient", function () { token: "tt", }); - const prom = client!.registerWithIdentityServer(token); - await httpBackend!.flushAllExpected(); + const prom = client.registerWithIdentityServer(token); + await httpBackend.flushAllExpected(); const resp = await prom; expect(resp.access_token).toBe("at"); expect(resp.token).toBe("tt"); @@ -1387,28 +1387,28 @@ describe("MatrixClient", function () { expectation: {}, }, ])("should modify power levels of $userId correctly", async ({ userId, powerLevel, expectation }) => { - httpBackend!.when("GET", "/state/m.room.power_levels/").respond(200, { + httpBackend.when("GET", "/state/m.room.power_levels/").respond(200, { users: { "alice@localhost": 50, }, }); - httpBackend! + httpBackend .when("PUT", "/state/m.room.power_levels") .check((req) => { expect(req.data.users).toStrictEqual(expectation); }) .respond(200, {}); - const prom = client!.setPowerLevel("!room_id:server", userId, powerLevel); - await httpBackend!.flushAllExpected(); + const prom = client.setPowerLevel("!room_id:server", userId, powerLevel); + await httpBackend.flushAllExpected(); await prom; }); it("should use power level from room state if available", async () => { - client!.clientRunning = true; - client!.isInitialSyncComplete = () => true; - const room = new Room("!room_id:server", client!, client!.getUserId()!); + client.clientRunning = true; + client.isInitialSyncComplete = () => true; + const room = new Room("!room_id:server", client, client.getUserId()!); room.currentState.events.set("m.room.power_levels", new Map()); room.currentState.events.get("m.room.power_levels")!.set( "", @@ -1422,9 +1422,9 @@ describe("MatrixClient", function () { }, }), ); - client!.getRoom = () => room; + client.getRoom = () => room; - httpBackend! + httpBackend .when("PUT", "/state/m.room.power_levels") .check((req) => { expect(req.data).toStrictEqual({ @@ -1436,29 +1436,29 @@ describe("MatrixClient", function () { }) .respond(200, {}); - const prom = client!.setPowerLevel("!room_id:server", userId, 42); - await httpBackend!.flushAllExpected(); + const prom = client.setPowerLevel("!room_id:server", userId, 42); + await httpBackend.flushAllExpected(); await prom; }); it("should throw error if state API errors", async () => { - httpBackend!.when("GET", "/state/m.room.power_levels/").respond(500, { + httpBackend.when("GET", "/state/m.room.power_levels/").respond(500, { errcode: "ERR_DERP", }); - const prom = client!.setPowerLevel("!room_id:server", userId, 42); + const prom = client.setPowerLevel("!room_id:server", userId, 42); await Promise.all([ expect(prom).rejects.toMatchInlineSnapshot(`[ERR_DERP: MatrixError: [500] Unknown message]`), - httpBackend!.flushAllExpected(), + httpBackend.flushAllExpected(), ]); }); it("should not throw error if /state/ API returns M_NOT_FOUND", async () => { - httpBackend!.when("GET", "/state/m.room.power_levels/").respond(404, { + httpBackend.when("GET", "/state/m.room.power_levels/").respond(404, { errcode: "M_NOT_FOUND", }); - httpBackend! + httpBackend .when("PUT", "/state/m.room.power_levels") .check((req) => { expect(req.data).toStrictEqual({ @@ -1469,8 +1469,8 @@ describe("MatrixClient", function () { }) .respond(200, {}); - const prom = client!.setPowerLevel("!room_id:server", userId, 42); - await httpBackend!.flushAllExpected(); + const prom = client.setPowerLevel("!room_id:server", userId, 42); + await httpBackend.flushAllExpected(); await prom; }); }); @@ -1478,42 +1478,42 @@ describe("MatrixClient", function () { describe("uploadKeys", () => { // uploadKeys() is a no-op nowadays, so there's not much to test here. it("should complete successfully", async () => { - await client!.uploadKeys(); + await client.uploadKeys(); }); }); describe("getCryptoTrustCrossSignedDevices", () => { it("should throw if e2e is disabled", () => { - expect(() => client!.getCryptoTrustCrossSignedDevices()).toThrow("End-to-end encryption disabled"); + expect(() => client.getCryptoTrustCrossSignedDevices()).toThrow("End-to-end encryption disabled"); }); it("should proxy to the crypto backend", async () => { const mockBackend = { getTrustCrossSignedDevices: jest.fn().mockReturnValue(true), } as unknown as Mocked; - client!["cryptoBackend"] = mockBackend; + client["cryptoBackend"] = mockBackend; - expect(client!.getCryptoTrustCrossSignedDevices()).toBe(true); + expect(client.getCryptoTrustCrossSignedDevices()).toBe(true); mockBackend.getTrustCrossSignedDevices.mockReturnValue(false); - expect(client!.getCryptoTrustCrossSignedDevices()).toBe(false); + expect(client.getCryptoTrustCrossSignedDevices()).toBe(false); }); }); describe("setCryptoTrustCrossSignedDevices", () => { it("should throw if e2e is disabled", () => { - expect(() => client!.setCryptoTrustCrossSignedDevices(false)).toThrow("End-to-end encryption disabled"); + expect(() => client.setCryptoTrustCrossSignedDevices(false)).toThrow("End-to-end encryption disabled"); }); it("should proxy to the crypto backend", async () => { const mockBackend = { setTrustCrossSignedDevices: jest.fn(), } as unknown as Mocked; - client!["cryptoBackend"] = mockBackend; + client["cryptoBackend"] = mockBackend; - client!.setCryptoTrustCrossSignedDevices(true); + client.setCryptoTrustCrossSignedDevices(true); expect(mockBackend.setTrustCrossSignedDevices).toHaveBeenLastCalledWith(true); - client!.setCryptoTrustCrossSignedDevices(false); + client.setCryptoTrustCrossSignedDevices(false); expect(mockBackend.setTrustCrossSignedDevices).toHaveBeenLastCalledWith(false); }); }); @@ -1523,10 +1523,73 @@ describe("MatrixClient", function () { const setPresence = jest.fn(); // @ts-ignore client.syncApi = { setPresence }; - client?.setSyncPresence(SetPresence.Unavailable); + client.setSyncPresence(SetPresence.Unavailable); expect(setPresence).toHaveBeenCalledWith(SetPresence.Unavailable); }); }); + + describe("sendTyping", () => { + it("should bail early for guests", async () => { + client.setGuest(true); + await client.sendTyping("!room:server", true, 100); + }); + + it("should call /typing API", async () => { + client.setGuest(false); + httpBackend + .when("PUT", "/rooms/!room%3Aserver/typing/" + encodeURIComponent(client.getSafeUserId())) + .check((req) => { + expect(req.data).toEqual({ + typing: true, + timeout: 100, + }); + }) + .respond(200, {}); + await Promise.all([client.sendTyping("!room:server", true, 100), httpBackend.flushAllExpected()]); + }); + }); + + describe("setGuestAccess", () => { + it("should set both guest access and history visibility if opts.allowRead=true", async () => { + httpBackend + .when("PUT", "/rooms/!room%3Aserver/state/m.room.guest_access/") + .check((req) => { + expect(req.data).toEqual({ + guest_access: "forbidden", + }); + }) + .respond(200, { event_id: "$event1" }); + httpBackend + .when("PUT", "/rooms/!room%3Aserver/state/m.room.history_visibility/") + .check((req) => { + expect(req.data).toEqual({ + history_visibility: "world_readable", + }); + }) + .respond(200, { event_id: "$event2" }); + await Promise.all([ + client.setGuestAccess("!room:server", { allowRead: true, allowJoin: false }), + httpBackend.flushAllExpected(), + ]); + }); + }); + + describe("searchUserDirectory", () => { + it("should call /user_directory/search API", async () => { + httpBackend + .when("POST", "/user_directory/search") + .check((req) => { + expect(req.data).toEqual({ + search_term: "This is my query", + }); + }) + .respond(200, {}); + await Promise.all([ + client.searchUserDirectory({ term: "This is my query" }), + httpBackend.flushAllExpected(), + ]); + }); + }); }); function withThreadId(event: MatrixEvent, newThreadId: string): MatrixEvent { diff --git a/src/client.ts b/src/client.ts index e84a19d0e94..16da1791701 100644 --- a/src/client.ts +++ b/src/client.ts @@ -71,6 +71,7 @@ import { UploadResponse, HTTPError, IRequestOpts, + Body, } from "./http-api"; import { Crypto, @@ -2012,12 +2013,11 @@ export class MatrixClient extends TypedEventEmitterThis method is experimental * and may change without warning. * @param guest - True if this is a guest account. + * @experimental if the token is a macaroon, it should be encoded in it that it is a 'guest' + * access token, which means that the SDK can determine this entirely without + * the dev manually flipping this flag. */ public setGuest(guest: boolean): void { - // EXPERIMENTAL: - // If the token is a macaroon, it should be encoded in it that it is a 'guest' - // access token, which means that the SDK can determine this entirely without - // the dev manually flipping this flag. this.isGuestAccount = guest; } @@ -4405,7 +4405,7 @@ export class MatrixClient extends TypedEventEmitter, txnId?: string, ): Promise { if (!txnId) { @@ -4982,7 +4982,12 @@ export class MatrixClient extends TypedEventEmitter { + public async sendReceipt( + event: MatrixEvent, + receiptType: ReceiptType, + body?: Record, + unthreaded = false, + ): Promise<{}> { if (this.isGuest()) { return Promise.resolve({}); // guests cannot send receipts so don't bother. } @@ -5140,7 +5145,7 @@ export class MatrixClient extends TypedEventEmitter[] = []; + const promises: Promise[] = []; const doLeave = (roomId: string): Promise => { return this.leave(roomId) @@ -5935,7 +5940,7 @@ export class MatrixClient extends TypedEventEmitter = Promise.resolve(undefined); + let readPromise: Promise = Promise.resolve(); if (opts.allowRead) { readPromise = this.sendStateEvent( roomId, @@ -6599,7 +6604,7 @@ export class MatrixClient extends TypedEventEmitter( endpoint: string, - params: Record, + params: QueryDict, ): Promise { const postParams = Object.assign({}, params); @@ -7949,8 +7954,11 @@ export class MatrixClient extends TypedEventEmitter { - const body: any = {}; + public deactivateAccount( + auth?: AuthDict, + erase?: boolean, + ): Promise<{ id_server_unbind_result: IdServerUnbindResult }> { + const body: Body = {}; if (auth) { body.auth = auth; } @@ -8188,7 +8196,7 @@ export class MatrixClient extends TypedEventEmitter { @@ -8406,13 +8414,13 @@ export class MatrixClient extends TypedEventEmitter { - // TODO: Types const path = utils.encodeUri("/directory/list/appservice/$networkId/$roomId", { $networkId: networkId, $roomId: roomId, @@ -8428,7 +8436,7 @@ export class MatrixClient extends TypedEventEmitter { - const body: any = { + const body: Body = { search_term: term, }; @@ -8506,14 +8514,12 @@ export class MatrixClient extends TypedEventEmitter { - // TODO: Types + public addThreePid(creds: IBindThreePidBody, bind: boolean): Promise<{ submit_url?: string }> { const path = "/account/3pid"; const data = { threePidCreds: creds, @@ -8673,7 +8679,7 @@ export class MatrixClient extends TypedEventEmitter { - const body: any = { devices }; + const body: Body = { devices }; if (auth) { body.auth = auth; @@ -8868,7 +8874,7 @@ export class MatrixClient extends TypedEventEmitter { - const queryParams: any = {}; + const queryParams: QueryDict = {}; if (nextBatch) { queryParams.next_batch = nextBatch; } @@ -9488,7 +9494,7 @@ export class MatrixClient extends TypedEventEmitter { + public getThirdpartyUser(protocol: string, params?: QueryDict): Promise { const path = utils.encodeUri("/thirdparty/user/$protocol", { $protocol: protocol, }); @@ -9664,7 +9670,7 @@ export class MatrixClient extends TypedEventEmitter { - const qps: Record = {}; + const qps: QueryDict = {}; if (req.pos) { qps.pos = req.pos; delete req.pos; diff --git a/src/crypto/CrossSigning.ts b/src/crypto/CrossSigning.ts index e71967cb2a5..aa1c218c84a 100644 --- a/src/crypto/CrossSigning.ts +++ b/src/crypto/CrossSigning.ts @@ -18,8 +18,7 @@ limitations under the License. * Cross signing methods */ -import { PkSigning } from "@matrix-org/olm"; - +import type { PkSigning } from "@matrix-org/olm"; import { decodeBase64, encodeBase64, IObject, pkSign, pkVerify } from "./olmlib"; import { logger } from "../logger"; import { IndexedDBCryptoStore } from "../crypto/store/indexeddb-crypto-store"; @@ -245,7 +244,7 @@ export class CrossSigningInfo { * @returns A map from key type (string) to private key (Uint8Array) */ public async getCrossSigningKeysFromCache(): Promise> { - const keys = new Map(); + const keys = new Map(); const cacheCallbacks = this.cacheCallbacks; if (!cacheCallbacks) return keys; for (const type of ["master", "self_signing", "user_signing"]) { @@ -294,8 +293,8 @@ export class CrossSigningInfo { const privateKeys: Record = {}; const keys: Record = {}; - let masterSigning; - let masterPub; + let masterSigning: PkSigning | undefined; + let masterPub: string | undefined; try { if (level & CrossSigningLevel.MASTER) { diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 4d96216be07..beeefa54645 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -48,7 +48,7 @@ import { InRoomChannel, InRoomRequests } from "./verification/request/InRoomChan import { Request, ToDeviceChannel, ToDeviceRequests } from "./verification/request/ToDeviceChannel"; import { IllegalMethod } from "./verification/IllegalMethod"; import { KeySignatureUploadError } from "../errors"; -import { calculateKeyCheck, decryptAES, encryptAES } from "./aes"; +import { calculateKeyCheck, decryptAES, encryptAES, IEncryptedPayload } from "./aes"; import { DehydrationManager } from "./dehydration"; import { BackupManager } from "./backup"; import { IStore } from "../store"; @@ -1242,8 +1242,7 @@ export class Crypto extends TypedEventEmitter { - let key = await new Promise((resolve) => { - // TODO types + let key = await new Promise((resolve) => { this.cryptoStore.doTxn("readonly", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => { this.cryptoStore.getSecretStorePrivateKey(txn, resolve, "m.megolm_backup.v1"); }); @@ -1254,7 +1253,7 @@ export class Crypto extends TypedEventEmitter, - ): Promise { + ): Promise { // Check if the 'device' is actually a cross signing key // The js-sdk's verification treats cross-signing keys as devices // and so uses this method to mark them verified. const xsk = this.deviceList.getStoredCrossSigningForUser(userId); - if (xsk && xsk.getId() === deviceId) { + if (xsk?.getId() === deviceId) { if (blocked !== null || known !== null) { throw new Error("Cannot set blocked or known for a cross-signing key"); } @@ -2257,7 +2256,7 @@ export class Crypto extends TypedEventEmitter | BodyInit; - interface TypedResponse extends Response { json(): Promise; } diff --git a/src/http-api/interface.ts b/src/http-api/interface.ts index 9946aa37bf2..ae9400f385c 100644 --- a/src/http-api/interface.ts +++ b/src/http-api/interface.ts @@ -16,6 +16,8 @@ limitations under the License. import { MatrixError } from "./errors"; +export type Body = Record | BodyInit; + export interface IHttpOpts { fetchFn?: typeof global.fetch; diff --git a/src/rendezvous/MSC3906Rendezvous.ts b/src/rendezvous/MSC3906Rendezvous.ts index 3528a66decf..de7be644dfc 100644 --- a/src/rendezvous/MSC3906Rendezvous.ts +++ b/src/rendezvous/MSC3906Rendezvous.ts @@ -17,7 +17,12 @@ limitations under the License. import { UnstableValue } from "matrix-events-sdk"; import { RendezvousChannel, RendezvousFailureListener, RendezvousFailureReason, RendezvousIntent } from "."; -import { IMSC3882GetLoginTokenCapability, MatrixClient, UNSTABLE_MSC3882_CAPABILITY } from "../client"; +import { + ICrossSigningKey, + IMSC3882GetLoginTokenCapability, + MatrixClient, + UNSTABLE_MSC3882_CAPABILITY, +} from "../client"; import { CrossSigningInfo } from "../crypto/CrossSigning"; import { DeviceInfo } from "../crypto/deviceinfo"; import { buildFeatureSupportMap, Feature, ServerSupport } from "../feature"; @@ -178,7 +183,9 @@ export class MSC3906Rendezvous { return deviceId; } - private async verifyAndCrossSignDevice(deviceInfo: DeviceInfo): Promise { + private async verifyAndCrossSignDevice( + deviceInfo: DeviceInfo, + ): Promise { if (!this.client.crypto) { throw new Error("Crypto not available on client"); } @@ -223,7 +230,7 @@ export class MSC3906Rendezvous { */ public async verifyNewDeviceOnExistingDevice( timeout = 10 * 1000, - ): Promise { + ): Promise { if (!this.newDeviceId) { throw new Error("No new device to sign"); } diff --git a/src/webrtc/stats/media/mediaTrackHandler.ts b/src/webrtc/stats/media/mediaTrackHandler.ts index 787ce1a64fe..31f1264b3ea 100644 --- a/src/webrtc/stats/media/mediaTrackHandler.ts +++ b/src/webrtc/stats/media/mediaTrackHandler.ts @@ -23,14 +23,13 @@ export class MediaTrackHandler { const isNotNullAndKind = (track: MediaStreamTrack | null): boolean => { return track !== null && track.kind === kind; }; - // @ts-ignore The linter don't get it return this.pc .getTransceivers() .filter((t) => t.currentDirection === "sendonly" || t.currentDirection === "sendrecv") .filter((t) => t.sender !== null) .map((t) => t.sender) .map((s) => s.track) - .filter(isNotNullAndKind); + .filter(isNotNullAndKind) as MediaStreamTrack[]; } public getTackById(trackId: string): MediaStreamTrack | undefined { From b052950a190a08b5b0170ad2b7c2b9b172211efd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:57:45 +0100 Subject: [PATCH 25/59] Update JS-DevTools/npm-publish action to v2.2.1 (#3581) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-npm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-npm.yml b/.github/workflows/release-npm.yml index e4837153589..b2f8e1e889a 100644 --- a/.github/workflows/release-npm.yml +++ b/.github/workflows/release-npm.yml @@ -24,7 +24,7 @@ jobs: - name: 🚀 Publish to npm id: npm-publish - uses: JS-DevTools/npm-publish@a25b4180b728b0279fca97d4e5bccf391685aead # v2.2.0 + uses: JS-DevTools/npm-publish@5a85faf05d2ade2d5b6682bfe5359915d5159c6c # v2.2.1 with: token: ${{ secrets.NPM_TOKEN }} access: public From aeede332be3a470b71499d19a00a37195fa52aca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jul 2023 10:59:05 +0000 Subject: [PATCH 26/59] Update dependency @types/jest to v29.5.3 (#3582) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index f5472c560ff..12fa4e31873 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1830,9 +1830,9 @@ "@types/istanbul-lib-report" "*" "@types/jest@^29.0.0": - version "29.5.2" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.2.tgz#86b4afc86e3a8f3005b297ed8a72494f89e6395b" - integrity sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg== + version "29.5.3" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.3.tgz#7a35dc0044ffb8b56325c6802a4781a626b05777" + integrity sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA== dependencies: expect "^29.0.0" pretty-format "^29.0.0" From 0fb3dc1b130184a2f54e643b5ebfc36d83d1f8c0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:01:00 +0000 Subject: [PATCH 27/59] Update typescript-eslint monorepo to v5.62.0 (#3583) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 86 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 19 deletions(-) diff --git a/yarn.lock b/yarn.lock index 12fa4e31873..8a221340ffa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1929,14 +1929,14 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.45.0": - version "5.61.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz#a1a5290cf33863b4db3fb79350b3c5275a7b1223" - integrity sha512-A5l/eUAug103qtkwccSCxn8ZRwT+7RXWkFECdA4Cvl1dOlDUgTpAOfSEElZn2uSUxhdDpnCdetrf0jvU4qrL+g== + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== dependencies: "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.61.0" - "@typescript-eslint/type-utils" "5.61.0" - "@typescript-eslint/utils" "5.61.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" graphemer "^1.4.0" ignore "^5.2.0" @@ -1945,13 +1945,13 @@ tsutils "^3.21.0" "@typescript-eslint/parser@^5.45.0": - version "5.61.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.61.0.tgz#7fbe3e2951904bb843f8932ebedd6e0635bffb70" - integrity sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg== + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== dependencies: - "@typescript-eslint/scope-manager" "5.61.0" - "@typescript-eslint/types" "5.61.0" - "@typescript-eslint/typescript-estree" "5.61.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" debug "^4.3.4" "@typescript-eslint/scope-manager@5.61.0": @@ -1962,13 +1962,21 @@ "@typescript-eslint/types" "5.61.0" "@typescript-eslint/visitor-keys" "5.61.0" -"@typescript-eslint/type-utils@5.61.0": - version "5.61.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.61.0.tgz#e90799eb2045c4435ea8378cb31cd8a9fddca47a" - integrity sha512-kk8u//r+oVK2Aj3ph/26XdH0pbAkC2RiSjUYhKD+PExemG4XSjpGFeyZ/QM8lBOa7O8aGOU+/yEbMJgQv/DnCg== +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== dependencies: - "@typescript-eslint/typescript-estree" "5.61.0" - "@typescript-eslint/utils" "5.61.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + +"@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== + dependencies: + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" tsutils "^3.21.0" @@ -1977,6 +1985,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.61.0.tgz#e99ff11b5792d791554abab0f0370936d8ca50c0" integrity sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ== +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== + "@typescript-eslint/typescript-estree@5.61.0": version "5.61.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz#4c7caca84ce95bb41aa585d46a764bcc050b92f3" @@ -1990,7 +2003,34 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.61.0", "@typescript-eslint/utils@^5.10.0": +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + eslint-scope "^5.1.1" + semver "^7.3.7" + +"@typescript-eslint/utils@^5.10.0": version "5.61.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.61.0.tgz#5064838a53e91c754fffbddd306adcca3fe0af36" integrity sha512-mV6O+6VgQmVE6+xzlA91xifndPW9ElFW8vbSF0xCT/czPXVhwDewKila1jOyRwa9AE19zKnrr7Cg5S3pJVrTWQ== @@ -2012,6 +2052,14 @@ "@typescript-eslint/types" "5.61.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== + dependencies: + "@typescript-eslint/types" "5.62.0" + eslint-visitor-keys "^3.3.0" + JSONStream@^1.0.3: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" From 9602aa88ea1c792f0e63a3e32decd5a8d61b9c83 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 12 Jul 2023 14:55:02 +0100 Subject: [PATCH 28/59] Fix sending `auth: null` due to broken types around UIA (#3594) * Fix type issue around `getSessionBackupPrivateKey` * Fix sending auth: null due to broken types around UIA * Discard changes to src/crypto/index.ts * Add comment --- src/crypto/EncryptionSetup.ts | 2 +- src/interactive-auth.ts | 5 +++-- src/rust-crypto/OutgoingRequestProcessor.ts | 8 +++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/crypto/EncryptionSetup.ts b/src/crypto/EncryptionSetup.ts index b8f52fcdcea..2c838446753 100644 --- a/src/crypto/EncryptionSetup.ts +++ b/src/crypto/EncryptionSetup.ts @@ -188,7 +188,7 @@ export class EncryptionSetupOperation { // We must only call `uploadDeviceSigningKeys` from inside this auth // helper to ensure we properly handle auth errors. await this.crossSigningKeys.authUpload?.((authDict) => { - return baseApis.uploadDeviceSigningKeys(authDict, keys as CrossSigningKeys); + return baseApis.uploadDeviceSigningKeys(authDict ?? undefined, keys as CrossSigningKeys); }); // pass the new keys to the main instance of our own CrossSigningInfo. diff --git a/src/interactive-auth.ts b/src/interactive-auth.ts index e85ac9c2770..0a75ab5232f 100644 --- a/src/interactive-auth.ts +++ b/src/interactive-auth.ts @@ -159,11 +159,12 @@ export class NoAuthFlowFoundError extends Error { * The type of an application callback to perform the user-interactive bit of UIA. * * It is called with a single parameter, `makeRequest`, which is a function which takes the UIA parameters and - * makes the HTTP request. + * makes the HTTP request. The `authData` parameter in `makeRequest` can be set to null to omit the `auth` field + * from the UIA request. * * The generic parameter `T` is the type of the response of the endpoint, once it is eventually successful. */ -export type UIAuthCallback = (makeRequest: (authData: IAuthDict) => Promise>) => Promise; +export type UIAuthCallback = (makeRequest: (authData: IAuthDict | null) => Promise>) => Promise; interface IOpts { /** diff --git a/src/rust-crypto/OutgoingRequestProcessor.ts b/src/rust-crypto/OutgoingRequestProcessor.ts index 20c0b93fa1b..213f8dd8400 100644 --- a/src/rust-crypto/OutgoingRequestProcessor.ts +++ b/src/rust-crypto/OutgoingRequestProcessor.ts @@ -116,11 +116,13 @@ export class OutgoingRequestProcessor { } const parsedBody = JSON.parse(body); - const makeRequest = async (auth: IAuthDict): Promise> => { - const newBody = { + const makeRequest = async (auth: IAuthDict | null): Promise> => { + const newBody: Record = { ...parsedBody, - auth, }; + if (auth !== null) { + newBody.auth = auth; + } const resp = await this.rawJsonRequest(method, path, queryParams, JSON.stringify(newBody)); return JSON.parse(resp) as T; }; From e82b5fe1dbf5302ad70c02f3d648f20778e12119 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 12 Jul 2023 15:38:14 +0100 Subject: [PATCH 29/59] Fix types in getSessionBackupPrivateKey (#3595) * Fix type issue around `getSessionBackupPrivateKey` * Fix sending auth: null due to broken types around UIA * Discard changes to src/crypto/index.ts * Add comment * Fix types * Fix types for MatrixClient::addThreePid * Iterate --- src/@types/requests.ts | 6 ++++++ src/client.ts | 3 ++- src/crypto/index.ts | 12 +++++++----- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/@types/requests.ts b/src/@types/requests.ts index 0c79534e875..eca0132fb31 100644 --- a/src/@types/requests.ts +++ b/src/@types/requests.ts @@ -181,6 +181,12 @@ export interface IBindThreePidBody { sid: string; } +export interface IAddThreePidBody { + client_secret: string; + id_server: string; + sid: string; +} + export interface IRelationsRequestOpts { from?: string; to?: string; diff --git a/src/client.ts b/src/client.ts index 16da1791701..b8568a0a3c6 100644 --- a/src/client.ts +++ b/src/client.ts @@ -133,6 +133,7 @@ import { IFilterResponse, ITagsResponse, IStatusResponse, + IAddThreePidBody, } from "./@types/requests"; import { EventType, @@ -8519,7 +8520,7 @@ export class MatrixClient extends TypedEventEmitter { + public addThreePid(creds: IAddThreePidBody, bind: boolean): Promise<{ submit_url?: string }> { const path = "/account/3pid"; const data = { threePidCreds: creds, diff --git a/src/crypto/index.ts b/src/crypto/index.ts index beeefa54645..ab588afce9f 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -1242,20 +1242,22 @@ export class Crypto extends TypedEventEmitter { - let key = await new Promise((resolve) => { + const encodedKey = await new Promise((resolve) => { this.cryptoStore.doTxn("readonly", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => { this.cryptoStore.getSecretStorePrivateKey(txn, resolve, "m.megolm_backup.v1"); }); }); + let key: Uint8Array | null = null; + // make sure we have a Uint8Array, rather than a string - if (key && typeof key === "string") { - key = new Uint8Array(olmlib.decodeBase64(fixBackupKey(key) || key)); + if (typeof encodedKey === "string") { + key = new Uint8Array(olmlib.decodeBase64(fixBackupKey(encodedKey) || encodedKey)); await this.storeSessionBackupPrivateKey(key); } - if (key && typeof key === "object" && "ciphertext" in key) { + if (encodedKey && typeof encodedKey === "object" && "ciphertext" in encodedKey) { const pickleKey = Buffer.from(this.olmDevice.pickleKey); - const decrypted = await decryptAES(key, pickleKey, "m.megolm_backup.v1"); + const decrypted = await decryptAES(encodedKey, pickleKey, "m.megolm_backup.v1"); key = olmlib.decodeBase64(decrypted); } return key; From b186d79dde2802dec1334cfe2e306bd931da7079 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 12 Jul 2023 18:11:52 +0100 Subject: [PATCH 30/59] Fix jest/valid-expects lints (#3586) --- .eslintrc.js | 3 -- .../matrix-client-event-timeline.spec.ts | 30 ++++++++++++++++--- spec/integ/sliding-sync.spec.ts | 23 +++++++------- spec/unit/login.spec.ts | 6 ++-- spec/unit/oidc/register.spec.ts | 4 +-- spec/unit/rendezvous/ecdhv2.spec.ts | 13 ++++---- spec/unit/rendezvous/rendezvous.spec.ts | 8 ++--- .../rendezvous/simpleHttpTransport.spec.ts | 22 +++++++------- spec/unit/stores/indexeddb.spec.ts | 2 +- spec/unit/utils.spec.ts | 2 -- spec/unit/webrtc/call.spec.ts | 2 +- 11 files changed, 66 insertions(+), 49 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 7db8e71402f..e0150cca7d1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -66,9 +66,6 @@ module.exports = { // Disabled tests are a reality for now but as soon as all of the xits are // eliminated, we should enforce this. "jest/no-disabled-tests": "off", - // TODO: There are many tests with invalid expects that should be fixed, - // https://github.com/matrix-org/matrix-js-sdk/issues/2976 - "jest/valid-expect": "off", // Also treat "oldBackendOnly" as a test function. // Used in some crypto tests. "jest/no-standalone-expect": [ diff --git a/spec/integ/matrix-client-event-timeline.spec.ts b/spec/integ/matrix-client-event-timeline.spec.ts index 9a8f7b3058f..bc28efa7222 100644 --- a/spec/integ/matrix-client-event-timeline.spec.ts +++ b/spec/integ/matrix-client-event-timeline.spec.ts @@ -248,7 +248,7 @@ describe("getEventTimeline support", function () { return startClient(httpBackend, client).then(function () { const room = client.getRoom(roomId)!; const timelineSet = room!.getTimelineSets()[0]; - expect(client.getEventTimeline(timelineSet, "event")).rejects.toBeTruthy(); + return expect(client.getEventTimeline(timelineSet, "event")).rejects.toBeTruthy(); }); }); @@ -260,7 +260,18 @@ describe("getEventTimeline support", function () { return startClient(httpBackend, client).then(() => { const room = client.getRoom(roomId)!; const timelineSet = room!.getTimelineSets()[0]; - expect(client.getEventTimeline(timelineSet, "event")).rejects.toBeFalsy(); + httpBackend.when("GET", `/rooms/${encodeURIComponent(roomId)}/context/event`).respond(200, () => ({ + event: { + event_id: "event", + }, + events_after: [], + events_before: [], + state: [], + })); + return Promise.all([ + expect(client.getEventTimeline(timelineSet, "event")).resolves.toBeTruthy(), + httpBackend.flushAllExpected(), + ]); }); }); @@ -271,7 +282,7 @@ describe("getEventTimeline support", function () { return startClient(httpBackend, client).then(function () { const timelineSet = new EventTimelineSet(undefined); - expect(client.getEventTimeline(timelineSet, "event")).rejects.toBeTruthy(); + return expect(client.getEventTimeline(timelineSet, "event")).rejects.toBeTruthy(); }); }); @@ -778,7 +789,18 @@ describe("MatrixClient event timelines", function () { return startClient(httpBackend, client).then(() => { const room = client.getRoom(roomId)!; const timelineSet = room.getTimelineSets()[0]; - expect(client.getLatestTimeline(timelineSet)).rejects.toBeFalsy(); + httpBackend.when("GET", `/rooms/${encodeURIComponent(roomId)}/context/event`).respond(200, () => ({ + event: { + event_id: "event", + }, + events_after: [], + events_before: [], + state: [], + })); + return Promise.all([ + expect(client.getEventTimeline(timelineSet, "event")).resolves.toBeTruthy(), + httpBackend.flushAllExpected(), + ]); }); }); diff --git a/spec/integ/sliding-sync.spec.ts b/spec/integ/sliding-sync.spec.ts index c37a7e69172..5066329c26c 100644 --- a/spec/integ/sliding-sync.spec.ts +++ b/spec/integ/sliding-sync.spec.ts @@ -1161,11 +1161,6 @@ describe("SlidingSync", () => { httpBackend!.when("POST", syncUrl).check(pushTxn).respond(200, { pos: "f" }); // missing txn_id await httpBackend!.flushAllExpected(); - // attach rejection handlers now else if we do it later Jest treats that as an unhandled rejection - // which is a fail. - expect(failPromise).rejects.toEqual(gotTxnIds[0]); - expect(failPromise2).rejects.toEqual(gotTxnIds[1]); - const okPromise = slidingSync.setListRanges("a", [[0, 20]]); let txnId: string | undefined; httpBackend! @@ -1180,8 +1175,12 @@ describe("SlidingSync", () => { txn_id: txnId, }; }); - await httpBackend!.flushAllExpected(); - await okPromise; + await Promise.all([ + expect(failPromise).rejects.toEqual(gotTxnIds[0]), + expect(failPromise2).rejects.toEqual(gotTxnIds[1]), + httpBackend!.flushAllExpected(), + okPromise, + ]); expect(txnId).toBeDefined(); }); @@ -1200,7 +1199,6 @@ describe("SlidingSync", () => { // attach rejection handlers now else if we do it later Jest treats that as an unhandled rejection // which is a fail. - expect(A).rejects.toEqual(gotTxnIds[0]); const C = slidingSync.setListRanges("a", [[0, 20]]); let pendingC = true; @@ -1217,9 +1215,12 @@ describe("SlidingSync", () => { txn_id: gotTxnIds[1], }; }); - await httpBackend!.flushAllExpected(); - // A is rejected, see above - expect(B).resolves.toEqual(gotTxnIds[1]); // B is resolved + await Promise.all([ + expect(A).rejects.toEqual(gotTxnIds[0]), + httpBackend!.flushAllExpected(), + // A is rejected, see above + expect(B).resolves.toEqual(gotTxnIds[1]), // B is resolved + ]); expect(pendingC).toBe(true); // C is pending still }); it("should do nothing for unknown txn_ids", async () => { diff --git a/spec/unit/login.spec.ts b/spec/unit/login.spec.ts index 242594fc433..ff6f298a076 100644 --- a/spec/unit/login.spec.ts +++ b/spec/unit/login.spec.ts @@ -121,7 +121,7 @@ describe("refreshToken", () => { body: { errcode: "M_UNRECOGNIZED" }, }); - expect(client.refreshToken("initial_refresh_token")).rejects.toMatchObject({ errcode: "M_UNRECOGNIZED" }); + await expect(client.refreshToken("initial_refresh_token")).rejects.toMatchObject({ errcode: "M_UNRECOGNIZED" }); }); it("re-raises non-M_UNRECOGNIZED exceptions from /v3", async () => { @@ -132,7 +132,7 @@ describe("refreshToken", () => { throw new Error("/v1/refresh unexpectedly called"); }); - expect(client.refreshToken("initial_refresh_token")).rejects.toMatchObject({ httpStatus: 429 }); + await expect(client.refreshToken("initial_refresh_token")).rejects.toMatchObject({ httpStatus: 429 }); }); it("re-raises non-M_UNRECOGNIZED exceptions from /v1", async () => { @@ -144,6 +144,6 @@ describe("refreshToken", () => { }); fetchMock.postOnce(client.http.getUrl("/refresh", undefined, ClientPrefix.V1).toString(), 429); - expect(client.refreshToken("initial_refresh_token")).rejects.toMatchObject({ httpStatus: 429 }); + await expect(client.refreshToken("initial_refresh_token")).rejects.toMatchObject({ httpStatus: 429 }); }); }); diff --git a/spec/unit/oidc/register.spec.ts b/spec/unit/oidc/register.spec.ts index e9ad60463a7..ae61ecd2d81 100644 --- a/spec/unit/oidc/register.spec.ts +++ b/spec/unit/oidc/register.spec.ts @@ -66,7 +66,7 @@ describe("registerOidcClient()", () => { fetchMockJest.post(registrationEndpoint, { status: 500, }); - expect(() => registerOidcClient(delegatedAuthConfig, clientName, baseUrl)).rejects.toThrow( + await expect(() => registerOidcClient(delegatedAuthConfig, clientName, baseUrl)).rejects.toThrow( OidcError.DynamicRegistrationFailed, ); }); @@ -77,7 +77,7 @@ describe("registerOidcClient()", () => { // no clientId in response body: "{}", }); - expect(() => registerOidcClient(delegatedAuthConfig, clientName, baseUrl)).rejects.toThrow( + await expect(() => registerOidcClient(delegatedAuthConfig, clientName, baseUrl)).rejects.toThrow( OidcError.DynamicRegistrationInvalid, ); }); diff --git a/spec/unit/rendezvous/ecdhv2.spec.ts b/spec/unit/rendezvous/ecdhv2.spec.ts index 92559bf050e..2e88b345054 100644 --- a/spec/unit/rendezvous/ecdhv2.spec.ts +++ b/spec/unit/rendezvous/ecdhv2.spec.ts @@ -96,7 +96,7 @@ describe("ECDHv2", function () { expect(aliceChecksum).toEqual(bobChecksum); - expect(alice.connect()).rejects.toThrow(); + await expect(alice.connect()).rejects.toThrow(); await alice.cancel(RendezvousFailureReason.Unknown); await bob.cancel(RendezvousFailureReason.Unknown); @@ -120,9 +120,9 @@ describe("ECDHv2", function () { alice.close(); - expect(alice.connect()).rejects.toThrow(); - expect(alice.send({})).rejects.toThrow(); - expect(alice.receive()).rejects.toThrow(); + await expect(alice.connect()).rejects.toThrow(); + await expect(alice.send({})).rejects.toThrow(); + await expect(alice.receive()).rejects.toThrow(); await alice.cancel(RendezvousFailureReason.Unknown); await bob.cancel(RendezvousFailureReason.Unknown); @@ -146,10 +146,10 @@ describe("ECDHv2", function () { // send a message without encryption await aliceTransport.send({ iv: "dummy", ciphertext: "dummy" }); - expect(bob.receive()).rejects.toThrow(); await alice.cancel(RendezvousFailureReason.Unknown); await bob.cancel(RendezvousFailureReason.Unknown); + await expect(bob.receive()).rejects.toThrow(); }); it("ciphertext before set up", async function () { @@ -164,9 +164,8 @@ describe("ECDHv2", function () { await bobTransport.send({ iv: "dummy", ciphertext: "dummy" }); - expect(alice.receive()).rejects.toThrow(); - await alice.cancel(RendezvousFailureReason.Unknown); + await expect(alice.receive()).rejects.toThrow(); }); }); }); diff --git a/spec/unit/rendezvous/rendezvous.spec.ts b/spec/unit/rendezvous/rendezvous.spec.ts index 087b2f2de7e..ba36005092b 100644 --- a/spec/unit/rendezvous/rendezvous.spec.ts +++ b/spec/unit/rendezvous/rendezvous.spec.ts @@ -172,7 +172,7 @@ describe("Rendezvous", function () { const cancelPromise = aliceRz.cancel(RendezvousFailureReason.UserDeclined); await httpBackend.flush(""); - expect(cancelPromise).resolves.toBeUndefined(); + await expect(cancelPromise).resolves.toBeUndefined(); httpBackend.verifyNoOutstandingExpectation(); httpBackend.verifyNoOutstandingRequests(); @@ -603,7 +603,7 @@ describe("Rendezvous", function () { it("device not online within timeout", async function () { const { aliceRz } = await completeLogin({}); - expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrow(); + await expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrow(); }); it("device appears online within timeout", async function () { @@ -627,7 +627,7 @@ describe("Rendezvous", function () { getFingerprint: () => "bbbb", }; }, 1500); - expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrow(); + await expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrow(); }); it("mismatched device key", async function () { @@ -636,6 +636,6 @@ describe("Rendezvous", function () { getFingerprint: () => "XXXX", }, }); - expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrow(/different key/); + await expect(aliceRz.verifyNewDeviceOnExistingDevice(1000)).rejects.toThrow(/different key/); }); }); diff --git a/spec/unit/rendezvous/simpleHttpTransport.spec.ts b/spec/unit/rendezvous/simpleHttpTransport.spec.ts index 6087fbc8818..166a6350730 100644 --- a/spec/unit/rendezvous/simpleHttpTransport.spec.ts +++ b/spec/unit/rendezvous/simpleHttpTransport.spec.ts @@ -95,10 +95,10 @@ describe("SimpleHttpRendezvousTransport", function () { httpBackend.verifyNoOutstandingExpectation(); } } - it("should throw an error when no server available", function () { + it("should throw an error when no server available", async function () { const client = makeMockClient({ userId: "@alice:example.com", deviceId: "DEVICEID", msc3886Enabled: false }); const simpleHttpTransport = new MSC3886SimpleHttpRendezvousTransport({ client, fetchFn }); - expect(simpleHttpTransport.send({})).rejects.toThrow("Invalid rendezvous URI"); + await expect(simpleHttpTransport.send({})).rejects.toThrow("Invalid rendezvous URI"); }); it("POST to fallback server", async function () { @@ -130,7 +130,6 @@ describe("SimpleHttpRendezvousTransport", function () { fetchFn, }); const prom = simpleHttpTransport.send({}); - expect(prom).rejects.toThrow(); httpBackend.when("POST", "https://fallbackserver/rz").response = { body: null, response: { @@ -138,7 +137,7 @@ describe("SimpleHttpRendezvousTransport", function () { headers: {}, }, }; - await httpBackend.flush(""); + await Promise.all([expect(prom).rejects.toThrow(), httpBackend.flush("")]); }); it("POST with absolute path response", async function () { @@ -364,7 +363,7 @@ describe("SimpleHttpRendezvousTransport", function () { fallbackRzServer: "https://fallbackserver/rz", fetchFn, }); - expect(simpleHttpTransport.details()).rejects.toThrow(); + await expect(simpleHttpTransport.details()).rejects.toThrow(); }); it("send after cancelled", async function () { @@ -375,7 +374,7 @@ describe("SimpleHttpRendezvousTransport", function () { fetchFn, }); await simpleHttpTransport.cancel(RendezvousFailureReason.UserDeclined); - expect(simpleHttpTransport.send({})).resolves.toBeUndefined(); + await expect(simpleHttpTransport.send({})).resolves.toBeUndefined(); }); it("receive before ready", async function () { @@ -385,7 +384,7 @@ describe("SimpleHttpRendezvousTransport", function () { fallbackRzServer: "https://fallbackserver/rz", fetchFn, }); - expect(simpleHttpTransport.receive()).rejects.toThrow(); + await expect(simpleHttpTransport.receive()).rejects.toThrow(); }); it("404 failure callback", async function () { @@ -398,7 +397,6 @@ describe("SimpleHttpRendezvousTransport", function () { onFailure, }); - expect(simpleHttpTransport.send({ foo: "baa" })).resolves.toBeUndefined(); httpBackend.when("POST", "https://fallbackserver/rz").response = { body: null, response: { @@ -406,7 +404,10 @@ describe("SimpleHttpRendezvousTransport", function () { headers: {}, }, }; - await httpBackend.flush("", 1); + await Promise.all([ + expect(simpleHttpTransport.send({ foo: "baa" })).resolves.toBeUndefined(), + httpBackend.flush("", 1), + ]); expect(onFailure).toHaveBeenCalledWith(RendezvousFailureReason.Unknown); }); @@ -438,7 +439,6 @@ describe("SimpleHttpRendezvousTransport", function () { } { // GET with 404 to simulate expiry - expect(simpleHttpTransport.receive()).resolves.toBeUndefined(); httpBackend.when("GET", "https://fallbackserver/rz/123").response = { body: { foo: "baa" }, response: { @@ -446,7 +446,7 @@ describe("SimpleHttpRendezvousTransport", function () { headers: {}, }, }; - await httpBackend.flush(""); + await Promise.all([expect(simpleHttpTransport.receive()).resolves.toBeUndefined(), httpBackend.flush("")]); expect(onFailure).toHaveBeenCalledWith(RendezvousFailureReason.Expired); } }); diff --git a/spec/unit/stores/indexeddb.spec.ts b/spec/unit/stores/indexeddb.spec.ts index 7f2bc25d458..5a1eb4172ef 100644 --- a/spec/unit/stores/indexeddb.spec.ts +++ b/spec/unit/stores/indexeddb.spec.ts @@ -278,7 +278,7 @@ describe("IndexedDBStore", () => { workerFactory: () => worker, }); await store.startup(); - await expect(store.destroy()).resolves; + await store.destroy(); expect(terminate).toHaveBeenCalled(); }); }); diff --git a/spec/unit/utils.spec.ts b/spec/unit/utils.spec.ts index 5c2db9e9c88..8adb822adbd 100644 --- a/spec/unit/utils.spec.ts +++ b/spec/unit/utils.spec.ts @@ -38,8 +38,6 @@ import { mkMessage } from "../test-utils/test-utils"; import { makeBeaconEvent } from "../test-utils/beacon"; import { ReceiptType } from "../../src/@types/read_receipts"; -// TODO: Fix types throughout - describe("utils", function () { describe("encodeParams", function () { it("should url encode and concat with &s", function () { diff --git a/spec/unit/webrtc/call.spec.ts b/spec/unit/webrtc/call.spec.ts index 5a3b384539f..4a82be59637 100644 --- a/spec/unit/webrtc/call.spec.ts +++ b/spec/unit/webrtc/call.spec.ts @@ -1607,7 +1607,7 @@ describe("Call", function () { it("throws when there is no error listener", async () => { call.off(CallEvent.Error, errorListener); - expect(call.placeVoiceCall()).rejects.toThrow(); + await expect(call.placeVoiceCall()).rejects.toThrow(); }); describe("hasPeerConnection()", () => { From b05f933d833ef6c9b2a8ff7a8b27723b682bcce6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 13 Jul 2023 09:25:23 +0100 Subject: [PATCH 31/59] Fix read receipt sending behaviour around thread roots (#3600) * Fix read receipt sending behaviour around thread roots * Update src/client.ts Co-authored-by: Eric Eastwood --------- Co-authored-by: Eric Eastwood --- src/client.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index b8568a0a3c6..a85b04f7dc2 100644 --- a/src/client.ts +++ b/src/client.ts @@ -5000,9 +5000,11 @@ export class MatrixClient extends TypedEventEmitter Date: Thu, 13 Jul 2023 09:41:03 +0000 Subject: [PATCH 32/59] Update babel monorepo to v7.22.9 (#3434) * Update babel monorepo to v7.22.9 * Make babel happier --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/embedded.ts | 4 +- yarn.lock | 165 +++++++++++++++++++++++++++++------------------- 2 files changed, 102 insertions(+), 67 deletions(-) diff --git a/src/embedded.ts b/src/embedded.ts index c2c30105a42..e20c64a28b4 100644 --- a/src/embedded.ts +++ b/src/embedded.ts @@ -97,7 +97,7 @@ export interface ICapabilities { */ export class RoomWidgetClient extends MatrixClient { private room?: Room; - private widgetApiReady = new Promise((resolve) => this.widgetApi.once("ready", resolve)); + private readonly widgetApiReady: Promise; private lifecycle?: AbortController; private syncState: SyncState | null = null; @@ -109,6 +109,8 @@ export class RoomWidgetClient extends MatrixClient { ) { super(opts); + this.widgetApiReady = new Promise((resolve) => this.widgetApi.once("ready", resolve)); + // Request capabilities for the functionality this client needs to support if ( capabilities.sendEvent?.length || diff --git a/yarn.lock b/yarn.lock index 8a221340ffa..06bd1a9e045 100644 --- a/yarn.lock +++ b/yarn.lock @@ -41,9 +41,9 @@ "@jridgewell/trace-mapping" "^0.3.9" "@babel/cli@^7.12.10": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.22.6.tgz#63f5be2a0abd587ccfbdc93424fa85f43142cc53" - integrity sha512-Be3/RfEDmkMRGT1+ru5nTkfcvWz5jDOYg1V9rXqTz2u9Qt96O1ryboGvxVBp7wOnYWDB8DNHIWb6DThrpudfOw== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.22.9.tgz#501b3614aeda7399371f6d5991404f069b059986" + integrity sha512-nb2O7AThqRo7/E53EGiuAkMaRbb7J5Qp3RvN+dmua1U+kydm0oznkhqbTEG15yk26G/C3yL6OdZjzgl+DMXVVA== dependencies: "@jridgewell/trace-mapping" "^0.3.17" commander "^4.0.1" @@ -63,40 +63,45 @@ dependencies: "@babel/highlight" "^7.22.5" -"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6": +"@babel/compat-data@^7.20.5": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.6.tgz#15606a20341de59ba02cd2fcc5086fcbe73bf544" integrity sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg== +"@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== + "@babel/core@^7.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.7.5": - version "7.22.8" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.8.tgz#386470abe884302db9c82e8e5e87be9e46c86785" - integrity sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.9.tgz#bd96492c68822198f33e8a256061da3cf391f58f" + integrity sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.22.5" - "@babel/generator" "^7.22.7" - "@babel/helper-compilation-targets" "^7.22.6" - "@babel/helper-module-transforms" "^7.22.5" + "@babel/generator" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.9" + "@babel/helper-module-transforms" "^7.22.9" "@babel/helpers" "^7.22.6" "@babel/parser" "^7.22.7" "@babel/template" "^7.22.5" "@babel/traverse" "^7.22.8" "@babel/types" "^7.22.5" - "@nicolo-ribaudo/semver-v6" "^6.3.3" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.2" + semver "^6.3.1" "@babel/eslint-parser@^7.12.10": - version "7.22.7" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.22.7.tgz#d2807fbd1fa4376162716da63dfd3c69a2249fed" - integrity sha512-LH6HJqjOyu/Qtp7LuSycZXK/CYXQ4ohdkliEaL1QTdtOXVdOVpTBKVxAo/+eeyt+x/2SRzB+zUPduVl+xiEvdg== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.22.9.tgz#75f8aa978d1e76c87cc6f26c1ea16ae58804d390" + integrity sha512-xdMkt39/nviO/4vpVdrEYPwXCsYIXSSAr6mC7WQsNIlGnuxKyKE7GZjalcnbSWiC4OXGNNN3UQPeHfjSC6sTDA== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" - "@nicolo-ribaudo/semver-v6" "^6.3.3" eslint-visitor-keys "^2.1.0" + semver "^6.3.1" "@babel/eslint-plugin@^7.12.10": version "7.22.5" @@ -105,7 +110,7 @@ dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.12.11", "@babel/generator@^7.22.7", "@babel/generator@^7.7.2": +"@babel/generator@^7.12.11", "@babel/generator@^7.7.2": version "7.22.7" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.7.tgz#a6b8152d5a621893f2c9dacf9a4e286d520633d5" integrity sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ== @@ -115,6 +120,16 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" +"@babel/generator@^7.22.7", "@babel/generator@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" + integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== + dependencies: + "@babel/types" "^7.22.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" @@ -129,7 +144,7 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": +"@babel/helper-compilation-targets@^7.20.7": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz#e30d61abe9480aa5a83232eb31c111be922d2e52" integrity sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA== @@ -140,7 +155,18 @@ browserslist "^4.21.9" lru-cache "^5.1.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.5": +"@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892" + integrity sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.18.6": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.6.tgz#58564873c889a6fea05a538e23f9f6d201f10950" integrity sha512-iwdzgtSiBxF6ni6mzVnZCF3xt5qE6cEA0J7nFt8QOAWZ0zjCFceEgpn3vtb2V7WFR6QzP2jmIFOHMTRo7eNJjQ== @@ -155,14 +181,29 @@ "@babel/helper-split-export-declaration" "^7.22.6" "@nicolo-ribaudo/semver-v6" "^6.3.3" +"@babel/helper-create-class-features-plugin@^7.22.5": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz#c36ea240bb3348f942f08b0fbe28d6d979fab236" + integrity sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.6.tgz#87afd63012688ad792de430ceb3b6dc28e4e7a40" - integrity sha512-nBookhLKxAWo/TUCmhnaEJyLz2dekjQvv5SRpE9epWQBcpedWLKt8aZdsuT9XV5ovzR3fENLjRXVT0GsSlGGhA== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" + integrity sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@nicolo-ribaudo/semver-v6" "^6.3.3" regexpu-core "^5.3.1" + semver "^6.3.1" "@babel/helper-define-polyfill-provider@^0.4.1": version "0.4.1" @@ -209,19 +250,16 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-module-transforms@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz#0f65daa0716961b6e96b164034e737f60a80d2ef" - integrity sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw== +"@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== dependencies: "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-module-imports" "^7.22.5" "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" "@babel/helper-validator-identifier" "^7.22.5" - "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" - "@babel/types" "^7.22.5" "@babel/helper-optimise-call-expression@^7.22.5": version "7.22.5" @@ -236,26 +274,22 @@ integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== "@babel/helper-remap-async-to-generator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz#14a38141a7bf2165ad38da61d61cf27b43015da2" - integrity sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz#53a25b7484e722d7efb9c350c75c032d4628de82" + integrity sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-wrap-function" "^7.22.5" - "@babel/types" "^7.22.5" + "@babel/helper-wrap-function" "^7.22.9" -"@babel/helper-replace-supers@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz#71bc5fb348856dea9fdc4eafd7e2e49f585145dc" - integrity sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg== +"@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz#cbdc27d6d8d18cd22c81ae4293765a5d9afd0779" + integrity sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg== dependencies: "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-member-expression-to-functions" "^7.22.5" "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" - "@babel/types" "^7.22.5" "@babel/helper-simple-access@^7.22.5": version "7.22.5" @@ -271,7 +305,7 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-split-export-declaration@^7.22.5", "@babel/helper-split-export-declaration@^7.22.6": +"@babel/helper-split-export-declaration@^7.22.6": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== @@ -293,14 +327,13 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== -"@babel/helper-wrap-function@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz#44d205af19ed8d872b4eefb0d2fa65f45eb34f06" - integrity sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw== +"@babel/helper-wrap-function@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz#189937248c45b0182c1dcf32f3444ca153944cb9" + integrity sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q== dependencies: "@babel/helper-function-name" "^7.22.5" "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" "@babel/types" "^7.22.5" "@babel/helpers@^7.22.6": @@ -852,16 +885,16 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-runtime@^7.12.10": - version "7.22.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.7.tgz#eb9094b5fb756cc2d98d398b2c88aeefa9205de9" - integrity sha512-o02xM7iY7mSPI+TvaYDH0aYl+lg3+KT7qrD705JlsB/GrZSNaYO/4i+aDFKPiJ7ubq3hgv8NNLCdyB5MFxT8mg== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.9.tgz#a87b11e170cbbfb018e6a2bf91f5c6e533b9e027" + integrity sha512-9KjBH61AGJetCPYp/IEyLEp47SyybZb0nDRpBvmtEkm+rUIwxdlKpyNHI1TmsGkeuLclJdleQHRZ8XLBnnh8CQ== dependencies: "@babel/helper-module-imports" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" - "@nicolo-ribaudo/semver-v6" "^6.3.3" babel-plugin-polyfill-corejs2 "^0.4.4" babel-plugin-polyfill-corejs3 "^0.8.2" babel-plugin-polyfill-regenerator "^0.5.1" + semver "^6.3.1" "@babel/plugin-transform-shorthand-properties@^7.22.5": version "7.22.5" @@ -941,12 +974,12 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/preset-env@^7.12.11": - version "7.22.7" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.7.tgz#a1ef34b64a80653c22ce4d9c25603cfa76fc168a" - integrity sha512-1whfDtW+CzhETuzYXfcgZAh8/GFMeEbz0V5dVgya8YeJyCU6Y/P2Gnx4Qb3MylK68Zu9UiwUvbPMPTpFAOJ+sQ== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.9.tgz#57f17108eb5dfd4c5c25a44c1977eba1df310ac7" + integrity sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g== dependencies: - "@babel/compat-data" "^7.22.6" - "@babel/helper-compilation-targets" "^7.22.6" + "@babel/compat-data" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.9" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-option" "^7.22.5" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.5" @@ -1020,11 +1053,11 @@ "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" "@babel/preset-modules" "^0.1.5" "@babel/types" "^7.22.5" - "@nicolo-ribaudo/semver-v6" "^6.3.3" babel-plugin-polyfill-corejs2 "^0.4.4" babel-plugin-polyfill-corejs3 "^0.8.2" babel-plugin-polyfill-regenerator "^0.5.1" core-js-compat "^3.31.0" + semver "^6.3.1" "@babel/preset-modules@^0.1.5": version "0.1.5" @@ -1080,7 +1113,7 @@ "@babel/parser" "^7.22.5" "@babel/types" "^7.22.5" -"@babel/traverse@^7.1.6", "@babel/traverse@^7.22.5", "@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": +"@babel/traverse@^7.1.6", "@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": version "7.22.8" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== @@ -2834,9 +2867,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001503: - version "1.0.30001514" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001514.tgz#e2a7e184a23affc9367b7c8d734e7ec4628c1309" - integrity sha512-ENcIpYBmwAAOm/V2cXgM7rZUrKKaqisZl4ZAI520FIkqGXUxJjmaIssbRW5HVVR5tyV6ygTLIm15aU8LUmQSaQ== + version "1.0.30001515" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001515.tgz#418aefeed9d024cd3129bfae0ccc782d4cb8f12b" + integrity sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA== center-align@^0.1.1: version "0.1.3" @@ -3452,9 +3485,9 @@ eastasianwidth@^0.2.0: integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== electron-to-chromium@^1.4.431: - version "1.4.454" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.454.tgz#774dc7cb5e58576d0125939ec34a4182f3ccc87d" - integrity sha512-pmf1rbAStw8UEQ0sr2cdJtWl48ZMuPD9Sto8HVQOq9vx9j2WgDEN6lYoaqFvqEHYOmGA9oRGn7LqWI9ta0YugQ== + version "1.4.457" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.457.tgz#3fdc7b4f97d628ac6b51e8b4b385befb362fe343" + integrity sha512-/g3UyNDmDd6ebeWapmAoiyy+Sy2HyJ+/X8KyvNeHfKRFfHaA2W8oF5fxD5F3tjBDcjpwo0iek6YNgxNXDBoEtA== elliptic@^6.5.3: version "6.5.4" @@ -6860,7 +6893,7 @@ sdp-transform@^2.14.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== From 13fec49e744a50ac0be7c6bb9fd97c30a9b24f95 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 13 Jul 2023 11:46:56 +0100 Subject: [PATCH 33/59] Element-R: ensure that `userHasCrossSigningKeys` uses up-to-date data (#3599) * Element-R: ensure that `userHasCrossSigningKeys` uses up-to-date data * Bump matrix-sdk-crypto-js --- package.json | 2 +- spec/unit/rust-crypto/rust-crypto.spec.ts | 75 +++++++++-------------- src/rust-crypto/rust-crypto.ts | 8 ++- yarn.lock | 8 +-- 4 files changed, 41 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index 4248cddbfb4..62e2b4efbd4 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ ], "dependencies": { "@babel/runtime": "^7.12.5", - "@matrix-org/matrix-sdk-crypto-js": "^0.1.3", + "@matrix-org/matrix-sdk-crypto-js": "^0.1.4", "another-json": "^0.2.0", "bs58": "^5.0.0", "content-type": "^1.0.4", diff --git a/spec/unit/rust-crypto/rust-crypto.spec.ts b/spec/unit/rust-crypto/rust-crypto.spec.ts index 7776e9ef837..61b04e38867 100644 --- a/spec/unit/rust-crypto/rust-crypto.spec.ts +++ b/spec/unit/rust-crypto/rust-crypto.spec.ts @@ -34,7 +34,7 @@ import { import { mkEvent } from "../../test-utils/test-utils"; import { CryptoBackend } from "../../../src/common-crypto/CryptoBackend"; import { IEventDecryptionResult } from "../../../src/@types/crypto"; -import { OutgoingRequest, OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor"; +import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor"; import { ServerSideSecretStorage } from "../../../src/secret-storage"; import { CryptoCallbacks, ImportRoomKeysOpts, VerificationRequest } from "../../../src/crypto-api"; import * as testData from "../../test-utils/test-data"; @@ -42,6 +42,10 @@ import * as testData from "../../test-utils/test-data"; const TEST_USER = "@alice:example.com"; const TEST_DEVICE_ID = "TEST_DEVICE"; +afterEach(() => { + fetchMock.reset(); +}); + describe("RustCrypto", () => { describe(".importRoomKeys and .exportRoomKeys", () => { let rustCrypto: RustCrypto; @@ -390,60 +394,39 @@ describe("RustCrypto", () => { let rustCrypto: RustCrypto; beforeEach(async () => { - rustCrypto = await makeTestRustCrypto(undefined, testData.TEST_USER_ID); - }); - - afterEach(() => { - jest.useRealTimers(); + rustCrypto = await makeTestRustCrypto( + new MatrixHttpApi(new TypedEventEmitter(), { + baseUrl: "http://server/", + prefix: "", + onlyData: true, + }), + testData.TEST_USER_ID, + ); }); - it("returns false initially", async () => { - jest.useFakeTimers(); - const prom = rustCrypto.userHasCrossSigningKeys(); - // the getIdentity() request should wait for a /keys/query request to complete, but times out after 1500ms - await jest.advanceTimersByTimeAsync(2000); - await expect(prom).resolves.toBe(false); + it("throws an error if the fetch fails", async () => { + fetchMock.post("path:/_matrix/client/v3/keys/query", 400); + await expect(rustCrypto.userHasCrossSigningKeys()).rejects.toThrow("400 error"); }); - it("returns false if there is no cross-signing identity", async () => { - // @ts-ignore private field - const olmMachine = rustCrypto.olmMachine; - - const outgoingRequests: OutgoingRequest[] = await olmMachine.outgoingRequests(); - // pick out the KeysQueryRequest, and respond to it with the device keys but *no* cross-signing keys. - const req = outgoingRequests.find((r) => r instanceof KeysQueryRequest)!; - await olmMachine.markRequestAsSent( - req.id!, - req.type, - JSON.stringify({ - device_keys: { - [testData.TEST_USER_ID]: { [testData.TEST_DEVICE_ID]: testData.SIGNED_TEST_DEVICE_DATA }, - }, - }), - ); + it("returns false if the user has no cross-signing keys", async () => { + fetchMock.post("path:/_matrix/client/v3/keys/query", { + device_keys: { + [testData.TEST_USER_ID]: { [testData.TEST_DEVICE_ID]: testData.SIGNED_TEST_DEVICE_DATA }, + }, + }); await expect(rustCrypto.userHasCrossSigningKeys()).resolves.toBe(false); }); - it("returns true if OlmMachine has a cross-signing identity", async () => { - // @ts-ignore private field - const olmMachine = rustCrypto.olmMachine; - - const outgoingRequests: OutgoingRequest[] = await olmMachine.outgoingRequests(); - // pick out the KeysQueryRequest, and respond to it with the cross-signing keys - const req = outgoingRequests.find((r) => r instanceof KeysQueryRequest)!; - await olmMachine.markRequestAsSent( - req.id!, - req.type, - JSON.stringify({ - device_keys: { - [testData.TEST_USER_ID]: { [testData.TEST_DEVICE_ID]: testData.SIGNED_TEST_DEVICE_DATA }, - }, - ...testData.SIGNED_CROSS_SIGNING_KEYS_DATA, - }), - ); + it("returns true if the user has cross-signing keys", async () => { + fetchMock.post("path:/_matrix/client/v3/keys/query", { + device_keys: { + [testData.TEST_USER_ID]: { [testData.TEST_DEVICE_ID]: testData.SIGNED_TEST_DEVICE_DATA }, + }, + ...testData.SIGNED_CROSS_SIGNING_KEYS_DATA, + }); - // ... and we should now have cross-signing keys. await expect(rustCrypto.userHasCrossSigningKeys()).resolves.toBe(true); }); }); diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 5ca8b7f65dd..d7248137c7b 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -206,7 +206,13 @@ export class RustCrypto extends TypedEventEmitter { - const userIdentity = await this.olmMachine.getIdentity(new RustSdkCryptoJs.UserId(this.userId)); + const userId = new RustSdkCryptoJs.UserId(this.userId); + /* make sure we have an *up-to-date* idea of the user's cross-signing keys. This is important, because if we + * return "false" here, we will end up generating new cross-signing keys and replacing the existing ones. + */ + const request = this.olmMachine.queryKeysForUsers([userId]); + await this.outgoingRequestProcessor.makeOutgoingRequest(request); + const userIdentity = await this.olmMachine.getIdentity(userId); return userIdentity !== undefined; } diff --git a/yarn.lock b/yarn.lock index 06bd1a9e045..49caa8cef22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1530,10 +1530,10 @@ dependencies: lodash "^4.17.21" -"@matrix-org/matrix-sdk-crypto-js@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.3.tgz#19981e7613d3673d07c885a98d39276b5fe74ef0" - integrity sha512-RcRlE3wcMnE5ijACHIHmhXFogEEJdIcb/CbJ4rK1PCMduQ4yvxycVpMxwh7aKxFNitZbHZLCK7TfRzUpzjU2tw== +"@matrix-org/matrix-sdk-crypto-js@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.4.tgz#c13c7c8c3a1d8da08e6ad195d25e5e61cc402df7" + integrity sha512-OxG84iSeR89zYLFeb+DCaFtZT+DDiIu+kTkqY8OYfhE5vpGLFX2sDVBRrAdos1IUqEoboDloDBR9+yU7hNRyog== "@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz": version "3.2.14" From f005984df301d00b429964f47afce3aeb6b9c3ee Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 13 Jul 2023 12:10:24 +0100 Subject: [PATCH 34/59] Export typed event emitter key types (#3597) * Export typed event emitter key types * Update src/matrix.ts --- src/matrix.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/matrix.ts b/src/matrix.ts index 7f2ca3f9d3f..ce3e713d5e2 100644 --- a/src/matrix.ts +++ b/src/matrix.ts @@ -63,9 +63,22 @@ export * as SecretStorage from "./secret-storage"; export type { ICryptoCallbacks } from "./crypto"; // used to be located here export { createNewMatrixCall } from "./webrtc/call"; export type { MatrixCall } from "./webrtc/call"; -export { GroupCallEvent, GroupCallIntent, GroupCallState, GroupCallType } from "./webrtc/groupCall"; +export { + GroupCallEvent, + GroupCallIntent, + GroupCallState, + GroupCallType, + GroupCallStatsReportEvent, +} from "./webrtc/groupCall"; export type { GroupCall } from "./webrtc/groupCall"; export { CryptoEvent } from "./crypto"; +export { SlidingSyncEvent } from "./sliding-sync"; +export { MediaHandlerEvent } from "./webrtc/mediaHandler"; +export { CallEvent } from "./webrtc/call"; +export { CallFeedEvent } from "./webrtc/callFeed"; +export { StatsReport } from "./webrtc/stats/statsReport"; +export { RelationsEvent } from "./models/relations"; +export { LocalStorageErrors } from "./store/local-storage-events-emitter"; /** * Types supporting cryptography. From d92936fba5c0ff76fbf1a9ceb7ce9685b0731ade Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 13 Jul 2023 12:11:13 +0100 Subject: [PATCH 35/59] Element-R: support for displaying QR codes during verification (#3588) * Support for showing QR codes * Emit `VerificationRequestEvent.Change` events when the verifier changes * Minor integ test tweaks * Handle transitions from QR code display to SAS * Fix naming * Add a test for `ShowQrCodeCallbacks.cancel` --- spec/integ/crypto/verification.spec.ts | 184 ++++++++++++++++++++++--- src/crypto-api/verification.ts | 4 +- src/rust-crypto/verification.ts | 133 +++++++++++++++--- 3 files changed, 279 insertions(+), 42 deletions(-) diff --git a/spec/integ/crypto/verification.spec.ts b/spec/integ/crypto/verification.spec.ts index 1a8ce32f116..56acc6d5c39 100644 --- a/spec/integ/crypto/verification.spec.ts +++ b/spec/integ/crypto/verification.spec.ts @@ -81,12 +81,8 @@ const TEST_HOMESERVER_URL = "https://alice-server.com"; */ // we test with both crypto stacks... describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: string, initCrypto: InitCrypto) => { - // oldBackendOnly is an alternative to `it` or `test` which will skip the test if we are running against the - // Rust backend. Once we have full support in the rust sdk, it will go away. - const oldBackendOnly = backend === "rust-sdk" ? test.skip : test; - // newBackendOnly is the opposite to `oldBackendOnly`: it will skip the test if we are running against the legacy - // backend. + // backend. Once we drop support for legacy crypto, it will go away. const newBackendOnly = backend === "rust-sdk" ? test : test.skip; /** the client under test */ @@ -391,12 +387,11 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st expect(toDeviceMessage.transaction_id).toEqual(transactionId); }); - oldBackendOnly("can verify another via QR code with an untrusted cross-signing key", async () => { + it("can verify another via QR code with an untrusted cross-signing key", async () => { aliceClient = await startTestClient(); // QRCode fails if we don't yet have the cross-signing keys, so make sure we have them now. e2eKeyResponder.addCrossSigningData(SIGNED_CROSS_SIGNING_KEYS_DATA); await waitForDeviceList(); - expect(aliceClient.getStoredCrossSigningForUser(TEST_USER_ID)).toBeTruthy(); // have alice initiate a verification. She should send a m.key.verification.request const [requestBody, request] = await Promise.all([ @@ -434,16 +429,12 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st ); const sharedSecret = qrCodeBuffer.subarray(74 + txnIdLen); + // we should still be "Ready" and have no verifier + expect(request.phase).toEqual(VerificationPhase.Ready); + expect(request.verifier).toBeUndefined(); + // the dummy device "scans" the displayed QR code and acknowledges it with a "m.key.verification.start" - returnToDeviceMessageFromSync({ - type: "m.key.verification.start", - content: { - from_device: TEST_DEVICE_ID, - method: "m.reciprocate.v1", - transaction_id: transactionId, - secret: encodeUnpaddedBase64(sharedSecret), - }, - }); + returnToDeviceMessageFromSync(buildReciprocateStartMessage(transactionId, sharedSecret)); await waitForVerificationRequestChanged(request); expect(request.phase).toEqual(VerificationPhase.Started); expect(request.chosenMethod).toEqual("m.reciprocate.v1"); @@ -451,23 +442,25 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st // there should now be a verifier const verifier: Verifier = request.verifier!; expect(verifier).toBeDefined(); - expect(verifier.getReciprocateQrCodeCallbacks()).toBeNull(); // ... which we call .verify on, which emits a ShowReciprocateQr event - const verificationPromise = verifier.verify(); - const reciprocateQRCodeCallbacks = await new Promise((resolve) => { + const reciprocatePromise = new Promise((resolve) => { verifier.once(VerifierEvent.ShowReciprocateQr, resolve); }); + const verificationPromise = verifier.verify(); + const reciprocateQRCodeCallbacks = await reciprocatePromise; // getReciprocateQrCodeCallbacks() is an alternative way to get the callbacks expect(verifier.getReciprocateQrCodeCallbacks()).toBe(reciprocateQRCodeCallbacks); expect(verifier.getShowSasCallbacks()).toBeNull(); - // Alice confirms she is happy + // Alice confirms she is happy, which makes her reply with a 'done' + const sendToDevicePromise = expectSendToDeviceMessage("m.key.verification.done"); reciprocateQRCodeCallbacks.confirm(); + await sendToDevicePromise; - // that should satisfy Alice, who should reply with a 'done' - await expectSendToDeviceMessage("m.key.verification.done"); + // the dummy device replies with its own 'done' + returnToDeviceMessageFromSync(buildDoneMessage(transactionId)); // ... and the whole thing should be done! await verificationPromise; @@ -531,12 +524,102 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st await verificationPromise; expect(request.phase).toEqual(VerificationPhase.Done); }); + + it("can send an SAS start after QR code display", async () => { + aliceClient = await startTestClient(); + e2eKeyResponder.addCrossSigningData(SIGNED_CROSS_SIGNING_KEYS_DATA); + await waitForDeviceList(); + + // Alice sends a m.key.verification.request + const [, request] = await Promise.all([ + expectSendToDeviceMessage("m.key.verification.request"), + aliceClient.getCrypto()!.requestDeviceVerification(TEST_USER_ID, TEST_DEVICE_ID), + ]); + const transactionId = request.transactionId!; + + // The dummy device replies with an m.key.verification.ready, with an indication it can scan a QR code + // or do the emoji dance + returnToDeviceMessageFromSync( + buildReadyMessage(transactionId, ["m.qr_code.scan.v1", "m.sas.v1", "m.reciprocate.v1"]), + ); + await waitForVerificationRequestChanged(request); + expect(request.phase).toEqual(VerificationPhase.Ready); + + // Alice displays the QR code + const qrCodeBuffer = (await request.generateQRCode())!; + expect(qrCodeBuffer).toBeTruthy(); + expect(request.phase).toEqual(VerificationPhase.Ready); + expect(request.verifier).toBeUndefined(); + + // advance the clock, because the devicelist likes to sleep for 5ms during key downloads + await jest.advanceTimersByTimeAsync(10); + + // ... but Alice wants to do an SAS verification + const sendToDevicePromise = expectSendToDeviceMessage("m.key.verification.start"); + await request.startVerification("m.sas.v1"); + await sendToDevicePromise; + + // There should now be a `verifier` + const verifier: Verifier = request.verifier!; + expect(verifier).toBeDefined(); + expect(request.chosenMethod).toEqual("m.sas.v1"); + + // clean up the test + expectSendToDeviceMessage("m.key.verification.cancel"); + request.cancel(); + await expect(verifier.verify()).rejects.toBeTruthy(); + }); + + it("can receive an SAS start after QR code display", async () => { + aliceClient = await startTestClient(); + e2eKeyResponder.addCrossSigningData(SIGNED_CROSS_SIGNING_KEYS_DATA); + await waitForDeviceList(); + + // Alice sends a m.key.verification.request + const [, request] = await Promise.all([ + expectSendToDeviceMessage("m.key.verification.request"), + aliceClient.getCrypto()!.requestDeviceVerification(TEST_USER_ID, TEST_DEVICE_ID), + ]); + const transactionId = request.transactionId!; + + // The dummy device replies with an m.key.verification.ready, with an indication it can scan a QR code + // or do the emoji dance + returnToDeviceMessageFromSync( + buildReadyMessage(transactionId, ["m.qr_code.scan.v1", "m.sas.v1", "m.reciprocate.v1"]), + ); + await waitForVerificationRequestChanged(request); + expect(request.phase).toEqual(VerificationPhase.Ready); + + // Alice displays the QR code + const qrCodeBuffer = (await request.generateQRCode())!; + expect(qrCodeBuffer).toBeTruthy(); + expect(request.phase).toEqual(VerificationPhase.Ready); + expect(request.verifier).toBeUndefined(); + + // advance the clock, because the devicelist likes to sleep for 5ms during key downloads + await jest.advanceTimersByTimeAsync(10); + + // ... but the dummy device wants to do an SAS verification + returnToDeviceMessageFromSync(buildSasStartMessage(transactionId)); + await emitPromise(request, VerificationRequestEvent.Change); + + // Alice should now have a `verifier` + const verifier: Verifier = request.verifier!; + expect(verifier).toBeDefined(); + expect(request.chosenMethod).toEqual("m.sas.v1"); + + // clean up the test + expectSendToDeviceMessage("m.key.verification.cancel"); + request.cancel(); + await expect(verifier.verify()).rejects.toBeTruthy(); + }); }); describe("cancellation", () => { beforeEach(async () => { // pretend that we have another device, which we will start verifying e2eKeyResponder.addDeviceKeys(TEST_USER_ID, TEST_DEVICE_ID, SIGNED_TEST_DEVICE_DATA); + e2eKeyResponder.addCrossSigningData(SIGNED_CROSS_SIGNING_KEYS_DATA); aliceClient = await startTestClient(); await waitForDeviceList(); @@ -604,6 +687,50 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st expect(request.phase).toEqual(VerificationPhase.Cancelled); expect(verifier.hasBeenCancelled).toBe(true); }); + + it("can cancel in the ShowQrCodeCallbacks", async () => { + // have alice initiate a verification. She should send a m.key.verification.request + const [, request] = await Promise.all([ + expectSendToDeviceMessage("m.key.verification.request"), + aliceClient.getCrypto()!.requestDeviceVerification(TEST_USER_ID, TEST_DEVICE_ID), + ]); + const transactionId = request.transactionId!; + + // The dummy device replies with an m.key.verification.ready, with an indication it can scan the QR code + returnToDeviceMessageFromSync(buildReadyMessage(transactionId, ["m.qr_code.scan.v1"])); + await waitForVerificationRequestChanged(request); + expect(request.phase).toEqual(VerificationPhase.Ready); + + // we should now have QR data we can display + const qrCodeBuffer = (await request.generateQRCode())!; + expect(qrCodeBuffer).toBeTruthy(); + const sharedSecret = qrCodeBuffer.subarray(74 + transactionId.length); + + // the dummy device "scans" the displayed QR code and acknowledges it with a "m.key.verification.start" + returnToDeviceMessageFromSync(buildReciprocateStartMessage(transactionId, sharedSecret)); + await waitForVerificationRequestChanged(request); + expect(request.phase).toEqual(VerificationPhase.Started); + expect(request.chosenMethod).toEqual("m.reciprocate.v1"); + + // there should now be a verifier + const verifier: Verifier = request.verifier!; + expect(verifier).toBeDefined(); + + // ... which we call .verify on, which emits a ShowReciprocateQr event + const reciprocatePromise = emitPromise(verifier, VerifierEvent.ShowReciprocateQr); + const verificationPromise = verifier.verify(); + const reciprocateQRCodeCallbacks: ShowQrCodeCallbacks = await reciprocatePromise; + + // Alice complains that she didn't see the dummy device scan her code + const sendToDevicePromise = expectSendToDeviceMessage("m.key.verification.cancel"); + reciprocateQRCodeCallbacks.cancel(); + await sendToDevicePromise; + + // ... which should cancel the verifier + await expect(verificationPromise).rejects.toBeTruthy(); + expect(request.phase).toEqual(VerificationPhase.Cancelled); + expect(verifier.hasBeenCancelled).toBe(true); + }); }); describe("Incoming verification from another device", () => { @@ -779,6 +906,19 @@ function buildReadyMessage(transactionId: string, methods: string[]): { type: st }; } +/** build an m.key.verification.start to-device message suitable for the m.reciprocate.v1 flow, originating from the dummy device */ +function buildReciprocateStartMessage(transactionId: string, sharedSecret: Uint8Array) { + return { + type: "m.key.verification.start", + content: { + from_device: TEST_DEVICE_ID, + method: "m.reciprocate.v1", + transaction_id: transactionId, + secret: encodeUnpaddedBase64(sharedSecret), + }, + }; +} + /** build an m.key.verification.start to-device message suitable for the SAS flow, originating from the dummy device */ function buildSasStartMessage(transactionId: string): { type: string; content: object } { return { diff --git a/src/crypto-api/verification.ts b/src/crypto-api/verification.ts index 07d3dbbeea6..acbade99f56 100644 --- a/src/crypto-api/verification.ts +++ b/src/crypto-api/verification.ts @@ -310,7 +310,7 @@ export enum VerifierEvent { ShowSas = "show_sas", /** - * QR code data should be displayed to the user. + * The user should confirm if the other side has scanned our QR code. * * The payload is the {@link ShowQrCodeCallbacks} object. */ @@ -325,7 +325,7 @@ export type VerifierEventHandlerMap = { }; /** - * Callbacks for user actions while a QR code is displayed. + * Callbacks for user actions to confirm that the other side has scanned our QR code. * * This is exposed as the payload of a `VerifierEvent.ShowReciprocateQr` event, or can be retrieved directly from the * verifier as `reciprocateQREvent`. diff --git a/src/rust-crypto/verification.ts b/src/rust-crypto/verification.ts index 5066ad1fae0..85ba876d22b 100644 --- a/src/rust-crypto/verification.ts +++ b/src/rust-crypto/verification.ts @@ -15,7 +15,7 @@ limitations under the License. */ import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; -import { Emoji } from "@matrix-org/matrix-sdk-crypto-js"; +import { Emoji, QrState } from "@matrix-org/matrix-sdk-crypto-js"; import { ShowQrCodeCallbacks, @@ -30,6 +30,7 @@ import { } from "../crypto-api/verification"; import { TypedEventEmitter } from "../models/typed-event-emitter"; import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProcessor"; +import { TypedReEmitter } from "../ReEmitter"; /** * An incoming, or outgoing, request to verify a user or a device via cross-signing. @@ -40,13 +41,16 @@ export class RustVerificationRequest extends TypedEventEmitter implements VerificationRequest { + /** a reëmitter which relays VerificationRequestEvent.Changed events emitted by the verifier */ + private readonly reEmitter: TypedReEmitter; + /** Are we in the process of sending an `m.key.verification.ready` event? */ private _accepting = false; /** Are we in the process of sending an `m.key.verification.cancellation` event? */ private _cancelling = false; - private _verifier: Verifier | undefined; + private _verifier: undefined | RustSASVerifier | RustQrCodeVerifier; /** * Construct a new RustVerificationRequest to wrap the rust-level `VerificationRequest`. @@ -62,15 +66,19 @@ export class RustVerificationRequest ) { super(); + this.reEmitter = new TypedReEmitter(this); + const onChange = async (): Promise => { - // if we now have a `Verification` where we lacked one before, wrap it. - if (this._verifier === undefined) { - const verification: RustSdkCryptoJs.Qr | RustSdkCryptoJs.Sas | undefined = this.inner.getVerification(); - if (verification instanceof RustSdkCryptoJs.Sas) { + const verification: RustSdkCryptoJs.Qr | RustSdkCryptoJs.Sas | undefined = this.inner.getVerification(); + + // If we now have a `Verification` where we lacked one before, or we have transitioned from QR to SAS, + // wrap the new rust Verification as a js-sdk Verifier. + if (verification instanceof RustSdkCryptoJs.Sas) { + if (this._verifier === undefined || this._verifier instanceof RustQrCodeVerifier) { this.setVerifier(new RustSASVerifier(verification, this, outgoingRequestProcessor)); - } else if (verification instanceof RustSdkCryptoJs.Qr) { - this.setVerifier(new RustQrCodeVerifier(verification, outgoingRequestProcessor)); } + } else if (verification instanceof RustSdkCryptoJs.Qr && this._verifier === undefined) { + this.setVerifier(new RustQrCodeVerifier(verification, outgoingRequestProcessor)); } this.emit(VerificationRequestEvent.Change); @@ -79,7 +87,12 @@ export class RustVerificationRequest } private setVerifier(verifier: RustSASVerifier | RustQrCodeVerifier): void { + // if we already have a verifier, unsubscribe from its events + if (this._verifier) { + this.reEmitter.stopReEmitting(this._verifier, [VerificationRequestEvent.Change]); + } this._verifier = verifier; + this.reEmitter.reEmit(this._verifier, [VerificationRequestEvent.Change]); } /** @@ -138,7 +151,11 @@ export class RustVerificationRequest // parlance. return this._accepting ? VerificationPhase.Requested : VerificationPhase.Ready; case RustSdkCryptoJs.VerificationRequestPhase.Transitioned: - return VerificationPhase.Started; + if (!this._verifier) { + // this shouldn't happen, because the onChange handler should have created a _verifier. + throw new Error("VerificationRequest: inner phase == Transitioned but no verifier!"); + } + return this._verifier.verificationPhase; case RustSdkCryptoJs.VerificationRequestPhase.Done: return VerificationPhase.Done; case RustSdkCryptoJs.VerificationRequestPhase.Cancelled: @@ -189,8 +206,9 @@ export class RustVerificationRequest /** the method picked in the .start event */ public get chosenMethod(): string | null { + if (this.phase !== VerificationPhase.Started) return null; + const verification: RustSdkCryptoJs.Qr | RustSdkCryptoJs.Sas | undefined = this.inner.getVerification(); - // TODO: this isn't quite right. The existence of a Verification doesn't prove that we have .started. if (verification instanceof RustSdkCryptoJs.Sas) { return "m.sas.v1"; } else if (verification instanceof RustSdkCryptoJs.Qr) { @@ -350,15 +368,20 @@ export class RustVerificationRequest * Only defined when the `phase` is Started. */ public get verifier(): Verifier | undefined { - return this._verifier; + // It's possible for us to have a Verifier before a method has been chosen (in particular, + // if we are showing a QR code which the other device has not yet scanned. At that point, we could + // still switch to SAS). + // + // In that case, we should not return it to the application yet, since the application will not expect the + // Verifier to be replaced during the lifetime of the VerificationRequest. + return this.phase === VerificationPhase.Started ? this._verifier : undefined; } /** * Stub implementation of {@link Crypto.VerificationRequest#getQRCodeBytes}. */ public getQRCodeBytes(): Buffer | undefined { - // TODO - return undefined; + throw new Error("getQRCodeBytes() unsupported in Rust Crypto; use generateQRCode() instead."); } /** @@ -367,8 +390,8 @@ export class RustVerificationRequest * Implementation of {@link Crypto.VerificationRequest#generateQRCode}. */ public async generateQRCode(): Promise { - // TODO - return undefined; + const innerVerifier: RustSdkCryptoJs.Qr = await this.inner.generateQrCode(); + return Buffer.from(innerVerifier.toBytes()); } /** @@ -396,8 +419,8 @@ export class RustVerificationRequest * @internal */ abstract class BaseRustVerifer extends TypedEventEmitter< - VerifierEvent, - VerifierEventHandlerMap + VerifierEvent | VerificationRequestEvent, + VerifierEventHandlerMap & VerificationRequestEventHandlerMap > { /** A promise which completes when the verification completes (or rejects when it is cancelled/fails) */ protected readonly completionPromise: Promise; @@ -424,6 +447,8 @@ abstract class BaseRustVerifer implements Verifier { + private callbacks: ShowQrCodeCallbacks | null = null; + public constructor(inner: RustSdkCryptoJs.Qr, outgoingRequestProcessor: OutgoingRequestProcessor) { super(inner, outgoingRequestProcessor); } + protected onChange(): void { + // if the other side has scanned our QR code and sent us a "reciprocate" message, it is now time for the + // application to prompt the user to confirm their side. + if (this.callbacks === null && this.inner.hasBeenScanned()) { + this.callbacks = { + confirm: () => this.confirmScanning(), + cancel: () => this.cancel(), + }; + } + } + /** * Start the key verification, if it has not already been started. * @@ -502,9 +540,61 @@ export class RustQrCodeVerifier extends BaseRustVerifer impl * or times out. */ public async verify(): Promise { + // Some applications (hello, matrix-react-sdk) may not check if there is a `ShowQrCodeCallbacks` and instead + // register a `ShowReciprocateQr` listener which they expect to be called once `.verify` is called. + if (this.callbacks !== null) { + this.emit(VerifierEvent.ShowReciprocateQr, this.callbacks); + } // Nothing to do here but wait. await this.completionPromise; } + + /** + * Calculate an appropriate VerificationPhase for a VerificationRequest where this is the verifier. + * + * This is abnormally complicated because a rust-side QR Code verifier can span several verification phases. + */ + public get verificationPhase(): VerificationPhase { + switch (this.inner.state()) { + case QrState.Created: + // we have created a QR for display; neither side has yet sent an `m.key.verification.start`. + return VerificationPhase.Ready; + case QrState.Scanned: + // other side has scanned our QR and sent an `m.key.verification.start` with `m.reciprocate.v1` + return VerificationPhase.Started; + case QrState.Confirmed: + // we have confirmed the other side's scan and sent an `m.key.verification.done`. + return VerificationPhase.Done; + case QrState.Reciprocated: + // although the rust SDK doesn't immediately send the `m.key.verification.start` on transition into this + // state, `RustVerificationRequest.scanQrCode` immediately calls `reciprocate()` and does so, so in practice + // we can treat the two the same. + return VerificationPhase.Started; + case QrState.Done: + return VerificationPhase.Done; + case QrState.Cancelled: + return VerificationPhase.Cancelled; + default: + throw new Error(`Unknown qr code state ${this.inner.state()}`); + } + } + + /** + * Get the details for reciprocating QR code verification, if one is in progress + * + * Returns `null`, unless this verifier is for reciprocating a QR-code-based verification (ie, the other user has + * already scanned our QR code), and we are waiting for the user to confirm. + */ + public getReciprocateQrCodeCallbacks(): ShowQrCodeCallbacks | null { + return this.callbacks; + } + + private async confirmScanning(): Promise { + const req: undefined | OutgoingRequest = this.inner.confirmScanning(); + if (req) { + await this.outgoingRequestProcessor.makeOutgoingRequest(req); + } + } } /** A Verifier instance which is used if we are exchanging emojis */ @@ -568,6 +658,13 @@ export class RustSASVerifier extends BaseRustVerifer implem } } + /** + * Calculate an appropriate VerificationPhase for a VerificationRequest where this is the verifier. + */ + public get verificationPhase(): VerificationPhase { + return VerificationPhase.Started; + } + /** * Get the details for an SAS verification, if one is in progress * From 8ef2e848b931aa9c1addae92690cbdf036be56e8 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Thu, 13 Jul 2023 08:07:01 -0500 Subject: [PATCH 36/59] Log query parameters on HTTP requests (#3591) * Log query parameters on HTTP requests Follow-up to https://github.com/matrix-org/matrix-js-sdk/pull/3485 * Only stringify once See https://github.com/matrix-org/matrix-js-sdk/pull/3591#discussion_r1261300323 --- spec/unit/http-api/fetch.spec.ts | 6 +++--- src/http-api/fetch.ts | 16 +++++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/spec/unit/http-api/fetch.spec.ts b/spec/unit/http-api/fetch.spec.ts index 236fbe1c32f..2cb5f4dd3af 100644 --- a/spec/unit/http-api/fetch.spec.ts +++ b/spec/unit/http-api/fetch.spec.ts @@ -300,7 +300,7 @@ describe("FetchHttpApi", () => { const fetchFn = jest.fn().mockReturnValue(deferred.promise); jest.spyOn(logger, "debug").mockImplementation(() => {}); const api = new FetchHttpApi(new TypedEventEmitter(), { baseUrl, prefix, fetchFn }); - const prom = api.requestOtherUrl(Method.Get, "https://server:8448/some/path#fragment?query=param"); + const prom = api.requestOtherUrl(Method.Get, "https://server:8448/some/path?query=param#fragment"); jest.advanceTimersByTime(1234); deferred.resolve({ ok: true, status: 200, text: () => Promise.resolve("RESPONSE") } as Response); await prom; @@ -310,12 +310,12 @@ describe("FetchHttpApi", () => { expect(logger.debug).toHaveBeenCalledTimes(2); expect(mocked(logger.debug).mock.calls[0]).toMatchInlineSnapshot(` [ - "FetchHttpApi: --> GET https://server:8448/some/path", + "FetchHttpApi: --> GET https://server:8448/some/path?query=xxx", ] `); expect(mocked(logger.debug).mock.calls[1]).toMatchInlineSnapshot(` [ - "FetchHttpApi: <-- GET https://server:8448/some/path [1234ms 200]", + "FetchHttpApi: <-- GET https://server:8448/some/path?query=xxx [1234ms 200]", ] `); }); diff --git a/src/http-api/fetch.ts b/src/http-api/fetch.ts index 9408c94cefe..f59546bb0b8 100644 --- a/src/http-api/fetch.ts +++ b/src/http-api/fetch.ts @@ -224,7 +224,7 @@ export class FetchHttpApi { body?: Body, opts: Pick = {}, ): Promise> { - const urlForLogs = this.clearUrlParamsForLogs(url); + const urlForLogs = this.sanitizeUrlForLogs(url); logger.debug(`FetchHttpApi: --> ${method} ${urlForLogs}`); const headers = Object.assign({}, opts.headers || {}); @@ -299,7 +299,7 @@ export class FetchHttpApi { return res as ResponseType; } - private clearUrlParamsForLogs(url: URL | string): string { + private sanitizeUrlForLogs(url: URL | string): string { try { let asUrl: URL; if (typeof url === "string") { @@ -307,9 +307,15 @@ export class FetchHttpApi { } else { asUrl = url; } - // get just the path to remove any potential url param that could have - // some potential secrets - return asUrl.origin + asUrl.pathname; + // Remove the values of any URL params that could contain potential secrets + const sanitizedQs = new URLSearchParams(); + for (const key of asUrl.searchParams.keys()) { + sanitizedQs.append(key, "xxx"); + } + const sanitizedQsString = sanitizedQs.toString(); + const sanitizedQsUrlPiece = sanitizedQsString ? `?${sanitizedQsString}` : ""; + + return asUrl.origin + asUrl.pathname + sanitizedQsUrlPiece; } catch (error) { // defensive coding for malformed url return "??"; From 0b193f466562304d7f9976aec1970d42cf2abb08 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 13 Jul 2023 18:11:57 +0100 Subject: [PATCH 37/59] matrix-sdk-crypto-js -> matrix-sdk-crypto-wasm (#3602) We've renamed matrix-sdk-crypto-js and released a v1.0. --- package.json | 2 +- spec/integ/crypto/verification.spec.ts | 2 +- spec/unit/rust-crypto/CrossSigningIdentity.spec.ts | 2 +- spec/unit/rust-crypto/KeyClaimManager.spec.ts | 4 ++-- spec/unit/rust-crypto/OutgoingRequestProcessor.spec.ts | 4 ++-- spec/unit/rust-crypto/rust-crypto.spec.ts | 4 ++-- spec/unit/rust-crypto/verification.spec.ts | 2 +- src/rust-crypto/CrossSigningIdentity.ts | 2 +- src/rust-crypto/KeyClaimManager.ts | 2 +- src/rust-crypto/OutgoingRequestProcessor.ts | 2 +- src/rust-crypto/RoomEncryptor.ts | 2 +- src/rust-crypto/device-converter.ts | 2 +- src/rust-crypto/index.ts | 4 ++-- src/rust-crypto/rust-crypto.ts | 2 +- src/rust-crypto/verification.ts | 4 ++-- yarn.lock | 8 ++++---- 16 files changed, 24 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 62e2b4efbd4..f32a3cad5a2 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ ], "dependencies": { "@babel/runtime": "^7.12.5", - "@matrix-org/matrix-sdk-crypto-js": "^0.1.4", + "@matrix-org/matrix-sdk-crypto-wasm": "^1.0.1", "another-json": "^0.2.0", "bs58": "^5.0.0", "content-type": "^1.0.4", diff --git a/spec/integ/crypto/verification.spec.ts b/spec/integ/crypto/verification.spec.ts index 56acc6d5c39..a245b56e25d 100644 --- a/spec/integ/crypto/verification.spec.ts +++ b/spec/integ/crypto/verification.spec.ts @@ -59,7 +59,7 @@ beforeAll(async () => { // load the rust library. This can take a few seconds on a slow GH worker. beforeAll(async () => { - const RustSdkCryptoJs = await require("@matrix-org/matrix-sdk-crypto-js"); + const RustSdkCryptoJs = await require("@matrix-org/matrix-sdk-crypto-wasm"); await RustSdkCryptoJs.initAsync(); }, 10000); diff --git a/spec/unit/rust-crypto/CrossSigningIdentity.spec.ts b/spec/unit/rust-crypto/CrossSigningIdentity.spec.ts index d0fb8bd36be..6187ec7ede3 100644 --- a/spec/unit/rust-crypto/CrossSigningIdentity.spec.ts +++ b/spec/unit/rust-crypto/CrossSigningIdentity.spec.ts @@ -15,7 +15,7 @@ limitations under the License. */ import { Mocked } from "jest-mock"; -import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; +import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; import { CrossSigningIdentity } from "../../../src/rust-crypto/CrossSigningIdentity"; import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor"; diff --git a/spec/unit/rust-crypto/KeyClaimManager.spec.ts b/spec/unit/rust-crypto/KeyClaimManager.spec.ts index e448feabeca..64a228d7f9a 100644 --- a/spec/unit/rust-crypto/KeyClaimManager.spec.ts +++ b/spec/unit/rust-crypto/KeyClaimManager.spec.ts @@ -14,10 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; +import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; import fetchMock from "fetch-mock-jest"; import { Mocked } from "jest-mock"; -import { KeysClaimRequest, UserId } from "@matrix-org/matrix-sdk-crypto-js"; +import { KeysClaimRequest, UserId } from "@matrix-org/matrix-sdk-crypto-wasm"; import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor"; import { KeyClaimManager } from "../../../src/rust-crypto/KeyClaimManager"; diff --git a/spec/unit/rust-crypto/OutgoingRequestProcessor.spec.ts b/spec/unit/rust-crypto/OutgoingRequestProcessor.spec.ts index bb1cdff6ab1..94ce93b7ef1 100644 --- a/spec/unit/rust-crypto/OutgoingRequestProcessor.spec.ts +++ b/spec/unit/rust-crypto/OutgoingRequestProcessor.spec.ts @@ -16,7 +16,7 @@ limitations under the License. import MockHttpBackend from "matrix-mock-request"; import { Mocked } from "jest-mock"; -import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; +import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; import { KeysBackupRequest, KeysClaimRequest, @@ -26,7 +26,7 @@ import { SignatureUploadRequest, SigningKeysUploadRequest, ToDeviceRequest, -} from "@matrix-org/matrix-sdk-crypto-js"; +} from "@matrix-org/matrix-sdk-crypto-wasm"; import { TypedEventEmitter } from "../../../src/models/typed-event-emitter"; import { HttpApiEvent, HttpApiEventHandlerMap, MatrixHttpApi, UIAuthCallback } from "../../../src"; diff --git a/spec/unit/rust-crypto/rust-crypto.spec.ts b/spec/unit/rust-crypto/rust-crypto.spec.ts index 61b04e38867..74b55ff7396 100644 --- a/spec/unit/rust-crypto/rust-crypto.spec.ts +++ b/spec/unit/rust-crypto/rust-crypto.spec.ts @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; -import { KeysQueryRequest, OlmMachine } from "@matrix-org/matrix-sdk-crypto-js"; +import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; +import { KeysQueryRequest, OlmMachine } from "@matrix-org/matrix-sdk-crypto-wasm"; import { Mocked } from "jest-mock"; import fetchMock from "fetch-mock-jest"; diff --git a/spec/unit/rust-crypto/verification.spec.ts b/spec/unit/rust-crypto/verification.spec.ts index a2f671fdb0b..a22ee8fd662 100644 --- a/spec/unit/rust-crypto/verification.spec.ts +++ b/spec/unit/rust-crypto/verification.spec.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; +import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; import { Mocked } from "jest-mock"; import { RustVerificationRequest } from "../../../src/rust-crypto/verification"; diff --git a/src/rust-crypto/CrossSigningIdentity.ts b/src/rust-crypto/CrossSigningIdentity.ts index 5203bd87731..2c43ed60397 100644 --- a/src/rust-crypto/CrossSigningIdentity.ts +++ b/src/rust-crypto/CrossSigningIdentity.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { OlmMachine, CrossSigningStatus } from "@matrix-org/matrix-sdk-crypto-js"; +import { OlmMachine, CrossSigningStatus } from "@matrix-org/matrix-sdk-crypto-wasm"; import { BootstrapCrossSigningOpts } from "../crypto-api"; import { logger } from "../logger"; diff --git a/src/rust-crypto/KeyClaimManager.ts b/src/rust-crypto/KeyClaimManager.ts index 4b13ef432cf..ff7f3956536 100644 --- a/src/rust-crypto/KeyClaimManager.ts +++ b/src/rust-crypto/KeyClaimManager.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { OlmMachine, UserId } from "@matrix-org/matrix-sdk-crypto-js"; +import { OlmMachine, UserId } from "@matrix-org/matrix-sdk-crypto-wasm"; import { OutgoingRequestProcessor } from "./OutgoingRequestProcessor"; diff --git a/src/rust-crypto/OutgoingRequestProcessor.ts b/src/rust-crypto/OutgoingRequestProcessor.ts index 213f8dd8400..c67bcd7c298 100644 --- a/src/rust-crypto/OutgoingRequestProcessor.ts +++ b/src/rust-crypto/OutgoingRequestProcessor.ts @@ -24,7 +24,7 @@ import { SignatureUploadRequest, ToDeviceRequest, SigningKeysUploadRequest, -} from "@matrix-org/matrix-sdk-crypto-js"; +} from "@matrix-org/matrix-sdk-crypto-wasm"; import { logger } from "../logger"; import { IHttpOpts, MatrixHttpApi, Method } from "../http-api"; diff --git a/src/rust-crypto/RoomEncryptor.ts b/src/rust-crypto/RoomEncryptor.ts index 0b51663c2bd..3863c859272 100644 --- a/src/rust-crypto/RoomEncryptor.ts +++ b/src/rust-crypto/RoomEncryptor.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { EncryptionSettings, OlmMachine, RoomId, UserId } from "@matrix-org/matrix-sdk-crypto-js"; +import { EncryptionSettings, OlmMachine, RoomId, UserId } from "@matrix-org/matrix-sdk-crypto-wasm"; import { EventType } from "../@types/event"; import { IContent, MatrixEvent } from "../models/event"; diff --git a/src/rust-crypto/device-converter.ts b/src/rust-crypto/device-converter.ts index 56945be830a..b37a63dcca0 100644 --- a/src/rust-crypto/device-converter.ts +++ b/src/rust-crypto/device-converter.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; +import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; import { Device, DeviceVerification } from "../models/device"; import { DeviceKeys } from "../client"; diff --git a/src/rust-crypto/index.ts b/src/rust-crypto/index.ts index b606cb6da55..9d8fe8d53cc 100644 --- a/src/rust-crypto/index.ts +++ b/src/rust-crypto/index.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; +import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; import { RustCrypto } from "./rust-crypto"; import { logger } from "../logger"; @@ -44,7 +44,7 @@ export async function initRustCrypto( cryptoCallbacks: ICryptoCallbacks, storePrefix: string | null, ): Promise { - // initialise the rust matrix-sdk-crypto-js, if it hasn't already been done + // initialise the rust matrix-sdk-crypto-wasm, if it hasn't already been done await RustSdkCryptoJs.initAsync(); // enable tracing in the rust-sdk diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index d7248137c7b..7fa1d62215a 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; +import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; import type { IEventDecryptionResult, IMegolmSessionData } from "../@types/crypto"; import type { IDeviceLists, IToDeviceEvent } from "../sync-accumulator"; diff --git a/src/rust-crypto/verification.ts b/src/rust-crypto/verification.ts index 85ba876d22b..252189fca91 100644 --- a/src/rust-crypto/verification.ts +++ b/src/rust-crypto/verification.ts @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; -import { Emoji, QrState } from "@matrix-org/matrix-sdk-crypto-js"; +import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; +import { Emoji, QrState } from "@matrix-org/matrix-sdk-crypto-wasm"; import { ShowQrCodeCallbacks, diff --git a/yarn.lock b/yarn.lock index 49caa8cef22..ffa40e4ae34 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1530,10 +1530,10 @@ dependencies: lodash "^4.17.21" -"@matrix-org/matrix-sdk-crypto-js@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.4.tgz#c13c7c8c3a1d8da08e6ad195d25e5e61cc402df7" - integrity sha512-OxG84iSeR89zYLFeb+DCaFtZT+DDiIu+kTkqY8OYfhE5vpGLFX2sDVBRrAdos1IUqEoboDloDBR9+yU7hNRyog== +"@matrix-org/matrix-sdk-crypto-wasm@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-1.0.1.tgz#21a0557a7bb3f60b37c6d412be8906c056fe79b8" + integrity sha512-VTwV5IowvhhLXwAsDDAv02bC5/qBQbG2YtpYAije11253sQ3MePIoSR+dS40Ih3lAlEzqQ00GU3O+i45jMzIRQ== "@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz": version "3.2.14" From d4628e78d45b5abcbba5a435a71b01fa10d30e1a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 13 Jul 2023 09:25:23 +0100 Subject: [PATCH 38/59] Fix read receipt sending behaviour around thread roots (#3600) * Fix read receipt sending behaviour around thread roots * Update src/client.ts Co-authored-by: Eric Eastwood --------- Co-authored-by: Eric Eastwood (cherry picked from commit b05f933d833ef6c9b2a8ff7a8b27723b682bcce6) --- src/client.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index 9d9e1d3aa19..40fe51daad3 100644 --- a/src/client.ts +++ b/src/client.ts @@ -4992,9 +4992,11 @@ export class MatrixClient extends TypedEventEmitter Date: Fri, 14 Jul 2023 16:10:09 +0100 Subject: [PATCH 39/59] Prepare changelog for v27.0.0-rc.2 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d55d46c52dd..e8ce80e5667 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Changes in [27.0.0-rc.2](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v27.0.0-rc.2) (2023-07-14) +============================================================================================================ + +## 🐛 Bug Fixes + * Fix read receipt sending behaviour around thread roots ([\#3600](https://github.com/matrix-org/matrix-js-sdk/pull/3600)). + Changes in [27.0.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v27.0.0-rc.1) (2023-07-11) ============================================================================================================ From d45a0b894a376a69cf6b45d92671ca8d4a58c473 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Fri, 14 Jul 2023 16:10:12 +0100 Subject: [PATCH 40/59] v27.0.0-rc.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d100887a975..8d0f453532d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "27.0.0-rc.1", + "version": "27.0.0-rc.2", "description": "Matrix Client-Server SDK for Javascript", "engines": { "node": ">=18.0.0" From eb7faa6c077162508f4a70b4ab5f73712ceeaf15 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 18:59:37 +0100 Subject: [PATCH 41/59] Lock file maintenance (#3604) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 259 ++++++++++++++++++++++++------------------------------ 1 file changed, 116 insertions(+), 143 deletions(-) diff --git a/yarn.lock b/yarn.lock index ffa40e4ae34..3f37f1acc07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -63,12 +63,7 @@ dependencies: "@babel/highlight" "^7.22.5" -"@babel/compat-data@^7.20.5": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.6.tgz#15606a20341de59ba02cd2fcc5086fcbe73bf544" - integrity sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg== - -"@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== @@ -110,17 +105,7 @@ dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.12.11", "@babel/generator@^7.7.2": - version "7.22.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.7.tgz#a6b8152d5a621893f2c9dacf9a4e286d520633d5" - integrity sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ== - dependencies: - "@babel/types" "^7.22.5" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/generator@^7.22.7", "@babel/generator@^7.22.9": +"@babel/generator@^7.12.11", "@babel/generator@^7.22.7", "@babel/generator@^7.22.9", "@babel/generator@^7.7.2": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== @@ -144,18 +129,7 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-compilation-targets@^7.20.7": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz#e30d61abe9480aa5a83232eb31c111be922d2e52" - integrity sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA== - dependencies: - "@babel/compat-data" "^7.22.6" - "@babel/helper-validator-option" "^7.22.5" - "@nicolo-ribaudo/semver-v6" "^6.3.3" - browserslist "^4.21.9" - lru-cache "^5.1.1" - -"@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.22.9": +"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892" integrity sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw== @@ -166,22 +140,7 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.6.tgz#58564873c889a6fea05a538e23f9f6d201f10950" - integrity sha512-iwdzgtSiBxF6ni6mzVnZCF3xt5qE6cEA0J7nFt8QOAWZ0zjCFceEgpn3vtb2V7WFR6QzP2jmIFOHMTRo7eNJjQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-member-expression-to-functions" "^7.22.5" - "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@nicolo-ribaudo/semver-v6" "^6.3.3" - -"@babel/helper-create-class-features-plugin@^7.22.5": +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.5", "@babel/helper-create-class-features-plugin@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz#c36ea240bb3348f942f08b0fbe28d6d979fab236" integrity sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ== @@ -933,12 +892,12 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-typescript@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.5.tgz#5c0f7adfc1b5f38c4dbc8f79b1f0f8074134bd7d" - integrity sha512-SMubA9S7Cb5sGSFFUlqxyClTA9zWJ8qGQrppNUm05LtFuN1ELRFNndkix4zUJrC9F+YivWwa1dHMSyo0e0N9dA== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.9.tgz#91e08ad1eb1028ecc62662a842e93ecfbf3c7234" + integrity sha512-BnVR1CpKiuD0iobHPaM1iLvcwPYN2uVFAqoLVSpEDKWuOikoCv5HbKLxclhKYUXlWkX86DoZGtqI4XhbOsyrMg== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.9" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-typescript" "^7.22.5" @@ -1895,9 +1854,9 @@ integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== "@types/node@*": - version "20.4.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.1.tgz#a6033a8718653c50ac4962977e14d0f984d9527d" - integrity sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg== + version "20.4.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" + integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== "@types/node@18": version "18.16.19" @@ -1987,14 +1946,6 @@ "@typescript-eslint/typescript-estree" "5.62.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.61.0": - version "5.61.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz#b670006d069c9abe6415c41f754b1b5d949ef2b2" - integrity sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw== - dependencies: - "@typescript-eslint/types" "5.61.0" - "@typescript-eslint/visitor-keys" "5.61.0" - "@typescript-eslint/scope-manager@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" @@ -2013,29 +1964,11 @@ debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.61.0": - version "5.61.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.61.0.tgz#e99ff11b5792d791554abab0f0370936d8ca50c0" - integrity sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ== - "@typescript-eslint/types@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/typescript-estree@5.61.0": - version "5.61.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz#4c7caca84ce95bb41aa585d46a764bcc050b92f3" - integrity sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw== - dependencies: - "@typescript-eslint/types" "5.61.0" - "@typescript-eslint/visitor-keys" "5.61.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - "@typescript-eslint/typescript-estree@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" @@ -2049,7 +1982,7 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.62.0": +"@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.10.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== @@ -2063,28 +1996,6 @@ eslint-scope "^5.1.1" semver "^7.3.7" -"@typescript-eslint/utils@^5.10.0": - version "5.61.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.61.0.tgz#5064838a53e91c754fffbddd306adcca3fe0af36" - integrity sha512-mV6O+6VgQmVE6+xzlA91xifndPW9ElFW8vbSF0xCT/czPXVhwDewKila1jOyRwa9AE19zKnrr7Cg5S3pJVrTWQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.61.0" - "@typescript-eslint/types" "5.61.0" - "@typescript-eslint/typescript-estree" "5.61.0" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.61.0": - version "5.61.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz#c79414fa42158fd23bd2bb70952dc5cdbb298140" - integrity sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg== - dependencies: - "@typescript-eslint/types" "5.61.0" - eslint-visitor-keys "^3.3.0" - "@typescript-eslint/visitor-keys@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" @@ -2107,9 +2018,9 @@ abab@^2.0.6: integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== ace-builds@^1.4.13: - version "1.23.2" - resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.23.2.tgz#3a08ef9877d66831726c1dbd40b48914849ce163" - integrity sha512-+LegSgEOcQo7xcvlS4JJidoPOs/QmFGoccWJSEKW/XUH4JzFPrxhPuAezg1bIbS3zxrlM1dVHSEWGiJMxPL9RQ== + version "1.23.4" + resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.23.4.tgz#4f2c813bbdc886a67224be255ab32a280f779a9a" + integrity sha512-a4hKAT2T7KNUQC4LQPW2peuoEsZmLYTn4Dwjkh26A3Z+fQ8/fA2JZNs3V6CqvivhbyMQXQJD1u/0qTCoSS6deA== acorn-globals@^3.0.0: version "3.1.0" @@ -2345,6 +2256,18 @@ array.prototype.flatmap@^1.3.1: es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" +arraybuffer.prototype.slice@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb" + integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -2867,9 +2790,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001503: - version "1.0.30001515" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001515.tgz#418aefeed9d024cd3129bfae0ccc782d4cb8f12b" - integrity sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA== + version "1.0.30001516" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001516.tgz#621b1be7d85a8843ee7d210fd9d87b52e3daab3a" + integrity sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g== center-align@^0.1.1: version "0.1.3" @@ -3485,9 +3408,9 @@ eastasianwidth@^0.2.0: integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== electron-to-chromium@^1.4.431: - version "1.4.457" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.457.tgz#3fdc7b4f97d628ac6b51e8b4b385befb362fe343" - integrity sha512-/g3UyNDmDd6ebeWapmAoiyy+Sy2HyJ+/X8KyvNeHfKRFfHaA2W8oF5fxD5F3tjBDcjpwo0iek6YNgxNXDBoEtA== + version "1.4.461" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.461.tgz#6b14af66042732bf883ab63a4d82cac8f35eb252" + integrity sha512-1JkvV2sgEGTDXjdsaQCeSwYYuhLRphRpc+g6EHTFELJXEiznLt3/0pZ9JuAOQ5p2rI3YxKTbivtvajirIfhrEQ== elliptic@^6.5.3: version "6.5.4" @@ -3538,17 +3461,18 @@ error-ex@^1.2.0, error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.21.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" - integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== + version "1.22.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" + integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== dependencies: array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.1" available-typed-arrays "^1.0.5" call-bind "^1.0.2" es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" function.prototype.name "^1.1.5" - get-intrinsic "^1.2.0" + get-intrinsic "^1.2.1" get-symbol-description "^1.0.0" globalthis "^1.0.3" gopd "^1.0.1" @@ -3568,14 +3492,18 @@ es-abstract@^1.19.0, es-abstract@^1.20.4: object-inspect "^1.12.3" object-keys "^1.1.1" object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" + regexp.prototype.flags "^1.5.0" + safe-array-concat "^1.0.0" safe-regex-test "^1.0.0" string.prototype.trim "^1.2.7" string.prototype.trimend "^1.0.6" string.prototype.trimstart "^1.0.6" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" typed-array-length "^1.0.4" unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" + which-typed-array "^1.1.10" es-set-tostringtag@^2.0.1: version "2.0.1" @@ -3731,16 +3659,16 @@ eslint-plugin-import@^2.26.0: tsconfig-paths "^3.14.1" eslint-plugin-jest@^27.1.6: - version "27.2.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.2.2.tgz#be4ded5f91905d9ec89aa8968d39c71f3b072c0c" - integrity sha512-euzbp06F934Z7UDl5ZUaRPLAc9MKjh0rMPERrHT7UhlCEwgb25kBj37TvMgWeHZVkR5I9CayswrpoaqZU1RImw== + version "27.2.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.2.3.tgz#6f8a4bb2ca82c0c5d481d1b3be256ab001f5a3ec" + integrity sha512-sRLlSCpICzWuje66Gl9zvdF6mwD5X86I4u55hJyFBsxYOsBCmT5+kSUjf+fkFWVMMgpzNEupjW8WzUqi83hJAQ== dependencies: "@typescript-eslint/utils" "^5.10.0" eslint-plugin-jsdoc@^46.0.0: - version "46.4.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.4.3.tgz#4a2ad3a01d7ba723acaed3940f746a0a31d1e58e" - integrity sha512-Prc7ol+vCIghPeECpwZq5+P+VZfoi87suywvbYCiCnkI1kTmVSdcOC2M8mioglWxBbd28wbb1OVjg/8OzGzatA== + version "46.4.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.4.4.tgz#cdcf9f59238381e3ee57110ceccefdfef388455d" + integrity sha512-D8TGPOkq3bnzmYmA7Q6jdsW+Slx7CunhJk1tlouVq6wJjlP1p6eigZPvxFn7aufud/D66xBsNVMhkDQEuqumMg== dependencies: "@es-joy/jsdoccomment" "~0.39.4" are-docs-informative "^0.0.2" @@ -3801,9 +3729,9 @@ eslint-scope@5.1.1, eslint-scope@^5.1.1: estraverse "^4.1.1" eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== + version "7.2.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.1.tgz#936821d3462675f25a18ac5fd88a67cc15b393bd" + integrity sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" @@ -3864,9 +3792,9 @@ eslint@8.44.0: text-table "^0.2.0" espree@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.0.tgz#80869754b1c6560f32e3b6929194a3fe07c5b82f" - integrity sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A== + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: acorn "^8.9.0" acorn-jsx "^5.3.2" @@ -4012,9 +3940,9 @@ ext@^1.1.2: type "^2.7.2" fake-indexeddb@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-4.0.1.tgz#09bb2468e21d0832b2177e894765fb109edac8fb" - integrity sha512-hFRyPmvEZILYgdcLBxVdHLik4Tj3gDTu/g7s9ZDOiU3sTNiGx+vEu1ri/AMsFJUZ/1sdRbAVrEcKndh3sViBcA== + version "4.0.2" + resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-4.0.2.tgz#e7a884158fa576e00f03e973b9874619947013e4" + integrity sha512-SdTwEhnakbgazc7W3WUXOJfGmhH0YfG4d+dRPOFoYDRTL6U5t8tvrmkf2W/C3W1jk2ylV7Wrnj44RASqpX/lEw== dependencies: realistic-structured-clone "^3.0.0" @@ -4241,7 +4169,7 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== @@ -4866,6 +4794,11 @@ isarray@0.0.1: resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -5840,9 +5773,9 @@ minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== "minipass@^5.0.0 || ^6.0.2 || ^7.0.0": - version "7.0.1" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.1.tgz#dff63464407cd8b83d7f008c0f116fa8c9b77ebf" - integrity sha512-NQ8MCKimInjVlaIqx51RKJJB7mINVkLTJbsZKmto4UAAOC/CWXES8PGaOgoBZyqoUsUA/U3DToGK7GJkkHbjJw== + version "7.0.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.2.tgz#58a82b7d81c7010da5bd4b2c0c85ac4b4ec5131e" + integrity sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA== mkdirp-classic@^0.5.2: version "0.5.3" @@ -6688,7 +6621,7 @@ regexp-tree@^0.1.24, regexp-tree@~0.1.1: resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.27.tgz#2198f0ef54518ffa743fe74d983b56ffd631b6cd" integrity sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA== -regexp.prototype.flags@^1.4.3: +regexp.prototype.flags@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== @@ -6845,6 +6778,16 @@ runnel@~0.5.1: resolved "https://registry.yarnpkg.com/runnel/-/runnel-0.5.3.tgz#f9362b165a05fc6f5e46e458f77a1f7ecdc0daec" integrity sha512-XAVCMr+hCRGKA4AJdNit1aQC0EKCuCZnlxqfeh9u2CbSPSPyLSI/BfavMfoC/WUd6HyaRBWW1usNsVAqWN9hgw== +safe-array-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.0.tgz#2064223cba3c08d2ee05148eedbc563cd6d84060" + integrity sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + has-symbols "^1.0.3" + isarray "^2.0.5" + safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -7290,9 +7233,9 @@ tapable@^2.2.0: integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== terser@^5.5.1: - version "5.18.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.18.2.tgz#ff3072a0faf21ffd38f99acc9a0ddf7b5f07b948" - integrity sha512-Ah19JS86ypbJzTzvUCX7KOsEIhDaRONungA4aYBjEP3JZRf4ocuDzTg4QWZnPn9DEMiMYGJPiSOy7aykoCc70w== + version "5.19.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.0.tgz#7b3137b01226bdd179978207b9c8148754a6da9c" + integrity sha512-JpcpGOQLOXm2jsomozdMDpd5f8ZHh1rR48OFgWUH3QsyZcfPgv2qDCYbcDEAYNd4OZRj2bWYKpwdll/udZCk/Q== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -7547,6 +7490,36 @@ type@^2.7.2: resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + typed-array-length@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" @@ -7966,10 +7939,10 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which-typed-array@^1.1.2, which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== +which-typed-array@^1.1.10, which-typed-array@^1.1.2: + version "1.1.10" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.10.tgz#74baa2789991905c2076abb317103b866c64e69e" + integrity sha512-uxoA5vLUfRPdjCuJ1h5LlYdmTLbYfums398v3WLkM+i/Wltl2/XyZpQWKbN++ck5L64SR/grOHqtXCUKmlZPNA== dependencies: available-typed-arrays "^1.0.5" call-bind "^1.0.2" From 706c084fa7993174f21b3a3659752eebe6752c88 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 18 Jul 2023 11:37:17 +0100 Subject: [PATCH 42/59] Add tests for room-hierarchy (#3606) * Add tests for room-hierarchy * overwriteroutes --- spec/unit/room-hierarchy.spec.ts | 76 ++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 spec/unit/room-hierarchy.spec.ts diff --git a/spec/unit/room-hierarchy.spec.ts b/spec/unit/room-hierarchy.spec.ts new file mode 100644 index 00000000000..80570969914 --- /dev/null +++ b/spec/unit/room-hierarchy.spec.ts @@ -0,0 +1,76 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import fetchMock from "fetch-mock-jest"; + +import { EventType, MatrixClient, Room } from "../../src"; +import { RoomHierarchy } from "../../src/room-hierarchy"; + +describe("RoomHierarchy", () => { + const roomId = "!room:server"; + const client = new MatrixClient({ baseUrl: "https://server", userId: "@user:server" }); + + it("should load data from /hierarchy API", async () => { + const spy = fetchMock.getOnce( + `https://server/_matrix/client/v1/rooms/${encodeURIComponent(roomId)}/hierarchy?suggested_only=false`, + { + rooms: [], + }, + { overwriteRoutes: true }, + ); + + const room = new Room(roomId, client, client.getSafeUserId()); + const hierarchy = new RoomHierarchy(room); + const res = await hierarchy.load(); + + expect(spy).toHaveBeenCalled(); + expect(res).toHaveLength(0); + }); + + describe("itSuggested", () => { + it("should return true if a room is suggested", async () => { + const spy = fetchMock.getOnce( + `https://server/_matrix/client/v1/rooms/${encodeURIComponent(roomId)}/hierarchy?suggested_only=false`, + { + rooms: [ + { + children_state: [ + { + origin_server_ts: 111, + content: { + suggested: true, + via: ["matrix.org"], + }, + type: EventType.SpaceChild, + state_key: "!child_room:server", + }, + ], + room_id: roomId, + }, + ], + }, + { overwriteRoutes: true }, + ); + + const room = new Room(roomId, client, client.getSafeUserId()); + const hierarchy = new RoomHierarchy(room); + await hierarchy.load(); + + expect(spy).toHaveBeenCalled(); + expect(hierarchy.isSuggested(hierarchy.root.roomId, "!child_room:server")).toBeTruthy(); + }); + }); +}); From 3e2460707c1892e61569b6d79dc69a9ad485f2d4 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 18 Jul 2023 12:51:57 +0100 Subject: [PATCH 43/59] Prepare changelog for v27.0.0 --- CHANGELOG.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8ce80e5667..c954c8892f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,20 +1,14 @@ -Changes in [27.0.0-rc.2](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v27.0.0-rc.2) (2023-07-14) -============================================================================================================ - -## 🐛 Bug Fixes - * Fix read receipt sending behaviour around thread roots ([\#3600](https://github.com/matrix-org/matrix-js-sdk/pull/3600)). - -Changes in [27.0.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v27.0.0-rc.1) (2023-07-11) -============================================================================================================ +Changes in [27.0.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v27.0.0) (2023-07-18) +================================================================================================== ## 🚨 BREAKING CHANGES + * Drop support for Node 16 ([\#3533](https://github.com/matrix-org/matrix-js-sdk/pull/3533)). * Improve types around login, registration, UIA and identity servers ([\#3537](https://github.com/matrix-org/matrix-js-sdk/pull/3537)). ## 🦖 Deprecations * **The Browserify artifact is being deprecated, scheduled for removal in the October 10th release cycle. (#3189)** * Simplify `MatrixClient::setPowerLevel` API ([\#3570](https://github.com/matrix-org/matrix-js-sdk/pull/3570)). Fixes vector-im/element-web#13900 and #1844. * Deprecate `VerificationRequest.getQRCodeBytes` and replace it with the asynchronous `generateQRCode`. ([\#3562](https://github.com/matrix-org/matrix-js-sdk/pull/3562)). - * Drop support for Node 16 ([\#3533](https://github.com/matrix-org/matrix-js-sdk/pull/3533)). * Deprecate `VerificationRequest.beginKeyVerification()` in favour of `VerificationRequest.startVerification()`. ([\#3528](https://github.com/matrix-org/matrix-js-sdk/pull/3528)). * Deprecate `Crypto.VerificationRequest` application event, replacing it with `Crypto.VerificationRequestReceived`. ([\#3514](https://github.com/matrix-org/matrix-js-sdk/pull/3514)). @@ -29,6 +23,7 @@ Changes in [27.0.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/ta * OIDC: validate id token ([\#3531](https://github.com/matrix-org/matrix-js-sdk/pull/3531)). Contributed by @kerryarchibald. ## 🐛 Bug Fixes + * Fix read receipt sending behaviour around thread roots ([\#3600](https://github.com/matrix-org/matrix-js-sdk/pull/3600)). * Fix `TypedEventEmitter::removeAllListeners(void)` not working ([\#3561](https://github.com/matrix-org/matrix-js-sdk/pull/3561)). * Don't allow Olm unwedging rate-limiting to race ([\#3549](https://github.com/matrix-org/matrix-js-sdk/pull/3549)). Fixes vector-im/element-web#25716. * Fix an instance of failed to decrypt error when an in flight `/keys/query` fails. ([\#3486](https://github.com/matrix-org/matrix-js-sdk/pull/3486)). From dfa242909417c62fb2ae722c1ccaa22d917dfcb6 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 18 Jul 2023 12:52:00 +0100 Subject: [PATCH 44/59] v27.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8d0f453532d..4627b31c10a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "27.0.0-rc.2", + "version": "27.0.0", "description": "Matrix Client-Server SDK for Javascript", "engines": { "node": ">=18.0.0" From f77662406c681e685ba600b4a8b9ede14e1f674f Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 18 Jul 2023 12:53:43 +0100 Subject: [PATCH 45/59] Resetting package fields for development --- package.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 1955971b7be..12b5f2d63c8 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "keywords": [ "matrix-org" ], - "main": "./lib/index.js", - "browser": "./lib/browser-index.js", + "main": "./src/index.ts", + "browser": "./src/browser-index.ts", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.ts", "matrix_lib_main": "./lib/index.js", @@ -158,6 +158,5 @@ "no-rust-crypto": { "src/rust-crypto/index.ts$": "./src/rust-crypto/browserify-index.ts" } - }, - "typings": "./lib/index.d.ts" + } } From fed9910fa10825fc89c1f568ef53508b2233ef73 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 19 Jul 2023 08:44:11 +0100 Subject: [PATCH 46/59] Remove unused better-docs & docdash (#3605) --- package.json | 2 - yarn.lock | 685 ++------------------------------------------------- 2 files changed, 23 insertions(+), 664 deletions(-) diff --git a/package.json b/package.json index 12b5f2d63c8..b28eacf23d8 100644 --- a/package.json +++ b/package.json @@ -97,11 +97,9 @@ "allchange": "^1.0.6", "babel-jest": "^29.0.0", "babelify": "^10.0.0", - "better-docs": "^2.4.0-beta.9", "browserify": "^17.0.0", "browserify-swap": "^0.2.2", "debug": "^4.3.4", - "docdash": "^2.0.0", "domexception": "^4.0.0", "eslint": "8.44.0", "eslint-config-google": "^0.14.0", diff --git a/yarn.lock b/yarn.lock index 3f37f1acc07..53069ea2c44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -68,7 +68,7 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== -"@babel/core@^7.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.7.5": +"@babel/core@^7.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.9.tgz#bd96492c68822198f33e8a256061da3cf391f58f" integrity sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w== @@ -105,7 +105,7 @@ dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.12.11", "@babel/generator@^7.22.7", "@babel/generator@^7.22.9", "@babel/generator@^7.7.2": +"@babel/generator@^7.22.7", "@babel/generator@^7.22.9", "@babel/generator@^7.7.2": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== @@ -313,7 +313,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.2.3", "@babel/parser@^7.20.7", "@babel/parser@^7.22.5", "@babel/parser@^7.22.7": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.5", "@babel/parser@^7.22.7": version "7.22.7" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== @@ -1056,7 +1056,7 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.8.4": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== @@ -1072,7 +1072,7 @@ "@babel/parser" "^7.22.5" "@babel/types" "^7.22.5" -"@babel/traverse@^7.1.6", "@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": +"@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": version "7.22.8" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== @@ -1088,7 +1088,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== @@ -1201,7 +1201,7 @@ js-yaml "^3.13.1" resolve-from "^5.0.0" -"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": +"@istanbuljs/schema@^0.1.2": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== @@ -1482,13 +1482,6 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" -"@jsdoc/salty@^0.2.1": - version "0.2.5" - resolved "https://registry.yarnpkg.com/@jsdoc/salty/-/salty-0.2.5.tgz#1b2fa5bb8c66485b536d86eee877c263d322f692" - integrity sha512-TfRP53RqunNe2HBobVBJ0VLhK1HbfvBYeTC1ahnN64PWvyYyGebmMiPkuwvD9fpw2ZbkoPb8Q7mwy0aR8Z9rvw== - dependencies: - lodash "^4.17.21" - "@matrix-org/matrix-sdk-crypto-wasm@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-1.0.1.tgz#21a0557a7bb3f60b37c6d412be8906c056fe79b8" @@ -1496,7 +1489,6 @@ "@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz": version "3.2.14" - uid acd96c00a881d0f462e1f97a56c73742c8dbc984 resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz#acd96c00a881d0f462e1f97a56c73742c8dbc984" "@microsoft/tsdoc-config@0.16.2": @@ -1719,11 +1711,6 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== -"@types/babel-types@*", "@types/babel-types@^7.0.0": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.11.tgz#263b113fa396fac4373188d73225297fb86f19a9" - integrity sha512-pkPtJUUY+Vwv6B1inAz55rQvivClHJxc9aVEPPmaq2cbyeMLCiDpbKpcKyX4LAwpNGi+SHBv0tHv6+0gXv0P2A== - "@types/babel__core@^7.1.14": version "7.20.1" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b" @@ -1757,13 +1744,6 @@ dependencies: "@babel/types" "^7.20.7" -"@types/babylon@^6.16.2": - version "6.16.6" - resolved "https://registry.yarnpkg.com/@types/babylon/-/babylon-6.16.6.tgz#a1e7e01567b26a5ebad321a74d10299189d8d932" - integrity sha512-G4yqdVlhr6YhzLXFKy5F7HtRBU8Y23+iWy7UKthMq/OSQnL1hbsoeXESQ2LY8zEDlknipDG3nRGhUC9tkwvy/w== - dependencies: - "@types/babel-types" "*" - "@types/bs58@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-4.0.1.tgz#3d51222aab067786d3bc3740a84a7f5a0effaa37" @@ -2017,18 +1997,6 @@ abab@^2.0.6: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -ace-builds@^1.4.13: - version "1.23.4" - resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.23.4.tgz#4f2c813bbdc886a67224be255ab32a280f779a9a" - integrity sha512-a4hKAT2T7KNUQC4LQPW2peuoEsZmLYTn4Dwjkh26A3Z+fQ8/fA2JZNs3V6CqvivhbyMQXQJD1u/0qTCoSS6deA== - -acorn-globals@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf" - integrity sha512-uWttZCk96+7itPxK8xCzY86PnxKTMrReKDqrHzv42VQY0K30PUO8WY13WMOuI+cOdX4EIdzdvQ8k6jkuGRFMYw== - dependencies: - acorn "^4.0.4" - acorn-globals@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" @@ -2061,16 +2029,6 @@ acorn-walk@^8.0.2, acorn-walk@^8.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - integrity sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw== - -acorn@^4.0.4, acorn@~4.0.2: - version "4.0.13" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" - integrity sha512-fu2ygVGuMmlzG8ZeRJ0bvR41nsAkxxhbyk8bZ1SS521Z7vmgJFTQQlfz/Mp/nJexGBz+v8sC9bM6+lNgskt4Ug== - acorn@^7.0.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" @@ -2098,15 +2056,6 @@ ajv@^6.10.0, ajv@^6.12.4, ajv@~6.12.6: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - integrity sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg== - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - allchange@^1.0.6: version "1.1.0" resolved "https://registry.yarnpkg.com/allchange/-/allchange-1.1.0.tgz#f8fa129e4b40c0b0a2c072c530f2324c6590e208" @@ -2268,11 +2217,6 @@ arraybuffer.prototype.slice@^1.0.1: is-array-buffer "^3.0.2" is-shared-array-buffer "^1.0.2" -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== - asn1.js@^5.2.0: version "5.4.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" @@ -2291,18 +2235,6 @@ assert@^1.4.0: object-assign "^4.1.1" util "0.10.3" -ast-types@0.12.4, ast-types@^0.12.2: - version "0.12.4" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.12.4.tgz#71ce6383800f24efc9a1a3308f3a6e420a0974d1" - integrity sha512-ky/YVYCbtVAS8TdMIaTiPFHwEpRB5z1hctepJplTr3UW5q8TDrpIMCILyk8pmLxGtn2KCtC/lSn7zOsaI7nzDw== - -ast-types@^0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" - integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== - dependencies: - tslib "^2.0.1" - async@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" @@ -2402,34 +2334,11 @@ babel-preset-jest@^29.5.0: babel-plugin-jest-hoist "^29.5.0" babel-preset-current-node-syntax "^1.0.0" -babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g== - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - integrity sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g== - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - babelify@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/babelify/-/babelify-10.0.0.tgz#fe73b1a22583f06680d8d072e25a1e0d1d1d7fb5" integrity sha512-X40FaxyH7t3X+JFAKvb1H9wooWKLRCi8pg3m8poqtdZaIng+bjzp9RvKQCvRjF9isHiPkXspbbXT/zwXLtwgwg== -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -2462,20 +2371,6 @@ before-after-hook@^2.2.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== -better-docs@^2.4.0-beta.9: - version "2.7.2" - resolved "https://registry.yarnpkg.com/better-docs/-/better-docs-2.7.2.tgz#fe0b54fca8a904fe050586aa819263195e5eb948" - integrity sha512-aIOsGhhcTIDAJfBTABIPDs3q98dfNF85yUwmKShXb3ZG6e7s+ojBePiDqvFwy/MpnjYwuSbuzkbEv4iPWcSuTQ== - dependencies: - brace "^0.11.1" - react-ace "^9.5.0" - react-docgen "^5.4.0" - react-frame-component "^5.2.1" - typescript "^4.5.4" - underscore "^1.13.2" - vue-docgen-api "^3.26.0" - vue2-ace-editor "^0.0.15" - big-integer@^1.6.44: version "1.6.51" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" @@ -2518,11 +2413,6 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -brace@^0.11.0, brace@^0.11.1: - version "0.11.1" - resolved "https://registry.yarnpkg.com/brace/-/brace-0.11.1.tgz#4896fcc9d544eef45f4bb7660db320d3b379fe58" - integrity sha512-Fc8Ne62jJlKHiG/ajlonC4Sd66Pq68fFwK4ihJGNZpGqboc324SQk+lRvMzpPRuJOmfrJefdG8/7JdWX4bzJ2Q== - braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -2738,24 +2628,6 @@ bundle-name@^3.0.0: dependencies: run-applescript "^5.0.0" -c8@^7.6.0: - version "7.14.0" - resolved "https://registry.yarnpkg.com/c8/-/c8-7.14.0.tgz#f368184c73b125a80565e9ab2396ff0be4d732f3" - integrity sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@istanbuljs/schema" "^0.1.3" - find-up "^5.0.0" - foreground-child "^2.0.0" - istanbul-lib-coverage "^3.2.0" - istanbul-lib-report "^3.0.0" - istanbul-reports "^3.1.4" - rimraf "^3.0.2" - test-exclude "^6.0.0" - v8-to-istanbul "^9.0.0" - yargs "^16.2.0" - yargs-parser "^20.2.9" - cached-path-relative@^1.0.0, cached-path-relative@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.1.0.tgz#865576dfef39c0d6a7defde794d078f5308e3ef3" @@ -2774,11 +2646,6 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - integrity sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g== - camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -2794,14 +2661,6 @@ caniuse-lite@^1.0.30001503: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001516.tgz#621b1be7d85a8843ee7d210fd9d87b52e3daab3a" integrity sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g== -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - integrity sha512-Baz3aNe2gd2LP2qk5U+sDk/m4oSuwSDcBfayTCTBoWpfIGO5XFxPmjILQII4NGiZjD6DoDI6kf7gKaxkf7s3VQ== - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - chalk@^2.0.0, chalk@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -2824,13 +2683,6 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -character-parser@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" - integrity sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw== - dependencies: - is-regex "^1.0.3" - chokidar@^3.4.0: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -2864,13 +2716,6 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== -clean-css@^4.1.11: - version "4.2.4" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" - integrity sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A== - dependencies: - source-map "~0.6.0" - clean-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7" @@ -2897,24 +2742,6 @@ cli-diff@^1.0.0: chalk "^2.4.1" diff "^3.5.0" -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - integrity sha512-GIOYRizG+TGoc7Wgc1LiOTLare95R3mzKgoln+Q/lE4ceiYH19gUpl0l0Ffq4lJDEf3FxujMe6IBfOCs7pfqNA== - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - cliui@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" @@ -2984,7 +2811,7 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@^2.19.0, commander@^2.20.0: +commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -3024,16 +2851,6 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== -constantinople@^3.0.1, constantinople@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-3.1.2.tgz#d45ed724f57d3d10500017a7d3a889c1381ae647" - integrity sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw== - dependencies: - "@types/babel-types" "^7.0.0" - "@types/babylon" "^6.16.2" - babel-types "^6.26.0" - babylon "^6.18.0" - constants-browserify@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -3066,11 +2883,6 @@ core-js-compat@^3.31.0: dependencies: browserslist "^4.21.9" -core-js@^2.4.0: - version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - core-js@^3.0.0: version "3.31.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.31.1.tgz#f2b0eea9be9da0def2c5fece71064a7e5d687653" @@ -3187,11 +2999,6 @@ data-urls@^3.0.2: whatwg-mimetype "^3.0.0" whatwg-url "^11.0.0" -de-indent@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" - integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg== - debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -3206,11 +3013,6 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -decamelize@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== - decimal.js@^10.4.2: version "10.4.3" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" @@ -3309,11 +3111,6 @@ detective@^5.2.0: defined "^1.0.0" minimist "^1.2.6" -diff-match-patch@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37" - integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw== - diff-sequences@^28.1.1: version "28.1.1" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" @@ -3350,13 +3147,6 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -docdash@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/docdash/-/docdash-2.0.1.tgz#ac36dd1b64a2ae298e642c9a8d8d3c0f7f0a2c55" - integrity sha512-mkBhkeMyMwGV4YIdA7S4dIC25ENrfU/ZBfyTs/MXj/HUewW/dtx44xoho4PttCOMsqxlcghzfj8HRlam5QiSoQ== - dependencies: - "@jsdoc/salty" "^0.2.1" - doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -3371,11 +3161,6 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -doctypes@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" - integrity sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ== - domain-browser@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -3800,7 +3585,7 @@ espree@^9.6.0: acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.1" -esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: +esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -3829,15 +3614,6 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -estree-to-babel@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/estree-to-babel/-/estree-to-babel-3.2.1.tgz#82e78315275c3ca74475fdc8ac1a5103c8a75bf5" - integrity sha512-YNF+mZ/Wu2FU/gvmzuWtYc8rloubL7wfXCTgouFrnjGVXPA/EeYYA7pupXWrb3Iv1cTBeSSxxJIbK23l4MRNqg== - dependencies: - "@babel/traverse" "^7.1.6" - "@babel/types" "^7.2.0" - c8 "^7.6.0" - esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -4085,14 +3861,6 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -foreground-child@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" - integrity sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^3.0.2" - foreground-child@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" @@ -4368,11 +4136,6 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" -hash-sum@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" - integrity sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA== - hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" @@ -4381,11 +4144,6 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -4586,7 +4344,7 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-buffer@^1.1.0, is-buffer@^1.1.5: +is-buffer@^1.1.0: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== @@ -4627,14 +4385,6 @@ is-docker@^3.0.0: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== -is-expression@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-3.0.0.tgz#39acaa6be7fd1f3471dc42c7416e61c24317ac9f" - integrity sha512-vyMeQMq+AiH5uUnoBfMTwf18tO3bM6k1QXBE9D6ueAAquEfCZe3AJPtud9g6qS0+4X8xA7ndpZiDyeb2l2qOBw== - dependencies: - acorn "~4.0.2" - object-assign "^4.0.1" - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -4710,12 +4460,12 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== -is-promise@^2.0.0, is-promise@^2.2.2: +is-promise@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== -is-regex@^1.0.3, is-regex@^1.1.4: +is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -4848,7 +4598,7 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.1.3, istanbul-reports@^3.1.4: +istanbul-reports@^3.1.3: version "3.1.5" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== @@ -5300,12 +5050,7 @@ jju@~1.4.0: resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA== -js-stringify@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" - integrity sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: +js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== @@ -5423,26 +5168,11 @@ jsonparse@^1.2.0: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -jstransformer@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" - integrity sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A== - dependencies: - is-promise "^2.0.0" - promise "^7.0.1" - jwt-decode@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59" integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A== -kind-of@^3.0.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" @@ -5461,11 +5191,6 @@ labeled-stream-splicer@^2.0.0: inherits "^2.0.1" stream-splicer "^2.0.0" -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - integrity sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ== - leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -5511,11 +5236,6 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== - lodash.isequal@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" @@ -5536,7 +5256,7 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== -lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: +lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -5546,31 +5266,11 @@ loglevel@^1.7.1: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4" integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg== -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - integrity sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg== - -loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - lru-cache@2: version "2.7.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" integrity sha512-WpibWJ60c3AgAz8a2iYErDrcT2C7OmKnsWhIcHOjkUHFjkXncJhtLxNSqUmxRxRunpb5I8Vprd7aNSd2NtksJQ== -lru-cache@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5748,7 +5448,7 @@ minimatch@0.3: lru-cache "2" sigmund "~1.0.0" -minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -5836,23 +5536,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -neo-async@^2.6.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - next-tick@1, next-tick@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== -node-dir@^0.1.10: - version "0.1.17" - resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" - integrity sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg== - dependencies: - minimatch "^3.0.2" - node-fetch@^2.6.7: version "2.6.12" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" @@ -5904,7 +5592,7 @@ nwsapi@^2.2.2: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -6238,11 +5926,6 @@ pretty-format@^29.0.0, pretty-format@^29.6.1: ansi-styles "^5.0.0" react-is "^18.0.0" -private@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== - process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -6253,13 +5936,6 @@ process@~0.11.0: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== -promise@^7.0.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - prompts@^2.0.1, prompts@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -6268,20 +5944,6 @@ prompts@^2.0.1, prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.7.2: - version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== - psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" @@ -6299,111 +5961,6 @@ public-encrypt@^4.0.0: randombytes "^2.0.1" safe-buffer "^5.1.2" -pug-attrs@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-2.0.4.tgz#b2f44c439e4eb4ad5d4ef25cac20d18ad28cc336" - integrity sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ== - dependencies: - constantinople "^3.0.1" - js-stringify "^1.0.1" - pug-runtime "^2.0.5" - -pug-code-gen@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-2.0.3.tgz#122eb9ada9b5bf601705fe15aaa0a7d26bc134ab" - integrity sha512-r9sezXdDuZJfW9J91TN/2LFbiqDhmltTFmGpHTsGdrNGp3p4SxAjjXEfnuK2e4ywYsRIVP0NeLbSAMHUcaX1EA== - dependencies: - constantinople "^3.1.2" - doctypes "^1.1.0" - js-stringify "^1.0.1" - pug-attrs "^2.0.4" - pug-error "^1.3.3" - pug-runtime "^2.0.5" - void-elements "^2.0.1" - with "^5.0.0" - -pug-error@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-1.3.3.tgz#f342fb008752d58034c185de03602dd9ffe15fa6" - integrity sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ== - -pug-filters@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-3.1.1.tgz#ab2cc82db9eeccf578bda89130e252a0db026aa7" - integrity sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg== - dependencies: - clean-css "^4.1.11" - constantinople "^3.0.1" - jstransformer "1.0.0" - pug-error "^1.3.3" - pug-walk "^1.1.8" - resolve "^1.1.6" - uglify-js "^2.6.1" - -pug-lexer@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-4.1.0.tgz#531cde48c7c0b1fcbbc2b85485c8665e31489cfd" - integrity sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA== - dependencies: - character-parser "^2.1.1" - is-expression "^3.0.0" - pug-error "^1.3.3" - -pug-linker@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-3.0.6.tgz#f5bf218b0efd65ce6670f7afc51658d0f82989fb" - integrity sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg== - dependencies: - pug-error "^1.3.3" - pug-walk "^1.1.8" - -pug-load@^2.0.12: - version "2.0.12" - resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-2.0.12.tgz#d38c85eb85f6e2f704dea14dcca94144d35d3e7b" - integrity sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg== - dependencies: - object-assign "^4.1.0" - pug-walk "^1.1.8" - -pug-parser@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-5.0.1.tgz#03e7ada48b6840bd3822f867d7d90f842d0ffdc9" - integrity sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA== - dependencies: - pug-error "^1.3.3" - token-stream "0.0.1" - -pug-runtime@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-2.0.5.tgz#6da7976c36bf22f68e733c359240d8ae7a32953a" - integrity sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw== - -pug-strip-comments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz#cc1b6de1f6e8f5931cf02ec66cdffd3f50eaf8a8" - integrity sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw== - dependencies: - pug-error "^1.3.3" - -pug-walk@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.8.tgz#b408f67f27912f8c21da2f45b7230c4bd2a5ea7a" - integrity sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA== - -pug@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.4.tgz#ee7682ec0a60494b38d48a88f05f3b0ac931377d" - integrity sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw== - dependencies: - pug-code-gen "^2.0.2" - pug-filters "^3.1.1" - pug-lexer "^4.1.0" - pug-linker "^3.0.6" - pug-load "^2.0.12" - pug-parser "^5.0.1" - pug-runtime "^2.0.5" - pug-strip-comments "^1.0.4" - punycode@^1.3.2, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" @@ -6461,43 +6018,6 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" -react-ace@^9.5.0: - version "9.5.0" - resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-9.5.0.tgz#b6c32b70d404dd821a7e01accc2d76da667ff1f7" - integrity sha512-4l5FgwGh6K7A0yWVMQlPIXDItM4Q9zzXRqOae8KkCl6MkOob7sC1CzHxZdOGvV+QioKWbX2p5HcdOVUv6cAdSg== - dependencies: - ace-builds "^1.4.13" - diff-match-patch "^1.0.5" - lodash.get "^4.4.2" - lodash.isequal "^4.5.0" - prop-types "^15.7.2" - -react-docgen@^5.4.0: - version "5.4.3" - resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-5.4.3.tgz#7d297f73b977d0c7611402e5fc2a168acf332b26" - integrity sha512-xlLJyOlnfr8lLEEeaDZ+X2J/KJoe6Nr9AzxnkdQWush5hz2ZSu66w6iLMOScMmxoSHWpWMn+k3v5ZiyCfcWsOA== - dependencies: - "@babel/core" "^7.7.5" - "@babel/generator" "^7.12.11" - "@babel/runtime" "^7.7.6" - ast-types "^0.14.2" - commander "^2.19.0" - doctrine "^3.0.0" - estree-to-babel "^3.1.0" - neo-async "^2.6.1" - node-dir "^0.1.10" - strip-indent "^3.0.0" - -react-frame-component@^5.2.1: - version "5.2.6" - resolved "https://registry.yarnpkg.com/react-frame-component/-/react-frame-component-5.2.6.tgz#0d9991d251ff1f7177479d8f370deea06b824b79" - integrity sha512-CwkEM5VSt6nFwZ1Op8hi3JB5rPseZlmnp5CGiismVTauE6S4Jsc4TNMlT0O7Cts4WgIC3ZBAQ2p1Mm9XgLbj+w== - -react-is@^16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - react-is@^18.0.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" @@ -6577,16 +6097,6 @@ realistic-structured-clone@^3.0.0: typeson "^6.1.0" typeson-registry "^1.0.0-alpha.20" -recast@^0.17.3: - version "0.17.6" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.17.6.tgz#64ae98d0d2dfb10ff92ff5fb9ffb7371823b69fa" - integrity sha512-yoQRMRrK1lszNtbkGyM4kN45AwylV5hMiuEveUBlxytUViWevjvX6w+tzJt1LH4cfUhWt4NZvy3ThIhu6+m5wQ== - dependencies: - ast-types "0.12.4" - esprima "~4.0.0" - private "^0.1.8" - source-map "~0.6.1" - regenerate-unicode-properties@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" @@ -6599,11 +6109,6 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== - regenerator-runtime@^0.13.11: version "0.13.11" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" @@ -6656,11 +6161,6 @@ regjsparser@^0.9.1: dependencies: jsesc "~0.5.0" -repeat-string@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -6698,7 +6198,7 @@ resolve.exports@^2.0.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== -resolve@^1.1.4, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.4.0: +resolve@^1.1.4, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.4.0: version "1.22.2" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== @@ -6730,13 +6230,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - integrity sha512-yqINtL/G7vs2v+dFIZmFUDbnVyFUJFKd6gK22Kgo6R4jfJGFtisKyncWDDULgjfqf4ASQuIQyjJ7XZ+3aWpsAg== - dependencies: - align-text "^0.1.1" - rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -6911,7 +6404,7 @@ sigmund@~1.0.0: resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" integrity sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g== -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -6962,12 +6455,12 @@ source-map-support@^0.5.16, source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@~0.5.1, source-map@~0.5.3: +source-map@~0.5.3: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== @@ -7307,11 +6800,6 @@ tmpl@1.0.5: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - integrity sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og== - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -7324,11 +6812,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -token-stream@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a" - integrity sha512-nfjOAu/zAWmX9tgwi5NRp7O7zTDUD1miHiB40klUnAh9qnL1iXdgzcz/i5dMaL5jahcBAaSfmNOBBJBLJW8TEg== - tough-cookie@^4.1.2: version "4.1.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" @@ -7365,11 +6848,6 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -ts-map@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ts-map/-/ts-map-1.0.3.tgz#1c4d218dec813d2103b7e04e4bcf348e1471c1ff" - integrity sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w== - ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -7426,7 +6904,7 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.1, tslib@^2.5.0, tslib@^2.6.0: +tslib@^2.5.0, tslib@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== @@ -7578,16 +7056,6 @@ typedoc@^0.24.0: minimatch "^9.0.0" shiki "^0.14.1" -typescript@^3.2.2: - version "3.9.10" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" - integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== - -typescript@^4.5.4: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - typescript@^5.0.0: version "5.1.6" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" @@ -7607,21 +7075,6 @@ typeson@^6.0.0, typeson@^6.1.0: resolved "https://registry.yarnpkg.com/typeson/-/typeson-6.1.0.tgz#5b2a53705a5f58ff4d6f82f965917cabd0d7448b" integrity sha512-6FTtyGr8ldU0pfbvW/eOZrEtEkczHRUtduBnA90Jh9kMPCiFNnXIon3vF41N0S4tV1HHQt4Hk1j4srpESziCaA== -uglify-js@^2.6.1: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - integrity sha512-qLq/4y2pjcU3vhlhseXGGJ7VbFO4pBANu0kwl8VCa9KEI0V8VfZIx2Fy3w01iSTA/pGwKZSmu/+I4etLNDdt5w== - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - integrity sha512-vb2s1lYx2xBtUgy+ta+b2J/GLVUR+wmpINwHePmPRhOsIVCG2wDzKJ0n14GslH1BifsqVzSOwQhRaCAsZ/nI4Q== - umd@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.3.tgz#aa9fe653c42b9097678489c01000acb69f0b26cf" @@ -7648,11 +7101,6 @@ undeclared-identifiers@^1.1.2: simple-concat "^1.0.0" xtend "^4.0.1" -underscore@^1.13.2: - version "1.13.6" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" - integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== - unhomoglyph@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/unhomoglyph/-/unhomoglyph-1.0.6.tgz#ea41f926d0fcf598e3b8bb2980c2ddac66b081d3" @@ -7770,7 +7218,7 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -v8-to-istanbul@^9.0.0, v8-to-istanbul@^9.0.1: +v8-to-istanbul@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== @@ -7802,11 +7250,6 @@ vm-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -void-elements@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" - integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== - vscode-oniguruma@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" @@ -7817,37 +7260,6 @@ vscode-textmate@^8.0.0: resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== -vue-docgen-api@^3.26.0: - version "3.26.0" - resolved "https://registry.yarnpkg.com/vue-docgen-api/-/vue-docgen-api-3.26.0.tgz#2afc6a39e72862fbbc60ceb8510c681749f05460" - integrity sha512-ujdg4i5ZI/wE46RZQMFzKnDGyhEuPCu+fMA86CAd9EIek/6+OqraSVBm5ZkLrbEd5f8xxdnqMU4yiSGHHeao/Q== - dependencies: - "@babel/parser" "^7.2.3" - "@babel/types" "^7.0.0" - ast-types "^0.12.2" - hash-sum "^1.0.2" - lru-cache "^4.1.5" - pug "^2.0.3" - recast "^0.17.3" - ts-map "^1.0.3" - typescript "^3.2.2" - vue-template-compiler "^2.0.0" - -vue-template-compiler@^2.0.0: - version "2.7.14" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz#4545b7dfb88090744c1577ae5ac3f964e61634b1" - integrity sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ== - dependencies: - de-indent "^1.0.2" - he "^1.2.0" - -vue2-ace-editor@^0.0.15: - version "0.0.15" - resolved "https://registry.yarnpkg.com/vue2-ace-editor/-/vue2-ace-editor-0.0.15.tgz#569b208e54ae771ae1edd3b8902ac42f0edc74e3" - integrity sha512-e3TR9OGXc71cGpvYcW068lNpRcFt3+OONCC81oxHL/0vwl/V3OgqnNMw2/RRolgQkO/CA5AjqVHWmANWKOtNnQ== - dependencies: - brace "^0.11.0" - w3c-xmlserializer@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073" @@ -7958,24 +7370,6 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - integrity sha512-1pTPQDKTdd61ozlKGNCjhNRd+KPmgLSGa3mZTHoOliaGcESD8G1PXhh7c1fgiPjVbNVfgy2Faw4BI8/m0cC8Mg== - -with@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/with/-/with-5.1.1.tgz#fa4daa92daf32c4ea94ed453c81f04686b575dfe" - integrity sha512-uAnSsFGfSpF6DNhBXStvlZILfHJfJu4eUkfbRGk94kGO1Ta7bg6FwfvoOhhyHAJuFbCw+0xk4uJ3u57jLvlCJg== - dependencies: - acorn "^3.1.0" - acorn-globals "^3.0.0" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - integrity sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q== - "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" @@ -8044,11 +7438,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== - yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" @@ -8059,29 +7448,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@^20.2.2, yargs-parser@^20.2.9: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - yargs@^17.0.1, yargs@^17.3.1, yargs@^17.5.1: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" @@ -8095,16 +7466,6 @@ yargs@^17.0.1, yargs@^17.3.1, yargs@^17.5.1: y18n "^5.0.5" yargs-parser "^21.1.1" -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - integrity sha512-QFzUah88GAGy9lyDKGBqZdkYApt63rCXYBGYnEP4xDJPXNqXXnBDACnbrXnViV6jRSqAePwrATi2i8mfYm4L1A== - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" - yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" From 43b240486545b1891fb52ec819e0d4821ff96f3c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 19 Jul 2023 10:29:41 +0100 Subject: [PATCH 47/59] Specify /preview_url requests as low priority (#3609) * Specify /preview_url requests as low priority * Update src/@types/global.d.ts Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Simplify interface --------- Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- src/@types/global.d.ts | 16 ++++++++++++++++ src/client.ts | 1 + src/http-api/fetch.ts | 3 ++- src/http-api/interface.ts | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 749eb7f417b..71c0c87b815 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -96,4 +96,20 @@ declare global { // but we still need this for MatrixCall::getRidOfRTXCodecs() setCodecPreferences(codecs: RTCRtpCodecCapability[]): void; } + + interface RequestInit { + /** + * Specifies the priority of the fetch request relative to other requests of the same type. + * Must be one of the following strings: + * high: A high priority fetch request relative to other requests of the same type. + * low: A low priority fetch request relative to other requests of the same type. + * auto: Automatically determine the priority of the fetch request relative to other requests of the same type (default). + * + * @see https://html.spec.whatwg.org/multipage/urls-and-fetching.html#fetch-priority-attribute + * @see https://github.com/microsoft/TypeScript/issues/54472 + * @see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API#browser_compatibility + * Not yet supported in Safari or Firefox + */ + priority?: "high" | "low" | "auto"; + } } diff --git a/src/client.ts b/src/client.ts index a85b04f7dc2..4c27cb0f7a3 100644 --- a/src/client.ts +++ b/src/client.ts @@ -5128,6 +5128,7 @@ export class MatrixClient extends TypedEventEmitter { method: Method, url: URL | string, body?: Body, - opts: Pick = {}, + opts: Pick = {}, ): Promise> { const urlForLogs = this.sanitizeUrlForLogs(url); logger.debug(`FetchHttpApi: --> ${method} ${urlForLogs}`); @@ -276,6 +276,7 @@ export class FetchHttpApi { cache: "no-cache", credentials: "omit", // we send credentials via headers keepalive: keepAlive, + priority: opts.priority, }); logger.debug(`FetchHttpApi: <-- ${method} ${urlForLogs} [${Date.now() - start}ms ${res.status}]`); diff --git a/src/http-api/interface.ts b/src/http-api/interface.ts index ae9400f385c..57e8a18e851 100644 --- a/src/http-api/interface.ts +++ b/src/http-api/interface.ts @@ -33,7 +33,7 @@ export interface IHttpOpts { localTimeoutMs?: number; } -export interface IRequestOpts { +export interface IRequestOpts extends Pick { /** * The alternative base url to use. * If not specified, uses this.opts.baseUrl From 66492e7ba84fd48a4334ac156a461c7fd1dc8a6b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 19 Jul 2023 12:21:50 +0100 Subject: [PATCH 48/59] Fix edge cases around non-thread relations to thread roots and read receipts (#3607) * Ensure non-thread relations to a thread root are actually in both timelines * Make thread in sendReceipt & sendReadReceipt explicit rather than guessing it * Apply suggestions from code review * Fix Room::eventShouldLiveIn to better match Synapse to diverging ideas of notifications * Update read receipt sending behaviour to align with Synapse * Fix tests * Fix thread rel type --- .../matrix-client-event-timeline.spec.ts | 1 - spec/integ/matrix-client-methods.spec.ts | 38 +++---- spec/test-utils/thread.ts | 4 +- spec/unit/read-receipt.spec.ts | 98 +++++++++++++------ spec/unit/room.spec.ts | 86 +++++++++++----- src/client.ts | 11 ++- src/models/room.ts | 41 +++++--- 7 files changed, 178 insertions(+), 101 deletions(-) diff --git a/spec/integ/matrix-client-event-timeline.spec.ts b/spec/integ/matrix-client-event-timeline.spec.ts index bc28efa7222..fd00a3c51ed 100644 --- a/spec/integ/matrix-client-event-timeline.spec.ts +++ b/spec/integ/matrix-client-event-timeline.spec.ts @@ -1284,7 +1284,6 @@ describe("MatrixClient event timelines", function () { THREAD_ROOT.event_id, THREAD_REPLY.event_id, THREAD_REPLY2.getId(), - THREAD_ROOT_REACTION.getId(), THREAD_REPLY3.getId(), ]); }); diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index 18e02624fa2..a44b3815bd5 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -656,7 +656,7 @@ describe("MatrixClient", function () { expect(threaded).toEqual([]); }); - it("copies pre-thread in-timeline vote events onto both timelines", function () { + it("should not copy pre-thread in-timeline vote events onto both timelines", function () { // @ts-ignore setting private property client.clientOpts = { ...defaultClientOpts, @@ -684,10 +684,10 @@ describe("MatrixClient", function () { const eventRefWithThreadId = withThreadId(eventPollResponseReference, eventPollStartThreadRoot.getId()!); expect(eventRefWithThreadId.threadRootId).toBeTruthy(); - expect(threaded).toEqual([eventPollStartThreadRoot, eventMessageInThread, eventRefWithThreadId]); + expect(threaded).toEqual([eventPollStartThreadRoot, eventMessageInThread]); }); - it("copies pre-thread in-timeline reactions onto both timelines", function () { + it("should not copy pre-thread in-timeline reactions onto both timelines", function () { // @ts-ignore setting private property client.clientOpts = { ...defaultClientOpts, @@ -704,14 +704,10 @@ describe("MatrixClient", function () { expect(timeline).toEqual([eventPollStartThreadRoot, eventReaction]); - expect(threaded).toEqual([ - eventPollStartThreadRoot, - eventMessageInThread, - withThreadId(eventReaction, eventPollStartThreadRoot.getId()!), - ]); + expect(threaded).toEqual([eventPollStartThreadRoot, eventMessageInThread]); }); - it("copies post-thread in-timeline vote events onto both timelines", function () { + it("should not copy post-thread in-timeline vote events onto both timelines", function () { // @ts-ignore setting private property client.clientOpts = { ...defaultClientOpts, @@ -728,14 +724,10 @@ describe("MatrixClient", function () { expect(timeline).toEqual([eventPollStartThreadRoot, eventPollResponseReference]); - expect(threaded).toEqual([ - eventPollStartThreadRoot, - withThreadId(eventPollResponseReference, eventPollStartThreadRoot.getId()!), - eventMessageInThread, - ]); + expect(threaded).toEqual([eventPollStartThreadRoot, eventMessageInThread]); }); - it("copies post-thread in-timeline reactions onto both timelines", function () { + it("should not copy post-thread in-timeline reactions onto both timelines", function () { // @ts-ignore setting private property client.clientOpts = { ...defaultClientOpts, @@ -752,11 +744,7 @@ describe("MatrixClient", function () { expect(timeline).toEqual([eventPollStartThreadRoot, eventReaction]); - expect(threaded).toEqual([ - eventPollStartThreadRoot, - eventMessageInThread, - withThreadId(eventReaction, eventPollStartThreadRoot.getId()!), - ]); + expect(threaded).toEqual([eventPollStartThreadRoot, eventMessageInThread]); }); it("sends room state events to the main timeline only", function () { @@ -809,11 +797,7 @@ describe("MatrixClient", function () { ]); // Thread should contain only stuff that happened in the thread - no room state events - expect(threaded).toEqual([ - eventPollStartThreadRoot, - withThreadId(eventPollResponseReference, eventPollStartThreadRoot.getId()!), - eventMessageInThread, - ]); + expect(threaded).toEqual([eventPollStartThreadRoot, eventMessageInThread]); }); it("sends redactions of reactions to thread responses to thread timeline only", () => { @@ -878,9 +862,9 @@ describe("MatrixClient", function () { const [timeline, threaded] = room.partitionThreadedEvents(events); - expect(timeline).toEqual([threadRootEvent, replyToThreadResponse]); + expect(timeline).toEqual([threadRootEvent]); - expect(threaded).toEqual([threadRootEvent, eventMessageInThread]); + expect(threaded).toEqual([threadRootEvent, eventMessageInThread, replyToThreadResponse]); }); }); diff --git a/spec/test-utils/thread.ts b/spec/test-utils/thread.ts index bed1b235e87..2b84239d367 100644 --- a/spec/test-utils/thread.ts +++ b/spec/test-utils/thread.ts @@ -18,7 +18,7 @@ import { RelationType } from "../../src/@types/event"; import { MatrixClient } from "../../src/client"; import { MatrixEvent, MatrixEventEvent } from "../../src/models/event"; import { Room } from "../../src/models/room"; -import { Thread } from "../../src/models/thread"; +import { Thread, THREAD_RELATION_TYPE } from "../../src/models/thread"; import { mkMessage } from "./test-utils"; export const makeThreadEvent = ({ @@ -34,7 +34,7 @@ export const makeThreadEvent = ({ ...props, relatesTo: { event_id: rootEventId, - rel_type: "m.thread", + rel_type: THREAD_RELATION_TYPE.name, ["m.in_reply_to"]: { event_id: replyToEventId, }, diff --git a/spec/unit/read-receipt.spec.ts b/spec/unit/read-receipt.spec.ts index 2bc941ab0af..1ea58dadedb 100644 --- a/spec/unit/read-receipt.spec.ts +++ b/spec/unit/read-receipt.spec.ts @@ -18,7 +18,7 @@ import MockHttpBackend from "matrix-mock-request"; import { MAIN_ROOM_TIMELINE, ReceiptType } from "../../src/@types/read_receipts"; import { MatrixClient } from "../../src/client"; -import { EventType } from "../../src/matrix"; +import { EventType, MatrixEvent, Room } from "../../src/matrix"; import { synthesizeReceipt } from "../../src/models/read-receipt"; import { encodeUri } from "../../src/utils"; import * as utils from "../test-utils/test-utils"; @@ -42,42 +42,45 @@ let httpBackend: MockHttpBackend; const THREAD_ID = "$thread_event_id"; const ROOM_ID = "!123:matrix.org"; -const threadEvent = utils.mkEvent({ - event: true, - type: EventType.RoomMessage, - user: "@bob:matrix.org", - room: ROOM_ID, - content: { - "body": "Hello from a thread", - "m.relates_to": { - "event_id": THREAD_ID, - "m.in_reply_to": { - event_id: THREAD_ID, - }, - "rel_type": "m.thread", - }, - }, -}); - -const roomEvent = utils.mkEvent({ - event: true, - type: EventType.RoomMessage, - user: "@bob:matrix.org", - room: ROOM_ID, - content: { - body: "Hello from a room", - }, -}); - describe("Read receipt", () => { + let threadEvent: MatrixEvent; + let roomEvent: MatrixEvent; + beforeEach(() => { httpBackend = new MockHttpBackend(); client = new MatrixClient({ + userId: "@user:server", baseUrl: "https://my.home.server", accessToken: "my.access.token", fetchFn: httpBackend.fetchFn as typeof global.fetch, }); client.isGuest = () => false; + + threadEvent = utils.mkEvent({ + event: true, + type: EventType.RoomMessage, + user: "@bob:matrix.org", + room: ROOM_ID, + content: { + "body": "Hello from a thread", + "m.relates_to": { + "event_id": THREAD_ID, + "m.in_reply_to": { + event_id: THREAD_ID, + }, + "rel_type": "m.thread", + }, + }, + }); + roomEvent = utils.mkEvent({ + event: true, + type: EventType.RoomMessage, + user: "@bob:matrix.org", + room: ROOM_ID, + content: { + body: "Hello from a room", + }, + }); }); describe("sendReceipt", () => { @@ -143,13 +146,46 @@ describe("Read receipt", () => { await httpBackend.flushAllExpected(); await flushPromises(); }); + + it("should send a main timeline read receipt for a reaction to a thread root", async () => { + roomEvent.event.event_id = THREAD_ID; + const reaction = utils.mkReaction(roomEvent, client, client.getSafeUserId(), ROOM_ID); + const thread = new Room(ROOM_ID, client, client.getSafeUserId()).createThread( + THREAD_ID, + roomEvent, + [threadEvent], + false, + ); + threadEvent.setThread(thread); + reaction.setThread(thread); + + httpBackend + .when( + "POST", + encodeUri("/rooms/$roomId/receipt/$receiptType/$eventId", { + $roomId: ROOM_ID, + $receiptType: ReceiptType.Read, + $eventId: reaction.getId()!, + }), + ) + .check((request) => { + expect(request.data.thread_id).toEqual(MAIN_ROOM_TIMELINE); + }) + .respond(200, {}); + + client.sendReceipt(reaction, ReceiptType.Read, {}); + + await httpBackend.flushAllExpected(); + await flushPromises(); + }); }); describe("synthesizeReceipt", () => { it.each([ - { event: roomEvent, destinationId: MAIN_ROOM_TIMELINE }, - { event: threadEvent, destinationId: threadEvent.threadRootId! }, - ])("adds the receipt to $destinationId", ({ event, destinationId }) => { + { getEvent: () => roomEvent, destinationId: MAIN_ROOM_TIMELINE }, + { getEvent: () => threadEvent, destinationId: THREAD_ID }, + ])("adds the receipt to $destinationId", ({ getEvent, destinationId }) => { + const event = getEvent(); const userId = "@bob:example.org"; const receiptType = ReceiptType.Read; diff --git a/spec/unit/room.spec.ts b/spec/unit/room.spec.ts index 777d46c469f..7464faa4174 100644 --- a/spec/unit/room.spec.ts +++ b/spec/unit/room.spec.ts @@ -2849,7 +2849,7 @@ describe("Room", function () { Thread.setServerSideSupport(FeatureSupport.Stable); const room = new Room(roomId, client, userA); - it("thread root and its relations&redactions should be in both", () => { + it("thread root and its relations&redactions should be in main timeline", () => { const randomMessage = mkMessage(); const threadRoot = mkMessage(); const threadResponse1 = mkThreadResponse(threadRoot); @@ -2867,6 +2867,9 @@ describe("Room", function () { threadReaction2Redaction, ]; + const thread = room.createThread(threadRoot.getId()!, threadRoot, [], false); + events.slice(1).forEach((ev) => ev.setThread(thread)); + expect(room.eventShouldLiveIn(randomMessage, events, roots).shouldLiveInRoom).toBeTruthy(); expect(room.eventShouldLiveIn(randomMessage, events, roots).shouldLiveInThread).toBeFalsy(); @@ -2878,14 +2881,11 @@ describe("Room", function () { expect(room.eventShouldLiveIn(threadResponse1, events, roots).threadId).toBe(threadRoot.getId()); expect(room.eventShouldLiveIn(threadReaction1, events, roots).shouldLiveInRoom).toBeTruthy(); - expect(room.eventShouldLiveIn(threadReaction1, events, roots).shouldLiveInThread).toBeTruthy(); - expect(room.eventShouldLiveIn(threadReaction1, events, roots).threadId).toBe(threadRoot.getId()); + expect(room.eventShouldLiveIn(threadReaction1, events, roots).shouldLiveInThread).toBeFalsy(); expect(room.eventShouldLiveIn(threadReaction2, events, roots).shouldLiveInRoom).toBeTruthy(); - expect(room.eventShouldLiveIn(threadReaction2, events, roots).shouldLiveInThread).toBeTruthy(); - expect(room.eventShouldLiveIn(threadReaction2, events, roots).threadId).toBe(threadRoot.getId()); + expect(room.eventShouldLiveIn(threadReaction2, events, roots).shouldLiveInThread).toBeFalsy(); expect(room.eventShouldLiveIn(threadReaction2Redaction, events, roots).shouldLiveInRoom).toBeTruthy(); - expect(room.eventShouldLiveIn(threadReaction2Redaction, events, roots).shouldLiveInThread).toBeTruthy(); - expect(room.eventShouldLiveIn(threadReaction2Redaction, events, roots).threadId).toBe(threadRoot.getId()); + expect(room.eventShouldLiveIn(threadReaction2Redaction, events, roots).shouldLiveInThread).toBeFalsy(); }); it("thread response and its relations&redactions should be only in thread timeline", () => { @@ -2909,25 +2909,39 @@ describe("Room", function () { expect(room.eventShouldLiveIn(threadReaction2Redaction, events, roots).threadId).toBe(threadRoot.getId()); }); - it("reply to thread response and its relations&redactions should be only in main timeline", () => { + it("reply to thread response and its relations&redactions should be only in thread timeline", () => { const threadRoot = mkMessage(); - const threadResponse1 = mkThreadResponse(threadRoot); - const reply1 = mkReply(threadResponse1); - const reaction1 = utils.mkReaction(reply1, room.client, userA, roomId); - const reaction2 = utils.mkReaction(reply1, room.client, userA, roomId); - const reaction2Redaction = mkRedaction(reply1); + const threadResp1 = mkThreadResponse(threadRoot); + const threadResp1Reply1 = mkReply(threadResp1); + const threadResp1Reply1Reaction1 = utils.mkReaction(threadResp1Reply1, room.client, userA, roomId); + const threadResp1Reply1Reaction2 = utils.mkReaction(threadResp1Reply1, room.client, userA, roomId); + const thResp1Rep1React2Redaction = mkRedaction(threadResp1Reply1); const roots = new Set([threadRoot.getId()!]); - const events = [threadRoot, threadResponse1, reply1, reaction1, reaction2, reaction2Redaction]; + const events = [ + threadRoot, + threadResp1, + threadResp1Reply1, + threadResp1Reply1Reaction1, + threadResp1Reply1Reaction2, + thResp1Rep1React2Redaction, + ]; - expect(room.eventShouldLiveIn(reply1, events, roots).shouldLiveInRoom).toBeTruthy(); - expect(room.eventShouldLiveIn(reply1, events, roots).shouldLiveInThread).toBeFalsy(); - expect(room.eventShouldLiveIn(reaction1, events, roots).shouldLiveInRoom).toBeTruthy(); - expect(room.eventShouldLiveIn(reaction1, events, roots).shouldLiveInThread).toBeFalsy(); - expect(room.eventShouldLiveIn(reaction2, events, roots).shouldLiveInRoom).toBeTruthy(); - expect(room.eventShouldLiveIn(reaction2, events, roots).shouldLiveInThread).toBeFalsy(); - expect(room.eventShouldLiveIn(reaction2Redaction, events, roots).shouldLiveInRoom).toBeTruthy(); - expect(room.eventShouldLiveIn(reaction2Redaction, events, roots).shouldLiveInThread).toBeFalsy(); + const thread = room.createThread(threadRoot.getId()!, threadRoot, [], false); + events.forEach((ev) => ev.setThread(thread)); + + expect(room.eventShouldLiveIn(threadResp1Reply1, events, roots).shouldLiveInRoom).toBeFalsy(); + expect(room.eventShouldLiveIn(threadResp1Reply1, events, roots).shouldLiveInThread).toBeTruthy(); + expect(room.eventShouldLiveIn(threadResp1Reply1, events, roots).threadId).toBe(thread.id); + expect(room.eventShouldLiveIn(threadResp1Reply1Reaction1, events, roots).shouldLiveInRoom).toBeFalsy(); + expect(room.eventShouldLiveIn(threadResp1Reply1Reaction1, events, roots).shouldLiveInThread).toBeTruthy(); + expect(room.eventShouldLiveIn(threadResp1Reply1Reaction1, events, roots).threadId).toBe(thread.id); + expect(room.eventShouldLiveIn(threadResp1Reply1Reaction2, events, roots).shouldLiveInRoom).toBeFalsy(); + expect(room.eventShouldLiveIn(threadResp1Reply1Reaction2, events, roots).shouldLiveInThread).toBeTruthy(); + expect(room.eventShouldLiveIn(threadResp1Reply1Reaction2, events, roots).threadId).toBe(thread.id); + expect(room.eventShouldLiveIn(thResp1Rep1React2Redaction, events, roots).shouldLiveInRoom).toBeFalsy(); + expect(room.eventShouldLiveIn(thResp1Rep1React2Redaction, events, roots).shouldLiveInThread).toBeTruthy(); + expect(room.eventShouldLiveIn(thResp1Rep1React2Redaction, events, roots).threadId).toBe(thread.id); }); it("reply to reply to thread root should only be in the main timeline", () => { @@ -2939,12 +2953,40 @@ describe("Room", function () { const roots = new Set([threadRoot.getId()!]); const events = [threadRoot, threadResponse1, reply1, reply2]; + const thread = room.createThread(threadRoot.getId()!, threadRoot, [], false); + threadResponse1.setThread(thread); + expect(room.eventShouldLiveIn(reply1, events, roots).shouldLiveInRoom).toBeTruthy(); expect(room.eventShouldLiveIn(reply1, events, roots).shouldLiveInThread).toBeFalsy(); expect(room.eventShouldLiveIn(reply2, events, roots).shouldLiveInRoom).toBeTruthy(); expect(room.eventShouldLiveIn(reply2, events, roots).shouldLiveInThread).toBeFalsy(); }); + it("edit to thread root should live in main timeline only", () => { + const threadRoot = mkMessage(); + const threadResponse1 = mkThreadResponse(threadRoot); + const threadRootEdit = mkEdit(threadRoot); + threadRoot.makeReplaced(threadRootEdit); + + const thread = room.createThread(threadRoot.getId()!, threadRoot, [threadResponse1], false); + threadResponse1.setThread(thread); + threadRootEdit.setThread(thread); + + const roots = new Set([threadRoot.getId()!]); + const events = [threadRoot, threadResponse1, threadRootEdit]; + + expect(room.eventShouldLiveIn(threadRoot, events, roots).shouldLiveInRoom).toBeTruthy(); + expect(room.eventShouldLiveIn(threadRoot, events, roots).shouldLiveInThread).toBeTruthy(); + expect(room.eventShouldLiveIn(threadRoot, events, roots).threadId).toBe(threadRoot.getId()); + + expect(room.eventShouldLiveIn(threadResponse1, events, roots).shouldLiveInRoom).toBeFalsy(); + expect(room.eventShouldLiveIn(threadResponse1, events, roots).shouldLiveInThread).toBeTruthy(); + expect(room.eventShouldLiveIn(threadResponse1, events, roots).threadId).toBe(threadRoot.getId()); + + expect(room.eventShouldLiveIn(threadRootEdit, events, roots).shouldLiveInRoom).toBeTruthy(); + expect(room.eventShouldLiveIn(threadRootEdit, events, roots).shouldLiveInThread).toBeFalsy(); + }); + it("should aggregate relations in thread event timeline set", async () => { Thread.setServerSideSupport(FeatureSupport.Stable); const threadRoot = mkMessage(); diff --git a/src/client.ts b/src/client.ts index 4c27cb0f7a3..1c2bdcd0475 100644 --- a/src/client.ts +++ b/src/client.ts @@ -5000,8 +5000,15 @@ export class MatrixClient extends TypedEventEmitter { } } + /** + * Determine which timeline(s) a given event should live in + * Thread roots live in both the main timeline and their corresponding thread timeline + * Relations, redactions, replies to thread relation events live only in the thread timeline + * Relations (other than m.thread), redactions, replies to a thread root live only in the main timeline + * Relations, redactions, replies where the parent cannot be found live in no timelines but should be aggregated regardless. + * Otherwise, the event lives in the main timeline only. + */ public eventShouldLiveIn( event: MatrixEvent, events?: MatrixEvent[], @@ -2109,7 +2117,7 @@ export class Room extends ReadReceipt { }; } - // A thread root is always shown in both timelines + // A thread root is the only event shown in both timelines if (event.isThreadRoot || roots?.has(event.getId()!)) { return { shouldLiveInRoom: true, @@ -2118,40 +2126,41 @@ export class Room extends ReadReceipt { }; } - // A thread relation (1st and 2nd order) is always only shown in a thread + const isThreadRelation = event.isRelation(THREAD_RELATION_TYPE.name); + const parentEventId = event.getAssociatedId(); const threadRootId = event.threadRootId; - if (threadRootId != undefined) { + + // Where the parent is the thread root and this is a non-thread relation this should live only in the main timeline + if (!!parentEventId && !isThreadRelation && (threadRootId === parentEventId || roots?.has(parentEventId!))) { return { - shouldLiveInRoom: false, - shouldLiveInThread: true, - threadId: threadRootId, + shouldLiveInRoom: true, + shouldLiveInThread: false, }; } - const parentEventId = event.getAssociatedId(); let parentEvent: MatrixEvent | undefined; if (parentEventId) { parentEvent = this.findEventById(parentEventId) ?? events?.find((e) => e.getId() === parentEventId); } - // Treat relations and redactions as extensions of their parents so evaluate parentEvent instead - if (parentEvent && (event.isRelation() || event.isRedaction())) { + // Treat non-thread-relations, redactions, and replies as extensions of their parents so evaluate parentEvent instead + if (parentEvent && !isThreadRelation) { return this.eventShouldLiveIn(parentEvent, events, roots); } - if (!event.isRelation()) { + // A thread relation (1st and 2nd order) is always only shown in a thread + if (threadRootId != undefined) { return { - shouldLiveInRoom: true, - shouldLiveInThread: false, + shouldLiveInRoom: false, + shouldLiveInThread: true, + threadId: threadRootId, }; } - // Edge case where we know the event is a relation but don't have the parentEvent - if (roots?.has(event.relationEventId!)) { + if (!parentEventId) { return { shouldLiveInRoom: true, - shouldLiveInThread: true, - threadId: event.relationEventId, + shouldLiveInThread: false, }; } From 7dffd8ffd3921b6c0b40c6c95aa82db5ff1a8c5d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 20 Jul 2023 09:47:30 +0100 Subject: [PATCH 49/59] Make sure to drop references to user device lists (#3610) Empirically, this seems to fix some problems with leaking references to IndexedDB. --- src/rust-crypto/rust-crypto.ts | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 7fa1d62215a..6da6dd53c22 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -296,15 +296,31 @@ export class RustCrypto extends TypedEventEmitter> { const rustUserId = new RustSdkCryptoJs.UserId(userId); - const devices: RustSdkCryptoJs.UserDevices = await this.olmMachine.getUserDevices(rustUserId); - return new Map( - devices - .devices() - .map((device: RustSdkCryptoJs.Device) => [ - device.deviceId.toString(), - rustDeviceToJsDevice(device, rustUserId), - ]), - ); + + // For reasons I don't really understand, the Javascript FinalizationRegistry doesn't seem to run the + // registered callbacks when `userDevices` goes out of scope, nor when the individual devices in the array + // returned by `userDevices.devices` do so. + // + // This is particularly problematic, because each of those structures holds a reference to the + // VerificationMachine, which in turn holds a reference to the IndexeddbCryptoStore. Hence, we end up leaking + // open connections to the crypto store, which means the store can't be deleted on logout. + // + // To fix this, we explicitly call `.free` on each of the objects, which tells the rust code to drop the + // allocated memory and decrement the refcounts for the crypto store. + + const userDevices: RustSdkCryptoJs.UserDevices = await this.olmMachine.getUserDevices(rustUserId); + try { + const deviceArray: RustSdkCryptoJs.Device[] = userDevices.devices(); + try { + return new Map( + deviceArray.map((device) => [device.deviceId.toString(), rustDeviceToJsDevice(device, rustUserId)]), + ); + } finally { + deviceArray.forEach((d) => d.free()); + } + } finally { + userDevices.free(); + } } /** From ecef9fd75519bd9adb8fda9afd8e19f03588576a Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Thu, 20 Jul 2023 11:46:55 +0200 Subject: [PATCH 50/59] Fix `CryptoApi#getVerificationRequestsToDeviceInProgress` (#3611) --- spec/integ/crypto/verification.spec.ts | 8 ++++++++ src/rust-crypto/rust-crypto.ts | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/spec/integ/crypto/verification.spec.ts b/spec/integ/crypto/verification.spec.ts index a245b56e25d..e13b80c54c7 100644 --- a/spec/integ/crypto/verification.spec.ts +++ b/spec/integ/crypto/verification.spec.ts @@ -164,6 +164,14 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st expect(requests[0].transactionId).toEqual(transactionId); } + // check that the returned request depends on the given userID + { + const requests = aliceClient + .getCrypto()! + .getVerificationRequestsToDeviceInProgress("@unknown:localhost"); + expect(requests.length).toEqual(0); + } + let toDeviceMessage = requestBody.messages[TEST_USER_ID][TEST_DEVICE_ID]; expect(toDeviceMessage.from_device).toEqual(aliceClient.deviceId); expect(toDeviceMessage.transaction_id).toEqual(transactionId); diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 6da6dd53c22..7e267071b4b 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -575,7 +575,7 @@ export class RustCrypto extends TypedEventEmitter request.roomId === undefined) From a47f319665683536db8492a566d463481c845e8e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 20 Jul 2023 16:44:52 +0100 Subject: [PATCH 51/59] Only send threaded read receipts if threads support is enabled (#3612) * Only send threaded read receipts if threads support is enabled * Tests --- spec/unit/read-receipt.spec.ts | 24 ++++++++++++++++++++++++ src/client.ts | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/spec/unit/read-receipt.spec.ts b/spec/unit/read-receipt.spec.ts index 1ea58dadedb..3ce0945c053 100644 --- a/spec/unit/read-receipt.spec.ts +++ b/spec/unit/read-receipt.spec.ts @@ -55,6 +55,7 @@ describe("Read receipt", () => { fetchFn: httpBackend.fetchFn as typeof global.fetch, }); client.isGuest = () => false; + client.supportsThreads = () => true; threadEvent = utils.mkEvent({ event: true, @@ -178,6 +179,29 @@ describe("Read receipt", () => { await httpBackend.flushAllExpected(); await flushPromises(); }); + + it("should always send unthreaded receipts if threads support is disabled", async () => { + client.supportsThreads = () => false; + + httpBackend + .when( + "POST", + encodeUri("/rooms/$roomId/receipt/$receiptType/$eventId", { + $roomId: ROOM_ID, + $receiptType: ReceiptType.Read, + $eventId: roomEvent.getId()!, + }), + ) + .check((request) => { + expect(request.data.thread_id).toEqual(undefined); + }) + .respond(200, {}); + + client.sendReceipt(roomEvent, ReceiptType.Read, {}); + + await httpBackend.flushAllExpected(); + await flushPromises(); + }); }); describe("synthesizeReceipt", () => { diff --git a/src/client.ts b/src/client.ts index 1c2bdcd0475..6fc34249295 100644 --- a/src/client.ts +++ b/src/client.ts @@ -4999,7 +4999,7 @@ export class MatrixClient extends TypedEventEmitter Date: Thu, 20 Jul 2023 22:43:49 +0100 Subject: [PATCH 52/59] Update downstream-artifacts.yml (#3613) --- .github/workflows/downstream-artifacts.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/downstream-artifacts.yml b/.github/workflows/downstream-artifacts.yml index 0d487b8ecd8..309a7587044 100644 --- a/.github/workflows/downstream-artifacts.yml +++ b/.github/workflows/downstream-artifacts.yml @@ -1,6 +1,8 @@ name: Build downstream artifacts on: - pull_request: {} + # We only want the Rust Crypto Cypress tests on merge queue to prevent regressions + # from creeping in. They take a long time to run and consume 4 concurrent runners. + # Anyone working on Rust Crypto is able to run the tests locally if required. merge_group: types: [checks_requested] From 6b018b692712c43d4064c65c1a79b170ef3cb135 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 24 Jul 2023 08:37:28 +0100 Subject: [PATCH 53/59] Fix how `Room::eventShouldLiveIn` handles replies to unknown parents (#3615) * Add warning * Fix how Room::eventShouldLiveIn handles replies to unknown parents --- spec/unit/room.spec.ts | 8 ++++++++ src/models/event-timeline-set.ts | 11 ++++++++++- src/models/room.ts | 5 ++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/spec/unit/room.spec.ts b/spec/unit/room.spec.ts index 7464faa4174..a70e993ae63 100644 --- a/spec/unit/room.spec.ts +++ b/spec/unit/room.spec.ts @@ -3018,6 +3018,14 @@ describe("Room", function () { expect(responseRelations![0][1].size).toEqual(1); expect(responseRelations![0][1].has(threadReaction)).toBeTruthy(); }); + + it("a non-thread reply to an unknown parent event should live in the main timeline only", async () => { + const message = mkMessage(); // we do not add this message to any timelines + const reply = mkReply(message); + + expect(room.eventShouldLiveIn(reply).shouldLiveInRoom).toBeTruthy(); + expect(room.eventShouldLiveIn(reply).shouldLiveInThread).toBeFalsy(); + }); }); describe("getEventReadUpTo()", () => { diff --git a/src/models/event-timeline-set.ts b/src/models/event-timeline-set.ts index cc41e543c44..0427967fd3b 100644 --- a/src/models/event-timeline-set.ts +++ b/src/models/event-timeline-set.ts @@ -984,11 +984,20 @@ export class EventTimelineSet extends TypedEventEmitter { }; } - if (!parentEventId) { + // Due to replies not being typical relations and being used as fallbacks for threads relations + // If we bypass the if case above then we know we are not a thread, so if we are still a reply + // then we know that we must be in the main timeline. Same goes if we have no associated parent event. + if (!parentEventId || !!event.replyEventId) { return { shouldLiveInRoom: true, shouldLiveInThread: false, From 533c21a515725d5e5ec9f6f84008ec3682bb8aca Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 24 Jul 2023 15:08:17 +0100 Subject: [PATCH 54/59] Fix registration check your emails stage regression (#3616) * Fix registration check your emails stage regression * Simplify diff * Add test --- spec/unit/interactive-auth.spec.ts | 38 +++++++++++++++++++++++++++++- src/interactive-auth.ts | 14 ++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/spec/unit/interactive-auth.spec.ts b/spec/unit/interactive-auth.spec.ts index ea11fc4c900..bd3c8e653bf 100644 --- a/spec/unit/interactive-auth.spec.ts +++ b/spec/unit/interactive-auth.spec.ts @@ -375,7 +375,7 @@ describe("InteractiveAuth", () => { await expect(ia.attemptAuth.bind(ia)).rejects.toThrow(new Error("No appropriate authentication flow found")); }); - it("should handle unexpected error types without data propery set", async () => { + it("should handle unexpected error types without data property set", async () => { const doRequest = jest.fn(); const stateUpdated = jest.fn(); const requestEmailToken = jest.fn(); @@ -559,4 +559,40 @@ describe("InteractiveAuth", () => { ia.chooseStage(); expect(ia.getChosenFlow()?.stages).toEqual([AuthType.Password]); }); + + it("should fire stateUpdated callback if with error when encountered", async () => { + const doRequest = jest.fn(); + const stateUpdated = jest.fn(); + + const ia = new InteractiveAuth({ + matrixClient: getFakeClient(), + doRequest: doRequest, + stateUpdated: stateUpdated, + requestEmailToken: jest.fn(), + authData: { + session: "sessionId", + flows: [{ stages: [AuthType.Password] }], + params: { + [AuthType.Password]: { param: "aa" }, + }, + }, + }); + + // first we expect a call here + stateUpdated.mockImplementation((stage) => { + expect(stage).toEqual(AuthType.Password); + ia.submitAuthDict({ + type: AuthType.Password, + }); + }); + + // .. which should trigger a call here + doRequest.mockRejectedValue(new MatrixError({ errcode: "M_UNKNOWN", error: "This is an error" })); + + await Promise.allSettled([ia.attemptAuth()]); + expect(stateUpdated).toHaveBeenCalledWith("m.login.password", { + errcode: "M_UNKNOWN", + error: "This is an error", + }); + }); }); diff --git a/src/interactive-auth.ts b/src/interactive-auth.ts index 0a75ab5232f..3617ce1765f 100644 --- a/src/interactive-auth.ts +++ b/src/interactive-auth.ts @@ -264,8 +264,8 @@ export class InteractiveAuth { private readonly requestEmailTokenCallback: IOpts["requestEmailToken"]; private readonly supportedStages?: Set; - // The current latest data received from the server during the user interactive auth flow. - private data: IAuthData; + // The current latest data or error received from the server during the user interactive auth flow. + private data: IAuthData & MatrixError["data"]; private emailSid?: string; private requestingEmailToken = false; private attemptAuthDeferred: IDeferred | null = null; @@ -549,7 +549,7 @@ export class InteractiveAuth { matrixError.data.session = (this.data as IAuthData).session; } if (matrixError) { - this.data = matrixError.data as IAuthData; + this.data = matrixError.data; } try { this.startNextAuthStage(); @@ -602,6 +602,14 @@ export class InteractiveAuth { return; } + if (this.data?.errcode || this.data?.error) { + this.stateUpdatedCallback(nextStage, { + errcode: this.data?.errcode || "", + error: this.data?.error || "", + }); + return; + } + this.stateUpdatedCallback(nextStage, nextStage === EMAIL_STAGE_TYPE ? { emailSid: this.emailSid } : {}); } From de7959de6c5cafbc88b9a0701b56b268b4595d62 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 24 Jul 2023 17:35:56 +0100 Subject: [PATCH 55/59] Ensure we do not clobber a newer RR with an older unthreaded one (#3617) * Ensure we do not clobber a newer RR with an older unthreaded one or vice versa * Fix test --- spec/unit/read-receipt.spec.ts | 40 +++++++++++++++++++++++++++++++++- spec/unit/room.spec.ts | 4 ++-- src/models/read-receipt.ts | 38 +++++++++++++++++--------------- 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/spec/unit/read-receipt.spec.ts b/spec/unit/read-receipt.spec.ts index 3ce0945c053..6f9aea92781 100644 --- a/spec/unit/read-receipt.spec.ts +++ b/spec/unit/read-receipt.spec.ts @@ -16,7 +16,7 @@ limitations under the License. import MockHttpBackend from "matrix-mock-request"; -import { MAIN_ROOM_TIMELINE, ReceiptType } from "../../src/@types/read_receipts"; +import { MAIN_ROOM_TIMELINE, ReceiptType, WrappedReceipt } from "../../src/@types/read_receipts"; import { MatrixClient } from "../../src/client"; import { EventType, MatrixEvent, Room } from "../../src/matrix"; import { synthesizeReceipt } from "../../src/models/read-receipt"; @@ -220,4 +220,42 @@ describe("Read receipt", () => { expect(content.thread_id).toEqual(destinationId); }); }); + + describe("addReceiptToStructure", () => { + it("should not allow an older unthreaded receipt to clobber a `main` threaded one", () => { + const userId = client.getSafeUserId(); + const room = new Room(ROOM_ID, client, userId); + + const unthreadedReceipt: WrappedReceipt = { + eventId: "$olderEvent", + data: { + ts: 1234567880, + }, + }; + const mainTimelineReceipt: WrappedReceipt = { + eventId: "$newerEvent", + data: { + ts: 1234567890, + }, + }; + + room.addReceiptToStructure( + mainTimelineReceipt.eventId, + ReceiptType.ReadPrivate, + userId, + mainTimelineReceipt.data, + false, + ); + expect(room.getEventReadUpTo(userId)).toBe(mainTimelineReceipt.eventId); + + room.addReceiptToStructure( + unthreadedReceipt.eventId, + ReceiptType.ReadPrivate, + userId, + unthreadedReceipt.data, + false, + ); + expect(room.getEventReadUpTo(userId)).toBe(mainTimelineReceipt.eventId); + }); + }); }); diff --git a/spec/unit/room.spec.ts b/spec/unit/room.spec.ts index a70e993ae63..b06c1bc021b 100644 --- a/spec/unit/room.spec.ts +++ b/spec/unit/room.spec.ts @@ -3112,10 +3112,10 @@ describe("Room", function () { it("should give precedence to m.read.private", () => { room.getReadReceiptForUserId = (userId, ignore, receiptType): WrappedReceipt | null => { if (receiptType === ReceiptType.ReadPrivate) { - return { eventId: "eventId1" } as WrappedReceipt; + return { eventId: "eventId1", data: { ts: 123 } }; } if (receiptType === ReceiptType.Read) { - return { eventId: "eventId2" } as WrappedReceipt; + return { eventId: "eventId2", data: { ts: 123 } }; } return null; }; diff --git a/src/models/read-receipt.ts b/src/models/read-receipt.ts index 7d30c8be95f..29eb1409a2c 100644 --- a/src/models/read-receipt.ts +++ b/src/models/read-receipt.ts @@ -57,9 +57,10 @@ export abstract class ReadReceipt< // which pass in an event ID and get back some receipts, so we also store // a pre-cached list for this purpose. // Map: receipt type → user Id → receipt - private receipts = new MapWithDefault>( - () => new Map(), - ); + private receipts = new MapWithDefault< + string, + Map + >(() => new Map()); private receiptCacheByEventId: ReceiptCache = new Map(); public abstract getUnfilteredTimelineSet(): EventTimelineSet; @@ -85,6 +86,13 @@ export abstract class ReadReceipt< return syntheticReceipt ?? realReceipt; } + private compareReceipts(a: WrappedReceipt, b: WrappedReceipt): number { + // Try compare them in our unfiltered timeline set order, falling back to receipt timestamp which should be + // relatively sane as receipts are set only by the originating homeserver so as long as its clock doesn't + // jump around then it should be valid. + return this.getUnfilteredTimelineSet().compareEventOrdering(a.eventId, b.eventId) ?? a.data.ts - b.data.ts; + } + /** * Get the ID of the event that a given user has read up to, or null if we * have received no read receipts from them. @@ -99,19 +107,13 @@ export abstract class ReadReceipt< // receipt type here again. IMHO this should be done by the server in // some more intelligent manner or the client should just use timestamps - const timelineSet = this.getUnfilteredTimelineSet(); const publicReadReceipt = this.getReadReceiptForUserId(userId, ignoreSynthesized, ReceiptType.Read); const privateReadReceipt = this.getReadReceiptForUserId(userId, ignoreSynthesized, ReceiptType.ReadPrivate); // If we have both, compare them let comparison: number | null | undefined; if (publicReadReceipt?.eventId && privateReadReceipt?.eventId) { - comparison = timelineSet.compareEventOrdering(publicReadReceipt?.eventId, privateReadReceipt?.eventId); - } - - // If we didn't get a comparison try to compare the ts of the receipts - if (!comparison && publicReadReceipt?.data?.ts && privateReadReceipt?.data?.ts) { - comparison = publicReadReceipt?.data?.ts - privateReadReceipt?.data?.ts; + comparison = this.compareReceipts(publicReadReceipt, privateReadReceipt); } // The public receipt is more likely to drift out of date so the private @@ -142,20 +144,20 @@ export abstract class ReadReceipt< existingReceipt = pair[ReceiptPairSyntheticIndex] ?? pair[ReceiptPairRealIndex]; } + const wrappedReceipt: WrappedReceipt = { + eventId, + data: receipt, + }; + if (existingReceipt) { - // we only want to add this receipt if we think it is later than the one we already have. + // We only want to add this receipt if we think it is later than the one we already have. // This is managed server-side, but because we synthesize RRs locally we have to do it here too. - const ordering = this.getUnfilteredTimelineSet().compareEventOrdering(existingReceipt.eventId, eventId); - if (ordering !== null && ordering >= 0) { + const ordering = this.compareReceipts(existingReceipt, wrappedReceipt); + if (ordering >= 0) { return; } } - const wrappedReceipt: WrappedReceipt = { - eventId, - data: receipt, - }; - const realReceipt = synthetic ? pair[ReceiptPairRealIndex] : wrappedReceipt; const syntheticReceipt = synthetic ? wrappedReceipt : pair[ReceiptPairSyntheticIndex]; From 8a808863584bb1a7de4e043372b443475153264c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 25 Jul 2023 16:28:52 +0100 Subject: [PATCH 56/59] Fix threads ending up with chunks of their timelines missing (#3618) * Fix threads ending up with chunks of their timelines missing * delint --- .../matrix-client-event-timeline.spec.ts | 19 +++++++++++++++++++ spec/unit/models/thread.spec.ts | 6 +++++- spec/unit/room.spec.ts | 19 ++++++++++--------- src/models/thread.ts | 5 ----- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/spec/integ/matrix-client-event-timeline.spec.ts b/spec/integ/matrix-client-event-timeline.spec.ts index fd00a3c51ed..254dff47f08 100644 --- a/spec/integ/matrix-client-event-timeline.spec.ts +++ b/spec/integ/matrix-client-event-timeline.spec.ts @@ -2026,6 +2026,25 @@ describe("MatrixClient event timelines", function () { .respond(200, function () { return THREAD_ROOT; }); + httpBackend + .when("GET", "/rooms/!foo%3Abar/event/" + encodeURIComponent(THREAD_ROOT.event_id!)) + .respond(200, function () { + return THREAD_ROOT; + }); + httpBackend + .when( + "GET", + "/_matrix/client/v1/rooms/!foo%3Abar/relations/" + + encodeURIComponent(THREAD_ROOT.event_id!) + + "/" + + encodeURIComponent(THREAD_RELATION_TYPE.name) + + buildRelationPaginationQuery({ dir: Direction.Backward, limit: 1 }), + ) + .respond(200, function () { + return { + chunk: [THREAD_REPLY], + }; + }); await Promise.all([httpBackend.flushAllExpected(), utils.syncPromise(client)]); const room = client.getRoom(roomId)!; diff --git a/spec/unit/models/thread.spec.ts b/spec/unit/models/thread.spec.ts index 0847bc8f054..8b451b48847 100644 --- a/spec/unit/models/thread.spec.ts +++ b/spec/unit/models/thread.spec.ts @@ -703,7 +703,11 @@ async function createThread(client: MatrixClient, user: string, roomId: string): root.setThreadId(root.getId()); await room.addLiveEvents([root]); - return room.createThread(root.getId()!, root, [], false); + // Create the thread and wait for it to be initialised + const thread = room.createThread(root.getId()!, root, [], false); + await new Promise((res) => thread.once(RoomEvent.TimelineReset, () => res())); + + return thread; } /** diff --git a/spec/unit/room.spec.ts b/spec/unit/room.spec.ts index b06c1bc021b..5dee474459f 100644 --- a/spec/unit/room.spec.ts +++ b/spec/unit/room.spec.ts @@ -2556,7 +2556,7 @@ describe("Room", function () { next_batch: "start_token", }); - let prom = emitPromise(room, ThreadEvent.New); + const prom = emitPromise(room, ThreadEvent.New); await room.addLiveEvents([randomMessage, threadRoot, threadResponse]); const thread: Thread = await prom; await emitPromise(room, ThreadEvent.Update); @@ -2583,9 +2583,11 @@ describe("Room", function () { }, }); - prom = emitPromise(room, ThreadEvent.Update); - await room.addLiveEvents([threadResponseEdit]); - await prom; + // XXX: If we add the relation to the thread response before the thread finishes fetching via /relations + // then the test will fail + await emitPromise(room, ThreadEvent.Update); + await emitPromise(room, ThreadEvent.Update); + await Promise.all([emitPromise(room, ThreadEvent.Update), room.addLiveEvents([threadResponseEdit])]); expect(thread.replyToEvent!.getContent().body).toBe(threadResponseEdit.getContent()["m.new_content"].body); }); @@ -2765,7 +2767,7 @@ describe("Room", function () { "m.relations": { "m.thread": { latest_event: threadResponse2.event, - count: 2, + count: 1, current_user_participated: true, }, }, @@ -2787,10 +2789,10 @@ describe("Room", function () { let prom = emitPromise(room, ThreadEvent.New); await room.addLiveEvents([threadRoot, threadResponse1]); const thread: Thread = await prom; + await emitPromise(room, ThreadEvent.Update); expect(thread.initialEventsFetched).toBeTruthy(); await room.addLiveEvents([threadResponse2]); - await emitPromise(room, ThreadEvent.Update); expect(thread).toHaveLength(2); expect(thread.replyToEvent!.getId()).toBe(threadResponse2.getId()); @@ -2809,11 +2811,10 @@ describe("Room", function () { }, }); - prom = emitPromise(room, ThreadEvent.Update); + await emitPromise(room, ThreadEvent.Update); const threadResponse2Redaction = mkRedaction(threadResponse2); - await room.addLiveEvents([threadResponse2Redaction]); - await prom; await emitPromise(room, ThreadEvent.Update); + await room.addLiveEvents([threadResponse2Redaction]); expect(thread).toHaveLength(1); expect(thread.replyToEvent!.getId()).toBe(threadResponse1.getId()); diff --git a/src/models/thread.ts b/src/models/thread.ts index 2966f22a545..2d8228d71ea 100644 --- a/src/models/thread.ts +++ b/src/models/thread.ts @@ -326,11 +326,6 @@ export class Thread extends ReadReceipt { this.setEventMetadata(event); - if (!this.initialEventsFetched && !toStartOfTimeline && event.getId() === this.id) { - // We're loading the thread organically - this.initialEventsFetched = true; - } - const lastReply = this.lastReply(); const isNewestReply = !lastReply || event.localTimestamp >= lastReply!.localTimestamp; From 79d4113a6b0e3ff8bf70e62115ed42be28d0d612 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Tue, 25 Jul 2023 19:03:43 +0200 Subject: [PATCH 57/59] ElementR: Stub `CheckOwnCrossSigningTrust`, import cross signing keys and verify local device in `bootstrapCrossSigning` (#3608) --- spec/integ/crypto/cross-signing.spec.ts | 139 +++++++++++++++++- spec/test-utils/mockEndpoints.ts | 7 +- .../test-data/generate-test-data.py | 38 +++++ spec/test-utils/test-data/index.ts | 15 ++ .../rust-crypto/CrossSigningIdentity.spec.ts | 10 +- src/client.ts | 11 +- src/common-crypto/CryptoBackend.ts | 16 ++ src/rust-crypto/CrossSigningIdentity.ts | 33 ++++- src/rust-crypto/rust-crypto.ts | 33 ++++- 9 files changed, 288 insertions(+), 14 deletions(-) diff --git a/spec/integ/crypto/cross-signing.spec.ts b/spec/integ/crypto/cross-signing.spec.ts index 4043379e1e7..3e03461e57e 100644 --- a/spec/integ/crypto/cross-signing.spec.ts +++ b/spec/integ/crypto/cross-signing.spec.ts @@ -18,9 +18,22 @@ import fetchMock from "fetch-mock-jest"; import "fake-indexeddb/auto"; import { IDBFactory } from "fake-indexeddb"; -import { CRYPTO_BACKENDS, InitCrypto } from "../../test-utils/test-utils"; -import { createClient, IAuthDict, MatrixClient } from "../../../src"; -import { mockSetupCrossSigningRequests } from "../../test-utils/mockEndpoints"; +import { CRYPTO_BACKENDS, InitCrypto, syncPromise } from "../../test-utils/test-utils"; +import { AuthDict, createClient, CryptoEvent, MatrixClient } from "../../../src"; +import { mockInitialApiRequests, mockSetupCrossSigningRequests } from "../../test-utils/mockEndpoints"; +import { encryptAES } from "../../../src/crypto/aes"; +import { CryptoCallbacks } from "../../../src/crypto-api"; +import { SECRET_STORAGE_ALGORITHM_V1_AES } from "../../../src/secret-storage"; +import { ISyncResponder, SyncResponder } from "../../test-utils/SyncResponder"; +import { E2EKeyReceiver } from "../../test-utils/E2EKeyReceiver"; +import { + MASTER_CROSS_SIGNING_PRIVATE_KEY_BASE64, + SELF_CROSS_SIGNING_PRIVATE_KEY_BASE64, + SELF_CROSS_SIGNING_PUBLIC_KEY_BASE64, + SIGNED_CROSS_SIGNING_KEYS_DATA, + USER_CROSS_SIGNING_PRIVATE_KEY_BASE64, +} from "../../test-utils/test-data"; +import { E2EKeyResponder } from "../../test-utils/E2EKeyResponder"; afterEach(() => { // reset fake-indexeddb after each test, to make sure we don't leak connections @@ -39,8 +52,32 @@ const TEST_DEVICE_ID = "xzcvb"; * to provide the most effective integration tests possible. */ describe.each(Object.entries(CRYPTO_BACKENDS))("cross-signing (%s)", (backend: string, initCrypto: InitCrypto) => { + // newBackendOnly is the opposite to `oldBackendOnly`: it will skip the test if we are running against the legacy + // backend. Once we drop support for legacy crypto, it will go away. + const newBackendOnly = backend === "rust-sdk" ? test : test.skip; + let aliceClient: MatrixClient; + /** an object which intercepts `/sync` requests from {@link #aliceClient} */ + let syncResponder: ISyncResponder; + + /** an object which intercepts `/keys/query` requests on the test homeserver */ + let e2eKeyResponder: E2EKeyResponder; + + // Encryption key used to encrypt cross signing keys + const encryptionKey = new Uint8Array(32); + + /** + * Create the {@link CryptoCallbacks} + */ + function createCryptoCallbacks(): CryptoCallbacks { + return { + getSecretStorageKey: (keys, name) => { + return Promise.resolve<[string, Uint8Array]>(["key_id", encryptionKey]); + }, + }; + } + beforeEach(async () => { // anything that we don't have a specific matcher for silently returns a 404 fetchMock.catch(404); @@ -52,8 +89,14 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("cross-signing (%s)", (backend: s userId: TEST_USER_ID, accessToken: "akjgkrgjs", deviceId: TEST_DEVICE_ID, + cryptoCallbacks: createCryptoCallbacks(), }); + syncResponder = new SyncResponder(homeserverUrl); + e2eKeyResponder = new E2EKeyResponder(homeserverUrl); + /** an object which intercepts `/keys/upload` requests on the test homeserver */ + new E2EKeyReceiver(homeserverUrl); + await initCrypto(aliceClient); }); @@ -68,7 +111,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("cross-signing (%s)", (backend: s * @param authDict - The parameters to as the `auth` dict in the key upload request. * @see https://spec.matrix.org/v1.6/client-server-api/#authentication-types */ - async function bootstrapCrossSigning(authDict: IAuthDict): Promise { + async function bootstrapCrossSigning(authDict: AuthDict): Promise { await aliceClient.getCrypto()?.bootstrapCrossSigning({ authUploadDeviceSigningKeys: (makeRequest) => makeRequest(authDict).then(() => undefined), }); @@ -105,6 +148,94 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("cross-signing (%s)", (backend: s `[${TEST_USER_ID}].[${TEST_DEVICE_ID}].signatures.[${TEST_USER_ID}].[${sskId}]`, ); }); + + newBackendOnly("get cross signing keys from secret storage and import them", async () => { + // Return public cross signing keys + e2eKeyResponder.addCrossSigningData(SIGNED_CROSS_SIGNING_KEYS_DATA); + + mockInitialApiRequests(aliceClient.getHomeserverUrl()); + + // Encrypt the private keys and return them in the /sync response as if they are in Secret Storage + const masterKey = await encryptAES( + MASTER_CROSS_SIGNING_PRIVATE_KEY_BASE64, + encryptionKey, + "m.cross_signing.master", + ); + const selfSigningKey = await encryptAES( + SELF_CROSS_SIGNING_PRIVATE_KEY_BASE64, + encryptionKey, + "m.cross_signing.self_signing", + ); + const userSigningKey = await encryptAES( + USER_CROSS_SIGNING_PRIVATE_KEY_BASE64, + encryptionKey, + "m.cross_signing.user_signing", + ); + + syncResponder.sendOrQueueSyncResponse({ + next_batch: 1, + account_data: { + events: [ + { + type: "m.cross_signing.master", + content: { + encrypted: { + key_id: masterKey, + }, + }, + }, + { + type: "m.cross_signing.self_signing", + content: { + encrypted: { + key_id: selfSigningKey, + }, + }, + }, + { + type: "m.cross_signing.user_signing", + content: { + encrypted: { + key_id: userSigningKey, + }, + }, + }, + { + type: "m.secret_storage.key.key_id", + content: { + key: "key_id", + algorithm: SECRET_STORAGE_ALGORITHM_V1_AES, + }, + }, + ], + }, + }); + await aliceClient.startClient(); + await syncPromise(aliceClient); + + // we expect a request to upload signatures for our device ... + fetchMock.post({ url: "path:/_matrix/client/v3/keys/signatures/upload", name: "upload-sigs" }, {}); + + // we expect the UserTrustStatusChanged event to be fired after the cross signing keys import + const userTrustStatusChangedPromise = new Promise((resolve) => + aliceClient.on(CryptoEvent.UserTrustStatusChanged, resolve), + ); + + const authDict = { type: "test" }; + await bootstrapCrossSigning(authDict); + + // Check if the UserTrustStatusChanged event was fired + expect(await userTrustStatusChangedPromise).toBe(aliceClient.getUserId()); + + // Expect the signature to be uploaded + expect(fetchMock.called("upload-sigs")).toBeTruthy(); + const [, sigsOpts] = fetchMock.lastCall("upload-sigs")!; + const body = JSON.parse(sigsOpts!.body as string); + // the device should have a signature with the public self cross signing keys. + expect(body).toHaveProperty( + `[${TEST_USER_ID}].[${TEST_DEVICE_ID}].signatures.[${TEST_USER_ID}].[ed25519:${SELF_CROSS_SIGNING_PUBLIC_KEY_BASE64}]`, + ); + }); }); describe("getCrossSigningStatus()", () => { diff --git a/spec/test-utils/mockEndpoints.ts b/spec/test-utils/mockEndpoints.ts index bd5bb819a42..386b7a4cb00 100644 --- a/spec/test-utils/mockEndpoints.ts +++ b/spec/test-utils/mockEndpoints.ts @@ -32,13 +32,16 @@ export function mockInitialApiRequests(homeserverUrl: string) { /** * Mock the requests needed to set up cross signing * - * Return `{}` for `GET _matrix/client/r0/user/:userId/account_data/:type` request + * Return 404 error for `GET _matrix/client/r0/user/:userId/account_data/:type` request * Return `{}` for `POST _matrix/client/v3/keys/signatures/upload` request (named `upload-sigs` for fetchMock check) * Return `{}` for `POST /_matrix/client/(unstable|v3)/keys/device_signing/upload` request (named `upload-keys` for fetchMock check) */ export function mockSetupCrossSigningRequests(): void { // have account_data requests return an empty object - fetchMock.get("express:/_matrix/client/r0/user/:userId/account_data/:type", {}); + fetchMock.get("express:/_matrix/client/r0/user/:userId/account_data/:type", { + status: 404, + body: { errcode: "M_NOT_FOUND", error: "Account data not found." }, + }); // we expect a request to upload signatures for our device ... fetchMock.post({ url: "path:/_matrix/client/v3/keys/signatures/upload", name: "upload-sigs" }, {}); diff --git a/spec/test-utils/test-data/generate-test-data.py b/spec/test-utils/test-data/generate-test-data.py index 3ba7dd4a8b9..d48bb37d786 100755 --- a/spec/test-utils/test-data/generate-test-data.py +++ b/spec/test-utils/test-data/generate-test-data.py @@ -71,6 +71,29 @@ def main() -> None: b64_master_public_key = encode_base64( master_private_key.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw) ) + b64_master_private_key = encode_base64( + MASTER_CROSS_SIGNING_PRIVATE_KEY_BYTES + ) + + self_signing_private_key = ed25519.Ed25519PrivateKey.from_private_bytes( + SELF_CROSS_SIGNING_PRIVATE_KEY_BYTES + ) + b64_self_signing_public_key = encode_base64( + self_signing_private_key.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw) + ) + b64_self_signing_private_key = encode_base64( + SELF_CROSS_SIGNING_PRIVATE_KEY_BYTES + ) + + user_signing_private_key = ed25519.Ed25519PrivateKey.from_private_bytes( + USER_CROSS_SIGNING_PRIVATE_KEY_BYTES + ) + b64_user_signing_public_key = encode_base64( + user_signing_private_key.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw) + ) + b64_user_signing_private_key = encode_base64( + USER_CROSS_SIGNING_PRIVATE_KEY_BYTES + ) print( f"""\ @@ -96,6 +119,21 @@ def main() -> None: /** base64-encoded public master cross-signing key */ export const MASTER_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "{b64_master_public_key}"; +/** base64-encoded private master cross-signing key */ +export const MASTER_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "{b64_master_private_key}"; + +/** base64-encoded public self cross-signing key */ +export const SELF_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "{b64_self_signing_public_key}"; + +/** base64-encoded private self signing cross-signing key */ +export const SELF_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "{b64_self_signing_private_key}"; + +/** base64-encoded public user cross-signing key */ +export const USER_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "{b64_user_signing_public_key}"; + +/** base64-encoded private user signing cross-signing key */ +export const USER_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "{b64_user_signing_private_key}"; + /** Signed cross-signing keys data, also suitable for returning from a `/keys/query` call */ export const SIGNED_CROSS_SIGNING_KEYS_DATA: Partial = { json.dumps(build_cross_signing_keys_data(), indent=4) diff --git a/spec/test-utils/test-data/index.ts b/spec/test-utils/test-data/index.ts index 07ff1222526..c25a2f78ae4 100644 --- a/spec/test-utils/test-data/index.ts +++ b/spec/test-utils/test-data/index.ts @@ -36,6 +36,21 @@ export const SIGNED_TEST_DEVICE_DATA: IDeviceKeys = { /** base64-encoded public master cross-signing key */ export const MASTER_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "J+5An10v1vzZpAXTYFokD1/PEVccFnLC61EfRXit0UY"; +/** base64-encoded private master cross-signing key */ +export const MASTER_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "ZG95b3VzcGVha3doYWFhYWFhYWFhYWFhYWFhYWFhbGU"; + +/** base64-encoded public self cross-signing key */ +export const SELF_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "aU2+2CyXQTCuDcmWW0EL2bhJ6PdjFW2LbAsbHqf02AY"; + +/** base64-encoded private self signing cross-signing key */ +export const SELF_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "c2VsZnNlbGZzZWxmc2VsZnNlbGZzZWxmc2VsZnNlbGY"; + +/** base64-encoded public user cross-signing key */ +export const USER_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "g5TC/zjQXyZYuDLZv7a41z5fFVrXpYPypG//AFQj8hY"; + +/** base64-encoded private user signing cross-signing key */ +export const USER_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "dXNlcnVzZXJ1c2VydXNlcnVzZXJ1c2VydXNlcnVzZXI"; + /** Signed cross-signing keys data, also suitable for returning from a `/keys/query` call */ export const SIGNED_CROSS_SIGNING_KEYS_DATA: Partial = { "master_keys": { diff --git a/spec/unit/rust-crypto/CrossSigningIdentity.spec.ts b/spec/unit/rust-crypto/CrossSigningIdentity.spec.ts index 6187ec7ede3..83d74716244 100644 --- a/spec/unit/rust-crypto/CrossSigningIdentity.spec.ts +++ b/spec/unit/rust-crypto/CrossSigningIdentity.spec.ts @@ -19,6 +19,7 @@ import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; import { CrossSigningIdentity } from "../../../src/rust-crypto/CrossSigningIdentity"; import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor"; +import { ServerSideSecretStorage } from "../../../src/secret-storage"; describe("CrossSigningIdentity", () => { describe("bootstrapCrossSigning", () => { @@ -31,6 +32,9 @@ describe("CrossSigningIdentity", () => { /** A mock OutgoingRequestProcessor which crossSigning is connected to */ let outgoingRequestProcessor: Mocked; + /** A mock ServerSideSecretStorage which crossSigning is connected to */ + let secretStorage: Mocked; + beforeEach(async () => { await RustSdkCryptoJs.initAsync(); @@ -44,7 +48,11 @@ describe("CrossSigningIdentity", () => { makeOutgoingRequest: jest.fn(), } as unknown as Mocked; - crossSigning = new CrossSigningIdentity(olmMachine, outgoingRequestProcessor); + secretStorage = { + get: jest.fn(), + } as unknown as Mocked; + + crossSigning = new CrossSigningIdentity(olmMachine, outgoingRequestProcessor, secretStorage, jest.fn()); }); it("should do nothing if keys are present on-device and in secret storage", async () => { diff --git a/src/client.ts b/src/client.ts index 6fc34249295..fc7f2bef30b 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2250,7 +2250,10 @@ export class MatrixClient extends TypedEventEmitter { - if (!this.crypto) { + if (!this.cryptoBackend) { throw new Error("End-to-end encryption disabled"); } - return this.crypto.checkOwnCrossSigningTrust(opts); + return this.cryptoBackend.checkOwnCrossSigningTrust(opts); } /** diff --git a/src/common-crypto/CryptoBackend.ts b/src/common-crypto/CryptoBackend.ts index c6888437d55..b99410d0749 100644 --- a/src/common-crypto/CryptoBackend.ts +++ b/src/common-crypto/CryptoBackend.ts @@ -90,6 +90,15 @@ export interface CryptoBackend extends SyncCryptoCallbacks, CryptoApi { * @returns the cross signing information for the user. */ getStoredCrossSigningForUser(userId: string): CrossSigningInfo | null; + + /** + * Check the cross signing trust of the current user + * + * @param opts - Options object. + * + * @deprecated Unneeded for the new crypto + */ + checkOwnCrossSigningTrust(opts?: CheckOwnCrossSigningTrustOpts): Promise; } /** The methods which crypto implementations should expose to the Sync api @@ -165,3 +174,10 @@ export interface OnSyncCompletedData { */ catchingUp?: boolean; } + +/** + * Options object for {@link CryptoBackend#checkOwnCrossSigningTrust}. + */ +export interface CheckOwnCrossSigningTrustOpts { + allowPrivateKeyRequests?: boolean; +} diff --git a/src/rust-crypto/CrossSigningIdentity.ts b/src/rust-crypto/CrossSigningIdentity.ts index 2c43ed60397..41f16b90e7f 100644 --- a/src/rust-crypto/CrossSigningIdentity.ts +++ b/src/rust-crypto/CrossSigningIdentity.ts @@ -15,11 +15,13 @@ limitations under the License. */ import { OlmMachine, CrossSigningStatus } from "@matrix-org/matrix-sdk-crypto-wasm"; +import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm"; import { BootstrapCrossSigningOpts } from "../crypto-api"; import { logger } from "../logger"; import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProcessor"; import { UIAuthCallback } from "../interactive-auth"; +import { ServerSideSecretStorage } from "../secret-storage"; /** Manages the cross-signing keys for our own user. * @@ -29,6 +31,9 @@ export class CrossSigningIdentity { public constructor( private readonly olmMachine: OlmMachine, private readonly outgoingRequestProcessor: OutgoingRequestProcessor, + private readonly secretStorage: ServerSideSecretStorage, + /** Called if the cross signing keys are imported from the secret storage */ + private readonly onCrossSigningKeysImport: () => void, ) {} /** @@ -41,7 +46,15 @@ export class CrossSigningIdentity { } const olmDeviceStatus: CrossSigningStatus = await this.olmMachine.crossSigningStatus(); - const privateKeysInSecretStorage = false; // TODO + + // Try to fetch cross signing keys from the secret storage + const masterKeyFromSecretStorage = await this.secretStorage.get("m.cross_signing.master"); + const selfSigningKeyFromSecretStorage = await this.secretStorage.get("m.cross_signing.self_signing"); + const userSigningKeyFromSecretStorage = await this.secretStorage.get("m.cross_signing.user_signing"); + const privateKeysInSecretStorage = Boolean( + masterKeyFromSecretStorage && selfSigningKeyFromSecretStorage && userSigningKeyFromSecretStorage, + ); + const olmDeviceHasKeys = olmDeviceStatus.hasMaster && olmDeviceStatus.hasUserSigning && olmDeviceStatus.hasSelfSigning; @@ -67,7 +80,23 @@ export class CrossSigningIdentity { "bootStrapCrossSigning: Cross-signing private keys not found locally, but they are available " + "in secret storage, reading storage and caching locally", ); - throw new Error("TODO"); + await this.olmMachine.importCrossSigningKeys( + masterKeyFromSecretStorage, + selfSigningKeyFromSecretStorage, + userSigningKeyFromSecretStorage, + ); + + // Get the current device + const device: RustSdkCryptoJs.Device = await this.olmMachine.getDevice( + this.olmMachine.userId, + this.olmMachine.deviceId, + ); + + // Sign the device with our cross-signing key and upload the signature + const request: RustSdkCryptoJs.SignatureUploadRequest = await device.verify(); + await this.outgoingRequestProcessor.makeOutgoingRequest(request); + + this.onCrossSigningKeysImport(); } // TODO: we might previously have bootstrapped cross-signing but not completed uploading the keys to the diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 7e267071b4b..f0404d5c0c2 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -108,7 +108,17 @@ export class RustCrypto extends TypedEventEmitter { + this.emit(CryptoEvent.UserTrustStatusChanged, this.userId, this.checkUserTrust(this.userId)); + }; + this.crossSigningIdentity = new CrossSigningIdentity( + olmMachine, + this.outgoingRequestProcessor, + secretStorage, + onCrossSigningKeysImport, + ); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -194,6 +204,20 @@ export class RustCrypto extends TypedEventEmitter { + return; + } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // CryptoApi implementation @@ -1019,11 +1043,16 @@ class EventDecryptor { } } -type RustCryptoEvents = CryptoEvent.VerificationRequestReceived; +type RustCryptoEvents = CryptoEvent.VerificationRequestReceived | CryptoEvent.UserTrustStatusChanged; type RustCryptoEventMap = { /** * Fires when a key verification request is received. */ [CryptoEvent.VerificationRequestReceived]: (request: VerificationRequest) => void; + + /** + * Fires when the cross signing keys are imported during {@link CryptoApi#bootstrapCrossSigning} + */ + [CryptoEvent.UserTrustStatusChanged]: (userId: string, userTrustLevel: UserTrustLevel) => void; }; From 0cf056958b3812165c0578f7d7847f5e091b19f3 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 25 Jul 2023 20:48:15 +0100 Subject: [PATCH 58/59] Fix broken unit tests for `FetchHttpApi.getUrl` (#3620) These tests have broken on Node.js 18.17.0. This is due to Node.js adopting an updated version of the URL parser, in which the internal `Symbol(query)` property is populated lazily. We shouldn't be relying on the internal state of the URL object anyway. Let's just compare the stringified copy. --- spec/unit/http-api/fetch.spec.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/unit/http-api/fetch.spec.ts b/spec/unit/http-api/fetch.spec.ts index 2cb5f4dd3af..434d507dafc 100644 --- a/spec/unit/http-api/fetch.spec.ts +++ b/spec/unit/http-api/fetch.spec.ts @@ -277,11 +277,13 @@ describe("FetchHttpApi", () => { ]; const runTests = (fetchBaseUrl: string) => { it.each(testCases)( - "creates url with params %s", - ({ path, queryParams, prefix, baseUrl }, result) => { + "creates url with params %s => %s", + ({ path, queryParams, prefix, baseUrl }, expected) => { const api = makeApi(fetchBaseUrl); - expect(api.getUrl(path, queryParams, prefix, baseUrl)).toEqual(new URL(result)); + const result = api.getUrl(path, queryParams, prefix, baseUrl); + // we only check the stringified URL, to avoid having the test depend on the internals of URL. + expect(result.toString()).toEqual(expected); }, ); }; From 29b815b6781d69620613f6a17e92a2d1de655220 Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 25 Jul 2023 22:42:41 +0200 Subject: [PATCH 59/59] Replace deprecated TestClient with fetchMock (#3550) * replace deprecated TestClient with fetchMock * add stop() api to BackupManager for clean shutdown * fix merge * code review cleaning * lint * Address review comments * Remove unused `TestClient.expectKeyBackupQuery` * clean up imports --------- Co-authored-by: Richard van der Hoff Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- spec/TestClient.ts | 17 --- spec/integ/crypto/megolm-backup.spec.ts | 160 +++++++++++++----------- 2 files changed, 87 insertions(+), 90 deletions(-) diff --git a/spec/TestClient.ts b/spec/TestClient.ts index 0ac9f8c8e1a..0a3d25425e3 100644 --- a/spec/TestClient.ts +++ b/spec/TestClient.ts @@ -32,8 +32,6 @@ import { syncPromise } from "./test-utils/test-utils"; import { createClient, IStartClientOpts } from "../src/matrix"; import { ICreateClientOpts, IDownloadKeyResult, MatrixClient, PendingEventOrdering } from "../src/client"; import { MockStorageApi } from "./MockStorageApi"; -import { encodeUri } from "../src/utils"; -import { IKeyBackupSession } from "../src/crypto/keybackup"; import { IKeysUploadResponse, IUploadKeysRequest } from "../src/client"; import { ISyncResponder } from "./test-utils/SyncResponder"; @@ -214,21 +212,6 @@ export class TestClient implements IE2EKeyReceiver, ISyncResponder { }); } - /** - * Set up expectations that the client will query key backups for a particular session - */ - public expectKeyBackupQuery(roomId: string, sessionId: string, status: number, response: IKeyBackupSession) { - this.httpBackend - .when( - "GET", - encodeUri("/room_keys/keys/$roomId/$sessionId", { - $roomId: roomId, - $sessionId: sessionId, - }), - ) - .respond(status, response); - } - /** * get the uploaded curve25519 device key * diff --git a/spec/integ/crypto/megolm-backup.spec.ts b/spec/integ/crypto/megolm-backup.spec.ts index 58adcbfc38f..1e956b52e61 100644 --- a/spec/integ/crypto/megolm-backup.spec.ts +++ b/spec/integ/crypto/megolm-backup.spec.ts @@ -14,17 +14,24 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Account } from "@matrix-org/olm"; +import fetchMock from "fetch-mock-jest"; import { logger } from "../../../src/logger"; import { decodeRecoveryKey } from "../../../src/crypto/recoverykey"; import { IKeyBackupInfo, IKeyBackupSession } from "../../../src/crypto/keybackup"; -import { TestClient } from "../../TestClient"; -import { IEvent } from "../../../src"; -import { MatrixEvent, MatrixEventEvent } from "../../../src/models/event"; +import { createClient, ICreateClientOpts, IEvent, MatrixClient } from "../../../src"; +import { MatrixEventEvent } from "../../../src/models/event"; +import { SyncResponder } from "../../test-utils/SyncResponder"; +import { E2EKeyReceiver } from "../../test-utils/E2EKeyReceiver"; +import { E2EKeyResponder } from "../../test-utils/E2EKeyResponder"; +import { mockInitialApiRequests } from "../../test-utils/mockEndpoints"; +import { syncPromise } from "../../test-utils/test-utils"; const ROOM_ID = "!ROOM:ID"; +/** The homeserver url that we give to the test client, and where we intercept /sync, /keys, etc requests. */ +const TEST_HOMESERVER_URL = "https://alice-server.com"; + const SESSION_ID = "o+21hSjP+mgEmcfdslPsQdvzWnkdt0Wyo00Kp++R8Kc"; const ENCRYPTED_EVENT: Partial = { @@ -70,57 +77,65 @@ const CURVE25519_BACKUP_INFO: IKeyBackupInfo = { version: "1", auth_data: { public_key: "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo", + // Will be updated with correct value on the fly + signatures: {}, }, }; const RECOVERY_KEY = "EsTc LW2K PGiF wKEA 3As5 g5c4 BXwk qeeJ ZJV8 Q9fu gUMN UE4d"; -/** - * start an Olm session with a given recipient - */ -function createOlmSession(olmAccount: Olm.Account, recipientTestClient: TestClient): Promise { - return recipientTestClient.awaitOneTimeKeyUpload().then((keys) => { - const otkId = Object.keys(keys)[0]; - const otk = keys[otkId]; - - const session = new global.Olm.Session(); - session.create_outbound(olmAccount, recipientTestClient.getDeviceKey(), otk.key); - return session; - }); -} +const TEST_USER_ID = "@alice:localhost"; +const TEST_DEVICE_ID = "xzcvb"; describe("megolm key backups", function () { - if (!global.Olm) { - logger.warn("not running megolm tests: Olm not present"); - return; - } - const Olm = global.Olm; - let testOlmAccount: Olm.Account; - let aliceTestClient: TestClient; - - const setupTestClient = (): [Account, TestClient] => { - const aliceTestClient = new TestClient("@alice:localhost", "xzcvb", "akjgkrgjs"); - const testOlmAccount = new Olm.Account(); - testOlmAccount!.create(); + let aliceClient: MatrixClient; + /** an object which intercepts `/sync` requests on the test homeserver */ + let syncResponder: SyncResponder; + + /** an object which intercepts `/keys/upload` requests on the test homeserver */ + let e2eKeyReceiver: E2EKeyReceiver; + /** an object which intercepts `/keys/query` requests on the test homeserver */ + let e2eKeyResponder: E2EKeyResponder; + + jest.useFakeTimers(); + + beforeEach(async () => { + // anything that we don't have a specific matcher for silently returns a 404 + fetchMock.catch(404); + fetchMock.config.warnOnFallback = false; + + mockInitialApiRequests(TEST_HOMESERVER_URL); + syncResponder = new SyncResponder(TEST_HOMESERVER_URL); + e2eKeyReceiver = new E2EKeyReceiver(TEST_HOMESERVER_URL); + e2eKeyResponder = new E2EKeyResponder(TEST_HOMESERVER_URL); + e2eKeyResponder.addKeyReceiver(TEST_USER_ID, e2eKeyReceiver); + }); - return [testOlmAccount, aliceTestClient]; - }; + afterEach(async () => { + if (aliceClient !== undefined) { + await aliceClient.stopClient(); + } - beforeAll(function () { - return Olm.init(); - }); + // Allow in-flight things to complete before we tear down the test + await jest.runAllTimersAsync(); - beforeEach(async function () { - [testOlmAccount, aliceTestClient] = setupTestClient(); - await aliceTestClient!.client.initCrypto(); - aliceTestClient!.client.crypto!.backupManager.backupInfo = CURVE25519_BACKUP_INFO; + fetchMock.mockReset(); }); - afterEach(function () { - return aliceTestClient!.stop(); - }); + async function initTestClient(opts: Partial = {}): Promise { + const client = createClient({ + baseUrl: TEST_HOMESERVER_URL, + userId: TEST_USER_ID, + accessToken: "akjgkrgjs", + deviceId: TEST_DEVICE_ID, + ...opts, + }); + await client.initCrypto(); + + return client; + } - it("Alice checks key backups when receiving a message she can't decrypt", function () { + it("Alice checks key backups when receiving a message she can't decrypt", async function () { const syncResponse = { next_batch: 1, rooms: { @@ -134,37 +149,36 @@ describe("megolm key backups", function () { }, }; - return aliceTestClient! - .start() - .then(() => { - return createOlmSession(testOlmAccount, aliceTestClient); - }) - .then(() => { - const privkey = decodeRecoveryKey(RECOVERY_KEY); - return aliceTestClient!.client!.crypto!.storeSessionBackupPrivateKey(privkey); - }) - .then(() => { - aliceTestClient!.httpBackend.when("GET", "/sync").respond(200, syncResponse); - aliceTestClient!.expectKeyBackupQuery(ROOM_ID, SESSION_ID, 200, CURVE25519_KEY_BACKUP_DATA); - return aliceTestClient!.httpBackend.flushAllExpected(); - }) - .then(function (): Promise { - const room = aliceTestClient!.client.getRoom(ROOM_ID)!; - const event = room.getLiveTimeline().getEvents()[0]; - - if (event.getContent()) { - return Promise.resolve(event); - } - - return new Promise((resolve, reject) => { - event.once(MatrixEventEvent.Decrypted, (ev) => { - logger.log(`${Date.now()} event ${event.getId()} now decrypted`); - resolve(ev); - }); - }); - }) - .then((event) => { - expect(event.getContent()).toEqual("testytest"); + fetchMock.get("express:/_matrix/client/v3/room_keys/keys/:room_id/:session_id", CURVE25519_KEY_BACKUP_DATA); + + // mock for the outgoing key requests that will be sent + fetchMock.put("express:/_matrix/client/r0/sendToDevice/m.room_key_request/:txid", {}); + + // We'll need to add a signature to the backup data, so take a copy to avoid mutating global state. + const backupData = JSON.parse(JSON.stringify(CURVE25519_BACKUP_INFO)); + fetchMock.get("path:/_matrix/client/v3/room_keys/version", backupData); + + aliceClient = await initTestClient(); + await aliceClient.crypto!.signObject(backupData.auth_data); + await aliceClient.crypto!.storeSessionBackupPrivateKey(decodeRecoveryKey(RECOVERY_KEY)); + await aliceClient.crypto!.backupManager!.checkAndStart(); + + // start after saving the private key + await aliceClient.startClient(); + + syncResponder.sendOrQueueSyncResponse(syncResponse); + await syncPromise(aliceClient); + + const room = aliceClient.getRoom(ROOM_ID)!; + + const event = room.getLiveTimeline().getEvents()[0]; + await new Promise((resolve, reject) => { + event.once(MatrixEventEvent.Decrypted, (ev) => { + logger.log(`${Date.now()} event ${event.getId()} now decrypted`); + resolve(ev); }); + }); + + expect(event.getContent()).toEqual("testytest"); }); });