From d7640d9e158c660e84ac98d671e1738d4a473894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 1 Sep 2021 18:08:59 +0200 Subject: [PATCH 01/47] Don't use a callback in setScreensharingEnabled() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/webrtc/call.ts | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index 2d29a6c8d..a25063177 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -784,12 +784,11 @@ export class MatrixCall extends EventEmitter { /** * Starts/stops screensharing * @param enabled the desired screensharing state - * @param selectDesktopCapturerSource callBack to select a screensharing stream on desktop + * @param desktopCapturerSource optional desktop capturer source to use * @returns {boolean} new screensharing state */ public async setScreensharingEnabled( - enabled: boolean, - selectDesktopCapturerSource?: () => Promise, + enabled: boolean, desktopCapturerSource?: DesktopCapturerSource, ): Promise { // Skip if there is nothing to do if (enabled && this.isScreensharing()) { @@ -802,13 +801,13 @@ export class MatrixCall extends EventEmitter { // Fallback to replaceTrack() if (!this.opponentSupportsSDPStreamMetadata()) { - return await this.setScreensharingEnabledWithoutMetadataSupport(enabled, selectDesktopCapturerSource); + return await this.setScreensharingEnabledWithoutMetadataSupport(enabled, desktopCapturerSource); } logger.debug(`Set screensharing enabled? ${enabled}`); if (enabled) { try { - const stream = await getScreensharingStream(selectDesktopCapturerSource); + const stream = await getScreensharingStream(desktopCapturerSource); if (!stream) return false; this.pushLocalFeed(stream, SDPStreamMetadataPurpose.Screenshare); return true; @@ -834,17 +833,16 @@ export class MatrixCall extends EventEmitter { * Starts/stops screensharing * Should be used ONLY if the opponent doesn't support SDPStreamMetadata * @param enabled the desired screensharing state - * @param selectDesktopCapturerSource callBack to select a screensharing stream on desktop + * @param desktopCapturerSource optional desktop capturer source to use * @returns {boolean} new screensharing state */ private async setScreensharingEnabledWithoutMetadataSupport( - enabled: boolean, - selectDesktopCapturerSource?: () => Promise, + enabled: boolean, desktopCapturerSource?: DesktopCapturerSource, ): Promise { logger.debug(`Set screensharing enabled? ${enabled} using replaceTrack()`); if (enabled) { try { - const stream = await getScreensharingStream(selectDesktopCapturerSource); + const stream = await getScreensharingStream(desktopCapturerSource); if (!stream) return false; const track = stream.getTracks().find((track) => { @@ -1926,13 +1924,11 @@ export class MatrixCall extends EventEmitter { } } -async function getScreensharingStream( - selectDesktopCapturerSource?: () => Promise, -): Promise { - const screenshareConstraints = await getScreenshareContraints(selectDesktopCapturerSource); +async function getScreensharingStream(desktopCapturerSource: DesktopCapturerSource): Promise { + const screenshareConstraints = getScreenshareContraints(desktopCapturerSource); if (!screenshareConstraints) return null; - if (window.electron?.getDesktopCapturerSources) { + if (desktopCapturerSource) { // We are using Electron logger.debug("Getting screen stream using getUserMedia()..."); return await navigator.mediaDevices.getUserMedia(screenshareConstraints); @@ -1980,27 +1976,20 @@ function getUserMediaContraints(type: ConstraintsType): MediaStreamConstraints { } } -async function getScreenshareContraints( - selectDesktopCapturerSource?: () => Promise, -): Promise { - if (window.electron?.getDesktopCapturerSources && selectDesktopCapturerSource) { - // We have access to getDesktopCapturerSources() - logger.debug("Electron getDesktopCapturerSources() is available..."); - const selectedSource = await selectDesktopCapturerSource(); - if (!selectedSource) return null; +function getScreenshareContraints(desktopCapturerSource?: DesktopCapturerSource): DesktopCapturerConstraints { + if (desktopCapturerSource) { + logger.debug("Using desktop capturer source", desktopCapturerSource); return { audio: false, video: { mandatory: { chromeMediaSource: "desktop", - chromeMediaSourceId: selectedSource.id, + chromeMediaSourceId: desktopCapturerSource.id, }, }, }; } else { - // We do not have access to the Electron desktop capturer, - // therefore we can assume we are on the web - logger.debug("Electron desktopCapturer is not available..."); + logger.debug("Not using desktop capturer source"); return { audio: false, video: true, From 13c664ad348c46d5a8268eae7c18016acbad6ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 1 Sep 2021 18:17:27 +0200 Subject: [PATCH 02/47] Remove Element-specifc screen-sharing code out of the js-sdk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/@types/global.d.ts | 14 -------------- src/webrtc/call.ts | 15 --------------- 2 files changed, 29 deletions(-) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 949630896..30f73b8c8 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -33,14 +33,9 @@ declare global { } interface Window { - electron?: Electron; webkitAudioContext: typeof AudioContext; } - interface Electron { - getDesktopCapturerSources(options: GetSourcesOptions): Promise>; - } - interface Crypto { webkitSubtle?: Window["crypto"]["subtle"]; } @@ -73,15 +68,6 @@ declare global { thumbnailURL: string; } - interface GetSourcesOptions { - types: Array; - thumbnailSize?: { - height: number; - width: number; - }; - fetchWindowIcons?: boolean; - } - interface HTMLAudioElement { // sinkId & setSinkId are experimental and typescript doesn't know about them sinkId: string; diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index a25063177..a3b657faf 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -226,21 +226,6 @@ const FALLBACK_ICE_SERVER = 'stun:turn.matrix.org'; /** The length of time a call can be ringing for. */ const CALL_TIMEOUT_MS = 60000; -/** Retrieves sources from desktopCapturer */ -export function getDesktopCapturerSources(): Promise> { - const options: GetSourcesOptions = { - thumbnailSize: { - height: 176, - width: 312, - }, - types: [ - "screen", - "window", - ], - }; - return window.electron.getDesktopCapturerSources(options); -} - export class CallError extends Error { code: string; From 9431a52abe96b8a6d36aa4d8cab8dc4659435171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 1 Sep 2021 18:22:04 +0200 Subject: [PATCH 03/47] Move DesktopCapturerSource out of global.d.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/@types/global.d.ts | 6 ------ src/webrtc/call.ts | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 30f73b8c8..2feaa748f 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -62,12 +62,6 @@ declare global { }; } - interface DesktopCapturerSource { - id: string; - name: string; - thumbnailURL: string; - } - interface HTMLAudioElement { // sinkId & setSinkId are experimental and typescript doesn't know about them sinkId: string; diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index a3b657faf..805d9fd04 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -84,6 +84,12 @@ interface AssertedIdentity { displayName: string; } +export interface DesktopCapturerSource { + id: string; + name: string; + thumbnailURL: string; +} + export enum CallState { Fledgling = 'fledgling', InviteSent = 'invite_sent', From cae03817cb461b171c5927a33ac560d764f8e371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 2 Sep 2021 14:10:43 +0200 Subject: [PATCH 04/47] Use source id directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/webrtc/call.ts | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index 805d9fd04..d998fd535 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -84,12 +84,6 @@ interface AssertedIdentity { displayName: string; } -export interface DesktopCapturerSource { - id: string; - name: string; - thumbnailURL: string; -} - export enum CallState { Fledgling = 'fledgling', InviteSent = 'invite_sent', @@ -775,11 +769,11 @@ export class MatrixCall extends EventEmitter { /** * Starts/stops screensharing * @param enabled the desired screensharing state - * @param desktopCapturerSource optional desktop capturer source to use + * @param {string} desktopCapturerSourceId optional id of the desktop capturer source to use * @returns {boolean} new screensharing state */ public async setScreensharingEnabled( - enabled: boolean, desktopCapturerSource?: DesktopCapturerSource, + enabled: boolean, desktopCapturerSourceId?: string, ): Promise { // Skip if there is nothing to do if (enabled && this.isScreensharing()) { @@ -792,13 +786,13 @@ export class MatrixCall extends EventEmitter { // Fallback to replaceTrack() if (!this.opponentSupportsSDPStreamMetadata()) { - return await this.setScreensharingEnabledWithoutMetadataSupport(enabled, desktopCapturerSource); + return await this.setScreensharingEnabledWithoutMetadataSupport(enabled, desktopCapturerSourceId); } logger.debug(`Set screensharing enabled? ${enabled}`); if (enabled) { try { - const stream = await getScreensharingStream(desktopCapturerSource); + const stream = await getScreensharingStream(desktopCapturerSourceId); if (!stream) return false; this.pushLocalFeed(stream, SDPStreamMetadataPurpose.Screenshare); return true; @@ -824,16 +818,16 @@ export class MatrixCall extends EventEmitter { * Starts/stops screensharing * Should be used ONLY if the opponent doesn't support SDPStreamMetadata * @param enabled the desired screensharing state - * @param desktopCapturerSource optional desktop capturer source to use + * @param {string} desktopCapturerSourceId optional id of the desktop capturer source to use * @returns {boolean} new screensharing state */ private async setScreensharingEnabledWithoutMetadataSupport( - enabled: boolean, desktopCapturerSource?: DesktopCapturerSource, + enabled: boolean, desktopCapturerSourceId?: string, ): Promise { logger.debug(`Set screensharing enabled? ${enabled} using replaceTrack()`); if (enabled) { try { - const stream = await getScreensharingStream(desktopCapturerSource); + const stream = await getScreensharingStream(desktopCapturerSourceId); if (!stream) return false; const track = stream.getTracks().find((track) => { @@ -1915,11 +1909,11 @@ export class MatrixCall extends EventEmitter { } } -async function getScreensharingStream(desktopCapturerSource: DesktopCapturerSource): Promise { - const screenshareConstraints = getScreenshareContraints(desktopCapturerSource); +async function getScreensharingStream(desktopCapturerSourceId: string): Promise { + const screenshareConstraints = getScreenshareContraints(desktopCapturerSourceId); if (!screenshareConstraints) return null; - if (desktopCapturerSource) { + if (desktopCapturerSourceId) { // We are using Electron logger.debug("Getting screen stream using getUserMedia()..."); return await navigator.mediaDevices.getUserMedia(screenshareConstraints); @@ -1967,15 +1961,15 @@ function getUserMediaContraints(type: ConstraintsType): MediaStreamConstraints { } } -function getScreenshareContraints(desktopCapturerSource?: DesktopCapturerSource): DesktopCapturerConstraints { - if (desktopCapturerSource) { - logger.debug("Using desktop capturer source", desktopCapturerSource); +function getScreenshareContraints(desktopCapturerSourceId?: string): DesktopCapturerConstraints { + if (desktopCapturerSourceId) { + logger.debug("Using desktop capturer source", desktopCapturerSourceId); return { audio: false, video: { mandatory: { chromeMediaSource: "desktop", - chromeMediaSourceId: desktopCapturerSource.id, + chromeMediaSourceId: desktopCapturerSourceId, }, }, }; From 2a5f6a7b3d31cbc5c63d54538ce0a5e1b0dd0bd3 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 2 Sep 2021 14:14:30 +0100 Subject: [PATCH 05/47] Move all relations event in thread timeline If an event is related to another event who's in a thread, we want to make sure to move that event to the thread's timeline --- src/sync.ts | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/sync.ts b/src/sync.ts index 29e25765f..c2ca30e23 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -315,7 +315,9 @@ export class SyncApi { public partitionThreadedEvents(events: MatrixEvent[]): [MatrixEvent[], MatrixEvent[]] { if (this.opts.experimentalThreadSupport) { return events.reduce((memo, event: MatrixEvent) => { - memo[event.replyInThread ? 1 : 0].push(event); + const room = this.client.getRoom(event.getRoomId()); + const eventInThread = this.shouldLiveInThreadTimeline(event, room); + memo[eventInThread ? 1 : 0].push(event); return memo; }, [[], []]); } else { @@ -328,6 +330,50 @@ export class SyncApi { } } + /** + * @experimental + * An event should live in a thread if it's a threaded reply + * Or if it's related to an event that is a threaded reply + * Things like annotations, redactions, ... + */ + private shouldLiveInThreadTimeline(event: MatrixEvent, room: Room): boolean { + let isThreadReply = event.replyInThread; + + // If the message is sent from a client that does not support threads + // The relation body will not contain `UNSTABLE_ELEMENT_REPLY_IN_THREAD` + // We go up the reply chain looking for an event that has this property + // If we find one, we then decide to render this reply inside the thread + if (!isThreadReply && event.replyEventId) { + isThreadReply = this.ancestorInThread(event, room); + } + + let isRelatedToThreadReply = false; + const relationEventId = event.getRelation()?.event_id; + if (relationEventId) { + const relatedEvent = room.findEventById(relationEventId); + isRelatedToThreadReply = relatedEvent.replyInThread; + } + + return isThreadReply || isRelatedToThreadReply; + } + + /** + * @experimental + * Checks whether an event up in the reply chain has + * the `UNSTABLE_ELEMENT_REPLY_IN_THREAD` property in its + * relations body + */ + private ancestorInThread(event: MatrixEvent, room: Room): boolean { + const relatedEvent = room.findEventById(event.replyEventId); + if (relatedEvent.replyInThread) { + return true; + } else if (relatedEvent.replyEventId) { + return this.ancestorInThread(relatedEvent, room); + } else { + return false; + } + } + /** * Peek into a room. This will result in the room in question being synced so it * is accessible via getRooms(). Live updates for the room will be provided. From d89f4a74f9914df909beebd1334167fca45247eb Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 7 Sep 2021 10:17:24 +0100 Subject: [PATCH 06/47] Fix replyInThread getter to match event m.in_reply_to structure --- src/models/event.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/models/event.ts b/src/models/event.ts index 983cb15d8..929ff12f5 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -412,9 +412,11 @@ export class MatrixEvent extends EventEmitter { * or in the main room timeline */ public get replyInThread(): boolean { - const relations = this.getWireContent()["m.relates_to"]; + const replyTo = this.getWireContent() + ?.["m.relates_to"] + ?.["m.in_reply_to"]; return this.replyEventId - && relations[UNSTABLE_ELEMENT_REPLY_IN_THREAD.name]; + && replyTo[UNSTABLE_ELEMENT_REPLY_IN_THREAD.name]; } /** From e87399c4a134312a506de2af89b031059237d65a Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 7 Sep 2021 18:20:06 +0100 Subject: [PATCH 07/47] Prepare changelog for v12.5.0-rc.1 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5621e0f25..6241a4c26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +Changes in [12.5.0-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v12.5.0-rc.1) (2021-09-07) +============================================================================================================= + +## ✨ Features + * Give `MatrixCall` the capability to emit `LengthChanged` events ([\#1873](https://github.com/matrix-org/matrix-js-sdk/pull/1873)). Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Improve browser example ([\#1875](https://github.com/matrix-org/matrix-js-sdk/pull/1875)). Contributed by [psrpinto](https://github.com/psrpinto). + * Give `CallFeed` the capability to emit on volume changes ([\#1865](https://github.com/matrix-org/matrix-js-sdk/pull/1865)). Contributed by [SimonBrandner](https://github.com/SimonBrandner). + +## 🐛 Bug Fixes + * Fix verification request cancellation ([\#1871](https://github.com/matrix-org/matrix-js-sdk/pull/1871)). + Changes in [12.4.0](https://github.com/vector-im/element-desktop/releases/tag/v12.4.0) (2021-08-31) =================================================================================================== From 341e936082197e13ced72ebb6e556e24a0f0d962 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 7 Sep 2021 18:20:07 +0100 Subject: [PATCH 08/47] v12.5.0-rc.1 --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 6d7091a84..009ebd053 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "12.4.0", + "version": "12.5.0-rc.1", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build", @@ -29,7 +29,7 @@ "keywords": [ "matrix-org" ], - "main": "./src/index.ts", + "main": "./lib/index.js", "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.js", @@ -112,5 +112,6 @@ "coverageReporters": [ "text" ] - } + }, + "typings": "./lib/index.d.ts" } From 7911e6371a08c26cb9b40aae6f88a7e7e94599c1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 8 Sep 2021 11:34:01 -0600 Subject: [PATCH 09/47] Exclude opt-in Element performance metrics from encryption This is needed for the system which is meant to be monitoring this metadata. See https://github.com/matrix-org/matrix-react-sdk/pull/6766 --- src/crypto/index.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/crypto/index.ts b/src/crypto/index.ts index ea627dddf..624a63f5d 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -2757,12 +2757,22 @@ export class Crypto extends EventEmitter { delete content['m.relates_to']; } + // Treat element's performance metrics the same as `m.relates_to` (when present) + const elementPerfMetrics = content['io.element.performance_metrics']; + if (elementPerfMetrics) { + content = Object.assign({}, content); + delete content['io.element.performance_metrics']; + } + const encryptedContent = await alg.encryptMessage( room, event.getType(), content); if (mRelatesTo) { encryptedContent['m.relates_to'] = mRelatesTo; } + if (elementPerfMetrics) { + encryptedContent['io.element.performance_metrics'] = elementPerfMetrics; + } event.makeEncrypted( "m.room.encrypted", From b52f3b1c57e8906c561b6ae15ccebd1a2d7e3b84 Mon Sep 17 00:00:00 2001 From: Robert Long Date: Thu, 9 Sep 2021 17:00:45 -0700 Subject: [PATCH 10/47] Add types for the MatrixClient register method --- src/client.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client.ts b/src/client.ts index 894c5a09d..a1ac2685a 100644 --- a/src/client.ts +++ b/src/client.ts @@ -6107,17 +6107,17 @@ export class MatrixClient extends EventEmitter { public register( username: string, password: string, - sessionId: string, - auth: any, - bindThreepids: any, - guestAccessToken: string, - inhibitLogin: boolean, + sessionId: string | null, + auth: { session?: string, type: string }, + bindThreepids?: boolean | null | { email?: boolean | boolean, msisdn?: boolean }, + guestAccessToken?: string, + inhibitLogin?: boolean, callback?: Callback, ): Promise { // TODO: Types (many) // backwards compat if (bindThreepids === true) { bindThreepids = { email: true }; - } else if (bindThreepids === null || bindThreepids === undefined) { + } else if (bindThreepids === null || bindThreepids === undefined || bindThreepids === false) { bindThreepids = {}; } if (typeof inhibitLogin === 'function') { From 3b4dcbb01d2980d9fa92987e5814a464e2f10cc1 Mon Sep 17 00:00:00 2001 From: Robert Long Date: Thu, 9 Sep 2021 17:15:41 -0700 Subject: [PATCH 11/47] Properly dispose of CallFeeds --- src/webrtc/call.ts | 5 +++++ src/webrtc/callFeed.ts | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index 35a7cb970..5673dadef 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -558,6 +558,10 @@ export class MatrixCall extends EventEmitter { } private deleteAllFeeds(): void { + for (const feed of this.feeds) { + feed.dispose(); + } + this.feeds = []; this.emit(CallEvent.FeedsChanged, this.feeds); } @@ -571,6 +575,7 @@ export class MatrixCall extends EventEmitter { return; } + feed.dispose(); this.feeds.splice(this.feeds.indexOf(feed), 1); this.emit(CallEvent.FeedsChanged, this.feeds); } diff --git a/src/webrtc/callFeed.ts b/src/webrtc/callFeed.ts index 6ebadb273..d4287b1de 100644 --- a/src/webrtc/callFeed.ts +++ b/src/webrtc/callFeed.ts @@ -36,6 +36,7 @@ export class CallFeed extends EventEmitter { private frequencyBinCount: Float32Array; private speakingThreshold = SPEAKING_THRESHOLD; private speaking = false; + private volumeLooperTimeout: number; constructor( public stream: MediaStream, @@ -166,7 +167,7 @@ export class CallFeed extends EventEmitter { private volumeLooper(): void { if (!this.analyser) return; - setTimeout(() => { + this.volumeLooperTimeout = setTimeout(() => { if (!this.measuringVolumeActivity) return; this.analyser.getFloatFrequencyData(this.frequencyBinCount); @@ -188,4 +189,8 @@ export class CallFeed extends EventEmitter { this.volumeLooper(); }, POLLING_INTERVAL); } + + public dispose(): void { + clearTimeout(this.volumeLooperTimeout); + } } From f40d0d24c7e0ba9bb7e450698cf276d3e8147d90 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 10 Sep 2021 09:21:25 +0100 Subject: [PATCH 12/47] Move relations and redactions to thread timeline --- src/models/event.ts | 5 ++++ src/models/room.ts | 3 +-- src/models/thread.ts | 4 +++ src/sync.ts | 58 +++++++++----------------------------------- 4 files changed, 22 insertions(+), 48 deletions(-) diff --git a/src/models/event.ts b/src/models/event.ts index 317377b1a..fcbdba3fa 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -420,6 +420,11 @@ export class MatrixEvent extends EventEmitter { || this.thread instanceof Thread; } + public get parentEventId(): string { + return this.replyEventId + || this.getWireContent()["m.relates_to"]?.event_id; + } + /** * Get the previous event content JSON. This will only return something for * state events which exist in the timeline. diff --git a/src/models/room.ts b/src/models/room.ts index ac80d9ceb..41d417417 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -1305,8 +1305,7 @@ export class Room extends EventEmitter { this.handleRemoteEcho(event, existingEvent); } } - - let thread = this.findEventById(event.replyEventId)?.getThread(); + let thread = this.findEventById(event.parentEventId)?.getThread(); if (thread) { thread.addEvent(event); } else { diff --git a/src/models/thread.ts b/src/models/thread.ts index 844fe2210..0415c554a 100644 --- a/src/models/thread.ts +++ b/src/models/thread.ts @@ -149,6 +149,10 @@ export class Thread extends EventEmitter { return this.findEventById(this.root); } + public get roomId(): string { + return this.rootEvent.getRoomId(); + } + /** * The number of messages in the thread */ diff --git a/src/sync.ts b/src/sync.ts index df9842132..0c5a81638 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -316,8 +316,18 @@ export class SyncApi { if (this.opts.experimentalThreadSupport) { return events.reduce((memo, event: MatrixEvent) => { const room = this.client.getRoom(event.getRoomId()); - const eventInThread = this.shouldLiveInThreadTimeline(event, room); - memo[eventInThread ? 1 : 0].push(event); + // An event should live in the thread timeline if + // - It's a reply in thread event + // - It's related to a reply in thread event + let shouldLiveInThreadTimeline = event.replyInThread; + if (!shouldLiveInThreadTimeline) { + const parentEventId = event.getWireContent()["m.relates_to"]?.event_id; + const parentEvent = room?.findEventById(parentEventId) || events.find((mxEv: MatrixEvent) => { + return mxEv.getId() === parentEventId; + }); + shouldLiveInThreadTimeline = parentEvent?.replyInThread; + } + memo[shouldLiveInThreadTimeline ? 1 : 0].push(event); return memo; }, [[], []]); } else { @@ -330,50 +340,6 @@ export class SyncApi { } } - /** - * @experimental - * An event should live in a thread if it's a threaded reply - * Or if it's related to an event that is a threaded reply - * Things like annotations, redactions, ... - */ - private shouldLiveInThreadTimeline(event: MatrixEvent, room: Room): boolean { - let isThreadReply = event.replyInThread; - - // If the message is sent from a client that does not support threads - // The relation body will not contain `UNSTABLE_ELEMENT_REPLY_IN_THREAD` - // We go up the reply chain looking for an event that has this property - // If we find one, we then decide to render this reply inside the thread - if (!isThreadReply && event.replyEventId) { - isThreadReply = this.ancestorInThread(event, room); - } - - let isRelatedToThreadReply = false; - const relationEventId = event.getRelation()?.event_id; - if (relationEventId) { - const relatedEvent = room.findEventById(relationEventId); - isRelatedToThreadReply = relatedEvent.replyInThread; - } - - return isThreadReply || isRelatedToThreadReply; - } - - /** - * @experimental - * Checks whether an event up in the reply chain has - * the `UNSTABLE_ELEMENT_REPLY_IN_THREAD` property in its - * relations body - */ - private ancestorInThread(event: MatrixEvent, room: Room): boolean { - const relatedEvent = room.findEventById(event.replyEventId); - if (relatedEvent.replyInThread) { - return true; - } else if (relatedEvent.replyEventId) { - return this.ancestorInThread(relatedEvent, room); - } else { - return false; - } - } - /** * Peek into a room. This will result in the room in question being synced so it * is accessible via getRooms(). Live updates for the room will be provided. From 9d63a12469c2f4fe86793ba748a9302daf6bb6c6 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 10 Sep 2021 15:31:21 +0100 Subject: [PATCH 13/47] Migrate realtime-callbacks to TypeScript --- ...ime-callbacks.js => realtime-callbacks.ts} | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) rename src/{realtime-callbacks.js => realtime-callbacks.ts} (70%) diff --git a/src/realtime-callbacks.js b/src/realtime-callbacks.ts similarity index 70% rename from src/realtime-callbacks.js rename to src/realtime-callbacks.ts index 5fa2008ca..0ef288407 100644 --- a/src/realtime-callbacks.js +++ b/src/realtime-callbacks.ts @@ -31,17 +31,17 @@ import { logger } from './logger'; const TIMER_CHECK_PERIOD_MS = 1000; // counter, for making up ids to return from setTimeout -let _count = 0; +let count = 0; // the key for our callback with the real global.setTimeout -let _realCallbackKey; +let realCallbackKey; // a sorted list of the callbacks to be run. // each is an object with keys [runAt, func, params, key]. -const _callbackList = []; +const callbackList = []; // var debuglog = logger.log.bind(logger); -const debuglog = function() {}; +const debuglog = function(...params: any[]) {}; /** * Replace the function used by this module to get the current time. @@ -52,10 +52,10 @@ const debuglog = function() {}; * * @internal */ -export function setNow(f) { - _now = f || Date.now; +export function setNow(f: () => number): void { + now = f || Date.now; } -let _now = Date.now; +let now = Date.now; /** * reimplementation of window.setTimeout, which will call the callback if @@ -67,17 +67,16 @@ let _now = Date.now; * @return {Number} an identifier for this callback, which may be passed into * clearTimeout later. */ -export function setTimeout(func, delayMs) { +export function setTimeout(func: (...params: any[]) => void, delayMs: number, ...params: any[]): number { delayMs = delayMs || 0; if (delayMs < 0) { delayMs = 0; } - const params = Array.prototype.slice.call(arguments, 2); - const runAt = _now() + delayMs; - const key = _count++; + const runAt = now() + delayMs; + const key = count++; debuglog("setTimeout: scheduling cb", key, "at", runAt, - "(delay", delayMs, ")"); + "(delay", delayMs, ")"); const data = { runAt: runAt, func: func, @@ -87,13 +86,13 @@ export function setTimeout(func, delayMs) { // figure out where it goes in the list const idx = binarySearch( - _callbackList, function(el) { + callbackList, function(el) { return el.runAt - runAt; }, ); - _callbackList.splice(idx, 0, data); - _scheduleRealCallback(); + callbackList.splice(idx, 0, data); + scheduleRealCallback(); return key; } @@ -103,68 +102,69 @@ export function setTimeout(func, delayMs) { * * @param {Number} key result from an earlier setTimeout call */ -export function clearTimeout(key) { - if (_callbackList.length === 0) { +export function clearTimeout(key: number): void { + if (callbackList.length === 0) { return; } // remove the element from the list let i; - for (i = 0; i < _callbackList.length; i++) { - const cb = _callbackList[i]; + for (i = 0; i < callbackList.length; i++) { + const cb = callbackList[i]; if (cb.key == key) { - _callbackList.splice(i, 1); + callbackList.splice(i, 1); break; } } // iff it was the first one in the list, reschedule our callback. if (i === 0) { - _scheduleRealCallback(); + scheduleRealCallback(); } } -// use the real global.setTimeout to schedule a callback to _runCallbacks. -function _scheduleRealCallback() { - if (_realCallbackKey) { - global.clearTimeout(_realCallbackKey); +// use the real global.setTimeout to schedule a callback to runCallbacks. +function scheduleRealCallback(): void { + if (realCallbackKey) { + global.clearTimeout(realCallbackKey); } - const first = _callbackList[0]; + const first = callbackList[0]; if (!first) { - debuglog("_scheduleRealCallback: no more callbacks, not rescheduling"); + debuglog("scheduleRealCallback: no more callbacks, not rescheduling"); return; } - const now = _now(); - const delayMs = Math.min(first.runAt - now, TIMER_CHECK_PERIOD_MS); + const timestamp = now(); + const delayMs = Math.min(first.runAt - timestamp, TIMER_CHECK_PERIOD_MS); - debuglog("_scheduleRealCallback: now:", now, "delay:", delayMs); - _realCallbackKey = global.setTimeout(_runCallbacks, delayMs); + debuglog("scheduleRealCallback: now:", timestamp, "delay:", delayMs); + realCallbackKey = global.setTimeout(runCallbacks, delayMs); } -function _runCallbacks() { +function runCallbacks(): void { let cb; - const now = _now(); - debuglog("_runCallbacks: now:", now); + const timestamp = now(); + debuglog("runCallbacks: now:", timestamp); // get the list of things to call const callbacksToRun = []; + // eslint-disable-next-line while (true) { - const first = _callbackList[0]; - if (!first || first.runAt > now) { + const first = callbackList[0]; + if (!first || first.runAt > timestamp) { break; } - cb = _callbackList.shift(); - debuglog("_runCallbacks: popping", cb.key); + cb = callbackList.shift(); + debuglog("runCallbacks: popping", cb.key); callbacksToRun.push(cb); } // reschedule the real callback before running our functions, to // keep the codepaths the same whether or not our functions // register their own setTimeouts. - _scheduleRealCallback(); + scheduleRealCallback(); for (let i = 0; i < callbacksToRun.length; i++) { cb = callbacksToRun[i]; @@ -172,7 +172,7 @@ function _runCallbacks() { cb.func.apply(global, cb.params); } catch (e) { logger.error("Uncaught exception in callback function", - e.stack || e); + e.stack || e); } } } @@ -182,7 +182,7 @@ function _runCallbacks() { * returns the index of the last element for which func returns * greater than zero, or array.length if no such element exists. */ -function binarySearch(array, func) { +function binarySearch(array: T[], func: (T) => number): number { // min is inclusive, max exclusive. let min = 0; let max = array.length; From ab906faa1756483d08705c29633a8368c44cf485 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 10 Sep 2021 15:39:36 +0100 Subject: [PATCH 14/47] Migrate errors to TypeScript --- src/{errors.js => errors.ts} | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) rename src/{errors.js => errors.ts} (71%) diff --git a/src/errors.js b/src/errors.ts similarity index 71% rename from src/errors.js rename to src/errors.ts index 186fc6911..324e04c46 100644 --- a/src/errors.js +++ b/src/errors.ts @@ -1,6 +1,6 @@ // can't just do InvalidStoreError extends Error // because of http://babeljs.io/docs/usage/caveats/#classes -export function InvalidStoreError(reason, value) { +export function InvalidStoreError(reason: string, value: boolean): void { const message = `Store is invalid because ${reason}, ` + `please stop the client, delete all data and start the client again`; const instance = Reflect.construct(Error, [message]); @@ -13,16 +13,16 @@ export function InvalidStoreError(reason, value) { InvalidStoreError.TOGGLED_LAZY_LOADING = "TOGGLED_LAZY_LOADING"; InvalidStoreError.prototype = Object.create(Error.prototype, { - constructor: { - value: Error, - enumerable: false, - writable: true, - configurable: true, - }, + constructor: { + value: Error, + enumerable: false, + writable: true, + configurable: true, + }, }); Reflect.setPrototypeOf(InvalidStoreError, Error); -export function InvalidCryptoStoreError(reason) { +export function InvalidCryptoStoreError(reason: string): void { const message = `Crypto store is invalid because ${reason}, ` + `please stop the client, delete all data and start the client again`; const instance = Reflect.construct(Error, [message]); @@ -35,18 +35,17 @@ export function InvalidCryptoStoreError(reason) { InvalidCryptoStoreError.TOO_NEW = "TOO_NEW"; InvalidCryptoStoreError.prototype = Object.create(Error.prototype, { - constructor: { - value: Error, - enumerable: false, - writable: true, - configurable: true, - }, + constructor: { + value: Error, + enumerable: false, + writable: true, + configurable: true, + }, }); Reflect.setPrototypeOf(InvalidCryptoStoreError, Error); export class KeySignatureUploadError extends Error { - constructor(message, value) { - super(message); - this.value = value; - } + constructor(message: string, public value: { failures: any }) { // TODO: types + super(message); + } } From 0722dafe583a28b7ba5690a62af9ed8f16141ac6 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Fri, 10 Sep 2021 16:04:55 +0100 Subject: [PATCH 15/47] Migrate AutoDiscovery to TypeScript --- src/{autodiscovery.js => autodiscovery.ts} | 193 +++++++-------------- 1 file changed, 64 insertions(+), 129 deletions(-) rename src/{autodiscovery.js => autodiscovery.ts} (74%) diff --git a/src/autodiscovery.js b/src/autodiscovery.ts similarity index 74% rename from src/autodiscovery.js rename to src/autodiscovery.ts index 1ccbbaa86..d128377f9 100644 --- a/src/autodiscovery.js +++ b/src/autodiscovery.ts @@ -23,73 +23,26 @@ import { URL as NodeURL } from "url"; // Dev note: Auto discovery is part of the spec. // See: https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery -/** - * Description for what an automatically discovered client configuration - * would look like. Although this is a class, it is recommended that it - * be treated as an interface definition rather than as a class. - * - * Additional properties than those defined here may be present, and - * should follow the Java package naming convention. - */ -class DiscoveredClientConfig { // eslint-disable-line no-unused-vars - // Dev note: this is basically a copy/paste of the .well-known response - // object as defined in the spec. It does have additional information, - // however. Overall, this exists to serve as a place for documentation - // and not functionality. - // See https://matrix.org/docs/spec/client_server/r0.4.0.html#get-well-known-matrix-client +enum AutoDiscoveryAction { + SUCCESS = "SUCCESS", + IGNORE = "IGNORE", + PROMPT = "PROMPT", + FAIL_PROMPT = "FAIL_PROMPT", + FAIL_ERROR = "FAIL_ERROR", +} - constructor() { - /** - * The homeserver configuration the client should use. This will - * always be present on the object. - * @type {{state: string, base_url: string}} The configuration. - */ - this["m.homeserver"] = { - /** - * The lookup result state. If this is anything other than - * AutoDiscovery.SUCCESS then base_url may be falsey. Additionally, - * if this is not AutoDiscovery.SUCCESS then the client should - * assume the other properties in the client config (such as - * the identity server configuration) are not valid. - */ - state: AutoDiscovery.PROMPT, +interface DiscoveredClientConfig { + "m.homeserver"?: WellKnownConfig; + "m.identity_server"?: WellKnownConfig; +} - /** - * If the state is AutoDiscovery.FAIL_ERROR or .FAIL_PROMPT - * then this will contain a human-readable (English) message - * for what went wrong. If the state is none of those previously - * mentioned, this will be falsey. - */ - error: "Something went wrong", - - /** - * The base URL clients should use to talk to the homeserver, - * particularly for the login process. May be falsey if the - * state is not AutoDiscovery.SUCCESS. - */ - base_url: "https://matrix.org", - }; - - /** - * The identity server configuration the client should use. This - * will always be present on teh object. - * @type {{state: string, base_url: string}} The configuration. - */ - this["m.identity_server"] = { - /** - * The lookup result state. If this is anything other than - * AutoDiscovery.SUCCESS then base_url may be falsey. - */ - state: AutoDiscovery.PROMPT, - - /** - * The base URL clients should use for interacting with the - * identity server. May be falsey if the state is not - * AutoDiscovery.SUCCESS. - */ - base_url: "https://vector.im", - }; - } +interface WellKnownConfig { + raw?: any; // todo typings + action?: AutoDiscoveryAction; + reason?: string; + error?: Error | string; + // eslint-disable-next-line + base_url?: string | null; } /** @@ -102,55 +55,36 @@ export class AutoDiscovery { // translate the meaning of the states in the spec, but also // support our own if needed. - static get ERROR_INVALID() { - return "Invalid homeserver discovery response"; - } + public static readonly ERROR_INVALID = "Invalid homeserver discovery response"; - static get ERROR_GENERIC_FAILURE() { - return "Failed to get autodiscovery configuration from server"; - } + public static readonly ERROR_GENERIC_FAILURE = "Failed to get autodiscovery configuration from server"; - static get ERROR_INVALID_HS_BASE_URL() { - return "Invalid base_url for m.homeserver"; - } + public static readonly ERROR_INVALID_HS_BASE_URL = "Invalid base_url for m.homeserver"; - static get ERROR_INVALID_HOMESERVER() { - return "Homeserver URL does not appear to be a valid Matrix homeserver"; - } + public static readonly ERROR_INVALID_HOMESERVER = "Homeserver URL does not appear to be a valid Matrix homeserver"; - static get ERROR_INVALID_IS_BASE_URL() { - return "Invalid base_url for m.identity_server"; - } + public static readonly ERROR_INVALID_IS_BASE_URL = "Invalid base_url for m.identity_server"; - static get ERROR_INVALID_IDENTITY_SERVER() { - return "Identity server URL does not appear to be a valid identity server"; - } + // eslint-disable-next-line + public static readonly ERROR_INVALID_IDENTITY_SERVER = "Identity server URL does not appear to be a valid identity server"; - static get ERROR_INVALID_IS() { - return "Invalid identity server discovery response"; - } + public static readonly ERROR_INVALID_IS = "Invalid identity server discovery response"; - static get ERROR_MISSING_WELLKNOWN() { - return "No .well-known JSON file found"; - } + public static readonly ERROR_MISSING_WELLKNOWN = "No .well-known JSON file found"; - static get ERROR_INVALID_JSON() { - return "Invalid JSON"; - } + public static readonly ERROR_INVALID_JSON = "Invalid JSON"; - static get ALL_ERRORS() { - return [ - AutoDiscovery.ERROR_INVALID, - AutoDiscovery.ERROR_GENERIC_FAILURE, - AutoDiscovery.ERROR_INVALID_HS_BASE_URL, - AutoDiscovery.ERROR_INVALID_HOMESERVER, - AutoDiscovery.ERROR_INVALID_IS_BASE_URL, - AutoDiscovery.ERROR_INVALID_IDENTITY_SERVER, - AutoDiscovery.ERROR_INVALID_IS, - AutoDiscovery.ERROR_MISSING_WELLKNOWN, - AutoDiscovery.ERROR_INVALID_JSON, - ]; - } + public static readonly ALL_ERRORS = [ + AutoDiscovery.ERROR_INVALID, + AutoDiscovery.ERROR_GENERIC_FAILURE, + AutoDiscovery.ERROR_INVALID_HS_BASE_URL, + AutoDiscovery.ERROR_INVALID_HOMESERVER, + AutoDiscovery.ERROR_INVALID_IS_BASE_URL, + AutoDiscovery.ERROR_INVALID_IDENTITY_SERVER, + AutoDiscovery.ERROR_INVALID_IS, + AutoDiscovery.ERROR_MISSING_WELLKNOWN, + AutoDiscovery.ERROR_INVALID_JSON, + ]; /** * The auto discovery failed. The client is expected to communicate @@ -158,7 +92,7 @@ export class AutoDiscovery { * @return {string} * @constructor */ - static get FAIL_ERROR() { return "FAIL_ERROR"; } + public static readonly FAIL_ERROR = AutoDiscoveryAction.FAIL_ERROR; /** * The auto discovery failed, however the client may still recover @@ -169,7 +103,7 @@ export class AutoDiscovery { * @return {string} * @constructor */ - static get FAIL_PROMPT() { return "FAIL_PROMPT"; } + public static readonly FAIL_PROMPT = AutoDiscoveryAction.FAIL_PROMPT; /** * The auto discovery didn't fail but did not find anything of @@ -178,14 +112,14 @@ export class AutoDiscovery { * @return {string} * @constructor */ - static get PROMPT() { return "PROMPT"; } + public static readonly PROMPT = AutoDiscoveryAction.PROMPT; /** * The auto discovery was successful. * @return {string} * @constructor */ - static get SUCCESS() { return "SUCCESS"; } + public static readonly SUCCESS = AutoDiscoveryAction.SUCCESS; /** * Validates and verifies client configuration information for purposes @@ -199,7 +133,7 @@ export class AutoDiscovery { * configuration, which may include error states. Rejects on unexpected * failure, not when verification fails. */ - static async fromDiscoveryConfig(wellknown) { + public static async fromDiscoveryConfig(wellknown: string): Promise { // Step 1 is to get the config, which is provided to us here. // We default to an error state to make the first few checks easier to @@ -240,7 +174,7 @@ export class AutoDiscovery { // Step 2: Make sure the homeserver URL is valid *looking*. We'll make // sure it points to a homeserver in Step 3. - const hsUrl = this._sanitizeWellKnownUrl( + const hsUrl = this.sanitizeWellKnownUrl( wellknown["m.homeserver"]["base_url"], ); if (!hsUrl) { @@ -250,7 +184,7 @@ export class AutoDiscovery { } // Step 3: Make sure the homeserver URL points to a homeserver. - const hsVersions = await this._fetchWellKnownObject( + const hsVersions = await this.fetchWellKnownObject( `${hsUrl}/_matrix/client/versions`, ); if (!hsVersions || !hsVersions.raw["versions"]) { @@ -272,7 +206,7 @@ export class AutoDiscovery { }; // Step 5: Try to pull out the identity server configuration - let isUrl = ""; + let isUrl: string | boolean = ""; if (wellknown["m.identity_server"]) { // We prepare a failing identity server response to save lines later // in this branch. @@ -287,7 +221,7 @@ export class AutoDiscovery { // Step 5a: Make sure the URL is valid *looking*. We'll make sure it // points to an identity server in Step 5b. - isUrl = this._sanitizeWellKnownUrl( + isUrl = this.sanitizeWellKnownUrl( wellknown["m.identity_server"]["base_url"], ); if (!isUrl) { @@ -299,10 +233,10 @@ export class AutoDiscovery { // Step 5b: Verify there is an identity server listening on the provided // URL. - const isResponse = await this._fetchWellKnownObject( + const isResponse = await this.fetchWellKnownObject( `${isUrl}/_matrix/identity/api/v1`, ); - if (!isResponse || !isResponse.raw || isResponse.action !== "SUCCESS") { + if (!isResponse || !isResponse.raw || isResponse.action !== AutoDiscoveryAction.SUCCESS) { logger.error("Invalid /api/v1 response"); failingClientConfig["m.identity_server"].error = AutoDiscovery.ERROR_INVALID_IDENTITY_SERVER; @@ -317,7 +251,7 @@ export class AutoDiscovery { // Step 6: Now that the identity server is valid, or never existed, // populate the IS section. - if (isUrl && isUrl.length > 0) { + if (isUrl && isUrl.toString().length > 0) { clientConfig["m.identity_server"] = { state: AutoDiscovery.SUCCESS, error: null, @@ -359,7 +293,7 @@ export class AutoDiscovery { * configuration, which may include error states. Rejects on unexpected * failure, not when discovery fails. */ - static async findClientConfig(domain) { + public static async findClientConfig(domain: string): Promise { if (!domain || typeof(domain) !== "string" || domain.length === 0) { throw new Error("'domain' must be a string of non-zero length"); } @@ -395,13 +329,13 @@ export class AutoDiscovery { // Step 1: Actually request the .well-known JSON file and make sure it // at least has a homeserver definition. - const wellknown = await this._fetchWellKnownObject( + const wellknown = await this.fetchWellKnownObject( `https://${domain}/.well-known/matrix/client`, ); - if (!wellknown || wellknown.action !== "SUCCESS") { + if (!wellknown || wellknown.action !== AutoDiscoveryAction.SUCCESS) { logger.error("No response or error when parsing .well-known"); if (wellknown.reason) logger.error(wellknown.reason); - if (wellknown.action === "IGNORE") { + if (wellknown.action === AutoDiscoveryAction.IGNORE) { clientConfig["m.homeserver"] = { state: AutoDiscovery.PROMPT, error: null, @@ -427,12 +361,12 @@ export class AutoDiscovery { * @returns {Promise} Resolves to the domain's client config. Can * be an empty object. */ - static async getRawClientConfig(domain) { + public static async getRawClientConfig(domain: string): Promise { if (!domain || typeof(domain) !== "string" || domain.length === 0) { throw new Error("'domain' must be a string of non-zero length"); } - const response = await this._fetchWellKnownObject( + const response = await this.fetchWellKnownObject( `https://${domain}/.well-known/matrix/client`, ); if (!response) return {}; @@ -447,7 +381,7 @@ export class AutoDiscovery { * @return {string|boolean} The sanitized URL or a falsey value if the URL is invalid. * @private */ - static _sanitizeWellKnownUrl(url) { + private static sanitizeWellKnownUrl(url: string): string | boolean { if (!url) return false; try { @@ -495,8 +429,9 @@ export class AutoDiscovery { * @return {Promise} Resolves to the returned state. * @private */ - static async _fetchWellKnownObject(url) { + private static async fetchWellKnownObject(url: string): Promise { // TODO: TYPES return new Promise(function(resolve, reject) { + // eslint-disable-next-line const request = require("./matrix").getRequest(); if (!request) throw new Error("No request library available"); request( @@ -505,10 +440,10 @@ export class AutoDiscovery { if (err || response && (response.statusCode < 200 || response.statusCode >= 300) ) { - let action = "FAIL_PROMPT"; + let action = AutoDiscoveryAction.FAIL_PROMPT; let reason = (err ? err.message : null) || "General failure"; if (response && response.statusCode === 404) { - action = "IGNORE"; + action = AutoDiscoveryAction.IGNORE; reason = AutoDiscovery.ERROR_MISSING_WELLKNOWN; } resolve({ raw: {}, action: action, reason: reason, error: err }); @@ -516,7 +451,7 @@ export class AutoDiscovery { } try { - resolve({ raw: JSON.parse(body), action: "SUCCESS" }); + resolve({ raw: JSON.parse(body), action: AutoDiscoveryAction.SUCCESS }); } catch (e) { let reason = AutoDiscovery.ERROR_INVALID; if (e.name === "SyntaxError") { @@ -524,7 +459,7 @@ export class AutoDiscovery { } resolve({ raw: {}, - action: "FAIL_PROMPT", + action: AutoDiscoveryAction.FAIL_PROMPT, reason: reason, error: e, }); From cf9fa991d197b8796545a7c03f743bcdac9cdfe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 10 Sep 2021 19:18:19 +0200 Subject: [PATCH 16/47] Add ISasEvent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/crypto/verification/SAS.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/crypto/verification/SAS.ts b/src/crypto/verification/SAS.ts index a7d679787..9ec4756d8 100644 --- a/src/crypto/verification/SAS.ts +++ b/src/crypto/verification/SAS.ts @@ -160,6 +160,13 @@ export interface IGeneratedSas { emoji?: EmojiMapping[]; } +export interface ISasEvent { + sas: IGeneratedSas; + confirm(): Promise; + cancel(): void; + mismatch(): void; +} + function generateSas(sasBytes: number[], methods: string[]): IGeneratedSas { const sas: IGeneratedSas = {}; for (const method of methods) { @@ -232,12 +239,7 @@ export class SAS extends Base { private waitingForAccept: boolean; public ourSASPubKey: string; public theirSASPubKey: string; - public sasEvent: { - sas: IGeneratedSas; - confirm(): Promise; - cancel(): void; - mismatch(): void; - }; + public sasEvent: ISasEvent; // eslint-disable-next-line @typescript-eslint/naming-convention public static get NAME(): string { From 5d1be6e8be462b38190fb22c281ea55613131246 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 10 Sep 2021 14:15:32 -0600 Subject: [PATCH 17/47] Add file locking to MSC3089 branches This isn't hooked up to versioning, yet, but will be eventually. --- src/models/MSC3089Branch.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/models/MSC3089Branch.ts b/src/models/MSC3089Branch.ts index 875f9bd7d..a011cf640 100644 --- a/src/models/MSC3089Branch.ts +++ b/src/models/MSC3089Branch.ts @@ -77,6 +77,26 @@ export class MSC3089Branch { }, this.id); } + /** + * Gets whether or not a file is locked. + * @returns {boolean} True if locked, false otherwise. + */ + public isLocked(): boolean { + return this.indexEvent.getContent()['locked'] || false; + } + + /** + * Sets a file as locked or unlocked. + * @param {boolean} locked True to lock the file, false otherwise. + * @returns {Promise} Resolves when complete. + */ + public async setLocked(locked: boolean): Promise { + await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, { + ...this.indexEvent.getContent(), + locked: locked, + }, this.id); + } + /** * Gets information about the file needed to download it. * @returns {Promise<{info: IEncryptedFile, httpUrl: string}>} Information about the file. From 3a9d5439a24da5c707e7d3e5df203f47ab202f8c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 10 Sep 2021 14:18:11 -0600 Subject: [PATCH 18/47] Add tests --- spec/unit/models/MSC3089Branch.spec.ts | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/spec/unit/models/MSC3089Branch.spec.ts b/spec/unit/models/MSC3089Branch.spec.ts index 72454cc54..4b59f08f1 100644 --- a/spec/unit/models/MSC3089Branch.spec.ts +++ b/spec/unit/models/MSC3089Branch.spec.ts @@ -127,6 +127,45 @@ describe("MSC3089Branch", () => { expect(stateFn).toHaveBeenCalledTimes(1); }); + it('should be unlocked by default', async () => { + indexEvent.getContent = () => ({ active: true }); + + const res = branch.isLocked(); + + expect(res).toEqual(false); + }); + + it('should use lock status from index event', async () => { + indexEvent.getContent = () => ({ active: true, locked: true }); + + const res = branch.isLocked(); + + expect(res).toEqual(true); + }); + + it('should be able to change its locked status', async () => { + const locked = true; + indexEvent.getContent = () => ({ active: true, retained: true }); + const stateFn = jest.fn() + .mockImplementation((roomId: string, eventType: string, content: any, stateKey: string) => { + expect(roomId).toEqual(branchRoomId); + expect(eventType).toEqual(UNSTABLE_MSC3089_BRANCH.unstable); // test that we're definitely using the unstable value + expect(content).toMatchObject({ + retained: true, // canary for copying state + active: true, + locked: locked, + }); + expect(stateKey).toEqual(fileEventId); + + return Promise.resolve(); // return value not used + }); + client.sendStateEvent = stateFn; + + await branch.setLocked(locked); + + expect(stateFn).toHaveBeenCalledTimes(1); + }); + it('should be able to return event information', async () => { const mxcLatter = "example.org/file"; const fileContent = { isFile: "not quite", url: "mxc://" + mxcLatter }; From d9f8710758a56aa7f16880668759f79dc729580b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 10 Sep 2021 14:44:50 -0600 Subject: [PATCH 19/47] Add missing tests for MSC3089 implementation Fixes https://github.com/vector-im/element-web/issues/18461 --- spec/unit/models/MSC3089Branch.spec.ts | 17 +++++++++++ spec/unit/models/MSC3089TreeSpace.spec.ts | 37 +++++++++++++++++++---- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/spec/unit/models/MSC3089Branch.spec.ts b/spec/unit/models/MSC3089Branch.spec.ts index 72454cc54..24ce8f9fc 100644 --- a/spec/unit/models/MSC3089Branch.spec.ts +++ b/spec/unit/models/MSC3089Branch.spec.ts @@ -151,4 +151,21 @@ describe("MSC3089Branch", () => { httpUrl: expect.stringMatching(`.+${mxcLatter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`), }); }); + + it('should be able to return the event object', async () => { + const mxcLatter = "example.org/file"; + const fileContent = { isFile: "not quite", url: "mxc://" + mxcLatter }; + const eventsArr = [ + { getId: () => "$not-file", getContent: () => ({}) }, + { getId: () => fileEventId, getContent: () => ({ file: fileContent }) }, + ]; + client.getEventTimeline = () => Promise.resolve({ + getEvents: () => eventsArr, + }) as any as Promise; // partial + client.decryptEventIfNeeded = () => Promise.resolve(); + + const res = await branch.getFileEvent(); + expect(res).toBeDefined(); + expect(res).toBe(eventsArr[1]); + }); }); diff --git a/spec/unit/models/MSC3089TreeSpace.spec.ts b/spec/unit/models/MSC3089TreeSpace.spec.ts index ae9652e7d..f034ee884 100644 --- a/spec/unit/models/MSC3089TreeSpace.spec.ts +++ b/spec/unit/models/MSC3089TreeSpace.spec.ts @@ -227,40 +227,61 @@ describe("MSC3089TreeSpace", () => { [targetUser]: expectedPl, }, }); + + // Store new power levels so the `getPermissions()` test passes + makePowerLevels(content); + return Promise.resolve(); }); client.sendStateEvent = fn; await tree.setPermissions(targetUser, role); expect(fn.mock.calls.length).toBe(1); + + const finalPermissions = tree.getPermissions(targetUser); + expect(finalPermissions).toEqual(role); } it('should support setting Viewer permissions', () => { return evaluatePowerLevels({ ...DEFAULT_TREE_POWER_LEVELS_TEMPLATE, users_default: 1024, + events_default: 1025, + events: { + [EventType.RoomPowerLevels]: 1026, + }, }, TreePermissions.Viewer, 1024); }); it('should support setting Editor permissions', () => { return evaluatePowerLevels({ ...DEFAULT_TREE_POWER_LEVELS_TEMPLATE, - events_default: 1024, - }, TreePermissions.Editor, 1024); + users_default: 1024, + events_default: 1025, + events: { + [EventType.RoomPowerLevels]: 1026, + }, + }, TreePermissions.Editor, 1025); }); it('should support setting Owner permissions', () => { return evaluatePowerLevels({ ...DEFAULT_TREE_POWER_LEVELS_TEMPLATE, + users_default: 1024, + events_default: 1025, events: { - [EventType.RoomPowerLevels]: 1024, + [EventType.RoomPowerLevels]: 1026, }, - }, TreePermissions.Owner, 1024); + }, TreePermissions.Owner, 1026); }); it('should support demoting permissions', () => { return evaluatePowerLevels({ ...DEFAULT_TREE_POWER_LEVELS_TEMPLATE, users_default: 1024, + events_default: 1025, + events: { + [EventType.RoomPowerLevels]: 1026, + }, users: { [targetUser]: 2222, }, @@ -270,11 +291,15 @@ describe("MSC3089TreeSpace", () => { it('should support promoting permissions', () => { return evaluatePowerLevels({ ...DEFAULT_TREE_POWER_LEVELS_TEMPLATE, - events_default: 1024, + users_default: 1024, + events_default: 1025, + events: { + [EventType.RoomPowerLevels]: 1026, + }, users: { [targetUser]: 5, }, - }, TreePermissions.Editor, 1024); + }, TreePermissions.Editor, 1025); }); it('should support defaults: Viewer', () => { From a1f73eee86aff8b5b3c667573b44942c3c4e23f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 29 Aug 2021 09:27:33 +0200 Subject: [PATCH 20/47] Add MediaHandler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/webrtc/mediaHandler.ts | 115 +++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/webrtc/mediaHandler.ts diff --git a/src/webrtc/mediaHandler.ts b/src/webrtc/mediaHandler.ts new file mode 100644 index 000000000..b41e39ba8 --- /dev/null +++ b/src/webrtc/mediaHandler.ts @@ -0,0 +1,115 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 New Vector Ltd +Copyright 2019, 2020 The Matrix.org Foundation C.I.C. +Copyright 2021 Šimon Brandner + +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 { logger } from "../logger"; + +export class MediaHandler { + private audioInput: string; + private videoInput: string; + + /** + * Set an audio input device to use for MatrixCalls + * @param {string} deviceId the identifier for the device + * undefined treated as unset + */ + public setAudioInput(deviceId: string): void { + this.audioInput = deviceId; + } + + /** + * Set a video input device to use for MatrixCalls + * @param {string} deviceId the identifier for the device + * undefined treated as unset + */ + public setVideoInput(deviceId: string): void { + this.videoInput = deviceId; + } + + /** + * @returns {MediaStream} based on passed parameters + */ + public async getUserMediaStream(audio: boolean, video: boolean): Promise { + const constraints = this.getUserMediaContraints(audio, video); + logger.log("Getting user media with constraints", constraints); + return await navigator.mediaDevices.getUserMedia(constraints); + } + + /** + * @returns {MediaStream} based on passed parameters + */ + public async getScreensharingStream(desktopCapturerSourceId: string): Promise { + const screenshareConstraints = this.getScreenshareContraints(desktopCapturerSourceId); + if (!screenshareConstraints) return null; + + if (desktopCapturerSourceId) { + // We are using Electron + logger.debug("Getting screen stream using getUserMedia()..."); + return await navigator.mediaDevices.getUserMedia(screenshareConstraints); + } else { + // We are not using Electron + logger.debug("Getting screen stream using getDisplayMedia()..."); + return await navigator.mediaDevices.getDisplayMedia(screenshareConstraints); + } + } + + private getUserMediaContraints(audio: boolean, video: boolean): MediaStreamConstraints { + const isWebkit = !!navigator.webkitGetUserMedia; + + return { + audio: audio + ? { + deviceId: this.audioInput ? { ideal: this.audioInput } : undefined, + } + : false, + video: video + ? { + deviceId: this.videoInput ? { ideal: this.videoInput } : undefined, + /* We want 640x360. Chrome will give it only if we ask exactly, + FF refuses entirely if we ask exactly, so have to ask for ideal + instead + XXX: Is this still true? + */ + width: isWebkit ? { exact: 640 } : { ideal: 640 }, + height: isWebkit ? { exact: 360 } : { ideal: 360 }, + } + : false, + }; + } + + private getScreenshareContraints(desktopCapturerSourceId?: string): DesktopCapturerConstraints { + if (desktopCapturerSourceId) { + logger.debug("Using desktop capturer source", desktopCapturerSourceId); + return { + audio: false, + video: { + mandatory: { + chromeMediaSource: "desktop", + chromeMediaSourceId: desktopCapturerSourceId, + }, + }, + }; + } else { + logger.debug("Not using desktop capturer source"); + return { + audio: false, + video: true, + }; + } + } +} From 1bd7de5a183d4ec370025799dbef596e173782ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 29 Aug 2021 09:38:44 +0200 Subject: [PATCH 21/47] Use MediaHandler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/client.ts | 9 ++++ src/matrix.ts | 2 - src/webrtc/call.ts | 132 ++++++++------------------------------------- 3 files changed, 30 insertions(+), 113 deletions(-) diff --git a/src/client.ts b/src/client.ts index 894c5a09d..baeb51735 100644 --- a/src/client.ts +++ b/src/client.ts @@ -144,6 +144,7 @@ import { IHierarchyRoom, ISpaceSummaryEvent, ISpaceSummaryRoom } from "./@types/ import { IPusher, IPusherRequest, IPushRules, PushRuleAction, PushRuleKind, RuleId } from "./@types/PushRules"; import { IThreepid } from "./@types/threepids"; import { CryptoStore } from "./crypto/store/base"; +import { MediaHandler } from "./webrtc/mediaHandler"; export type Store = IStore; export type SessionStore = WebStorageSessionStore; @@ -733,6 +734,7 @@ export class MatrixClient extends EventEmitter { protected checkTurnServersIntervalID: number; protected exportedOlmDeviceToImport: IOlmDevice; protected txnCtr = 0; + protected mediaHandler = new MediaHandler(); constructor(opts: IMatrixClientCreateOpts) { super(); @@ -1240,6 +1242,13 @@ export class MatrixClient extends EventEmitter { return this.canSupportVoip; } + /** + * @returns {MediaHandler} + */ + public getMediaHandler(): MediaHandler { + return this.mediaHandler; + } + /** * Set whether VoIP calls are forced to use only TURN * candidates. This is the same as the forceTURN option diff --git a/src/matrix.ts b/src/matrix.ts index 97709e314..bb6492412 100644 --- a/src/matrix.ts +++ b/src/matrix.ts @@ -49,8 +49,6 @@ export * from "./content-repo"; export * as ContentHelpers from "./content-helpers"; export { createNewMatrixCall, - setAudioInput as setMatrixCallAudioInput, - setVideoInput as setMatrixCallVideoInput, } from "./webrtc/call"; // expose the underlying request object so different environments can use diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index 1cd3d8243..f15300c87 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -212,11 +212,6 @@ export enum CallErrorCode { Transfered = 'transferred', } -enum ConstraintsType { - Audio = "audio", - Video = "video", -} - /** * The version field that we set in m.call.* events */ @@ -337,11 +332,7 @@ export class MatrixCall extends EventEmitter { * @throws If you have not specified a listener for 'error' events. */ public async placeVoiceCall(): Promise { - logger.debug("placeVoiceCall"); - this.checkForErrorListener(); - const constraints = getUserMediaContraints(ConstraintsType.Audio); - this.type = CallType.Voice; - await this.placeCallWithConstraints(constraints); + await this.placeCall(true, false); } /** @@ -349,11 +340,7 @@ export class MatrixCall extends EventEmitter { * @throws If you have not specified a listener for 'error' events. */ public async placeVideoCall(): Promise { - logger.debug("placeVideoCall"); - this.checkForErrorListener(); - const constraints = getUserMediaContraints(ConstraintsType.Video); - this.type = CallType.Video; - await this.placeCallWithConstraints(constraints); + await this.placeCall(true, true); } public getOpponentMember(): RoomMember { @@ -672,17 +659,14 @@ export class MatrixCall extends EventEmitter { logger.debug(`Answering call ${this.callId} of type ${this.type}`); if (!this.localUsermediaStream && !this.waitForLocalAVStream) { - const constraints = getUserMediaContraints( - this.type == CallType.Video ? - ConstraintsType.Video: - ConstraintsType.Audio, - ); - logger.log("Getting user media with constraints", constraints); this.setState(CallState.WaitLocalMedia); this.waitForLocalAVStream = true; try { - const mediaStream = await navigator.mediaDevices.getUserMedia(constraints); + const mediaStream = await this.client.getMediaHandler().getUserMediaStream( + true, + this.type === CallType.Video, + ); this.waitForLocalAVStream = false; this.gotUserMediaForAnswer(mediaStream); } catch (e) { @@ -797,7 +781,7 @@ export class MatrixCall extends EventEmitter { logger.debug(`Set screensharing enabled? ${enabled}`); if (enabled) { try { - const stream = await getScreensharingStream(desktopCapturerSourceId); + const stream = await this.client.getMediaHandler().getScreensharingStream(desktopCapturerSourceId); if (!stream) return false; this.pushLocalFeed(stream, SDPStreamMetadataPurpose.Screenshare); return true; @@ -832,7 +816,7 @@ export class MatrixCall extends EventEmitter { logger.debug(`Set screensharing enabled? ${enabled} using replaceTrack()`); if (enabled) { try { - const stream = await getScreensharingStream(desktopCapturerSourceId); + const stream = await this.client.getMediaHandler().getScreensharingStream(desktopCapturerSourceId); if (!stream) return false; const track = stream.getTracks().find((track) => { @@ -1809,8 +1793,18 @@ export class MatrixCall extends EventEmitter { } } - private async placeCallWithConstraints(constraints: MediaStreamConstraints): Promise { - logger.log("Getting user media with constraints", constraints); + /** + * Place a call to this room. + * @throws if you have not specified a listener for 'error' events. + * @throws if have passed audio=false. + */ + public async placeCall(audio: boolean, video: boolean): Promise { + logger.debug(`placeCall audio=${audio} video=${video}`); + if (!audio) { + throw new Error("You CANNOT start a call without audio"); + } + this.type = video ? CallType.Video : CallType.Voice; + this.checkForErrorListener(); // XXX Find a better way to do this this.client.callEventHandler.calls.set(this.callId, this); this.setState(CallState.WaitLocalMedia); @@ -1828,7 +1822,7 @@ export class MatrixCall extends EventEmitter { this.peerConn = this.createPeerConnection(); try { - const mediaStream = await navigator.mediaDevices.getUserMedia(constraints); + const mediaStream = await this.client.getMediaHandler().getUserMediaStream(audio, video); this.gotUserMediaForInvite(mediaStream); } catch (e) { this.getUserMediaFailed(e); @@ -1922,96 +1916,12 @@ export class MatrixCall extends EventEmitter { } } -async function getScreensharingStream(desktopCapturerSourceId: string): Promise { - const screenshareConstraints = getScreenshareContraints(desktopCapturerSourceId); - if (!screenshareConstraints) return null; - - if (desktopCapturerSourceId) { - // We are using Electron - logger.debug("Getting screen stream using getUserMedia()..."); - return await navigator.mediaDevices.getUserMedia(screenshareConstraints); - } else { - // We are not using Electron - logger.debug("Getting screen stream using getDisplayMedia()..."); - return await navigator.mediaDevices.getDisplayMedia(screenshareConstraints); - } -} - function setTracksEnabled(tracks: Array, enabled: boolean): void { for (let i = 0; i < tracks.length; i++) { tracks[i].enabled = enabled; } } -function getUserMediaContraints(type: ConstraintsType): MediaStreamConstraints { - const isWebkit = !!navigator.webkitGetUserMedia; - - switch (type) { - case ConstraintsType.Audio: { - return { - audio: { - deviceId: audioInput ? { ideal: audioInput } : undefined, - }, - video: false, - }; - } - case ConstraintsType.Video: { - return { - audio: { - deviceId: audioInput ? { ideal: audioInput } : undefined, - }, video: { - deviceId: videoInput ? { ideal: videoInput } : undefined, - /* We want 640x360. Chrome will give it only if we ask exactly, - FF refuses entirely if we ask exactly, so have to ask for ideal - instead - XXX: Is this still true? - */ - width: isWebkit ? { exact: 640 } : { ideal: 640 }, - height: isWebkit ? { exact: 360 } : { ideal: 360 }, - }, - }; - } - } -} - -function getScreenshareContraints(desktopCapturerSourceId?: string): DesktopCapturerConstraints { - if (desktopCapturerSourceId) { - logger.debug("Using desktop capturer source", desktopCapturerSourceId); - return { - audio: false, - video: { - mandatory: { - chromeMediaSource: "desktop", - chromeMediaSourceId: desktopCapturerSourceId, - }, - }, - }; - } else { - logger.debug("Not using desktop capturer source"); - return { - audio: false, - video: true, - }; - } -} - -let audioInput: string; -let videoInput: string; -/** - * Set an audio input device to use for MatrixCalls - * @function - * @param {string=} deviceId the identifier for the device - * undefined treated as unset - */ -export function setAudioInput(deviceId: string): void { audioInput = deviceId; } -/** - * Set a video input device to use for MatrixCalls - * @function - * @param {string=} deviceId the identifier for the device - * undefined treated as unset - */ -export function setVideoInput(deviceId: string): void { videoInput = deviceId; } - /** * DEPRECATED * Use client.createCall() From 7143ef8a32ec9427fabaea4edbf811f66b64ade7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 29 Aug 2021 10:43:19 +0200 Subject: [PATCH 22/47] Internally remove call types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/webrtc/call.ts | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index f15300c87..f74f8d31b 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -251,7 +251,6 @@ function genCallID(): string { */ export class MatrixCall extends EventEmitter { public roomId: string; - public type: CallType = null; public callId: string; public state = CallState.Fledgling; public hangupParty: CallParty; @@ -359,6 +358,25 @@ export class MatrixCall extends EventEmitter { return this.remoteAssertedIdentity; } + public get type(): CallType { + return (this.hasLocalUserMediaVideoTrack || this.hasRemoteUserMediaVideoTrack) + ? CallType.Video + : CallType.Voice; + } + + public get hasLocalUserMediaVideoTrack(): boolean { + return this.localUsermediaStream?.getVideoTracks().length > 0; + } + + public get hasRemoteUserMediaVideoTrack(): boolean { + return this.getRemoteFeeds().some((feed) => { + return ( + feed.purpose === SDPStreamMetadataPurpose.Usermedia && + feed.stream.getVideoTracks().length > 0 + ); + }); + } + public get localUsermediaFeed(): CallFeed { return this.getLocalFeeds().find((feed) => feed.purpose === SDPStreamMetadataPurpose.Usermedia); } @@ -617,8 +635,6 @@ export class MatrixCall extends EventEmitter { return; } - this.type = remoteStream.getTracks().some(t => t.kind === 'video') ? CallType.Video : CallType.Voice; - this.setState(CallState.Ringing); if (event.getLocalAge()) { @@ -656,7 +672,7 @@ export class MatrixCall extends EventEmitter { return; } - logger.debug(`Answering call ${this.callId} of type ${this.type}`); + logger.debug(`Answering call ${this.callId}`); if (!this.localUsermediaStream && !this.waitForLocalAVStream) { this.setState(CallState.WaitLocalMedia); @@ -665,7 +681,7 @@ export class MatrixCall extends EventEmitter { try { const mediaStream = await this.client.getMediaHandler().getUserMediaStream( true, - this.type === CallType.Video, + this.hasRemoteUserMediaVideoTrack, ); this.waitForLocalAVStream = false; this.gotUserMediaForAnswer(mediaStream); @@ -986,7 +1002,7 @@ export class MatrixCall extends EventEmitter { this.pushLocalFeed(stream, SDPStreamMetadataPurpose.Usermedia); this.setState(CallState.CreateOffer); - logger.debug("gotUserMediaForInvite -> " + this.type); + logger.debug("gotUserMediaForInvite"); // Now we wait for the negotiationneeded event }; @@ -1803,7 +1819,6 @@ export class MatrixCall extends EventEmitter { if (!audio) { throw new Error("You CANNOT start a call without audio"); } - this.type = video ? CallType.Video : CallType.Voice; this.checkForErrorListener(); // XXX Find a better way to do this this.client.callEventHandler.calls.set(this.callId, this); From 375b228bb2a5dfcc40e77131596a98871766a074 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Sat, 11 Sep 2021 16:06:29 +0100 Subject: [PATCH 23/47] fix missing types and linting errors --- src/autodiscovery.ts | 31 +++++-------------------------- src/client.ts | 27 ++++++++++++++++++++------- src/realtime-callbacks.ts | 13 +++++++++---- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/autodiscovery.ts b/src/autodiscovery.ts index d128377f9..1d7be9bf2 100644 --- a/src/autodiscovery.ts +++ b/src/autodiscovery.ts @@ -17,34 +17,13 @@ limitations under the License. /** @module auto-discovery */ +import { IClientWellKnown, IWellKnownConfig, AutoDiscoveryAction } from "./client"; import { logger } from './logger'; import { URL as NodeURL } from "url"; // Dev note: Auto discovery is part of the spec. // See: https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery -enum AutoDiscoveryAction { - SUCCESS = "SUCCESS", - IGNORE = "IGNORE", - PROMPT = "PROMPT", - FAIL_PROMPT = "FAIL_PROMPT", - FAIL_ERROR = "FAIL_ERROR", -} - -interface DiscoveredClientConfig { - "m.homeserver"?: WellKnownConfig; - "m.identity_server"?: WellKnownConfig; -} - -interface WellKnownConfig { - raw?: any; // todo typings - action?: AutoDiscoveryAction; - reason?: string; - error?: Error | string; - // eslint-disable-next-line - base_url?: string | null; -} - /** * Utilities for automatically discovery resources, such as homeservers * for users to log in to. @@ -133,7 +112,7 @@ export class AutoDiscovery { * configuration, which may include error states. Rejects on unexpected * failure, not when verification fails. */ - public static async fromDiscoveryConfig(wellknown: string): Promise { + public static async fromDiscoveryConfig(wellknown: string): Promise { // Step 1 is to get the config, which is provided to us here. // We default to an error state to make the first few checks easier to @@ -293,7 +272,7 @@ export class AutoDiscovery { * configuration, which may include error states. Rejects on unexpected * failure, not when discovery fails. */ - public static async findClientConfig(domain: string): Promise { + public static async findClientConfig(domain: string): Promise { if (!domain || typeof(domain) !== "string" || domain.length === 0) { throw new Error("'domain' must be a string of non-zero length"); } @@ -361,7 +340,7 @@ export class AutoDiscovery { * @returns {Promise} Resolves to the domain's client config. Can * be an empty object. */ - public static async getRawClientConfig(domain: string): Promise { + public static async getRawClientConfig(domain: string): Promise { if (!domain || typeof(domain) !== "string" || domain.length === 0) { throw new Error("'domain' must be a string of non-zero length"); } @@ -429,7 +408,7 @@ export class AutoDiscovery { * @return {Promise} Resolves to the returned state. * @private */ - private static async fetchWellKnownObject(url: string): Promise { // TODO: TYPES + private static async fetchWellKnownObject(url: string): Promise { // TODO: TYPES return new Promise(function(resolve, reject) { // eslint-disable-next-line const request = require("./matrix").getRequest(); diff --git a/src/client.ts b/src/client.ts index 894c5a09d..624e39e2a 100644 --- a/src/client.ts +++ b/src/client.ts @@ -475,14 +475,27 @@ interface IServerVersions { unstable_features: Record; } -interface IClientWellKnown { +export interface IClientWellKnown { [key: string]: any; - "m.homeserver": { - base_url: string; - }; - "m.identity_server"?: { - base_url: string; - }; + "m.homeserver"?: IWellKnownConfig; + "m.identity_server"?: IWellKnownConfig; +} + +export interface IWellKnownConfig { + raw?: any; // todo typings + action?: AutoDiscoveryAction; + reason?: string; + error?: Error | string; + // eslint-disable-next-line + base_url?: string | null; +} + +export enum AutoDiscoveryAction { + SUCCESS = "SUCCESS", + IGNORE = "IGNORE", + PROMPT = "PROMPT", + FAIL_PROMPT = "FAIL_PROMPT", + FAIL_ERROR = "FAIL_ERROR", } interface IKeyBackupPath { diff --git a/src/realtime-callbacks.ts b/src/realtime-callbacks.ts index 0ef288407..68e41be53 100644 --- a/src/realtime-callbacks.ts +++ b/src/realtime-callbacks.ts @@ -34,11 +34,16 @@ const TIMER_CHECK_PERIOD_MS = 1000; let count = 0; // the key for our callback with the real global.setTimeout -let realCallbackKey; +let realCallbackKey: NodeJS.Timeout | number; // a sorted list of the callbacks to be run. // each is an object with keys [runAt, func, params, key]. -const callbackList = []; +const callbackList: { + runAt: number; + func: (...params: any[]) => void; + params: any[]; + key: number; +}[] = []; // var debuglog = logger.log.bind(logger); const debuglog = function(...params: any[]) {}; @@ -126,7 +131,7 @@ export function clearTimeout(key: number): void { // use the real global.setTimeout to schedule a callback to runCallbacks. function scheduleRealCallback(): void { if (realCallbackKey) { - global.clearTimeout(realCallbackKey); + global.clearTimeout(realCallbackKey as NodeJS.Timeout); } const first = callbackList[0]; @@ -182,7 +187,7 @@ function runCallbacks(): void { * returns the index of the last element for which func returns * greater than zero, or array.length if no such element exists. */ -function binarySearch(array: T[], func: (T) => number): number { +function binarySearch(array: T[], func: (v: T) => number): number { // min is inclusive, max exclusive. let min = 0; let max = array.length; From edd614dd0c19ede3253f077588e336fadebccf53 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Sat, 11 Sep 2021 16:17:40 +0100 Subject: [PATCH 24/47] fix cyclic dependencies for AutoDiscoveryActionEnum --- src/autodiscovery.ts | 10 +++++++++- src/client.ts | 10 +--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/autodiscovery.ts b/src/autodiscovery.ts index 1d7be9bf2..a300cb049 100644 --- a/src/autodiscovery.ts +++ b/src/autodiscovery.ts @@ -17,13 +17,21 @@ limitations under the License. /** @module auto-discovery */ -import { IClientWellKnown, IWellKnownConfig, AutoDiscoveryAction } from "./client"; +import { IClientWellKnown, IWellKnownConfig } from "./client"; import { logger } from './logger'; import { URL as NodeURL } from "url"; // Dev note: Auto discovery is part of the spec. // See: https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery +export enum AutoDiscoveryAction { + SUCCESS = "SUCCESS", + IGNORE = "IGNORE", + PROMPT = "PROMPT", + FAIL_PROMPT = "FAIL_PROMPT", + FAIL_ERROR = "FAIL_ERROR", +} + /** * Utilities for automatically discovery resources, such as homeservers * for users to log in to. diff --git a/src/client.ts b/src/client.ts index 624e39e2a..328c66e14 100644 --- a/src/client.ts +++ b/src/client.ts @@ -31,7 +31,7 @@ import { sleep } from './utils'; import { Group } from "./models/group"; import { Direction, EventTimeline } from "./models/event-timeline"; import { IActionsObject, PushProcessor } from "./pushprocessor"; -import { AutoDiscovery } from "./autodiscovery"; +import { AutoDiscovery, AutoDiscoveryAction } from "./autodiscovery"; import * as olmlib from "./crypto/olmlib"; import { decodeBase64, encodeBase64 } from "./crypto/olmlib"; import { IExportedDevice as IOlmDevice } from "./crypto/OlmDevice"; @@ -490,14 +490,6 @@ export interface IWellKnownConfig { base_url?: string | null; } -export enum AutoDiscoveryAction { - SUCCESS = "SUCCESS", - IGNORE = "IGNORE", - PROMPT = "PROMPT", - FAIL_PROMPT = "FAIL_PROMPT", - FAIL_ERROR = "FAIL_ERROR", -} - interface IKeyBackupPath { path: string; queryData?: { From fed0ced89d884dc2fd25ad2d0f1f6849c13fb400 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Sun, 12 Sep 2021 08:56:31 +0200 Subject: [PATCH 25/47] Type fixes for CreateSecretStorageDialog TS migration --- src/client.ts | 4 ++-- src/crypto/api.ts | 4 ++-- src/crypto/index.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/client.ts b/src/client.ts index 894c5a09d..1598ef34b 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2027,7 +2027,7 @@ export class MatrixClient extends EventEmitter { * recovery key which should be disposed of after displaying to the user, * and raw private key to avoid round tripping if needed. */ - public createRecoveryKeyFromPassphrase(password: string): Promise { + public createRecoveryKeyFromPassphrase(password?: string): Promise { if (!this.crypto) { throw new Error("End-to-end encryption disabled"); } @@ -7451,7 +7451,7 @@ export class MatrixClient extends EventEmitter { return this.http.authedRequest(undefined, "GET", path, qps, undefined); } - public uploadDeviceSigningKeys(auth: any, keys: CrossSigningKeys): Promise<{}> { // TODO: types + public uploadDeviceSigningKeys(auth: any, keys?: CrossSigningKeys): Promise<{}> { // TODO: types const data = Object.assign({}, keys); if (auth) Object.assign(data, { auth }); return this.http.authedRequest( diff --git a/src/crypto/api.ts b/src/crypto/api.ts index 57f48c18c..1bd65d7db 100644 --- a/src/crypto/api.ts +++ b/src/crypto/api.ts @@ -58,7 +58,7 @@ export interface IEncryptedEventInfo { } export interface IRecoveryKey { - keyInfo: { + keyInfo?: { pubkey: string; passphrase?: { algorithm: string; @@ -67,7 +67,7 @@ export interface IRecoveryKey { }; }; privateKey: Uint8Array; - encodedPrivateKey: string; + encodedPrivateKey?: string; } export interface ICreateSecretStorageOpts { diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 4022ce400..e35eef493 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -506,7 +506,7 @@ export class Crypto extends EventEmitter { * recovery key which should be disposed of after displaying to the user, * and raw private key to avoid round tripping if needed. */ - public async createRecoveryKeyFromPassphrase(password: string): Promise { + public async createRecoveryKeyFromPassphrase(password?: string): Promise { const decryption = new global.Olm.PkDecryption(); try { const keyInfo: Partial = {}; From 7daab62850b1c482eb27f5d297491bffa79fcbec Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Sun, 12 Sep 2021 09:21:04 +0200 Subject: [PATCH 26/47] Types fixes for CreateKeyBackupDialog TS migration --- src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index 1598ef34b..f9c54126b 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2470,7 +2470,7 @@ export class MatrixClient extends EventEmitter { */ // TODO: Verify types public async prepareKeyBackupVersion( - password: string, + password?: string, opts: IKeyBackupPrepareOpts = { secureSecretStorage: false }, ): Promise> { if (!this.crypto) { From 9c100fea484f6cf7dc93e7a7caf3169aee5d4b1d Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Sun, 12 Sep 2021 10:12:59 +0200 Subject: [PATCH 27/47] Types update for UserView TS migration --- src/models/room-member.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/room-member.ts b/src/models/room-member.ts index e3d6b66ce..01948ac16 100644 --- a/src/models/room-member.ts +++ b/src/models/room-member.ts @@ -103,7 +103,7 @@ export class RoomMember extends EventEmitter { * @fires module:client~MatrixClient#event:"RoomMember.name" * @fires module:client~MatrixClient#event:"RoomMember.membership" */ - public setMembershipEvent(event: MatrixEvent, roomState: RoomState): void { + public setMembershipEvent(event: MatrixEvent, roomState?: RoomState): void { const displayName = event.getDirectionalContent().displayname; if (event.getType() !== "m.room.member") { @@ -322,7 +322,7 @@ export class RoomMember extends EventEmitter { const MXID_PATTERN = /@.+:.+/; const LTR_RTL_PATTERN = /[\u200E\u200F\u202A-\u202F]/; -function shouldDisambiguate(selfUserId: string, displayName: string, roomState: RoomState): boolean { +function shouldDisambiguate(selfUserId: string, displayName: string, roomState?: RoomState): boolean { if (!displayName || displayName === selfUserId) return false; // First check if the displayname is something we consider truthy From 894c24880da0e1cc81818f51c0db80e3c9fb2be9 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 13 Sep 2021 12:34:48 +0100 Subject: [PATCH 28/47] Verify target device key on reshare --- src/crypto/algorithms/megolm.ts | 38 +++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/crypto/algorithms/megolm.ts b/src/crypto/algorithms/megolm.ts index 381f85188..55a766620 100644 --- a/src/crypto/algorithms/megolm.ts +++ b/src/crypto/algorithms/megolm.ts @@ -101,6 +101,13 @@ interface IPayload extends Partial { } /* eslint-enable camelcase */ +interface SharedWithData { + // The identity key of the device we shared with + deviceKey: string; + // The message index of the ratchet we shared with that device + messageIndex: number; +} + /** * @private * @constructor @@ -115,12 +122,12 @@ interface IPayload extends Partial { * * @property {object} sharedWithDevices * devices with which we have shared the session key - * userId -> {deviceId -> msgindex} + * userId -> {deviceId -> SharedWithData} */ class OutboundSessionInfo { public useCount = 0; public creationTime: number; - public sharedWithDevices: Record> = {}; + public sharedWithDevices: Record> = {}; public blockedDevicesNotified: Record> = {}; constructor(public readonly sessionId: string, public readonly sharedHistory = false) { @@ -150,11 +157,11 @@ class OutboundSessionInfo { return false; } - public markSharedWithDevice(userId: string, deviceId: string, chainIndex: number): void { + public markSharedWithDevice(userId: string, deviceId: string, deviceKey: string, chainIndex: number): void { if (!this.sharedWithDevices[userId]) { this.sharedWithDevices[userId] = {}; } - this.sharedWithDevices[userId][deviceId] = chainIndex; + this.sharedWithDevices[userId][deviceId] = { deviceKey, messageIndex: chainIndex }; } public markNotifiedBlockedDevice(userId: string, deviceId: string): void { @@ -572,6 +579,7 @@ class MegolmEncryption extends EncryptionAlgorithm { payload: IPayload, ): Promise { const contentMap = {}; + const deviceInfoByDeviceId = new Map(); const promises = []; for (let i = 0; i < userDeviceMap.length; i++) { @@ -584,6 +592,7 @@ class MegolmEncryption extends EncryptionAlgorithm { const userId = val.userId; const deviceInfo = val.deviceInfo; const deviceId = deviceInfo.deviceId; + deviceInfoByDeviceId.set(deviceId, deviceInfo); if (!contentMap[userId]) { contentMap[userId] = {}; @@ -636,7 +645,10 @@ class MegolmEncryption extends EncryptionAlgorithm { for (const userId of Object.keys(contentMap)) { for (const deviceId of Object.keys(contentMap[userId])) { session.markSharedWithDevice( - userId, deviceId, chainIndex, + userId, + deviceId, + deviceInfoByDeviceId.get(deviceId).getIdentityKey(), + chainIndex, ); } } @@ -719,8 +731,8 @@ class MegolmEncryption extends EncryptionAlgorithm { logger.debug(`megolm session ${sessionId} never shared with user ${userId}`); return; } - const sentChainIndex = obSessionInfo.sharedWithDevices[userId][device.deviceId]; - if (sentChainIndex === undefined) { + const sessionSharedData = obSessionInfo.sharedWithDevices[userId][device.deviceId]; + if (sessionSharedData === undefined) { logger.debug( "megolm session ID " + sessionId + " never shared with device " + userId + ":" + device.deviceId, @@ -728,10 +740,18 @@ class MegolmEncryption extends EncryptionAlgorithm { return; } + if (sessionSharedData.deviceKey !== device.getIdentityKey()) { + logger.warn( + `Session has been shared with device ${device.deviceId} but with identity ` + + `key ${sessionSharedData.deviceKey}. Key is now ${device.getIdentityKey()}!`, + ); + return; + } + // get the key from the inbound session: the outbound one will already // have been ratcheted to the next chain index. const key = await this.olmDevice.getInboundGroupSessionKey( - this.roomId, senderKey, sessionId, sentChainIndex, + this.roomId, senderKey, sessionId, sessionSharedData.messageIndex, ); if (!key) { @@ -882,7 +902,7 @@ class MegolmEncryption extends EncryptionAlgorithm { const deviceId = deviceInfo.deviceId; session.markSharedWithDevice( - userId, deviceId, key.chain_index, + userId, deviceId, deviceInfo.getIdentityKey(), key.chain_index, ); } From fac700bf4d3b113b898346d8eeeaabfb614f514d Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 13 Sep 2021 12:43:13 +0100 Subject: [PATCH 29/47] Changelog for 12.4.1 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5621e0f25..28a6141b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [12.4.1](https://github.com/vector-im/element-desktop/releases/tag/v12.4.1) (2021-09-13) +=================================================================================================== + +## 🔒 SECURITY FIXES + * Fix a security issue with message key sharing. See https://matrix.org/blog/2021/09/13/vulnerability-disclosure-key-sharing + for details. + Changes in [12.4.0](https://github.com/vector-im/element-desktop/releases/tag/v12.4.0) (2021-08-31) =================================================================================================== From e878b7683b1d7b47eca10d8dfc4510f7826679b3 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 13 Sep 2021 12:47:04 +0100 Subject: [PATCH 30/47] v12.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 341cd0821..066e12b32 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "12.4.0", + "version": "12.4.1", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build", From 4e5847f356be63892b21b046770b7a28e09eb1c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Mon, 13 Sep 2021 18:01:24 +0200 Subject: [PATCH 31/47] Add hasBeenCancelled to VerificationBase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/crypto/verification/Base.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/crypto/verification/Base.ts b/src/crypto/verification/Base.ts index 2fa54ae11..bd8f275b0 100644 --- a/src/crypto/verification/Base.ts +++ b/src/crypto/verification/Base.ts @@ -103,6 +103,10 @@ export class VerificationBase extends EventEmitter { content.from_device === this.baseApis.getDeviceId(); } + public get hasBeenCancelled(): boolean { + return this.cancelled; + } + private resetTimer(): void { logger.info("Refreshing/starting the verification transaction timeout timer"); if (this.transactionTimeoutTimer !== null) { From 2119e88c7852354ae5b2e63b5e516348e4651d9a Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Sep 2021 13:11:18 +0100 Subject: [PATCH 32/47] Tests for key sharing security fix Tests for 894c24880da0e1cc81818f51c0db80e3c9fb2be9 --- spec/unit/crypto/algorithms/megolm.spec.js | 194 +++++++++++++-------- 1 file changed, 121 insertions(+), 73 deletions(-) diff --git a/spec/unit/crypto/algorithms/megolm.spec.js b/spec/unit/crypto/algorithms/megolm.spec.js index e7d63c6a2..d949b1bed 100644 --- a/spec/unit/crypto/algorithms/megolm.spec.js +++ b/spec/unit/crypto/algorithms/megolm.spec.js @@ -256,97 +256,145 @@ describe("MegolmDecryption", function() { }); }); - it("re-uses sessions for sequential messages", async function() { - mockCrypto.backupManager = { - backupGroupSession: () => {}, - }; - const mockStorage = new MockStorageApi(); - const cryptoStore = new MemoryCryptoStore(mockStorage); + describe("session reuse and key reshares", () => { + let megolmEncryption; + let aliceDeviceInfo; + let mockRoom; + let olmDevice; - const olmDevice = new OlmDevice(cryptoStore); - olmDevice.verifySignature = jest.fn(); - await olmDevice.init(); + beforeEach(async () => { + mockCrypto.backupManager = { + backupGroupSession: () => {}, + }; + const mockStorage = new MockStorageApi(); + const cryptoStore = new MemoryCryptoStore(mockStorage); - mockBaseApis.claimOneTimeKeys = jest.fn().mockReturnValue(Promise.resolve({ - one_time_keys: { - '@alice:home.server': { - aliceDevice: { - 'signed_curve25519:flooble': { - key: 'YmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI', - signatures: { - '@alice:home.server': { - 'ed25519:aliceDevice': 'totally valid', + olmDevice = new OlmDevice(cryptoStore); + olmDevice.verifySignature = jest.fn(); + await olmDevice.init(); + + mockBaseApis.claimOneTimeKeys = jest.fn().mockReturnValue(Promise.resolve({ + one_time_keys: { + '@alice:home.server': { + aliceDevice: { + 'signed_curve25519:flooble': { + key: 'YmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI', + signatures: { + '@alice:home.server': { + 'ed25519:aliceDevice': 'totally valid', + }, }, }, }, }, }, - }, - })); - mockBaseApis.sendToDevice = jest.fn().mockResolvedValue(undefined); + })); + mockBaseApis.sendToDevice = jest.fn().mockResolvedValue(undefined); - mockCrypto.downloadKeys.mockReturnValue(Promise.resolve({ - '@alice:home.server': { - aliceDevice: { - deviceId: 'aliceDevice', - isBlocked: jest.fn().mockReturnValue(false), - isUnverified: jest.fn().mockReturnValue(false), - getIdentityKey: jest.fn().mockReturnValue( - 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE', - ), - getFingerprint: jest.fn().mockReturnValue(''), + aliceDeviceInfo = { + deviceId: 'aliceDevice', + isBlocked: jest.fn().mockReturnValue(false), + isUnverified: jest.fn().mockReturnValue(false), + getIdentityKey: jest.fn().mockReturnValue( + 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE', + ), + getFingerprint: jest.fn().mockReturnValue(''), + }; + + mockCrypto.downloadKeys.mockReturnValue(Promise.resolve({ + '@alice:home.server': { + aliceDevice: aliceDeviceInfo, }, - }, - })); + })); - mockCrypto.checkDeviceTrust.mockReturnValue({ - isVerified: () => false, + mockCrypto.checkDeviceTrust.mockReturnValue({ + isVerified: () => false, + }); + + megolmEncryption = new MegolmEncryption({ + userId: '@user:id', + crypto: mockCrypto, + olmDevice: olmDevice, + baseApis: mockBaseApis, + roomId: ROOM_ID, + config: { + rotation_period_ms: 9999999999999, + }, + }); + mockRoom = { + getEncryptionTargetMembers: jest.fn().mockReturnValue( + [{ userId: "@alice:home.server" }], + ), + getBlacklistUnverifiedDevices: jest.fn().mockReturnValue(false), + }; }); - const megolmEncryption = new MegolmEncryption({ - userId: '@user:id', - crypto: mockCrypto, - olmDevice: olmDevice, - baseApis: mockBaseApis, - roomId: ROOM_ID, - config: { - rotation_period_ms: 9999999999999, - }, - }); - const mockRoom = { - getEncryptionTargetMembers: jest.fn().mockReturnValue( - [{ userId: "@alice:home.server" }], - ), - getBlacklistUnverifiedDevices: jest.fn().mockReturnValue(false), - }; - const ct1 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { - body: "Some text", - }); - expect(mockRoom.getEncryptionTargetMembers).toHaveBeenCalled(); + it("re-uses sessions for sequential messages", async function() { + const ct1 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { + body: "Some text", + }); + expect(mockRoom.getEncryptionTargetMembers).toHaveBeenCalled(); - // this should have claimed a key for alice as it's starting a new session - expect(mockBaseApis.claimOneTimeKeys).toHaveBeenCalledWith( - [['@alice:home.server', 'aliceDevice']], 'signed_curve25519', 2000, - ); - expect(mockCrypto.downloadKeys).toHaveBeenCalledWith( - ['@alice:home.server'], false, - ); - expect(mockBaseApis.sendToDevice).toHaveBeenCalled(); - expect(mockBaseApis.claimOneTimeKeys).toHaveBeenCalledWith( - [['@alice:home.server', 'aliceDevice']], 'signed_curve25519', 2000, - ); + // this should have claimed a key for alice as it's starting a new session + expect(mockBaseApis.claimOneTimeKeys).toHaveBeenCalledWith( + [['@alice:home.server', 'aliceDevice']], 'signed_curve25519', 2000, + ); + expect(mockCrypto.downloadKeys).toHaveBeenCalledWith( + ['@alice:home.server'], false, + ); + expect(mockBaseApis.sendToDevice).toHaveBeenCalled(); + expect(mockBaseApis.claimOneTimeKeys).toHaveBeenCalledWith( + [['@alice:home.server', 'aliceDevice']], 'signed_curve25519', 2000, + ); - mockBaseApis.claimOneTimeKeys.mockReset(); + mockBaseApis.claimOneTimeKeys.mockReset(); - const ct2 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { - body: "Some more text", + const ct2 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { + body: "Some more text", + }); + + // this should *not* have claimed a key as it should be using the same session + expect(mockBaseApis.claimOneTimeKeys).not.toHaveBeenCalled(); + + // likewise they should show the same session ID + expect(ct2.session_id).toEqual(ct1.session_id); }); - // this should *not* have claimed a key as it should be using the same session - expect(mockBaseApis.claimOneTimeKeys).not.toHaveBeenCalled(); + it("re-shares keys to devices it's already sent to", async function() { + const ct1 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { + body: "Some text", + }); - // likewise they should show the same session ID - expect(ct2.session_id).toEqual(ct1.session_id); + mockBaseApis.sendToDevice.mockClear(); + await megolmEncryption.reshareKeyWithDevice( + olmDevice.deviceCurve25519Key, + ct1.session_id, + '@alice:home.server', + aliceDeviceInfo, + ); + + expect(mockBaseApis.sendToDevice).toHaveBeenCalled(); + }); + + it("does not re-share keys to devices whose keys have changed", async function() { + const ct1 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { + body: "Some text", + }); + + aliceDeviceInfo.getIdentityKey = jest.fn().mockReturnValue( + 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWI', + ); + + mockBaseApis.sendToDevice.mockClear(); + await megolmEncryption.reshareKeyWithDevice( + olmDevice.deviceCurve25519Key, + ct1.session_id, + '@alice:home.server', + aliceDeviceInfo, + ); + + expect(mockBaseApis.sendToDevice).not.toHaveBeenCalled(); + }); }); }); From 557f8009190835d1bb3d9c3ce6236f8e5fbe3c44 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 13 Sep 2021 12:34:48 +0100 Subject: [PATCH 33/47] Verify target device key on reshare --- src/crypto/algorithms/megolm.ts | 38 +++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/crypto/algorithms/megolm.ts b/src/crypto/algorithms/megolm.ts index 381f85188..55a766620 100644 --- a/src/crypto/algorithms/megolm.ts +++ b/src/crypto/algorithms/megolm.ts @@ -101,6 +101,13 @@ interface IPayload extends Partial { } /* eslint-enable camelcase */ +interface SharedWithData { + // The identity key of the device we shared with + deviceKey: string; + // The message index of the ratchet we shared with that device + messageIndex: number; +} + /** * @private * @constructor @@ -115,12 +122,12 @@ interface IPayload extends Partial { * * @property {object} sharedWithDevices * devices with which we have shared the session key - * userId -> {deviceId -> msgindex} + * userId -> {deviceId -> SharedWithData} */ class OutboundSessionInfo { public useCount = 0; public creationTime: number; - public sharedWithDevices: Record> = {}; + public sharedWithDevices: Record> = {}; public blockedDevicesNotified: Record> = {}; constructor(public readonly sessionId: string, public readonly sharedHistory = false) { @@ -150,11 +157,11 @@ class OutboundSessionInfo { return false; } - public markSharedWithDevice(userId: string, deviceId: string, chainIndex: number): void { + public markSharedWithDevice(userId: string, deviceId: string, deviceKey: string, chainIndex: number): void { if (!this.sharedWithDevices[userId]) { this.sharedWithDevices[userId] = {}; } - this.sharedWithDevices[userId][deviceId] = chainIndex; + this.sharedWithDevices[userId][deviceId] = { deviceKey, messageIndex: chainIndex }; } public markNotifiedBlockedDevice(userId: string, deviceId: string): void { @@ -572,6 +579,7 @@ class MegolmEncryption extends EncryptionAlgorithm { payload: IPayload, ): Promise { const contentMap = {}; + const deviceInfoByDeviceId = new Map(); const promises = []; for (let i = 0; i < userDeviceMap.length; i++) { @@ -584,6 +592,7 @@ class MegolmEncryption extends EncryptionAlgorithm { const userId = val.userId; const deviceInfo = val.deviceInfo; const deviceId = deviceInfo.deviceId; + deviceInfoByDeviceId.set(deviceId, deviceInfo); if (!contentMap[userId]) { contentMap[userId] = {}; @@ -636,7 +645,10 @@ class MegolmEncryption extends EncryptionAlgorithm { for (const userId of Object.keys(contentMap)) { for (const deviceId of Object.keys(contentMap[userId])) { session.markSharedWithDevice( - userId, deviceId, chainIndex, + userId, + deviceId, + deviceInfoByDeviceId.get(deviceId).getIdentityKey(), + chainIndex, ); } } @@ -719,8 +731,8 @@ class MegolmEncryption extends EncryptionAlgorithm { logger.debug(`megolm session ${sessionId} never shared with user ${userId}`); return; } - const sentChainIndex = obSessionInfo.sharedWithDevices[userId][device.deviceId]; - if (sentChainIndex === undefined) { + const sessionSharedData = obSessionInfo.sharedWithDevices[userId][device.deviceId]; + if (sessionSharedData === undefined) { logger.debug( "megolm session ID " + sessionId + " never shared with device " + userId + ":" + device.deviceId, @@ -728,10 +740,18 @@ class MegolmEncryption extends EncryptionAlgorithm { return; } + if (sessionSharedData.deviceKey !== device.getIdentityKey()) { + logger.warn( + `Session has been shared with device ${device.deviceId} but with identity ` + + `key ${sessionSharedData.deviceKey}. Key is now ${device.getIdentityKey()}!`, + ); + return; + } + // get the key from the inbound session: the outbound one will already // have been ratcheted to the next chain index. const key = await this.olmDevice.getInboundGroupSessionKey( - this.roomId, senderKey, sessionId, sentChainIndex, + this.roomId, senderKey, sessionId, sessionSharedData.messageIndex, ); if (!key) { @@ -882,7 +902,7 @@ class MegolmEncryption extends EncryptionAlgorithm { const deviceId = deviceInfo.deviceId; session.markSharedWithDevice( - userId, deviceId, key.chain_index, + userId, deviceId, deviceInfo.getIdentityKey(), key.chain_index, ); } From 32d727293990ec144eb9f60a0b97b4e451c33b93 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Sep 2021 13:11:18 +0100 Subject: [PATCH 34/47] Tests for key sharing security fix Tests for 894c24880da0e1cc81818f51c0db80e3c9fb2be9 --- spec/unit/crypto/algorithms/megolm.spec.js | 194 +++++++++++++-------- 1 file changed, 121 insertions(+), 73 deletions(-) diff --git a/spec/unit/crypto/algorithms/megolm.spec.js b/spec/unit/crypto/algorithms/megolm.spec.js index e7d63c6a2..d949b1bed 100644 --- a/spec/unit/crypto/algorithms/megolm.spec.js +++ b/spec/unit/crypto/algorithms/megolm.spec.js @@ -256,97 +256,145 @@ describe("MegolmDecryption", function() { }); }); - it("re-uses sessions for sequential messages", async function() { - mockCrypto.backupManager = { - backupGroupSession: () => {}, - }; - const mockStorage = new MockStorageApi(); - const cryptoStore = new MemoryCryptoStore(mockStorage); + describe("session reuse and key reshares", () => { + let megolmEncryption; + let aliceDeviceInfo; + let mockRoom; + let olmDevice; - const olmDevice = new OlmDevice(cryptoStore); - olmDevice.verifySignature = jest.fn(); - await olmDevice.init(); + beforeEach(async () => { + mockCrypto.backupManager = { + backupGroupSession: () => {}, + }; + const mockStorage = new MockStorageApi(); + const cryptoStore = new MemoryCryptoStore(mockStorage); - mockBaseApis.claimOneTimeKeys = jest.fn().mockReturnValue(Promise.resolve({ - one_time_keys: { - '@alice:home.server': { - aliceDevice: { - 'signed_curve25519:flooble': { - key: 'YmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI', - signatures: { - '@alice:home.server': { - 'ed25519:aliceDevice': 'totally valid', + olmDevice = new OlmDevice(cryptoStore); + olmDevice.verifySignature = jest.fn(); + await olmDevice.init(); + + mockBaseApis.claimOneTimeKeys = jest.fn().mockReturnValue(Promise.resolve({ + one_time_keys: { + '@alice:home.server': { + aliceDevice: { + 'signed_curve25519:flooble': { + key: 'YmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI', + signatures: { + '@alice:home.server': { + 'ed25519:aliceDevice': 'totally valid', + }, }, }, }, }, }, - }, - })); - mockBaseApis.sendToDevice = jest.fn().mockResolvedValue(undefined); + })); + mockBaseApis.sendToDevice = jest.fn().mockResolvedValue(undefined); - mockCrypto.downloadKeys.mockReturnValue(Promise.resolve({ - '@alice:home.server': { - aliceDevice: { - deviceId: 'aliceDevice', - isBlocked: jest.fn().mockReturnValue(false), - isUnverified: jest.fn().mockReturnValue(false), - getIdentityKey: jest.fn().mockReturnValue( - 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE', - ), - getFingerprint: jest.fn().mockReturnValue(''), + aliceDeviceInfo = { + deviceId: 'aliceDevice', + isBlocked: jest.fn().mockReturnValue(false), + isUnverified: jest.fn().mockReturnValue(false), + getIdentityKey: jest.fn().mockReturnValue( + 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE', + ), + getFingerprint: jest.fn().mockReturnValue(''), + }; + + mockCrypto.downloadKeys.mockReturnValue(Promise.resolve({ + '@alice:home.server': { + aliceDevice: aliceDeviceInfo, }, - }, - })); + })); - mockCrypto.checkDeviceTrust.mockReturnValue({ - isVerified: () => false, + mockCrypto.checkDeviceTrust.mockReturnValue({ + isVerified: () => false, + }); + + megolmEncryption = new MegolmEncryption({ + userId: '@user:id', + crypto: mockCrypto, + olmDevice: olmDevice, + baseApis: mockBaseApis, + roomId: ROOM_ID, + config: { + rotation_period_ms: 9999999999999, + }, + }); + mockRoom = { + getEncryptionTargetMembers: jest.fn().mockReturnValue( + [{ userId: "@alice:home.server" }], + ), + getBlacklistUnverifiedDevices: jest.fn().mockReturnValue(false), + }; }); - const megolmEncryption = new MegolmEncryption({ - userId: '@user:id', - crypto: mockCrypto, - olmDevice: olmDevice, - baseApis: mockBaseApis, - roomId: ROOM_ID, - config: { - rotation_period_ms: 9999999999999, - }, - }); - const mockRoom = { - getEncryptionTargetMembers: jest.fn().mockReturnValue( - [{ userId: "@alice:home.server" }], - ), - getBlacklistUnverifiedDevices: jest.fn().mockReturnValue(false), - }; - const ct1 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { - body: "Some text", - }); - expect(mockRoom.getEncryptionTargetMembers).toHaveBeenCalled(); + it("re-uses sessions for sequential messages", async function() { + const ct1 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { + body: "Some text", + }); + expect(mockRoom.getEncryptionTargetMembers).toHaveBeenCalled(); - // this should have claimed a key for alice as it's starting a new session - expect(mockBaseApis.claimOneTimeKeys).toHaveBeenCalledWith( - [['@alice:home.server', 'aliceDevice']], 'signed_curve25519', 2000, - ); - expect(mockCrypto.downloadKeys).toHaveBeenCalledWith( - ['@alice:home.server'], false, - ); - expect(mockBaseApis.sendToDevice).toHaveBeenCalled(); - expect(mockBaseApis.claimOneTimeKeys).toHaveBeenCalledWith( - [['@alice:home.server', 'aliceDevice']], 'signed_curve25519', 2000, - ); + // this should have claimed a key for alice as it's starting a new session + expect(mockBaseApis.claimOneTimeKeys).toHaveBeenCalledWith( + [['@alice:home.server', 'aliceDevice']], 'signed_curve25519', 2000, + ); + expect(mockCrypto.downloadKeys).toHaveBeenCalledWith( + ['@alice:home.server'], false, + ); + expect(mockBaseApis.sendToDevice).toHaveBeenCalled(); + expect(mockBaseApis.claimOneTimeKeys).toHaveBeenCalledWith( + [['@alice:home.server', 'aliceDevice']], 'signed_curve25519', 2000, + ); - mockBaseApis.claimOneTimeKeys.mockReset(); + mockBaseApis.claimOneTimeKeys.mockReset(); - const ct2 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { - body: "Some more text", + const ct2 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { + body: "Some more text", + }); + + // this should *not* have claimed a key as it should be using the same session + expect(mockBaseApis.claimOneTimeKeys).not.toHaveBeenCalled(); + + // likewise they should show the same session ID + expect(ct2.session_id).toEqual(ct1.session_id); }); - // this should *not* have claimed a key as it should be using the same session - expect(mockBaseApis.claimOneTimeKeys).not.toHaveBeenCalled(); + it("re-shares keys to devices it's already sent to", async function() { + const ct1 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { + body: "Some text", + }); - // likewise they should show the same session ID - expect(ct2.session_id).toEqual(ct1.session_id); + mockBaseApis.sendToDevice.mockClear(); + await megolmEncryption.reshareKeyWithDevice( + olmDevice.deviceCurve25519Key, + ct1.session_id, + '@alice:home.server', + aliceDeviceInfo, + ); + + expect(mockBaseApis.sendToDevice).toHaveBeenCalled(); + }); + + it("does not re-share keys to devices whose keys have changed", async function() { + const ct1 = await megolmEncryption.encryptMessage(mockRoom, "a.fake.type", { + body: "Some text", + }); + + aliceDeviceInfo.getIdentityKey = jest.fn().mockReturnValue( + 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWI', + ); + + mockBaseApis.sendToDevice.mockClear(); + await megolmEncryption.reshareKeyWithDevice( + olmDevice.deviceCurve25519Key, + ct1.session_id, + '@alice:home.server', + aliceDeviceInfo, + ); + + expect(mockBaseApis.sendToDevice).not.toHaveBeenCalled(); + }); }); }); From a734fdf9b076b10264356b3cd67a6270350182a5 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 14 Sep 2021 15:46:08 +0100 Subject: [PATCH 35/47] Prepare changelog for v12.5.0 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6241a4c26..38ee462a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +Changes in [12.5.0](https://github.com/vector-im/element-desktop/releases/tag/v12.5.0) (2021-09-14) +=================================================================================================== + +## ✨ Features + * [Release] Exclude opt-in Element performance metrics from encryption ([\#1901](https://github.com/matrix-org/matrix-js-sdk/pull/1901)). + * Give `MatrixCall` the capability to emit `LengthChanged` events ([\#1873](https://github.com/matrix-org/matrix-js-sdk/pull/1873)). Contributed by [SimonBrandner](https://github.com/SimonBrandner). + * Improve browser example ([\#1875](https://github.com/matrix-org/matrix-js-sdk/pull/1875)). Contributed by [psrpinto](https://github.com/psrpinto). + * Give `CallFeed` the capability to emit on volume changes ([\#1865](https://github.com/matrix-org/matrix-js-sdk/pull/1865)). Contributed by [SimonBrandner](https://github.com/SimonBrandner). + +## 🐛 Bug Fixes + * Fix verification request cancellation ([\#1871](https://github.com/matrix-org/matrix-js-sdk/pull/1871)). + Changes in [12.5.0-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v12.5.0-rc.1) (2021-09-07) ============================================================================================================= From 99f428e091b23cf366651cb6d297f69c85e4bab3 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 14 Sep 2021 15:46:09 +0100 Subject: [PATCH 36/47] v12.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 009ebd053..8d39a5ae2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "12.5.0-rc.1", + "version": "12.5.0", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build", From b4eb29138b5ad7859aaa43c26dc61b7bebb8a7f3 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 14 Sep 2021 15:52:38 +0100 Subject: [PATCH 37/47] Resetting package fields for development --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 8d39a5ae2..5a2634f8e 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "keywords": [ "matrix-org" ], - "main": "./lib/index.js", + "main": "./src/index.js", "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.js", @@ -112,6 +112,5 @@ "coverageReporters": [ "text" ] - }, - "typings": "./lib/index.d.ts" + } } From d4f35bf07a3d3ec2467c8e2346f7edff28f2f0d4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 14 Sep 2021 10:03:23 -0600 Subject: [PATCH 38/47] fix main package? --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5a2634f8e..26bb5f552 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "keywords": [ "matrix-org" ], - "main": "./src/index.js", + "main": "./src/index.ts", "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.js", From cb6700f21bfe662c2d641f6046204ddb867b729d Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Sep 2021 18:41:14 +0100 Subject: [PATCH 39/47] yarn upgrade --- yarn.lock | 961 +++++++++++++++++++++++++++--------------------------- 1 file changed, 488 insertions(+), 473 deletions(-) diff --git a/yarn.lock b/yarn.lock index af2a33f2d..811d5dc9f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25,9 +25,9 @@ tunnel "0.0.6" "@babel/cli@^7.12.10": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.14.8.tgz#fac73c0e2328a8af9fd3560c06b096bfa3730933" - integrity sha512-lcy6Lymft9Rpfqmrqdd4oTDdUx9ZwaAhAfywVrHG4771Pa6PPT0danJ1kDHBXYqh4HHSmIdA+nlmfxfxSDPtBg== + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.15.4.tgz#00e21e192b738dec7900c8bb36270e377217c0a4" + integrity sha512-9RhhQ7tgKRcSO/jI3rNLxalLSk30cHqeM8bb+nGOJTyYBDpkoXw/A9QHZ2SYjlslAt4tr90pZQGIEobwWHSIDw== dependencies: commander "^4.0.1" convert-source-map "^1.1.0" @@ -47,25 +47,25 @@ dependencies: "@babel/highlight" "^7.14.5" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.7", "@babel/compat-data@^7.15.0": +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.15.0": version "7.15.0" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== "@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.7.5": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.0.tgz#749e57c68778b73ad8082775561f67f5196aafa8" - integrity sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw== + version "7.15.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.5.tgz#f8ed9ace730722544609f90c9bb49162dc3bf5b9" + integrity sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg== dependencies: "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.0" - "@babel/helper-compilation-targets" "^7.15.0" - "@babel/helper-module-transforms" "^7.15.0" - "@babel/helpers" "^7.14.8" - "@babel/parser" "^7.15.0" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.15.0" - "@babel/types" "^7.15.0" + "@babel/generator" "^7.15.4" + "@babel/helper-compilation-targets" "^7.15.4" + "@babel/helper-module-transforms" "^7.15.4" + "@babel/helpers" "^7.15.4" + "@babel/parser" "^7.15.5" + "@babel/template" "^7.15.4" + "@babel/traverse" "^7.15.4" + "@babel/types" "^7.15.4" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -74,9 +74,9 @@ source-map "^0.5.0" "@babel/eslint-parser@^7.12.10": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.15.0.tgz#b54f06e04d0e93aebcba99f89251e3bf0ee39f21" - integrity sha512-+gSPtjSBxOZz4Uh8Ggqu7HbfpB8cT1LwW0DnVVLZEJvzXauiD0Di3zszcBkRmfGGrLdYeHUwcflG7i3tr9kQlw== + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.15.4.tgz#46385943726291fb3e8db99522c8099b15684387" + integrity sha512-hPMIAmGNbmQzXJIo2P43Zj9UhRmGev5f9nqdBFOWNGDGh6XKmjby79woBvg6y0Jur6yRfQBneDbUQ8ZVc1krFw== dependencies: eslint-scope "^5.1.1" eslint-visitor-keys "^2.1.0" @@ -89,51 +89,51 @@ dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.12.11", "@babel/generator@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.0.tgz#a7d0c172e0d814974bad5aa77ace543b97917f15" - integrity sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ== +"@babel/generator@^7.12.11", "@babel/generator@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.4.tgz#85acb159a267ca6324f9793986991ee2022a05b0" + integrity sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw== dependencies: - "@babel/types" "^7.15.0" + "@babel/types" "^7.15.4" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61" - integrity sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA== +"@babel/helper-annotate-as-pure@^7.14.5", "@babel/helper-annotate-as-pure@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz#3d0e43b00c5e49fdb6c57e421601a7a658d5f835" + integrity sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.15.4" "@babel/helper-builder-binary-assignment-operator-visitor@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz#b939b43f8c37765443a19ae74ad8b15978e0a191" - integrity sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w== + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.15.4.tgz#21ad815f609b84ee0e3058676c33cf6d1670525f" + integrity sha512-P8o7JP2Mzi0SdC6eWr1zF+AEYvrsZa7GSY1lTayjF5XJhVH0kjLYUZPvTMflP7tBgZoe9gIhTa60QwFpqh/E0Q== dependencies: - "@babel/helper-explode-assignable-expression" "^7.14.5" - "@babel/types" "^7.14.5" + "@babel/helper-explode-assignable-expression" "^7.15.4" + "@babel/types" "^7.15.4" -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5", "@babel/helper-compilation-targets@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz#973df8cbd025515f3ff25db0c05efc704fa79818" - integrity sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A== +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9" + integrity sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ== dependencies: "@babel/compat-data" "^7.15.0" "@babel/helper-validator-option" "^7.14.5" browserslist "^4.16.6" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.0.tgz#c9a137a4d137b2d0e2c649acf536d7ba1a76c0f7" - integrity sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q== +"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz#7f977c17bd12a5fba363cb19bea090394bf37d2e" + integrity sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw== dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-member-expression-to-functions" "^7.15.0" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/helper-replace-supers" "^7.15.0" - "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/helper-annotate-as-pure" "^7.15.4" + "@babel/helper-function-name" "^7.15.4" + "@babel/helper-member-expression-to-functions" "^7.15.4" + "@babel/helper-optimise-call-expression" "^7.15.4" + "@babel/helper-replace-supers" "^7.15.4" + "@babel/helper-split-export-declaration" "^7.15.4" "@babel/helper-create-regexp-features-plugin@^7.14.5": version "7.14.5" @@ -157,115 +157,115 @@ resolve "^1.14.2" semver "^6.1.2" -"@babel/helper-explode-assignable-expression@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz#8aa72e708205c7bb643e45c73b4386cdf2a1f645" - integrity sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ== +"@babel/helper-explode-assignable-expression@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.15.4.tgz#f9aec9d219f271eaf92b9f561598ca6b2682600c" + integrity sha512-J14f/vq8+hdC2KoWLIQSsGrC9EFBKE4NFts8pfMpymfApds+fPqR30AOUWc4tyr56h9l/GA1Sxv2q3dLZWbQ/g== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.15.4" -"@babel/helper-function-name@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4" - integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ== +"@babel/helper-function-name@^7.14.5", "@babel/helper-function-name@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" + integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw== dependencies: - "@babel/helper-get-function-arity" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/types" "^7.14.5" + "@babel/helper-get-function-arity" "^7.15.4" + "@babel/template" "^7.15.4" + "@babel/types" "^7.15.4" -"@babel/helper-get-function-arity@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815" - integrity sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg== +"@babel/helper-get-function-arity@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" + integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.15.4" -"@babel/helper-hoist-variables@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d" - integrity sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ== +"@babel/helper-hoist-variables@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" + integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.15.4" -"@babel/helper-member-expression-to-functions@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz#0ddaf5299c8179f27f37327936553e9bba60990b" - integrity sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg== +"@babel/helper-member-expression-to-functions@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz#bfd34dc9bba9824a4658b0317ec2fd571a51e6ef" + integrity sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA== dependencies: - "@babel/types" "^7.15.0" + "@babel/types" "^7.15.4" -"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3" - integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ== +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5", "@babel/helper-module-imports@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f" + integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.15.4" -"@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz#679275581ea056373eddbe360e1419ef23783b08" - integrity sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg== +"@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.4.tgz#962cc629a7f7f9a082dd62d0307fa75fe8788d7c" + integrity sha512-9fHHSGE9zTC++KuXLZcB5FKgvlV83Ox+NLUmQTawovwlJ85+QMhk1CnVk406CQVj97LaWod6KVjl2Sfgw9Aktw== dependencies: - "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-replace-supers" "^7.15.0" - "@babel/helper-simple-access" "^7.14.8" - "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/helper-module-imports" "^7.15.4" + "@babel/helper-replace-supers" "^7.15.4" + "@babel/helper-simple-access" "^7.15.4" + "@babel/helper-split-export-declaration" "^7.15.4" "@babel/helper-validator-identifier" "^7.14.9" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.15.0" - "@babel/types" "^7.15.0" + "@babel/template" "^7.15.4" + "@babel/traverse" "^7.15.4" + "@babel/types" "^7.15.4" -"@babel/helper-optimise-call-expression@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c" - integrity sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA== +"@babel/helper-optimise-call-expression@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz#f310a5121a3b9cc52d9ab19122bd729822dee171" + integrity sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.15.4" "@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.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== -"@babel/helper-remap-async-to-generator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz#51439c913612958f54a987a4ffc9ee587a2045d6" - integrity sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A== +"@babel/helper-remap-async-to-generator@^7.14.5", "@babel/helper-remap-async-to-generator@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.15.4.tgz#2637c0731e4c90fbf58ac58b50b2b5a192fc970f" + integrity sha512-v53MxgvMK/HCwckJ1bZrq6dNKlmwlyRNYM6ypaRTdXWGOE2c1/SCa6dL/HimhPulGhZKw9W0QhREM583F/t0vQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-wrap-function" "^7.14.5" - "@babel/types" "^7.14.5" + "@babel/helper-annotate-as-pure" "^7.15.4" + "@babel/helper-wrap-function" "^7.15.4" + "@babel/types" "^7.15.4" -"@babel/helper-replace-supers@^7.14.5", "@babel/helper-replace-supers@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz#ace07708f5bf746bf2e6ba99572cce79b5d4e7f4" - integrity sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA== +"@babel/helper-replace-supers@^7.14.5", "@babel/helper-replace-supers@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz#52a8ab26ba918c7f6dee28628b07071ac7b7347a" + integrity sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw== dependencies: - "@babel/helper-member-expression-to-functions" "^7.15.0" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/traverse" "^7.15.0" - "@babel/types" "^7.15.0" + "@babel/helper-member-expression-to-functions" "^7.15.4" + "@babel/helper-optimise-call-expression" "^7.15.4" + "@babel/traverse" "^7.15.4" + "@babel/types" "^7.15.4" -"@babel/helper-simple-access@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz#82e1fec0644a7e775c74d305f212c39f8fe73924" - integrity sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg== +"@babel/helper-simple-access@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz#ac368905abf1de8e9781434b635d8f8674bcc13b" + integrity sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg== dependencies: - "@babel/types" "^7.14.8" + "@babel/types" "^7.15.4" -"@babel/helper-skip-transparent-expression-wrappers@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz#96f486ac050ca9f44b009fbe5b7d394cab3a0ee4" - integrity sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ== +"@babel/helper-skip-transparent-expression-wrappers@^7.14.5", "@babel/helper-skip-transparent-expression-wrappers@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz#707dbdba1f4ad0fa34f9114fc8197aec7d5da2eb" + integrity sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.15.4" -"@babel/helper-split-export-declaration@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a" - integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA== +"@babel/helper-split-export-declaration@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257" + integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.15.4" "@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9": version "7.14.9" @@ -277,24 +277,24 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== -"@babel/helper-wrap-function@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz#5919d115bf0fe328b8a5d63bcb610f51601f2bff" - integrity sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ== +"@babel/helper-wrap-function@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz#6f754b2446cfaf3d612523e6ab8d79c27c3a3de7" + integrity sha512-Y2o+H/hRV5W8QhIfTpRIBwl57y8PrZt6JM3V8FOo5qarjshHItyH5lXlpMfBfmBefOqSCpKZs/6Dxqp0E/U+uw== dependencies: - "@babel/helper-function-name" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" + "@babel/helper-function-name" "^7.15.4" + "@babel/template" "^7.15.4" + "@babel/traverse" "^7.15.4" + "@babel/types" "^7.15.4" -"@babel/helpers@^7.14.8": - version "7.15.3" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.15.3.tgz#c96838b752b95dcd525b4e741ed40bb1dc2a1357" - integrity sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g== +"@babel/helpers@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.15.4.tgz#5f40f02050a3027121a3cf48d497c05c555eaf43" + integrity sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ== dependencies: - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.15.0" - "@babel/types" "^7.15.0" + "@babel/template" "^7.15.4" + "@babel/traverse" "^7.15.4" + "@babel/types" "^7.15.4" "@babel/highlight@^7.14.5": version "7.14.5" @@ -305,27 +305,27 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.15.0", "@babel/parser@^7.2.3", "@babel/parser@^7.9.4": - version "7.15.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.3.tgz#3416d9bea748052cfcb63dbcc27368105b1ed862" - integrity sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA== +"@babel/parser@^7.1.0", "@babel/parser@^7.15.4", "@babel/parser@^7.15.5", "@babel/parser@^7.2.3", "@babel/parser@^7.9.4": + version "7.15.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.6.tgz#043b9aa3c303c0722e5377fef9197f4cf1796549" + integrity sha512-S/TSCcsRuCkmpUuoWijua0Snt+f3ewU/8spLo+4AXJCZfT0bVCzLD5MuOKdrx0mlAptbKzn5AdgEIIKXxXkz9Q== -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e" - integrity sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.15.4.tgz#dbdeabb1e80f622d9f0b583efb2999605e0a567e" + integrity sha512-eBnpsl9tlhPhpI10kU06JHnrYXwg3+V6CaP2idsCXNef0aeslpqyITXQ74Vfk5uHgY7IG7XP0yIH8b42KSzHog== dependencies: "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.15.4" "@babel/plugin-proposal-optional-chaining" "^7.14.5" -"@babel/plugin-proposal-async-generator-functions@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.9.tgz#7028dc4fa21dc199bbacf98b39bab1267d0eaf9a" - integrity sha512-d1lnh+ZnKrFKwtTYdw320+sQWCTwgkB9fmUhNXRADA4akR6wLjaruSGnIEUjpt9HCOwTr4ynFTKu19b7rFRpmw== +"@babel/plugin-proposal-async-generator-functions@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.4.tgz#f82aabe96c135d2ceaa917feb9f5fca31635277e" + integrity sha512-2zt2g5vTXpMC3OmK6uyjvdXptbhBXfA77XGrd3gh93zwG8lZYBLOBImiGBEG0RANu3JqKEACCz5CGk73OJROBw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.14.5" + "@babel/helper-remap-async-to-generator" "^7.15.4" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.14.5": @@ -336,12 +336,12 @@ "@babel/helper-create-class-features-plugin" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-proposal-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz#158e9e10d449c3849ef3ecde94a03d9f1841b681" - integrity sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg== +"@babel/plugin-proposal-class-static-block@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.15.4.tgz#3e7ca6128453c089e8b477a99f970c63fc1cb8d7" + integrity sha512-M682XWrrLNk3chXCjoPUQWOyYsB93B9z3mRyjtqqYJWDf2mfCdIYgDrA11cgNVhAQieaq6F2fn2f3wI0U4aTjA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.15.4" "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-class-static-block" "^7.14.5" @@ -393,16 +393,16 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz#5920a2b3df7f7901df0205974c0641b13fd9d363" - integrity sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g== +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.15.6": + version "7.15.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz#ef68050c8703d07b25af402cb96cf7f34a68ed11" + integrity sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg== dependencies: - "@babel/compat-data" "^7.14.7" - "@babel/helper-compilation-targets" "^7.14.5" + "@babel/compat-data" "^7.15.0" + "@babel/helper-compilation-targets" "^7.15.4" "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.14.5" + "@babel/plugin-transform-parameters" "^7.15.4" "@babel/plugin-proposal-optional-catch-binding@^7.14.5": version "7.14.5" @@ -429,13 +429,13 @@ "@babel/helper-create-class-features-plugin" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-proposal-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz#9f65a4d0493a940b4c01f8aa9d3f1894a587f636" - integrity sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q== +"@babel/plugin-proposal-private-property-in-object@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.15.4.tgz#55c5e3b4d0261fd44fe637e3f624cfb0f484e3e5" + integrity sha512-X0UTixkLf0PCCffxgu5/1RQyGGbgZuKoI+vXP4iSbJSYwPb7hu06omsFGBvQ9lJEvwgrxHdS8B5nbfcd8GyUNA== dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-create-class-features-plugin" "^7.14.5" + "@babel/helper-annotate-as-pure" "^7.15.4" + "@babel/helper-create-class-features-plugin" "^7.15.4" "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" @@ -589,24 +589,24 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-block-scoping@^7.14.5": +"@babel/plugin-transform-block-scoping@^7.15.3": version "7.15.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz#94c81a6e2fc230bcce6ef537ac96a1e4d2b3afaf" integrity sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q== dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-classes@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.9.tgz#2a391ffb1e5292710b00f2e2c210e1435e7d449f" - integrity sha512-NfZpTcxU3foGWbl4wxmZ35mTsYJy8oQocbeIMoDAGGFarAmSQlL+LWMkDx/tj6pNotpbX3rltIA4dprgAPOq5A== +"@babel/plugin-transform-classes@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.15.4.tgz#50aee17aaf7f332ae44e3bce4c2e10534d5d3bf1" + integrity sha512-Yjvhex8GzBmmPQUvpXRPWQ9WnxXgAFuZSrqOK/eJlOGIXwvv8H3UEdUigl1gb/bnjTrln+e8bkZUYCBt/xYlBg== dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-optimise-call-expression" "^7.14.5" + "@babel/helper-annotate-as-pure" "^7.15.4" + "@babel/helper-function-name" "^7.15.4" + "@babel/helper-optimise-call-expression" "^7.15.4" "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/helper-replace-supers" "^7.15.4" + "@babel/helper-split-export-declaration" "^7.15.4" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.14.5": @@ -646,10 +646,10 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-for-of@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz#dae384613de8f77c196a8869cbf602a44f7fc0eb" - integrity sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA== +"@babel/plugin-transform-for-of@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.15.4.tgz#25c62cce2718cfb29715f416e75d5263fb36a8c2" + integrity sha512-DRTY9fA751AFBDh2oxydvVm4SYevs5ILTWLs6xKXps4Re/KG5nfUkr+TdHCrRWB8C69TlzVgA9b3RmGWmgN9LA== dependencies: "@babel/helper-plugin-utils" "^7.14.5" @@ -684,25 +684,25 @@ "@babel/helper-plugin-utils" "^7.14.5" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.0.tgz#3305896e5835f953b5cdb363acd9e8c2219a5281" - integrity sha512-3H/R9s8cXcOGE8kgMlmjYYC9nqr5ELiPkJn4q0mypBrjhYQoc+5/Maq69vV4xRPWnkzZuwJPf5rArxpB/35Cig== +"@babel/plugin-transform-modules-commonjs@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz#8201101240eabb5a76c08ef61b2954f767b6b4c1" + integrity sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA== dependencies: - "@babel/helper-module-transforms" "^7.15.0" + "@babel/helper-module-transforms" "^7.15.4" "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-simple-access" "^7.14.8" + "@babel/helper-simple-access" "^7.15.4" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz#c75342ef8b30dcde4295d3401aae24e65638ed29" - integrity sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA== +"@babel/plugin-transform-modules-systemjs@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz#b42890c7349a78c827719f1d2d0cd38c7d268132" + integrity sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw== dependencies: - "@babel/helper-hoist-variables" "^7.14.5" - "@babel/helper-module-transforms" "^7.14.5" + "@babel/helper-hoist-variables" "^7.15.4" + "@babel/helper-module-transforms" "^7.15.4" "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-identifier" "^7.14.5" + "@babel/helper-validator-identifier" "^7.14.9" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-umd@^7.14.5": @@ -735,10 +735,10 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-replace-supers" "^7.14.5" -"@babel/plugin-transform-parameters@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz#49662e86a1f3ddccac6363a7dfb1ff0a158afeb3" - integrity sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA== +"@babel/plugin-transform-parameters@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.15.4.tgz#5f2285cc3160bf48c8502432716b48504d29ed62" + integrity sha512-9WB/GUTO6lvJU3XQsSr6J/WKvBC2hcs4Pew8YxZagi6GkTdniyqp8On5kqdK8MN0LMeu0mGbhPN+O049NV/9FQ== dependencies: "@babel/helper-plugin-utils" "^7.14.5" @@ -812,11 +812,11 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-transform-typescript@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.0.tgz#553f230b9d5385018716586fc48db10dd228eb7e" - integrity sha512-WIIEazmngMEEHDaPTx0IZY48SaAmjVWe3TRSX7cmJXn0bEv9midFzAjxiruOWYIVf5iQ10vFx7ASDpgEO08L5w== + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.4.tgz#db7a062dcf8be5fc096bc0eeb40a13fbfa1fa251" + integrity sha512-sM1/FEjwYjXvMwu1PJStH11kJ154zd/lpY56NQJ5qH2D0mabMv1CAy/kdvS9RP4Xgfj9fBBA3JiSLdDHgXdzOA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.15.0" + "@babel/helper-create-class-features-plugin" "^7.15.4" "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript" "^7.14.5" @@ -844,29 +844,29 @@ regenerator-runtime "^0.13.4" "@babel/preset-env@^7.12.11": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.15.0.tgz#e2165bf16594c9c05e52517a194bf6187d6fe464" - integrity sha512-FhEpCNFCcWW3iZLg0L2NPE9UerdtsCR6ZcsGHUX6Om6kbCQeL5QZDqFDmeNHC6/fy6UH3jEge7K4qG5uC9In0Q== + version "7.15.6" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.15.6.tgz#0f3898db9d63d320f21b17380d8462779de57659" + integrity sha512-L+6jcGn7EWu7zqaO2uoTDjjMBW+88FXzV8KvrBl2z6MtRNxlsmUNRlZPaNNPUTgqhyC5DHNFk/2Jmra+ublZWw== dependencies: "@babel/compat-data" "^7.15.0" - "@babel/helper-compilation-targets" "^7.15.0" + "@babel/helper-compilation-targets" "^7.15.4" "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-validator-option" "^7.14.5" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.14.5" - "@babel/plugin-proposal-async-generator-functions" "^7.14.9" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.15.4" + "@babel/plugin-proposal-async-generator-functions" "^7.15.4" "@babel/plugin-proposal-class-properties" "^7.14.5" - "@babel/plugin-proposal-class-static-block" "^7.14.5" + "@babel/plugin-proposal-class-static-block" "^7.15.4" "@babel/plugin-proposal-dynamic-import" "^7.14.5" "@babel/plugin-proposal-export-namespace-from" "^7.14.5" "@babel/plugin-proposal-json-strings" "^7.14.5" "@babel/plugin-proposal-logical-assignment-operators" "^7.14.5" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.5" "@babel/plugin-proposal-numeric-separator" "^7.14.5" - "@babel/plugin-proposal-object-rest-spread" "^7.14.7" + "@babel/plugin-proposal-object-rest-spread" "^7.15.6" "@babel/plugin-proposal-optional-catch-binding" "^7.14.5" "@babel/plugin-proposal-optional-chaining" "^7.14.5" "@babel/plugin-proposal-private-methods" "^7.14.5" - "@babel/plugin-proposal-private-property-in-object" "^7.14.5" + "@babel/plugin-proposal-private-property-in-object" "^7.15.4" "@babel/plugin-proposal-unicode-property-regex" "^7.14.5" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" @@ -885,25 +885,25 @@ "@babel/plugin-transform-arrow-functions" "^7.14.5" "@babel/plugin-transform-async-to-generator" "^7.14.5" "@babel/plugin-transform-block-scoped-functions" "^7.14.5" - "@babel/plugin-transform-block-scoping" "^7.14.5" - "@babel/plugin-transform-classes" "^7.14.9" + "@babel/plugin-transform-block-scoping" "^7.15.3" + "@babel/plugin-transform-classes" "^7.15.4" "@babel/plugin-transform-computed-properties" "^7.14.5" "@babel/plugin-transform-destructuring" "^7.14.7" "@babel/plugin-transform-dotall-regex" "^7.14.5" "@babel/plugin-transform-duplicate-keys" "^7.14.5" "@babel/plugin-transform-exponentiation-operator" "^7.14.5" - "@babel/plugin-transform-for-of" "^7.14.5" + "@babel/plugin-transform-for-of" "^7.15.4" "@babel/plugin-transform-function-name" "^7.14.5" "@babel/plugin-transform-literals" "^7.14.5" "@babel/plugin-transform-member-expression-literals" "^7.14.5" "@babel/plugin-transform-modules-amd" "^7.14.5" - "@babel/plugin-transform-modules-commonjs" "^7.15.0" - "@babel/plugin-transform-modules-systemjs" "^7.14.5" + "@babel/plugin-transform-modules-commonjs" "^7.15.4" + "@babel/plugin-transform-modules-systemjs" "^7.15.4" "@babel/plugin-transform-modules-umd" "^7.14.5" "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.9" "@babel/plugin-transform-new-target" "^7.14.5" "@babel/plugin-transform-object-super" "^7.14.5" - "@babel/plugin-transform-parameters" "^7.14.5" + "@babel/plugin-transform-parameters" "^7.15.4" "@babel/plugin-transform-property-literals" "^7.14.5" "@babel/plugin-transform-regenerator" "^7.14.5" "@babel/plugin-transform-reserved-words" "^7.14.5" @@ -915,7 +915,7 @@ "@babel/plugin-transform-unicode-escapes" "^7.14.5" "@babel/plugin-transform-unicode-regex" "^7.14.5" "@babel/preset-modules" "^0.1.4" - "@babel/types" "^7.15.0" + "@babel/types" "^7.15.6" babel-plugin-polyfill-corejs2 "^0.2.2" babel-plugin-polyfill-corejs3 "^0.2.2" babel-plugin-polyfill-regenerator "^0.2.2" @@ -954,40 +954,40 @@ source-map-support "^0.5.16" "@babel/runtime@^7.12.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4": - version "7.15.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.3.tgz#2e1c2880ca118e5b2f9988322bd8a7656a32502b" - integrity sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA== + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" + integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.14.5", "@babel/template@^7.3.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" - integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== +"@babel/template@^7.15.4", "@babel/template@^7.3.3": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" + integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg== dependencies: "@babel/code-frame" "^7.14.5" - "@babel/parser" "^7.14.5" - "@babel/types" "^7.14.5" + "@babel/parser" "^7.15.4" + "@babel/types" "^7.15.4" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98" - integrity sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw== +"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.13.0", "@babel/traverse@^7.15.4": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" + integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== dependencies: "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.0" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-hoist-variables" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/parser" "^7.15.0" - "@babel/types" "^7.15.0" + "@babel/generator" "^7.15.4" + "@babel/helper-function-name" "^7.15.4" + "@babel/helper-hoist-variables" "^7.15.4" + "@babel/helper-split-export-declaration" "^7.15.4" + "@babel/parser" "^7.15.4" + "@babel/types" "^7.15.4" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.15.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd" - integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ== +"@babel/types@^7.0.0", "@babel/types@^7.15.4", "@babel/types@^7.15.6", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.15.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" + integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== dependencies: "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" @@ -1257,7 +1257,7 @@ dependencies: "@octokit/types" "^6.0.3" -"@octokit/core@^3.4.0", "@octokit/core@^3.5.0": +"@octokit/core@^3.4.0", "@octokit/core@^3.5.1": version "3.5.1" resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.5.1.tgz#8601ceeb1ec0e1b1b8217b960a413ed8e947809b" integrity sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw== @@ -1280,37 +1280,37 @@ universal-user-agent "^6.0.0" "@octokit/graphql@^4.5.8": - version "4.6.4" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.6.4.tgz#0c3f5bed440822182e972317122acb65d311a5ed" - integrity sha512-SWTdXsVheRmlotWNjKzPOb6Js6tjSqA2a8z9+glDJng0Aqjzti8MEWOtuT8ZSu6wHnci7LZNuarE87+WJBG4vg== + version "4.8.0" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.8.0.tgz#664d9b11c0e12112cbf78e10f49a05959aa22cc3" + integrity sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg== dependencies: "@octokit/request" "^5.6.0" "@octokit/types" "^6.0.3" universal-user-agent "^6.0.0" -"@octokit/openapi-types@^9.5.0": - version "9.7.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-9.7.0.tgz#9897cdefd629cd88af67b8dbe2e5fb19c63426b2" - integrity sha512-TUJ16DJU8mekne6+KVcMV5g6g/rJlrnIKn7aALG9QrNpnEipFc1xjoarh0PKaAWf2Hf+HwthRKYt+9mCm5RsRg== +"@octokit/openapi-types@^10.1.5": + version "10.2.1" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-10.2.1.tgz#825a705e617be3043394101256bd7b5b04c4e249" + integrity sha512-IN33Fmzjw2AQEXOsfuInddirTQOO5l7lKcbfPIUPPdJqj1D5bdUiqgu/SmOdGrv1Lx+Pxqq2h3dYRNogKm0v9w== -"@octokit/plugin-paginate-rest@^2.13.3", "@octokit/plugin-paginate-rest@^2.6.2": - version "2.15.1" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.15.1.tgz#264189dd3ce881c6c33758824aac05a4002e056a" - integrity sha512-47r52KkhQDkmvUKZqXzA1lKvcyJEfYh3TKAIe5+EzMeyDM3d+/s5v11i2gTk8/n6No6DPi3k5Ind6wtDbo/AEg== +"@octokit/plugin-paginate-rest@^2.13.3", "@octokit/plugin-paginate-rest@^2.16.0": + version "2.16.2" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.2.tgz#9ca5bebbaf3e6672b345502f89ae4ef3be6c2ddd" + integrity sha512-WF5/MTPnFgYH6rMGuxBvbxX2S/3ygNWylakgD7njKES0Qwk5e+d/L6r/BYXSw7B6xJJ3hlwIAmUmOxxYrR+Q8A== dependencies: - "@octokit/types" "^6.24.0" + "@octokit/types" "^6.27.2" -"@octokit/plugin-request-log@^1.0.2": +"@octokit/plugin-request-log@^1.0.4": version "1.0.4" resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== -"@octokit/plugin-rest-endpoint-methods@5.8.0", "@octokit/plugin-rest-endpoint-methods@^5.1.1": - version "5.8.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.8.0.tgz#33b342fe41f2603fdf8b958e6652103bb3ea3f3b" - integrity sha512-qeLZZLotNkoq+it6F+xahydkkbnvSK0iDjlXFo3jNTB+Ss0qIbYQb9V/soKLMkgGw8Q2sHjY5YEXiA47IVPp4A== +"@octokit/plugin-rest-endpoint-methods@^5.1.1", "@octokit/plugin-rest-endpoint-methods@^5.9.0": + version "5.10.3" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.10.3.tgz#9207e8e893d980d7828d85950bbb460b187146f2" + integrity sha512-eAT4gje+VR9xdSlhuHWNXsNLpiODqdqz8jqShMgaxRH82Le2nS6EV6LAo3QPZ05Fso5oGmDfJF6eq9vs1cEhdA== dependencies: - "@octokit/types" "^6.25.0" + "@octokit/types" "^6.27.2" deprecation "^2.3.1" "@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0": @@ -1335,21 +1335,21 @@ universal-user-agent "^6.0.0" "@octokit/rest@^18.6.7": - version "18.9.1" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.9.1.tgz#db1d7ac1d7b10e908f7d4b78fe35a392554ccb26" - integrity sha512-idZ3e5PqXVWOhtZYUa546IDHTHjkGZbj3tcJsN0uhCy984KD865e8GB2WbYDc2ZxFuJRiyd0AftpL2uPNhF+UA== + version "18.10.0" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.10.0.tgz#8a0add9611253e0e31d3ed5b4bc941a3795a7648" + integrity sha512-esHR5OKy38bccL/sajHqZudZCvmv4yjovMJzyXlphaUo7xykmtOdILGJ3aAm0mFHmMLmPFmDMJXf39cAjNJsrw== dependencies: - "@octokit/core" "^3.5.0" - "@octokit/plugin-paginate-rest" "^2.6.2" - "@octokit/plugin-request-log" "^1.0.2" - "@octokit/plugin-rest-endpoint-methods" "5.8.0" + "@octokit/core" "^3.5.1" + "@octokit/plugin-paginate-rest" "^2.16.0" + "@octokit/plugin-request-log" "^1.0.4" + "@octokit/plugin-rest-endpoint-methods" "^5.9.0" -"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.24.0", "@octokit/types@^6.25.0": - version "6.25.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.25.0.tgz#c8e37e69dbe7ce55ed98ee63f75054e7e808bf1a" - integrity sha512-bNvyQKfngvAd/08COlYIN54nRgxskmejgywodizQNyiKoXmWRAjKup2/LYwm+T9V0gsKH6tuld1gM0PzmOiB4Q== +"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.27.2": + version "6.27.2" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.27.2.tgz#b6f88d002aa06104f46ccaec0aaa8a5de1bf262c" + integrity sha512-AgajmAJh7LhStgaEaNoY1N7znst2q07CKZVdnVB/V4tmitMbk+qijmD0IkkSKulXE5RVLbJjQikJF9+XLqhsVA== dependencies: - "@octokit/openapi-types" "^9.5.0" + "@octokit/openapi-types" "^10.1.5" "@sinonjs/commons@^1.7.0": version "1.8.3" @@ -1371,14 +1371,14 @@ integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== "@types/babel-types@*", "@types/babel-types@^7.0.0": - version "7.0.10" - resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.10.tgz#c12a182ecf326c26acc7b18a301827594bab6df9" - integrity sha512-g7zrcqL4MiRu3jZzdZZYk0g0KcKk2fddXazSdP1PacEpmjihRsNGU50aaEKnPFuKzfN7WkRktUiCXvs4zU9XXQ== + 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.0.0", "@types/babel__core@^7.1.7": - version "7.1.15" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.15.tgz#2ccfb1ad55a02c83f8e0ad327cbc332f55eb1024" - integrity sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew== + version "7.1.16" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.16.tgz#bc12c74b7d65e82d29876b5d0baf5c625ac58702" + integrity sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -1474,14 +1474,14 @@ integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== "@types/node@*": - version "16.7.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.7.1.tgz#c6b9198178da504dfca1fd0be9b2e1002f1586f0" - integrity sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A== + version "16.9.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.1.tgz#0611b37db4246c937feef529ddcc018cf8e35708" + integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@12": - version "12.20.20" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.20.tgz#ce3d6c13c15c5e622a85efcd3a1cb2d9c7fa43a6" - integrity sha512-kqmxiJg4AT7rsSPIhO6eoBIx9mNwwpeH42yjtgQh6X2ANSpLpvToMXv+LMFdfxpwG1FZXZ41OGZMiUAtbBLEvg== + version "12.20.24" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.24.tgz#c37ac69cb2948afb4cef95f424fa0037971a9a5c" + integrity sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -1531,72 +1531,72 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^4.17.0": - version "4.29.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.3.tgz#95cb8029a8bd8bd9c7f4ab95074a7cb2115adefa" - integrity sha512-tBgfA3K/3TsZY46ROGvoRxQr1wBkclbVqRQep97MjVHJzcRBURRY3sNFqLk0/Xr//BY5hM9H2p/kp+6qim85SA== + version "4.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.1.tgz#e938603a136f01dcabeece069da5fb2e331d4498" + integrity sha512-UDqhWmd5i0TvPLmbK5xY3UZB0zEGseF+DHPghZ37Sb83Qd3p8ujhvAtkU4OF46Ka5Pm5kWvFIx0cCTBFKo0alA== dependencies: - "@typescript-eslint/experimental-utils" "4.29.3" - "@typescript-eslint/scope-manager" "4.29.3" + "@typescript-eslint/experimental-utils" "4.31.1" + "@typescript-eslint/scope-manager" "4.31.1" debug "^4.3.1" functional-red-black-tree "^1.0.1" regexpp "^3.1.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.29.3": - version "4.29.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.3.tgz#52e437a689ccdef73e83c5106b34240a706f15e1" - integrity sha512-ffIvbytTVWz+3keg+Sy94FG1QeOvmV9dP2YSdLFHw/ieLXWCa3U1TYu8IRCOpMv2/SPS8XqhM1+ou1YHsdzKrg== +"@typescript-eslint/experimental-utils@4.31.1": + version "4.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.1.tgz#0c900f832f270b88e13e51753647b02d08371ce5" + integrity sha512-NtoPsqmcSsWty0mcL5nTZXMf7Ei0Xr2MT8jWjXMVgRK0/1qeQ2jZzLFUh4QtyJ4+/lPUyMw5cSfeeME+Zrtp9Q== dependencies: "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.29.3" - "@typescript-eslint/types" "4.29.3" - "@typescript-eslint/typescript-estree" "4.29.3" + "@typescript-eslint/scope-manager" "4.31.1" + "@typescript-eslint/types" "4.31.1" + "@typescript-eslint/typescript-estree" "4.31.1" eslint-scope "^5.1.1" eslint-utils "^3.0.0" "@typescript-eslint/parser@^4.17.0": - version "4.29.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.29.3.tgz#2ac25535f34c0e98f50c0e6b28c679c2357d45f2" - integrity sha512-jrHOV5g2u8ROghmspKoW7pN8T/qUzk0+DITun0MELptvngtMrwUJ1tv5zMI04CYVEUsSrN4jV7AKSv+I0y0EfQ== + version "4.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.31.1.tgz#8f9a2672033e6f6d33b1c0260eebdc0ddf539064" + integrity sha512-dnVZDB6FhpIby6yVbHkwTKkn2ypjVIfAR9nh+kYsA/ZL0JlTsd22BiDjouotisY3Irmd3OW1qlk9EI5R8GrvRQ== dependencies: - "@typescript-eslint/scope-manager" "4.29.3" - "@typescript-eslint/types" "4.29.3" - "@typescript-eslint/typescript-estree" "4.29.3" + "@typescript-eslint/scope-manager" "4.31.1" + "@typescript-eslint/types" "4.31.1" + "@typescript-eslint/typescript-estree" "4.31.1" debug "^4.3.1" -"@typescript-eslint/scope-manager@4.29.3": - version "4.29.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.3.tgz#497dec66f3a22e459f6e306cf14021e40ec86e19" - integrity sha512-x+w8BLXO7iWPkG5mEy9bA1iFRnk36p/goVlYobVWHyDw69YmaH9q6eA+Fgl7kYHmFvWlebUTUfhtIg4zbbl8PA== +"@typescript-eslint/scope-manager@4.31.1": + version "4.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.31.1.tgz#0c21e8501f608d6a25c842fcf59541ef4f1ab561" + integrity sha512-N1Uhn6SqNtU2XpFSkD4oA+F0PfKdWHyr4bTX0xTj8NRx1314gBDRL1LUuZd5+L3oP+wo6hCbZpaa1in6SwMcVQ== dependencies: - "@typescript-eslint/types" "4.29.3" - "@typescript-eslint/visitor-keys" "4.29.3" + "@typescript-eslint/types" "4.31.1" + "@typescript-eslint/visitor-keys" "4.31.1" -"@typescript-eslint/types@4.29.3": - version "4.29.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.3.tgz#d7980c49aef643d0af8954c9f14f656b7fd16017" - integrity sha512-s1eV1lKNgoIYLAl1JUba8NhULmf+jOmmeFO1G5MN/RBCyyzg4TIOfIOICVNC06lor+Xmy4FypIIhFiJXOknhIg== +"@typescript-eslint/types@4.31.1": + version "4.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.31.1.tgz#5f255b695627a13401d2fdba5f7138bc79450d66" + integrity sha512-kixltt51ZJGKENNW88IY5MYqTBA8FR0Md8QdGbJD2pKZ+D5IvxjTYDNtJPDxFBiXmka2aJsITdB1BtO1fsgmsQ== -"@typescript-eslint/typescript-estree@4.29.3": - version "4.29.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.3.tgz#1bafad610015c4ded35c85a70b6222faad598b40" - integrity sha512-45oQJA0bxna4O5TMwz55/TpgjX1YrAPOI/rb6kPgmdnemRZx/dB0rsx+Ku8jpDvqTxcE1C/qEbVHbS3h0hflag== +"@typescript-eslint/typescript-estree@4.31.1": + version "4.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.1.tgz#4a04d5232cf1031232b7124a9c0310b577a62d17" + integrity sha512-EGHkbsUvjFrvRnusk6yFGqrqMBTue5E5ROnS5puj3laGQPasVUgwhrxfcgkdHNFECHAewpvELE1Gjv0XO3mdWg== dependencies: - "@typescript-eslint/types" "4.29.3" - "@typescript-eslint/visitor-keys" "4.29.3" + "@typescript-eslint/types" "4.31.1" + "@typescript-eslint/visitor-keys" "4.31.1" debug "^4.3.1" globby "^11.0.3" is-glob "^4.0.1" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.29.3": - version "4.29.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.3.tgz#c691760a00bd86bf8320d2a90a93d86d322f1abf" - integrity sha512-MGGfJvXT4asUTeVs0Q2m+sY63UsfnA+C/FDgBKV3itLBmM9H0u+URcneePtkd0at1YELmZK6HSolCqM4Fzs6yA== +"@typescript-eslint/visitor-keys@4.31.1": + version "4.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.1.tgz#f2e7a14c7f20c4ae07d7fc3c5878c4441a1da9cc" + integrity sha512-PCncP8hEqKw6SOJY+3St4LVtoZpPPn+Zlpm7KW5xnviMhdqcsBty4Lsg4J/VECpJjw1CkROaZhH4B8M1OfnXTQ== dependencies: - "@typescript-eslint/types" "4.29.3" + "@typescript-eslint/types" "4.31.1" eslint-visitor-keys "^2.0.0" JSONStream@^1.0.3: @@ -1662,9 +1662,9 @@ acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.2.4: - version "8.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" - integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== + version "8.5.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" + integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== agent-base@6: version "6.0.2" @@ -1684,9 +1684,9 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: uri-js "^4.2.2" ajv@^8.0.1: - version "8.6.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" - integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w== + version "8.6.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.3.tgz#11a66527761dc3e9a3845ea775d2d3c0414e8764" + integrity sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -1703,9 +1703,9 @@ align-text@^0.1.1, align-text@^0.1.3: repeat-string "^1.5.2" allchange@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/allchange/-/allchange-1.0.2.tgz#86b9190e12b7ede4f230ae763cbd504c48fd907b" - integrity sha512-qJv1t2yvBThkes8g/dPMt8CGu+04U+q5QjCJn2Ngp92edZU8DJBfKGyGXo7w1iV48LVuQKQDfMsdIWhP7zHdlQ== + version "1.0.3" + resolved "https://registry.yarnpkg.com/allchange/-/allchange-1.0.3.tgz#f8814ddfbcfe39a01bf4570778ee7e6d9ff0ebb3" + integrity sha512-UZkfz5SkNEMFQFLr8vZcXHaph2EbJxmkVNF5Nt6D9RIa5pmAar7oAMfNdda714jg7IQijvaFty5PYazXLgd5WA== dependencies: "@actions/core" "^1.4.0" "@actions/github" "^5.0.0" @@ -1739,9 +1739,9 @@ ansi-regex@^2.1.1: integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^3.2.1: version "3.2.1" @@ -1887,10 +1887,10 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -available-typed-arrays@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9" - integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA== +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== aws-sign2@~0.7.0: version "0.7.0" @@ -2296,14 +2296,14 @@ browserify@^17.0.0: vm-browserify "^1.0.0" xtend "^4.0.0" -browserslist@^4.16.6, browserslist@^4.16.8: - version "4.16.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.8.tgz#cb868b0b554f137ba6e33de0ecff2eda403c4fb0" - integrity sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ== +browserslist@^4.16.6, browserslist@^4.17.0: + version "4.17.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.0.tgz#1fcd81ec75b41d6d4994fb0831b92ac18c01649c" + integrity sha512-g2BJ2a0nEYvEFQC208q8mVAhfNwpZ5Mu8BwgtCdZKO3qx98HChmeg448fPdUzld8aFmfLgVh7yymqV+q1lJZ5g== dependencies: - caniuse-lite "^1.0.30001251" + caniuse-lite "^1.0.30001254" colorette "^1.3.0" - electron-to-chromium "^1.3.811" + electron-to-chromium "^1.3.830" escalade "^3.1.1" node-releases "^1.1.75" @@ -2357,9 +2357,9 @@ builtin-status-codes@^3.0.0: integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= c8@^7.6.0: - version "7.8.0" - resolved "https://registry.yarnpkg.com/c8/-/c8-7.8.0.tgz#8fcfe848587d9d5796f22e9b0546a387a66d1b3b" - integrity sha512-x2Bx+IIEd608B1LmjiNQ/kizRPkCWo5XzuV57J9afPjAHSnYXALwbCSOkQ7cSaNXBNblfqcvdycj+klmL+j6yA== + version "7.9.0" + resolved "https://registry.yarnpkg.com/c8/-/c8-7.9.0.tgz#e63b9a22c8b4adbf6a8c8cb6194ee086b3e13c24" + integrity sha512-aQ7dC8gASnKdBwHUuYuzsdKCEDrKnWr7ZuZUnf4CNAL81oyKloKrs7H7zYvcrmCtIrMToudBSUhq2q+LLBMvgg== dependencies: "@bcoe/v8-coverage" "^0.2.3" "@istanbuljs/schema" "^0.1.2" @@ -2422,10 +2422,10 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== -caniuse-lite@^1.0.30001251: - version "1.0.30001251" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz#6853a606ec50893115db660f82c094d18f096d85" - integrity sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A== +caniuse-lite@^1.0.30001254: + version "1.0.30001257" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001257.tgz#150aaf649a48bee531104cfeda57f92ce587f6e5" + integrity sha512-JN49KplOgHSXpIsVSF+LUyhD8PUp6xPpAXeRrrcBh4KBeP7W864jHn6RvzJgDlrReyeVjMFJL3PLpPvKIxlIHA== capture-exit@^2.0.0: version "2.0.0" @@ -2624,9 +2624,9 @@ color-name@~1.1.4: integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== colorette@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.3.0.tgz#ff45d2f0edb244069d3b772adeb04fed38d0a0af" - integrity sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w== + version "1.4.0" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" + integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== combine-source-map@^0.8.0, combine-source-map@~0.8.0: version "0.8.0" @@ -2733,11 +2733,11 @@ copy-descriptor@^0.1.0: integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js-compat@^3.14.0, core-js-compat@^3.16.0: - version "3.16.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.16.3.tgz#ae12a6e20505a1d79fbd16b6689dfc77fc989114" - integrity sha512-A/OtSfSJQKLAFRVd4V0m6Sep9lPdjD8bpN8v3tCCGwE0Tmh0hOiVDm9tw6mXmWOKOSZIyr3EkywPo84cJjGvIQ== + version "3.17.3" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.17.3.tgz#b39c8e4dec71ecdc735c653ce5233466e561324e" + integrity sha512-+in61CKYs4hQERiADCJsdgewpdl/X0GhEX77pjKgbeibXviIt2oxEjTc8O2fqHX8mDdBrDvX8MYD/RYsBv4OiA== dependencies: - browserslist "^4.16.8" + browserslist "^4.17.0" semver "7.0.0" core-js@^2.4.0, core-js@^2.5.3, core-js@^2.6.5: @@ -2746,15 +2746,20 @@ core-js@^2.4.0, core-js@^2.5.3, core-js@^2.6.5: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.14.0: - version "3.16.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.16.3.tgz#1f2d43c51a9ed014cc6c83440af14697ae4b75f2" - integrity sha512-lM3GftxzHNtPNUJg0v4pC2RC6puwMd6VZA7vXUczi+SKmCWSf4JwO89VJGMqbzmB7jlK7B5hr3S64PqwFL49cA== + version "3.17.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.17.3.tgz#8e8bd20e91df9951e903cabe91f9af4a0895bc1e" + integrity sha512-lyvajs+wd8N1hXfzob1LdOCCHFU4bGMbqqmLn1Q4QlCpDqWPpGf+p0nj+LNrvDDG33j0hZXw2nsvvVpHysxyNw== -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -2904,9 +2909,9 @@ decode-uri-component@^0.2.0: integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= deep-is@^0.1.3, deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + 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== deepmerge@^4.2.2: version "4.2.2" @@ -3074,10 +3079,10 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -electron-to-chromium@^1.3.811: - version "1.3.817" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.817.tgz#911b4775b5d9fa0c4729d4694adc81de85d8d8f6" - integrity sha512-Vw0Faepf2Id9Kf2e97M/c99qf168xg86JLKDxivvlpBQ9KDtjSeX0v+TiuSE25PqeQfTz+NJs375b64ca3XOIQ== +electron-to-chromium@^1.3.830: + version "1.3.838" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.838.tgz#d178b34a268c750c0444ba69e4c94d4c4fb3aa0d" + integrity sha512-65O6UJiyohFAdX/nc6KJ0xG/4zOn7XCO03kQNNbCeMRGxlWTLzc6Uyi0tFNQuuGWqySZJi8CD2KXPXySVYmzMA== elliptic@^6.5.3: version "6.5.4" @@ -3128,22 +3133,23 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2, es-abstract@^1.18.5: - version "1.18.5" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.5.tgz#9b10de7d4c206a3581fd5b2124233e04db49ae19" - integrity sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA== +es-abstract@^1.18.0-next.2, es-abstract@^1.18.2, es-abstract@^1.18.5, es-abstract@^1.18.6: + version "1.18.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.6.tgz#2c44e3ea7a6255039164d26559777a6d978cb456" + integrity sha512-kAeIT4cku5eNLNuUKhlmtuk1/TRZvQoYccn6TO0cSVdf1kzB0T7+dYuVK9MWM7l+/53W2Q8M7N2c6MQvhXFcUQ== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" has "^1.0.3" has-symbols "^1.0.2" internal-slot "^1.0.3" - is-callable "^1.2.3" + is-callable "^1.2.4" is-negative-zero "^2.0.1" - is-regex "^1.1.3" - is-string "^1.0.6" + is-regex "^1.1.4" + is-string "^1.0.7" object-inspect "^1.11.0" object-keys "^1.1.1" object.assign "^4.1.2" @@ -3571,14 +3577,14 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fast-safe-stringify@^2.0.7: - version "2.0.8" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz#dc2af48c46cf712b683e849b2bbd446b32de936f" - integrity sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag== + version "2.1.1" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" + integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== fastq@^1.6.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.12.0.tgz#ed7b6ab5d62393fb2cc591c853652a5c318bf794" - integrity sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg== + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== dependencies: reusify "^1.0.4" @@ -3798,6 +3804,14 @@ get-stream@^5.0.0: dependencies: pump "^3.0.0" +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -4201,7 +4215,7 @@ is-buffer@^1.1.0, is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.0.4, is-callable@^1.1.4, is-callable@^1.2.3, is-callable@^1.2.4: +is-callable@^1.0.4, is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== @@ -4396,7 +4410,7 @@ is-promise@^2.0.0, is-promise@^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.3, is-regex@^1.1.4: +is-regex@^1.0.3, 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== @@ -4419,7 +4433,7 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-string@^1.0.5, is-string@^1.0.6, is-string@^1.0.7: +is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== @@ -4433,12 +4447,12 @@ is-symbol@^1.0.2, is-symbol@^1.0.3, is-symbol@^1.0.4: dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.3, is-typed-array@^1.1.6: - version "1.1.7" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.7.tgz#881ddc660b13cb8423b2090fa88c0fe37a83eb2f" - integrity sha512-VxlpTBGknhQ3o7YiVjIhdLU6+oD8dPz/79vvvH4F+S/c8608UCVa9fgDpa1kZgFoUST2DCgacc70UszKgzKuvA== +is-typed-array@^1.1.3, is-typed-array@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.8.tgz#cbaa6585dc7db43318bc5b89523ea384a6f65e79" + integrity sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA== dependencies: - available-typed-arrays "^1.0.4" + available-typed-arrays "^1.0.5" call-bind "^1.0.2" es-abstract "^1.18.5" foreach "^2.0.5" @@ -5583,9 +5597,9 @@ node-dir@^0.1.10: minimatch "^3.0.2" node-fetch@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + version "2.6.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.2.tgz#986996818b73785e47b1965cc34eb093a1d464d0" + integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA== node-int64@^0.4.0: version "0.4.0" @@ -5711,13 +5725,13 @@ object.entries@^1.1.4: es-abstract "^1.18.2" object.getprototypeof@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.getprototypeof/-/object.getprototypeof-1.0.1.tgz#dce7a9e6335b04db2e218afc5f423352a8ee3ada" - integrity sha512-orf7CoEkZKn1HYzA5KIt6G3Z2G4LKi1CiIK73c2PA2OK7ZASYp+rlIymYSs09qyrMm2o14U00z3VeD7MSsdvNw== + version "1.0.2" + resolved "https://registry.yarnpkg.com/object.getprototypeof/-/object.getprototypeof-1.0.2.tgz#a993d88ca63d68f9c328186dd17d76d4188b3624" + integrity sha512-7KoF7BcUJi6YZ+7g9XqbaJzxsmp4jSjUw8TkOSdN/GF9ZAhDM/ssERDddC+WR556niTKtCk9HtwwsbnaEeWNlg== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" + es-abstract "^1.18.6" reflect.getprototypeof "^1.0.0" object.pick@^1.3.0: @@ -6395,24 +6409,24 @@ recast@^0.17.3: source-map "~0.6.1" reflect.getprototypeof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.0.tgz#e54220a9bb67ec810c1916fc206ba6039509cb53" - integrity sha512-+0EPfQjXK+0X35YbfoXm6SKonJYwD1seJiS170Hl7MVLp5eGAKOGqbnLVtvC9boQ5qV5UpDNop+p0beVYbSI+Q== + version "1.0.1" + resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.1.tgz#f113f15e19d103d60b8d52ce7e0d45867efdddfc" + integrity sha512-z0FhUSaxXxnFQi+YyGfAvUJjCGPPwe0AO51LU/HtRLj/+a4LROrmSD6eYA3zr6aAK6GSbl8BCh/m5SAqUdAgTg== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - get-intrinsic "^1.0.2" - which-builtin-type "^1.0.1" + es-abstract "^1.18.6" + get-intrinsic "^1.1.1" + which-builtin-type "^1.1.1" -regenerate-unicode-properties@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" - integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== +regenerate-unicode-properties@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326" + integrity sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA== dependencies: - regenerate "^1.4.0" + regenerate "^1.4.2" -regenerate@^1.4.0: +regenerate@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== @@ -6448,26 +6462,26 @@ regexpp@^3.1.0: integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== regexpu-core@^4.2.0, regexpu-core@^4.7.1: - version "4.7.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" - integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== + version "4.8.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0" + integrity sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg== dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.2.0" - regjsgen "^0.5.1" - regjsparser "^0.6.4" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.2.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^9.0.0" + regjsgen "^0.5.2" + regjsparser "^0.7.0" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" -regjsgen@^0.5.1: +regjsgen@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== -regjsparser@^0.6.4: - version "0.6.9" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.9.tgz#b489eef7c9a2ce43727627011429cf833a7183e6" - integrity sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ== +regjsparser@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968" + integrity sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ== dependencies: jsesc "~0.5.0" @@ -6839,10 +6853,10 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.5.16, source-map-support@^0.5.6, source-map-support@~0.5.19: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== +source-map-support@^0.5.16, source-map-support@^0.5.20, source-map-support@^0.5.6, source-map-support@~0.5.20: + version "0.5.20" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" + integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -6926,11 +6940,12 @@ sshpk@^1.7.0: tweetnacl "~0.14.0" stack-utils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" - integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== + version "2.0.4" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.4.tgz#bf967ae2813d3d2d1e1f59a4408676495c8112ab" + integrity sha512-ERg+H//lSSYlZhBIUu+wJnqg30AbyBbpZlIhcshpn7BNzpoRODZgfyr9J+8ERf3ooC6af3u7Lcl01nleau7MrA== dependencies: escape-string-regexp "^2.0.0" + source-map-support "^0.5.20" static-extend@^0.1.1: version "0.1.2" @@ -7134,13 +7149,13 @@ terminal-link@^2.0.0: supports-hyperlinks "^2.0.0" terser@^5.5.1: - version "5.7.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.2.tgz#d4d95ed4f8bf735cb933e802f2a1829abf545e3f" - integrity sha512-0Omye+RD4X7X69O0eql3lC4Heh/5iLj3ggxR/B5ketZLOtLiOqukUgjw3q4PDnNQbsrkKr3UMypqStQG3XKRvw== + version "5.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.8.0.tgz#c6d352f91aed85cc6171ccb5e84655b77521d947" + integrity sha512-f0JH+6yMpneYcRJN314lZrSwu9eKkUFEHLN/kNy8ceh8gaRiLgFPJqrB9HsXjhEGdv4e/ekjTOFxIlL6xlma8A== dependencies: commander "^2.20.0" source-map "~0.7.2" - source-map-support "~0.5.19" + source-map-support "~0.5.20" test-exclude@^6.0.0: version "6.0.0" @@ -7200,9 +7215,9 @@ tmatch@^2.0.1: integrity sha1-DFYkbzPzDaG409colauvFmYPOM8= tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + version "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" @@ -7403,9 +7418,9 @@ typescript@^3.2.2: integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== typescript@^4.1.3: - version "4.3.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" - integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== + version "4.4.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324" + integrity sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA== typeson-registry@^1.0.0-alpha.20: version "1.0.0-alpha.39" @@ -7484,28 +7499,28 @@ unhomoglyph@^1.0.6: resolved "https://registry.yarnpkg.com/unhomoglyph/-/unhomoglyph-1.0.6.tgz#ea41f926d0fcf598e3b8bb2980c2ddac66b081d3" integrity sha512-7uvcWI3hWshSADBu4JpnyYbTVc7YlhF5GDW/oPD5AxIxl34k4wXR3WDkPnzLxkN32LiTCTKMQLtKVZiwki3zGg== -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" -unicode-match-property-value-ecmascript@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" - integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" + integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== -unicode-property-aliases-ecmascript@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" - integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== +unicode-property-aliases-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" + integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== union-value@^1.0.0: version "1.0.1" @@ -7753,7 +7768,7 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which-builtin-type@^1.0.1: +which-builtin-type@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.1.tgz#1d14bb1b69b5680ebdddd7244689574678a1d83c" integrity sha512-zY3bUNzl/unBfSDS6ePT+/dwu6hZ7RMVMqHFvYxZEhisGEwCV/pYnXQ70nd3Hn2X6l8BNOWge5sHk3wAR3L42w== @@ -7787,16 +7802,16 @@ which-module@^2.0.0: integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= which-typed-array@^1.1.2, which-typed-array@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.6.tgz#f3713d801da0720a7f26f50c596980a9f5c8b383" - integrity sha512-DdY984dGD5sQ7Tf+x1CkXzdg85b9uEel6nr4UkFg1LoE9OXv3uRuZhe5CoWdawhGACeFpEZXH8fFLQnDhbpm/Q== + version "1.1.7" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.7.tgz#2761799b9a22d4b8660b3c1b40abaa7739691793" + integrity sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw== dependencies: - available-typed-arrays "^1.0.4" + available-typed-arrays "^1.0.5" call-bind "^1.0.2" es-abstract "^1.18.5" foreach "^2.0.5" has-tostringtag "^1.0.0" - is-typed-array "^1.1.6" + is-typed-array "^1.1.7" which@^1.2.9: version "1.3.1" @@ -7869,9 +7884,9 @@ write-file-atomic@^3.0.0: typedarray-to-buffer "^3.1.5" ws@^7.4.6: - version "7.5.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" - integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== + version "7.5.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" + integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== xml-name-validator@^3.0.0: version "3.0.0" From 14ed8a110cbf75fb49fb62feb64ba7d4b7c0dc21 Mon Sep 17 00:00:00 2001 From: Robert Long Date: Tue, 14 Sep 2021 10:50:50 -0700 Subject: [PATCH 40/47] Update src/client.ts Co-authored-by: Travis Ralston --- src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index a1ac2685a..b8c36dc52 100644 --- a/src/client.ts +++ b/src/client.ts @@ -6109,7 +6109,7 @@ export class MatrixClient extends EventEmitter { password: string, sessionId: string | null, auth: { session?: string, type: string }, - bindThreepids?: boolean | null | { email?: boolean | boolean, msisdn?: boolean }, + bindThreepids?: boolean | null | { email?: boolean, msisdn?: boolean }, guestAccessToken?: string, inhibitLogin?: boolean, callback?: Callback, From e1d8d6bf4e6927c4434314a82344c6597435b07d Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Sep 2021 18:52:35 +0100 Subject: [PATCH 41/47] Not typescript again because this time they just removed setCodecPreferences from webrtc? --- yarn.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 811d5dc9f..01de151c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7412,16 +7412,16 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typescript@^4.1.3: + version "4.3.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" + integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== + 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.1.3: - version "4.4.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324" - integrity sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA== - typeson-registry@^1.0.0-alpha.20: version "1.0.0-alpha.39" resolved "https://registry.yarnpkg.com/typeson-registry/-/typeson-registry-1.0.0-alpha.39.tgz#9e0f5aabd5eebfcffd65a796487541196f4b1211" From 50e0d76f101d73cccb9f2c523d5b00671e83faa5 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 15 Sep 2021 09:26:25 +0200 Subject: [PATCH 42/47] remove erroneous comment related to typings --- src/autodiscovery.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/autodiscovery.ts b/src/autodiscovery.ts index a300cb049..19d2aa9f8 100644 --- a/src/autodiscovery.ts +++ b/src/autodiscovery.ts @@ -416,7 +416,7 @@ export class AutoDiscovery { * @return {Promise} Resolves to the returned state. * @private */ - private static async fetchWellKnownObject(url: string): Promise { // TODO: TYPES + private static async fetchWellKnownObject(url: string): Promise { return new Promise(function(resolve, reject) { // eslint-disable-next-line const request = require("./matrix").getRequest(); From cf4d3117c1698415e26da0f5785df9d087c311bf Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 15 Sep 2021 10:29:14 +0100 Subject: [PATCH 43/47] Fix types This is 'any' (defined as any by IWellKnownConfig.raw) rather than string (which the jsdoc claimed). We were calling this method ourselves but with an object that was also 'any', so it was fine, but react-sdk calls it with an object literal, which typescript knows it not a string. --- src/autodiscovery.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/autodiscovery.ts b/src/autodiscovery.ts index 19d2aa9f8..dd24bddc2 100644 --- a/src/autodiscovery.ts +++ b/src/autodiscovery.ts @@ -114,13 +114,13 @@ export class AutoDiscovery { * and identity server URL the client would want. Additional details * may also be included, and will be transparently brought into the * response object unaltered. - * @param {string} wellknown The configuration object itself, as returned + * @param {object} wellknown The configuration object itself, as returned * by the .well-known auto-discovery endpoint. * @return {Promise} Resolves to the verified * configuration, which may include error states. Rejects on unexpected * failure, not when verification fails. */ - public static async fromDiscoveryConfig(wellknown: string): Promise { + public static async fromDiscoveryConfig(wellknown: any): Promise { // Step 1 is to get the config, which is provided to us here. // We default to an error state to make the first few checks easier to From c3308e1de95273a2e9baab4482176944a4138b2c Mon Sep 17 00:00:00 2001 From: James Salter Date: Wed, 15 Sep 2021 12:01:34 +0100 Subject: [PATCH 44/47] Revert "Migrate errors to TypeScript" This reverts commit ab906faa1756483d08705c29633a8368c44cf485. --- src/{errors.ts => errors.js} | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) rename src/{errors.ts => errors.js} (71%) diff --git a/src/errors.ts b/src/errors.js similarity index 71% rename from src/errors.ts rename to src/errors.js index 324e04c46..186fc6911 100644 --- a/src/errors.ts +++ b/src/errors.js @@ -1,6 +1,6 @@ // can't just do InvalidStoreError extends Error // because of http://babeljs.io/docs/usage/caveats/#classes -export function InvalidStoreError(reason: string, value: boolean): void { +export function InvalidStoreError(reason, value) { const message = `Store is invalid because ${reason}, ` + `please stop the client, delete all data and start the client again`; const instance = Reflect.construct(Error, [message]); @@ -13,16 +13,16 @@ export function InvalidStoreError(reason: string, value: boolean): void { InvalidStoreError.TOGGLED_LAZY_LOADING = "TOGGLED_LAZY_LOADING"; InvalidStoreError.prototype = Object.create(Error.prototype, { - constructor: { - value: Error, - enumerable: false, - writable: true, - configurable: true, - }, + constructor: { + value: Error, + enumerable: false, + writable: true, + configurable: true, + }, }); Reflect.setPrototypeOf(InvalidStoreError, Error); -export function InvalidCryptoStoreError(reason: string): void { +export function InvalidCryptoStoreError(reason) { const message = `Crypto store is invalid because ${reason}, ` + `please stop the client, delete all data and start the client again`; const instance = Reflect.construct(Error, [message]); @@ -35,17 +35,18 @@ export function InvalidCryptoStoreError(reason: string): void { InvalidCryptoStoreError.TOO_NEW = "TOO_NEW"; InvalidCryptoStoreError.prototype = Object.create(Error.prototype, { - constructor: { - value: Error, - enumerable: false, - writable: true, - configurable: true, - }, + constructor: { + value: Error, + enumerable: false, + writable: true, + configurable: true, + }, }); Reflect.setPrototypeOf(InvalidCryptoStoreError, Error); export class KeySignatureUploadError extends Error { - constructor(message: string, public value: { failures: any }) { // TODO: types - super(message); - } + constructor(message, value) { + super(message); + this.value = value; + } } From be942fd66a8f1f9510bca66a3049fce2cb0392b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 15 Sep 2021 16:38:59 +0200 Subject: [PATCH 45/47] Remove RTX codec hack as the issue is no longer present on Chromium 90 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/webrtc/call.ts | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index 79df07b43..5767b96c5 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -1068,7 +1068,6 @@ export class MatrixCall extends EventEmitter { let myAnswer; try { - this.getRidOfRTXCodecs(); myAnswer = await this.peerConn.createAnswer(); } catch (err) { logger.debug("Failed to create answer: ", err); @@ -1285,7 +1284,6 @@ export class MatrixCall extends EventEmitter { await this.peerConn.setRemoteDescription(description); if (description.type === 'offer') { - this.getRidOfRTXCodecs(); const localDescription = await this.peerConn.createAnswer(); await this.peerConn.setLocalDescription(localDescription); @@ -1499,47 +1497,6 @@ export class MatrixCall extends EventEmitter { stream.addEventListener("removetrack", () => this.deleteFeedByStream(stream)); }; - /** - * This method removes all video/rtx codecs from screensharing video - * transceivers. This is necessary since they can cause problems. Without - * this the following steps should produce an error: - * Chromium calls Firefox - * Firefox answers - * Firefox starts screen-sharing - * Chromium starts screen-sharing - * Call crashes for Chromium with: - * [96685:23:0518/162603.933321:ERROR:webrtc_video_engine.cc(3296)] RTX codec (PT=97) mapped to PT=96 which is not in the codec list. - * [96685:23:0518/162603.933377:ERROR:webrtc_video_engine.cc(1171)] GetChangedRecvParameters called without any video codecs. - * [96685:23:0518/162603.933430:ERROR:sdp_offer_answer.cc(4302)] Failed to set local video description recv parameters for m-section with mid='2'. (INVALID_PARAMETER) - */ - private getRidOfRTXCodecs(): void { - // RTCRtpReceiver.getCapabilities and RTCRtpSender.getCapabilities don't seem to be supported on FF - if (!RTCRtpReceiver.getCapabilities || !RTCRtpSender.getCapabilities) return; - - const recvCodecs = RTCRtpReceiver.getCapabilities("video").codecs; - const sendCodecs = RTCRtpSender.getCapabilities("video").codecs; - const codecs = [...sendCodecs, ...recvCodecs]; - - for (const codec of codecs) { - if (codec.mimeType === "video/rtx") { - const rtxCodecIndex = codecs.indexOf(codec); - codecs.splice(rtxCodecIndex, 1); - } - } - - for (const trans of this.peerConn.getTransceivers()) { - if ( - this.screensharingSenders.includes(trans.sender) && - ( - trans.sender.track?.kind === "video" || - trans.receiver.track?.kind === "video" - ) - ) { - trans.setCodecPreferences(codecs); - } - } - } - private onNegotiationNeeded = async (): Promise => { logger.info("Negotiation is needed!"); @@ -1550,7 +1507,6 @@ export class MatrixCall extends EventEmitter { this.makingOffer = true; try { - this.getRidOfRTXCodecs(); const myOffer = await this.peerConn.createOffer(); await this.gotLocalOffer(myOffer); } catch (e) { From 9bb87145f642379c6653e62d563894258ffa57de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 15 Sep 2021 17:17:56 +0200 Subject: [PATCH 46/47] Revert "Remove RTX codec hack " --- src/webrtc/call.ts | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index 5767b96c5..79df07b43 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -1068,6 +1068,7 @@ export class MatrixCall extends EventEmitter { let myAnswer; try { + this.getRidOfRTXCodecs(); myAnswer = await this.peerConn.createAnswer(); } catch (err) { logger.debug("Failed to create answer: ", err); @@ -1284,6 +1285,7 @@ export class MatrixCall extends EventEmitter { await this.peerConn.setRemoteDescription(description); if (description.type === 'offer') { + this.getRidOfRTXCodecs(); const localDescription = await this.peerConn.createAnswer(); await this.peerConn.setLocalDescription(localDescription); @@ -1497,6 +1499,47 @@ export class MatrixCall extends EventEmitter { stream.addEventListener("removetrack", () => this.deleteFeedByStream(stream)); }; + /** + * This method removes all video/rtx codecs from screensharing video + * transceivers. This is necessary since they can cause problems. Without + * this the following steps should produce an error: + * Chromium calls Firefox + * Firefox answers + * Firefox starts screen-sharing + * Chromium starts screen-sharing + * Call crashes for Chromium with: + * [96685:23:0518/162603.933321:ERROR:webrtc_video_engine.cc(3296)] RTX codec (PT=97) mapped to PT=96 which is not in the codec list. + * [96685:23:0518/162603.933377:ERROR:webrtc_video_engine.cc(1171)] GetChangedRecvParameters called without any video codecs. + * [96685:23:0518/162603.933430:ERROR:sdp_offer_answer.cc(4302)] Failed to set local video description recv parameters for m-section with mid='2'. (INVALID_PARAMETER) + */ + private getRidOfRTXCodecs(): void { + // RTCRtpReceiver.getCapabilities and RTCRtpSender.getCapabilities don't seem to be supported on FF + if (!RTCRtpReceiver.getCapabilities || !RTCRtpSender.getCapabilities) return; + + const recvCodecs = RTCRtpReceiver.getCapabilities("video").codecs; + const sendCodecs = RTCRtpSender.getCapabilities("video").codecs; + const codecs = [...sendCodecs, ...recvCodecs]; + + for (const codec of codecs) { + if (codec.mimeType === "video/rtx") { + const rtxCodecIndex = codecs.indexOf(codec); + codecs.splice(rtxCodecIndex, 1); + } + } + + for (const trans of this.peerConn.getTransceivers()) { + if ( + this.screensharingSenders.includes(trans.sender) && + ( + trans.sender.track?.kind === "video" || + trans.receiver.track?.kind === "video" + ) + ) { + trans.setCodecPreferences(codecs); + } + } + } + private onNegotiationNeeded = async (): Promise => { logger.info("Negotiation is needed!"); @@ -1507,6 +1550,7 @@ export class MatrixCall extends EventEmitter { this.makingOffer = true; try { + this.getRidOfRTXCodecs(); const myOffer = await this.peerConn.createOffer(); await this.gotLocalOffer(myOffer); } catch (e) { From 4e14d810c5c6652a5644bb51cb8269d3636d0dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 15 Sep 2021 17:44:16 +0200 Subject: [PATCH 47/47] Add setCodecPreferences() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/@types/global.d.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 2feaa748f..0a857b4e8 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -88,4 +88,11 @@ declare global { interface PromiseConstructor { allSettled(promises: Promise[]): Promise | ISettledRejected>>; } + + interface RTCRtpTransceiver { + // This has been removed from TS + // (https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1029), + // but we still need this for MatrixCall::getRidOfRTXCodecs() + setCodecPreferences(codecs: RTCRtpCodecCapability[]): void; + } }