summaryrefslogtreecommitdiff
path: root/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification
diff options
context:
space:
mode:
Diffstat (limited to 'includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification')
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts87
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js347
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts35
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js101
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts15
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js50
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts54
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js272
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts37
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js453
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts8
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js40
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts18
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js6
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts113
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js344
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts105
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js324
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts208
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts.map1
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js876
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js.map1
40 files changed, 3513 insertions, 0 deletions
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts
new file mode 100644
index 0000000..413728c
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts
@@ -0,0 +1,87 @@
+/**
+ * Base class for verification methods.
+ */
+import { MatrixEvent } from "../../models/event";
+import { DeviceInfo } from "../deviceinfo";
+import { KeysDuringVerification } from "../CrossSigning";
+import { IVerificationChannel } from "./request/Channel";
+import { MatrixClient } from "../../client";
+import { VerificationRequest } from "./request/VerificationRequest";
+import { ListenerMap, TypedEventEmitter } from "../../models/typed-event-emitter";
+export declare class SwitchStartEventError extends Error {
+ readonly startEvent: MatrixEvent | null;
+ constructor(startEvent: MatrixEvent | null);
+}
+export type KeyVerifier = (keyId: string, device: DeviceInfo, keyInfo: string) => void;
+export declare enum VerificationEvent {
+ Cancel = "cancel"
+}
+export type VerificationEventHandlerMap = {
+ [VerificationEvent.Cancel]: (e: Error | MatrixEvent) => void;
+};
+export declare class VerificationBase<Events extends string, Arguments extends ListenerMap<Events | VerificationEvent>> extends TypedEventEmitter<Events | VerificationEvent, Arguments, VerificationEventHandlerMap> {
+ readonly channel: IVerificationChannel;
+ readonly baseApis: MatrixClient;
+ readonly userId: string;
+ readonly deviceId: string;
+ startEvent: MatrixEvent | null;
+ readonly request: VerificationRequest;
+ private cancelled;
+ private _done;
+ private promise;
+ private transactionTimeoutTimer;
+ protected expectedEvent?: string;
+ private resolve?;
+ private reject?;
+ private resolveEvent?;
+ private rejectEvent?;
+ private started?;
+ /**
+ * Base class for verification methods.
+ *
+ * <p>Once a verifier object is created, the verification can be started by
+ * calling the verify() method, which will return a promise that will
+ * resolve when the verification is completed, or reject if it could not
+ * complete.</p>
+ *
+ * <p>Subclasses must have a NAME class property.</p>
+ *
+ * @param channel - the verification channel to send verification messages over.
+ * TODO: Channel types
+ *
+ * @param baseApis - base matrix api interface
+ *
+ * @param userId - the user ID that is being verified
+ *
+ * @param deviceId - the device ID that is being verified
+ *
+ * @param startEvent - the m.key.verification.start event that
+ * initiated this verification, if any
+ *
+ * @param request - the key verification request object related to
+ * this verification, if any
+ */
+ constructor(channel: IVerificationChannel, baseApis: MatrixClient, userId: string, deviceId: string, startEvent: MatrixEvent | null, request: VerificationRequest);
+ get initiatedByMe(): boolean;
+ get hasBeenCancelled(): boolean;
+ private resetTimer;
+ private endTimer;
+ protected send(type: string, uncompletedContent: Record<string, any>): Promise<void>;
+ protected waitForEvent(type: string): Promise<MatrixEvent>;
+ canSwitchStartEvent(event: MatrixEvent): boolean;
+ switchStartEvent(event: MatrixEvent): void;
+ handleEvent(e: MatrixEvent): void;
+ done(): Promise<KeysDuringVerification | void>;
+ cancel(e: Error | MatrixEvent): void;
+ /**
+ * Begin the key verification
+ *
+ * @returns Promise which resolves when the verification has
+ * completed.
+ */
+ verify(): Promise<void>;
+ protected doVerification?: () => Promise<void>;
+ protected verifyKeys(userId: string, keys: Record<string, string>, verifier: KeyVerifier): Promise<void>;
+ get events(): string[] | undefined;
+}
+//# sourceMappingURL=Base.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts.map
new file mode 100644
index 0000000..30d70f8
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"Base.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/Base.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js
new file mode 100644
index 0000000..31150dc
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js
@@ -0,0 +1,347 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.VerificationEvent = exports.VerificationBase = exports.SwitchStartEventError = void 0;
+var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
+var _event = require("../../models/event");
+var _event2 = require("../../@types/event");
+var _logger = require("../../logger");
+var _deviceinfo = require("../deviceinfo");
+var _Error = require("./Error");
+var _CrossSigning = require("../CrossSigning");
+var _typedEventEmitter = require("../../models/typed-event-emitter");
+/*
+Copyright 2018 New Vector Ltd
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/**
+ * Base class for verification methods.
+ */
+
+const timeoutException = new Error("Verification timed out");
+class SwitchStartEventError extends Error {
+ constructor(startEvent) {
+ super();
+ this.startEvent = startEvent;
+ }
+}
+exports.SwitchStartEventError = SwitchStartEventError;
+let VerificationEvent;
+exports.VerificationEvent = VerificationEvent;
+(function (VerificationEvent) {
+ VerificationEvent["Cancel"] = "cancel";
+})(VerificationEvent || (exports.VerificationEvent = VerificationEvent = {}));
+class VerificationBase extends _typedEventEmitter.TypedEventEmitter {
+ /**
+ * Base class for verification methods.
+ *
+ * <p>Once a verifier object is created, the verification can be started by
+ * calling the verify() method, which will return a promise that will
+ * resolve when the verification is completed, or reject if it could not
+ * complete.</p>
+ *
+ * <p>Subclasses must have a NAME class property.</p>
+ *
+ * @param channel - the verification channel to send verification messages over.
+ * TODO: Channel types
+ *
+ * @param baseApis - base matrix api interface
+ *
+ * @param userId - the user ID that is being verified
+ *
+ * @param deviceId - the device ID that is being verified
+ *
+ * @param startEvent - the m.key.verification.start event that
+ * initiated this verification, if any
+ *
+ * @param request - the key verification request object related to
+ * this verification, if any
+ */
+ constructor(channel, baseApis, userId, deviceId, startEvent, request) {
+ super();
+ this.channel = channel;
+ this.baseApis = baseApis;
+ this.userId = userId;
+ this.deviceId = deviceId;
+ this.startEvent = startEvent;
+ this.request = request;
+ (0, _defineProperty2.default)(this, "cancelled", false);
+ (0, _defineProperty2.default)(this, "_done", false);
+ (0, _defineProperty2.default)(this, "promise", null);
+ (0, _defineProperty2.default)(this, "transactionTimeoutTimer", null);
+ (0, _defineProperty2.default)(this, "expectedEvent", void 0);
+ (0, _defineProperty2.default)(this, "resolve", void 0);
+ (0, _defineProperty2.default)(this, "reject", void 0);
+ (0, _defineProperty2.default)(this, "resolveEvent", void 0);
+ (0, _defineProperty2.default)(this, "rejectEvent", void 0);
+ (0, _defineProperty2.default)(this, "started", void 0);
+ (0, _defineProperty2.default)(this, "doVerification", void 0);
+ }
+ get initiatedByMe() {
+ // if there is no start event yet,
+ // we probably want to send it,
+ // which happens if we initiate
+ if (!this.startEvent) {
+ return true;
+ }
+ const sender = this.startEvent.getSender();
+ const content = this.startEvent.getContent();
+ return sender === this.baseApis.getUserId() && content.from_device === this.baseApis.getDeviceId();
+ }
+ get hasBeenCancelled() {
+ return this.cancelled;
+ }
+ resetTimer() {
+ _logger.logger.info("Refreshing/starting the verification transaction timeout timer");
+ if (this.transactionTimeoutTimer !== null) {
+ clearTimeout(this.transactionTimeoutTimer);
+ }
+ this.transactionTimeoutTimer = setTimeout(() => {
+ if (!this._done && !this.cancelled) {
+ _logger.logger.info("Triggering verification timeout");
+ this.cancel(timeoutException);
+ }
+ }, 10 * 60 * 1000); // 10 minutes
+ }
+
+ endTimer() {
+ if (this.transactionTimeoutTimer !== null) {
+ clearTimeout(this.transactionTimeoutTimer);
+ this.transactionTimeoutTimer = null;
+ }
+ }
+ send(type, uncompletedContent) {
+ return this.channel.send(type, uncompletedContent);
+ }
+ waitForEvent(type) {
+ if (this._done) {
+ return Promise.reject(new Error("Verification is already done"));
+ }
+ const existingEvent = this.request.getEventFromOtherParty(type);
+ if (existingEvent) {
+ return Promise.resolve(existingEvent);
+ }
+ this.expectedEvent = type;
+ return new Promise((resolve, reject) => {
+ this.resolveEvent = resolve;
+ this.rejectEvent = reject;
+ });
+ }
+ canSwitchStartEvent(event) {
+ return false;
+ }
+ switchStartEvent(event) {
+ if (this.canSwitchStartEvent(event)) {
+ _logger.logger.log("Verification Base: switching verification start event", {
+ restartingFlow: !!this.rejectEvent
+ });
+ if (this.rejectEvent) {
+ const reject = this.rejectEvent;
+ this.rejectEvent = undefined;
+ reject(new SwitchStartEventError(event));
+ } else {
+ this.startEvent = event;
+ }
+ }
+ }
+ handleEvent(e) {
+ if (this._done) {
+ return;
+ } else if (e.getType() === this.expectedEvent) {
+ // if we receive an expected m.key.verification.done, then just
+ // ignore it, since we don't need to do anything about it
+ if (this.expectedEvent !== _event2.EventType.KeyVerificationDone) {
+ var _this$resolveEvent;
+ this.expectedEvent = undefined;
+ this.rejectEvent = undefined;
+ this.resetTimer();
+ (_this$resolveEvent = this.resolveEvent) === null || _this$resolveEvent === void 0 ? void 0 : _this$resolveEvent.call(this, e);
+ }
+ } else if (e.getType() === _event2.EventType.KeyVerificationCancel) {
+ const reject = this.reject;
+ this.reject = undefined;
+ // there is only promise to reject if verify has been called
+ if (reject) {
+ const content = e.getContent();
+ const {
+ reason,
+ code
+ } = content;
+ reject(new Error(`Other side cancelled verification ` + `because ${reason} (${code})`));
+ }
+ } else if (this.expectedEvent) {
+ // only cancel if there is an event expected.
+ // if there is no event expected, it means verify() wasn't called
+ // and we're just replaying the timeline events when syncing
+ // after a refresh when the events haven't been stored in the cache yet.
+ const exception = new Error("Unexpected message: expecting " + this.expectedEvent + " but got " + e.getType());
+ this.expectedEvent = undefined;
+ if (this.rejectEvent) {
+ const reject = this.rejectEvent;
+ this.rejectEvent = undefined;
+ reject(exception);
+ }
+ this.cancel(exception);
+ }
+ }
+ async done() {
+ this.endTimer(); // always kill the activity timer
+ if (!this._done) {
+ var _this$resolve;
+ this.request.onVerifierFinished();
+ (_this$resolve = this.resolve) === null || _this$resolve === void 0 ? void 0 : _this$resolve.call(this);
+ return (0, _CrossSigning.requestKeysDuringVerification)(this.baseApis, this.userId, this.deviceId);
+ }
+ }
+ cancel(e) {
+ this.endTimer(); // always kill the activity timer
+ if (!this._done) {
+ this.cancelled = true;
+ this.request.onVerifierCancelled();
+ if (this.userId && this.deviceId) {
+ // send a cancellation to the other user (if it wasn't
+ // cancelled by the other user)
+ if (e === timeoutException) {
+ const timeoutEvent = (0, _Error.newTimeoutError)();
+ this.send(timeoutEvent.getType(), timeoutEvent.getContent());
+ } else if (e instanceof _event.MatrixEvent) {
+ const sender = e.getSender();
+ if (sender !== this.userId) {
+ const content = e.getContent();
+ if (e.getType() === _event2.EventType.KeyVerificationCancel) {
+ content.code = content.code || "m.unknown";
+ content.reason = content.reason || content.body || "Unknown reason";
+ this.send(_event2.EventType.KeyVerificationCancel, content);
+ } else {
+ this.send(_event2.EventType.KeyVerificationCancel, {
+ code: "m.unknown",
+ reason: content.body || "Unknown reason"
+ });
+ }
+ }
+ } else {
+ this.send(_event2.EventType.KeyVerificationCancel, {
+ code: "m.unknown",
+ reason: e.toString()
+ });
+ }
+ }
+ if (this.promise !== null) {
+ // when we cancel without a promise, we end up with a promise
+ // but no reject function. If cancel is called again, we'd error.
+ if (this.reject) this.reject(e);
+ } else {
+ // FIXME: this causes an "Uncaught promise" console message
+ // if nothing ends up chaining this promise.
+ this.promise = Promise.reject(e);
+ }
+ // Also emit a 'cancel' event that the app can listen for to detect cancellation
+ // before calling verify()
+ this.emit(VerificationEvent.Cancel, e);
+ }
+ }
+
+ /**
+ * Begin the key verification
+ *
+ * @returns Promise which resolves when the verification has
+ * completed.
+ */
+ verify() {
+ if (this.promise) return this.promise;
+ this.promise = new Promise((resolve, reject) => {
+ this.resolve = (...args) => {
+ this._done = true;
+ this.endTimer();
+ resolve(...args);
+ };
+ this.reject = e => {
+ this._done = true;
+ this.endTimer();
+ reject(e);
+ };
+ });
+ if (this.doVerification && !this.started) {
+ this.started = true;
+ this.resetTimer(); // restart the timeout
+ new Promise((resolve, reject) => {
+ var _deviceList$getStored;
+ const crossSignId = (_deviceList$getStored = this.baseApis.crypto.deviceList.getStoredCrossSigningForUser(this.userId)) === null || _deviceList$getStored === void 0 ? void 0 : _deviceList$getStored.getId();
+ if (crossSignId === this.deviceId) {
+ reject(new Error("Device ID is the same as the cross-signing ID"));
+ }
+ resolve();
+ }).then(() => this.doVerification()).then(this.done.bind(this), this.cancel.bind(this));
+ }
+ return this.promise;
+ }
+ async verifyKeys(userId, keys, verifier) {
+ // we try to verify all the keys that we're told about, but we might
+ // not know about all of them, so keep track of the keys that we know
+ // about, and ignore the rest
+ const verifiedDevices = [];
+ for (const [keyId, keyInfo] of Object.entries(keys)) {
+ const deviceId = keyId.split(":", 2)[1];
+ const device = this.baseApis.getStoredDevice(userId, deviceId);
+ if (device) {
+ verifier(keyId, device, keyInfo);
+ verifiedDevices.push([deviceId, keyId, device.keys[keyId]]);
+ } else {
+ const crossSigningInfo = this.baseApis.crypto.deviceList.getStoredCrossSigningForUser(userId);
+ if (crossSigningInfo && crossSigningInfo.getId() === deviceId) {
+ verifier(keyId, _deviceinfo.DeviceInfo.fromStorage({
+ keys: {
+ [keyId]: deviceId
+ }
+ }, deviceId), keyInfo);
+ verifiedDevices.push([deviceId, keyId, deviceId]);
+ } else {
+ _logger.logger.warn(`verification: Could not find device ${deviceId} to verify`);
+ }
+ }
+ }
+
+ // if none of the keys could be verified, then error because the app
+ // should be informed about that
+ if (!verifiedDevices.length) {
+ throw new Error("No devices could be verified");
+ }
+ _logger.logger.info("Verification completed! Marking devices verified: ", verifiedDevices);
+ // TODO: There should probably be a batch version of this, otherwise it's going
+ // to upload each signature in a separate API call which is silly because the
+ // API supports as many signatures as you like.
+ for (const [deviceId, keyId, key] of verifiedDevices) {
+ await this.baseApis.crypto.setDeviceVerification(userId, deviceId, true, null, null, {
+ [keyId]: key
+ });
+ }
+
+ // if one of the user's own devices is being marked as verified / unverified,
+ // check the key backup status, since whether or not we use this depends on
+ // whether it has a signature from a verified device
+ if (userId == this.baseApis.credentials.userId) {
+ await this.baseApis.checkKeyBackup();
+ }
+ }
+ get events() {
+ return undefined;
+ }
+}
+exports.VerificationBase = VerificationBase;
+//# sourceMappingURL=Base.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js.map
new file mode 100644
index 0000000..058d197
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Base.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"Base.js","names":["_event","require","_event2","_logger","_deviceinfo","_Error","_CrossSigning","_typedEventEmitter","timeoutException","Error","SwitchStartEventError","constructor","startEvent","exports","VerificationEvent","VerificationBase","TypedEventEmitter","channel","baseApis","userId","deviceId","request","_defineProperty2","default","initiatedByMe","sender","getSender","content","getContent","getUserId","from_device","getDeviceId","hasBeenCancelled","cancelled","resetTimer","logger","info","transactionTimeoutTimer","clearTimeout","setTimeout","_done","cancel","endTimer","send","type","uncompletedContent","waitForEvent","Promise","reject","existingEvent","getEventFromOtherParty","resolve","expectedEvent","resolveEvent","rejectEvent","canSwitchStartEvent","event","switchStartEvent","log","restartingFlow","undefined","handleEvent","e","getType","EventType","KeyVerificationDone","_this$resolveEvent","call","KeyVerificationCancel","reason","code","exception","done","_this$resolve","onVerifierFinished","requestKeysDuringVerification","onVerifierCancelled","timeoutEvent","newTimeoutError","MatrixEvent","body","toString","promise","emit","Cancel","verify","args","doVerification","started","_deviceList$getStored","crossSignId","crypto","deviceList","getStoredCrossSigningForUser","getId","then","bind","verifyKeys","keys","verifier","verifiedDevices","keyId","keyInfo","Object","entries","split","device","getStoredDevice","push","crossSigningInfo","DeviceInfo","fromStorage","warn","length","key","setDeviceVerification","credentials","checkKeyBackup","events"],"sources":["../../../src/crypto/verification/Base.ts"],"sourcesContent":["/*\nCopyright 2018 New Vector Ltd\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Base class for verification methods.\n */\n\nimport { MatrixEvent } from \"../../models/event\";\nimport { EventType } from \"../../@types/event\";\nimport { logger } from \"../../logger\";\nimport { DeviceInfo } from \"../deviceinfo\";\nimport { newTimeoutError } from \"./Error\";\nimport { KeysDuringVerification, requestKeysDuringVerification } from \"../CrossSigning\";\nimport { IVerificationChannel } from \"./request/Channel\";\nimport { MatrixClient } from \"../../client\";\nimport { VerificationRequest } from \"./request/VerificationRequest\";\nimport { ListenerMap, TypedEventEmitter } from \"../../models/typed-event-emitter\";\n\nconst timeoutException = new Error(\"Verification timed out\");\n\nexport class SwitchStartEventError extends Error {\n public constructor(public readonly startEvent: MatrixEvent | null) {\n super();\n }\n}\n\nexport type KeyVerifier = (keyId: string, device: DeviceInfo, keyInfo: string) => void;\n\nexport enum VerificationEvent {\n Cancel = \"cancel\",\n}\n\nexport type VerificationEventHandlerMap = {\n [VerificationEvent.Cancel]: (e: Error | MatrixEvent) => void;\n};\n\nexport class VerificationBase<\n Events extends string,\n Arguments extends ListenerMap<Events | VerificationEvent>,\n> extends TypedEventEmitter<Events | VerificationEvent, Arguments, VerificationEventHandlerMap> {\n private cancelled = false;\n private _done = false;\n private promise: Promise<void> | null = null;\n private transactionTimeoutTimer: ReturnType<typeof setTimeout> | null = null;\n protected expectedEvent?: string;\n private resolve?: () => void;\n private reject?: (e: Error | MatrixEvent) => void;\n private resolveEvent?: (e: MatrixEvent) => void;\n private rejectEvent?: (e: Error) => void;\n private started?: boolean;\n\n /**\n * Base class for verification methods.\n *\n * <p>Once a verifier object is created, the verification can be started by\n * calling the verify() method, which will return a promise that will\n * resolve when the verification is completed, or reject if it could not\n * complete.</p>\n *\n * <p>Subclasses must have a NAME class property.</p>\n *\n * @param channel - the verification channel to send verification messages over.\n * TODO: Channel types\n *\n * @param baseApis - base matrix api interface\n *\n * @param userId - the user ID that is being verified\n *\n * @param deviceId - the device ID that is being verified\n *\n * @param startEvent - the m.key.verification.start event that\n * initiated this verification, if any\n *\n * @param request - the key verification request object related to\n * this verification, if any\n */\n public constructor(\n public readonly channel: IVerificationChannel,\n public readonly baseApis: MatrixClient,\n public readonly userId: string,\n public readonly deviceId: string,\n public startEvent: MatrixEvent | null,\n public readonly request: VerificationRequest,\n ) {\n super();\n }\n\n public get initiatedByMe(): boolean {\n // if there is no start event yet,\n // we probably want to send it,\n // which happens if we initiate\n if (!this.startEvent) {\n return true;\n }\n const sender = this.startEvent.getSender();\n const content = this.startEvent.getContent();\n return sender === this.baseApis.getUserId() && content.from_device === this.baseApis.getDeviceId();\n }\n\n public get hasBeenCancelled(): boolean {\n return this.cancelled;\n }\n\n private resetTimer(): void {\n logger.info(\"Refreshing/starting the verification transaction timeout timer\");\n if (this.transactionTimeoutTimer !== null) {\n clearTimeout(this.transactionTimeoutTimer);\n }\n this.transactionTimeoutTimer = setTimeout(() => {\n if (!this._done && !this.cancelled) {\n logger.info(\"Triggering verification timeout\");\n this.cancel(timeoutException);\n }\n }, 10 * 60 * 1000); // 10 minutes\n }\n\n private endTimer(): void {\n if (this.transactionTimeoutTimer !== null) {\n clearTimeout(this.transactionTimeoutTimer);\n this.transactionTimeoutTimer = null;\n }\n }\n\n protected send(type: string, uncompletedContent: Record<string, any>): Promise<void> {\n return this.channel.send(type, uncompletedContent);\n }\n\n protected waitForEvent(type: string): Promise<MatrixEvent> {\n if (this._done) {\n return Promise.reject(new Error(\"Verification is already done\"));\n }\n const existingEvent = this.request.getEventFromOtherParty(type);\n if (existingEvent) {\n return Promise.resolve(existingEvent);\n }\n\n this.expectedEvent = type;\n return new Promise((resolve, reject) => {\n this.resolveEvent = resolve;\n this.rejectEvent = reject;\n });\n }\n\n public canSwitchStartEvent(event: MatrixEvent): boolean {\n return false;\n }\n\n public switchStartEvent(event: MatrixEvent): void {\n if (this.canSwitchStartEvent(event)) {\n logger.log(\"Verification Base: switching verification start event\", { restartingFlow: !!this.rejectEvent });\n if (this.rejectEvent) {\n const reject = this.rejectEvent;\n this.rejectEvent = undefined;\n reject(new SwitchStartEventError(event));\n } else {\n this.startEvent = event;\n }\n }\n }\n\n public handleEvent(e: MatrixEvent): void {\n if (this._done) {\n return;\n } else if (e.getType() === this.expectedEvent) {\n // if we receive an expected m.key.verification.done, then just\n // ignore it, since we don't need to do anything about it\n if (this.expectedEvent !== EventType.KeyVerificationDone) {\n this.expectedEvent = undefined;\n this.rejectEvent = undefined;\n this.resetTimer();\n this.resolveEvent?.(e);\n }\n } else if (e.getType() === EventType.KeyVerificationCancel) {\n const reject = this.reject;\n this.reject = undefined;\n // there is only promise to reject if verify has been called\n if (reject) {\n const content = e.getContent();\n const { reason, code } = content;\n reject(new Error(`Other side cancelled verification ` + `because ${reason} (${code})`));\n }\n } else if (this.expectedEvent) {\n // only cancel if there is an event expected.\n // if there is no event expected, it means verify() wasn't called\n // and we're just replaying the timeline events when syncing\n // after a refresh when the events haven't been stored in the cache yet.\n const exception = new Error(\n \"Unexpected message: expecting \" + this.expectedEvent + \" but got \" + e.getType(),\n );\n this.expectedEvent = undefined;\n if (this.rejectEvent) {\n const reject = this.rejectEvent;\n this.rejectEvent = undefined;\n reject(exception);\n }\n this.cancel(exception);\n }\n }\n\n public async done(): Promise<KeysDuringVerification | void> {\n this.endTimer(); // always kill the activity timer\n if (!this._done) {\n this.request.onVerifierFinished();\n this.resolve?.();\n return requestKeysDuringVerification(this.baseApis, this.userId, this.deviceId);\n }\n }\n\n public cancel(e: Error | MatrixEvent): void {\n this.endTimer(); // always kill the activity timer\n if (!this._done) {\n this.cancelled = true;\n this.request.onVerifierCancelled();\n if (this.userId && this.deviceId) {\n // send a cancellation to the other user (if it wasn't\n // cancelled by the other user)\n if (e === timeoutException) {\n const timeoutEvent = newTimeoutError();\n this.send(timeoutEvent.getType(), timeoutEvent.getContent());\n } else if (e instanceof MatrixEvent) {\n const sender = e.getSender();\n if (sender !== this.userId) {\n const content = e.getContent();\n if (e.getType() === EventType.KeyVerificationCancel) {\n content.code = content.code || \"m.unknown\";\n content.reason = content.reason || content.body || \"Unknown reason\";\n this.send(EventType.KeyVerificationCancel, content);\n } else {\n this.send(EventType.KeyVerificationCancel, {\n code: \"m.unknown\",\n reason: content.body || \"Unknown reason\",\n });\n }\n }\n } else {\n this.send(EventType.KeyVerificationCancel, {\n code: \"m.unknown\",\n reason: e.toString(),\n });\n }\n }\n if (this.promise !== null) {\n // when we cancel without a promise, we end up with a promise\n // but no reject function. If cancel is called again, we'd error.\n if (this.reject) this.reject(e);\n } else {\n // FIXME: this causes an \"Uncaught promise\" console message\n // if nothing ends up chaining this promise.\n this.promise = Promise.reject(e);\n }\n // Also emit a 'cancel' event that the app can listen for to detect cancellation\n // before calling verify()\n this.emit(VerificationEvent.Cancel, e);\n }\n }\n\n /**\n * Begin the key verification\n *\n * @returns Promise which resolves when the verification has\n * completed.\n */\n public verify(): Promise<void> {\n if (this.promise) return this.promise;\n\n this.promise = new Promise((resolve, reject) => {\n this.resolve = (...args): void => {\n this._done = true;\n this.endTimer();\n resolve(...args);\n };\n this.reject = (e: Error | MatrixEvent): void => {\n this._done = true;\n this.endTimer();\n reject(e);\n };\n });\n if (this.doVerification && !this.started) {\n this.started = true;\n this.resetTimer(); // restart the timeout\n new Promise<void>((resolve, reject) => {\n const crossSignId = this.baseApis.crypto!.deviceList.getStoredCrossSigningForUser(this.userId)?.getId();\n if (crossSignId === this.deviceId) {\n reject(new Error(\"Device ID is the same as the cross-signing ID\"));\n }\n resolve();\n })\n .then(() => this.doVerification!())\n .then(this.done.bind(this), this.cancel.bind(this));\n }\n return this.promise;\n }\n\n protected doVerification?: () => Promise<void>;\n\n protected async verifyKeys(userId: string, keys: Record<string, string>, verifier: KeyVerifier): Promise<void> {\n // we try to verify all the keys that we're told about, but we might\n // not know about all of them, so keep track of the keys that we know\n // about, and ignore the rest\n const verifiedDevices: [string, string, string][] = [];\n\n for (const [keyId, keyInfo] of Object.entries(keys)) {\n const deviceId = keyId.split(\":\", 2)[1];\n const device = this.baseApis.getStoredDevice(userId, deviceId);\n if (device) {\n verifier(keyId, device, keyInfo);\n verifiedDevices.push([deviceId, keyId, device.keys[keyId]]);\n } else {\n const crossSigningInfo = this.baseApis.crypto!.deviceList.getStoredCrossSigningForUser(userId);\n if (crossSigningInfo && crossSigningInfo.getId() === deviceId) {\n verifier(\n keyId,\n DeviceInfo.fromStorage(\n {\n keys: {\n [keyId]: deviceId,\n },\n },\n deviceId,\n ),\n keyInfo,\n );\n verifiedDevices.push([deviceId, keyId, deviceId]);\n } else {\n logger.warn(`verification: Could not find device ${deviceId} to verify`);\n }\n }\n }\n\n // if none of the keys could be verified, then error because the app\n // should be informed about that\n if (!verifiedDevices.length) {\n throw new Error(\"No devices could be verified\");\n }\n\n logger.info(\"Verification completed! Marking devices verified: \", verifiedDevices);\n // TODO: There should probably be a batch version of this, otherwise it's going\n // to upload each signature in a separate API call which is silly because the\n // API supports as many signatures as you like.\n for (const [deviceId, keyId, key] of verifiedDevices) {\n await this.baseApis.crypto!.setDeviceVerification(userId, deviceId, true, null, null, { [keyId]: key });\n }\n\n // if one of the user's own devices is being marked as verified / unverified,\n // check the key backup status, since whether or not we use this depends on\n // whether it has a signature from a verified device\n if (userId == this.baseApis.credentials.userId) {\n await this.baseApis.checkKeyBackup();\n }\n }\n\n public get events(): string[] | undefined {\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;AAqBA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,WAAA,GAAAH,OAAA;AACA,IAAAI,MAAA,GAAAJ,OAAA;AACA,IAAAK,aAAA,GAAAL,OAAA;AAIA,IAAAM,kBAAA,GAAAN,OAAA;AA9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAaA,MAAMO,gBAAgB,GAAG,IAAIC,KAAK,CAAC,wBAAwB,CAAC;AAErD,MAAMC,qBAAqB,SAASD,KAAK,CAAC;EACtCE,WAAWA,CAAiBC,UAA8B,EAAE;IAC/D,KAAK,EAAE;IAAC,KADuBA,UAA8B,GAA9BA,UAA8B;EAEjE;AACJ;AAACC,OAAA,CAAAH,qBAAA,GAAAA,qBAAA;AAAA,IAIWI,iBAAiB;AAAAD,OAAA,CAAAC,iBAAA,GAAAA,iBAAA;AAAA,WAAjBA,iBAAiB;EAAjBA,iBAAiB;AAAA,GAAjBA,iBAAiB,KAAAD,OAAA,CAAAC,iBAAA,GAAjBA,iBAAiB;AAQtB,MAAMC,gBAAgB,SAGnBC,oCAAiB,CAAqE;EAY5F;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACWL,WAAWA,CACEM,OAA6B,EAC7BC,QAAsB,EACtBC,MAAc,EACdC,QAAgB,EACzBR,UAA8B,EACrBS,OAA4B,EAC9C;IACE,KAAK,EAAE;IAAC,KAPQJ,OAA6B,GAA7BA,OAA6B;IAAA,KAC7BC,QAAsB,GAAtBA,QAAsB;IAAA,KACtBC,MAAc,GAAdA,MAAc;IAAA,KACdC,QAAgB,GAAhBA,QAAgB;IAAA,KACzBR,UAA8B,GAA9BA,UAA8B;IAAA,KACrBS,OAA4B,GAA5BA,OAA4B;IAAA,IAAAC,gBAAA,CAAAC,OAAA,qBA1C5B,KAAK;IAAA,IAAAD,gBAAA,CAAAC,OAAA,iBACT,KAAK;IAAA,IAAAD,gBAAA,CAAAC,OAAA,mBACmB,IAAI;IAAA,IAAAD,gBAAA,CAAAC,OAAA,mCAC4B,IAAI;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;EA0C5E;EAEA,IAAWC,aAAaA,CAAA,EAAY;IAChC;IACA;IACA;IACA,IAAI,CAAC,IAAI,CAACZ,UAAU,EAAE;MAClB,OAAO,IAAI;IACf;IACA,MAAMa,MAAM,GAAG,IAAI,CAACb,UAAU,CAACc,SAAS,EAAE;IAC1C,MAAMC,OAAO,GAAG,IAAI,CAACf,UAAU,CAACgB,UAAU,EAAE;IAC5C,OAAOH,MAAM,KAAK,IAAI,CAACP,QAAQ,CAACW,SAAS,EAAE,IAAIF,OAAO,CAACG,WAAW,KAAK,IAAI,CAACZ,QAAQ,CAACa,WAAW,EAAE;EACtG;EAEA,IAAWC,gBAAgBA,CAAA,EAAY;IACnC,OAAO,IAAI,CAACC,SAAS;EACzB;EAEQC,UAAUA,CAAA,EAAS;IACvBC,cAAM,CAACC,IAAI,CAAC,gEAAgE,CAAC;IAC7E,IAAI,IAAI,CAACC,uBAAuB,KAAK,IAAI,EAAE;MACvCC,YAAY,CAAC,IAAI,CAACD,uBAAuB,CAAC;IAC9C;IACA,IAAI,CAACA,uBAAuB,GAAGE,UAAU,CAAC,MAAM;MAC5C,IAAI,CAAC,IAAI,CAACC,KAAK,IAAI,CAAC,IAAI,CAACP,SAAS,EAAE;QAChCE,cAAM,CAACC,IAAI,CAAC,iCAAiC,CAAC;QAC9C,IAAI,CAACK,MAAM,CAACjC,gBAAgB,CAAC;MACjC;IACJ,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;EACxB;;EAEQkC,QAAQA,CAAA,EAAS;IACrB,IAAI,IAAI,CAACL,uBAAuB,KAAK,IAAI,EAAE;MACvCC,YAAY,CAAC,IAAI,CAACD,uBAAuB,CAAC;MAC1C,IAAI,CAACA,uBAAuB,GAAG,IAAI;IACvC;EACJ;EAEUM,IAAIA,CAACC,IAAY,EAAEC,kBAAuC,EAAiB;IACjF,OAAO,IAAI,CAAC5B,OAAO,CAAC0B,IAAI,CAACC,IAAI,EAAEC,kBAAkB,CAAC;EACtD;EAEUC,YAAYA,CAACF,IAAY,EAAwB;IACvD,IAAI,IAAI,CAACJ,KAAK,EAAE;MACZ,OAAOO,OAAO,CAACC,MAAM,CAAC,IAAIvC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACpE;IACA,MAAMwC,aAAa,GAAG,IAAI,CAAC5B,OAAO,CAAC6B,sBAAsB,CAACN,IAAI,CAAC;IAC/D,IAAIK,aAAa,EAAE;MACf,OAAOF,OAAO,CAACI,OAAO,CAACF,aAAa,CAAC;IACzC;IAEA,IAAI,CAACG,aAAa,GAAGR,IAAI;IACzB,OAAO,IAAIG,OAAO,CAAC,CAACI,OAAO,EAAEH,MAAM,KAAK;MACpC,IAAI,CAACK,YAAY,GAAGF,OAAO;MAC3B,IAAI,CAACG,WAAW,GAAGN,MAAM;IAC7B,CAAC,CAAC;EACN;EAEOO,mBAAmBA,CAACC,KAAkB,EAAW;IACpD,OAAO,KAAK;EAChB;EAEOC,gBAAgBA,CAACD,KAAkB,EAAQ;IAC9C,IAAI,IAAI,CAACD,mBAAmB,CAACC,KAAK,CAAC,EAAE;MACjCrB,cAAM,CAACuB,GAAG,CAAC,uDAAuD,EAAE;QAAEC,cAAc,EAAE,CAAC,CAAC,IAAI,CAACL;MAAY,CAAC,CAAC;MAC3G,IAAI,IAAI,CAACA,WAAW,EAAE;QAClB,MAAMN,MAAM,GAAG,IAAI,CAACM,WAAW;QAC/B,IAAI,CAACA,WAAW,GAAGM,SAAS;QAC5BZ,MAAM,CAAC,IAAItC,qBAAqB,CAAC8C,KAAK,CAAC,CAAC;MAC5C,CAAC,MAAM;QACH,IAAI,CAAC5C,UAAU,GAAG4C,KAAK;MAC3B;IACJ;EACJ;EAEOK,WAAWA,CAACC,CAAc,EAAQ;IACrC,IAAI,IAAI,CAACtB,KAAK,EAAE;MACZ;IACJ,CAAC,MAAM,IAAIsB,CAAC,CAACC,OAAO,EAAE,KAAK,IAAI,CAACX,aAAa,EAAE;MAC3C;MACA;MACA,IAAI,IAAI,CAACA,aAAa,KAAKY,iBAAS,CAACC,mBAAmB,EAAE;QAAA,IAAAC,kBAAA;QACtD,IAAI,CAACd,aAAa,GAAGQ,SAAS;QAC9B,IAAI,CAACN,WAAW,GAAGM,SAAS;QAC5B,IAAI,CAAC1B,UAAU,EAAE;QACjB,CAAAgC,kBAAA,OAAI,CAACb,YAAY,cAAAa,kBAAA,uBAAjBA,kBAAA,CAAAC,IAAA,KAAI,EAAgBL,CAAC,CAAC;MAC1B;IACJ,CAAC,MAAM,IAAIA,CAAC,CAACC,OAAO,EAAE,KAAKC,iBAAS,CAACI,qBAAqB,EAAE;MACxD,MAAMpB,MAAM,GAAG,IAAI,CAACA,MAAM;MAC1B,IAAI,CAACA,MAAM,GAAGY,SAAS;MACvB;MACA,IAAIZ,MAAM,EAAE;QACR,MAAMrB,OAAO,GAAGmC,CAAC,CAAClC,UAAU,EAAE;QAC9B,MAAM;UAAEyC,MAAM;UAAEC;QAAK,CAAC,GAAG3C,OAAO;QAChCqB,MAAM,CAAC,IAAIvC,KAAK,CAAE,oCAAmC,GAAI,WAAU4D,MAAO,KAAIC,IAAK,GAAE,CAAC,CAAC;MAC3F;IACJ,CAAC,MAAM,IAAI,IAAI,CAAClB,aAAa,EAAE;MAC3B;MACA;MACA;MACA;MACA,MAAMmB,SAAS,GAAG,IAAI9D,KAAK,CACvB,gCAAgC,GAAG,IAAI,CAAC2C,aAAa,GAAG,WAAW,GAAGU,CAAC,CAACC,OAAO,EAAE,CACpF;MACD,IAAI,CAACX,aAAa,GAAGQ,SAAS;MAC9B,IAAI,IAAI,CAACN,WAAW,EAAE;QAClB,MAAMN,MAAM,GAAG,IAAI,CAACM,WAAW;QAC/B,IAAI,CAACA,WAAW,GAAGM,SAAS;QAC5BZ,MAAM,CAACuB,SAAS,CAAC;MACrB;MACA,IAAI,CAAC9B,MAAM,CAAC8B,SAAS,CAAC;IAC1B;EACJ;EAEA,MAAaC,IAAIA,CAAA,EAA2C;IACxD,IAAI,CAAC9B,QAAQ,EAAE,CAAC,CAAC;IACjB,IAAI,CAAC,IAAI,CAACF,KAAK,EAAE;MAAA,IAAAiC,aAAA;MACb,IAAI,CAACpD,OAAO,CAACqD,kBAAkB,EAAE;MACjC,CAAAD,aAAA,OAAI,CAACtB,OAAO,cAAAsB,aAAA,uBAAZA,aAAA,CAAAN,IAAA,KAAI,CAAY;MAChB,OAAO,IAAAQ,2CAA6B,EAAC,IAAI,CAACzD,QAAQ,EAAE,IAAI,CAACC,MAAM,EAAE,IAAI,CAACC,QAAQ,CAAC;IACnF;EACJ;EAEOqB,MAAMA,CAACqB,CAAsB,EAAQ;IACxC,IAAI,CAACpB,QAAQ,EAAE,CAAC,CAAC;IACjB,IAAI,CAAC,IAAI,CAACF,KAAK,EAAE;MACb,IAAI,CAACP,SAAS,GAAG,IAAI;MACrB,IAAI,CAACZ,OAAO,CAACuD,mBAAmB,EAAE;MAClC,IAAI,IAAI,CAACzD,MAAM,IAAI,IAAI,CAACC,QAAQ,EAAE;QAC9B;QACA;QACA,IAAI0C,CAAC,KAAKtD,gBAAgB,EAAE;UACxB,MAAMqE,YAAY,GAAG,IAAAC,sBAAe,GAAE;UACtC,IAAI,CAACnC,IAAI,CAACkC,YAAY,CAACd,OAAO,EAAE,EAAEc,YAAY,CAACjD,UAAU,EAAE,CAAC;QAChE,CAAC,MAAM,IAAIkC,CAAC,YAAYiB,kBAAW,EAAE;UACjC,MAAMtD,MAAM,GAAGqC,CAAC,CAACpC,SAAS,EAAE;UAC5B,IAAID,MAAM,KAAK,IAAI,CAACN,MAAM,EAAE;YACxB,MAAMQ,OAAO,GAAGmC,CAAC,CAAClC,UAAU,EAAE;YAC9B,IAAIkC,CAAC,CAACC,OAAO,EAAE,KAAKC,iBAAS,CAACI,qBAAqB,EAAE;cACjDzC,OAAO,CAAC2C,IAAI,GAAG3C,OAAO,CAAC2C,IAAI,IAAI,WAAW;cAC1C3C,OAAO,CAAC0C,MAAM,GAAG1C,OAAO,CAAC0C,MAAM,IAAI1C,OAAO,CAACqD,IAAI,IAAI,gBAAgB;cACnE,IAAI,CAACrC,IAAI,CAACqB,iBAAS,CAACI,qBAAqB,EAAEzC,OAAO,CAAC;YACvD,CAAC,MAAM;cACH,IAAI,CAACgB,IAAI,CAACqB,iBAAS,CAACI,qBAAqB,EAAE;gBACvCE,IAAI,EAAE,WAAW;gBACjBD,MAAM,EAAE1C,OAAO,CAACqD,IAAI,IAAI;cAC5B,CAAC,CAAC;YACN;UACJ;QACJ,CAAC,MAAM;UACH,IAAI,CAACrC,IAAI,CAACqB,iBAAS,CAACI,qBAAqB,EAAE;YACvCE,IAAI,EAAE,WAAW;YACjBD,MAAM,EAAEP,CAAC,CAACmB,QAAQ;UACtB,CAAC,CAAC;QACN;MACJ;MACA,IAAI,IAAI,CAACC,OAAO,KAAK,IAAI,EAAE;QACvB;QACA;QACA,IAAI,IAAI,CAAClC,MAAM,EAAE,IAAI,CAACA,MAAM,CAACc,CAAC,CAAC;MACnC,CAAC,MAAM;QACH;QACA;QACA,IAAI,CAACoB,OAAO,GAAGnC,OAAO,CAACC,MAAM,CAACc,CAAC,CAAC;MACpC;MACA;MACA;MACA,IAAI,CAACqB,IAAI,CAACrE,iBAAiB,CAACsE,MAAM,EAAEtB,CAAC,CAAC;IAC1C;EACJ;;EAEA;AACJ;AACA;AACA;AACA;AACA;EACWuB,MAAMA,CAAA,EAAkB;IAC3B,IAAI,IAAI,CAACH,OAAO,EAAE,OAAO,IAAI,CAACA,OAAO;IAErC,IAAI,CAACA,OAAO,GAAG,IAAInC,OAAO,CAAC,CAACI,OAAO,EAAEH,MAAM,KAAK;MAC5C,IAAI,CAACG,OAAO,GAAG,CAAC,GAAGmC,IAAI,KAAW;QAC9B,IAAI,CAAC9C,KAAK,GAAG,IAAI;QACjB,IAAI,CAACE,QAAQ,EAAE;QACfS,OAAO,CAAC,GAAGmC,IAAI,CAAC;MACpB,CAAC;MACD,IAAI,CAACtC,MAAM,GAAIc,CAAsB,IAAW;QAC5C,IAAI,CAACtB,KAAK,GAAG,IAAI;QACjB,IAAI,CAACE,QAAQ,EAAE;QACfM,MAAM,CAACc,CAAC,CAAC;MACb,CAAC;IACL,CAAC,CAAC;IACF,IAAI,IAAI,CAACyB,cAAc,IAAI,CAAC,IAAI,CAACC,OAAO,EAAE;MACtC,IAAI,CAACA,OAAO,GAAG,IAAI;MACnB,IAAI,CAACtD,UAAU,EAAE,CAAC,CAAC;MACnB,IAAIa,OAAO,CAAO,CAACI,OAAO,EAAEH,MAAM,KAAK;QAAA,IAAAyC,qBAAA;QACnC,MAAMC,WAAW,IAAAD,qBAAA,GAAG,IAAI,CAACvE,QAAQ,CAACyE,MAAM,CAAEC,UAAU,CAACC,4BAA4B,CAAC,IAAI,CAAC1E,MAAM,CAAC,cAAAsE,qBAAA,uBAA1EA,qBAAA,CAA4EK,KAAK,EAAE;QACvG,IAAIJ,WAAW,KAAK,IAAI,CAACtE,QAAQ,EAAE;UAC/B4B,MAAM,CAAC,IAAIvC,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACtE;QACA0C,OAAO,EAAE;MACb,CAAC,CAAC,CACG4C,IAAI,CAAC,MAAM,IAAI,CAACR,cAAc,EAAG,CAAC,CAClCQ,IAAI,CAAC,IAAI,CAACvB,IAAI,CAACwB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAACvD,MAAM,CAACuD,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D;IACA,OAAO,IAAI,CAACd,OAAO;EACvB;EAIA,MAAgBe,UAAUA,CAAC9E,MAAc,EAAE+E,IAA4B,EAAEC,QAAqB,EAAiB;IAC3G;IACA;IACA;IACA,MAAMC,eAA2C,GAAG,EAAE;IAEtD,KAAK,MAAM,CAACC,KAAK,EAAEC,OAAO,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACN,IAAI,CAAC,EAAE;MACjD,MAAM9E,QAAQ,GAAGiF,KAAK,CAACI,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;MACvC,MAAMC,MAAM,GAAG,IAAI,CAACxF,QAAQ,CAACyF,eAAe,CAACxF,MAAM,EAAEC,QAAQ,CAAC;MAC9D,IAAIsF,MAAM,EAAE;QACRP,QAAQ,CAACE,KAAK,EAAEK,MAAM,EAAEJ,OAAO,CAAC;QAChCF,eAAe,CAACQ,IAAI,CAAC,CAACxF,QAAQ,EAAEiF,KAAK,EAAEK,MAAM,CAACR,IAAI,CAACG,KAAK,CAAC,CAAC,CAAC;MAC/D,CAAC,MAAM;QACH,MAAMQ,gBAAgB,GAAG,IAAI,CAAC3F,QAAQ,CAACyE,MAAM,CAAEC,UAAU,CAACC,4BAA4B,CAAC1E,MAAM,CAAC;QAC9F,IAAI0F,gBAAgB,IAAIA,gBAAgB,CAACf,KAAK,EAAE,KAAK1E,QAAQ,EAAE;UAC3D+E,QAAQ,CACJE,KAAK,EACLS,sBAAU,CAACC,WAAW,CAClB;YACIb,IAAI,EAAE;cACF,CAACG,KAAK,GAAGjF;YACb;UACJ,CAAC,EACDA,QAAQ,CACX,EACDkF,OAAO,CACV;UACDF,eAAe,CAACQ,IAAI,CAAC,CAACxF,QAAQ,EAAEiF,KAAK,EAAEjF,QAAQ,CAAC,CAAC;QACrD,CAAC,MAAM;UACHe,cAAM,CAAC6E,IAAI,CAAE,uCAAsC5F,QAAS,YAAW,CAAC;QAC5E;MACJ;IACJ;;IAEA;IACA;IACA,IAAI,CAACgF,eAAe,CAACa,MAAM,EAAE;MACzB,MAAM,IAAIxG,KAAK,CAAC,8BAA8B,CAAC;IACnD;IAEA0B,cAAM,CAACC,IAAI,CAAC,oDAAoD,EAAEgE,eAAe,CAAC;IAClF;IACA;IACA;IACA,KAAK,MAAM,CAAChF,QAAQ,EAAEiF,KAAK,EAAEa,GAAG,CAAC,IAAId,eAAe,EAAE;MAClD,MAAM,IAAI,CAAClF,QAAQ,CAACyE,MAAM,CAAEwB,qBAAqB,CAAChG,MAAM,EAAEC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;QAAE,CAACiF,KAAK,GAAGa;MAAI,CAAC,CAAC;IAC3G;;IAEA;IACA;IACA;IACA,IAAI/F,MAAM,IAAI,IAAI,CAACD,QAAQ,CAACkG,WAAW,CAACjG,MAAM,EAAE;MAC5C,MAAM,IAAI,CAACD,QAAQ,CAACmG,cAAc,EAAE;IACxC;EACJ;EAEA,IAAWC,MAAMA,CAAA,EAAyB;IACtC,OAAO1D,SAAS;EACpB;AACJ;AAAC/C,OAAA,CAAAE,gBAAA,GAAAA,gBAAA"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts
new file mode 100644
index 0000000..b8fac30
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts
@@ -0,0 +1,35 @@
+/**
+ * Error messages.
+ */
+import { MatrixEvent } from "../../models/event";
+export declare function newVerificationError(code: string, reason: string, extraData?: Record<string, any>): MatrixEvent;
+export declare function errorFactory(code: string, reason: string): (extraData?: Record<string, any>) => MatrixEvent;
+/**
+ * The verification was cancelled by the user.
+ */
+export declare const newUserCancelledError: (extraData?: Record<string, any>) => MatrixEvent;
+/**
+ * The verification timed out.
+ */
+export declare const newTimeoutError: (extraData?: Record<string, any>) => MatrixEvent;
+/**
+ * An unknown method was selected.
+ */
+export declare const newUnknownMethodError: (extraData?: Record<string, any>) => MatrixEvent;
+/**
+ * An unexpected message was sent.
+ */
+export declare const newUnexpectedMessageError: (extraData?: Record<string, any>) => MatrixEvent;
+/**
+ * The key does not match.
+ */
+export declare const newKeyMismatchError: (extraData?: Record<string, any>) => MatrixEvent;
+/**
+ * An invalid message was sent.
+ */
+export declare const newInvalidMessageError: (extraData?: Record<string, any>) => MatrixEvent;
+export declare function errorFromEvent(event: MatrixEvent): {
+ code: string;
+ reason: string;
+};
+//# sourceMappingURL=Error.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts.map
new file mode 100644
index 0000000..63a87b1
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"Error.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/Error.ts"],"names":[],"mappings":"AAgBA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,WAAW,CAM/G;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,WAAW,CAI3G;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,eATuC,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WASjB,CAAC;AAEjF;;GAEG;AACH,eAAO,MAAM,eAAe,eAd6C,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WAc5B,CAAC;AAEtE;;GAEG;AACH,eAAO,MAAM,qBAAqB,eAnBuC,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WAmBV,CAAC;AAExF;;GAEG;AACH,eAAO,MAAM,yBAAyB,eAxBmC,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WAwBE,CAAC;AAEpG;;GAEG;AACH,eAAO,MAAM,mBAAmB,eA7ByC,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WA6BhB,CAAC;AAElF;;GAEG;AACH,eAAO,MAAM,sBAAsB,eAlCsC,OAAO,MAAM,EAAE,GAAG,CAAC,KAAK,WAkCP,CAAC;AAE3F,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAQnF"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js
new file mode 100644
index 0000000..3b4c690
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js
@@ -0,0 +1,101 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.errorFactory = errorFactory;
+exports.errorFromEvent = errorFromEvent;
+exports.newUserCancelledError = exports.newUnknownMethodError = exports.newUnexpectedMessageError = exports.newTimeoutError = exports.newKeyMismatchError = exports.newInvalidMessageError = void 0;
+exports.newVerificationError = newVerificationError;
+var _event = require("../../models/event");
+var _event2 = require("../../@types/event");
+/*
+Copyright 2018 - 2021 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/**
+ * Error messages.
+ */
+
+function newVerificationError(code, reason, extraData) {
+ const content = Object.assign({}, {
+ code,
+ reason
+ }, extraData);
+ return new _event.MatrixEvent({
+ type: _event2.EventType.KeyVerificationCancel,
+ content
+ });
+}
+function errorFactory(code, reason) {
+ return function (extraData) {
+ return newVerificationError(code, reason, extraData);
+ };
+}
+
+/**
+ * The verification was cancelled by the user.
+ */
+const newUserCancelledError = errorFactory("m.user", "Cancelled by user");
+
+/**
+ * The verification timed out.
+ */
+exports.newUserCancelledError = newUserCancelledError;
+const newTimeoutError = errorFactory("m.timeout", "Timed out");
+
+/**
+ * An unknown method was selected.
+ */
+exports.newTimeoutError = newTimeoutError;
+const newUnknownMethodError = errorFactory("m.unknown_method", "Unknown method");
+
+/**
+ * An unexpected message was sent.
+ */
+exports.newUnknownMethodError = newUnknownMethodError;
+const newUnexpectedMessageError = errorFactory("m.unexpected_message", "Unexpected message");
+
+/**
+ * The key does not match.
+ */
+exports.newUnexpectedMessageError = newUnexpectedMessageError;
+const newKeyMismatchError = errorFactory("m.key_mismatch", "Key mismatch");
+
+/**
+ * An invalid message was sent.
+ */
+exports.newKeyMismatchError = newKeyMismatchError;
+const newInvalidMessageError = errorFactory("m.invalid_message", "Invalid message");
+exports.newInvalidMessageError = newInvalidMessageError;
+function errorFromEvent(event) {
+ const content = event.getContent();
+ if (content) {
+ const {
+ code,
+ reason
+ } = content;
+ return {
+ code,
+ reason
+ };
+ } else {
+ return {
+ code: "Unknown error",
+ reason: "m.unknown"
+ };
+ }
+}
+//# sourceMappingURL=Error.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js.map
new file mode 100644
index 0000000..955658f
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/Error.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"Error.js","names":["_event","require","_event2","newVerificationError","code","reason","extraData","content","Object","assign","MatrixEvent","type","EventType","KeyVerificationCancel","errorFactory","newUserCancelledError","exports","newTimeoutError","newUnknownMethodError","newUnexpectedMessageError","newKeyMismatchError","newInvalidMessageError","errorFromEvent","event","getContent"],"sources":["../../../src/crypto/verification/Error.ts"],"sourcesContent":["/*\nCopyright 2018 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Error messages.\n */\n\nimport { MatrixEvent } from \"../../models/event\";\nimport { EventType } from \"../../@types/event\";\n\nexport function newVerificationError(code: string, reason: string, extraData?: Record<string, any>): MatrixEvent {\n const content = Object.assign({}, { code, reason }, extraData);\n return new MatrixEvent({\n type: EventType.KeyVerificationCancel,\n content,\n });\n}\n\nexport function errorFactory(code: string, reason: string): (extraData?: Record<string, any>) => MatrixEvent {\n return function (extraData?: Record<string, any>) {\n return newVerificationError(code, reason, extraData);\n };\n}\n\n/**\n * The verification was cancelled by the user.\n */\nexport const newUserCancelledError = errorFactory(\"m.user\", \"Cancelled by user\");\n\n/**\n * The verification timed out.\n */\nexport const newTimeoutError = errorFactory(\"m.timeout\", \"Timed out\");\n\n/**\n * An unknown method was selected.\n */\nexport const newUnknownMethodError = errorFactory(\"m.unknown_method\", \"Unknown method\");\n\n/**\n * An unexpected message was sent.\n */\nexport const newUnexpectedMessageError = errorFactory(\"m.unexpected_message\", \"Unexpected message\");\n\n/**\n * The key does not match.\n */\nexport const newKeyMismatchError = errorFactory(\"m.key_mismatch\", \"Key mismatch\");\n\n/**\n * An invalid message was sent.\n */\nexport const newInvalidMessageError = errorFactory(\"m.invalid_message\", \"Invalid message\");\n\nexport function errorFromEvent(event: MatrixEvent): { code: string; reason: string } {\n const content = event.getContent();\n if (content) {\n const { code, reason } = content;\n return { code, reason };\n } else {\n return { code: \"Unknown error\", reason: \"m.unknown\" };\n }\n}\n"],"mappings":";;;;;;;;;AAoBA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AArBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAKO,SAASE,oBAAoBA,CAACC,IAAY,EAAEC,MAAc,EAAEC,SAA+B,EAAe;EAC7G,MAAMC,OAAO,GAAGC,MAAM,CAACC,MAAM,CAAC,CAAC,CAAC,EAAE;IAAEL,IAAI;IAAEC;EAAO,CAAC,EAAEC,SAAS,CAAC;EAC9D,OAAO,IAAII,kBAAW,CAAC;IACnBC,IAAI,EAAEC,iBAAS,CAACC,qBAAqB;IACrCN;EACJ,CAAC,CAAC;AACN;AAEO,SAASO,YAAYA,CAACV,IAAY,EAAEC,MAAc,EAAoD;EACzG,OAAO,UAAUC,SAA+B,EAAE;IAC9C,OAAOH,oBAAoB,CAACC,IAAI,EAAEC,MAAM,EAAEC,SAAS,CAAC;EACxD,CAAC;AACL;;AAEA;AACA;AACA;AACO,MAAMS,qBAAqB,GAAGD,YAAY,CAAC,QAAQ,EAAE,mBAAmB,CAAC;;AAEhF;AACA;AACA;AAFAE,OAAA,CAAAD,qBAAA,GAAAA,qBAAA;AAGO,MAAME,eAAe,GAAGH,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC;;AAErE;AACA;AACA;AAFAE,OAAA,CAAAC,eAAA,GAAAA,eAAA;AAGO,MAAMC,qBAAqB,GAAGJ,YAAY,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;;AAEvF;AACA;AACA;AAFAE,OAAA,CAAAE,qBAAA,GAAAA,qBAAA;AAGO,MAAMC,yBAAyB,GAAGL,YAAY,CAAC,sBAAsB,EAAE,oBAAoB,CAAC;;AAEnG;AACA;AACA;AAFAE,OAAA,CAAAG,yBAAA,GAAAA,yBAAA;AAGO,MAAMC,mBAAmB,GAAGN,YAAY,CAAC,gBAAgB,EAAE,cAAc,CAAC;;AAEjF;AACA;AACA;AAFAE,OAAA,CAAAI,mBAAA,GAAAA,mBAAA;AAGO,MAAMC,sBAAsB,GAAGP,YAAY,CAAC,mBAAmB,EAAE,iBAAiB,CAAC;AAACE,OAAA,CAAAK,sBAAA,GAAAA,sBAAA;AAEpF,SAASC,cAAcA,CAACC,KAAkB,EAAoC;EACjF,MAAMhB,OAAO,GAAGgB,KAAK,CAACC,UAAU,EAAE;EAClC,IAAIjB,OAAO,EAAE;IACT,MAAM;MAAEH,IAAI;MAAEC;IAAO,CAAC,GAAGE,OAAO;IAChC,OAAO;MAAEH,IAAI;MAAEC;IAAO,CAAC;EAC3B,CAAC,MAAM;IACH,OAAO;MAAED,IAAI,EAAE,eAAe;MAAEC,MAAM,EAAE;IAAY,CAAC;EACzD;AACJ"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts
new file mode 100644
index 0000000..b0b08b1
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts
@@ -0,0 +1,15 @@
+/**
+ * Verification method that is illegal to have (cannot possibly
+ * do verification with this method).
+ */
+import { VerificationBase as Base, VerificationEvent, VerificationEventHandlerMap } from "./Base";
+import { IVerificationChannel } from "./request/Channel";
+import { MatrixClient } from "../../client";
+import { MatrixEvent } from "../../models/event";
+import { VerificationRequest } from "./request/VerificationRequest";
+export declare class IllegalMethod extends Base<VerificationEvent, VerificationEventHandlerMap> {
+ static factory(channel: IVerificationChannel, baseApis: MatrixClient, userId: string, deviceId: string, startEvent: MatrixEvent, request: VerificationRequest): IllegalMethod;
+ static get NAME(): string;
+ protected doVerification: () => Promise<void>;
+}
+//# sourceMappingURL=IllegalMethod.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts.map
new file mode 100644
index 0000000..f06ce4b
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"IllegalMethod.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/IllegalMethod.ts"],"names":[],"mappings":"AAgBA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,IAAI,IAAI,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,QAAQ,CAAC;AAClG,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEpE,qBAAa,aAAc,SAAQ,IAAI,CAAC,iBAAiB,EAAE,2BAA2B,CAAC;WACrE,OAAO,CACjB,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,mBAAmB,GAC7B,aAAa;IAKhB,WAAkB,IAAI,IAAI,MAAM,CAI/B;IAED,SAAS,CAAC,cAAc,QAAa,QAAQ,IAAI,CAAC,CAEhD;CACL"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js
new file mode 100644
index 0000000..c67a675
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js
@@ -0,0 +1,50 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.IllegalMethod = void 0;
+var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
+var _Base = require("./Base");
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/**
+ * Verification method that is illegal to have (cannot possibly
+ * do verification with this method).
+ */
+
+class IllegalMethod extends _Base.VerificationBase {
+ constructor(...args) {
+ super(...args);
+ (0, _defineProperty2.default)(this, "doVerification", async () => {
+ throw new Error("Verification is not possible with this method");
+ });
+ }
+ static factory(channel, baseApis, userId, deviceId, startEvent, request) {
+ return new IllegalMethod(channel, baseApis, userId, deviceId, startEvent, request);
+ }
+
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ static get NAME() {
+ // Typically the name will be something else, but to complete
+ // the contract we offer a default one here.
+ return "org.matrix.illegal_method";
+ }
+}
+exports.IllegalMethod = IllegalMethod;
+//# sourceMappingURL=IllegalMethod.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js.map
new file mode 100644
index 0000000..df32c4a
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/IllegalMethod.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"IllegalMethod.js","names":["_Base","require","IllegalMethod","Base","constructor","args","_defineProperty2","default","Error","factory","channel","baseApis","userId","deviceId","startEvent","request","NAME","exports"],"sources":["../../../src/crypto/verification/IllegalMethod.ts"],"sourcesContent":["/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Verification method that is illegal to have (cannot possibly\n * do verification with this method).\n */\n\nimport { VerificationBase as Base, VerificationEvent, VerificationEventHandlerMap } from \"./Base\";\nimport { IVerificationChannel } from \"./request/Channel\";\nimport { MatrixClient } from \"../../client\";\nimport { MatrixEvent } from \"../../models/event\";\nimport { VerificationRequest } from \"./request/VerificationRequest\";\n\nexport class IllegalMethod extends Base<VerificationEvent, VerificationEventHandlerMap> {\n public static factory(\n channel: IVerificationChannel,\n baseApis: MatrixClient,\n userId: string,\n deviceId: string,\n startEvent: MatrixEvent,\n request: VerificationRequest,\n ): IllegalMethod {\n return new IllegalMethod(channel, baseApis, userId, deviceId, startEvent, request);\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static get NAME(): string {\n // Typically the name will be something else, but to complete\n // the contract we offer a default one here.\n return \"org.matrix.illegal_method\";\n }\n\n protected doVerification = async (): Promise<void> => {\n throw new Error(\"Verification is not possible with this method\");\n };\n}\n"],"mappings":";;;;;;;;AAqBA,IAAAA,KAAA,GAAAC,OAAA;AArBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAQO,MAAMC,aAAa,SAASC,sBAAI,CAAiD;EAAAC,YAAA,GAAAC,IAAA;IAAA,SAAAA,IAAA;IAAA,IAAAC,gBAAA,CAAAC,OAAA,0BAmBzD,YAA2B;MAClD,MAAM,IAAIC,KAAK,CAAC,+CAA+C,CAAC;IACpE,CAAC;EAAA;EApBD,OAAcC,OAAOA,CACjBC,OAA6B,EAC7BC,QAAsB,EACtBC,MAAc,EACdC,QAAgB,EAChBC,UAAuB,EACvBC,OAA4B,EACf;IACb,OAAO,IAAIb,aAAa,CAACQ,OAAO,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,OAAO,CAAC;EACtF;;EAEA;EACA,WAAkBC,IAAIA,CAAA,EAAW;IAC7B;IACA;IACA,OAAO,2BAA2B;EACtC;AAKJ;AAACC,OAAA,CAAAf,aAAA,GAAAA,aAAA"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts
new file mode 100644
index 0000000..0286f45
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts
@@ -0,0 +1,54 @@
+/// <reference types="node" />
+/**
+ * QR code key verification.
+ */
+import { VerificationBase as Base, VerificationEventHandlerMap } from "./Base";
+import { VerificationRequest } from "./request/VerificationRequest";
+import { MatrixClient } from "../../client";
+import { IVerificationChannel } from "./request/Channel";
+import { MatrixEvent } from "../../models/event";
+export declare const SHOW_QR_CODE_METHOD = "m.qr_code.show.v1";
+export declare const SCAN_QR_CODE_METHOD = "m.qr_code.scan.v1";
+interface IReciprocateQr {
+ confirm(): void;
+ cancel(): void;
+}
+export declare enum QrCodeEvent {
+ ShowReciprocateQr = "show_reciprocate_qr"
+}
+type EventHandlerMap = {
+ [QrCodeEvent.ShowReciprocateQr]: (qr: IReciprocateQr) => void;
+} & VerificationEventHandlerMap;
+export declare class ReciprocateQRCode extends Base<QrCodeEvent, EventHandlerMap> {
+ reciprocateQREvent?: IReciprocateQr;
+ static factory(channel: IVerificationChannel, baseApis: MatrixClient, userId: string, deviceId: string, startEvent: MatrixEvent, request: VerificationRequest): ReciprocateQRCode;
+ static get NAME(): string;
+ protected doVerification: () => Promise<void>;
+}
+declare enum Mode {
+ VerifyOtherUser = 0,
+ VerifySelfTrusted = 1,
+ VerifySelfUntrusted = 2
+}
+export declare class QRCodeData {
+ readonly mode: Mode;
+ private readonly sharedSecret;
+ readonly otherUserMasterKey: string | null;
+ readonly otherDeviceKey: string | null;
+ readonly myMasterKey: string | null;
+ private readonly buffer;
+ constructor(mode: Mode, sharedSecret: string, otherUserMasterKey: string | null, otherDeviceKey: string | null, myMasterKey: string | null, buffer: Buffer);
+ static create(request: VerificationRequest, client: MatrixClient): Promise<QRCodeData>;
+ /**
+ * The unpadded base64 encoded shared secret.
+ */
+ get encodedSharedSecret(): string;
+ getBuffer(): Buffer;
+ private static generateSharedSecret;
+ private static getOtherDeviceKey;
+ private static determineMode;
+ private static generateQrData;
+ private static generateBuffer;
+}
+export {};
+//# sourceMappingURL=QRCode.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts.map
new file mode 100644
index 0000000..b76c304
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"QRCode.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/QRCode.ts"],"names":[],"mappings":";AAgBA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,IAAI,IAAI,EAAE,2BAA2B,EAAE,MAAM,QAAQ,CAAC;AAI/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,eAAO,MAAM,mBAAmB,sBAAsB,CAAC;AACvD,eAAO,MAAM,mBAAmB,sBAAsB,CAAC;AAEvD,UAAU,cAAc;IACpB,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,IAAI,IAAI,CAAC;CAClB;AAED,oBAAY,WAAW;IACnB,iBAAiB,wBAAwB;CAC5C;AAED,KAAK,eAAe,GAAG;IACnB,CAAC,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,cAAc,KAAK,IAAI,CAAC;CACjE,GAAG,2BAA2B,CAAC;AAEhC,qBAAa,iBAAkB,SAAQ,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC;IAC9D,kBAAkB,CAAC,EAAE,cAAc,CAAC;WAE7B,OAAO,CACjB,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,mBAAmB,GAC7B,iBAAiB;IAKpB,WAAkB,IAAI,IAAI,MAAM,CAE/B;IAED,SAAS,CAAC,cAAc,QAAa,QAAQ,IAAI,CAAC,CA+DhD;CACL;AAKD,aAAK,IAAI;IACL,eAAe,IAAO;IACtB,iBAAiB,IAAO;IACxB,mBAAmB,IAAO;CAC7B;AAYD,qBAAa,UAAU;aAEC,IAAI,EAAE,IAAI;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;aAEb,kBAAkB,EAAE,MAAM,GAAG,IAAI;aAEjC,cAAc,EAAE,MAAM,GAAG,IAAI;aAE7B,WAAW,EAAE,MAAM,GAAG,IAAI;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM;gBARP,IAAI,EAAE,IAAI,EACT,YAAY,EAAE,MAAM,EAErB,kBAAkB,EAAE,MAAM,GAAG,IAAI,EAEjC,cAAc,EAAE,MAAM,GAAG,IAAI,EAE7B,WAAW,EAAE,MAAM,GAAG,IAAI,EACzB,MAAM,EAAE,MAAM;WAGf,MAAM,CAAC,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;IA6BnG;;OAEG;IACH,IAAW,mBAAmB,IAAI,MAAM,CAEvC;IAEM,SAAS,IAAI,MAAM;IAI1B,OAAO,CAAC,MAAM,CAAC,oBAAoB;mBAMd,iBAAiB;IAUtC,OAAO,CAAC,MAAM,CAAC,aAAa;IAiB5B,OAAO,CAAC,MAAM,CAAC,cAAc;IAyC7B,OAAO,CAAC,MAAM,CAAC,cAAc;CAkChC"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js
new file mode 100644
index 0000000..6e6ba1c
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js
@@ -0,0 +1,272 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.SHOW_QR_CODE_METHOD = exports.SCAN_QR_CODE_METHOD = exports.ReciprocateQRCode = exports.QrCodeEvent = exports.QRCodeData = void 0;
+var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
+var _Base = require("./Base");
+var _Error = require("./Error");
+var _olmlib = require("../olmlib");
+var _logger = require("../../logger");
+/*
+Copyright 2018 - 2021 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/**
+ * QR code key verification.
+ */
+
+const SHOW_QR_CODE_METHOD = "m.qr_code.show.v1";
+exports.SHOW_QR_CODE_METHOD = SHOW_QR_CODE_METHOD;
+const SCAN_QR_CODE_METHOD = "m.qr_code.scan.v1";
+exports.SCAN_QR_CODE_METHOD = SCAN_QR_CODE_METHOD;
+let QrCodeEvent;
+exports.QrCodeEvent = QrCodeEvent;
+(function (QrCodeEvent) {
+ QrCodeEvent["ShowReciprocateQr"] = "show_reciprocate_qr";
+})(QrCodeEvent || (exports.QrCodeEvent = QrCodeEvent = {}));
+class ReciprocateQRCode extends _Base.VerificationBase {
+ constructor(...args) {
+ super(...args);
+ (0, _defineProperty2.default)(this, "reciprocateQREvent", void 0);
+ (0, _defineProperty2.default)(this, "doVerification", async () => {
+ if (!this.startEvent) {
+ // TODO: Support scanning QR codes
+ throw new Error("It is not currently possible to start verification" + "with this method yet.");
+ }
+ const {
+ qrCodeData
+ } = this.request;
+ // 1. check the secret
+ if (this.startEvent.getContent()["secret"] !== (qrCodeData === null || qrCodeData === void 0 ? void 0 : qrCodeData.encodedSharedSecret)) {
+ throw (0, _Error.newKeyMismatchError)();
+ }
+
+ // 2. ask if other user shows shield as well
+ await new Promise((resolve, reject) => {
+ this.reciprocateQREvent = {
+ confirm: resolve,
+ cancel: () => reject((0, _Error.newUserCancelledError)())
+ };
+ this.emit(QrCodeEvent.ShowReciprocateQr, this.reciprocateQREvent);
+ });
+
+ // 3. determine key to sign / mark as trusted
+ const keys = {};
+ switch (qrCodeData === null || qrCodeData === void 0 ? void 0 : qrCodeData.mode) {
+ case Mode.VerifyOtherUser:
+ {
+ // add master key to keys to be signed, only if we're not doing self-verification
+ const masterKey = qrCodeData.otherUserMasterKey;
+ keys[`ed25519:${masterKey}`] = masterKey;
+ break;
+ }
+ case Mode.VerifySelfTrusted:
+ {
+ const deviceId = this.request.targetDevice.deviceId;
+ keys[`ed25519:${deviceId}`] = qrCodeData.otherDeviceKey;
+ break;
+ }
+ case Mode.VerifySelfUntrusted:
+ {
+ const masterKey = qrCodeData.myMasterKey;
+ keys[`ed25519:${masterKey}`] = masterKey;
+ break;
+ }
+ }
+
+ // 4. sign the key (or mark own MSK as verified in case of MODE_VERIFY_SELF_TRUSTED)
+ await this.verifyKeys(this.userId, keys, (keyId, device, keyInfo) => {
+ // make sure the device has the expected keys
+ const targetKey = keys[keyId];
+ if (!targetKey) throw (0, _Error.newKeyMismatchError)();
+ if (keyInfo !== targetKey) {
+ _logger.logger.error("key ID from key info does not match");
+ throw (0, _Error.newKeyMismatchError)();
+ }
+ for (const deviceKeyId in device.keys) {
+ if (!deviceKeyId.startsWith("ed25519")) continue;
+ const deviceTargetKey = keys[deviceKeyId];
+ if (!deviceTargetKey) throw (0, _Error.newKeyMismatchError)();
+ if (device.keys[deviceKeyId] !== deviceTargetKey) {
+ _logger.logger.error("master key does not match");
+ throw (0, _Error.newKeyMismatchError)();
+ }
+ }
+ });
+ });
+ }
+ static factory(channel, baseApis, userId, deviceId, startEvent, request) {
+ return new ReciprocateQRCode(channel, baseApis, userId, deviceId, startEvent, request);
+ }
+
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ static get NAME() {
+ return "m.reciprocate.v1";
+ }
+}
+exports.ReciprocateQRCode = ReciprocateQRCode;
+const CODE_VERSION = 0x02; // the version of binary QR codes we support
+const BINARY_PREFIX = "MATRIX"; // ASCII, used to prefix the binary format
+var Mode; // We do not trust the master key
+(function (Mode) {
+ Mode[Mode["VerifyOtherUser"] = 0] = "VerifyOtherUser";
+ Mode[Mode["VerifySelfTrusted"] = 1] = "VerifySelfTrusted";
+ Mode[Mode["VerifySelfUntrusted"] = 2] = "VerifySelfUntrusted";
+})(Mode || (Mode = {}));
+class QRCodeData {
+ constructor(mode, sharedSecret,
+ // only set when mode is MODE_VERIFY_OTHER_USER, master key of other party at time of generating QR code
+ otherUserMasterKey,
+ // only set when mode is MODE_VERIFY_SELF_TRUSTED, device key of other party at time of generating QR code
+ otherDeviceKey,
+ // only set when mode is MODE_VERIFY_SELF_UNTRUSTED, own master key at time of generating QR code
+ myMasterKey, buffer) {
+ this.mode = mode;
+ this.sharedSecret = sharedSecret;
+ this.otherUserMasterKey = otherUserMasterKey;
+ this.otherDeviceKey = otherDeviceKey;
+ this.myMasterKey = myMasterKey;
+ this.buffer = buffer;
+ }
+ static async create(request, client) {
+ const sharedSecret = QRCodeData.generateSharedSecret();
+ const mode = QRCodeData.determineMode(request, client);
+ let otherUserMasterKey = null;
+ let otherDeviceKey = null;
+ let myMasterKey = null;
+ if (mode === Mode.VerifyOtherUser) {
+ const otherUserCrossSigningInfo = client.getStoredCrossSigningForUser(request.otherUserId);
+ otherUserMasterKey = otherUserCrossSigningInfo.getId("master");
+ } else if (mode === Mode.VerifySelfTrusted) {
+ otherDeviceKey = await QRCodeData.getOtherDeviceKey(request, client);
+ } else if (mode === Mode.VerifySelfUntrusted) {
+ const myUserId = client.getUserId();
+ const myCrossSigningInfo = client.getStoredCrossSigningForUser(myUserId);
+ myMasterKey = myCrossSigningInfo.getId("master");
+ }
+ const qrData = QRCodeData.generateQrData(request, client, mode, sharedSecret, otherUserMasterKey, otherDeviceKey, myMasterKey);
+ const buffer = QRCodeData.generateBuffer(qrData);
+ return new QRCodeData(mode, sharedSecret, otherUserMasterKey, otherDeviceKey, myMasterKey, buffer);
+ }
+
+ /**
+ * The unpadded base64 encoded shared secret.
+ */
+ get encodedSharedSecret() {
+ return this.sharedSecret;
+ }
+ getBuffer() {
+ return this.buffer;
+ }
+ static generateSharedSecret() {
+ const secretBytes = new Uint8Array(11);
+ global.crypto.getRandomValues(secretBytes);
+ return (0, _olmlib.encodeUnpaddedBase64)(secretBytes);
+ }
+ static async getOtherDeviceKey(request, client) {
+ const myUserId = client.getUserId();
+ const otherDevice = request.targetDevice;
+ const device = otherDevice.deviceId ? client.getStoredDevice(myUserId, otherDevice.deviceId) : undefined;
+ if (!device) {
+ throw new Error("could not find device " + (otherDevice === null || otherDevice === void 0 ? void 0 : otherDevice.deviceId));
+ }
+ return device.getFingerprint();
+ }
+ static determineMode(request, client) {
+ const myUserId = client.getUserId();
+ const otherUserId = request.otherUserId;
+ let mode = Mode.VerifyOtherUser;
+ if (myUserId === otherUserId) {
+ // Mode changes depending on whether or not we trust the master cross signing key
+ const myTrust = client.checkUserTrust(myUserId);
+ if (myTrust.isCrossSigningVerified()) {
+ mode = Mode.VerifySelfTrusted;
+ } else {
+ mode = Mode.VerifySelfUntrusted;
+ }
+ }
+ return mode;
+ }
+ static generateQrData(request, client, mode, encodedSharedSecret, otherUserMasterKey, otherDeviceKey, myMasterKey) {
+ const myUserId = client.getUserId();
+ const transactionId = request.channel.transactionId;
+ const qrData = {
+ prefix: BINARY_PREFIX,
+ version: CODE_VERSION,
+ mode,
+ transactionId,
+ firstKeyB64: "",
+ // worked out shortly
+ secondKeyB64: "",
+ // worked out shortly
+ secretB64: encodedSharedSecret
+ };
+ const myCrossSigningInfo = client.getStoredCrossSigningForUser(myUserId);
+ if (mode === Mode.VerifyOtherUser) {
+ // First key is our master cross signing key
+ qrData.firstKeyB64 = myCrossSigningInfo.getId("master");
+ // Second key is the other user's master cross signing key
+ qrData.secondKeyB64 = otherUserMasterKey;
+ } else if (mode === Mode.VerifySelfTrusted) {
+ // First key is our master cross signing key
+ qrData.firstKeyB64 = myCrossSigningInfo.getId("master");
+ qrData.secondKeyB64 = otherDeviceKey;
+ } else if (mode === Mode.VerifySelfUntrusted) {
+ // First key is our device's key
+ qrData.firstKeyB64 = client.getDeviceEd25519Key();
+ // Second key is what we think our master cross signing key is
+ qrData.secondKeyB64 = myMasterKey;
+ }
+ return qrData;
+ }
+ static generateBuffer(qrData) {
+ let buf = Buffer.alloc(0); // we'll concat our way through life
+
+ const appendByte = b => {
+ const tmpBuf = Buffer.from([b]);
+ buf = Buffer.concat([buf, tmpBuf]);
+ };
+ const appendInt = i => {
+ const tmpBuf = Buffer.alloc(2);
+ tmpBuf.writeInt16BE(i, 0);
+ buf = Buffer.concat([buf, tmpBuf]);
+ };
+ const appendStr = (s, enc, withLengthPrefix = true) => {
+ const tmpBuf = Buffer.from(s, enc);
+ if (withLengthPrefix) appendInt(tmpBuf.byteLength);
+ buf = Buffer.concat([buf, tmpBuf]);
+ };
+ const appendEncBase64 = b64 => {
+ const b = (0, _olmlib.decodeBase64)(b64);
+ const tmpBuf = Buffer.from(b);
+ buf = Buffer.concat([buf, tmpBuf]);
+ };
+
+ // Actually build the buffer for the QR code
+ appendStr(qrData.prefix, "ascii", false);
+ appendByte(qrData.version);
+ appendByte(qrData.mode);
+ appendStr(qrData.transactionId, "utf-8");
+ appendEncBase64(qrData.firstKeyB64);
+ appendEncBase64(qrData.secondKeyB64);
+ appendEncBase64(qrData.secretB64);
+ return buf;
+ }
+}
+exports.QRCodeData = QRCodeData;
+//# sourceMappingURL=QRCode.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js.map
new file mode 100644
index 0000000..4f2ac08
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/QRCode.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"QRCode.js","names":["_Base","require","_Error","_olmlib","_logger","SHOW_QR_CODE_METHOD","exports","SCAN_QR_CODE_METHOD","QrCodeEvent","ReciprocateQRCode","Base","constructor","args","_defineProperty2","default","startEvent","Error","qrCodeData","request","getContent","encodedSharedSecret","newKeyMismatchError","Promise","resolve","reject","reciprocateQREvent","confirm","cancel","newUserCancelledError","emit","ShowReciprocateQr","keys","mode","Mode","VerifyOtherUser","masterKey","otherUserMasterKey","VerifySelfTrusted","deviceId","targetDevice","otherDeviceKey","VerifySelfUntrusted","myMasterKey","verifyKeys","userId","keyId","device","keyInfo","targetKey","logger","error","deviceKeyId","startsWith","deviceTargetKey","factory","channel","baseApis","NAME","CODE_VERSION","BINARY_PREFIX","QRCodeData","sharedSecret","buffer","create","client","generateSharedSecret","determineMode","otherUserCrossSigningInfo","getStoredCrossSigningForUser","otherUserId","getId","getOtherDeviceKey","myUserId","getUserId","myCrossSigningInfo","qrData","generateQrData","generateBuffer","getBuffer","secretBytes","Uint8Array","global","crypto","getRandomValues","encodeUnpaddedBase64","otherDevice","getStoredDevice","undefined","getFingerprint","myTrust","checkUserTrust","isCrossSigningVerified","transactionId","prefix","version","firstKeyB64","secondKeyB64","secretB64","getDeviceEd25519Key","buf","Buffer","alloc","appendByte","b","tmpBuf","from","concat","appendInt","i","writeInt16BE","appendStr","s","enc","withLengthPrefix","byteLength","appendEncBase64","b64","decodeBase64"],"sources":["../../../src/crypto/verification/QRCode.ts"],"sourcesContent":["/*\nCopyright 2018 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * QR code key verification.\n */\n\nimport { VerificationBase as Base, VerificationEventHandlerMap } from \"./Base\";\nimport { newKeyMismatchError, newUserCancelledError } from \"./Error\";\nimport { decodeBase64, encodeUnpaddedBase64 } from \"../olmlib\";\nimport { logger } from \"../../logger\";\nimport { VerificationRequest } from \"./request/VerificationRequest\";\nimport { MatrixClient } from \"../../client\";\nimport { IVerificationChannel } from \"./request/Channel\";\nimport { MatrixEvent } from \"../../models/event\";\n\nexport const SHOW_QR_CODE_METHOD = \"m.qr_code.show.v1\";\nexport const SCAN_QR_CODE_METHOD = \"m.qr_code.scan.v1\";\n\ninterface IReciprocateQr {\n confirm(): void;\n cancel(): void;\n}\n\nexport enum QrCodeEvent {\n ShowReciprocateQr = \"show_reciprocate_qr\",\n}\n\ntype EventHandlerMap = {\n [QrCodeEvent.ShowReciprocateQr]: (qr: IReciprocateQr) => void;\n} & VerificationEventHandlerMap;\n\nexport class ReciprocateQRCode extends Base<QrCodeEvent, EventHandlerMap> {\n public reciprocateQREvent?: IReciprocateQr;\n\n public static factory(\n channel: IVerificationChannel,\n baseApis: MatrixClient,\n userId: string,\n deviceId: string,\n startEvent: MatrixEvent,\n request: VerificationRequest,\n ): ReciprocateQRCode {\n return new ReciprocateQRCode(channel, baseApis, userId, deviceId, startEvent, request);\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static get NAME(): string {\n return \"m.reciprocate.v1\";\n }\n\n protected doVerification = async (): Promise<void> => {\n if (!this.startEvent) {\n // TODO: Support scanning QR codes\n throw new Error(\"It is not currently possible to start verification\" + \"with this method yet.\");\n }\n\n const { qrCodeData } = this.request;\n // 1. check the secret\n if (this.startEvent.getContent()[\"secret\"] !== qrCodeData?.encodedSharedSecret) {\n throw newKeyMismatchError();\n }\n\n // 2. ask if other user shows shield as well\n await new Promise<void>((resolve, reject) => {\n this.reciprocateQREvent = {\n confirm: resolve,\n cancel: () => reject(newUserCancelledError()),\n };\n this.emit(QrCodeEvent.ShowReciprocateQr, this.reciprocateQREvent);\n });\n\n // 3. determine key to sign / mark as trusted\n const keys: Record<string, string> = {};\n\n switch (qrCodeData?.mode) {\n case Mode.VerifyOtherUser: {\n // add master key to keys to be signed, only if we're not doing self-verification\n const masterKey = qrCodeData.otherUserMasterKey;\n keys[`ed25519:${masterKey}`] = masterKey!;\n break;\n }\n case Mode.VerifySelfTrusted: {\n const deviceId = this.request.targetDevice.deviceId;\n keys[`ed25519:${deviceId}`] = qrCodeData.otherDeviceKey!;\n break;\n }\n case Mode.VerifySelfUntrusted: {\n const masterKey = qrCodeData.myMasterKey;\n keys[`ed25519:${masterKey}`] = masterKey!;\n break;\n }\n }\n\n // 4. sign the key (or mark own MSK as verified in case of MODE_VERIFY_SELF_TRUSTED)\n await this.verifyKeys(this.userId, keys, (keyId, device, keyInfo) => {\n // make sure the device has the expected keys\n const targetKey = keys[keyId];\n if (!targetKey) throw newKeyMismatchError();\n\n if (keyInfo !== targetKey) {\n logger.error(\"key ID from key info does not match\");\n throw newKeyMismatchError();\n }\n for (const deviceKeyId in device.keys) {\n if (!deviceKeyId.startsWith(\"ed25519\")) continue;\n const deviceTargetKey = keys[deviceKeyId];\n if (!deviceTargetKey) throw newKeyMismatchError();\n if (device.keys[deviceKeyId] !== deviceTargetKey) {\n logger.error(\"master key does not match\");\n throw newKeyMismatchError();\n }\n }\n });\n };\n}\n\nconst CODE_VERSION = 0x02; // the version of binary QR codes we support\nconst BINARY_PREFIX = \"MATRIX\"; // ASCII, used to prefix the binary format\n\nenum Mode {\n VerifyOtherUser = 0x00, // Verifying someone who isn't us\n VerifySelfTrusted = 0x01, // We trust the master key\n VerifySelfUntrusted = 0x02, // We do not trust the master key\n}\n\ninterface IQrData {\n prefix: string;\n version: number;\n mode: Mode;\n transactionId?: string;\n firstKeyB64: string;\n secondKeyB64: string;\n secretB64: string;\n}\n\nexport class QRCodeData {\n public constructor(\n public readonly mode: Mode,\n private readonly sharedSecret: string,\n // only set when mode is MODE_VERIFY_OTHER_USER, master key of other party at time of generating QR code\n public readonly otherUserMasterKey: string | null,\n // only set when mode is MODE_VERIFY_SELF_TRUSTED, device key of other party at time of generating QR code\n public readonly otherDeviceKey: string | null,\n // only set when mode is MODE_VERIFY_SELF_UNTRUSTED, own master key at time of generating QR code\n public readonly myMasterKey: string | null,\n private readonly buffer: Buffer,\n ) {}\n\n public static async create(request: VerificationRequest, client: MatrixClient): Promise<QRCodeData> {\n const sharedSecret = QRCodeData.generateSharedSecret();\n const mode = QRCodeData.determineMode(request, client);\n let otherUserMasterKey: string | null = null;\n let otherDeviceKey: string | null = null;\n let myMasterKey: string | null = null;\n if (mode === Mode.VerifyOtherUser) {\n const otherUserCrossSigningInfo = client.getStoredCrossSigningForUser(request.otherUserId);\n otherUserMasterKey = otherUserCrossSigningInfo!.getId(\"master\");\n } else if (mode === Mode.VerifySelfTrusted) {\n otherDeviceKey = await QRCodeData.getOtherDeviceKey(request, client);\n } else if (mode === Mode.VerifySelfUntrusted) {\n const myUserId = client.getUserId()!;\n const myCrossSigningInfo = client.getStoredCrossSigningForUser(myUserId);\n myMasterKey = myCrossSigningInfo!.getId(\"master\");\n }\n const qrData = QRCodeData.generateQrData(\n request,\n client,\n mode,\n sharedSecret,\n otherUserMasterKey!,\n otherDeviceKey!,\n myMasterKey!,\n );\n const buffer = QRCodeData.generateBuffer(qrData);\n return new QRCodeData(mode, sharedSecret, otherUserMasterKey, otherDeviceKey, myMasterKey, buffer);\n }\n\n /**\n * The unpadded base64 encoded shared secret.\n */\n public get encodedSharedSecret(): string {\n return this.sharedSecret;\n }\n\n public getBuffer(): Buffer {\n return this.buffer;\n }\n\n private static generateSharedSecret(): string {\n const secretBytes = new Uint8Array(11);\n global.crypto.getRandomValues(secretBytes);\n return encodeUnpaddedBase64(secretBytes);\n }\n\n private static async getOtherDeviceKey(request: VerificationRequest, client: MatrixClient): Promise<string> {\n const myUserId = client.getUserId()!;\n const otherDevice = request.targetDevice;\n const device = otherDevice.deviceId ? client.getStoredDevice(myUserId, otherDevice.deviceId) : undefined;\n if (!device) {\n throw new Error(\"could not find device \" + otherDevice?.deviceId);\n }\n return device.getFingerprint();\n }\n\n private static determineMode(request: VerificationRequest, client: MatrixClient): Mode {\n const myUserId = client.getUserId();\n const otherUserId = request.otherUserId;\n\n let mode = Mode.VerifyOtherUser;\n if (myUserId === otherUserId) {\n // Mode changes depending on whether or not we trust the master cross signing key\n const myTrust = client.checkUserTrust(myUserId);\n if (myTrust.isCrossSigningVerified()) {\n mode = Mode.VerifySelfTrusted;\n } else {\n mode = Mode.VerifySelfUntrusted;\n }\n }\n return mode;\n }\n\n private static generateQrData(\n request: VerificationRequest,\n client: MatrixClient,\n mode: Mode,\n encodedSharedSecret: string,\n otherUserMasterKey?: string,\n otherDeviceKey?: string,\n myMasterKey?: string,\n ): IQrData {\n const myUserId = client.getUserId()!;\n const transactionId = request.channel.transactionId;\n const qrData: IQrData = {\n prefix: BINARY_PREFIX,\n version: CODE_VERSION,\n mode,\n transactionId,\n firstKeyB64: \"\", // worked out shortly\n secondKeyB64: \"\", // worked out shortly\n secretB64: encodedSharedSecret,\n };\n\n const myCrossSigningInfo = client.getStoredCrossSigningForUser(myUserId);\n\n if (mode === Mode.VerifyOtherUser) {\n // First key is our master cross signing key\n qrData.firstKeyB64 = myCrossSigningInfo!.getId(\"master\")!;\n // Second key is the other user's master cross signing key\n qrData.secondKeyB64 = otherUserMasterKey!;\n } else if (mode === Mode.VerifySelfTrusted) {\n // First key is our master cross signing key\n qrData.firstKeyB64 = myCrossSigningInfo!.getId(\"master\")!;\n qrData.secondKeyB64 = otherDeviceKey!;\n } else if (mode === Mode.VerifySelfUntrusted) {\n // First key is our device's key\n qrData.firstKeyB64 = client.getDeviceEd25519Key()!;\n // Second key is what we think our master cross signing key is\n qrData.secondKeyB64 = myMasterKey!;\n }\n return qrData;\n }\n\n private static generateBuffer(qrData: IQrData): Buffer {\n let buf = Buffer.alloc(0); // we'll concat our way through life\n\n const appendByte = (b: number): void => {\n const tmpBuf = Buffer.from([b]);\n buf = Buffer.concat([buf, tmpBuf]);\n };\n const appendInt = (i: number): void => {\n const tmpBuf = Buffer.alloc(2);\n tmpBuf.writeInt16BE(i, 0);\n buf = Buffer.concat([buf, tmpBuf]);\n };\n const appendStr = (s: string, enc: BufferEncoding, withLengthPrefix = true): void => {\n const tmpBuf = Buffer.from(s, enc);\n if (withLengthPrefix) appendInt(tmpBuf.byteLength);\n buf = Buffer.concat([buf, tmpBuf]);\n };\n const appendEncBase64 = (b64: string): void => {\n const b = decodeBase64(b64);\n const tmpBuf = Buffer.from(b);\n buf = Buffer.concat([buf, tmpBuf]);\n };\n\n // Actually build the buffer for the QR code\n appendStr(qrData.prefix, \"ascii\", false);\n appendByte(qrData.version);\n appendByte(qrData.mode);\n appendStr(qrData.transactionId!, \"utf-8\");\n appendEncBase64(qrData.firstKeyB64);\n appendEncBase64(qrData.secondKeyB64);\n appendEncBase64(qrData.secretB64);\n\n return buf;\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts
new file mode 100644
index 0000000..0854f13
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts
@@ -0,0 +1,37 @@
+import { VerificationBase as Base, VerificationEventHandlerMap } from "./Base";
+import { MatrixEvent } from "../../models/event";
+type EmojiMapping = [emoji: string, name: string];
+export interface IGeneratedSas {
+ decimal?: [number, number, number];
+ emoji?: EmojiMapping[];
+}
+export interface ISasEvent {
+ sas: IGeneratedSas;
+ confirm(): Promise<void>;
+ cancel(): void;
+ mismatch(): void;
+}
+export declare enum SasEvent {
+ ShowSas = "show_sas"
+}
+type EventHandlerMap = {
+ [SasEvent.ShowSas]: (sas: ISasEvent) => void;
+} & VerificationEventHandlerMap;
+export declare class SAS extends Base<SasEvent, EventHandlerMap> {
+ private waitingForAccept?;
+ ourSASPubKey?: string;
+ theirSASPubKey?: string;
+ sasEvent?: ISasEvent;
+ static get NAME(): string;
+ get events(): string[];
+ protected doVerification: () => Promise<void>;
+ canSwitchStartEvent(event: MatrixEvent): boolean;
+ private sendStart;
+ private verifyAndCheckMAC;
+ private doSendVerification;
+ private doRespondVerification;
+ private sendMAC;
+ private checkMAC;
+}
+export {};
+//# sourceMappingURL=SAS.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts.map
new file mode 100644
index 0000000..7e02a7b
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"SAS.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/SAS.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,gBAAgB,IAAI,IAAI,EAAyB,2BAA2B,EAAE,MAAM,QAAQ,CAAC;AAStG,OAAO,EAAY,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAc3D,KAAK,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAyFlD,MAAM,WAAW,aAAa;IAC1B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACtB,GAAG,EAAE,aAAa,CAAC;IACnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,IAAI,IAAI,CAAC;IACf,QAAQ,IAAI,IAAI,CAAC;CACpB;AA6ED,oBAAY,QAAQ;IAChB,OAAO,aAAa;CACvB;AAED,KAAK,eAAe,GAAG;IACnB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;CAChD,GAAG,2BAA2B,CAAC;AAEhC,qBAAa,GAAI,SAAQ,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC;IACpD,OAAO,CAAC,gBAAgB,CAAC,CAAU;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,CAAC;IAG5B,WAAkB,IAAI,IAAI,MAAM,CAE/B;IAED,IAAW,MAAM,IAAI,MAAM,EAAE,CAE5B;IAED,SAAS,CAAC,cAAc,QAAa,QAAQ,IAAI,CAAC,CAyBhD;IAEK,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;YAQzC,SAAS;YAcT,iBAAiB;YAsCjB,kBAAkB;YAiElB,qBAAqB;IA8CnC,OAAO,CAAC,OAAO;YA0BD,QAAQ;CAsBzB"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js
new file mode 100644
index 0000000..781e203
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js
@@ -0,0 +1,453 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.SasEvent = exports.SAS = void 0;
+var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
+var _anotherJson = _interopRequireDefault(require("another-json"));
+var _Base = require("./Base");
+var _Error = require("./Error");
+var _logger = require("../../logger");
+var _SASDecimal = require("./SASDecimal");
+var _event = require("../../@types/event");
+/*
+Copyright 2018 - 2021 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/**
+ * Short Authentication String (SAS) verification.
+ */
+
+const START_TYPE = _event.EventType.KeyVerificationStart;
+const EVENTS = [_event.EventType.KeyVerificationAccept, _event.EventType.KeyVerificationKey, _event.EventType.KeyVerificationMac];
+let olmutil;
+const newMismatchedSASError = (0, _Error.errorFactory)("m.mismatched_sas", "Mismatched short authentication string");
+const newMismatchedCommitmentError = (0, _Error.errorFactory)("m.mismatched_commitment", "Mismatched commitment");
+const emojiMapping = [["🐶", "dog"],
+// 0
+["🐱", "cat"],
+// 1
+["🦁", "lion"],
+// 2
+["🐎", "horse"],
+// 3
+["🦄", "unicorn"],
+// 4
+["🐷", "pig"],
+// 5
+["🐘", "elephant"],
+// 6
+["🐰", "rabbit"],
+// 7
+["🐼", "panda"],
+// 8
+["🐓", "rooster"],
+// 9
+["🐧", "penguin"],
+// 10
+["🐢", "turtle"],
+// 11
+["🐟", "fish"],
+// 12
+["🐙", "octopus"],
+// 13
+["🦋", "butterfly"],
+// 14
+["🌷", "flower"],
+// 15
+["🌳", "tree"],
+// 16
+["🌵", "cactus"],
+// 17
+["🍄", "mushroom"],
+// 18
+["🌏", "globe"],
+// 19
+["🌙", "moon"],
+// 20
+["☁️", "cloud"],
+// 21
+["🔥", "fire"],
+// 22
+["🍌", "banana"],
+// 23
+["🍎", "apple"],
+// 24
+["🍓", "strawberry"],
+// 25
+["🌽", "corn"],
+// 26
+["🍕", "pizza"],
+// 27
+["🎂", "cake"],
+// 28
+["❤️", "heart"],
+// 29
+["🙂", "smiley"],
+// 30
+["🤖", "robot"],
+// 31
+["🎩", "hat"],
+// 32
+["👓", "glasses"],
+// 33
+["🔧", "spanner"],
+// 34
+["🎅", "santa"],
+// 35
+["👍", "thumbs up"],
+// 36
+["☂️", "umbrella"],
+// 37
+["⌛", "hourglass"],
+// 38
+["⏰", "clock"],
+// 39
+["🎁", "gift"],
+// 40
+["💡", "light bulb"],
+// 41
+["📕", "book"],
+// 42
+["✏️", "pencil"],
+// 43
+["📎", "paperclip"],
+// 44
+["✂️", "scissors"],
+// 45
+["🔒", "lock"],
+// 46
+["🔑", "key"],
+// 47
+["🔨", "hammer"],
+// 48
+["☎️", "telephone"],
+// 49
+["🏁", "flag"],
+// 50
+["🚂", "train"],
+// 51
+["🚲", "bicycle"],
+// 52
+["✈️", "aeroplane"],
+// 53
+["🚀", "rocket"],
+// 54
+["🏆", "trophy"],
+// 55
+["⚽", "ball"],
+// 56
+["🎸", "guitar"],
+// 57
+["🎺", "trumpet"],
+// 58
+["🔔", "bell"],
+// 59
+["⚓️", "anchor"],
+// 60
+["🎧", "headphones"],
+// 61
+["📁", "folder"],
+// 62
+["📌", "pin"] // 63
+];
+
+function generateEmojiSas(sasBytes) {
+ const emojis = [
+ // just like base64 encoding
+ sasBytes[0] >> 2, (sasBytes[0] & 0x3) << 4 | sasBytes[1] >> 4, (sasBytes[1] & 0xf) << 2 | sasBytes[2] >> 6, sasBytes[2] & 0x3f, sasBytes[3] >> 2, (sasBytes[3] & 0x3) << 4 | sasBytes[4] >> 4, (sasBytes[4] & 0xf) << 2 | sasBytes[5] >> 6];
+ return emojis.map(num => emojiMapping[num]);
+}
+const sasGenerators = {
+ decimal: _SASDecimal.generateDecimalSas,
+ emoji: generateEmojiSas
+};
+function generateSas(sasBytes, methods) {
+ const sas = {};
+ for (const method of methods) {
+ if (method in sasGenerators) {
+ // @ts-ignore - ts doesn't like us mixing types like this
+ sas[method] = sasGenerators[method](Array.from(sasBytes));
+ }
+ }
+ return sas;
+}
+const macMethods = {
+ "hkdf-hmac-sha256": "calculate_mac",
+ "org.matrix.msc3783.hkdf-hmac-sha256": "calculate_mac_fixed_base64",
+ "hkdf-hmac-sha256.v2": "calculate_mac_fixed_base64",
+ "hmac-sha256": "calculate_mac_long_kdf"
+};
+function calculateMAC(olmSAS, method) {
+ return function (input, info) {
+ const mac = olmSAS[macMethods[method]](input, info);
+ _logger.logger.log("SAS calculateMAC:", method, [input, info], mac);
+ return mac;
+ };
+}
+const calculateKeyAgreement = {
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ "curve25519-hkdf-sha256": function (sas, olmSAS, bytes) {
+ const ourInfo = `${sas.baseApis.getUserId()}|${sas.baseApis.deviceId}|` + `${sas.ourSASPubKey}|`;
+ const theirInfo = `${sas.userId}|${sas.deviceId}|${sas.theirSASPubKey}|`;
+ const sasInfo = "MATRIX_KEY_VERIFICATION_SAS|" + (sas.initiatedByMe ? ourInfo + theirInfo : theirInfo + ourInfo) + sas.channel.transactionId;
+ return olmSAS.generate_bytes(sasInfo, bytes);
+ },
+ "curve25519": function (sas, olmSAS, bytes) {
+ const ourInfo = `${sas.baseApis.getUserId()}${sas.baseApis.deviceId}`;
+ const theirInfo = `${sas.userId}${sas.deviceId}`;
+ const sasInfo = "MATRIX_KEY_VERIFICATION_SAS" + (sas.initiatedByMe ? ourInfo + theirInfo : theirInfo + ourInfo) + sas.channel.transactionId;
+ return olmSAS.generate_bytes(sasInfo, bytes);
+ }
+};
+/* lists of algorithms/methods that are supported. The key agreement, hashes,
+ * and MAC lists should be sorted in order of preference (most preferred
+ * first).
+ */
+const KEY_AGREEMENT_LIST = ["curve25519-hkdf-sha256", "curve25519"];
+const HASHES_LIST = ["sha256"];
+const MAC_LIST = ["hkdf-hmac-sha256.v2", "org.matrix.msc3783.hkdf-hmac-sha256", "hkdf-hmac-sha256", "hmac-sha256"];
+const SAS_LIST = Object.keys(sasGenerators);
+const KEY_AGREEMENT_SET = new Set(KEY_AGREEMENT_LIST);
+const HASHES_SET = new Set(HASHES_LIST);
+const MAC_SET = new Set(MAC_LIST);
+const SAS_SET = new Set(SAS_LIST);
+function intersection(anArray, aSet) {
+ return Array.isArray(anArray) ? anArray.filter(x => aSet.has(x)) : [];
+}
+let SasEvent;
+exports.SasEvent = SasEvent;
+(function (SasEvent) {
+ SasEvent["ShowSas"] = "show_sas";
+})(SasEvent || (exports.SasEvent = SasEvent = {}));
+class SAS extends _Base.VerificationBase {
+ constructor(...args) {
+ super(...args);
+ (0, _defineProperty2.default)(this, "waitingForAccept", void 0);
+ (0, _defineProperty2.default)(this, "ourSASPubKey", void 0);
+ (0, _defineProperty2.default)(this, "theirSASPubKey", void 0);
+ (0, _defineProperty2.default)(this, "sasEvent", void 0);
+ (0, _defineProperty2.default)(this, "doVerification", async () => {
+ await global.Olm.init();
+ olmutil = olmutil || new global.Olm.Utility();
+
+ // make sure user's keys are downloaded
+ await this.baseApis.downloadKeys([this.userId]);
+ let retry = false;
+ do {
+ try {
+ if (this.initiatedByMe) {
+ return await this.doSendVerification();
+ } else {
+ return await this.doRespondVerification();
+ }
+ } catch (err) {
+ if (err instanceof _Base.SwitchStartEventError) {
+ // this changes what initiatedByMe returns
+ this.startEvent = err.startEvent;
+ retry = true;
+ } else {
+ throw err;
+ }
+ }
+ } while (retry);
+ });
+ }
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ static get NAME() {
+ return "m.sas.v1";
+ }
+ get events() {
+ return EVENTS;
+ }
+ canSwitchStartEvent(event) {
+ if (event.getType() !== START_TYPE) {
+ return false;
+ }
+ const content = event.getContent();
+ return (content === null || content === void 0 ? void 0 : content.method) === SAS.NAME && !!this.waitingForAccept;
+ }
+ async sendStart() {
+ const startContent = this.channel.completeContent(START_TYPE, {
+ method: SAS.NAME,
+ from_device: this.baseApis.deviceId,
+ key_agreement_protocols: KEY_AGREEMENT_LIST,
+ hashes: HASHES_LIST,
+ message_authentication_codes: MAC_LIST,
+ // FIXME: allow app to specify what SAS methods can be used
+ short_authentication_string: SAS_LIST
+ });
+ await this.channel.sendCompleted(START_TYPE, startContent);
+ return startContent;
+ }
+ async verifyAndCheckMAC(keyAgreement, sasMethods, olmSAS, macMethod) {
+ const sasBytes = calculateKeyAgreement[keyAgreement](this, olmSAS, 6);
+ const verifySAS = new Promise((resolve, reject) => {
+ this.sasEvent = {
+ sas: generateSas(sasBytes, sasMethods),
+ confirm: async () => {
+ try {
+ await this.sendMAC(olmSAS, macMethod);
+ resolve();
+ } catch (err) {
+ reject(err);
+ }
+ },
+ cancel: () => reject((0, _Error.newUserCancelledError)()),
+ mismatch: () => reject(newMismatchedSASError())
+ };
+ this.emit(SasEvent.ShowSas, this.sasEvent);
+ });
+ const [e] = await Promise.all([this.waitForEvent(_event.EventType.KeyVerificationMac).then(e => {
+ // we don't expect any more messages from the other
+ // party, and they may send a m.key.verification.done
+ // when they're done on their end
+ this.expectedEvent = _event.EventType.KeyVerificationDone;
+ return e;
+ }), verifySAS]);
+ const content = e.getContent();
+ await this.checkMAC(olmSAS, content, macMethod);
+ }
+ async doSendVerification() {
+ this.waitingForAccept = true;
+ let startContent;
+ if (this.startEvent) {
+ startContent = this.channel.completedContentFromEvent(this.startEvent);
+ } else {
+ startContent = await this.sendStart();
+ }
+
+ // we might have switched to a different start event,
+ // but was we didn't call _waitForEvent there was no
+ // call that could throw yet. So check manually that
+ // we're still on the initiator side
+ if (!this.initiatedByMe) {
+ throw new _Base.SwitchStartEventError(this.startEvent);
+ }
+ let e;
+ try {
+ e = await this.waitForEvent(_event.EventType.KeyVerificationAccept);
+ } finally {
+ this.waitingForAccept = false;
+ }
+ let content = e.getContent();
+ const sasMethods = intersection(content.short_authentication_string, SAS_SET);
+ if (!(KEY_AGREEMENT_SET.has(content.key_agreement_protocol) && HASHES_SET.has(content.hash) && MAC_SET.has(content.message_authentication_code) && sasMethods.length)) {
+ throw (0, _Error.newUnknownMethodError)();
+ }
+ if (typeof content.commitment !== "string") {
+ throw (0, _Error.newInvalidMessageError)();
+ }
+ const keyAgreement = content.key_agreement_protocol;
+ const macMethod = content.message_authentication_code;
+ const hashCommitment = content.commitment;
+ const olmSAS = new global.Olm.SAS();
+ try {
+ this.ourSASPubKey = olmSAS.get_pubkey();
+ await this.send(_event.EventType.KeyVerificationKey, {
+ key: this.ourSASPubKey
+ });
+ e = await this.waitForEvent(_event.EventType.KeyVerificationKey);
+ // FIXME: make sure event is properly formed
+ content = e.getContent();
+ const commitmentStr = content.key + _anotherJson.default.stringify(startContent);
+ // TODO: use selected hash function (when we support multiple)
+ if (olmutil.sha256(commitmentStr) !== hashCommitment) {
+ throw newMismatchedCommitmentError();
+ }
+ this.theirSASPubKey = content.key;
+ olmSAS.set_their_key(content.key);
+ await this.verifyAndCheckMAC(keyAgreement, sasMethods, olmSAS, macMethod);
+ } finally {
+ olmSAS.free();
+ }
+ }
+ async doRespondVerification() {
+ // as m.related_to is not included in the encrypted content in e2e rooms,
+ // we need to make sure it is added
+ let content = this.channel.completedContentFromEvent(this.startEvent);
+
+ // Note: we intersect using our pre-made lists, rather than the sets,
+ // so that the result will be in our order of preference. Then
+ // fetching the first element from the array will give our preferred
+ // method out of the ones offered by the other party.
+ const keyAgreement = intersection(KEY_AGREEMENT_LIST, new Set(content.key_agreement_protocols))[0];
+ const hashMethod = intersection(HASHES_LIST, new Set(content.hashes))[0];
+ const macMethod = intersection(MAC_LIST, new Set(content.message_authentication_codes))[0];
+ // FIXME: allow app to specify what SAS methods can be used
+ const sasMethods = intersection(content.short_authentication_string, SAS_SET);
+ if (!(keyAgreement !== undefined && hashMethod !== undefined && macMethod !== undefined && sasMethods.length)) {
+ throw (0, _Error.newUnknownMethodError)();
+ }
+ const olmSAS = new global.Olm.SAS();
+ try {
+ const commitmentStr = olmSAS.get_pubkey() + _anotherJson.default.stringify(content);
+ await this.send(_event.EventType.KeyVerificationAccept, {
+ key_agreement_protocol: keyAgreement,
+ hash: hashMethod,
+ message_authentication_code: macMethod,
+ short_authentication_string: sasMethods,
+ // TODO: use selected hash function (when we support multiple)
+ commitment: olmutil.sha256(commitmentStr)
+ });
+ const e = await this.waitForEvent(_event.EventType.KeyVerificationKey);
+ // FIXME: make sure event is properly formed
+ content = e.getContent();
+ this.theirSASPubKey = content.key;
+ olmSAS.set_their_key(content.key);
+ this.ourSASPubKey = olmSAS.get_pubkey();
+ await this.send(_event.EventType.KeyVerificationKey, {
+ key: this.ourSASPubKey
+ });
+ await this.verifyAndCheckMAC(keyAgreement, sasMethods, olmSAS, macMethod);
+ } finally {
+ olmSAS.free();
+ }
+ }
+ sendMAC(olmSAS, method) {
+ const mac = {};
+ const keyList = [];
+ const baseInfo = "MATRIX_KEY_VERIFICATION_MAC" + this.baseApis.getUserId() + this.baseApis.deviceId + this.userId + this.deviceId + this.channel.transactionId;
+ const deviceKeyId = `ed25519:${this.baseApis.deviceId}`;
+ mac[deviceKeyId] = calculateMAC(olmSAS, method)(this.baseApis.getDeviceEd25519Key(), baseInfo + deviceKeyId);
+ keyList.push(deviceKeyId);
+ const crossSigningId = this.baseApis.getCrossSigningId();
+ if (crossSigningId) {
+ const crossSigningKeyId = `ed25519:${crossSigningId}`;
+ mac[crossSigningKeyId] = calculateMAC(olmSAS, method)(crossSigningId, baseInfo + crossSigningKeyId);
+ keyList.push(crossSigningKeyId);
+ }
+ const keys = calculateMAC(olmSAS, method)(keyList.sort().join(","), baseInfo + "KEY_IDS");
+ return this.send(_event.EventType.KeyVerificationMac, {
+ mac,
+ keys
+ });
+ }
+ async checkMAC(olmSAS, content, method) {
+ const baseInfo = "MATRIX_KEY_VERIFICATION_MAC" + this.userId + this.deviceId + this.baseApis.getUserId() + this.baseApis.deviceId + this.channel.transactionId;
+ if (content.keys !== calculateMAC(olmSAS, method)(Object.keys(content.mac).sort().join(","), baseInfo + "KEY_IDS")) {
+ throw (0, _Error.newKeyMismatchError)();
+ }
+ await this.verifyKeys(this.userId, content.mac, (keyId, device, keyInfo) => {
+ if (keyInfo !== calculateMAC(olmSAS, method)(device.keys[keyId], baseInfo + keyId)) {
+ throw (0, _Error.newKeyMismatchError)();
+ }
+ });
+ }
+}
+exports.SAS = SAS;
+//# sourceMappingURL=SAS.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js.map
new file mode 100644
index 0000000..be47b3f
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SAS.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"SAS.js","names":["_anotherJson","_interopRequireDefault","require","_Base","_Error","_logger","_SASDecimal","_event","START_TYPE","EventType","KeyVerificationStart","EVENTS","KeyVerificationAccept","KeyVerificationKey","KeyVerificationMac","olmutil","newMismatchedSASError","errorFactory","newMismatchedCommitmentError","emojiMapping","generateEmojiSas","sasBytes","emojis","map","num","sasGenerators","decimal","generateDecimalSas","emoji","generateSas","methods","sas","method","Array","from","macMethods","calculateMAC","olmSAS","input","info","mac","logger","log","calculateKeyAgreement","curve25519-hkdf-sha256","bytes","ourInfo","baseApis","getUserId","deviceId","ourSASPubKey","theirInfo","userId","theirSASPubKey","sasInfo","initiatedByMe","channel","transactionId","generate_bytes","curve25519","KEY_AGREEMENT_LIST","HASHES_LIST","MAC_LIST","SAS_LIST","Object","keys","KEY_AGREEMENT_SET","Set","HASHES_SET","MAC_SET","SAS_SET","intersection","anArray","aSet","isArray","filter","x","has","SasEvent","exports","SAS","Base","constructor","args","_defineProperty2","default","global","Olm","init","Utility","downloadKeys","retry","doSendVerification","doRespondVerification","err","SwitchStartEventError","startEvent","NAME","events","canSwitchStartEvent","event","getType","content","getContent","waitingForAccept","sendStart","startContent","completeContent","from_device","key_agreement_protocols","hashes","message_authentication_codes","short_authentication_string","sendCompleted","verifyAndCheckMAC","keyAgreement","sasMethods","macMethod","verifySAS","Promise","resolve","reject","sasEvent","confirm","sendMAC","cancel","newUserCancelledError","mismatch","emit","ShowSas","e","all","waitForEvent","then","expectedEvent","KeyVerificationDone","checkMAC","completedContentFromEvent","key_agreement_protocol","hash","message_authentication_code","length","newUnknownMethodError","commitment","newInvalidMessageError","hashCommitment","get_pubkey","send","key","commitmentStr","anotherjson","stringify","sha256","set_their_key","free","hashMethod","undefined","keyList","baseInfo","deviceKeyId","getDeviceEd25519Key","push","crossSigningId","getCrossSigningId","crossSigningKeyId","sort","join","newKeyMismatchError","verifyKeys","keyId","device","keyInfo"],"sources":["../../../src/crypto/verification/SAS.ts"],"sourcesContent":["/*\nCopyright 2018 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Short Authentication String (SAS) verification.\n */\n\nimport anotherjson from \"another-json\";\nimport { Utility, SAS as OlmSAS } from \"@matrix-org/olm\";\n\nimport { VerificationBase as Base, SwitchStartEventError, VerificationEventHandlerMap } from \"./Base\";\nimport {\n errorFactory,\n newInvalidMessageError,\n newKeyMismatchError,\n newUnknownMethodError,\n newUserCancelledError,\n} from \"./Error\";\nimport { logger } from \"../../logger\";\nimport { IContent, MatrixEvent } from \"../../models/event\";\nimport { generateDecimalSas } from \"./SASDecimal\";\nimport { EventType } from \"../../@types/event\";\n\nconst START_TYPE = EventType.KeyVerificationStart;\n\nconst EVENTS = [EventType.KeyVerificationAccept, EventType.KeyVerificationKey, EventType.KeyVerificationMac];\n\nlet olmutil: Utility;\n\nconst newMismatchedSASError = errorFactory(\"m.mismatched_sas\", \"Mismatched short authentication string\");\n\nconst newMismatchedCommitmentError = errorFactory(\"m.mismatched_commitment\", \"Mismatched commitment\");\n\ntype EmojiMapping = [emoji: string, name: string];\n\nconst emojiMapping: EmojiMapping[] = [\n [\"🐶\", \"dog\"], // 0\n [\"🐱\", \"cat\"], // 1\n [\"🦁\", \"lion\"], // 2\n [\"🐎\", \"horse\"], // 3\n [\"🦄\", \"unicorn\"], // 4\n [\"🐷\", \"pig\"], // 5\n [\"🐘\", \"elephant\"], // 6\n [\"🐰\", \"rabbit\"], // 7\n [\"🐼\", \"panda\"], // 8\n [\"🐓\", \"rooster\"], // 9\n [\"🐧\", \"penguin\"], // 10\n [\"🐢\", \"turtle\"], // 11\n [\"🐟\", \"fish\"], // 12\n [\"🐙\", \"octopus\"], // 13\n [\"🦋\", \"butterfly\"], // 14\n [\"🌷\", \"flower\"], // 15\n [\"🌳\", \"tree\"], // 16\n [\"🌵\", \"cactus\"], // 17\n [\"🍄\", \"mushroom\"], // 18\n [\"🌏\", \"globe\"], // 19\n [\"🌙\", \"moon\"], // 20\n [\"☁️\", \"cloud\"], // 21\n [\"🔥\", \"fire\"], // 22\n [\"🍌\", \"banana\"], // 23\n [\"🍎\", \"apple\"], // 24\n [\"🍓\", \"strawberry\"], // 25\n [\"🌽\", \"corn\"], // 26\n [\"🍕\", \"pizza\"], // 27\n [\"🎂\", \"cake\"], // 28\n [\"❤️\", \"heart\"], // 29\n [\"🙂\", \"smiley\"], // 30\n [\"🤖\", \"robot\"], // 31\n [\"🎩\", \"hat\"], // 32\n [\"👓\", \"glasses\"], // 33\n [\"🔧\", \"spanner\"], // 34\n [\"🎅\", \"santa\"], // 35\n [\"👍\", \"thumbs up\"], // 36\n [\"☂️\", \"umbrella\"], // 37\n [\"⌛\", \"hourglass\"], // 38\n [\"⏰\", \"clock\"], // 39\n [\"🎁\", \"gift\"], // 40\n [\"💡\", \"light bulb\"], // 41\n [\"📕\", \"book\"], // 42\n [\"✏️\", \"pencil\"], // 43\n [\"📎\", \"paperclip\"], // 44\n [\"✂️\", \"scissors\"], // 45\n [\"🔒\", \"lock\"], // 46\n [\"🔑\", \"key\"], // 47\n [\"🔨\", \"hammer\"], // 48\n [\"☎️\", \"telephone\"], // 49\n [\"🏁\", \"flag\"], // 50\n [\"🚂\", \"train\"], // 51\n [\"🚲\", \"bicycle\"], // 52\n [\"✈️\", \"aeroplane\"], // 53\n [\"🚀\", \"rocket\"], // 54\n [\"🏆\", \"trophy\"], // 55\n [\"⚽\", \"ball\"], // 56\n [\"🎸\", \"guitar\"], // 57\n [\"🎺\", \"trumpet\"], // 58\n [\"🔔\", \"bell\"], // 59\n [\"⚓️\", \"anchor\"], // 60\n [\"🎧\", \"headphones\"], // 61\n [\"📁\", \"folder\"], // 62\n [\"📌\", \"pin\"], // 63\n];\n\nfunction generateEmojiSas(sasBytes: number[]): EmojiMapping[] {\n const emojis = [\n // just like base64 encoding\n sasBytes[0] >> 2,\n ((sasBytes[0] & 0x3) << 4) | (sasBytes[1] >> 4),\n ((sasBytes[1] & 0xf) << 2) | (sasBytes[2] >> 6),\n sasBytes[2] & 0x3f,\n sasBytes[3] >> 2,\n ((sasBytes[3] & 0x3) << 4) | (sasBytes[4] >> 4),\n ((sasBytes[4] & 0xf) << 2) | (sasBytes[5] >> 6),\n ];\n\n return emojis.map((num) => emojiMapping[num]);\n}\n\nconst sasGenerators = {\n decimal: generateDecimalSas,\n emoji: generateEmojiSas,\n} as const;\n\nexport interface IGeneratedSas {\n decimal?: [number, number, number];\n emoji?: EmojiMapping[];\n}\n\nexport interface ISasEvent {\n sas: IGeneratedSas;\n confirm(): Promise<void>;\n cancel(): void;\n mismatch(): void;\n}\n\nfunction generateSas(sasBytes: Uint8Array, methods: string[]): IGeneratedSas {\n const sas: IGeneratedSas = {};\n for (const method of methods) {\n if (method in sasGenerators) {\n // @ts-ignore - ts doesn't like us mixing types like this\n sas[method] = sasGenerators[method](Array.from(sasBytes));\n }\n }\n return sas;\n}\n\nconst macMethods = {\n \"hkdf-hmac-sha256\": \"calculate_mac\",\n \"org.matrix.msc3783.hkdf-hmac-sha256\": \"calculate_mac_fixed_base64\",\n \"hkdf-hmac-sha256.v2\": \"calculate_mac_fixed_base64\",\n \"hmac-sha256\": \"calculate_mac_long_kdf\",\n} as const;\n\ntype MacMethod = keyof typeof macMethods;\n\nfunction calculateMAC(olmSAS: OlmSAS, method: MacMethod) {\n return function (input: string, info: string): string {\n const mac = olmSAS[macMethods[method]](input, info);\n logger.log(\"SAS calculateMAC:\", method, [input, info], mac);\n return mac;\n };\n}\n\nconst calculateKeyAgreement = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n \"curve25519-hkdf-sha256\": function (sas: SAS, olmSAS: OlmSAS, bytes: number): Uint8Array {\n const ourInfo = `${sas.baseApis.getUserId()}|${sas.baseApis.deviceId}|` + `${sas.ourSASPubKey}|`;\n const theirInfo = `${sas.userId}|${sas.deviceId}|${sas.theirSASPubKey}|`;\n const sasInfo =\n \"MATRIX_KEY_VERIFICATION_SAS|\" +\n (sas.initiatedByMe ? ourInfo + theirInfo : theirInfo + ourInfo) +\n sas.channel.transactionId;\n return olmSAS.generate_bytes(sasInfo, bytes);\n },\n \"curve25519\": function (sas: SAS, olmSAS: OlmSAS, bytes: number): Uint8Array {\n const ourInfo = `${sas.baseApis.getUserId()}${sas.baseApis.deviceId}`;\n const theirInfo = `${sas.userId}${sas.deviceId}`;\n const sasInfo =\n \"MATRIX_KEY_VERIFICATION_SAS\" +\n (sas.initiatedByMe ? ourInfo + theirInfo : theirInfo + ourInfo) +\n sas.channel.transactionId;\n return olmSAS.generate_bytes(sasInfo, bytes);\n },\n} as const;\n\ntype KeyAgreement = keyof typeof calculateKeyAgreement;\n\n/* lists of algorithms/methods that are supported. The key agreement, hashes,\n * and MAC lists should be sorted in order of preference (most preferred\n * first).\n */\nconst KEY_AGREEMENT_LIST: KeyAgreement[] = [\"curve25519-hkdf-sha256\", \"curve25519\"];\nconst HASHES_LIST = [\"sha256\"];\nconst MAC_LIST: MacMethod[] = [\n \"hkdf-hmac-sha256.v2\",\n \"org.matrix.msc3783.hkdf-hmac-sha256\",\n \"hkdf-hmac-sha256\",\n \"hmac-sha256\",\n];\nconst SAS_LIST = Object.keys(sasGenerators);\n\nconst KEY_AGREEMENT_SET = new Set(KEY_AGREEMENT_LIST);\nconst HASHES_SET = new Set(HASHES_LIST);\nconst MAC_SET = new Set(MAC_LIST);\nconst SAS_SET = new Set(SAS_LIST);\n\nfunction intersection<T>(anArray: T[], aSet: Set<T>): T[] {\n return Array.isArray(anArray) ? anArray.filter((x) => aSet.has(x)) : [];\n}\n\nexport enum SasEvent {\n ShowSas = \"show_sas\",\n}\n\ntype EventHandlerMap = {\n [SasEvent.ShowSas]: (sas: ISasEvent) => void;\n} & VerificationEventHandlerMap;\n\nexport class SAS extends Base<SasEvent, EventHandlerMap> {\n private waitingForAccept?: boolean;\n public ourSASPubKey?: string;\n public theirSASPubKey?: string;\n public sasEvent?: ISasEvent;\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static get NAME(): string {\n return \"m.sas.v1\";\n }\n\n public get events(): string[] {\n return EVENTS;\n }\n\n protected doVerification = async (): Promise<void> => {\n await global.Olm.init();\n olmutil = olmutil || new global.Olm.Utility();\n\n // make sure user's keys are downloaded\n await this.baseApis.downloadKeys([this.userId]);\n\n let retry = false;\n do {\n try {\n if (this.initiatedByMe) {\n return await this.doSendVerification();\n } else {\n return await this.doRespondVerification();\n }\n } catch (err) {\n if (err instanceof SwitchStartEventError) {\n // this changes what initiatedByMe returns\n this.startEvent = err.startEvent;\n retry = true;\n } else {\n throw err;\n }\n }\n } while (retry);\n };\n\n public canSwitchStartEvent(event: MatrixEvent): boolean {\n if (event.getType() !== START_TYPE) {\n return false;\n }\n const content = event.getContent();\n return content?.method === SAS.NAME && !!this.waitingForAccept;\n }\n\n private async sendStart(): Promise<Record<string, any>> {\n const startContent = this.channel.completeContent(START_TYPE, {\n method: SAS.NAME,\n from_device: this.baseApis.deviceId,\n key_agreement_protocols: KEY_AGREEMENT_LIST,\n hashes: HASHES_LIST,\n message_authentication_codes: MAC_LIST,\n // FIXME: allow app to specify what SAS methods can be used\n short_authentication_string: SAS_LIST,\n });\n await this.channel.sendCompleted(START_TYPE, startContent);\n return startContent;\n }\n\n private async verifyAndCheckMAC(\n keyAgreement: KeyAgreement,\n sasMethods: string[],\n olmSAS: OlmSAS,\n macMethod: MacMethod,\n ): Promise<void> {\n const sasBytes = calculateKeyAgreement[keyAgreement](this, olmSAS, 6);\n const verifySAS = new Promise<void>((resolve, reject) => {\n this.sasEvent = {\n sas: generateSas(sasBytes, sasMethods),\n confirm: async (): Promise<void> => {\n try {\n await this.sendMAC(olmSAS, macMethod);\n resolve();\n } catch (err) {\n reject(err);\n }\n },\n cancel: () => reject(newUserCancelledError()),\n mismatch: () => reject(newMismatchedSASError()),\n };\n this.emit(SasEvent.ShowSas, this.sasEvent);\n });\n\n const [e] = await Promise.all([\n this.waitForEvent(EventType.KeyVerificationMac).then((e) => {\n // we don't expect any more messages from the other\n // party, and they may send a m.key.verification.done\n // when they're done on their end\n this.expectedEvent = EventType.KeyVerificationDone;\n return e;\n }),\n verifySAS,\n ]);\n const content = e.getContent();\n await this.checkMAC(olmSAS, content, macMethod);\n }\n\n private async doSendVerification(): Promise<void> {\n this.waitingForAccept = true;\n let startContent;\n if (this.startEvent) {\n startContent = this.channel.completedContentFromEvent(this.startEvent);\n } else {\n startContent = await this.sendStart();\n }\n\n // we might have switched to a different start event,\n // but was we didn't call _waitForEvent there was no\n // call that could throw yet. So check manually that\n // we're still on the initiator side\n if (!this.initiatedByMe) {\n throw new SwitchStartEventError(this.startEvent);\n }\n\n let e: MatrixEvent;\n try {\n e = await this.waitForEvent(EventType.KeyVerificationAccept);\n } finally {\n this.waitingForAccept = false;\n }\n let content = e.getContent();\n const sasMethods = intersection(content.short_authentication_string, SAS_SET);\n if (\n !(\n KEY_AGREEMENT_SET.has(content.key_agreement_protocol) &&\n HASHES_SET.has(content.hash) &&\n MAC_SET.has(content.message_authentication_code) &&\n sasMethods.length\n )\n ) {\n throw newUnknownMethodError();\n }\n if (typeof content.commitment !== \"string\") {\n throw newInvalidMessageError();\n }\n const keyAgreement = content.key_agreement_protocol;\n const macMethod = content.message_authentication_code;\n const hashCommitment = content.commitment;\n const olmSAS = new global.Olm.SAS();\n try {\n this.ourSASPubKey = olmSAS.get_pubkey();\n await this.send(EventType.KeyVerificationKey, {\n key: this.ourSASPubKey,\n });\n\n e = await this.waitForEvent(EventType.KeyVerificationKey);\n // FIXME: make sure event is properly formed\n content = e.getContent();\n const commitmentStr = content.key + anotherjson.stringify(startContent);\n // TODO: use selected hash function (when we support multiple)\n if (olmutil.sha256(commitmentStr) !== hashCommitment) {\n throw newMismatchedCommitmentError();\n }\n this.theirSASPubKey = content.key;\n olmSAS.set_their_key(content.key);\n\n await this.verifyAndCheckMAC(keyAgreement, sasMethods, olmSAS, macMethod);\n } finally {\n olmSAS.free();\n }\n }\n\n private async doRespondVerification(): Promise<void> {\n // as m.related_to is not included in the encrypted content in e2e rooms,\n // we need to make sure it is added\n let content = this.channel.completedContentFromEvent(this.startEvent!);\n\n // Note: we intersect using our pre-made lists, rather than the sets,\n // so that the result will be in our order of preference. Then\n // fetching the first element from the array will give our preferred\n // method out of the ones offered by the other party.\n const keyAgreement = intersection(KEY_AGREEMENT_LIST, new Set(content.key_agreement_protocols))[0];\n const hashMethod = intersection(HASHES_LIST, new Set(content.hashes))[0];\n const macMethod = intersection(MAC_LIST, new Set(content.message_authentication_codes))[0];\n // FIXME: allow app to specify what SAS methods can be used\n const sasMethods = intersection(content.short_authentication_string, SAS_SET);\n if (!(keyAgreement !== undefined && hashMethod !== undefined && macMethod !== undefined && sasMethods.length)) {\n throw newUnknownMethodError();\n }\n\n const olmSAS = new global.Olm.SAS();\n try {\n const commitmentStr = olmSAS.get_pubkey() + anotherjson.stringify(content);\n await this.send(EventType.KeyVerificationAccept, {\n key_agreement_protocol: keyAgreement,\n hash: hashMethod,\n message_authentication_code: macMethod,\n short_authentication_string: sasMethods,\n // TODO: use selected hash function (when we support multiple)\n commitment: olmutil.sha256(commitmentStr),\n });\n\n const e = await this.waitForEvent(EventType.KeyVerificationKey);\n // FIXME: make sure event is properly formed\n content = e.getContent();\n this.theirSASPubKey = content.key;\n olmSAS.set_their_key(content.key);\n this.ourSASPubKey = olmSAS.get_pubkey();\n await this.send(EventType.KeyVerificationKey, {\n key: this.ourSASPubKey,\n });\n\n await this.verifyAndCheckMAC(keyAgreement, sasMethods, olmSAS, macMethod);\n } finally {\n olmSAS.free();\n }\n }\n\n private sendMAC(olmSAS: OlmSAS, method: MacMethod): Promise<void> {\n const mac: Record<string, string> = {};\n const keyList: string[] = [];\n const baseInfo =\n \"MATRIX_KEY_VERIFICATION_MAC\" +\n this.baseApis.getUserId() +\n this.baseApis.deviceId +\n this.userId +\n this.deviceId +\n this.channel.transactionId;\n\n const deviceKeyId = `ed25519:${this.baseApis.deviceId}`;\n mac[deviceKeyId] = calculateMAC(olmSAS, method)(this.baseApis.getDeviceEd25519Key()!, baseInfo + deviceKeyId);\n keyList.push(deviceKeyId);\n\n const crossSigningId = this.baseApis.getCrossSigningId();\n if (crossSigningId) {\n const crossSigningKeyId = `ed25519:${crossSigningId}`;\n mac[crossSigningKeyId] = calculateMAC(olmSAS, method)(crossSigningId, baseInfo + crossSigningKeyId);\n keyList.push(crossSigningKeyId);\n }\n\n const keys = calculateMAC(olmSAS, method)(keyList.sort().join(\",\"), baseInfo + \"KEY_IDS\");\n return this.send(EventType.KeyVerificationMac, { mac, keys });\n }\n\n private async checkMAC(olmSAS: OlmSAS, content: IContent, method: MacMethod): Promise<void> {\n const baseInfo =\n \"MATRIX_KEY_VERIFICATION_MAC\" +\n this.userId +\n this.deviceId +\n this.baseApis.getUserId() +\n this.baseApis.deviceId +\n this.channel.transactionId;\n\n if (\n content.keys !==\n calculateMAC(olmSAS, method)(Object.keys(content.mac).sort().join(\",\"), baseInfo + \"KEY_IDS\")\n ) {\n throw newKeyMismatchError();\n }\n\n await this.verifyKeys(this.userId, content.mac, (keyId, device, keyInfo) => {\n if (keyInfo !== calculateMAC(olmSAS, method)(device.keys[keyId], baseInfo + keyId)) {\n throw newKeyMismatchError();\n }\n });\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts
new file mode 100644
index 0000000..673b56a
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts
@@ -0,0 +1,8 @@
+/**
+ * Implementation of decimal encoding of SAS as per:
+ * https://spec.matrix.org/v1.4/client-server-api/#sas-method-decimal
+ * @param sasBytes - the five bytes generated by HKDF
+ * @returns the derived three numbers between 1000 and 9191 inclusive
+ */
+export declare function generateDecimalSas(sasBytes: number[]): [number, number, number];
+//# sourceMappingURL=SASDecimal.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts.map
new file mode 100644
index 0000000..bc7a0fa
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"SASDecimal.d.ts","sourceRoot":"","sources":["../../../src/crypto/verification/SASDecimal.ts"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAc/E"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js
new file mode 100644
index 0000000..5ed2ea7
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js
@@ -0,0 +1,40 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.generateDecimalSas = generateDecimalSas;
+/*
+Copyright 2018 - 2022 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/**
+ * Implementation of decimal encoding of SAS as per:
+ * https://spec.matrix.org/v1.4/client-server-api/#sas-method-decimal
+ * @param sasBytes - the five bytes generated by HKDF
+ * @returns the derived three numbers between 1000 and 9191 inclusive
+ */
+function generateDecimalSas(sasBytes) {
+ /*
+ * +--------+--------+--------+--------+--------+
+ * | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
+ * +--------+--------+--------+--------+--------+
+ * bits: 87654321 87654321 87654321 87654321 87654321
+ * \____________/\_____________/\____________/
+ * 1st number 2nd number 3rd number
+ */
+ return [(sasBytes[0] << 5 | sasBytes[1] >> 3) + 1000, ((sasBytes[1] & 0x7) << 10 | sasBytes[2] << 2 | sasBytes[3] >> 6) + 1000, ((sasBytes[3] & 0x3f) << 7 | sasBytes[4] >> 1) + 1000];
+}
+//# sourceMappingURL=SASDecimal.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js.map
new file mode 100644
index 0000000..5138d2b
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/SASDecimal.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"SASDecimal.js","names":["generateDecimalSas","sasBytes"],"sources":["../../../src/crypto/verification/SASDecimal.ts"],"sourcesContent":["/*\nCopyright 2018 - 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Implementation of decimal encoding of SAS as per:\n * https://spec.matrix.org/v1.4/client-server-api/#sas-method-decimal\n * @param sasBytes - the five bytes generated by HKDF\n * @returns the derived three numbers between 1000 and 9191 inclusive\n */\nexport function generateDecimalSas(sasBytes: number[]): [number, number, number] {\n /*\n * +--------+--------+--------+--------+--------+\n * | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 |\n * +--------+--------+--------+--------+--------+\n * bits: 87654321 87654321 87654321 87654321 87654321\n * \\____________/\\_____________/\\____________/\n * 1st number 2nd number 3rd number\n */\n return [\n ((sasBytes[0] << 5) | (sasBytes[1] >> 3)) + 1000,\n (((sasBytes[1] & 0x7) << 10) | (sasBytes[2] << 2) | (sasBytes[3] >> 6)) + 1000,\n (((sasBytes[3] & 0x3f) << 7) | (sasBytes[4] >> 1)) + 1000,\n ];\n}\n"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,kBAAkBA,CAACC,QAAkB,EAA4B;EAC7E;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;EACI,OAAO,CACH,CAAEA,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAKA,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAE,IAAI,IAAI,EAChD,CAAE,CAACA,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,EAAE,GAAKA,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAE,GAAIA,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAE,IAAI,IAAI,EAC9E,CAAE,CAACA,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,GAAKA,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAE,IAAI,IAAI,CAC5D;AACL"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts
new file mode 100644
index 0000000..f9948e2
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts
@@ -0,0 +1,18 @@
+import { MatrixEvent } from "../../../models/event";
+import { VerificationRequest } from "./VerificationRequest";
+export interface IVerificationChannel {
+ request?: VerificationRequest;
+ readonly userId?: string;
+ readonly roomId?: string;
+ readonly deviceId?: string;
+ readonly transactionId?: string;
+ readonly receiveStartFromOtherDevices?: boolean;
+ getTimestamp(event: MatrixEvent): number;
+ send(type: string, uncompletedContent: Record<string, any>): Promise<void>;
+ completeContent(type: string, content: Record<string, any>): Record<string, any>;
+ sendCompleted(type: string, content: Record<string, any>): Promise<void>;
+ completedContentFromEvent(event: MatrixEvent): Record<string, any>;
+ canCreateRequest(type: string): boolean;
+ handleEvent(event: MatrixEvent, request: VerificationRequest, isLiveEvent: boolean): Promise<void>;
+}
+//# sourceMappingURL=Channel.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts.map
new file mode 100644
index 0000000..9951a5f
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"Channel.d.ts","sourceRoot":"","sources":["../../../../src/crypto/verification/request/Channel.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,oBAAoB;IACjC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,OAAO,CAAC;IAChD,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC;IACzC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjF,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,yBAAyB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnE,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtG"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js
new file mode 100644
index 0000000..93fbf04
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js
@@ -0,0 +1,6 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+//# sourceMappingURL=Channel.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js.map
new file mode 100644
index 0000000..9d7004f
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/Channel.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"Channel.js","names":[],"sources":["../../../../src/crypto/verification/request/Channel.ts"],"sourcesContent":["/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { MatrixEvent } from \"../../../models/event\";\nimport { VerificationRequest } from \"./VerificationRequest\";\n\nexport interface IVerificationChannel {\n request?: VerificationRequest;\n readonly userId?: string;\n readonly roomId?: string;\n readonly deviceId?: string;\n readonly transactionId?: string;\n readonly receiveStartFromOtherDevices?: boolean;\n getTimestamp(event: MatrixEvent): number;\n send(type: string, uncompletedContent: Record<string, any>): Promise<void>;\n completeContent(type: string, content: Record<string, any>): Record<string, any>;\n sendCompleted(type: string, content: Record<string, any>): Promise<void>;\n completedContentFromEvent(event: MatrixEvent): Record<string, any>;\n canCreateRequest(type: string): boolean;\n handleEvent(event: MatrixEvent, request: VerificationRequest, isLiveEvent: boolean): Promise<void>;\n}\n"],"mappings":""} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts
new file mode 100644
index 0000000..c646c90
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts
@@ -0,0 +1,113 @@
+import { VerificationRequest } from "./VerificationRequest";
+import { IVerificationChannel } from "./Channel";
+import { MatrixClient } from "../../../client";
+import { MatrixEvent } from "../../../models/event";
+import { IRequestsMap } from "../..";
+/**
+ * A key verification channel that sends verification events in the timeline of a room.
+ * Uses the event id of the initial m.key.verification.request event as a transaction id.
+ */
+export declare class InRoomChannel implements IVerificationChannel {
+ private readonly client;
+ readonly roomId: string;
+ userId?: string | undefined;
+ private requestEventId?;
+ /**
+ * @param client - the matrix client, to send messages with and get current user & device from.
+ * @param roomId - id of the room where verification events should be posted in, should be a DM with the given user.
+ * @param userId - id of user that the verification request is directed at, should be present in the room.
+ */
+ constructor(client: MatrixClient, roomId: string, userId?: string | undefined);
+ get receiveStartFromOtherDevices(): boolean;
+ /** The transaction id generated/used by this verification channel */
+ get transactionId(): string | undefined;
+ static getOtherPartyUserId(event: MatrixEvent, client: MatrixClient): string | undefined;
+ /**
+ * @param event - the event to get the timestamp of
+ * @returns the timestamp when the event was sent
+ */
+ getTimestamp(event: MatrixEvent): number;
+ /**
+ * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel
+ * @param type - the event type to check
+ * @returns boolean flag
+ */
+ static canCreateRequest(type: string): boolean;
+ canCreateRequest(type: string): boolean;
+ /**
+ * Extract the transaction id used by a given key verification event, if any
+ * @param event - the event
+ * @returns the transaction id
+ */
+ static getTransactionId(event: MatrixEvent): string | undefined;
+ /**
+ * Checks whether this event is a well-formed key verification event.
+ * This only does checks that don't rely on the current state of a potentially already channel
+ * so we can prevent channels being created by invalid events.
+ * `handleEvent` can do more checks and choose to ignore invalid events.
+ * @param event - the event to validate
+ * @param client - the client to get the current user and device id from
+ * @returns whether the event is valid and should be passed to handleEvent
+ */
+ static validateEvent(event: MatrixEvent, client: MatrixClient): boolean;
+ /**
+ * As m.key.verification.request events are as m.room.message events with the InRoomChannel
+ * to have a fallback message in non-supporting clients, we map the real event type
+ * to the symbolic one to keep things in unison with ToDeviceChannel
+ * @param event - the event to get the type of
+ * @returns the "symbolic" event type
+ */
+ static getEventType(event: MatrixEvent): string;
+ /**
+ * Changes the state of the channel, request, and verifier in response to a key verification event.
+ * @param event - to handle
+ * @param request - the request to forward handling to
+ * @param isLiveEvent - whether this is an even received through sync or not
+ * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
+ */
+ handleEvent(event: MatrixEvent, request: VerificationRequest, isLiveEvent?: boolean): Promise<void>;
+ /**
+ * Adds the transaction id (relation) back to a received event
+ * so it has the same format as returned by `completeContent` before sending.
+ * The relation can not appear on the event content because of encryption,
+ * relations are excluded from encryption.
+ * @param event - the received event
+ * @returns the content object with the relation added again
+ */
+ completedContentFromEvent(event: MatrixEvent): Record<string, any>;
+ /**
+ * Add all the fields to content needed for sending it over this channel.
+ * This is public so verification methods (SAS uses this) can get the exact
+ * content that will be sent independent of the used channel,
+ * as they need to calculate the hash of it.
+ * @param type - the event type
+ * @param content - the (incomplete) content
+ * @returns the complete content, as it will be sent.
+ */
+ completeContent(type: string, content: Record<string, any>): Record<string, any>;
+ /**
+ * Send an event over the channel with the content not having gone through `completeContent`.
+ * @param type - the event type
+ * @param uncompletedContent - the (incomplete) content
+ * @returns the promise of the request
+ */
+ send(type: string, uncompletedContent: Record<string, any>): Promise<void>;
+ /**
+ * Send an event over the channel with the content having gone through `completeContent` already.
+ * @param type - the event type
+ * @returns the promise of the request
+ */
+ sendCompleted(type: string, content: Record<string, any>): Promise<void>;
+}
+export declare class InRoomRequests implements IRequestsMap {
+ private requestsByRoomId;
+ getRequest(event: MatrixEvent): VerificationRequest | undefined;
+ getRequestByChannel(channel: InRoomChannel): VerificationRequest | undefined;
+ private getRequestByTxnId;
+ setRequest(event: MatrixEvent, request: VerificationRequest): void;
+ setRequestByChannel(channel: IVerificationChannel, request: VerificationRequest): void;
+ private doSetRequest;
+ removeRequest(event: MatrixEvent): void;
+ findRequestInProgress(roomId: string): VerificationRequest | undefined;
+}
+//# sourceMappingURL=InRoomChannel.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts.map
new file mode 100644
index 0000000..05c308c
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"InRoomChannel.d.ts","sourceRoot":"","sources":["../../../../src/crypto/verification/request/InRoomChannel.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,mBAAmB,EAAwC,MAAM,uBAAuB,CAAC;AAElG,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAMrC;;;GAGG;AACH,qBAAa,aAAc,YAAW,oBAAoB;IAQnC,OAAO,CAAC,QAAQ,CAAC,MAAM;aAAgC,MAAM,EAAE,MAAM;IAAS,MAAM,CAAC;IAPxG,OAAO,CAAC,cAAc,CAAC,CAAS;IAEhC;;;;OAIG;gBACiC,MAAM,EAAE,YAAY,EAAkB,MAAM,EAAE,MAAM,EAAS,MAAM,CAAC,oBAAQ;IAEhH,IAAW,4BAA4B,IAAI,OAAO,CAEjD;IAED,qEAAqE;IACrE,IAAW,aAAa,IAAI,MAAM,GAAG,SAAS,CAE7C;WAEa,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS;IAiB/F;;;OAGG;IACI,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM;IAI/C;;;;OAIG;WACW,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9C,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9C;;;;OAIG;WACW,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS;IAWtE;;;;;;;;OAQG;WACW,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO;IA8B9E;;;;;;OAMG;WACW,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM;IAkBtD;;;;;;OAMG;IACU,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAuC9G;;;;;;;OAOG;IACI,yBAAyB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAQzE;;;;;;;;OAQG;IACI,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IA4BvF;;;;;OAKG;IACI,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjF;;;;OAIG;IACU,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAUxF;AAED,qBAAa,cAAe,YAAW,YAAY;IAC/C,OAAO,CAAC,gBAAgB,CAAuD;IAExE,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,mBAAmB,GAAG,SAAS;IAM/D,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,mBAAmB,GAAG,SAAS;IAInF,OAAO,CAAC,iBAAiB;IAOlB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAIlE,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAI7F,OAAO,CAAC,YAAY;IASb,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAWvC,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;CAUhF"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js
new file mode 100644
index 0000000..480e980
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js
@@ -0,0 +1,344 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.InRoomRequests = exports.InRoomChannel = void 0;
+var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
+var _VerificationRequest = require("./VerificationRequest");
+var _logger = require("../../../logger");
+var _event = require("../../../@types/event");
+/*
+Copyright 2018 New Vector Ltd
+Copyright 2019 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+const MESSAGE_TYPE = _event.EventType.RoomMessage;
+const M_REFERENCE = "m.reference";
+const M_RELATES_TO = "m.relates_to";
+
+/**
+ * A key verification channel that sends verification events in the timeline of a room.
+ * Uses the event id of the initial m.key.verification.request event as a transaction id.
+ */
+class InRoomChannel {
+ /**
+ * @param client - the matrix client, to send messages with and get current user & device from.
+ * @param roomId - id of the room where verification events should be posted in, should be a DM with the given user.
+ * @param userId - id of user that the verification request is directed at, should be present in the room.
+ */
+ constructor(client, roomId, userId) {
+ this.client = client;
+ this.roomId = roomId;
+ this.userId = userId;
+ (0, _defineProperty2.default)(this, "requestEventId", void 0);
+ }
+ get receiveStartFromOtherDevices() {
+ return true;
+ }
+
+ /** The transaction id generated/used by this verification channel */
+ get transactionId() {
+ return this.requestEventId;
+ }
+ static getOtherPartyUserId(event, client) {
+ const type = InRoomChannel.getEventType(event);
+ if (type !== _VerificationRequest.REQUEST_TYPE) {
+ return;
+ }
+ const ownUserId = client.getUserId();
+ const sender = event.getSender();
+ const content = event.getContent();
+ const receiver = content.to;
+ if (sender === ownUserId) {
+ return receiver;
+ } else if (receiver === ownUserId) {
+ return sender;
+ }
+ }
+
+ /**
+ * @param event - the event to get the timestamp of
+ * @returns the timestamp when the event was sent
+ */
+ getTimestamp(event) {
+ return event.getTs();
+ }
+
+ /**
+ * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel
+ * @param type - the event type to check
+ * @returns boolean flag
+ */
+ static canCreateRequest(type) {
+ return type === _VerificationRequest.REQUEST_TYPE;
+ }
+ canCreateRequest(type) {
+ return InRoomChannel.canCreateRequest(type);
+ }
+
+ /**
+ * Extract the transaction id used by a given key verification event, if any
+ * @param event - the event
+ * @returns the transaction id
+ */
+ static getTransactionId(event) {
+ if (InRoomChannel.getEventType(event) === _VerificationRequest.REQUEST_TYPE) {
+ return event.getId();
+ } else {
+ const relation = event.getRelation();
+ if ((relation === null || relation === void 0 ? void 0 : relation.rel_type) === M_REFERENCE) {
+ return relation.event_id;
+ }
+ }
+ }
+
+ /**
+ * Checks whether this event is a well-formed key verification event.
+ * This only does checks that don't rely on the current state of a potentially already channel
+ * so we can prevent channels being created by invalid events.
+ * `handleEvent` can do more checks and choose to ignore invalid events.
+ * @param event - the event to validate
+ * @param client - the client to get the current user and device id from
+ * @returns whether the event is valid and should be passed to handleEvent
+ */
+ static validateEvent(event, client) {
+ const txnId = InRoomChannel.getTransactionId(event);
+ if (typeof txnId !== "string" || txnId.length === 0) {
+ return false;
+ }
+ const type = InRoomChannel.getEventType(event);
+ const content = event.getContent();
+
+ // from here on we're fairly sure that this is supposed to be
+ // part of a verification request, so be noisy when rejecting something
+ if (type === _VerificationRequest.REQUEST_TYPE) {
+ if (!content || typeof content.to !== "string" || !content.to.length) {
+ _logger.logger.log("InRoomChannel: validateEvent: " + "no valid to " + (content && content.to));
+ return false;
+ }
+
+ // ignore requests that are not direct to or sent by the syncing user
+ if (!InRoomChannel.getOtherPartyUserId(event, client)) {
+ _logger.logger.log("InRoomChannel: validateEvent: " + `not directed to or sent by me: ${event.getSender()}` + `, ${content && content.to}`);
+ return false;
+ }
+ }
+ return _VerificationRequest.VerificationRequest.validateEvent(type, event, client);
+ }
+
+ /**
+ * As m.key.verification.request events are as m.room.message events with the InRoomChannel
+ * to have a fallback message in non-supporting clients, we map the real event type
+ * to the symbolic one to keep things in unison with ToDeviceChannel
+ * @param event - the event to get the type of
+ * @returns the "symbolic" event type
+ */
+ static getEventType(event) {
+ const type = event.getType();
+ if (type === MESSAGE_TYPE) {
+ const content = event.getContent();
+ if (content) {
+ const {
+ msgtype
+ } = content;
+ if (msgtype === _VerificationRequest.REQUEST_TYPE) {
+ return _VerificationRequest.REQUEST_TYPE;
+ }
+ }
+ }
+ if (type && type !== _VerificationRequest.REQUEST_TYPE) {
+ return type;
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Changes the state of the channel, request, and verifier in response to a key verification event.
+ * @param event - to handle
+ * @param request - the request to forward handling to
+ * @param isLiveEvent - whether this is an even received through sync or not
+ * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
+ */
+ async handleEvent(event, request, isLiveEvent = false) {
+ // prevent processing the same event multiple times, as under
+ // some circumstances Room.timeline can get emitted twice for the same event
+ if (request.hasEventId(event.getId())) {
+ return;
+ }
+ const type = InRoomChannel.getEventType(event);
+ // do validations that need state (roomId, userId),
+ // ignore if invalid
+
+ if (event.getRoomId() !== this.roomId) {
+ return;
+ }
+ // set userId if not set already
+ if (!this.userId) {
+ const userId = InRoomChannel.getOtherPartyUserId(event, this.client);
+ if (userId) {
+ this.userId = userId;
+ }
+ }
+ // ignore events not sent by us or the other party
+ const ownUserId = this.client.getUserId();
+ const sender = event.getSender();
+ if (this.userId) {
+ if (sender !== ownUserId && sender !== this.userId) {
+ _logger.logger.log(`InRoomChannel: ignoring verification event from non-participating sender ${sender}`);
+ return;
+ }
+ }
+ if (!this.requestEventId) {
+ this.requestEventId = InRoomChannel.getTransactionId(event);
+ }
+ const isRemoteEcho = !!event.getUnsigned().transaction_id;
+ const isSentByUs = event.getSender() === this.client.getUserId();
+ return request.handleEvent(type, event, isLiveEvent, isRemoteEcho, isSentByUs);
+ }
+
+ /**
+ * Adds the transaction id (relation) back to a received event
+ * so it has the same format as returned by `completeContent` before sending.
+ * The relation can not appear on the event content because of encryption,
+ * relations are excluded from encryption.
+ * @param event - the received event
+ * @returns the content object with the relation added again
+ */
+ completedContentFromEvent(event) {
+ // ensure m.related_to is included in e2ee rooms
+ // as the field is excluded from encryption
+ const content = Object.assign({}, event.getContent());
+ content[M_RELATES_TO] = event.getRelation();
+ return content;
+ }
+
+ /**
+ * Add all the fields to content needed for sending it over this channel.
+ * This is public so verification methods (SAS uses this) can get the exact
+ * content that will be sent independent of the used channel,
+ * as they need to calculate the hash of it.
+ * @param type - the event type
+ * @param content - the (incomplete) content
+ * @returns the complete content, as it will be sent.
+ */
+ completeContent(type, content) {
+ content = Object.assign({}, content);
+ if (type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.READY_TYPE || type === _VerificationRequest.START_TYPE) {
+ content.from_device = this.client.getDeviceId();
+ }
+ if (type === _VerificationRequest.REQUEST_TYPE) {
+ // type is mapped to m.room.message in the send method
+ content = {
+ body: this.client.getUserId() + " is requesting to verify " + "your key, but your client does not support in-chat key " + "verification. You will need to use legacy key " + "verification to verify keys.",
+ msgtype: _VerificationRequest.REQUEST_TYPE,
+ to: this.userId,
+ from_device: content.from_device,
+ methods: content.methods
+ };
+ } else {
+ content[M_RELATES_TO] = {
+ rel_type: M_REFERENCE,
+ event_id: this.transactionId
+ };
+ }
+ return content;
+ }
+
+ /**
+ * Send an event over the channel with the content not having gone through `completeContent`.
+ * @param type - the event type
+ * @param uncompletedContent - the (incomplete) content
+ * @returns the promise of the request
+ */
+ send(type, uncompletedContent) {
+ const content = this.completeContent(type, uncompletedContent);
+ return this.sendCompleted(type, content);
+ }
+
+ /**
+ * Send an event over the channel with the content having gone through `completeContent` already.
+ * @param type - the event type
+ * @returns the promise of the request
+ */
+ async sendCompleted(type, content) {
+ let sendType = type;
+ if (type === _VerificationRequest.REQUEST_TYPE) {
+ sendType = MESSAGE_TYPE;
+ }
+ const response = await this.client.sendEvent(this.roomId, sendType, content);
+ if (type === _VerificationRequest.REQUEST_TYPE) {
+ this.requestEventId = response.event_id;
+ }
+ }
+}
+exports.InRoomChannel = InRoomChannel;
+class InRoomRequests {
+ constructor() {
+ (0, _defineProperty2.default)(this, "requestsByRoomId", new Map());
+ }
+ getRequest(event) {
+ const roomId = event.getRoomId();
+ const txnId = InRoomChannel.getTransactionId(event);
+ return this.getRequestByTxnId(roomId, txnId);
+ }
+ getRequestByChannel(channel) {
+ return this.getRequestByTxnId(channel.roomId, channel.transactionId);
+ }
+ getRequestByTxnId(roomId, txnId) {
+ const requestsByTxnId = this.requestsByRoomId.get(roomId);
+ if (requestsByTxnId) {
+ return requestsByTxnId.get(txnId);
+ }
+ }
+ setRequest(event, request) {
+ this.doSetRequest(event.getRoomId(), InRoomChannel.getTransactionId(event), request);
+ }
+ setRequestByChannel(channel, request) {
+ this.doSetRequest(channel.roomId, channel.transactionId, request);
+ }
+ doSetRequest(roomId, txnId, request) {
+ let requestsByTxnId = this.requestsByRoomId.get(roomId);
+ if (!requestsByTxnId) {
+ requestsByTxnId = new Map();
+ this.requestsByRoomId.set(roomId, requestsByTxnId);
+ }
+ requestsByTxnId.set(txnId, request);
+ }
+ removeRequest(event) {
+ const roomId = event.getRoomId();
+ const requestsByTxnId = this.requestsByRoomId.get(roomId);
+ if (requestsByTxnId) {
+ requestsByTxnId.delete(InRoomChannel.getTransactionId(event));
+ if (requestsByTxnId.size === 0) {
+ this.requestsByRoomId.delete(roomId);
+ }
+ }
+ }
+ findRequestInProgress(roomId) {
+ const requestsByTxnId = this.requestsByRoomId.get(roomId);
+ if (requestsByTxnId) {
+ for (const request of requestsByTxnId.values()) {
+ if (request.pending) {
+ return request;
+ }
+ }
+ }
+ }
+}
+exports.InRoomRequests = InRoomRequests;
+//# sourceMappingURL=InRoomChannel.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js.map
new file mode 100644
index 0000000..5b61e18
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/InRoomChannel.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"InRoomChannel.js","names":["_VerificationRequest","require","_logger","_event","MESSAGE_TYPE","EventType","RoomMessage","M_REFERENCE","M_RELATES_TO","InRoomChannel","constructor","client","roomId","userId","_defineProperty2","default","receiveStartFromOtherDevices","transactionId","requestEventId","getOtherPartyUserId","event","type","getEventType","REQUEST_TYPE","ownUserId","getUserId","sender","getSender","content","getContent","receiver","to","getTimestamp","getTs","canCreateRequest","getTransactionId","getId","relation","getRelation","rel_type","event_id","validateEvent","txnId","length","logger","log","VerificationRequest","getType","msgtype","handleEvent","request","isLiveEvent","hasEventId","getRoomId","isRemoteEcho","getUnsigned","transaction_id","isSentByUs","completedContentFromEvent","Object","assign","completeContent","READY_TYPE","START_TYPE","from_device","getDeviceId","body","methods","send","uncompletedContent","sendCompleted","sendType","response","sendEvent","exports","InRoomRequests","Map","getRequest","getRequestByTxnId","getRequestByChannel","channel","requestsByTxnId","requestsByRoomId","get","setRequest","doSetRequest","setRequestByChannel","set","removeRequest","delete","size","findRequestInProgress","values","pending"],"sources":["../../../../src/crypto/verification/request/InRoomChannel.ts"],"sourcesContent":["/*\nCopyright 2018 New Vector Ltd\nCopyright 2019 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { VerificationRequest, REQUEST_TYPE, READY_TYPE, START_TYPE } from \"./VerificationRequest\";\nimport { logger } from \"../../../logger\";\nimport { IVerificationChannel } from \"./Channel\";\nimport { EventType } from \"../../../@types/event\";\nimport { MatrixClient } from \"../../../client\";\nimport { MatrixEvent } from \"../../../models/event\";\nimport { IRequestsMap } from \"../..\";\n\nconst MESSAGE_TYPE = EventType.RoomMessage;\nconst M_REFERENCE = \"m.reference\";\nconst M_RELATES_TO = \"m.relates_to\";\n\n/**\n * A key verification channel that sends verification events in the timeline of a room.\n * Uses the event id of the initial m.key.verification.request event as a transaction id.\n */\nexport class InRoomChannel implements IVerificationChannel {\n private requestEventId?: string;\n\n /**\n * @param client - the matrix client, to send messages with and get current user & device from.\n * @param roomId - id of the room where verification events should be posted in, should be a DM with the given user.\n * @param userId - id of user that the verification request is directed at, should be present in the room.\n */\n public constructor(private readonly client: MatrixClient, public readonly roomId: string, public userId?: string) {}\n\n public get receiveStartFromOtherDevices(): boolean {\n return true;\n }\n\n /** The transaction id generated/used by this verification channel */\n public get transactionId(): string | undefined {\n return this.requestEventId;\n }\n\n public static getOtherPartyUserId(event: MatrixEvent, client: MatrixClient): string | undefined {\n const type = InRoomChannel.getEventType(event);\n if (type !== REQUEST_TYPE) {\n return;\n }\n const ownUserId = client.getUserId();\n const sender = event.getSender();\n const content = event.getContent();\n const receiver = content.to;\n\n if (sender === ownUserId) {\n return receiver;\n } else if (receiver === ownUserId) {\n return sender;\n }\n }\n\n /**\n * @param event - the event to get the timestamp of\n * @returns the timestamp when the event was sent\n */\n public getTimestamp(event: MatrixEvent): number {\n return event.getTs();\n }\n\n /**\n * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel\n * @param type - the event type to check\n * @returns boolean flag\n */\n public static canCreateRequest(type: string): boolean {\n return type === REQUEST_TYPE;\n }\n\n public canCreateRequest(type: string): boolean {\n return InRoomChannel.canCreateRequest(type);\n }\n\n /**\n * Extract the transaction id used by a given key verification event, if any\n * @param event - the event\n * @returns the transaction id\n */\n public static getTransactionId(event: MatrixEvent): string | undefined {\n if (InRoomChannel.getEventType(event) === REQUEST_TYPE) {\n return event.getId();\n } else {\n const relation = event.getRelation();\n if (relation?.rel_type === M_REFERENCE) {\n return relation.event_id;\n }\n }\n }\n\n /**\n * Checks whether this event is a well-formed key verification event.\n * This only does checks that don't rely on the current state of a potentially already channel\n * so we can prevent channels being created by invalid events.\n * `handleEvent` can do more checks and choose to ignore invalid events.\n * @param event - the event to validate\n * @param client - the client to get the current user and device id from\n * @returns whether the event is valid and should be passed to handleEvent\n */\n public static validateEvent(event: MatrixEvent, client: MatrixClient): boolean {\n const txnId = InRoomChannel.getTransactionId(event);\n if (typeof txnId !== \"string\" || txnId.length === 0) {\n return false;\n }\n const type = InRoomChannel.getEventType(event);\n const content = event.getContent();\n\n // from here on we're fairly sure that this is supposed to be\n // part of a verification request, so be noisy when rejecting something\n if (type === REQUEST_TYPE) {\n if (!content || typeof content.to !== \"string\" || !content.to.length) {\n logger.log(\"InRoomChannel: validateEvent: \" + \"no valid to \" + (content && content.to));\n return false;\n }\n\n // ignore requests that are not direct to or sent by the syncing user\n if (!InRoomChannel.getOtherPartyUserId(event, client)) {\n logger.log(\n \"InRoomChannel: validateEvent: \" +\n `not directed to or sent by me: ${event.getSender()}` +\n `, ${content && content.to}`,\n );\n return false;\n }\n }\n\n return VerificationRequest.validateEvent(type, event, client);\n }\n\n /**\n * As m.key.verification.request events are as m.room.message events with the InRoomChannel\n * to have a fallback message in non-supporting clients, we map the real event type\n * to the symbolic one to keep things in unison with ToDeviceChannel\n * @param event - the event to get the type of\n * @returns the \"symbolic\" event type\n */\n public static getEventType(event: MatrixEvent): string {\n const type = event.getType();\n if (type === MESSAGE_TYPE) {\n const content = event.getContent();\n if (content) {\n const { msgtype } = content;\n if (msgtype === REQUEST_TYPE) {\n return REQUEST_TYPE;\n }\n }\n }\n if (type && type !== REQUEST_TYPE) {\n return type;\n } else {\n return \"\";\n }\n }\n\n /**\n * Changes the state of the channel, request, and verifier in response to a key verification event.\n * @param event - to handle\n * @param request - the request to forward handling to\n * @param isLiveEvent - whether this is an even received through sync or not\n * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.\n */\n public async handleEvent(event: MatrixEvent, request: VerificationRequest, isLiveEvent = false): Promise<void> {\n // prevent processing the same event multiple times, as under\n // some circumstances Room.timeline can get emitted twice for the same event\n if (request.hasEventId(event.getId()!)) {\n return;\n }\n const type = InRoomChannel.getEventType(event);\n // do validations that need state (roomId, userId),\n // ignore if invalid\n\n if (event.getRoomId() !== this.roomId) {\n return;\n }\n // set userId if not set already\n if (!this.userId) {\n const userId = InRoomChannel.getOtherPartyUserId(event, this.client);\n if (userId) {\n this.userId = userId;\n }\n }\n // ignore events not sent by us or the other party\n const ownUserId = this.client.getUserId();\n const sender = event.getSender();\n if (this.userId) {\n if (sender !== ownUserId && sender !== this.userId) {\n logger.log(`InRoomChannel: ignoring verification event from non-participating sender ${sender}`);\n return;\n }\n }\n if (!this.requestEventId) {\n this.requestEventId = InRoomChannel.getTransactionId(event);\n }\n\n const isRemoteEcho = !!event.getUnsigned().transaction_id;\n const isSentByUs = event.getSender() === this.client.getUserId();\n\n return request.handleEvent(type, event, isLiveEvent, isRemoteEcho, isSentByUs);\n }\n\n /**\n * Adds the transaction id (relation) back to a received event\n * so it has the same format as returned by `completeContent` before sending.\n * The relation can not appear on the event content because of encryption,\n * relations are excluded from encryption.\n * @param event - the received event\n * @returns the content object with the relation added again\n */\n public completedContentFromEvent(event: MatrixEvent): Record<string, any> {\n // ensure m.related_to is included in e2ee rooms\n // as the field is excluded from encryption\n const content = Object.assign({}, event.getContent());\n content[M_RELATES_TO] = event.getRelation()!;\n return content;\n }\n\n /**\n * Add all the fields to content needed for sending it over this channel.\n * This is public so verification methods (SAS uses this) can get the exact\n * content that will be sent independent of the used channel,\n * as they need to calculate the hash of it.\n * @param type - the event type\n * @param content - the (incomplete) content\n * @returns the complete content, as it will be sent.\n */\n public completeContent(type: string, content: Record<string, any>): Record<string, any> {\n content = Object.assign({}, content);\n if (type === REQUEST_TYPE || type === READY_TYPE || type === START_TYPE) {\n content.from_device = this.client.getDeviceId();\n }\n if (type === REQUEST_TYPE) {\n // type is mapped to m.room.message in the send method\n content = {\n body:\n this.client.getUserId() +\n \" is requesting to verify \" +\n \"your key, but your client does not support in-chat key \" +\n \"verification. You will need to use legacy key \" +\n \"verification to verify keys.\",\n msgtype: REQUEST_TYPE,\n to: this.userId,\n from_device: content.from_device,\n methods: content.methods,\n };\n } else {\n content[M_RELATES_TO] = {\n rel_type: M_REFERENCE,\n event_id: this.transactionId,\n };\n }\n return content;\n }\n\n /**\n * Send an event over the channel with the content not having gone through `completeContent`.\n * @param type - the event type\n * @param uncompletedContent - the (incomplete) content\n * @returns the promise of the request\n */\n public send(type: string, uncompletedContent: Record<string, any>): Promise<void> {\n const content = this.completeContent(type, uncompletedContent);\n return this.sendCompleted(type, content);\n }\n\n /**\n * Send an event over the channel with the content having gone through `completeContent` already.\n * @param type - the event type\n * @returns the promise of the request\n */\n public async sendCompleted(type: string, content: Record<string, any>): Promise<void> {\n let sendType = type;\n if (type === REQUEST_TYPE) {\n sendType = MESSAGE_TYPE;\n }\n const response = await this.client.sendEvent(this.roomId, sendType, content);\n if (type === REQUEST_TYPE) {\n this.requestEventId = response.event_id;\n }\n }\n}\n\nexport class InRoomRequests implements IRequestsMap {\n private requestsByRoomId = new Map<string, Map<string, VerificationRequest>>();\n\n public getRequest(event: MatrixEvent): VerificationRequest | undefined {\n const roomId = event.getRoomId()!;\n const txnId = InRoomChannel.getTransactionId(event)!;\n return this.getRequestByTxnId(roomId, txnId);\n }\n\n public getRequestByChannel(channel: InRoomChannel): VerificationRequest | undefined {\n return this.getRequestByTxnId(channel.roomId, channel.transactionId!);\n }\n\n private getRequestByTxnId(roomId: string, txnId: string): VerificationRequest | undefined {\n const requestsByTxnId = this.requestsByRoomId.get(roomId);\n if (requestsByTxnId) {\n return requestsByTxnId.get(txnId);\n }\n }\n\n public setRequest(event: MatrixEvent, request: VerificationRequest): void {\n this.doSetRequest(event.getRoomId()!, InRoomChannel.getTransactionId(event)!, request);\n }\n\n public setRequestByChannel(channel: IVerificationChannel, request: VerificationRequest): void {\n this.doSetRequest(channel.roomId!, channel.transactionId!, request);\n }\n\n private doSetRequest(roomId: string, txnId: string, request: VerificationRequest): void {\n let requestsByTxnId = this.requestsByRoomId.get(roomId);\n if (!requestsByTxnId) {\n requestsByTxnId = new Map();\n this.requestsByRoomId.set(roomId, requestsByTxnId);\n }\n requestsByTxnId.set(txnId, request);\n }\n\n public removeRequest(event: MatrixEvent): void {\n const roomId = event.getRoomId()!;\n const requestsByTxnId = this.requestsByRoomId.get(roomId);\n if (requestsByTxnId) {\n requestsByTxnId.delete(InRoomChannel.getTransactionId(event)!);\n if (requestsByTxnId.size === 0) {\n this.requestsByRoomId.delete(roomId);\n }\n }\n }\n\n public findRequestInProgress(roomId: string): VerificationRequest | undefined {\n const requestsByTxnId = this.requestsByRoomId.get(roomId);\n if (requestsByTxnId) {\n for (const request of requestsByTxnId.values()) {\n if (request.pending) {\n return request;\n }\n }\n }\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts
new file mode 100644
index 0000000..f7e97e8
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts
@@ -0,0 +1,105 @@
+import { VerificationRequest } from "./VerificationRequest";
+import { MatrixEvent } from "../../../models/event";
+import { IVerificationChannel } from "./Channel";
+import { MatrixClient } from "../../../client";
+import { IRequestsMap } from "../..";
+export type Request = VerificationRequest<ToDeviceChannel>;
+/**
+ * A key verification channel that sends verification events over to_device messages.
+ * Generates its own transaction ids.
+ */
+export declare class ToDeviceChannel implements IVerificationChannel {
+ private readonly client;
+ readonly userId: string;
+ private readonly devices;
+ transactionId?: string | undefined;
+ deviceId?: string | undefined;
+ request?: VerificationRequest;
+ constructor(client: MatrixClient, userId: string, devices: string[], transactionId?: string | undefined, deviceId?: string | undefined);
+ isToDevices(devices: string[]): boolean;
+ static getEventType(event: MatrixEvent): string;
+ /**
+ * Extract the transaction id used by a given key verification event, if any
+ * @param event - the event
+ * @returns the transaction id
+ */
+ static getTransactionId(event: MatrixEvent): string;
+ /**
+ * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel
+ * @param type - the event type to check
+ * @returns boolean flag
+ */
+ static canCreateRequest(type: string): boolean;
+ canCreateRequest(type: string): boolean;
+ /**
+ * Checks whether this event is a well-formed key verification event.
+ * This only does checks that don't rely on the current state of a potentially already channel
+ * so we can prevent channels being created by invalid events.
+ * `handleEvent` can do more checks and choose to ignore invalid events.
+ * @param event - the event to validate
+ * @param client - the client to get the current user and device id from
+ * @returns whether the event is valid and should be passed to handleEvent
+ */
+ static validateEvent(event: MatrixEvent, client: MatrixClient): boolean;
+ /**
+ * @param event - the event to get the timestamp of
+ * @returns the timestamp when the event was sent
+ */
+ getTimestamp(event: MatrixEvent): number;
+ /**
+ * Changes the state of the channel, request, and verifier in response to a key verification event.
+ * @param event - to handle
+ * @param request - the request to forward handling to
+ * @param isLiveEvent - whether this is an even received through sync or not
+ * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
+ */
+ handleEvent(event: MatrixEvent, request: Request, isLiveEvent?: boolean): Promise<void>;
+ /**
+ * See {@link InRoomChannel#completedContentFromEvent} for why this is needed.
+ * @param event - the received event
+ * @returns the content object
+ */
+ completedContentFromEvent(event: MatrixEvent): Record<string, any>;
+ /**
+ * Add all the fields to content needed for sending it over this channel.
+ * This is public so verification methods (SAS uses this) can get the exact
+ * content that will be sent independent of the used channel,
+ * as they need to calculate the hash of it.
+ * @param type - the event type
+ * @param content - the (incomplete) content
+ * @returns the complete content, as it will be sent.
+ */
+ completeContent(type: string, content: Record<string, any>): Record<string, any>;
+ /**
+ * Send an event over the channel with the content not having gone through `completeContent`.
+ * @param type - the event type
+ * @param uncompletedContent - the (incomplete) content
+ * @returns the promise of the request
+ */
+ send(type: string, uncompletedContent?: Record<string, any>): Promise<void>;
+ /**
+ * Send an event over the channel with the content having gone through `completeContent` already.
+ * @param type - the event type
+ * @returns the promise of the request
+ */
+ sendCompleted(type: string, content: Record<string, any>): Promise<void>;
+ private sendToDevices;
+ /**
+ * Allow Crypto module to create and know the transaction id before the .start event gets sent.
+ * @returns the transaction id
+ */
+ static makeTransactionId(): string;
+}
+export declare class ToDeviceRequests implements IRequestsMap {
+ private requestsByUserId;
+ getRequest(event: MatrixEvent): Request | undefined;
+ getRequestByChannel(channel: ToDeviceChannel): Request | undefined;
+ getRequestBySenderAndTxnId(sender: string, txnId: string): Request | undefined;
+ setRequest(event: MatrixEvent, request: Request): void;
+ setRequestByChannel(channel: ToDeviceChannel, request: Request): void;
+ setRequestBySenderAndTxnId(sender: string, txnId: string, request: Request): void;
+ removeRequest(event: MatrixEvent): void;
+ findRequestInProgress(userId: string, devices: string[]): Request | undefined;
+ getRequestsInProgress(userId: string): Request[];
+}
+//# sourceMappingURL=ToDeviceChannel.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts.map
new file mode 100644
index 0000000..f6a0de2
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"ToDeviceChannel.d.ts","sourceRoot":"","sources":["../../../../src/crypto/verification/request/ToDeviceChannel.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js
new file mode 100644
index 0000000..3f6e48c
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js
@@ -0,0 +1,324 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.ToDeviceRequests = exports.ToDeviceChannel = void 0;
+var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
+var _randomstring = require("../../../randomstring");
+var _logger = require("../../../logger");
+var _VerificationRequest = require("./VerificationRequest");
+var _Error = require("../Error");
+var _event = require("../../../models/event");
+/*
+Copyright 2018 New Vector Ltd
+Copyright 2019 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/**
+ * A key verification channel that sends verification events over to_device messages.
+ * Generates its own transaction ids.
+ */
+class ToDeviceChannel {
+ // userId and devices of user we're about to verify
+ constructor(client, userId, devices, transactionId, deviceId) {
+ this.client = client;
+ this.userId = userId;
+ this.devices = devices;
+ this.transactionId = transactionId;
+ this.deviceId = deviceId;
+ (0, _defineProperty2.default)(this, "request", void 0);
+ }
+ isToDevices(devices) {
+ if (devices.length === this.devices.length) {
+ for (const device of devices) {
+ if (!this.devices.includes(device)) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+ static getEventType(event) {
+ return event.getType();
+ }
+
+ /**
+ * Extract the transaction id used by a given key verification event, if any
+ * @param event - the event
+ * @returns the transaction id
+ */
+ static getTransactionId(event) {
+ const content = event.getContent();
+ return content && content.transaction_id;
+ }
+
+ /**
+ * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel
+ * @param type - the event type to check
+ * @returns boolean flag
+ */
+ static canCreateRequest(type) {
+ return type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.START_TYPE;
+ }
+ canCreateRequest(type) {
+ return ToDeviceChannel.canCreateRequest(type);
+ }
+
+ /**
+ * Checks whether this event is a well-formed key verification event.
+ * This only does checks that don't rely on the current state of a potentially already channel
+ * so we can prevent channels being created by invalid events.
+ * `handleEvent` can do more checks and choose to ignore invalid events.
+ * @param event - the event to validate
+ * @param client - the client to get the current user and device id from
+ * @returns whether the event is valid and should be passed to handleEvent
+ */
+ static validateEvent(event, client) {
+ if (event.isCancelled()) {
+ _logger.logger.warn("Ignoring flagged verification request from " + event.getSender());
+ return false;
+ }
+ const content = event.getContent();
+ if (!content) {
+ _logger.logger.warn("ToDeviceChannel.validateEvent: invalid: no content");
+ return false;
+ }
+ if (!content.transaction_id) {
+ _logger.logger.warn("ToDeviceChannel.validateEvent: invalid: no transaction_id");
+ return false;
+ }
+ const type = event.getType();
+ if (type === _VerificationRequest.REQUEST_TYPE) {
+ if (!Number.isFinite(content.timestamp)) {
+ _logger.logger.warn("ToDeviceChannel.validateEvent: invalid: no timestamp");
+ return false;
+ }
+ if (event.getSender() === client.getUserId() && content.from_device == client.getDeviceId()) {
+ // ignore requests from ourselves, because it doesn't make sense for a
+ // device to verify itself
+ _logger.logger.warn("ToDeviceChannel.validateEvent: invalid: from own device");
+ return false;
+ }
+ }
+ return _VerificationRequest.VerificationRequest.validateEvent(type, event, client);
+ }
+
+ /**
+ * @param event - the event to get the timestamp of
+ * @returns the timestamp when the event was sent
+ */
+ getTimestamp(event) {
+ const content = event.getContent();
+ return content && content.timestamp;
+ }
+
+ /**
+ * Changes the state of the channel, request, and verifier in response to a key verification event.
+ * @param event - to handle
+ * @param request - the request to forward handling to
+ * @param isLiveEvent - whether this is an even received through sync or not
+ * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
+ */
+ async handleEvent(event, request, isLiveEvent = false) {
+ const type = event.getType();
+ const content = event.getContent();
+ if (type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.READY_TYPE || type === _VerificationRequest.START_TYPE) {
+ if (!this.transactionId) {
+ this.transactionId = content.transaction_id;
+ }
+ const deviceId = content.from_device;
+ // adopt deviceId if not set before and valid
+ if (!this.deviceId && this.devices.includes(deviceId)) {
+ this.deviceId = deviceId;
+ }
+ // if no device id or different from adopted one, cancel with sender
+ if (!this.deviceId || this.deviceId !== deviceId) {
+ // also check that message came from the device we sent the request to earlier on
+ // and do send a cancel message to that device
+ // (but don't cancel the request for the device we should be talking to)
+ const cancelContent = this.completeContent(_VerificationRequest.CANCEL_TYPE, (0, _Error.errorFromEvent)((0, _Error.newUnexpectedMessageError)()));
+ return this.sendToDevices(_VerificationRequest.CANCEL_TYPE, cancelContent, [deviceId]);
+ }
+ }
+ const wasStarted = request.phase === _VerificationRequest.PHASE_STARTED || request.phase === _VerificationRequest.PHASE_READY;
+ await request.handleEvent(event.getType(), event, isLiveEvent, false, false);
+ const isStarted = request.phase === _VerificationRequest.PHASE_STARTED || request.phase === _VerificationRequest.PHASE_READY;
+ const isAcceptingEvent = type === _VerificationRequest.START_TYPE || type === _VerificationRequest.READY_TYPE;
+ // the request has picked a ready or start event, tell the other devices about it
+ if (isAcceptingEvent && !wasStarted && isStarted && this.deviceId) {
+ const nonChosenDevices = this.devices.filter(d => d !== this.deviceId && d !== this.client.getDeviceId());
+ if (nonChosenDevices.length) {
+ const message = this.completeContent(_VerificationRequest.CANCEL_TYPE, {
+ code: "m.accepted",
+ reason: "Verification request accepted by another device"
+ });
+ await this.sendToDevices(_VerificationRequest.CANCEL_TYPE, message, nonChosenDevices);
+ }
+ }
+ }
+
+ /**
+ * See {@link InRoomChannel#completedContentFromEvent} for why this is needed.
+ * @param event - the received event
+ * @returns the content object
+ */
+ completedContentFromEvent(event) {
+ return event.getContent();
+ }
+
+ /**
+ * Add all the fields to content needed for sending it over this channel.
+ * This is public so verification methods (SAS uses this) can get the exact
+ * content that will be sent independent of the used channel,
+ * as they need to calculate the hash of it.
+ * @param type - the event type
+ * @param content - the (incomplete) content
+ * @returns the complete content, as it will be sent.
+ */
+ completeContent(type, content) {
+ // make a copy
+ content = Object.assign({}, content);
+ if (this.transactionId) {
+ content.transaction_id = this.transactionId;
+ }
+ if (type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.READY_TYPE || type === _VerificationRequest.START_TYPE) {
+ content.from_device = this.client.getDeviceId();
+ }
+ if (type === _VerificationRequest.REQUEST_TYPE) {
+ content.timestamp = Date.now();
+ }
+ return content;
+ }
+
+ /**
+ * Send an event over the channel with the content not having gone through `completeContent`.
+ * @param type - the event type
+ * @param uncompletedContent - the (incomplete) content
+ * @returns the promise of the request
+ */
+ send(type, uncompletedContent = {}) {
+ // create transaction id when sending request
+ if ((type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.START_TYPE) && !this.transactionId) {
+ this.transactionId = ToDeviceChannel.makeTransactionId();
+ }
+ const content = this.completeContent(type, uncompletedContent);
+ return this.sendCompleted(type, content);
+ }
+
+ /**
+ * Send an event over the channel with the content having gone through `completeContent` already.
+ * @param type - the event type
+ * @returns the promise of the request
+ */
+ async sendCompleted(type, content) {
+ let result;
+ if (type === _VerificationRequest.REQUEST_TYPE || type === _VerificationRequest.CANCEL_TYPE && !this.deviceId) {
+ result = await this.sendToDevices(type, content, this.devices);
+ } else {
+ result = await this.sendToDevices(type, content, [this.deviceId]);
+ }
+ // the VerificationRequest state machine requires remote echos of the event
+ // the client sends itself, so we fake this for to_device messages
+ const remoteEchoEvent = new _event.MatrixEvent({
+ sender: this.client.getUserId(),
+ content,
+ type
+ });
+ await this.request.handleEvent(type, remoteEchoEvent, /*isLiveEvent=*/true, /*isRemoteEcho=*/true, /*isSentByUs=*/true);
+ return result;
+ }
+ async sendToDevices(type, content, devices) {
+ if (devices.length) {
+ const deviceMessages = new Map();
+ for (const deviceId of devices) {
+ deviceMessages.set(deviceId, content);
+ }
+ await this.client.sendToDevice(type, new Map([[this.userId, deviceMessages]]));
+ }
+ }
+
+ /**
+ * Allow Crypto module to create and know the transaction id before the .start event gets sent.
+ * @returns the transaction id
+ */
+ static makeTransactionId() {
+ return (0, _randomstring.randomString)(32);
+ }
+}
+exports.ToDeviceChannel = ToDeviceChannel;
+class ToDeviceRequests {
+ constructor() {
+ (0, _defineProperty2.default)(this, "requestsByUserId", new Map());
+ }
+ getRequest(event) {
+ return this.getRequestBySenderAndTxnId(event.getSender(), ToDeviceChannel.getTransactionId(event));
+ }
+ getRequestByChannel(channel) {
+ return this.getRequestBySenderAndTxnId(channel.userId, channel.transactionId);
+ }
+ getRequestBySenderAndTxnId(sender, txnId) {
+ const requestsByTxnId = this.requestsByUserId.get(sender);
+ if (requestsByTxnId) {
+ return requestsByTxnId.get(txnId);
+ }
+ }
+ setRequest(event, request) {
+ this.setRequestBySenderAndTxnId(event.getSender(), ToDeviceChannel.getTransactionId(event), request);
+ }
+ setRequestByChannel(channel, request) {
+ this.setRequestBySenderAndTxnId(channel.userId, channel.transactionId, request);
+ }
+ setRequestBySenderAndTxnId(sender, txnId, request) {
+ let requestsByTxnId = this.requestsByUserId.get(sender);
+ if (!requestsByTxnId) {
+ requestsByTxnId = new Map();
+ this.requestsByUserId.set(sender, requestsByTxnId);
+ }
+ requestsByTxnId.set(txnId, request);
+ }
+ removeRequest(event) {
+ const userId = event.getSender();
+ const requestsByTxnId = this.requestsByUserId.get(userId);
+ if (requestsByTxnId) {
+ requestsByTxnId.delete(ToDeviceChannel.getTransactionId(event));
+ if (requestsByTxnId.size === 0) {
+ this.requestsByUserId.delete(userId);
+ }
+ }
+ }
+ findRequestInProgress(userId, devices) {
+ const requestsByTxnId = this.requestsByUserId.get(userId);
+ if (requestsByTxnId) {
+ for (const request of requestsByTxnId.values()) {
+ if (request.pending && request.channel.isToDevices(devices)) {
+ return request;
+ }
+ }
+ }
+ }
+ getRequestsInProgress(userId) {
+ const requestsByTxnId = this.requestsByUserId.get(userId);
+ if (requestsByTxnId) {
+ return Array.from(requestsByTxnId.values()).filter(r => r.pending);
+ }
+ return [];
+ }
+}
+exports.ToDeviceRequests = ToDeviceRequests;
+//# sourceMappingURL=ToDeviceChannel.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js.map
new file mode 100644
index 0000000..52bb286
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/ToDeviceChannel.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"ToDeviceChannel.js","names":["_randomstring","require","_logger","_VerificationRequest","_Error","_event","ToDeviceChannel","constructor","client","userId","devices","transactionId","deviceId","_defineProperty2","default","isToDevices","length","device","includes","getEventType","event","getType","getTransactionId","content","getContent","transaction_id","canCreateRequest","type","REQUEST_TYPE","START_TYPE","validateEvent","isCancelled","logger","warn","getSender","Number","isFinite","timestamp","getUserId","from_device","getDeviceId","VerificationRequest","getTimestamp","handleEvent","request","isLiveEvent","READY_TYPE","cancelContent","completeContent","CANCEL_TYPE","errorFromEvent","newUnexpectedMessageError","sendToDevices","wasStarted","phase","PHASE_STARTED","PHASE_READY","isStarted","isAcceptingEvent","nonChosenDevices","filter","d","message","code","reason","completedContentFromEvent","Object","assign","Date","now","send","uncompletedContent","makeTransactionId","sendCompleted","result","remoteEchoEvent","MatrixEvent","sender","deviceMessages","Map","set","sendToDevice","randomString","exports","ToDeviceRequests","getRequest","getRequestBySenderAndTxnId","getRequestByChannel","channel","txnId","requestsByTxnId","requestsByUserId","get","setRequest","setRequestBySenderAndTxnId","setRequestByChannel","removeRequest","delete","size","findRequestInProgress","values","pending","getRequestsInProgress","Array","from","r"],"sources":["../../../../src/crypto/verification/request/ToDeviceChannel.ts"],"sourcesContent":["/*\nCopyright 2018 New Vector Ltd\nCopyright 2019 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { randomString } from \"../../../randomstring\";\nimport { logger } from \"../../../logger\";\nimport {\n CANCEL_TYPE,\n PHASE_STARTED,\n PHASE_READY,\n REQUEST_TYPE,\n READY_TYPE,\n START_TYPE,\n VerificationRequest,\n} from \"./VerificationRequest\";\nimport { errorFromEvent, newUnexpectedMessageError } from \"../Error\";\nimport { MatrixEvent } from \"../../../models/event\";\nimport { IVerificationChannel } from \"./Channel\";\nimport { MatrixClient } from \"../../../client\";\nimport { IRequestsMap } from \"../..\";\n\nexport type Request = VerificationRequest<ToDeviceChannel>;\n\n/**\n * A key verification channel that sends verification events over to_device messages.\n * Generates its own transaction ids.\n */\nexport class ToDeviceChannel implements IVerificationChannel {\n public request?: VerificationRequest;\n\n // userId and devices of user we're about to verify\n public constructor(\n private readonly client: MatrixClient,\n public readonly userId: string,\n private readonly devices: string[],\n public transactionId?: string,\n public deviceId?: string,\n ) {}\n\n public isToDevices(devices: string[]): boolean {\n if (devices.length === this.devices.length) {\n for (const device of devices) {\n if (!this.devices.includes(device)) {\n return false;\n }\n }\n return true;\n } else {\n return false;\n }\n }\n\n public static getEventType(event: MatrixEvent): string {\n return event.getType();\n }\n\n /**\n * Extract the transaction id used by a given key verification event, if any\n * @param event - the event\n * @returns the transaction id\n */\n public static getTransactionId(event: MatrixEvent): string {\n const content = event.getContent();\n return content && content.transaction_id;\n }\n\n /**\n * Checks whether the given event type should be allowed to initiate a new VerificationRequest over this channel\n * @param type - the event type to check\n * @returns boolean flag\n */\n public static canCreateRequest(type: string): boolean {\n return type === REQUEST_TYPE || type === START_TYPE;\n }\n\n public canCreateRequest(type: string): boolean {\n return ToDeviceChannel.canCreateRequest(type);\n }\n\n /**\n * Checks whether this event is a well-formed key verification event.\n * This only does checks that don't rely on the current state of a potentially already channel\n * so we can prevent channels being created by invalid events.\n * `handleEvent` can do more checks and choose to ignore invalid events.\n * @param event - the event to validate\n * @param client - the client to get the current user and device id from\n * @returns whether the event is valid and should be passed to handleEvent\n */\n public static validateEvent(event: MatrixEvent, client: MatrixClient): boolean {\n if (event.isCancelled()) {\n logger.warn(\"Ignoring flagged verification request from \" + event.getSender());\n return false;\n }\n const content = event.getContent();\n if (!content) {\n logger.warn(\"ToDeviceChannel.validateEvent: invalid: no content\");\n return false;\n }\n\n if (!content.transaction_id) {\n logger.warn(\"ToDeviceChannel.validateEvent: invalid: no transaction_id\");\n return false;\n }\n\n const type = event.getType();\n\n if (type === REQUEST_TYPE) {\n if (!Number.isFinite(content.timestamp)) {\n logger.warn(\"ToDeviceChannel.validateEvent: invalid: no timestamp\");\n return false;\n }\n if (event.getSender() === client.getUserId() && content.from_device == client.getDeviceId()) {\n // ignore requests from ourselves, because it doesn't make sense for a\n // device to verify itself\n logger.warn(\"ToDeviceChannel.validateEvent: invalid: from own device\");\n return false;\n }\n }\n\n return VerificationRequest.validateEvent(type, event, client);\n }\n\n /**\n * @param event - the event to get the timestamp of\n * @returns the timestamp when the event was sent\n */\n public getTimestamp(event: MatrixEvent): number {\n const content = event.getContent();\n return content && content.timestamp;\n }\n\n /**\n * Changes the state of the channel, request, and verifier in response to a key verification event.\n * @param event - to handle\n * @param request - the request to forward handling to\n * @param isLiveEvent - whether this is an even received through sync or not\n * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.\n */\n public async handleEvent(event: MatrixEvent, request: Request, isLiveEvent = false): Promise<void> {\n const type = event.getType();\n const content = event.getContent();\n if (type === REQUEST_TYPE || type === READY_TYPE || type === START_TYPE) {\n if (!this.transactionId) {\n this.transactionId = content.transaction_id;\n }\n const deviceId = content.from_device;\n // adopt deviceId if not set before and valid\n if (!this.deviceId && this.devices.includes(deviceId)) {\n this.deviceId = deviceId;\n }\n // if no device id or different from adopted one, cancel with sender\n if (!this.deviceId || this.deviceId !== deviceId) {\n // also check that message came from the device we sent the request to earlier on\n // and do send a cancel message to that device\n // (but don't cancel the request for the device we should be talking to)\n const cancelContent = this.completeContent(CANCEL_TYPE, errorFromEvent(newUnexpectedMessageError()));\n return this.sendToDevices(CANCEL_TYPE, cancelContent, [deviceId]);\n }\n }\n const wasStarted = request.phase === PHASE_STARTED || request.phase === PHASE_READY;\n\n await request.handleEvent(event.getType(), event, isLiveEvent, false, false);\n\n const isStarted = request.phase === PHASE_STARTED || request.phase === PHASE_READY;\n\n const isAcceptingEvent = type === START_TYPE || type === READY_TYPE;\n // the request has picked a ready or start event, tell the other devices about it\n if (isAcceptingEvent && !wasStarted && isStarted && this.deviceId) {\n const nonChosenDevices = this.devices.filter((d) => d !== this.deviceId && d !== this.client.getDeviceId());\n if (nonChosenDevices.length) {\n const message = this.completeContent(CANCEL_TYPE, {\n code: \"m.accepted\",\n reason: \"Verification request accepted by another device\",\n });\n await this.sendToDevices(CANCEL_TYPE, message, nonChosenDevices);\n }\n }\n }\n\n /**\n * See {@link InRoomChannel#completedContentFromEvent} for why this is needed.\n * @param event - the received event\n * @returns the content object\n */\n public completedContentFromEvent(event: MatrixEvent): Record<string, any> {\n return event.getContent();\n }\n\n /**\n * Add all the fields to content needed for sending it over this channel.\n * This is public so verification methods (SAS uses this) can get the exact\n * content that will be sent independent of the used channel,\n * as they need to calculate the hash of it.\n * @param type - the event type\n * @param content - the (incomplete) content\n * @returns the complete content, as it will be sent.\n */\n public completeContent(type: string, content: Record<string, any>): Record<string, any> {\n // make a copy\n content = Object.assign({}, content);\n if (this.transactionId) {\n content.transaction_id = this.transactionId;\n }\n if (type === REQUEST_TYPE || type === READY_TYPE || type === START_TYPE) {\n content.from_device = this.client.getDeviceId();\n }\n if (type === REQUEST_TYPE) {\n content.timestamp = Date.now();\n }\n return content;\n }\n\n /**\n * Send an event over the channel with the content not having gone through `completeContent`.\n * @param type - the event type\n * @param uncompletedContent - the (incomplete) content\n * @returns the promise of the request\n */\n public send(type: string, uncompletedContent: Record<string, any> = {}): Promise<void> {\n // create transaction id when sending request\n if ((type === REQUEST_TYPE || type === START_TYPE) && !this.transactionId) {\n this.transactionId = ToDeviceChannel.makeTransactionId();\n }\n const content = this.completeContent(type, uncompletedContent);\n return this.sendCompleted(type, content);\n }\n\n /**\n * Send an event over the channel with the content having gone through `completeContent` already.\n * @param type - the event type\n * @returns the promise of the request\n */\n public async sendCompleted(type: string, content: Record<string, any>): Promise<void> {\n let result;\n if (type === REQUEST_TYPE || (type === CANCEL_TYPE && !this.deviceId)) {\n result = await this.sendToDevices(type, content, this.devices);\n } else {\n result = await this.sendToDevices(type, content, [this.deviceId!]);\n }\n // the VerificationRequest state machine requires remote echos of the event\n // the client sends itself, so we fake this for to_device messages\n const remoteEchoEvent = new MatrixEvent({\n sender: this.client.getUserId()!,\n content,\n type,\n });\n await this.request!.handleEvent(\n type,\n remoteEchoEvent,\n /*isLiveEvent=*/ true,\n /*isRemoteEcho=*/ true,\n /*isSentByUs=*/ true,\n );\n return result;\n }\n\n private async sendToDevices(type: string, content: Record<string, any>, devices: string[]): Promise<void> {\n if (devices.length) {\n const deviceMessages: Map<string, Record<string, any>> = new Map();\n for (const deviceId of devices) {\n deviceMessages.set(deviceId, content);\n }\n\n await this.client.sendToDevice(type, new Map([[this.userId, deviceMessages]]));\n }\n }\n\n /**\n * Allow Crypto module to create and know the transaction id before the .start event gets sent.\n * @returns the transaction id\n */\n public static makeTransactionId(): string {\n return randomString(32);\n }\n}\n\nexport class ToDeviceRequests implements IRequestsMap {\n private requestsByUserId = new Map<string, Map<string, Request>>();\n\n public getRequest(event: MatrixEvent): Request | undefined {\n return this.getRequestBySenderAndTxnId(event.getSender()!, ToDeviceChannel.getTransactionId(event));\n }\n\n public getRequestByChannel(channel: ToDeviceChannel): Request | undefined {\n return this.getRequestBySenderAndTxnId(channel.userId, channel.transactionId!);\n }\n\n public getRequestBySenderAndTxnId(sender: string, txnId: string): Request | undefined {\n const requestsByTxnId = this.requestsByUserId.get(sender);\n if (requestsByTxnId) {\n return requestsByTxnId.get(txnId);\n }\n }\n\n public setRequest(event: MatrixEvent, request: Request): void {\n this.setRequestBySenderAndTxnId(event.getSender()!, ToDeviceChannel.getTransactionId(event), request);\n }\n\n public setRequestByChannel(channel: ToDeviceChannel, request: Request): void {\n this.setRequestBySenderAndTxnId(channel.userId, channel.transactionId!, request);\n }\n\n public setRequestBySenderAndTxnId(sender: string, txnId: string, request: Request): void {\n let requestsByTxnId = this.requestsByUserId.get(sender);\n if (!requestsByTxnId) {\n requestsByTxnId = new Map();\n this.requestsByUserId.set(sender, requestsByTxnId);\n }\n requestsByTxnId.set(txnId, request);\n }\n\n public removeRequest(event: MatrixEvent): void {\n const userId = event.getSender()!;\n const requestsByTxnId = this.requestsByUserId.get(userId);\n if (requestsByTxnId) {\n requestsByTxnId.delete(ToDeviceChannel.getTransactionId(event));\n if (requestsByTxnId.size === 0) {\n this.requestsByUserId.delete(userId);\n }\n }\n }\n\n public findRequestInProgress(userId: string, devices: string[]): Request | undefined {\n const requestsByTxnId = this.requestsByUserId.get(userId);\n if (requestsByTxnId) {\n for (const request of requestsByTxnId.values()) {\n if (request.pending && request.channel.isToDevices(devices)) {\n return request;\n }\n }\n }\n }\n\n public getRequestsInProgress(userId: string): Request[] {\n const requestsByTxnId = this.requestsByUserId.get(userId);\n if (requestsByTxnId) {\n return Array.from(requestsByTxnId.values()).filter((r) => r.pending);\n }\n return [];\n }\n}\n"],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts
new file mode 100644
index 0000000..8d16b31
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts
@@ -0,0 +1,208 @@
+import { QRCodeData } from "../QRCode";
+import { IVerificationChannel } from "./Channel";
+import { MatrixClient } from "../../../client";
+import { MatrixEvent } from "../../../models/event";
+import { VerificationBase } from "../Base";
+import { VerificationMethod } from "../../index";
+import { TypedEventEmitter } from "../../../models/typed-event-emitter";
+export declare const EVENT_PREFIX = "m.key.verification.";
+export declare const REQUEST_TYPE: string;
+export declare const START_TYPE: string;
+export declare const CANCEL_TYPE: string;
+export declare const DONE_TYPE: string;
+export declare const READY_TYPE: string;
+export declare enum Phase {
+ Unsent = 1,
+ Requested = 2,
+ Ready = 3,
+ Started = 4,
+ Cancelled = 5,
+ Done = 6
+}
+export declare const PHASE_UNSENT = Phase.Unsent;
+export declare const PHASE_REQUESTED = Phase.Requested;
+export declare const PHASE_READY = Phase.Ready;
+export declare const PHASE_STARTED = Phase.Started;
+export declare const PHASE_CANCELLED = Phase.Cancelled;
+export declare const PHASE_DONE = Phase.Done;
+interface ITargetDevice {
+ userId?: string;
+ deviceId?: string;
+}
+export declare enum VerificationRequestEvent {
+ Change = "change"
+}
+type EventHandlerMap = {
+ /**
+ * Fires whenever the state of the request object has changed.
+ */
+ [VerificationRequestEvent.Change]: () => void;
+};
+/**
+ * State machine for verification requests.
+ * Things that differ based on what channel is used to
+ * send and receive verification events are put in `InRoomChannel` or `ToDeviceChannel`.
+ */
+export declare class VerificationRequest<C extends IVerificationChannel = IVerificationChannel> extends TypedEventEmitter<VerificationRequestEvent, EventHandlerMap> {
+ readonly channel: C;
+ private readonly verificationMethods;
+ private readonly client;
+ private eventsByUs;
+ private eventsByThem;
+ private _observeOnly;
+ private timeoutTimer;
+ private _accepting;
+ private _declining;
+ private verifierHasFinished;
+ private _cancelled;
+ private _chosenMethod;
+ private _qrCodeData;
+ private requestReceivedAt;
+ private commonMethods;
+ private _phase;
+ _cancellingUserId?: string;
+ private _verifier?;
+ constructor(channel: C, verificationMethods: Map<VerificationMethod, typeof VerificationBase>, client: MatrixClient);
+ /**
+ * Stateless validation logic not specific to the channel.
+ * Invoked by the same static method in either channel.
+ * @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
+ * @param event - the event to validate. Don't call getType() on it but use the `type` parameter instead.
+ * @param client - the client to get the current user and device id from
+ * @returns whether the event is valid and should be passed to handleEvent
+ */
+ static validateEvent(type: string, event: MatrixEvent, client: MatrixClient): boolean;
+ get invalid(): boolean;
+ /** returns whether the phase is PHASE_REQUESTED */
+ get requested(): boolean;
+ /** returns whether the phase is PHASE_CANCELLED */
+ get cancelled(): boolean;
+ /** returns whether the phase is PHASE_READY */
+ get ready(): boolean;
+ /** returns whether the phase is PHASE_STARTED */
+ get started(): boolean;
+ /** returns whether the phase is PHASE_DONE */
+ get done(): boolean;
+ /** once the phase is PHASE_STARTED (and !initiatedByMe) or PHASE_READY: common methods supported by both sides */
+ get methods(): VerificationMethod[];
+ /** the method picked in the .start event */
+ get chosenMethod(): VerificationMethod | null;
+ calculateEventTimeout(event: MatrixEvent): number;
+ /** The current remaining amount of ms before the request should be automatically cancelled */
+ get timeout(): number;
+ /**
+ * The key verification request event.
+ * @returns The request event, or falsey if not found.
+ */
+ get requestEvent(): MatrixEvent | undefined;
+ /** current phase of the request. Some properties might only be defined in a current phase. */
+ get phase(): Phase;
+ /** The verifier to do the actual verification, once the method has been established. Only defined when the `phase` is PHASE_STARTED. */
+ get verifier(): VerificationBase<any, any> | undefined;
+ get canAccept(): boolean;
+ get accepting(): boolean;
+ get declining(): boolean;
+ /** whether this request has sent it's initial event and needs more events to complete */
+ get pending(): boolean;
+ /** Only set after a .ready if the other party can scan a QR code */
+ get qrCodeData(): QRCodeData | null;
+ /** Checks whether the other party supports a given verification method.
+ * This is useful when setting up the QR code UI, as it is somewhat asymmetrical:
+ * if the other party supports SCAN_QR, we should show a QR code in the UI, and vice versa.
+ * For methods that need to be supported by both ends, use the `methods` property.
+ * @param method - the method to check
+ * @param force - to check even if the phase is not ready or started yet, internal usage
+ * @returns whether or not the other party said the supported the method */
+ otherPartySupportsMethod(method: string, force?: boolean): boolean;
+ /** Whether this request was initiated by the syncing user.
+ * For InRoomChannel, this is who sent the .request event.
+ * For ToDeviceChannel, this is who sent the .start event
+ */
+ get initiatedByMe(): boolean;
+ /** The id of the user that initiated the request */
+ get requestingUserId(): string;
+ /** The id of the user that (will) receive(d) the request */
+ get receivingUserId(): string;
+ /** The user id of the other party in this request */
+ get otherUserId(): string;
+ get isSelfVerification(): boolean;
+ /**
+ * The id of the user that cancelled the request,
+ * only defined when phase is PHASE_CANCELLED
+ */
+ get cancellingUserId(): string | undefined;
+ /**
+ * The cancellation code e.g m.user which is responsible for cancelling this verification
+ */
+ get cancellationCode(): string;
+ get observeOnly(): boolean;
+ /**
+ * Gets which device the verification should be started with
+ * given the events sent so far in the verification. This is the
+ * same algorithm used to determine which device to send the
+ * verification to when no specific device is specified.
+ * @returns The device information
+ */
+ get targetDevice(): ITargetDevice;
+ beginKeyVerification(method: VerificationMethod, targetDevice?: ITargetDevice | null): VerificationBase<any, any>;
+ /**
+ * sends the initial .request event.
+ * @returns resolves when the event has been sent.
+ */
+ sendRequest(): Promise<void>;
+ /**
+ * Cancels the request, sending a cancellation to the other party
+ * @param reason - the error reason to send the cancellation with
+ * @param code - the error code to send the cancellation with
+ * @returns resolves when the event has been sent.
+ */
+ cancel({ reason, code }?: {
+ reason?: string | undefined;
+ code?: string | undefined;
+ }): Promise<void>;
+ /**
+ * Accepts the request, sending a .ready event to the other party
+ * @returns resolves when the event has been sent.
+ */
+ accept(): Promise<void>;
+ /**
+ * Can be used to listen for state changes until the callback returns true.
+ * @param fn - callback to evaluate whether the request is in the desired state.
+ * Takes the request as an argument.
+ * @returns that resolves once the callback returns true
+ * @throws Error when the request is cancelled
+ */
+ waitFor(fn: (request: VerificationRequest) => boolean): Promise<VerificationRequest>;
+ private setPhase;
+ private getEventByEither;
+ private getEventBy;
+ private calculatePhaseTransitions;
+ private transitionToPhase;
+ private applyPhaseTransitions;
+ private isWinningStartRace;
+ hasEventId(eventId: string): boolean;
+ /**
+ * Changes the state of the request and verifier in response to a key verification event.
+ * @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
+ * @param event - the event to handle. Don't call getType() on it but use the `type` parameter instead.
+ * @param isLiveEvent - whether this is an even received through sync or not
+ * @param isRemoteEcho - whether this is the remote echo of an event sent by the same device
+ * @param isSentByUs - whether this event is sent by a party that can accept and/or observe the request like one of our peers.
+ * For InRoomChannel this means any device for the syncing user. For ToDeviceChannel, just the syncing device.
+ * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
+ */
+ handleEvent(type: string, event: MatrixEvent, isLiveEvent: boolean, isRemoteEcho: boolean, isSentByUs: boolean): Promise<void>;
+ private setupTimeout;
+ private cancelOnTimeout;
+ private cancelOnError;
+ private adjustObserveOnly;
+ private addEvent;
+ private createVerifier;
+ private wasSentByOwnUser;
+ private wasSentByOwnDevice;
+ onVerifierCancelled(): void;
+ onVerifierFinished(): void;
+ getEventFromOtherParty(type: string): MatrixEvent | undefined;
+}
+export {};
+//# sourceMappingURL=VerificationRequest.d.ts.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts.map
new file mode 100644
index 0000000..37ca935
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"VerificationRequest.d.ts","sourceRoot":"","sources":["../../../../src/crypto/verification/request/VerificationRequest.ts"],"names":[],"mappings":"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"} \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js
new file mode 100644
index 0000000..f6e4dc0
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js
@@ -0,0 +1,876 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.VerificationRequestEvent = exports.VerificationRequest = exports.START_TYPE = exports.REQUEST_TYPE = exports.READY_TYPE = exports.Phase = exports.PHASE_UNSENT = exports.PHASE_STARTED = exports.PHASE_REQUESTED = exports.PHASE_READY = exports.PHASE_DONE = exports.PHASE_CANCELLED = exports.EVENT_PREFIX = exports.DONE_TYPE = exports.CANCEL_TYPE = void 0;
+var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
+var _logger = require("../../../logger");
+var _Error = require("../Error");
+var _QRCode = require("../QRCode");
+var _event = require("../../../@types/event");
+var _typedEventEmitter = require("../../../models/typed-event-emitter");
+/*
+Copyright 2018 - 2021 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// How long after the event's timestamp that the request times out
+const TIMEOUT_FROM_EVENT_TS = 10 * 60 * 1000; // 10 minutes
+
+// How long after we receive the event that the request times out
+const TIMEOUT_FROM_EVENT_RECEIPT = 2 * 60 * 1000; // 2 minutes
+
+// to avoid almost expired verification notifications
+// from showing a notification and almost immediately
+// disappearing, also ignore verification requests that
+// are this amount of time away from expiring.
+const VERIFICATION_REQUEST_MARGIN = 3 * 1000; // 3 seconds
+
+const EVENT_PREFIX = "m.key.verification.";
+exports.EVENT_PREFIX = EVENT_PREFIX;
+const REQUEST_TYPE = EVENT_PREFIX + "request";
+exports.REQUEST_TYPE = REQUEST_TYPE;
+const START_TYPE = EVENT_PREFIX + "start";
+exports.START_TYPE = START_TYPE;
+const CANCEL_TYPE = EVENT_PREFIX + "cancel";
+exports.CANCEL_TYPE = CANCEL_TYPE;
+const DONE_TYPE = EVENT_PREFIX + "done";
+exports.DONE_TYPE = DONE_TYPE;
+const READY_TYPE = EVENT_PREFIX + "ready";
+exports.READY_TYPE = READY_TYPE;
+let Phase; // Legacy export fields
+exports.Phase = Phase;
+(function (Phase) {
+ Phase[Phase["Unsent"] = 1] = "Unsent";
+ Phase[Phase["Requested"] = 2] = "Requested";
+ Phase[Phase["Ready"] = 3] = "Ready";
+ Phase[Phase["Started"] = 4] = "Started";
+ Phase[Phase["Cancelled"] = 5] = "Cancelled";
+ Phase[Phase["Done"] = 6] = "Done";
+})(Phase || (exports.Phase = Phase = {}));
+const PHASE_UNSENT = Phase.Unsent;
+exports.PHASE_UNSENT = PHASE_UNSENT;
+const PHASE_REQUESTED = Phase.Requested;
+exports.PHASE_REQUESTED = PHASE_REQUESTED;
+const PHASE_READY = Phase.Ready;
+exports.PHASE_READY = PHASE_READY;
+const PHASE_STARTED = Phase.Started;
+exports.PHASE_STARTED = PHASE_STARTED;
+const PHASE_CANCELLED = Phase.Cancelled;
+exports.PHASE_CANCELLED = PHASE_CANCELLED;
+const PHASE_DONE = Phase.Done;
+exports.PHASE_DONE = PHASE_DONE;
+let VerificationRequestEvent;
+exports.VerificationRequestEvent = VerificationRequestEvent;
+(function (VerificationRequestEvent) {
+ VerificationRequestEvent["Change"] = "change";
+})(VerificationRequestEvent || (exports.VerificationRequestEvent = VerificationRequestEvent = {}));
+/**
+ * State machine for verification requests.
+ * Things that differ based on what channel is used to
+ * send and receive verification events are put in `InRoomChannel` or `ToDeviceChannel`.
+ */
+class VerificationRequest extends _typedEventEmitter.TypedEventEmitter {
+ // we keep a copy of the QR Code data (including other user master key) around
+ // for QR reciprocate verification, to protect against
+ // cross-signing identity reset between the .ready and .start event
+ // and signing the wrong key after .start
+
+ // The timestamp when we received the request event from the other side
+
+ // Used in tests only
+
+ constructor(channel, verificationMethods, client) {
+ super();
+ this.channel = channel;
+ this.verificationMethods = verificationMethods;
+ this.client = client;
+ (0, _defineProperty2.default)(this, "eventsByUs", new Map());
+ (0, _defineProperty2.default)(this, "eventsByThem", new Map());
+ (0, _defineProperty2.default)(this, "_observeOnly", false);
+ (0, _defineProperty2.default)(this, "timeoutTimer", null);
+ (0, _defineProperty2.default)(this, "_accepting", false);
+ (0, _defineProperty2.default)(this, "_declining", false);
+ (0, _defineProperty2.default)(this, "verifierHasFinished", false);
+ (0, _defineProperty2.default)(this, "_cancelled", false);
+ (0, _defineProperty2.default)(this, "_chosenMethod", null);
+ (0, _defineProperty2.default)(this, "_qrCodeData", null);
+ (0, _defineProperty2.default)(this, "requestReceivedAt", null);
+ (0, _defineProperty2.default)(this, "commonMethods", []);
+ (0, _defineProperty2.default)(this, "_phase", void 0);
+ (0, _defineProperty2.default)(this, "_cancellingUserId", void 0);
+ (0, _defineProperty2.default)(this, "_verifier", void 0);
+ (0, _defineProperty2.default)(this, "cancelOnTimeout", async () => {
+ try {
+ if (this.initiatedByMe) {
+ await this.cancel({
+ reason: "Other party didn't accept in time",
+ code: "m.timeout"
+ });
+ } else {
+ await this.cancel({
+ reason: "User didn't accept in time",
+ code: "m.timeout"
+ });
+ }
+ } catch (err) {
+ _logger.logger.error("Error while cancelling verification request", err);
+ }
+ });
+ this.channel.request = this;
+ this.setPhase(PHASE_UNSENT, false);
+ }
+
+ /**
+ * Stateless validation logic not specific to the channel.
+ * Invoked by the same static method in either channel.
+ * @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
+ * @param event - the event to validate. Don't call getType() on it but use the `type` parameter instead.
+ * @param client - the client to get the current user and device id from
+ * @returns whether the event is valid and should be passed to handleEvent
+ */
+ static validateEvent(type, event, client) {
+ const content = event.getContent();
+ if (!type || !type.startsWith(EVENT_PREFIX)) {
+ return false;
+ }
+
+ // from here on we're fairly sure that this is supposed to be
+ // part of a verification request, so be noisy when rejecting something
+ if (!content) {
+ _logger.logger.log("VerificationRequest: validateEvent: no content");
+ return false;
+ }
+ if (type === REQUEST_TYPE || type === READY_TYPE) {
+ if (!Array.isArray(content.methods)) {
+ _logger.logger.log("VerificationRequest: validateEvent: " + "fail because methods");
+ return false;
+ }
+ }
+ if (type === REQUEST_TYPE || type === READY_TYPE || type === START_TYPE) {
+ if (typeof content.from_device !== "string" || content.from_device.length === 0) {
+ _logger.logger.log("VerificationRequest: validateEvent: " + "fail because from_device");
+ return false;
+ }
+ }
+ return true;
+ }
+ get invalid() {
+ return this.phase === PHASE_UNSENT;
+ }
+
+ /** returns whether the phase is PHASE_REQUESTED */
+ get requested() {
+ return this.phase === PHASE_REQUESTED;
+ }
+
+ /** returns whether the phase is PHASE_CANCELLED */
+ get cancelled() {
+ return this.phase === PHASE_CANCELLED;
+ }
+
+ /** returns whether the phase is PHASE_READY */
+ get ready() {
+ return this.phase === PHASE_READY;
+ }
+
+ /** returns whether the phase is PHASE_STARTED */
+ get started() {
+ return this.phase === PHASE_STARTED;
+ }
+
+ /** returns whether the phase is PHASE_DONE */
+ get done() {
+ return this.phase === PHASE_DONE;
+ }
+
+ /** once the phase is PHASE_STARTED (and !initiatedByMe) or PHASE_READY: common methods supported by both sides */
+ get methods() {
+ return this.commonMethods;
+ }
+
+ /** the method picked in the .start event */
+ get chosenMethod() {
+ return this._chosenMethod;
+ }
+ calculateEventTimeout(event) {
+ let effectiveExpiresAt = this.channel.getTimestamp(event) + TIMEOUT_FROM_EVENT_TS;
+ if (this.requestReceivedAt && !this.initiatedByMe && this.phase <= PHASE_REQUESTED) {
+ const expiresAtByReceipt = this.requestReceivedAt + TIMEOUT_FROM_EVENT_RECEIPT;
+ effectiveExpiresAt = Math.min(effectiveExpiresAt, expiresAtByReceipt);
+ }
+ return Math.max(0, effectiveExpiresAt - Date.now());
+ }
+
+ /** The current remaining amount of ms before the request should be automatically cancelled */
+ get timeout() {
+ const requestEvent = this.getEventByEither(REQUEST_TYPE);
+ if (requestEvent) {
+ return this.calculateEventTimeout(requestEvent);
+ }
+ return 0;
+ }
+
+ /**
+ * The key verification request event.
+ * @returns The request event, or falsey if not found.
+ */
+ get requestEvent() {
+ return this.getEventByEither(REQUEST_TYPE);
+ }
+
+ /** current phase of the request. Some properties might only be defined in a current phase. */
+ get phase() {
+ return this._phase;
+ }
+
+ /** The verifier to do the actual verification, once the method has been established. Only defined when the `phase` is PHASE_STARTED. */
+ get verifier() {
+ return this._verifier;
+ }
+ get canAccept() {
+ return this.phase < PHASE_READY && !this._accepting && !this._declining;
+ }
+ get accepting() {
+ return this._accepting;
+ }
+ get declining() {
+ return this._declining;
+ }
+
+ /** whether this request has sent it's initial event and needs more events to complete */
+ get pending() {
+ return !this.observeOnly && this._phase !== PHASE_DONE && this._phase !== PHASE_CANCELLED;
+ }
+
+ /** Only set after a .ready if the other party can scan a QR code */
+ get qrCodeData() {
+ return this._qrCodeData;
+ }
+
+ /** Checks whether the other party supports a given verification method.
+ * This is useful when setting up the QR code UI, as it is somewhat asymmetrical:
+ * if the other party supports SCAN_QR, we should show a QR code in the UI, and vice versa.
+ * For methods that need to be supported by both ends, use the `methods` property.
+ * @param method - the method to check
+ * @param force - to check even if the phase is not ready or started yet, internal usage
+ * @returns whether or not the other party said the supported the method */
+ otherPartySupportsMethod(method, force = false) {
+ if (!force && !this.ready && !this.started) {
+ return false;
+ }
+ const theirMethodEvent = this.eventsByThem.get(REQUEST_TYPE) || this.eventsByThem.get(READY_TYPE);
+ if (!theirMethodEvent) {
+ // if we started straight away with .start event,
+ // we are assuming that the other side will support the
+ // chosen method, so return true for that.
+ if (this.started && this.initiatedByMe) {
+ const myStartEvent = this.eventsByUs.get(START_TYPE);
+ const content = myStartEvent && myStartEvent.getContent();
+ const myStartMethod = content && content.method;
+ return method == myStartMethod;
+ }
+ return false;
+ }
+ const content = theirMethodEvent.getContent();
+ if (!content) {
+ return false;
+ }
+ const {
+ methods
+ } = content;
+ if (!Array.isArray(methods)) {
+ return false;
+ }
+ return methods.includes(method);
+ }
+
+ /** Whether this request was initiated by the syncing user.
+ * For InRoomChannel, this is who sent the .request event.
+ * For ToDeviceChannel, this is who sent the .start event
+ */
+ get initiatedByMe() {
+ // event created by us but no remote echo has been received yet
+ const noEventsYet = this.eventsByUs.size + this.eventsByThem.size === 0;
+ if (this._phase === PHASE_UNSENT && noEventsYet) {
+ return true;
+ }
+ const hasMyRequest = this.eventsByUs.has(REQUEST_TYPE);
+ const hasTheirRequest = this.eventsByThem.has(REQUEST_TYPE);
+ if (hasMyRequest && !hasTheirRequest) {
+ return true;
+ }
+ if (!hasMyRequest && hasTheirRequest) {
+ return false;
+ }
+ const hasMyStart = this.eventsByUs.has(START_TYPE);
+ const hasTheirStart = this.eventsByThem.has(START_TYPE);
+ if (hasMyStart && !hasTheirStart) {
+ return true;
+ }
+ return false;
+ }
+
+ /** The id of the user that initiated the request */
+ get requestingUserId() {
+ if (this.initiatedByMe) {
+ return this.client.getUserId();
+ } else {
+ return this.otherUserId;
+ }
+ }
+
+ /** The id of the user that (will) receive(d) the request */
+ get receivingUserId() {
+ if (this.initiatedByMe) {
+ return this.otherUserId;
+ } else {
+ return this.client.getUserId();
+ }
+ }
+
+ /** The user id of the other party in this request */
+ get otherUserId() {
+ return this.channel.userId;
+ }
+ get isSelfVerification() {
+ return this.client.getUserId() === this.otherUserId;
+ }
+
+ /**
+ * The id of the user that cancelled the request,
+ * only defined when phase is PHASE_CANCELLED
+ */
+ get cancellingUserId() {
+ const myCancel = this.eventsByUs.get(CANCEL_TYPE);
+ const theirCancel = this.eventsByThem.get(CANCEL_TYPE);
+ if (myCancel && (!theirCancel || myCancel.getId() < theirCancel.getId())) {
+ return myCancel.getSender();
+ }
+ if (theirCancel) {
+ return theirCancel.getSender();
+ }
+ return undefined;
+ }
+
+ /**
+ * The cancellation code e.g m.user which is responsible for cancelling this verification
+ */
+ get cancellationCode() {
+ const ev = this.getEventByEither(CANCEL_TYPE);
+ return ev ? ev.getContent().code : null;
+ }
+ get observeOnly() {
+ return this._observeOnly;
+ }
+
+ /**
+ * Gets which device the verification should be started with
+ * given the events sent so far in the verification. This is the
+ * same algorithm used to determine which device to send the
+ * verification to when no specific device is specified.
+ * @returns The device information
+ */
+ get targetDevice() {
+ const theirFirstEvent = this.eventsByThem.get(REQUEST_TYPE) || this.eventsByThem.get(READY_TYPE) || this.eventsByThem.get(START_TYPE);
+ const theirFirstContent = theirFirstEvent === null || theirFirstEvent === void 0 ? void 0 : theirFirstEvent.getContent();
+ const fromDevice = theirFirstContent === null || theirFirstContent === void 0 ? void 0 : theirFirstContent.from_device;
+ return {
+ userId: this.otherUserId,
+ deviceId: fromDevice
+ };
+ }
+
+ /* Start the key verification, creating a verifier and sending a .start event.
+ * If no previous events have been sent, pass in `targetDevice` to set who to direct this request to.
+ * @param method - the name of the verification method to use.
+ * @param targetDevice.userId the id of the user to direct this request to
+ * @param targetDevice.deviceId the id of the device to direct this request to
+ * @returns the verifier of the given method
+ */
+ beginKeyVerification(method, targetDevice = null) {
+ // need to allow also when unsent in case of to_device
+ if (!this.observeOnly && !this._verifier) {
+ const validStartPhase = this.phase === PHASE_REQUESTED || this.phase === PHASE_READY || this.phase === PHASE_UNSENT && this.channel.canCreateRequest(START_TYPE);
+ if (validStartPhase) {
+ // when called on a request that was initiated with .request event
+ // check the method is supported by both sides
+ if (this.commonMethods.length && !this.commonMethods.includes(method)) {
+ throw (0, _Error.newUnknownMethodError)();
+ }
+ this._verifier = this.createVerifier(method, null, targetDevice);
+ if (!this._verifier) {
+ throw (0, _Error.newUnknownMethodError)();
+ }
+ this._chosenMethod = method;
+ }
+ }
+ return this._verifier;
+ }
+
+ /**
+ * sends the initial .request event.
+ * @returns resolves when the event has been sent.
+ */
+ async sendRequest() {
+ if (!this.observeOnly && this._phase === PHASE_UNSENT) {
+ const methods = [...this.verificationMethods.keys()];
+ await this.channel.send(REQUEST_TYPE, {
+ methods
+ });
+ }
+ }
+
+ /**
+ * Cancels the request, sending a cancellation to the other party
+ * @param reason - the error reason to send the cancellation with
+ * @param code - the error code to send the cancellation with
+ * @returns resolves when the event has been sent.
+ */
+ async cancel({
+ reason = "User declined",
+ code = "m.user"
+ } = {}) {
+ if (!this.observeOnly && this._phase !== PHASE_CANCELLED) {
+ this._declining = true;
+ this.emit(VerificationRequestEvent.Change);
+ if (this._verifier) {
+ return this._verifier.cancel((0, _Error.errorFactory)(code, reason)());
+ } else {
+ this._cancellingUserId = this.client.getUserId();
+ await this.channel.send(CANCEL_TYPE, {
+ code,
+ reason
+ });
+ }
+ }
+ }
+
+ /**
+ * Accepts the request, sending a .ready event to the other party
+ * @returns resolves when the event has been sent.
+ */
+ async accept() {
+ if (!this.observeOnly && this.phase === PHASE_REQUESTED && !this.initiatedByMe) {
+ const methods = [...this.verificationMethods.keys()];
+ this._accepting = true;
+ this.emit(VerificationRequestEvent.Change);
+ await this.channel.send(READY_TYPE, {
+ methods
+ });
+ }
+ }
+
+ /**
+ * Can be used to listen for state changes until the callback returns true.
+ * @param fn - callback to evaluate whether the request is in the desired state.
+ * Takes the request as an argument.
+ * @returns that resolves once the callback returns true
+ * @throws Error when the request is cancelled
+ */
+ waitFor(fn) {
+ return new Promise((resolve, reject) => {
+ const check = () => {
+ let handled = false;
+ if (fn(this)) {
+ resolve(this);
+ handled = true;
+ } else if (this.cancelled) {
+ reject(new Error("cancelled"));
+ handled = true;
+ }
+ if (handled) {
+ this.off(VerificationRequestEvent.Change, check);
+ }
+ return handled;
+ };
+ if (!check()) {
+ this.on(VerificationRequestEvent.Change, check);
+ }
+ });
+ }
+ setPhase(phase, notify = true) {
+ this._phase = phase;
+ if (notify) {
+ this.emit(VerificationRequestEvent.Change);
+ }
+ }
+ getEventByEither(type) {
+ return this.eventsByThem.get(type) || this.eventsByUs.get(type);
+ }
+ getEventBy(type, byThem = false) {
+ if (byThem) {
+ return this.eventsByThem.get(type);
+ } else {
+ return this.eventsByUs.get(type);
+ }
+ }
+ calculatePhaseTransitions() {
+ const transitions = [{
+ phase: PHASE_UNSENT
+ }];
+ const phase = () => transitions[transitions.length - 1].phase;
+
+ // always pass by .request first to be sure channel.userId has been set
+ const hasRequestByThem = this.eventsByThem.has(REQUEST_TYPE);
+ const requestEvent = this.getEventBy(REQUEST_TYPE, hasRequestByThem);
+ if (requestEvent) {
+ transitions.push({
+ phase: PHASE_REQUESTED,
+ event: requestEvent
+ });
+ }
+ const readyEvent = requestEvent && this.getEventBy(READY_TYPE, !hasRequestByThem);
+ if (readyEvent && phase() === PHASE_REQUESTED) {
+ transitions.push({
+ phase: PHASE_READY,
+ event: readyEvent
+ });
+ }
+ let startEvent;
+ if (readyEvent || !requestEvent) {
+ const theirStartEvent = this.eventsByThem.get(START_TYPE);
+ const ourStartEvent = this.eventsByUs.get(START_TYPE);
+ // any party can send .start after a .ready or unsent
+ if (theirStartEvent && ourStartEvent) {
+ startEvent = theirStartEvent.getSender() < ourStartEvent.getSender() ? theirStartEvent : ourStartEvent;
+ } else {
+ startEvent = theirStartEvent ? theirStartEvent : ourStartEvent;
+ }
+ } else {
+ startEvent = this.getEventBy(START_TYPE, !hasRequestByThem);
+ }
+ if (startEvent) {
+ const fromRequestPhase = phase() === PHASE_REQUESTED && (requestEvent === null || requestEvent === void 0 ? void 0 : requestEvent.getSender()) !== startEvent.getSender();
+ const fromUnsentPhase = phase() === PHASE_UNSENT && this.channel.canCreateRequest(START_TYPE);
+ if (fromRequestPhase || phase() === PHASE_READY || fromUnsentPhase) {
+ transitions.push({
+ phase: PHASE_STARTED,
+ event: startEvent
+ });
+ }
+ }
+ const ourDoneEvent = this.eventsByUs.get(DONE_TYPE);
+ if (this.verifierHasFinished || ourDoneEvent && phase() === PHASE_STARTED) {
+ transitions.push({
+ phase: PHASE_DONE
+ });
+ }
+ const cancelEvent = this.getEventByEither(CANCEL_TYPE);
+ if ((this._cancelled || cancelEvent) && phase() !== PHASE_DONE) {
+ transitions.push({
+ phase: PHASE_CANCELLED,
+ event: cancelEvent
+ });
+ return transitions;
+ }
+ return transitions;
+ }
+ transitionToPhase(transition) {
+ const {
+ phase,
+ event
+ } = transition;
+ // get common methods
+ if (phase === PHASE_REQUESTED || phase === PHASE_READY) {
+ if (!this.wasSentByOwnDevice(event)) {
+ const content = event.getContent();
+ this.commonMethods = content.methods.filter(m => this.verificationMethods.has(m));
+ }
+ }
+ // detect if we're not a party in the request, and we should just observe
+ if (!this.observeOnly) {
+ // if requested or accepted by one of my other devices
+ if (phase === PHASE_REQUESTED || phase === PHASE_STARTED || phase === PHASE_READY) {
+ if (this.channel.receiveStartFromOtherDevices && this.wasSentByOwnUser(event) && !this.wasSentByOwnDevice(event)) {
+ this._observeOnly = true;
+ }
+ }
+ }
+ // create verifier
+ if (phase === PHASE_STARTED) {
+ const {
+ method
+ } = event.getContent();
+ if (!this._verifier && !this.observeOnly) {
+ this._verifier = this.createVerifier(method, event);
+ if (!this._verifier) {
+ this.cancel({
+ code: "m.unknown_method",
+ reason: `Unknown method: ${method}`
+ });
+ } else {
+ this._chosenMethod = method;
+ }
+ }
+ }
+ }
+ applyPhaseTransitions() {
+ const transitions = this.calculatePhaseTransitions();
+ const existingIdx = transitions.findIndex(t => t.phase === this.phase);
+ // trim off phases we already went through, if any
+ const newTransitions = transitions.slice(existingIdx + 1);
+ // transition to all new phases
+ for (const transition of newTransitions) {
+ this.transitionToPhase(transition);
+ }
+ return newTransitions;
+ }
+ isWinningStartRace(newEvent) {
+ if (newEvent.getType() !== START_TYPE) {
+ return false;
+ }
+ const oldEvent = this._verifier.startEvent;
+ let oldRaceIdentifier;
+ if (this.isSelfVerification) {
+ // if the verifier does not have a startEvent,
+ // it is because it's still sending and we are on the initator side
+ // we know we are sending a .start event because we already
+ // have a verifier (checked in calling method)
+ if (oldEvent) {
+ const oldContent = oldEvent.getContent();
+ oldRaceIdentifier = oldContent && oldContent.from_device;
+ } else {
+ oldRaceIdentifier = this.client.getDeviceId();
+ }
+ } else {
+ if (oldEvent) {
+ oldRaceIdentifier = oldEvent.getSender();
+ } else {
+ oldRaceIdentifier = this.client.getUserId();
+ }
+ }
+ let newRaceIdentifier;
+ if (this.isSelfVerification) {
+ const newContent = newEvent.getContent();
+ newRaceIdentifier = newContent && newContent.from_device;
+ } else {
+ newRaceIdentifier = newEvent.getSender();
+ }
+ return newRaceIdentifier < oldRaceIdentifier;
+ }
+ hasEventId(eventId) {
+ for (const event of this.eventsByUs.values()) {
+ if (event.getId() === eventId) {
+ return true;
+ }
+ }
+ for (const event of this.eventsByThem.values()) {
+ if (event.getId() === eventId) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Changes the state of the request and verifier in response to a key verification event.
+ * @param type - the "symbolic" event type, as returned by the `getEventType` function on the channel.
+ * @param event - the event to handle. Don't call getType() on it but use the `type` parameter instead.
+ * @param isLiveEvent - whether this is an even received through sync or not
+ * @param isRemoteEcho - whether this is the remote echo of an event sent by the same device
+ * @param isSentByUs - whether this event is sent by a party that can accept and/or observe the request like one of our peers.
+ * For InRoomChannel this means any device for the syncing user. For ToDeviceChannel, just the syncing device.
+ * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.
+ */
+ async handleEvent(type, event, isLiveEvent, isRemoteEcho, isSentByUs) {
+ // if reached phase cancelled or done, ignore anything else that comes
+ if (this.done || this.cancelled) {
+ return;
+ }
+ const wasObserveOnly = this._observeOnly;
+ this.adjustObserveOnly(event, isLiveEvent);
+ if (!this.observeOnly && !isRemoteEcho) {
+ if (await this.cancelOnError(type, event)) {
+ return;
+ }
+ }
+
+ // This assumes verification won't need to send an event with
+ // the same type for the same party twice.
+ // This is true for QR and SAS verification, and was
+ // added here to prevent verification getting cancelled
+ // when the server duplicates an event (https://github.com/matrix-org/synapse/issues/3365)
+ const isDuplicateEvent = isSentByUs ? this.eventsByUs.has(type) : this.eventsByThem.has(type);
+ if (isDuplicateEvent) {
+ return;
+ }
+ const oldPhase = this.phase;
+ this.addEvent(type, event, isSentByUs);
+
+ // this will create if needed the verifier so needs to happen before calling it
+ const newTransitions = this.applyPhaseTransitions();
+ try {
+ // only pass events from the other side to the verifier,
+ // no remote echos of our own events
+ if (this._verifier && !this.observeOnly) {
+ const newEventWinsRace = this.isWinningStartRace(event);
+ if (this._verifier.canSwitchStartEvent(event) && newEventWinsRace) {
+ this._verifier.switchStartEvent(event);
+ } else if (!isRemoteEcho) {
+ var _this$_verifier$event;
+ if (type === CANCEL_TYPE || (_this$_verifier$event = this._verifier.events) !== null && _this$_verifier$event !== void 0 && _this$_verifier$event.includes(type)) {
+ this._verifier.handleEvent(event);
+ }
+ }
+ }
+ if (newTransitions.length) {
+ // create QRCodeData if the other side can scan
+ // important this happens before emitting a phase change,
+ // so listeners can rely on it being there already
+ // We only do this for live events because it is important that
+ // we sign the keys that were in the QR code, and not the keys
+ // we happen to have at some later point in time.
+ if (isLiveEvent && newTransitions.some(t => t.phase === PHASE_READY)) {
+ const shouldGenerateQrCode = this.otherPartySupportsMethod(_QRCode.SCAN_QR_CODE_METHOD, true);
+ if (shouldGenerateQrCode) {
+ this._qrCodeData = await _QRCode.QRCodeData.create(this, this.client);
+ }
+ }
+ const lastTransition = newTransitions[newTransitions.length - 1];
+ const {
+ phase
+ } = lastTransition;
+ this.setupTimeout(phase);
+ // set phase as last thing as this emits the "change" event
+ this.setPhase(phase);
+ } else if (this._observeOnly !== wasObserveOnly) {
+ this.emit(VerificationRequestEvent.Change);
+ }
+ } finally {
+ // log events we processed so we can see from rageshakes what events were added to a request
+ _logger.logger.log(`Verification request ${this.channel.transactionId}: ` + `${type} event with id:${event.getId()}, ` + `content:${JSON.stringify(event.getContent())} ` + `deviceId:${this.channel.deviceId}, ` + `sender:${event.getSender()}, isSentByUs:${isSentByUs}, ` + `isLiveEvent:${isLiveEvent}, isRemoteEcho:${isRemoteEcho}, ` + `phase:${oldPhase}=>${this.phase}, ` + `observeOnly:${wasObserveOnly}=>${this._observeOnly}`);
+ }
+ }
+ setupTimeout(phase) {
+ const shouldTimeout = !this.timeoutTimer && !this.observeOnly && phase === PHASE_REQUESTED;
+ if (shouldTimeout) {
+ this.timeoutTimer = setTimeout(this.cancelOnTimeout, this.timeout);
+ }
+ if (this.timeoutTimer) {
+ const shouldClear = phase === PHASE_STARTED || phase === PHASE_READY || phase === PHASE_DONE || phase === PHASE_CANCELLED;
+ if (shouldClear) {
+ clearTimeout(this.timeoutTimer);
+ this.timeoutTimer = null;
+ }
+ }
+ }
+ async cancelOnError(type, event) {
+ if (type === START_TYPE) {
+ const method = event.getContent().method;
+ if (!this.verificationMethods.has(method)) {
+ await this.cancel((0, _Error.errorFromEvent)((0, _Error.newUnknownMethodError)()));
+ return true;
+ }
+ }
+ const isUnexpectedRequest = type === REQUEST_TYPE && this.phase !== PHASE_UNSENT;
+ const isUnexpectedReady = type === READY_TYPE && this.phase !== PHASE_REQUESTED && this.phase !== PHASE_STARTED;
+ // only if phase has passed from PHASE_UNSENT should we cancel, because events
+ // are allowed to come in in any order (at least with InRoomChannel). So we only know
+ // we're dealing with a valid request we should participate in once we've moved to PHASE_REQUESTED.
+ // Before that, we could be looking at somebody else's verification request and we just
+ // happen to be in the room
+ if (this.phase !== PHASE_UNSENT && (isUnexpectedRequest || isUnexpectedReady)) {
+ _logger.logger.warn(`Cancelling, unexpected ${type} verification ` + `event from ${event.getSender()}`);
+ const reason = `Unexpected ${type} event in phase ${this.phase}`;
+ await this.cancel((0, _Error.errorFromEvent)((0, _Error.newUnexpectedMessageError)({
+ reason
+ })));
+ return true;
+ }
+ return false;
+ }
+ adjustObserveOnly(event, isLiveEvent = false) {
+ // don't send out events for historical requests
+ if (!isLiveEvent) {
+ this._observeOnly = true;
+ }
+ if (this.calculateEventTimeout(event) < VERIFICATION_REQUEST_MARGIN) {
+ this._observeOnly = true;
+ }
+ }
+ addEvent(type, event, isSentByUs = false) {
+ if (isSentByUs) {
+ this.eventsByUs.set(type, event);
+ } else {
+ this.eventsByThem.set(type, event);
+ }
+
+ // once we know the userId of the other party (from the .request event)
+ // see if any event by anyone else crept into this.eventsByThem
+ if (type === REQUEST_TYPE) {
+ for (const [type, event] of this.eventsByThem.entries()) {
+ if (event.getSender() !== this.otherUserId) {
+ this.eventsByThem.delete(type);
+ }
+ }
+ // also remember when we received the request event
+ this.requestReceivedAt = Date.now();
+ }
+ }
+ createVerifier(method, startEvent = null, targetDevice = null) {
+ if (!targetDevice) {
+ targetDevice = this.targetDevice;
+ }
+ const {
+ userId,
+ deviceId
+ } = targetDevice;
+ const VerifierCtor = this.verificationMethods.get(method);
+ if (!VerifierCtor) {
+ _logger.logger.warn("could not find verifier constructor for method", method);
+ return;
+ }
+ return new VerifierCtor(this.channel, this.client, userId, deviceId, startEvent, this);
+ }
+ wasSentByOwnUser(event) {
+ return (event === null || event === void 0 ? void 0 : event.getSender()) === this.client.getUserId();
+ }
+
+ // only for .request, .ready or .start
+ wasSentByOwnDevice(event) {
+ if (!this.wasSentByOwnUser(event)) {
+ return false;
+ }
+ const content = event.getContent();
+ if (!content || content.from_device !== this.client.getDeviceId()) {
+ return false;
+ }
+ return true;
+ }
+ onVerifierCancelled() {
+ this._cancelled = true;
+ // move to cancelled phase
+ const newTransitions = this.applyPhaseTransitions();
+ if (newTransitions.length) {
+ this.setPhase(newTransitions[newTransitions.length - 1].phase);
+ }
+ }
+ onVerifierFinished() {
+ this.channel.send(_event.EventType.KeyVerificationDone, {});
+ this.verifierHasFinished = true;
+ // move to .done phase
+ const newTransitions = this.applyPhaseTransitions();
+ if (newTransitions.length) {
+ this.setPhase(newTransitions[newTransitions.length - 1].phase);
+ }
+ }
+ getEventFromOtherParty(type) {
+ return this.eventsByThem.get(type);
+ }
+}
+exports.VerificationRequest = VerificationRequest;
+//# sourceMappingURL=VerificationRequest.js.map \ No newline at end of file
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js.map b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js.map
new file mode 100644
index 0000000..4d110ef
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/crypto/verification/request/VerificationRequest.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"VerificationRequest.js","names":["_logger","require","_Error","_QRCode","_event","_typedEventEmitter","TIMEOUT_FROM_EVENT_TS","TIMEOUT_FROM_EVENT_RECEIPT","VERIFICATION_REQUEST_MARGIN","EVENT_PREFIX","exports","REQUEST_TYPE","START_TYPE","CANCEL_TYPE","DONE_TYPE","READY_TYPE","Phase","PHASE_UNSENT","Unsent","PHASE_REQUESTED","Requested","PHASE_READY","Ready","PHASE_STARTED","Started","PHASE_CANCELLED","Cancelled","PHASE_DONE","Done","VerificationRequestEvent","VerificationRequest","TypedEventEmitter","constructor","channel","verificationMethods","client","_defineProperty2","default","Map","initiatedByMe","cancel","reason","code","err","logger","error","request","setPhase","validateEvent","type","event","content","getContent","startsWith","log","Array","isArray","methods","from_device","length","invalid","phase","requested","cancelled","ready","started","done","commonMethods","chosenMethod","_chosenMethod","calculateEventTimeout","effectiveExpiresAt","getTimestamp","requestReceivedAt","expiresAtByReceipt","Math","min","max","Date","now","timeout","requestEvent","getEventByEither","_phase","verifier","_verifier","canAccept","_accepting","_declining","accepting","declining","pending","observeOnly","qrCodeData","_qrCodeData","otherPartySupportsMethod","method","force","theirMethodEvent","eventsByThem","get","myStartEvent","eventsByUs","myStartMethod","includes","noEventsYet","size","hasMyRequest","has","hasTheirRequest","hasMyStart","hasTheirStart","requestingUserId","getUserId","otherUserId","receivingUserId","userId","isSelfVerification","cancellingUserId","myCancel","theirCancel","getId","getSender","undefined","cancellationCode","ev","_observeOnly","targetDevice","theirFirstEvent","theirFirstContent","fromDevice","deviceId","beginKeyVerification","validStartPhase","canCreateRequest","newUnknownMethodError","createVerifier","sendRequest","keys","send","emit","Change","errorFactory","_cancellingUserId","accept","waitFor","fn","Promise","resolve","reject","check","handled","Error","off","on","notify","getEventBy","byThem","calculatePhaseTransitions","transitions","hasRequestByThem","push","readyEvent","startEvent","theirStartEvent","ourStartEvent","fromRequestPhase","fromUnsentPhase","ourDoneEvent","verifierHasFinished","cancelEvent","_cancelled","transitionToPhase","transition","wasSentByOwnDevice","filter","m","receiveStartFromOtherDevices","wasSentByOwnUser","applyPhaseTransitions","existingIdx","findIndex","t","newTransitions","slice","isWinningStartRace","newEvent","getType","oldEvent","oldRaceIdentifier","oldContent","getDeviceId","newRaceIdentifier","newContent","hasEventId","eventId","values","handleEvent","isLiveEvent","isRemoteEcho","isSentByUs","wasObserveOnly","adjustObserveOnly","cancelOnError","isDuplicateEvent","oldPhase","addEvent","newEventWinsRace","canSwitchStartEvent","switchStartEvent","_this$_verifier$event","events","some","shouldGenerateQrCode","SCAN_QR_CODE_METHOD","QRCodeData","create","lastTransition","setupTimeout","transactionId","JSON","stringify","shouldTimeout","timeoutTimer","setTimeout","cancelOnTimeout","shouldClear","clearTimeout","errorFromEvent","isUnexpectedRequest","isUnexpectedReady","warn","newUnexpectedMessageError","set","entries","delete","VerifierCtor","onVerifierCancelled","onVerifierFinished","EventType","KeyVerificationDone","getEventFromOtherParty"],"sources":["../../../../src/crypto/verification/request/VerificationRequest.ts"],"sourcesContent":["/*\nCopyright 2018 - 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { logger } from \"../../../logger\";\nimport { errorFactory, errorFromEvent, newUnexpectedMessageError, newUnknownMethodError } from \"../Error\";\nimport { QRCodeData, SCAN_QR_CODE_METHOD } from \"../QRCode\";\nimport { IVerificationChannel } from \"./Channel\";\nimport { MatrixClient } from \"../../../client\";\nimport { MatrixEvent } from \"../../../models/event\";\nimport { EventType } from \"../../../@types/event\";\nimport { VerificationBase } from \"../Base\";\nimport { VerificationMethod } from \"../../index\";\nimport { TypedEventEmitter } from \"../../../models/typed-event-emitter\";\n\n// How long after the event's timestamp that the request times out\nconst TIMEOUT_FROM_EVENT_TS = 10 * 60 * 1000; // 10 minutes\n\n// How long after we receive the event that the request times out\nconst TIMEOUT_FROM_EVENT_RECEIPT = 2 * 60 * 1000; // 2 minutes\n\n// to avoid almost expired verification notifications\n// from showing a notification and almost immediately\n// disappearing, also ignore verification requests that\n// are this amount of time away from expiring.\nconst VERIFICATION_REQUEST_MARGIN = 3 * 1000; // 3 seconds\n\nexport const EVENT_PREFIX = \"m.key.verification.\";\nexport const REQUEST_TYPE = EVENT_PREFIX + \"request\";\nexport const START_TYPE = EVENT_PREFIX + \"start\";\nexport const CANCEL_TYPE = EVENT_PREFIX + \"cancel\";\nexport const DONE_TYPE = EVENT_PREFIX + \"done\";\nexport const READY_TYPE = EVENT_PREFIX + \"ready\";\n\nexport enum Phase {\n Unsent = 1,\n Requested,\n Ready,\n Started,\n Cancelled,\n Done,\n}\n\n// Legacy export fields\nexport const PHASE_UNSENT = Phase.Unsent;\nexport const PHASE_REQUESTED = Phase.Requested;\nexport const PHASE_READY = Phase.Ready;\nexport const PHASE_STARTED = Phase.Started;\nexport const PHASE_CANCELLED = Phase.Cancelled;\nexport const PHASE_DONE = Phase.Done;\n\ninterface ITargetDevice {\n userId?: string;\n deviceId?: string;\n}\n\ninterface ITransition {\n phase: Phase;\n event?: MatrixEvent;\n}\n\nexport enum VerificationRequestEvent {\n Change = \"change\",\n}\n\ntype EventHandlerMap = {\n /**\n * Fires whenever the state of the request object has changed.\n */\n [VerificationRequestEvent.Change]: () => void;\n};\n\n/**\n * State machine for verification requests.\n * Things that differ based on what channel is used to\n * send and receive verification events are put in `InRoomChannel` or `ToDeviceChannel`.\n */\nexport class VerificationRequest<C extends IVerificationChannel = IVerificationChannel> extends TypedEventEmitter<\n VerificationRequestEvent,\n EventHandlerMap\n> {\n private eventsByUs = new Map<string, MatrixEvent>();\n private eventsByThem = new Map<string, MatrixEvent>();\n private _observeOnly = false;\n private timeoutTimer: ReturnType<typeof setTimeout> | null = null;\n private _accepting = false;\n private _declining = false;\n private verifierHasFinished = false;\n private _cancelled = false;\n private _chosenMethod: VerificationMethod | null = null;\n // we keep a copy of the QR Code data (including other user master key) around\n // for QR reciprocate verification, to protect against\n // cross-signing identity reset between the .ready and .start event\n // and signing the wrong key after .start\n private _qrCodeData: QRCodeData | null = null;\n\n // The timestamp when we received the request event from the other side\n private requestReceivedAt: number | null = null;\n\n private commonMethods: VerificationMethod[] = [];\n private _phase!: Phase;\n public _cancellingUserId?: string; // Used in tests only\n private _verifier?: VerificationBase<any, any>;\n\n public constructor(\n public readonly channel: C,\n private readonly verificationMethods: Map<VerificationMethod, typeof VerificationBase>,\n private readonly client: MatrixClient,\n ) {\n super();\n this.channel.request = this;\n this.setPhase(PHASE_UNSENT, false);\n }\n\n /**\n * Stateless validation logic not specific to the channel.\n * Invoked by the same static method in either channel.\n * @param type - the \"symbolic\" event type, as returned by the `getEventType` function on the channel.\n * @param event - the event to validate. Don't call getType() on it but use the `type` parameter instead.\n * @param client - the client to get the current user and device id from\n * @returns whether the event is valid and should be passed to handleEvent\n */\n public static validateEvent(type: string, event: MatrixEvent, client: MatrixClient): boolean {\n const content = event.getContent();\n\n if (!type || !type.startsWith(EVENT_PREFIX)) {\n return false;\n }\n\n // from here on we're fairly sure that this is supposed to be\n // part of a verification request, so be noisy when rejecting something\n if (!content) {\n logger.log(\"VerificationRequest: validateEvent: no content\");\n return false;\n }\n\n if (type === REQUEST_TYPE || type === READY_TYPE) {\n if (!Array.isArray(content.methods)) {\n logger.log(\"VerificationRequest: validateEvent: \" + \"fail because methods\");\n return false;\n }\n }\n\n if (type === REQUEST_TYPE || type === READY_TYPE || type === START_TYPE) {\n if (typeof content.from_device !== \"string\" || content.from_device.length === 0) {\n logger.log(\"VerificationRequest: validateEvent: \" + \"fail because from_device\");\n return false;\n }\n }\n\n return true;\n }\n\n public get invalid(): boolean {\n return this.phase === PHASE_UNSENT;\n }\n\n /** returns whether the phase is PHASE_REQUESTED */\n public get requested(): boolean {\n return this.phase === PHASE_REQUESTED;\n }\n\n /** returns whether the phase is PHASE_CANCELLED */\n public get cancelled(): boolean {\n return this.phase === PHASE_CANCELLED;\n }\n\n /** returns whether the phase is PHASE_READY */\n public get ready(): boolean {\n return this.phase === PHASE_READY;\n }\n\n /** returns whether the phase is PHASE_STARTED */\n public get started(): boolean {\n return this.phase === PHASE_STARTED;\n }\n\n /** returns whether the phase is PHASE_DONE */\n public get done(): boolean {\n return this.phase === PHASE_DONE;\n }\n\n /** once the phase is PHASE_STARTED (and !initiatedByMe) or PHASE_READY: common methods supported by both sides */\n public get methods(): VerificationMethod[] {\n return this.commonMethods;\n }\n\n /** the method picked in the .start event */\n public get chosenMethod(): VerificationMethod | null {\n return this._chosenMethod;\n }\n\n public calculateEventTimeout(event: MatrixEvent): number {\n let effectiveExpiresAt = this.channel.getTimestamp(event) + TIMEOUT_FROM_EVENT_TS;\n\n if (this.requestReceivedAt && !this.initiatedByMe && this.phase <= PHASE_REQUESTED) {\n const expiresAtByReceipt = this.requestReceivedAt + TIMEOUT_FROM_EVENT_RECEIPT;\n effectiveExpiresAt = Math.min(effectiveExpiresAt, expiresAtByReceipt);\n }\n\n return Math.max(0, effectiveExpiresAt - Date.now());\n }\n\n /** The current remaining amount of ms before the request should be automatically cancelled */\n public get timeout(): number {\n const requestEvent = this.getEventByEither(REQUEST_TYPE);\n if (requestEvent) {\n return this.calculateEventTimeout(requestEvent);\n }\n return 0;\n }\n\n /**\n * The key verification request event.\n * @returns The request event, or falsey if not found.\n */\n public get requestEvent(): MatrixEvent | undefined {\n return this.getEventByEither(REQUEST_TYPE);\n }\n\n /** current phase of the request. Some properties might only be defined in a current phase. */\n public get phase(): Phase {\n return this._phase;\n }\n\n /** The verifier to do the actual verification, once the method has been established. Only defined when the `phase` is PHASE_STARTED. */\n public get verifier(): VerificationBase<any, any> | undefined {\n return this._verifier;\n }\n\n public get canAccept(): boolean {\n return this.phase < PHASE_READY && !this._accepting && !this._declining;\n }\n\n public get accepting(): boolean {\n return this._accepting;\n }\n\n public get declining(): boolean {\n return this._declining;\n }\n\n /** whether this request has sent it's initial event and needs more events to complete */\n public get pending(): boolean {\n return !this.observeOnly && this._phase !== PHASE_DONE && this._phase !== PHASE_CANCELLED;\n }\n\n /** Only set after a .ready if the other party can scan a QR code */\n public get qrCodeData(): QRCodeData | null {\n return this._qrCodeData;\n }\n\n /** Checks whether the other party supports a given verification method.\n * This is useful when setting up the QR code UI, as it is somewhat asymmetrical:\n * if the other party supports SCAN_QR, we should show a QR code in the UI, and vice versa.\n * For methods that need to be supported by both ends, use the `methods` property.\n * @param method - the method to check\n * @param force - to check even if the phase is not ready or started yet, internal usage\n * @returns whether or not the other party said the supported the method */\n public otherPartySupportsMethod(method: string, force = false): boolean {\n if (!force && !this.ready && !this.started) {\n return false;\n }\n const theirMethodEvent = this.eventsByThem.get(REQUEST_TYPE) || this.eventsByThem.get(READY_TYPE);\n if (!theirMethodEvent) {\n // if we started straight away with .start event,\n // we are assuming that the other side will support the\n // chosen method, so return true for that.\n if (this.started && this.initiatedByMe) {\n const myStartEvent = this.eventsByUs.get(START_TYPE);\n const content = myStartEvent && myStartEvent.getContent();\n const myStartMethod = content && content.method;\n return method == myStartMethod;\n }\n return false;\n }\n const content = theirMethodEvent.getContent();\n if (!content) {\n return false;\n }\n const { methods } = content;\n if (!Array.isArray(methods)) {\n return false;\n }\n\n return methods.includes(method);\n }\n\n /** Whether this request was initiated by the syncing user.\n * For InRoomChannel, this is who sent the .request event.\n * For ToDeviceChannel, this is who sent the .start event\n */\n public get initiatedByMe(): boolean {\n // event created by us but no remote echo has been received yet\n const noEventsYet = this.eventsByUs.size + this.eventsByThem.size === 0;\n if (this._phase === PHASE_UNSENT && noEventsYet) {\n return true;\n }\n const hasMyRequest = this.eventsByUs.has(REQUEST_TYPE);\n const hasTheirRequest = this.eventsByThem.has(REQUEST_TYPE);\n if (hasMyRequest && !hasTheirRequest) {\n return true;\n }\n if (!hasMyRequest && hasTheirRequest) {\n return false;\n }\n const hasMyStart = this.eventsByUs.has(START_TYPE);\n const hasTheirStart = this.eventsByThem.has(START_TYPE);\n if (hasMyStart && !hasTheirStart) {\n return true;\n }\n return false;\n }\n\n /** The id of the user that initiated the request */\n public get requestingUserId(): string {\n if (this.initiatedByMe) {\n return this.client.getUserId()!;\n } else {\n return this.otherUserId;\n }\n }\n\n /** The id of the user that (will) receive(d) the request */\n public get receivingUserId(): string {\n if (this.initiatedByMe) {\n return this.otherUserId;\n } else {\n return this.client.getUserId()!;\n }\n }\n\n /** The user id of the other party in this request */\n public get otherUserId(): string {\n return this.channel.userId!;\n }\n\n public get isSelfVerification(): boolean {\n return this.client.getUserId() === this.otherUserId;\n }\n\n /**\n * The id of the user that cancelled the request,\n * only defined when phase is PHASE_CANCELLED\n */\n public get cancellingUserId(): string | undefined {\n const myCancel = this.eventsByUs.get(CANCEL_TYPE);\n const theirCancel = this.eventsByThem.get(CANCEL_TYPE);\n\n if (myCancel && (!theirCancel || myCancel.getId()! < theirCancel.getId()!)) {\n return myCancel.getSender();\n }\n if (theirCancel) {\n return theirCancel.getSender();\n }\n return undefined;\n }\n\n /**\n * The cancellation code e.g m.user which is responsible for cancelling this verification\n */\n public get cancellationCode(): string {\n const ev = this.getEventByEither(CANCEL_TYPE);\n return ev ? ev.getContent().code : null;\n }\n\n public get observeOnly(): boolean {\n return this._observeOnly;\n }\n\n /**\n * Gets which device the verification should be started with\n * given the events sent so far in the verification. This is the\n * same algorithm used to determine which device to send the\n * verification to when no specific device is specified.\n * @returns The device information\n */\n public get targetDevice(): ITargetDevice {\n const theirFirstEvent =\n this.eventsByThem.get(REQUEST_TYPE) ||\n this.eventsByThem.get(READY_TYPE) ||\n this.eventsByThem.get(START_TYPE);\n const theirFirstContent = theirFirstEvent?.getContent();\n const fromDevice = theirFirstContent?.from_device;\n return {\n userId: this.otherUserId,\n deviceId: fromDevice,\n };\n }\n\n /* Start the key verification, creating a verifier and sending a .start event.\n * If no previous events have been sent, pass in `targetDevice` to set who to direct this request to.\n * @param method - the name of the verification method to use.\n * @param targetDevice.userId the id of the user to direct this request to\n * @param targetDevice.deviceId the id of the device to direct this request to\n * @returns the verifier of the given method\n */\n public beginKeyVerification(\n method: VerificationMethod,\n targetDevice: ITargetDevice | null = null,\n ): VerificationBase<any, any> {\n // need to allow also when unsent in case of to_device\n if (!this.observeOnly && !this._verifier) {\n const validStartPhase =\n this.phase === PHASE_REQUESTED ||\n this.phase === PHASE_READY ||\n (this.phase === PHASE_UNSENT && this.channel.canCreateRequest(START_TYPE));\n if (validStartPhase) {\n // when called on a request that was initiated with .request event\n // check the method is supported by both sides\n if (this.commonMethods.length && !this.commonMethods.includes(method)) {\n throw newUnknownMethodError();\n }\n this._verifier = this.createVerifier(method, null, targetDevice);\n if (!this._verifier) {\n throw newUnknownMethodError();\n }\n this._chosenMethod = method;\n }\n }\n return this._verifier!;\n }\n\n /**\n * sends the initial .request event.\n * @returns resolves when the event has been sent.\n */\n public async sendRequest(): Promise<void> {\n if (!this.observeOnly && this._phase === PHASE_UNSENT) {\n const methods = [...this.verificationMethods.keys()];\n await this.channel.send(REQUEST_TYPE, { methods });\n }\n }\n\n /**\n * Cancels the request, sending a cancellation to the other party\n * @param reason - the error reason to send the cancellation with\n * @param code - the error code to send the cancellation with\n * @returns resolves when the event has been sent.\n */\n public async cancel({ reason = \"User declined\", code = \"m.user\" } = {}): Promise<void> {\n if (!this.observeOnly && this._phase !== PHASE_CANCELLED) {\n this._declining = true;\n this.emit(VerificationRequestEvent.Change);\n if (this._verifier) {\n return this._verifier.cancel(errorFactory(code, reason)());\n } else {\n this._cancellingUserId = this.client.getUserId()!;\n await this.channel.send(CANCEL_TYPE, { code, reason });\n }\n }\n }\n\n /**\n * Accepts the request, sending a .ready event to the other party\n * @returns resolves when the event has been sent.\n */\n public async accept(): Promise<void> {\n if (!this.observeOnly && this.phase === PHASE_REQUESTED && !this.initiatedByMe) {\n const methods = [...this.verificationMethods.keys()];\n this._accepting = true;\n this.emit(VerificationRequestEvent.Change);\n await this.channel.send(READY_TYPE, { methods });\n }\n }\n\n /**\n * Can be used to listen for state changes until the callback returns true.\n * @param fn - callback to evaluate whether the request is in the desired state.\n * Takes the request as an argument.\n * @returns that resolves once the callback returns true\n * @throws Error when the request is cancelled\n */\n public waitFor(fn: (request: VerificationRequest) => boolean): Promise<VerificationRequest> {\n return new Promise((resolve, reject) => {\n const check = (): boolean => {\n let handled = false;\n if (fn(this)) {\n resolve(this);\n handled = true;\n } else if (this.cancelled) {\n reject(new Error(\"cancelled\"));\n handled = true;\n }\n if (handled) {\n this.off(VerificationRequestEvent.Change, check);\n }\n return handled;\n };\n if (!check()) {\n this.on(VerificationRequestEvent.Change, check);\n }\n });\n }\n\n private setPhase(phase: Phase, notify = true): void {\n this._phase = phase;\n if (notify) {\n this.emit(VerificationRequestEvent.Change);\n }\n }\n\n private getEventByEither(type: string): MatrixEvent | undefined {\n return this.eventsByThem.get(type) || this.eventsByUs.get(type);\n }\n\n private getEventBy(type: string, byThem = false): MatrixEvent | undefined {\n if (byThem) {\n return this.eventsByThem.get(type);\n } else {\n return this.eventsByUs.get(type);\n }\n }\n\n private calculatePhaseTransitions(): ITransition[] {\n const transitions: ITransition[] = [{ phase: PHASE_UNSENT }];\n const phase = (): Phase => transitions[transitions.length - 1].phase;\n\n // always pass by .request first to be sure channel.userId has been set\n const hasRequestByThem = this.eventsByThem.has(REQUEST_TYPE);\n const requestEvent = this.getEventBy(REQUEST_TYPE, hasRequestByThem);\n if (requestEvent) {\n transitions.push({ phase: PHASE_REQUESTED, event: requestEvent });\n }\n\n const readyEvent = requestEvent && this.getEventBy(READY_TYPE, !hasRequestByThem);\n if (readyEvent && phase() === PHASE_REQUESTED) {\n transitions.push({ phase: PHASE_READY, event: readyEvent });\n }\n\n let startEvent: MatrixEvent | undefined;\n if (readyEvent || !requestEvent) {\n const theirStartEvent = this.eventsByThem.get(START_TYPE);\n const ourStartEvent = this.eventsByUs.get(START_TYPE);\n // any party can send .start after a .ready or unsent\n if (theirStartEvent && ourStartEvent) {\n startEvent =\n theirStartEvent.getSender()! < ourStartEvent.getSender()! ? theirStartEvent : ourStartEvent;\n } else {\n startEvent = theirStartEvent ? theirStartEvent : ourStartEvent;\n }\n } else {\n startEvent = this.getEventBy(START_TYPE, !hasRequestByThem);\n }\n if (startEvent) {\n const fromRequestPhase =\n phase() === PHASE_REQUESTED && requestEvent?.getSender() !== startEvent.getSender();\n const fromUnsentPhase = phase() === PHASE_UNSENT && this.channel.canCreateRequest(START_TYPE);\n if (fromRequestPhase || phase() === PHASE_READY || fromUnsentPhase) {\n transitions.push({ phase: PHASE_STARTED, event: startEvent });\n }\n }\n\n const ourDoneEvent = this.eventsByUs.get(DONE_TYPE);\n if (this.verifierHasFinished || (ourDoneEvent && phase() === PHASE_STARTED)) {\n transitions.push({ phase: PHASE_DONE });\n }\n\n const cancelEvent = this.getEventByEither(CANCEL_TYPE);\n if ((this._cancelled || cancelEvent) && phase() !== PHASE_DONE) {\n transitions.push({ phase: PHASE_CANCELLED, event: cancelEvent });\n return transitions;\n }\n\n return transitions;\n }\n\n private transitionToPhase(transition: ITransition): void {\n const { phase, event } = transition;\n // get common methods\n if (phase === PHASE_REQUESTED || phase === PHASE_READY) {\n if (!this.wasSentByOwnDevice(event)) {\n const content = event!.getContent<{\n methods: string[];\n }>();\n this.commonMethods = content.methods.filter((m) => this.verificationMethods.has(m));\n }\n }\n // detect if we're not a party in the request, and we should just observe\n if (!this.observeOnly) {\n // if requested or accepted by one of my other devices\n if (phase === PHASE_REQUESTED || phase === PHASE_STARTED || phase === PHASE_READY) {\n if (\n this.channel.receiveStartFromOtherDevices &&\n this.wasSentByOwnUser(event) &&\n !this.wasSentByOwnDevice(event)\n ) {\n this._observeOnly = true;\n }\n }\n }\n // create verifier\n if (phase === PHASE_STARTED) {\n const { method } = event!.getContent();\n if (!this._verifier && !this.observeOnly) {\n this._verifier = this.createVerifier(method, event);\n if (!this._verifier) {\n this.cancel({\n code: \"m.unknown_method\",\n reason: `Unknown method: ${method}`,\n });\n } else {\n this._chosenMethod = method;\n }\n }\n }\n }\n\n private applyPhaseTransitions(): ITransition[] {\n const transitions = this.calculatePhaseTransitions();\n const existingIdx = transitions.findIndex((t) => t.phase === this.phase);\n // trim off phases we already went through, if any\n const newTransitions = transitions.slice(existingIdx + 1);\n // transition to all new phases\n for (const transition of newTransitions) {\n this.transitionToPhase(transition);\n }\n return newTransitions;\n }\n\n private isWinningStartRace(newEvent: MatrixEvent): boolean {\n if (newEvent.getType() !== START_TYPE) {\n return false;\n }\n const oldEvent = this._verifier!.startEvent;\n\n let oldRaceIdentifier;\n if (this.isSelfVerification) {\n // if the verifier does not have a startEvent,\n // it is because it's still sending and we are on the initator side\n // we know we are sending a .start event because we already\n // have a verifier (checked in calling method)\n if (oldEvent) {\n const oldContent = oldEvent.getContent();\n oldRaceIdentifier = oldContent && oldContent.from_device;\n } else {\n oldRaceIdentifier = this.client.getDeviceId();\n }\n } else {\n if (oldEvent) {\n oldRaceIdentifier = oldEvent.getSender();\n } else {\n oldRaceIdentifier = this.client.getUserId();\n }\n }\n\n let newRaceIdentifier;\n if (this.isSelfVerification) {\n const newContent = newEvent.getContent();\n newRaceIdentifier = newContent && newContent.from_device;\n } else {\n newRaceIdentifier = newEvent.getSender();\n }\n return newRaceIdentifier < oldRaceIdentifier;\n }\n\n public hasEventId(eventId: string): boolean {\n for (const event of this.eventsByUs.values()) {\n if (event.getId() === eventId) {\n return true;\n }\n }\n for (const event of this.eventsByThem.values()) {\n if (event.getId() === eventId) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Changes the state of the request and verifier in response to a key verification event.\n * @param type - the \"symbolic\" event type, as returned by the `getEventType` function on the channel.\n * @param event - the event to handle. Don't call getType() on it but use the `type` parameter instead.\n * @param isLiveEvent - whether this is an even received through sync or not\n * @param isRemoteEcho - whether this is the remote echo of an event sent by the same device\n * @param isSentByUs - whether this event is sent by a party that can accept and/or observe the request like one of our peers.\n * For InRoomChannel this means any device for the syncing user. For ToDeviceChannel, just the syncing device.\n * @returns a promise that resolves when any requests as an answer to the passed-in event are sent.\n */\n public async handleEvent(\n type: string,\n event: MatrixEvent,\n isLiveEvent: boolean,\n isRemoteEcho: boolean,\n isSentByUs: boolean,\n ): Promise<void> {\n // if reached phase cancelled or done, ignore anything else that comes\n if (this.done || this.cancelled) {\n return;\n }\n const wasObserveOnly = this._observeOnly;\n\n this.adjustObserveOnly(event, isLiveEvent);\n\n if (!this.observeOnly && !isRemoteEcho) {\n if (await this.cancelOnError(type, event)) {\n return;\n }\n }\n\n // This assumes verification won't need to send an event with\n // the same type for the same party twice.\n // This is true for QR and SAS verification, and was\n // added here to prevent verification getting cancelled\n // when the server duplicates an event (https://github.com/matrix-org/synapse/issues/3365)\n const isDuplicateEvent = isSentByUs ? this.eventsByUs.has(type) : this.eventsByThem.has(type);\n if (isDuplicateEvent) {\n return;\n }\n\n const oldPhase = this.phase;\n this.addEvent(type, event, isSentByUs);\n\n // this will create if needed the verifier so needs to happen before calling it\n const newTransitions = this.applyPhaseTransitions();\n try {\n // only pass events from the other side to the verifier,\n // no remote echos of our own events\n if (this._verifier && !this.observeOnly) {\n const newEventWinsRace = this.isWinningStartRace(event);\n if (this._verifier.canSwitchStartEvent(event) && newEventWinsRace) {\n this._verifier.switchStartEvent(event);\n } else if (!isRemoteEcho) {\n if (type === CANCEL_TYPE || this._verifier.events?.includes(type)) {\n this._verifier.handleEvent(event);\n }\n }\n }\n\n if (newTransitions.length) {\n // create QRCodeData if the other side can scan\n // important this happens before emitting a phase change,\n // so listeners can rely on it being there already\n // We only do this for live events because it is important that\n // we sign the keys that were in the QR code, and not the keys\n // we happen to have at some later point in time.\n if (isLiveEvent && newTransitions.some((t) => t.phase === PHASE_READY)) {\n const shouldGenerateQrCode = this.otherPartySupportsMethod(SCAN_QR_CODE_METHOD, true);\n if (shouldGenerateQrCode) {\n this._qrCodeData = await QRCodeData.create(this, this.client);\n }\n }\n\n const lastTransition = newTransitions[newTransitions.length - 1];\n const { phase } = lastTransition;\n\n this.setupTimeout(phase);\n // set phase as last thing as this emits the \"change\" event\n this.setPhase(phase);\n } else if (this._observeOnly !== wasObserveOnly) {\n this.emit(VerificationRequestEvent.Change);\n }\n } finally {\n // log events we processed so we can see from rageshakes what events were added to a request\n logger.log(\n `Verification request ${this.channel.transactionId}: ` +\n `${type} event with id:${event.getId()}, ` +\n `content:${JSON.stringify(event.getContent())} ` +\n `deviceId:${this.channel.deviceId}, ` +\n `sender:${event.getSender()}, isSentByUs:${isSentByUs}, ` +\n `isLiveEvent:${isLiveEvent}, isRemoteEcho:${isRemoteEcho}, ` +\n `phase:${oldPhase}=>${this.phase}, ` +\n `observeOnly:${wasObserveOnly}=>${this._observeOnly}`,\n );\n }\n }\n\n private setupTimeout(phase: Phase): void {\n const shouldTimeout = !this.timeoutTimer && !this.observeOnly && phase === PHASE_REQUESTED;\n\n if (shouldTimeout) {\n this.timeoutTimer = setTimeout(this.cancelOnTimeout, this.timeout);\n }\n if (this.timeoutTimer) {\n const shouldClear =\n phase === PHASE_STARTED || phase === PHASE_READY || phase === PHASE_DONE || phase === PHASE_CANCELLED;\n if (shouldClear) {\n clearTimeout(this.timeoutTimer);\n this.timeoutTimer = null;\n }\n }\n }\n\n private cancelOnTimeout = async (): Promise<void> => {\n try {\n if (this.initiatedByMe) {\n await this.cancel({\n reason: \"Other party didn't accept in time\",\n code: \"m.timeout\",\n });\n } else {\n await this.cancel({\n reason: \"User didn't accept in time\",\n code: \"m.timeout\",\n });\n }\n } catch (err) {\n logger.error(\"Error while cancelling verification request\", err);\n }\n };\n\n private async cancelOnError(type: string, event: MatrixEvent): Promise<boolean> {\n if (type === START_TYPE) {\n const method = event.getContent().method;\n if (!this.verificationMethods.has(method)) {\n await this.cancel(errorFromEvent(newUnknownMethodError()));\n return true;\n }\n }\n\n const isUnexpectedRequest = type === REQUEST_TYPE && this.phase !== PHASE_UNSENT;\n const isUnexpectedReady = type === READY_TYPE && this.phase !== PHASE_REQUESTED && this.phase !== PHASE_STARTED;\n // only if phase has passed from PHASE_UNSENT should we cancel, because events\n // are allowed to come in in any order (at least with InRoomChannel). So we only know\n // we're dealing with a valid request we should participate in once we've moved to PHASE_REQUESTED.\n // Before that, we could be looking at somebody else's verification request and we just\n // happen to be in the room\n if (this.phase !== PHASE_UNSENT && (isUnexpectedRequest || isUnexpectedReady)) {\n logger.warn(`Cancelling, unexpected ${type} verification ` + `event from ${event.getSender()}`);\n const reason = `Unexpected ${type} event in phase ${this.phase}`;\n await this.cancel(errorFromEvent(newUnexpectedMessageError({ reason })));\n return true;\n }\n return false;\n }\n\n private adjustObserveOnly(event: MatrixEvent, isLiveEvent = false): void {\n // don't send out events for historical requests\n if (!isLiveEvent) {\n this._observeOnly = true;\n }\n if (this.calculateEventTimeout(event) < VERIFICATION_REQUEST_MARGIN) {\n this._observeOnly = true;\n }\n }\n\n private addEvent(type: string, event: MatrixEvent, isSentByUs = false): void {\n if (isSentByUs) {\n this.eventsByUs.set(type, event);\n } else {\n this.eventsByThem.set(type, event);\n }\n\n // once we know the userId of the other party (from the .request event)\n // see if any event by anyone else crept into this.eventsByThem\n if (type === REQUEST_TYPE) {\n for (const [type, event] of this.eventsByThem.entries()) {\n if (event.getSender() !== this.otherUserId) {\n this.eventsByThem.delete(type);\n }\n }\n // also remember when we received the request event\n this.requestReceivedAt = Date.now();\n }\n }\n\n private createVerifier(\n method: VerificationMethod,\n startEvent: MatrixEvent | null = null,\n targetDevice: ITargetDevice | null = null,\n ): VerificationBase<any, any> | undefined {\n if (!targetDevice) {\n targetDevice = this.targetDevice;\n }\n const { userId, deviceId } = targetDevice;\n\n const VerifierCtor = this.verificationMethods.get(method);\n if (!VerifierCtor) {\n logger.warn(\"could not find verifier constructor for method\", method);\n return;\n }\n return new VerifierCtor(this.channel, this.client, userId!, deviceId!, startEvent, this);\n }\n\n private wasSentByOwnUser(event?: MatrixEvent): boolean {\n return event?.getSender() === this.client.getUserId();\n }\n\n // only for .request, .ready or .start\n private wasSentByOwnDevice(event?: MatrixEvent): boolean {\n if (!this.wasSentByOwnUser(event)) {\n return false;\n }\n const content = event!.getContent();\n if (!content || content.from_device !== this.client.getDeviceId()) {\n return false;\n }\n return true;\n }\n\n public onVerifierCancelled(): void {\n this._cancelled = true;\n // move to cancelled phase\n const newTransitions = this.applyPhaseTransitions();\n if (newTransitions.length) {\n this.setPhase(newTransitions[newTransitions.length - 1].phase);\n }\n }\n\n public onVerifierFinished(): void {\n this.channel.send(EventType.KeyVerificationDone, {});\n this.verifierHasFinished = true;\n // move to .done phase\n const newTransitions = this.applyPhaseTransitions();\n if (newTransitions.length) {\n this.setPhase(newTransitions[newTransitions.length - 1].phase);\n }\n }\n\n public getEventFromOtherParty(type: string): MatrixEvent | undefined {\n return this.eventsByThem.get(type);\n }\n}\n"],"mappings":"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"} \ No newline at end of file