element-call/public/browser-matrix.js.map

319 lines
3.1 MiB
Text
Raw Normal View History

{
"version": 3,
"sources": [
"node_modules/browser-pack/_prelude.js",
"node_modules/@babel/runtime/helpers/arrayLikeToArray.js",
"node_modules/@babel/runtime/helpers/arrayWithHoles.js",
"node_modules/@babel/runtime/helpers/arrayWithoutHoles.js",
"node_modules/@babel/runtime/helpers/assertThisInitialized.js",
"node_modules/@babel/runtime/helpers/asyncToGenerator.js",
"node_modules/@babel/runtime/helpers/classCallCheck.js",
"node_modules/@babel/runtime/helpers/construct.js",
"node_modules/@babel/runtime/helpers/createClass.js",
"node_modules/@babel/runtime/helpers/defineProperty.js",
"node_modules/@babel/runtime/helpers/getPrototypeOf.js",
"node_modules/@babel/runtime/helpers/inherits.js",
"node_modules/@babel/runtime/helpers/interopRequireDefault.js",
"node_modules/@babel/runtime/helpers/isNativeFunction.js",
"node_modules/@babel/runtime/helpers/isNativeReflectConstruct.js",
"node_modules/@babel/runtime/helpers/iterableToArray.js",
"node_modules/@babel/runtime/helpers/iterableToArrayLimit.js",
"node_modules/@babel/runtime/helpers/nonIterableRest.js",
"node_modules/@babel/runtime/helpers/nonIterableSpread.js",
"node_modules/@babel/runtime/helpers/possibleConstructorReturn.js",
"node_modules/@babel/runtime/helpers/setPrototypeOf.js",
"node_modules/@babel/runtime/helpers/slicedToArray.js",
"node_modules/@babel/runtime/helpers/toConsumableArray.js",
"node_modules/@babel/runtime/helpers/typeof.js",
"node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js",
"node_modules/@babel/runtime/helpers/wrapNativeSuper.js",
"node_modules/@babel/runtime/regenerator/index.js",
"node_modules/another-json/another-json.js",
"node_modules/base-x/src/index.js",
"node_modules/base64-js/index.js",
"node_modules/browser-request/index.js",
2021-08-11 18:56:57 +00:00
"node_modules/browser-resolve/empty.js",
"node_modules/browserify/node_modules/punycode/punycode.js",
"node_modules/bs58/index.js",
"node_modules/buffer/index.js",
2021-08-11 18:56:57 +00:00
"node_modules/call-bind/callBound.js",
"node_modules/call-bind/index.js",
"node_modules/content-type/index.js",
"node_modules/events/events.js",
2021-08-11 18:56:57 +00:00
"node_modules/function-bind/implementation.js",
"node_modules/function-bind/index.js",
"node_modules/get-intrinsic/index.js",
"node_modules/has-symbols/index.js",
"node_modules/has-symbols/shams.js",
"node_modules/has/src/index.js",
"node_modules/ieee754/index.js",
"node_modules/loglevel/lib/loglevel.js",
2021-08-11 18:56:57 +00:00
"node_modules/object-inspect/index.js",
"node_modules/p-retry/index.js",
"node_modules/process/browser.js",
"node_modules/qs/lib/formats.js",
"node_modules/qs/lib/index.js",
"node_modules/qs/lib/parse.js",
"node_modules/qs/lib/stringify.js",
"node_modules/qs/lib/utils.js",
"node_modules/querystring-es3/decode.js",
"node_modules/querystring-es3/encode.js",
"node_modules/querystring-es3/index.js",
"node_modules/regenerator-runtime/runtime.js",
"node_modules/retry/index.js",
"node_modules/retry/lib/retry.js",
"node_modules/retry/lib/retry_operation.js",
"node_modules/safe-buffer/index.js",
2021-08-11 18:56:57 +00:00
"node_modules/side-channel/index.js",
"node_modules/unhomoglyph/data.json",
"node_modules/unhomoglyph/index.js",
"node_modules/url/url.js",
"node_modules/url/util.js",
2021-08-11 18:56:57 +00:00
"src/@types/PushRules.ts",
"src/@types/event.ts",
"src/@types/partials.ts",
2021-08-11 18:56:57 +00:00
"src/@types/search.ts",
"src/NamespacedValue.ts",
"src/ReEmitter.ts",
"src/autodiscovery.js",
"src/browser-index.js",
"src/client.ts",
"src/content-helpers.ts",
"src/content-repo.ts",
"src/crypto/CrossSigning.ts",
"src/crypto/DeviceList.ts",
"src/crypto/EncryptionSetup.ts",
"src/crypto/OlmDevice.js",
"src/crypto/OutgoingRoomKeyRequestManager.ts",
"src/crypto/RoomList.ts",
"src/crypto/SecretStorage.ts",
"src/crypto/aes.ts",
"src/crypto/algorithms/base.ts",
"src/crypto/algorithms/index.ts",
"src/crypto/algorithms/megolm.ts",
"src/crypto/algorithms/olm.ts",
"src/crypto/api.ts",
"src/crypto/backup.ts",
"src/crypto/dehydration.ts",
"src/crypto/deviceinfo.ts",
"src/crypto/index.ts",
"src/crypto/key_passphrase.ts",
"src/crypto/olmlib.ts",
"src/crypto/recoverykey.ts",
2021-08-11 18:56:57 +00:00
"src/crypto/store/indexeddb-crypto-store-backend.ts",
"src/crypto/store/indexeddb-crypto-store.ts",
"src/crypto/store/localStorage-crypto-store.ts",
"src/crypto/store/memory-crypto-store.ts",
"src/crypto/verification/Base.js",
"src/crypto/verification/Error.js",
"src/crypto/verification/IllegalMethod.js",
"src/crypto/verification/QRCode.js",
"src/crypto/verification/SAS.js",
"src/crypto/verification/request/InRoomChannel.js",
"src/crypto/verification/request/ToDeviceChannel.js",
"src/crypto/verification/request/VerificationRequest.js",
"src/errors.js",
"src/event-mapper.ts",
"src/filter-component.ts",
"src/filter.ts",
"src/http-api.js",
2021-08-11 18:56:57 +00:00
"src/indexeddb-helpers.ts",
"src/interactive-auth.js",
"src/logger.ts",
"src/matrix.ts",
"src/models/MSC3089Branch.ts",
"src/models/MSC3089TreeSpace.ts",
"src/models/event-context.ts",
"src/models/event-timeline-set.ts",
"src/models/event-timeline.ts",
"src/models/event.ts",
"src/models/group.js",
"src/models/relations.ts",
"src/models/room-member.ts",
"src/models/room-state.ts",
"src/models/room-summary.ts",
"src/models/room.ts",
2021-08-11 18:56:57 +00:00
"src/models/search-result.ts",
"src/models/user.ts",
"src/pushprocessor.js",
"src/randomstring.ts",
"src/realtime-callbacks.js",
"src/scheduler.js",
"src/service-types.ts",
2021-08-11 18:56:57 +00:00
"src/store/indexeddb-local-backend.ts",
"src/store/indexeddb-remote-backend.ts",
"src/store/indexeddb.ts",
"src/store/memory.ts",
"src/store/session/webstorage.js",
"src/store/stub.ts",
"src/sync-accumulator.ts",
"src/sync.api.ts",
"src/sync.ts",
"src/timeline-window.ts",
"src/utils.ts",
"src/webrtc/call.ts",
"src/webrtc/callEventHandler.ts",
"src/webrtc/callEventTypes.ts",
"src/webrtc/callFeed.ts"
],
"names": [],
2021-08-20 21:43:16 +00:00
"mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACXA;AACA;AACA;AACA;AACA;AACA;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACdA;AACA;AACA;AACA;AACA;AACA;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BA;AACA;AACA;AACA;AACA;AACA;;ACLA;AACA;AACA;AACA;AACA;AACA;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5CA;AACA;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;
"file": "generated.js",
"sourceRoot": "",
"sourcesContent": [
"(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()",
2021-08-11 18:56:57 +00:00
"function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}\n\nmodule.exports = _arrayLikeToArray;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\n\nmodule.exports = _arrayWithHoles;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"var arrayLikeToArray = require(\"./arrayLikeToArray.js\");\n\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return arrayLikeToArray(arr);\n}\n\nmodule.exports = _arrayWithoutHoles;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}\n\nmodule.exports = _assertThisInitialized;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n Promise.resolve(value).then(_next, _throw);\n }\n}\n\nfunction _asyncToGenerator(fn) {\n return function () {\n var self = this,\n args = arguments;\n return new Promise(function (resolve, reject) {\n var gen = fn.apply(self, args);\n\n function _next(value) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value);\n }\n\n function _throw(err) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err);\n }\n\n _next(undefined);\n });\n };\n}\n\nmodule.exports = _asyncToGenerator;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n\nmodule.exports = _classCallCheck;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"var setPrototypeOf = require(\"./setPrototypeOf.js\");\n\nvar isNativeReflectConstruct = require(\"./isNativeReflectConstruct.js\");\n\nfunction _construct(Parent, args, Class) {\n if (isNativeReflectConstruct()) {\n module.exports = _construct = Reflect.construct;\n module.exports[\"default\"] = module.exports, module.exports.__esModule = true;\n } else {\n module.exports = _construct = function _construct(Parent, args, Class) {\n var a = [null];\n a.push.apply(a, args);\n var Constructor = Function.bind.apply(Parent, a);\n var instance = new Constructor();\n if (Class) setPrototypeOf(instance, Class.prototype);\n return instance;\n };\n\n module.exports[\"default\"] = module.exports, module.exports.__esModule = true;\n }\n\n return _construct.apply(null, arguments);\n}\n\nmodule.exports = _construct;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n}\n\nmodule.exports = _createClass;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nmodule.exports = _defineProperty;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _getPrototypeOf(o) {\n module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n module.exports[\"default\"] = module.exports, module.exports.__esModule = true;\n return _getPrototypeOf(o);\n}\n\nmodule.exports = _getPrototypeOf;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"var setPrototypeOf = require(\"./setPrototypeOf.js\");\n\nfunction _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n if (superClass) setPrototypeOf(subClass, superClass);\n}\n\nmodule.exports = _inherits;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n \"default\": obj\n };\n}\n\nmodule.exports = _interopRequireDefault;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _isNativeFunction(fn) {\n return Function.toString.call(fn).indexOf(\"[native code]\") !== -1;\n}\n\nmodule.exports = _isNativeFunction;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _isNativeReflectConstruct() {\n if (typeof Reflect === \"undefined\" || !Reflect.construct) return false;\n if (Reflect.construct.sham) return false;\n if (typeof Proxy === \"function\") return true;\n\n try {\n Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n return true;\n } catch (e) {\n return false;\n }\n}\n\nmodule.exports = _isNativeReflectConstruct;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}\n\nmodule.exports = _iterableToArray;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n\nmodule.exports = _iterableToArrayLimit;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nmodule.exports = _nonIterableRest;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nmodule.exports = _nonIterableSpread;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"var _typeof = require(\"@babel/runtime/helpers/typeof\")[\"default\"];\n\nvar assertThisInitialized = require(\"./assertThisInitialized.js\");\n\nfunction _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) {\n return call;\n }\n\n return assertThisInitialized(self);\n}\n\nmodule.exports = _possibleConstructorReturn;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _setPrototypeOf(o, p) {\n module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n module.exports[\"default\"] = module.exports, module.exports.__esModule = true;\n return _setPrototypeOf(o, p);\n}\n\nmodule.exports = _setPrototypeOf;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"var arrayWithHoles = require(\"./arrayWithHoles.js\");\n\nvar iterableToArrayLimit = require(\"./iterableToArrayLimit.js\");\n\nvar unsupportedIterableToArray = require(\"./unsupportedIterableToArray.js\");\n\nvar nonIterableRest = require(\"./nonIterableRest.js\");\n\nfunction _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}\n\nmodule.exports = _slicedToArray;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"var arrayWithoutHoles = require(\"./arrayWithoutHoles.js\");\n\nvar iterableToArray = require(\"./iterableToArray.js\");\n\nvar unsupportedIterableToArray = require(\"./unsupportedIterableToArray.js\");\n\nvar nonIterableSpread = require(\"./nonIterableSpread.js\");\n\nfunction _toConsumableArray(arr) {\n return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();\n}\n\nmodule.exports = _toConsumableArray;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n module.exports = _typeof = function _typeof(obj) {\n return typeof obj;\n };\n\n module.exports[\"default\"] = module.exports, module.exports.__esModule = true;\n } else {\n module.exports = _typeof = function _typeof(obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n\n module.exports[\"default\"] = module.exports, module.exports.__esModule = true;\n }\n\n return _typeof(obj);\n}\n\nmodule.exports = _typeof;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"var arrayLikeToArray = require(\"./arrayLikeToArray.js\");\n\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}\n\nmodule.exports = _unsupportedIterableToArray;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"var getPrototypeOf = require(\"./getPrototypeOf.js\");\n\nvar setPrototypeOf = require(\"./setPrototypeOf.js\");\n\nvar isNativeFunction = require(\"./isNativeFunction.js\");\n\nvar construct = require(\"./construct.js\");\n\nfunction _wrapNativeSuper(Class) {\n var _cache = typeof Map === \"function\" ? new Map() : undefined;\n\n module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) {\n if (Class === null || !isNativeFunction(Class)) return Class;\n\n if (typeof Class !== \"function\") {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n if (typeof _cache !== \"undefined\") {\n if (_cache.has(Class)) return _cache.get(Class);\n\n _cache.set(Class, Wrapper);\n }\n\n function Wrapper() {\n return construct(Class, arguments, getPrototypeOf(this).constructor);\n }\n\n Wrapper.prototype = Object.create(Class.prototype, {\n constructor: {\n value: Wrapper,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n return setPrototypeOf(Wrapper, Class);\n };\n\n module.exports[\"default\"] = module.exports, module.exports.__esModule = true;\n return _wrapNativeSuper(Class);\n}\n\nmodule.exports = _wrapNativeSuper;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;",
"module.exports = require(\"regenerator-runtime\");\n",
"/* Copyright 2015 Mark Haines\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use strict';\n\nvar escaped = /[\\\\\\\"\\x00-\\x1F]/g;\nvar escapes = {};\nfor (var i = 0; i < 0x20; ++i) {\n escapes[String.fromCharCode(i)] = (\n '\\\\U' + ('0000' + i.toString(16)).slice(-4).toUpperCase()\n );\n}\nescapes['\\b'] = '\\\\b';\nescapes['\\t'] = '\\\\t';\nescapes['\\n'] = '\\\\n';\nescapes['\\f'] = '\\\\f';\nescapes['\\r'] = '\\\\r';\nescapes['\\\"'] = '\\\\\\\"';\nescapes['\\\\'] = '\\\\\\\\';\n\nfunction escapeString(value) {\n escaped.lastIndex = 0;\n return value.replace(escaped, function(c) { return escapes[c]; });\n}\n\nfunction stringify(value) {\n switch (typeof value) {\n case 'string':\n return '\"' + escapeString(value) + '\"';\n case 'number':\n return isFinite(value) ? value : 'null';\n case 'boolean':\n return value;\n case 'object':\n if (value === null) {\n return 'null';\n }\n if (Array.isArray(value)) {\n return stringifyArray(value);\n }\n return stringifyObject(value);\n default:\n throw new Error('Cannot stringify: ' + typeof value);\n }\n}\n\nfunction stringifyArray(array) {\n var sep = '[';\n var result = '';\n for (var i = 0; i < array.length; ++i) {\n result += sep;\n sep = ',';\n result += stringify(array[i]);\n }\n if (sep != ',') {\n return '[]';\n } else {\n return result + ']';\n }\n}\n\nfunction stringifyObject(object) {\n var sep = '{';\n var result = '';\n var keys = Object.keys(object);\n keys.sort();\n for (var i = 0; i < keys.length; ++i) {\n var key = keys[i];\n result += sep + '\"' + escapeString(key) + '\":';\n sep = ',';\n result += stringify(object[key]);\n }\n if (sep != ',') {\n return '{}';\n } else {\n return result + '}';\n }\n}\n\n/** */\nmodule.exports = {stringify: stringify};\n",
"'use strict'\n// base-x encoding / decoding\n// Copyright (c) 2018 base-x contributors\n// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)\n// Distributed under the MIT software license, see the accompanying\n// file LICENSE or http://www.opensource.org/licenses/mit-license.php.\n// @ts-ignore\nvar _Buffer = require('safe-buffer').Buffer\nfunction base (ALPHABET) {\n if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }\n var BASE_MAP = new Uint8Array(256)\n for (var j = 0; j < BASE_MAP.length; j++) {\n BASE_MAP[j] = 255\n }\n for (var i = 0; i < ALPHABET.length; i++) {\n var x = ALPHABET.charAt(i)\n var xc = x.charCodeAt(0)\n if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }\n BASE_MAP[xc] = i\n }\n var BASE = ALPHABET.length\n var LEADER = ALPHABET.charAt(0)\n var FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up\n var iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up\n function encode (source) {\n if (Array.isArray(source) || source instanceof Uint8Array) { source = _Buffer.from(source) }\n if (!_Buffer.isBuffer(source)) { throw new TypeError('Expected Buffer') }\n if (source.length === 0) { return '' }\n // Skip & count leading zeroes.\n var zeroes = 0\n var length = 0\n var pbegin = 0\n var pend = source.length\n while (pbegin !== pend && source[pbegin] === 0) {\n pbegin++\n zeroes++\n }\n // Allocate enough space in big-endian base58 representation.\n var size = ((pend - pbegin) * iFACTOR + 1) >>> 0\n var b58 = new Uint8Array(size)\n // Process the bytes.\n while (pbegin !== pend) {\n var carry = source[pbegin]\n // Apply \"b58 = b58 * 256 + ch\".\n var i = 0\n for (var it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {\n carry += (256 * b58[it1]) >>> 0\n b58[it1] = (carry % BASE) >>> 0\n carry = (carry / BASE) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n pbegin++\n }\n // Skip leading zeroes in base58 result.\n var it2 = size - length\n while (it2 !== size && b58[it2] === 0) {\n it2++\n }\n // Translate the result into a string.\n var str = LEADER.repeat(zeroes)\n for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]) }\n return str\n }\n function decodeUnsafe (source) {\n if (typeof source !== 'string') { throw new TypeError('Expected String') }\n if (source.length === 0) { return _Buffer.alloc(0) }\n var psz = 0\n // Skip leading spaces.\n if (source[psz] === ' ') { return }\n // Skip and count leading '1's.\n var zeroes = 0\n var length = 0\n while (source[psz] === LEADER) {\n zeroes++\n psz++\n }\n // Allocate enough space in big-endian base256 representation.\n var size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up.\n var b256 = new Uint8Array(size)\n // Process the characters.\n while (source[psz]) {\n // Decode character\n var carry = BASE_MAP[source.charCodeAt(psz)]\n // Invalid character\n if (carry === 255) { return }\n var i = 0\n for (var it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {\n carry += (BASE * b256[it3]) >>> 0\n b256[it3] = (carry % 256) >>> 0\n carry = (carry / 256) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n psz++\n }\n // Skip trailing spaces.\n if (source[psz] === ' ') { return }\n // Skip leading zeroes in b256.\n var it4 = size - length\n while (it4 !== size && b256[it4] === 0) {\n it4++\n }\n var vch = _Buffer.allocUnsafe(zeroes + (size - it4))\n vch.fill(0x00, 0, zeroes)\n var j = zeroes\n while (it4 !== size) {\n vch[j++] = b256[it4++]\n }\n return vch\n }\n function decode (string) {\n var buff
"'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n var len = b64.length\n\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf('=')\n if (validLen === -1) validLen = len\n\n var placeHoldersLen = validLen === len\n ? 0\n : 4 - (validLen % 4)\n\n return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n var tmp\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n var curByte = 0\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0\n ? validLen - 4\n : validLen\n\n var i\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)]\n arr[curByte++] = (tmp >> 16) & 0xFF\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] +\n lookup[num >> 12 & 0x3F] +\n lookup[num >> 6 & 0x3F] +\n lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xFF0000) +\n ((uint8[i + 1] << 8) & 0xFF00) +\n (uint8[i + 2] & 0xFF)\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n parts.push(\n lookup[tmp >> 2] +\n lookup[(tmp << 4) & 0x3F] +\n '=='\n )\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3F] +\n lookup[(tmp << 2) & 0x3F] +\n '='\n )\n }\n\n return parts.join('')\n}\n",
"// Browser Request\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// UMD HEADER START \n(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define([], factory);\n } else if (typeof exports === 'object') {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like enviroments that support module.exports,\n // like Node.\n module.exports = factory();\n } else {\n // Browser globals (root is window)\n root.returnExports = factory();\n }\n}(this, function () {\n// UMD HEADER END\n\nvar XHR = XMLHttpRequest\nif (!XHR) throw new Error('missing XMLHttpRequest')\nrequest.log = {\n 'trace': noop, 'debug': noop, 'info': noop, 'warn': noop, 'error': noop\n}\n\nvar DEFAULT_TIMEOUT = 3 * 60 * 1000 // 3 minutes\n\n//\n// request\n//\n\nfunction request(options, callback) {\n // The entry-point to the API: prep the options object and pass the real work to run_xhr.\n if(typeof callback !== 'function')\n throw new Error('Bad callback given: ' + callback)\n\n if(!options)\n throw new Error('No options given')\n\n var options_onResponse = options.onResponse; // Save this for later.\n\n if(typeof options === 'string')\n options = {'uri':options};\n else\n options = JSON.parse(JSON.stringify(options)); // Use a duplicate for mutating.\n\n options.onResponse = options_onResponse // And put it back.\n\n if (options.verbose) request.log = getLogger();\n\n if(options.url) {\n options.uri = options.url;\n delete options.url;\n }\n\n if(!options.uri && options.uri !== \"\")\n throw new Error(\"options.uri is a required argument\");\n\n if(typeof options.uri != \"string\")\n throw new Error(\"options.uri must be a string\");\n\n var unsupported_options = ['proxy', '_redirectsFollowed', 'maxRedirects', 'followRedirect']\n for (var i = 0; i < unsupported_options.length; i++)\n if(options[ unsupported_options[i] ])\n throw new Error(\"options.\" + unsupported_options[i] + \" is not supported\")\n\n options.callback = callback\n options.method = options.method || 'GET';\n options.headers = options.headers || {};\n options.body = options.body || null\n options.timeout = options.timeout || request.DEFAULT_TIMEOUT\n\n if(options.headers.host)\n throw new Error(\"Options.headers.host is not supported\");\n\n if(options.json) {\n options.headers.accept = options.headers.accept || 'application/json'\n if(options.method !== 'GET')\n options.headers['content-type'] = 'application/json'\n\n if(typeof options.json !== 'boolean')\n options.body = JSON.stringify(options.json)\n else if(typeof options.body !== 'string')\n options.body = JSON.stringify(options.body)\n }\n \n //BEGIN QS Hack\n var serialize = function(obj) {\n var str = [];\n for(var p in obj)\n if (obj.hasOwnProperty(p)) {\n str.push(encodeURIComponent(p) + \"=\" + encodeURIComponent(obj[p]));\n }\n return str.join(\"&\");\n }\n \n if(options.qs){\n var qs = (typeof options.qs == 'string')? options.qs : serialize(options.qs);\n if(options.uri.indexOf('?') !== -1){ //no get params\n options.uri = options.uri+'&'+qs;\n }else{ //existing get params\n options.uri = options.uri+'?'+qs;\n }\n }\n //END QS Hack\n \n //BEGIN FORM Hack\n var multipart = function(obj) {\n //todo: support file type (useful?)\n var result = {};\n result.boundry = '-----------------------------
2021-08-11 18:56:57 +00:00
"",
"/*! https://mths.be/punycode v1.4.1 by @mathias */\n;(function(root) {\n\n\t/** Detect free variables */\n\tvar freeExports = typeof exports == 'object' && exports &&\n\t\t!exports.nodeType && exports;\n\tvar freeModule = typeof module == 'object' && module &&\n\t\t!module.nodeType && module;\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (\n\t\tfreeGlobal.global === freeGlobal ||\n\t\tfreeGlobal.window === freeGlobal ||\n\t\tfreeGlobal.self === freeGlobal\n\t) {\n\t\troot = freeGlobal;\n\t}\n\n\t/**\n\t * The `punycode` object.\n\t * @name punycode\n\t * @type Object\n\t */\n\tvar punycode,\n\n\t/** Highest positive signed 32-bit float value */\n\tmaxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1\n\n\t/** Bootstring parameters */\n\tbase = 36,\n\ttMin = 1,\n\ttMax = 26,\n\tskew = 38,\n\tdamp = 700,\n\tinitialBias = 72,\n\tinitialN = 128, // 0x80\n\tdelimiter = '-', // '\\x2D'\n\n\t/** Regular expressions */\n\tregexPunycode = /^xn--/,\n\tregexNonASCII = /[^\\x20-\\x7E]/, // unprintable ASCII chars + non-ASCII chars\n\tregexSeparators = /[\\x2E\\u3002\\uFF0E\\uFF61]/g, // RFC 3490 separators\n\n\t/** Error messages */\n\terrors = {\n\t\t'overflow': 'Overflow: input needs wider integers to process',\n\t\t'not-basic': 'Illegal input >= 0x80 (not a basic code point)',\n\t\t'invalid-input': 'Invalid input'\n\t},\n\n\t/** Convenience shortcuts */\n\tbaseMinusTMin = base - tMin,\n\tfloor = Math.floor,\n\tstringFromCharCode = String.fromCharCode,\n\n\t/** Temporary variable */\n\tkey;\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/**\n\t * A generic error utility function.\n\t * @private\n\t * @param {String} type The error type.\n\t * @returns {Error} Throws a `RangeError` with the applicable error message.\n\t */\n\tfunction error(type) {\n\t\tthrow new RangeError(errors[type]);\n\t}\n\n\t/**\n\t * A generic `Array#map` utility function.\n\t * @private\n\t * @param {Array} array The array to iterate over.\n\t * @param {Function} callback The function that gets called for every array\n\t * item.\n\t * @returns {Array} A new array of values returned by the callback function.\n\t */\n\tfunction map(array, fn) {\n\t\tvar length = array.length;\n\t\tvar result = [];\n\t\twhile (length--) {\n\t\t\tresult[length] = fn(array[length]);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * A simple `Array#map`-like wrapper to work with domain name strings or email\n\t * addresses.\n\t * @private\n\t * @param {String} domain The domain name or email address.\n\t * @param {Function} callback The function that gets called for every\n\t * character.\n\t * @returns {Array} A new string of characters returned by the callback\n\t * function.\n\t */\n\tfunction mapDomain(string, fn) {\n\t\tvar parts = string.split('@');\n\t\tvar result = '';\n\t\tif (parts.length > 1) {\n\t\t\t// In email addresses, only the domain name should be punycoded. Leave\n\t\t\t// the local part (i.e. everything up to `@`) intact.\n\t\t\tresult = parts[0] + '@';\n\t\t\tstring = parts[1];\n\t\t}\n\t\t// Avoid `split(regex)` for IE8 compatibility. See #17.\n\t\tstring = string.replace(regexSeparators, '\\x2E');\n\t\tvar labels = string.split('.');\n\t\tvar encoded = map(labels, fn).join('.');\n\t\treturn result + encoded;\n\t}\n\n\t/**\n\t * Creates an array containing the numeric code points of each Unicode\n\t * character in the string. While JavaScript uses UCS-2 internally,\n\t * this function will convert a pair of surrogate halves (each of which\n\t * UCS-2 exposes as separate characters) into a single code point,\n\t * matching UTF-16.\n\t * @see `punycode.ucs2.encode`\n\t * @see <https://mathiasbynens.be/notes/javascript-encoding>\n\t * @memberOf punycode.ucs2\n\t * @name decode\n\t * @param {String} string The Unicode input string (UCS-2).\n\t * @returns {Array} The new array of code points.\n\t */\n\tfunction ucs2decode(string) {\n\t\tvar output = [],\n\t\t counter = 0,\n\t\t length = string.length,\n\t\t value,\n\t\t extra;\n\t\twhile (counter < length) {\n\t\t\tvalue = string.charCodeAt(co
"var basex = require('base-x')\nvar ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'\n\nmodule.exports = basex(ALPHABET)\n",
"/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh <https://feross.org>\n * @license MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\nvar K_MAX_LENGTH = 0x7fffffff\nexports.kMaxLength = K_MAX_LENGTH\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Print warning and recommend using `buffer` v4.x which has an Object\n * implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * We report that the browser does not support typed arrays if the are not subclassable\n * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`\n * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support\n * for __proto__ and has a buggy typed array implementation.\n */\nBuffer.TYPED_ARRAY_SUPPORT = typedArraySupport()\n\nif (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&\n typeof console.error === 'function') {\n console.error(\n 'This browser lacks typed array (Uint8Array) support which is required by ' +\n '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'\n )\n}\n\nfunction typedArraySupport () {\n // Can typed array instances can be augmented?\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }\n return arr.foo() === 42\n } catch (e) {\n return false\n }\n}\n\nObject.defineProperty(Buffer.prototype, 'parent', {\n enumerable: true,\n get: function () {\n if (!Buffer.isBuffer(this)) return undefined\n return this.buffer\n }\n})\n\nObject.defineProperty(Buffer.prototype, 'offset', {\n enumerable: true,\n get: function () {\n if (!Buffer.isBuffer(this)) return undefined\n return this.byteOffset\n }\n})\n\nfunction createBuffer (length) {\n if (length > K_MAX_LENGTH) {\n throw new RangeError('The value \"' + length + '\" is invalid for option \"size\"')\n }\n // Return an augmented `Uint8Array` instance\n var buf = new Uint8Array(length)\n buf.__proto__ = Buffer.prototype\n return buf\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new TypeError(\n 'The \"string\" argument must be of type string. Received type number'\n )\n }\n return allocUnsafe(arg)\n }\n return from(arg, encodingOrOffset, length)\n}\n\n// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\nif (typeof Symbol !== 'undefined' && Symbol.species != null &&\n Buffer[Symbol.species] === Buffer) {\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true,\n enumerable: false,\n writable: false\n })\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\nfunction from (value, encodingOrOffset, length) {\n if (typeof value === 'string') {\n return fromString(value, encodingOrOffset)\n }\n\n if (ArrayBuffer.isView(value)) {\n return fromArrayLike(value)\n }\n\n if (value == null) {\n throw TypeError(\n 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +\n 'or Array-like Object. Received type ' + (typeof value)\n )\n }\n\n if (isInstance(value, ArrayBuffer) ||\n (value && isI
2021-08-11 18:56:57 +00:00
"'use strict';\n\nvar GetIntrinsic = require('get-intrinsic');\n\nvar callBind = require('./');\n\nvar $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));\n\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n\tvar intrinsic = GetIntrinsic(name, !!allowMissing);\n\tif (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {\n\t\treturn callBind(intrinsic);\n\t}\n\treturn intrinsic;\n};\n",
"'use strict';\n\nvar bind = require('function-bind');\nvar GetIntrinsic = require('get-intrinsic');\n\nvar $apply = GetIntrinsic('%Function.prototype.apply%');\nvar $call = GetIntrinsic('%Function.prototype.call%');\nvar $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);\n\nvar $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);\nvar $defineProperty = GetIntrinsic('%Object.defineProperty%', true);\nvar $max = GetIntrinsic('%Math.max%');\n\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = null;\n\t}\n}\n\nmodule.exports = function callBind(originalFunction) {\n\tvar func = $reflectApply(bind, $call, arguments);\n\tif ($gOPD && $defineProperty) {\n\t\tvar desc = $gOPD(func, 'length');\n\t\tif (desc.configurable) {\n\t\t\t// original length, plus the receiver, minus any additional arguments (after the receiver)\n\t\t\t$defineProperty(\n\t\t\t\tfunc,\n\t\t\t\t'length',\n\t\t\t\t{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }\n\t\t\t);\n\t\t}\n\t}\n\treturn func;\n};\n\nvar applyBind = function applyBind() {\n\treturn $reflectApply(bind, $apply, arguments);\n};\n\nif ($defineProperty) {\n\t$defineProperty(module.exports, 'apply', { value: applyBind });\n} else {\n\tmodule.exports.apply = applyBind;\n}\n",
"/*!\n * content-type\n * Copyright(c) 2015 Douglas Christopher Wilson\n * MIT Licensed\n */\n\n'use strict'\n\n/**\n * RegExp to match *( \";\" parameter ) in RFC 7231 sec 3.1.1.1\n *\n * parameter = token \"=\" ( token / quoted-string )\n * token = 1*tchar\n * tchar = \"!\" / \"#\" / \"$\" / \"%\" / \"&\" / \"'\" / \"*\"\n * / \"+\" / \"-\" / \".\" / \"^\" / \"_\" / \"`\" / \"|\" / \"~\"\n * / DIGIT / ALPHA\n * ; any VCHAR, except delimiters\n * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE\n * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text\n * obs-text = %x80-FF\n * quoted-pair = \"\\\" ( HTAB / SP / VCHAR / obs-text )\n */\nvar PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *(\"(?:[\\u000b\\u0020\\u0021\\u0023-\\u005b\\u005d-\\u007e\\u0080-\\u00ff]|\\\\[\\u000b\\u0020-\\u00ff])*\"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g\nvar TEXT_REGEXP = /^[\\u000b\\u0020-\\u007e\\u0080-\\u00ff]+$/\nvar TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/\n\n/**\n * RegExp to match quoted-pair in RFC 7230 sec 3.2.6\n *\n * quoted-pair = \"\\\" ( HTAB / SP / VCHAR / obs-text )\n * obs-text = %x80-FF\n */\nvar QESC_REGEXP = /\\\\([\\u000b\\u0020-\\u00ff])/g\n\n/**\n * RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6\n */\nvar QUOTE_REGEXP = /([\\\\\"])/g\n\n/**\n * RegExp to match type in RFC 7231 sec 3.1.1.1\n *\n * media-type = type \"/\" subtype\n * type = token\n * subtype = token\n */\nvar TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/\n\n/**\n * Module exports.\n * @public\n */\n\nexports.format = format\nexports.parse = parse\n\n/**\n * Format object to media type.\n *\n * @param {object} obj\n * @return {string}\n * @public\n */\n\nfunction format (obj) {\n if (!obj || typeof obj !== 'object') {\n throw new TypeError('argument obj is required')\n }\n\n var parameters = obj.parameters\n var type = obj.type\n\n if (!type || !TYPE_REGEXP.test(type)) {\n throw new TypeError('invalid type')\n }\n\n var string = type\n\n // append parameters\n if (parameters && typeof parameters === 'object') {\n var param\n var params = Object.keys(parameters).sort()\n\n for (var i = 0; i < params.length; i++) {\n param = params[i]\n\n if (!TOKEN_REGEXP.test(param)) {\n throw new TypeError('invalid parameter name')\n }\n\n string += '; ' + param + '=' + qstring(parameters[param])\n }\n }\n\n return string\n}\n\n/**\n * Parse media type to object.\n *\n * @param {string|object} string\n * @return {Object}\n * @public\n */\n\nfunction parse (string) {\n if (!string) {\n throw new TypeError('argument string is required')\n }\n\n // support req/res-like objects as argument\n var header = typeof string === 'object'\n ? getcontenttype(string)\n : string\n\n if (typeof header !== 'string') {\n throw new TypeError('argument string is required to be a string')\n }\n\n var index = header.indexOf(';')\n var type = index !== -1\n ? header.substr(0, index).trim()\n : header.trim()\n\n if (!TYPE_REGEXP.test(type)) {\n throw new TypeError('invalid media type')\n }\n\n var obj = new ContentType(type.toLowerCase())\n\n // parse parameters\n if (index !== -1) {\n var key\n var match\n var value\n\n PARAM_REGEXP.lastIndex = index\n\n while ((match = PARAM_REGEXP.exec(header))) {\n if (match.index !== index) {\n throw new TypeError('invalid parameter format')\n }\n\n index += match[0].length\n key = match[1].toLowerCase()\n value = match[2]\n\n if (value[0] === '\"') {\n // remove quotes and escapes\n value = value\n .substr(1, value.length - 2)\n .replace(QESC_REGEXP, '$1')\n }\n\n obj.parameters[key] = value\n }\n\n if (index !== header.length) {\n throw new TypeError('invalid parameter format')\n }\n }\n\n return obj\n}\n\n/**\n * Get content-type from req/res objects.\n *\n * @param {object}\n * @return {Object}\n *
2021-08-11 18:56:57 +00:00
"// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar R = typeof Reflect === 'object' ? Reflect : null\nvar ReflectApply = R && typeof R.apply === 'function'\n ? R.apply\n : function ReflectApply(target, receiver, args) {\n return Function.prototype.apply.call(target, receiver, args);\n }\n\nvar ReflectOwnKeys\nif (R && typeof R.ownKeys === 'function') {\n ReflectOwnKeys = R.ownKeys\n} else if (Object.getOwnPropertySymbols) {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target)\n .concat(Object.getOwnPropertySymbols(target));\n };\n} else {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target);\n };\n}\n\nfunction ProcessEmitWarning(warning) {\n if (console && console.warn) console.warn(warning);\n}\n\nvar NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {\n return value !== value;\n}\n\nfunction EventEmitter() {\n EventEmitter.init.call(this);\n}\nmodule.exports = EventEmitter;\nmodule.exports.once = once;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._eventsCount = 0;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nvar defaultMaxListeners = 10;\n\nfunction checkListener(listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n}\n\nObject.defineProperty(EventEmitter, 'defaultMaxListeners', {\n enumerable: true,\n get: function() {\n return defaultMaxListeners;\n },\n set: function(arg) {\n if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {\n throw new RangeError('The value of \"defaultMaxListeners\" is out of range. It must be a non-negative number. Received ' + arg + '.');\n }\n defaultMaxListeners = arg;\n }\n});\n\nEventEmitter.init = function() {\n\n if (this._events === undefined ||\n this._events === Object.getPrototypeOf(this)._events) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n }\n\n this._maxListeners = this._maxListeners || undefined;\n};\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {\n if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {\n throw new RangeError('The value of \"n\" is out of range. It must be a non-negative number. Received ' + n + '.');\n }\n this._maxListeners = n;\n return this;\n};\n\nfunction _getMaxListeners(that) {\n if (that._maxListeners === undefined)\n return EventEmitter.defaultMaxListeners;\n return that._maxListeners;\n}\n\nEventEmitter
"'use strict';\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n var target = this;\n if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n var args = slice.call(arguments, 1);\n\n var bound;\n var binder = function () {\n if (this instanceof bound) {\n var result = target.apply(\n this,\n args.concat(slice.call(arguments))\n );\n if (Object(result) === result) {\n return result;\n }\n return this;\n } else {\n return target.apply(\n that,\n args.concat(slice.call(arguments))\n );\n }\n };\n\n var boundLength = Math.max(0, target.length - args.length);\n var boundArgs = [];\n for (var i = 0; i < boundLength; i++) {\n boundArgs.push('$' + i);\n }\n\n bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};\n",
"'use strict';\n\nvar implementation = require('./implementation');\n\nmodule.exports = Function.prototype.bind || implementation;\n",
"'use strict';\n\nvar undefined;\n\nvar $SyntaxError = SyntaxError;\nvar $Function = Function;\nvar $TypeError = TypeError;\n\n// eslint-disable-next-line consistent-return\nvar getEvalledConstructor = function (expressionSyntax) {\n\ttry {\n\t\treturn $Function('\"use strict\"; return (' + expressionSyntax + ').constructor;')();\n\t} catch (e) {}\n};\n\nvar $gOPD = Object.getOwnPropertyDescriptor;\nif ($gOPD) {\n\ttry {\n\t\t$gOPD({}, '');\n\t} catch (e) {\n\t\t$gOPD = null; // this is IE 8, which has a broken gOPD\n\t}\n}\n\nvar throwTypeError = function () {\n\tthrow new $TypeError();\n};\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = require('has-symbols')();\n\nvar getProto = Object.getPrototypeOf || function (x) { return x.__proto__; }; // eslint-disable-line no-proto\n\nvar needsEval = {};\n\nvar TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': needsEval,\n\t'%AsyncGenerator%': needsEval,\n\t'%AsyncGeneratorFunction%': needsEval,\n\t'%AsyncIteratorPrototype%': needsEval,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,\n\t'%Boolean%': Boolean,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%Date%': Date,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': Error,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': EvalError,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,\n\t'%Function%': $Function,\n\t'%GeneratorFunction%': needsEval,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%Object%': Object,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': RangeError,\n\t'%ReferenceError%': ReferenceError,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%String%': String,\n\t'%StringIt
"'use strict';\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = require('./shams');\n\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n",
"'use strict';\n\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\tvar descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n",
"'use strict';\n\nvar bind = require('function-bind');\n\nmodule.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);\n",
"/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var nBits = -7\n var i = isLE ? (nBytes - 1) : 0\n var d = isLE ? -1 : 1\n var s = buffer[offset + i]\n\n i += d\n\n e = s & ((1 << (-nBits)) - 1)\n s >>= (-nBits)\n nBits += eLen\n for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & ((1 << (-nBits)) - 1)\n e >>= (-nBits)\n nBits += mLen\n for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity)\n } else {\n m = m + Math.pow(2, mLen)\n e = e - eBias\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n var i = isLE ? 0 : (nBytes - 1)\n var d = isLE ? 1 : -1\n var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n value = Math.abs(value)\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0\n e = eMax\n } else {\n e = Math.floor(Math.log(value) / Math.LN2)\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--\n c *= 2\n }\n if (e + eBias >= 1) {\n value += rt / c\n } else {\n value += rt * Math.pow(2, 1 - eBias)\n }\n if (value * c >= 2) {\n e++\n c /= 2\n }\n\n if (e + eBias >= eMax) {\n m = 0\n e = eMax\n } else if (e + eBias >= 1) {\n m = ((value * c) - 1) * Math.pow(2, mLen)\n e = e + eBias\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n e = 0\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = (e << mLen) | m\n eLen += mLen\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128\n}\n",
"/*\n* loglevel - https://github.com/pimterry/loglevel\n*\n* Copyright (c) 2013 Tim Perry\n* Licensed under the MIT license.\n*/\n(function (root, definition) {\n \"use strict\";\n if (typeof define === 'function' && define.amd) {\n define(definition);\n } else if (typeof module === 'object' && module.exports) {\n module.exports = definition();\n } else {\n root.log = definition();\n }\n}(this, function () {\n \"use strict\";\n\n // Slightly dubious tricks to cut down minimized file size\n var noop = function() {};\n var undefinedType = \"undefined\";\n var isIE = (typeof window !== undefinedType) && (typeof window.navigator !== undefinedType) && (\n /Trident\\/|MSIE /.test(window.navigator.userAgent)\n );\n\n var logMethods = [\n \"trace\",\n \"debug\",\n \"info\",\n \"warn\",\n \"error\"\n ];\n\n // Cross-browser bind equivalent that works at least back to IE6\n function bindMethod(obj, methodName) {\n var method = obj[methodName];\n if (typeof method.bind === 'function') {\n return method.bind(obj);\n } else {\n try {\n return Function.prototype.bind.call(method, obj);\n } catch (e) {\n // Missing bind shim or IE8 + Modernizr, fallback to wrapping\n return function() {\n return Function.prototype.apply.apply(method, [obj, arguments]);\n };\n }\n }\n }\n\n // Trace() doesn't print the message in IE, so for that case we need to wrap it\n function traceForIE() {\n if (console.log) {\n if (console.log.apply) {\n console.log.apply(console, arguments);\n } else {\n // In old IE, native console methods themselves don't have apply().\n Function.prototype.apply.apply(console.log, [console, arguments]);\n }\n }\n if (console.trace) console.trace();\n }\n\n // Build the best logging method possible for this env\n // Wherever possible we want to bind, not wrap, to preserve stack traces\n function realMethod(methodName) {\n if (methodName === 'debug') {\n methodName = 'log';\n }\n\n if (typeof console === undefinedType) {\n return false; // No method possible, for now - fixed later by enableLoggingWhenConsoleArrives\n } else if (methodName === 'trace' && isIE) {\n return traceForIE;\n } else if (console[methodName] !== undefined) {\n return bindMethod(console, methodName);\n } else if (console.log !== undefined) {\n return bindMethod(console, 'log');\n } else {\n return noop;\n }\n }\n\n // These private functions always need `this` to be set properly\n\n function replaceLoggingMethods(level, loggerName) {\n /*jshint validthis:true */\n for (var i = 0; i < logMethods.length; i++) {\n var methodName = logMethods[i];\n this[methodName] = (i < level) ?\n noop :\n this.methodFactory(methodName, level, loggerName);\n }\n\n // Define log.log as an alias for log.debug\n this.log = this.debug;\n }\n\n // In old IE versions, the console isn't present until you first open it.\n // We build realMethod() replacements here that regenerate logging methods\n function enableLoggingWhenConsoleArrives(methodName, level, loggerName) {\n return function () {\n if (typeof console !== undefinedType) {\n replaceLoggingMethods.call(this, level, loggerName);\n this[methodName].apply(this, arguments);\n }\n };\n }\n\n // By default, we use closely bound real methods wherever possible, and\n // otherwise we wait for a console to appear, and then try again.\n function defaultMethodFactory(methodName, level, loggerName) {\n /*jshint validthis:true */\n return realMet
2021-08-11 18:56:57 +00:00
"var hasMap = typeof Map === 'function' && Map.prototype;\nvar mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;\nvar mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;\nvar mapForEach = hasMap && Map.prototype.forEach;\nvar hasSet = typeof Set === 'function' && Set.prototype;\nvar setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;\nvar setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;\nvar setForEach = hasSet && Set.prototype.forEach;\nvar hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;\nvar weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;\nvar hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;\nvar weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;\nvar hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;\nvar weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;\nvar booleanValueOf = Boolean.prototype.valueOf;\nvar objectToString = Object.prototype.toString;\nvar functionToString = Function.prototype.toString;\nvar match = String.prototype.match;\nvar bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;\nvar gOPS = Object.getOwnPropertySymbols;\nvar symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;\nvar hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';\nvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\nvar gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (\n [].__proto__ === Array.prototype // eslint-disable-line no-proto\n ? function (O) {\n return O.__proto__; // eslint-disable-line no-proto\n }\n : null\n);\n\nvar inspectCustom = require('./util.inspect').custom;\nvar inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;\nvar toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;\n\nmodule.exports = function inspect_(obj, options, depth, seen) {\n var opts = options || {};\n\n if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {\n throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');\n }\n if (\n has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'\n ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity\n : opts.maxStringLength !== null\n )\n ) {\n throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');\n }\n var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;\n if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {\n throw new TypeError('option \"customInspect\", if provided, must be `true`, `false`, or `\\'symbol\\'`');\n }\n\n if (\n has(opts, 'indent')\n && opts.indent !== null\n && opts.indent !== '\\t'\n && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)\n ) {\n throw new TypeError('options \"indent\" must be \"\\\\t\", an integer > 0, or `null`');\n }\n\n if (typeof obj === 'undefined') {\n return 'undefined';\n }\n if (obj === null) {\n return 'null';\n }\n if (typeof obj === 'boolean') {\n return obj ? 'true' : 'false';\n }\n\n if (typeof obj === 'string') {\n return inspectString(obj, opts);\n }\n if (typeof obj === 'number') {\n if (obj === 0) {\n return Infinity / obj > 0 ? '0' : '-0';\n }\n return String(obj);\n }\n if (typeof obj === 'bigint') {\n return String(obj) + 'n';\n }\n\n var maxDepth = typeof opts.depth
"'use strict';\nconst retry = require('retry');\n\nconst networkErrorMsgs = [\n\t'Failed to fetch', // Chrome\n\t'NetworkError when attempting to fetch resource.', // Firefox\n\t'The Internet connection appears to be offline.', // Safari\n\t'Network request failed' // `cross-fetch`\n];\n\nclass AbortError extends Error {\n\tconstructor(message) {\n\t\tsuper();\n\n\t\tif (message instanceof Error) {\n\t\t\tthis.originalError = message;\n\t\t\t({message} = message);\n\t\t} else {\n\t\t\tthis.originalError = new Error(message);\n\t\t\tthis.originalError.stack = this.stack;\n\t\t}\n\n\t\tthis.name = 'AbortError';\n\t\tthis.message = message;\n\t}\n}\n\nconst decorateErrorWithCounts = (error, attemptNumber, options) => {\n\t// Minus 1 from attemptNumber because the first attempt does not count as a retry\n\tconst retriesLeft = options.retries - (attemptNumber - 1);\n\n\terror.attemptNumber = attemptNumber;\n\terror.retriesLeft = retriesLeft;\n\treturn error;\n};\n\nconst isNetworkError = errorMessage => networkErrorMsgs.includes(errorMessage);\n\nconst pRetry = (input, options) => new Promise((resolve, reject) => {\n\toptions = {\n\t\tonFailedAttempt: () => {},\n\t\tretries: 10,\n\t\t...options\n\t};\n\n\tconst operation = retry.operation(options);\n\n\toperation.attempt(async attemptNumber => {\n\t\ttry {\n\t\t\tresolve(await input(attemptNumber));\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof Error)) {\n\t\t\t\treject(new TypeError(`Non-error was thrown: \"${error}\". You should only throw errors.`));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (error instanceof AbortError) {\n\t\t\t\toperation.stop();\n\t\t\t\treject(error.originalError);\n\t\t\t} else if (error instanceof TypeError && !isNetworkError(error.message)) {\n\t\t\t\toperation.stop();\n\t\t\t\treject(error);\n\t\t\t} else {\n\t\t\t\tdecorateErrorWithCounts(error, attemptNumber, options);\n\n\t\t\t\ttry {\n\t\t\t\t\tawait options.onFailedAttempt(error);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (!operation.retry(error)) {\n\t\t\t\t\treject(operation.mainError());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n});\n\nmodule.exports = pRetry;\n// TODO: remove this in the next major version\nmodule.exports.default = pRetry;\n\nmodule.exports.AbortError = AbortError;\n",
"// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n
"'use strict';\n\nvar replace = String.prototype.replace;\nvar percentTwenties = /%20/g;\n\nvar Format = {\n RFC1738: 'RFC1738',\n RFC3986: 'RFC3986'\n};\n\nmodule.exports = {\n 'default': Format.RFC3986,\n formatters: {\n RFC1738: function (value) {\n return replace.call(value, percentTwenties, '+');\n },\n RFC3986: function (value) {\n return String(value);\n }\n },\n RFC1738: Format.RFC1738,\n RFC3986: Format.RFC3986\n};\n",
"'use strict';\n\nvar stringify = require('./stringify');\nvar parse = require('./parse');\nvar formats = require('./formats');\n\nmodule.exports = {\n formats: formats,\n parse: parse,\n stringify: stringify\n};\n",
2021-08-11 18:56:57 +00:00
"'use strict';\n\nvar utils = require('./utils');\n\nvar has = Object.prototype.hasOwnProperty;\nvar isArray = Array.isArray;\n\nvar defaults = {\n allowDots: false,\n allowPrototypes: false,\n allowSparse: false,\n arrayLimit: 20,\n charset: 'utf-8',\n charsetSentinel: false,\n comma: false,\n decoder: utils.decode,\n delimiter: '&',\n depth: 5,\n ignoreQueryPrefix: false,\n interpretNumericEntities: false,\n parameterLimit: 1000,\n parseArrays: true,\n plainObjects: false,\n strictNullHandling: false\n};\n\nvar interpretNumericEntities = function (str) {\n return str.replace(/&#(\\d+);/g, function ($0, numberStr) {\n return String.fromCharCode(parseInt(numberStr, 10));\n });\n};\n\nvar parseArrayValue = function (val, options) {\n if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {\n return val.split(',');\n }\n\n return val;\n};\n\n// This is what browsers will submit when the ✓ character occurs in an\n// application/x-www-form-urlencoded body and the encoding of the page containing\n// the form is iso-8859-1, or when the submitted form has an accept-charset\n// attribute of iso-8859-1. Presumably also with other charsets that do not contain\n// the ✓ character, such as us-ascii.\nvar isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('&#10003;')\n\n// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.\nvar charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')\n\nvar parseValues = function parseQueryStringValues(str, options) {\n var obj = {};\n var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\\?/, '') : str;\n var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;\n var parts = cleanStr.split(options.delimiter, limit);\n var skipIndex = -1; // Keep track of where the utf8 sentinel was found\n var i;\n\n var charset = options.charset;\n if (options.charsetSentinel) {\n for (i = 0; i < parts.length; ++i) {\n if (parts[i].indexOf('utf8=') === 0) {\n if (parts[i] === charsetSentinel) {\n charset = 'utf-8';\n } else if (parts[i] === isoSentinel) {\n charset = 'iso-8859-1';\n }\n skipIndex = i;\n i = parts.length; // The eslint settings do not allow break;\n }\n }\n }\n\n for (i = 0; i < parts.length; ++i) {\n if (i === skipIndex) {\n continue;\n }\n var part = parts[i];\n\n var bracketEqualsPos = part.indexOf(']=');\n var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;\n\n var key, val;\n if (pos === -1) {\n key = options.decoder(part, defaults.decoder, charset, 'key');\n val = options.strictNullHandling ? null : '';\n } else {\n key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');\n val = utils.maybeMap(\n parseArrayValue(part.slice(pos + 1), options),\n function (encodedVal) {\n return options.decoder(encodedVal, defaults.decoder, charset, 'value');\n }\n );\n }\n\n if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {\n val = interpretNumericEntities(val);\n }\n\n if (part.indexOf('[]=') > -1) {\n val = isArray(val) ? [val] : val;\n }\n\n if (has.call(obj, key)) {\n obj[key] = utils.combine(obj[key], val);\n } else {\n obj[key] = val;\n }\n }\n\n return obj;\n};\n\nvar parseObject = function (chain, val, options, valuesParsed) {\n var leaf = valuesParsed ? val : parseArrayValue(val, options);\n\n for (var i = chain.length - 1; i >= 0; --i) {\n var obj;\n var root = chain[i];\n\n if (root === '[]' && options.parseArrays)
"'use strict';\n\nvar getSideChannel = require('side-channel');\nvar utils = require('./utils');\nvar formats = require('./formats');\nvar has = Object.prototype.hasOwnProperty;\n\nvar arrayPrefixGenerators = {\n brackets: function brackets(prefix) {\n return prefix + '[]';\n },\n comma: 'comma',\n indices: function indices(prefix, key) {\n return prefix + '[' + key + ']';\n },\n repeat: function repeat(prefix) {\n return prefix;\n }\n};\n\nvar isArray = Array.isArray;\nvar push = Array.prototype.push;\nvar pushToArray = function (arr, valueOrArray) {\n push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);\n};\n\nvar toISO = Date.prototype.toISOString;\n\nvar defaultFormat = formats['default'];\nvar defaults = {\n addQueryPrefix: false,\n allowDots: false,\n charset: 'utf-8',\n charsetSentinel: false,\n delimiter: '&',\n encode: true,\n encoder: utils.encode,\n encodeValuesOnly: false,\n format: defaultFormat,\n formatter: formats.formatters[defaultFormat],\n // deprecated\n indices: false,\n serializeDate: function serializeDate(date) {\n return toISO.call(date);\n },\n skipNulls: false,\n strictNullHandling: false\n};\n\nvar isNonNullishPrimitive = function isNonNullishPrimitive(v) {\n return typeof v === 'string'\n || typeof v === 'number'\n || typeof v === 'boolean'\n || typeof v === 'symbol'\n || typeof v === 'bigint';\n};\n\nvar stringify = function stringify(\n object,\n prefix,\n generateArrayPrefix,\n strictNullHandling,\n skipNulls,\n encoder,\n filter,\n sort,\n allowDots,\n serializeDate,\n format,\n formatter,\n encodeValuesOnly,\n charset,\n sideChannel\n) {\n var obj = object;\n\n if (sideChannel.has(object)) {\n throw new RangeError('Cyclic object value');\n }\n\n if (typeof filter === 'function') {\n obj = filter(prefix, obj);\n } else if (obj instanceof Date) {\n obj = serializeDate(obj);\n } else if (generateArrayPrefix === 'comma' && isArray(obj)) {\n obj = utils.maybeMap(obj, function (value) {\n if (value instanceof Date) {\n return serializeDate(value);\n }\n return value;\n });\n }\n\n if (obj === null) {\n if (strictNullHandling) {\n return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix;\n }\n\n obj = '';\n }\n\n if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {\n if (encoder) {\n var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);\n return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];\n }\n return [formatter(prefix) + '=' + formatter(String(obj))];\n }\n\n var values = [];\n\n if (typeof obj === 'undefined') {\n return values;\n }\n\n var objKeys;\n if (generateArrayPrefix === 'comma' && isArray(obj)) {\n // we need to join elements in\n objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }];\n } else if (isArray(filter)) {\n objKeys = filter;\n } else {\n var keys = Object.keys(obj);\n objKeys = sort ? keys.sort(sort) : keys;\n }\n\n for (var i = 0; i < objKeys.length; ++i) {\n var key = objKeys[i];\n var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];\n\n if (skipNulls && value === null) {\n continue;\n }\n\n var keyPrefix = isArray(obj)\n ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix\n : prefix + (allowDots ? '.' + key : '[' + key + ']');\n\n sideChannel.set(object, true);\n var valueSideChannel = getSideChannel();\n pushToArray(values, stringify(\n value,\n keyPrefix,\n
"'use strict';\n\nvar formats = require('./formats');\n\nvar has = Object.prototype.hasOwnProperty;\nvar isArray = Array.isArray;\n\nvar hexTable = (function () {\n var array = [];\n for (var i = 0; i < 256; ++i) {\n array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());\n }\n\n return array;\n}());\n\nvar compactQueue = function compactQueue(queue) {\n while (queue.length > 1) {\n var item = queue.pop();\n var obj = item.obj[item.prop];\n\n if (isArray(obj)) {\n var compacted = [];\n\n for (var j = 0; j < obj.length; ++j) {\n if (typeof obj[j] !== 'undefined') {\n compacted.push(obj[j]);\n }\n }\n\n item.obj[item.prop] = compacted;\n }\n }\n};\n\nvar arrayToObject = function arrayToObject(source, options) {\n var obj = options && options.plainObjects ? Object.create(null) : {};\n for (var i = 0; i < source.length; ++i) {\n if (typeof source[i] !== 'undefined') {\n obj[i] = source[i];\n }\n }\n\n return obj;\n};\n\nvar merge = function merge(target, source, options) {\n /* eslint no-param-reassign: 0 */\n if (!source) {\n return target;\n }\n\n if (typeof source !== 'object') {\n if (isArray(target)) {\n target.push(source);\n } else if (target && typeof target === 'object') {\n if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {\n target[source] = true;\n }\n } else {\n return [target, source];\n }\n\n return target;\n }\n\n if (!target || typeof target !== 'object') {\n return [target].concat(source);\n }\n\n var mergeTarget = target;\n if (isArray(target) && !isArray(source)) {\n mergeTarget = arrayToObject(target, options);\n }\n\n if (isArray(target) && isArray(source)) {\n source.forEach(function (item, i) {\n if (has.call(target, i)) {\n var targetItem = target[i];\n if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {\n target[i] = merge(targetItem, item, options);\n } else {\n target.push(item);\n }\n } else {\n target[i] = item;\n }\n });\n return target;\n }\n\n return Object.keys(source).reduce(function (acc, key) {\n var value = source[key];\n\n if (has.call(acc, key)) {\n acc[key] = merge(acc[key], value, options);\n } else {\n acc[key] = value;\n }\n return acc;\n }, mergeTarget);\n};\n\nvar assign = function assignSingleSource(target, source) {\n return Object.keys(source).reduce(function (acc, key) {\n acc[key] = source[key];\n return acc;\n }, target);\n};\n\nvar decode = function (str, decoder, charset) {\n var strWithoutPlus = str.replace(/\\+/g, ' ');\n if (charset === 'iso-8859-1') {\n // unescape never throws, no try...catch needed:\n return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);\n }\n // utf-8\n try {\n return decodeURIComponent(strWithoutPlus);\n } catch (e) {\n return strWithoutPlus;\n }\n};\n\nvar encode = function encode(str, defaultEncoder, charset, kind, format) {\n // This code was originally written by Brian White (mscdex) for the io.js core querystring library.\n // It has been adapted here for stricter adherence to RFC 3986\n if (str.length === 0) {\n return str;\n }\n\n var string = str;\n if (typeof str === 'symbol') {\n string = Symbol.prototype.toString.call(str);\n } else if (typeof str !== 'string') {\n string = String(str);\n }\n\n if (charset === 'iso-8859-1') {\n return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {\n return '%26%23' + parseInt($0.slice(2),
"// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\n// If obj.hasOwnProperty has been overridden, then calling\n// obj.hasOwnProperty(prop) will break.\n// See: https://github.com/joyent/node/issues/1707\nfunction hasOwnProperty(obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\nmodule.exports = function(qs, sep, eq, options) {\n sep = sep || '&';\n eq = eq || '=';\n var obj = {};\n\n if (typeof qs !== 'string' || qs.length === 0) {\n return obj;\n }\n\n var regexp = /\\+/g;\n qs = qs.split(sep);\n\n var maxKeys = 1000;\n if (options && typeof options.maxKeys === 'number') {\n maxKeys = options.maxKeys;\n }\n\n var len = qs.length;\n // maxKeys <= 0 means that we should not limit keys count\n if (maxKeys > 0 && len > maxKeys) {\n len = maxKeys;\n }\n\n for (var i = 0; i < len; ++i) {\n var x = qs[i].replace(regexp, '%20'),\n idx = x.indexOf(eq),\n kstr, vstr, k, v;\n\n if (idx >= 0) {\n kstr = x.substr(0, idx);\n vstr = x.substr(idx + 1);\n } else {\n kstr = x;\n vstr = '';\n }\n\n k = decodeURIComponent(kstr);\n v = decodeURIComponent(vstr);\n\n if (!hasOwnProperty(obj, k)) {\n obj[k] = v;\n } else if (isArray(obj[k])) {\n obj[k].push(v);\n } else {\n obj[k] = [obj[k], v];\n }\n }\n\n return obj;\n};\n\nvar isArray = Array.isArray || function (xs) {\n return Object.prototype.toString.call(xs) === '[object Array]';\n};\n",
"// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar stringifyPrimitive = function(v) {\n switch (typeof v) {\n case 'string':\n return v;\n\n case 'boolean':\n return v ? 'true' : 'false';\n\n case 'number':\n return isFinite(v) ? v : '';\n\n default:\n return '';\n }\n};\n\nmodule.exports = function(obj, sep, eq, name) {\n sep = sep || '&';\n eq = eq || '=';\n if (obj === null) {\n obj = undefined;\n }\n\n if (typeof obj === 'object') {\n return map(objectKeys(obj), function(k) {\n var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;\n if (isArray(obj[k])) {\n return map(obj[k], function(v) {\n return ks + encodeURIComponent(stringifyPrimitive(v));\n }).join(sep);\n } else {\n return ks + encodeURIComponent(stringifyPrimitive(obj[k]));\n }\n }).join(sep);\n\n }\n\n if (!name) return '';\n return encodeURIComponent(stringifyPrimitive(name)) + eq +\n encodeURIComponent(stringifyPrimitive(obj));\n};\n\nvar isArray = Array.isArray || function (xs) {\n return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\nfunction map (xs, f) {\n if (xs.map) return xs.map(f);\n var res = [];\n for (var i = 0; i < xs.length; i++) {\n res.push(f(xs[i], i));\n }\n return res;\n}\n\nvar objectKeys = Object.keys || function (obj) {\n var res = [];\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);\n }\n return res;\n};\n",
"'use strict';\n\nexports.decode = exports.parse = require('./decode');\nexports.encode = exports.stringify = require('./encode');\n",
"/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nvar runtime = (function (exports) {\n \"use strict\";\n\n var Op = Object.prototype;\n var hasOwn = Op.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n function define(obj, key, value) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n return obj[key];\n }\n try {\n // IE 8 has a broken Object.defineProperty that only works on DOM objects.\n define({}, \"\");\n } catch (err) {\n define = function(obj, key, value) {\n return obj[key] = value;\n };\n }\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n var generator = Object.create(protoGenerator.prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n exports.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n // This is a polyfill for %IteratorPrototype% for environments that\n // don't natively support it.\n var IteratorPrototype = {};\n IteratorPrototype[iteratorSymbol] = function () {\n return this;\n };\n\n var getProto = Object.getPrototypeOf;\n var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n if (NativeIteratorPrototype &&\n NativeIteratorPrototype !== Op &&\n hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n // This environment has a native %IteratorPrototype%; use it instead\n // of the polyfill.\n IteratorPrototype = NativeIteratorPrototype;\n }\n\n var Gp = GeneratorFunctionPrototype.prototype =\n Generator.prototype = Object.create(IteratorPrototype);\n GeneratorFunction.prototype
"module.exports = require('./lib/retry');",
2021-08-11 18:56:57 +00:00
"var RetryOperation = require('./retry_operation');\n\nexports.operation = function(options) {\n var timeouts = exports.timeouts(options);\n return new RetryOperation(timeouts, {\n forever: options && (options.forever || options.retries === Infinity),\n unref: options && options.unref,\n maxRetryTime: options && options.maxRetryTime\n });\n};\n\nexports.timeouts = function(options) {\n if (options instanceof Array) {\n return [].concat(options);\n }\n\n var opts = {\n retries: 10,\n factor: 2,\n minTimeout: 1 * 1000,\n maxTimeout: Infinity,\n randomize: false\n };\n for (var key in options) {\n opts[key] = options[key];\n }\n\n if (opts.minTimeout > opts.maxTimeout) {\n throw new Error('minTimeout is greater than maxTimeout');\n }\n\n var timeouts = [];\n for (var i = 0; i < opts.retries; i++) {\n timeouts.push(this.createTimeout(i, opts));\n }\n\n if (options && options.forever && !timeouts.length) {\n timeouts.push(this.createTimeout(i, opts));\n }\n\n // sort the array numerically ascending\n timeouts.sort(function(a,b) {\n return a - b;\n });\n\n return timeouts;\n};\n\nexports.createTimeout = function(attempt, opts) {\n var random = (opts.randomize)\n ? (Math.random() + 1)\n : 1;\n\n var timeout = Math.round(random * Math.max(opts.minTimeout, 1) * Math.pow(opts.factor, attempt));\n timeout = Math.min(timeout, opts.maxTimeout);\n\n return timeout;\n};\n\nexports.wrap = function(obj, options, methods) {\n if (options instanceof Array) {\n methods = options;\n options = null;\n }\n\n if (!methods) {\n methods = [];\n for (var key in obj) {\n if (typeof obj[key] === 'function') {\n methods.push(key);\n }\n }\n }\n\n for (var i = 0; i < methods.length; i++) {\n var method = methods[i];\n var original = obj[method];\n\n obj[method] = function retryWrapper(original) {\n var op = exports.operation(options);\n var args = Array.prototype.slice.call(arguments, 1);\n var callback = args.pop();\n\n args.push(function(err) {\n if (op.retry(err)) {\n return;\n }\n if (err) {\n arguments[0] = op.mainError();\n }\n callback.apply(this, arguments);\n });\n\n op.attempt(function() {\n original.apply(obj, args);\n });\n }.bind(obj, original);\n obj[method].options = options;\n }\n};\n",
"function RetryOperation(timeouts, options) {\n // Compatibility for the old (timeouts, retryForever) signature\n if (typeof options === 'boolean') {\n options = { forever: options };\n }\n\n this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));\n this._timeouts = timeouts;\n this._options = options || {};\n this._maxRetryTime = options && options.maxRetryTime || Infinity;\n this._fn = null;\n this._errors = [];\n this._attempts = 1;\n this._operationTimeout = null;\n this._operationTimeoutCb = null;\n this._timeout = null;\n this._operationStart = null;\n this._timer = null;\n\n if (this._options.forever) {\n this._cachedTimeouts = this._timeouts.slice(0);\n }\n}\nmodule.exports = RetryOperation;\n\nRetryOperation.prototype.reset = function() {\n this._attempts = 1;\n this._timeouts = this._originalTimeouts.slice(0);\n}\n\nRetryOperation.prototype.stop = function() {\n if (this._timeout) {\n clearTimeout(this._timeout);\n }\n if (this._timer) {\n clearTimeout(this._timer);\n }\n\n this._timeouts = [];\n this._cachedTimeouts = null;\n};\n\nRetryOperation.prototype.retry = function(err) {\n if (this._timeout) {\n clearTimeout(this._timeout);\n }\n\n if (!err) {\n return false;\n }\n var currentTime = new Date().getTime();\n if (err && currentTime - this._operationStart >= this._maxRetryTime) {\n this._errors.push(err);\n this._errors.unshift(new Error('RetryOperation timeout occurred'));\n return false;\n }\n\n this._errors.push(err);\n\n var timeout = this._timeouts.shift();\n if (timeout === undefined) {\n if (this._cachedTimeouts) {\n // retry forever, only keep last error\n this._errors.splice(0, this._errors.length - 1);\n timeout = this._cachedTimeouts.slice(-1);\n } else {\n return false;\n }\n }\n\n var self = this;\n this._timer = setTimeout(function() {\n self._attempts++;\n\n if (self._operationTimeoutCb) {\n self._timeout = setTimeout(function() {\n self._operationTimeoutCb(self._attempts);\n }, self._operationTimeout);\n\n if (self._options.unref) {\n self._timeout.unref();\n }\n }\n\n self._fn(self._attempts);\n }, timeout);\n\n if (this._options.unref) {\n this._timer.unref();\n }\n\n return true;\n};\n\nRetryOperation.prototype.attempt = function(fn, timeoutOps) {\n this._fn = fn;\n\n if (timeoutOps) {\n if (timeoutOps.timeout) {\n this._operationTimeout = timeoutOps.timeout;\n }\n if (timeoutOps.cb) {\n this._operationTimeoutCb = timeoutOps.cb;\n }\n }\n\n var self = this;\n if (this._operationTimeoutCb) {\n this._timeout = setTimeout(function() {\n self._operationTimeoutCb();\n }, self._operationTimeout);\n }\n\n this._operationStart = new Date().getTime();\n\n this._fn(this._attempts);\n};\n\nRetryOperation.prototype.try = function(fn) {\n console.log('Using RetryOperation.try() is deprecated');\n this.attempt(fn);\n};\n\nRetryOperation.prototype.start = function(fn) {\n console.log('Using RetryOperation.start() is deprecated');\n this.attempt(fn);\n};\n\nRetryOperation.prototype.start = RetryOperation.prototype.try;\n\nRetryOperation.prototype.errors = function() {\n return this._errors;\n};\n\nRetryOperation.prototype.attempts = function() {\n return this._attempts;\n};\n\nRetryOperation.prototype.mainError = function() {\n if (this._errors.length === 0) {\n return null;\n }\n\n var counts = {};\n var mainError = null;\n var mainErrorCount = 0;\n\n for (var i = 0; i < this._errors.length; i++) {\n var error = this._errors[i];\n var message = error.message;\n var count = (counts[message] || 0) + 1;\n\n counts[message] = count;\n\n if (count >= mainErrorCount) {\n mainError = error;\n mainErrorCount = count;\n }\n }\n\n return mainError;\n};\n",
"/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */\n/* eslint-disable node/no-deprecated-api */\nvar buffer = require('buffer')\nvar Buffer = buffer.Buffer\n\n// alternative to using Object.keys for old browsers\nfunction copyProps (src, dst) {\n for (var key in src) {\n dst[key] = src[key]\n }\n}\nif (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {\n module.exports = buffer\n} else {\n // Copy properties from require('buffer')\n copyProps(buffer, exports)\n exports.Buffer = SafeBuffer\n}\n\nfunction SafeBuffer (arg, encodingOrOffset, length) {\n return Buffer(arg, encodingOrOffset, length)\n}\n\nSafeBuffer.prototype = Object.create(Buffer.prototype)\n\n// Copy static methods from Buffer\ncopyProps(Buffer, SafeBuffer)\n\nSafeBuffer.from = function (arg, encodingOrOffset, length) {\n if (typeof arg === 'number') {\n throw new TypeError('Argument must not be a number')\n }\n return Buffer(arg, encodingOrOffset, length)\n}\n\nSafeBuffer.alloc = function (size, fill, encoding) {\n if (typeof size !== 'number') {\n throw new TypeError('Argument must be a number')\n }\n var buf = Buffer(size)\n if (fill !== undefined) {\n if (typeof encoding === 'string') {\n buf.fill(fill, encoding)\n } else {\n buf.fill(fill)\n }\n } else {\n buf.fill(0)\n }\n return buf\n}\n\nSafeBuffer.allocUnsafe = function (size) {\n if (typeof size !== 'number') {\n throw new TypeError('Argument must be a number')\n }\n return Buffer(size)\n}\n\nSafeBuffer.allocUnsafeSlow = function (size) {\n if (typeof size !== 'number') {\n throw new TypeError('Argument must be a number')\n }\n return buffer.SlowBuffer(size)\n}\n",
2021-08-11 18:56:57 +00:00
"'use strict';\n\nvar GetIntrinsic = require('get-intrinsic');\nvar callBound = require('call-bind/callBound');\nvar inspect = require('object-inspect');\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $WeakMap = GetIntrinsic('%WeakMap%', true);\nvar $Map = GetIntrinsic('%Map%', true);\n\nvar $weakMapGet = callBound('WeakMap.prototype.get', true);\nvar $weakMapSet = callBound('WeakMap.prototype.set', true);\nvar $weakMapHas = callBound('WeakMap.prototype.has', true);\nvar $mapGet = callBound('Map.prototype.get', true);\nvar $mapSet = callBound('Map.prototype.set', true);\nvar $mapHas = callBound('Map.prototype.has', true);\n\n/*\n * This function traverses the list returning the node corresponding to the\n * given key.\n *\n * That node is also moved to the head of the list, so that if it's accessed\n * again we don't need to traverse the whole list. By doing so, all the recently\n * used nodes can be accessed relatively quickly.\n */\nvar listGetNode = function (list, key) { // eslint-disable-line consistent-return\n\tfor (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {\n\t\tif (curr.key === key) {\n\t\t\tprev.next = curr.next;\n\t\t\tcurr.next = list.next;\n\t\t\tlist.next = curr; // eslint-disable-line no-param-reassign\n\t\t\treturn curr;\n\t\t}\n\t}\n};\n\nvar listGet = function (objects, key) {\n\tvar node = listGetNode(objects, key);\n\treturn node && node.value;\n};\nvar listSet = function (objects, key, value) {\n\tvar node = listGetNode(objects, key);\n\tif (node) {\n\t\tnode.value = value;\n\t} else {\n\t\t// Prepend the new node to the beginning of the list\n\t\tobjects.next = { // eslint-disable-line no-param-reassign\n\t\t\tkey: key,\n\t\t\tnext: objects.next,\n\t\t\tvalue: value\n\t\t};\n\t}\n};\nvar listHas = function (objects, key) {\n\treturn !!listGetNode(objects, key);\n};\n\nmodule.exports = function getSideChannel() {\n\tvar $wm;\n\tvar $m;\n\tvar $o;\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\tget: function (key) { // eslint-disable-line consistent-return\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapGet($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapGet($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listGet($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\thas: function (key) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif ($wm) {\n\t\t\t\t\treturn $weakMapHas($wm, key);\n\t\t\t\t}\n\t\t\t} else if ($Map) {\n\t\t\t\tif ($m) {\n\t\t\t\t\treturn $mapHas($m, key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ($o) { // eslint-disable-line no-lonely-if\n\t\t\t\t\treturn listHas($o, key);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\tif (!$wm) {\n\t\t\t\t\t$wm = new $WeakMap();\n\t\t\t\t}\n\t\t\t\t$weakMapSet($wm, key, value);\n\t\t\t} else if ($Map) {\n\t\t\t\tif (!$m) {\n\t\t\t\t\t$m = new $Map();\n\t\t\t\t}\n\t\t\t\t$mapSet($m, key, value);\n\t\t\t} else {\n\t\t\t\tif (!$o) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Initialize the linked list as an empty node, so that we don't have\n\t\t\t\t\t * to special-case handling of the first node: we can always refer to\n\t\t\t\t\t * it as (previous node).next, instead of something like (list).head\n\t\t\t\t\t */\n\t\t\t\t\t$o = { key: {}, next: null };\n\t\t\t\t}\n\t\t\t\tlistSet($o, key, value);\n\t\t\t}\n\t\t}\n\t};\n\treturn channel;\n};\n",
"module.exports={\n \"0\": \"O\",\n \"1\": \"l\",\n \"֭\": \"֖\",\n \"֮\": \"֘\",\n \"֨\": \"֙\",\n \"֤\": \"֚\",\n \"᪴\": \"ۛ\",\n \"⃛\": \"ۛ\",\n \"ؙ\": \"̓\",\n \"ࣳ\": \"̓\",\n \"̓\": \"̓\",\n \"̕\": \"̓\",\n \"ُ\": \"̓\",\n \"ٝ\": \"̔\",\n \"֜\": \"́\",\n \"֝\": \"́\",\n \"ؘ\": \"́\",\n \"݇\": \"́\",\n \"́\": \"́\",\n \"॔\": \"́\",\n \"َ\": \"́\",\n \"̀\": \"̀\",\n \"॓\": \"̀\",\n \"̌\": \"̆\",\n \"꙼\": \"̆\",\n \"٘\": \"̆\",\n \"ٚ\": \"̆\",\n \"ͮ\": \"̆\",\n \"ۨ\": \"̆̇\",\n \"̐\": \"̆̇\",\n \"ँ\": \"̆̇\",\n \"ঁ\": \"̆̇\",\n \"ઁ\": \"̆̇\",\n \"ଁ\": \"̆̇\",\n \"ఀ\": \"̆̇\",\n \"ಁ\": \"̆̇\",\n \"ഁ\": \"̆̇\",\n \"𑒿\": \"̆̇\",\n \"᳐\": \"̂\",\n \"̑\": \"̂\",\n \"ٛ\": \"̂\",\n \"߮\": \"̂\",\n \"꛰\": \"̂\",\n \"֯\": \"̊\",\n \"۟\": \"̊\",\n \"៓\": \"̊\",\n \"゚\": \"̊\",\n \"ْ\": \"̊\",\n \"ஂ\": \"̊\",\n \"ံ\": \"̊\",\n \"ំ\": \"̊\",\n \"𑌀\": \"̊\",\n \"ํ\": \"̊\",\n \"ໍ\": \"̊\",\n \"ͦ\": \"̊\",\n \"ⷪ\": \"̊\",\n \"࣫\": \"̈\",\n \"߳\": \"̈\",\n \"ً\": \"̋\",\n \"ࣰ\": \"̋\",\n \"͂\": \"̃\",\n \"ٓ\": \"̃\",\n \"ׄ\": \"̇\",\n \"۬\": \"̇\",\n \"݀\": \"̇\",\n \"࣪\": \"̇\",\n \"݁\": \"̇\",\n \"͘\": \"̇\",\n \"ֹ\": \"̇\",\n \"ֺ\": \"̇\",\n \"ׂ\": \"̇\",\n \"ׁ\": \"̇\",\n \"߭\": \"̇\",\n \"ं\": \"̇\",\n \"ਂ\": \"̇\",\n \"ં\": \"̇\",\n \"்\": \"̇\",\n \"̷\": \"̸\",\n \"᪷\": \"̨\",\n \"̢\": \"̨\",\n \"ͅ\": \"̨\",\n \"᳒\": \"̄\",\n \"̅\": \"̄\",\n \"ٙ\": \"̄\",\n \"߫\": \"̄\",\n \"꛱\": \"̄\",\n \"᳚\": \"̎\",\n \"ٗ\": \"̒\",\n \"͗\": \"͐\",\n \"ࣿ\": \"͐\",\n \"ࣸ\": \"͐\",\n \"ऀ\": \"͒\",\n \"᳭\": \"̖\",\n \"᳜\": \"̩\",\n \"ٖ\": \"̩\",\n \"᳕\": \"̫\",\n \"͇\": \"̳\",\n \"ࣹ\": \"͔\",\n \"ࣺ\": \"͕\",\n \"゛\": \"゙\",\n \"゜\": \"゚\",\n \"̶\": \"̵\",\n \"〬\": \"̉\",\n \"ׅ\": \"̣\",\n \"࣭\": \"̣\",\n \"᳝\": \"̣\",\n \"ִ\": \"̣\",\n \"ٜ\": \"̣\",\n \"़\": \"̣\",\n \"়\": \"̣\",\n \"਼\": \"̣\",\n \"઼\": \"̣\",\n \"଼\": \"̣\",\n \"𑇊\": \"̣\",\n \"𑓃\": \"̣\",\n \"𐨺\": \"̣\",\n \"࣮\": \"̤\",\n \"᳞\": \"̤\",\n \"༷\": \"̥\",\n \"〭\": \"̥\",\n \"̧\": \"̦\",\n \"̡\": \"̦\",\n \"̹\": \"̦\",\n \"᳙\": \"̭\",\n \"᳘\": \"̮\",\n \"॒\": \"̱\",\n \"̠\": \"̱\",\n \"ࣱ\": \"ٌ\",\n \"ࣨ\": \"ٌ\",\n \"ࣥ\": \"ٌ\",\n \"ﱞ\": \"ﹲّ\",\n \"ࣲ\": \"ٍ\",\n \"ﱟ\": \"ﹴّ\",\n \"ﳲ\": \"ﹷّ\",\n \"ﱠ\": \"ﹶّ\",\n \"ﳳ\": \"ﹹّ\",\n \"ﱡ\": \"ﹸّ\",\n \"ؚ\": \"ِ\",\n \"̗\": \"ِ\",\n \"ﳴ\": \"ﹻّ\",\n \"ﱢ\": \"ﹺّ\",\n \"ﱣ\": \"ﹼٰ\",\n \"ٟ\": \"ٕ\",\n \"̍\": \"ٰ\",\n \"݂\": \"ܼ\",\n \"ਃ\": \"ঃ\",\n \"ః\": \"ঃ\",\n \"ಃ\": \"ঃ\",\n \"ഃ\": \"ঃ\",\n \"ඃ\": \"ঃ\",\n \"း\": \"ঃ\",\n \"𑓁\": \"ঃ\",\n \"់\": \"่\",\n \"່\": \"่\",\n \"້\": \"้\",\n \"໊\": \"๊\",\n \"໋\": \"๋\",\n \"꙯\": \"⃩\",\n \"\\u2028\": \" \",\n \"\\u2029\": \" \",\n \"\": \" \",\n \" \": \" \",\n \"\": \" \",\n \"\": \" \",\n \"\": \" \",\n \"\": \" \",\n \"\": \" \",\n \"\": \" \",\n \"\": \" \",\n \"\": \" \",\n \"\": \" \",\n \"\": \" \",\n \" \": \" \",\n \"\": \" \",\n \"\": \" \",\n \"ߺ\": \"_\",\n \"\": \"_\",\n \"\": \"_\",\n \"\": \"_\",\n \"\": \"-\",\n \"\": \"-\",\n \"\": \"-\",\n \"\": \"-\",\n \"\": \"-\",\n \"۔\": \"-\",\n \"\": \"-\",\n \"˗\": \"-\",\n \"\": \"-\",\n \"\": \"-\",\n \"\": \"-\",\n \"⨩\": \"-̓\",\n \"⸚\": \"-̈\",\n \"﬩\": \"-̇\",\n \"∸\": \"-̇\",\n \"⨪\": \"-̣\",\n \"꓾\": \"-.\",\n \"\": \"〜\",\n \"؍\": \",\",\n \"٫\": \",\",\n \"\": \",\",\n \"¸\": \",\",\n \"\": \",\",\n \"⸲\": \"،\",\n \"٬\": \"،\",\n \";\": \";\",\n \"⸵\"
"'use strict';\n\n\nvar data = require('./data.json');\n\nfunction escapeRegexp(str) {\n return str.replace(/([.?*+^$[\\]\\\\(){}|-])/g, '\\\\$1');\n}\n\nvar REPLACE_RE = RegExp(Object.keys(data).map(escapeRegexp).join('|'), 'g');\n\nfunction replace_fn(match) {\n return data[match];\n}\n\nfunction unhomoglyph(str) {\n return str.replace(REPLACE_RE, replace_fn);\n}\n\nmodule.exports = unhomoglyph;\n",
"// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar punycode = require('punycode');\nvar util = require('./util');\n\nexports.parse = urlParse;\nexports.resolve = urlResolve;\nexports.resolveObject = urlResolveObject;\nexports.format = urlFormat;\n\nexports.Url = Url;\n\nfunction Url() {\n this.protocol = null;\n this.slashes = null;\n this.auth = null;\n this.host = null;\n this.port = null;\n this.hostname = null;\n this.hash = null;\n this.search = null;\n this.query = null;\n this.pathname = null;\n this.path = null;\n this.href = null;\n}\n\n// Reference: RFC 3986, RFC 1808, RFC 2396\n\n// define these here so at least they only have to be\n// compiled once on the first module load.\nvar protocolPattern = /^([a-z0-9.+-]+:)/i,\n portPattern = /:[0-9]*$/,\n\n // Special case for a simple path URL\n simplePathPattern = /^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/,\n\n // RFC 2396: characters reserved for delimiting URLs.\n // We actually just auto-escape these.\n delims = ['<', '>', '\"', '`', ' ', '\\r', '\\n', '\\t'],\n\n // RFC 2396: characters not allowed for various reasons.\n unwise = ['{', '}', '|', '\\\\', '^', '`'].concat(delims),\n\n // Allowed by RFCs, but cause of XSS attacks. Always escape these.\n autoEscape = ['\\''].concat(unwise),\n // Characters that are never ever allowed in a hostname.\n // Note that any invalid chars are also handled, but these\n // are the ones that are *expected* to be seen, so we fast-path\n // them.\n nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),\n hostEndingChars = ['/', '?', '#'],\n hostnameMaxLen = 255,\n hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,\n hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,\n // protocols that can allow \"unsafe\" and \"unwise\" chars.\n unsafeProtocol = {\n 'javascript': true,\n 'javascript:': true\n },\n // protocols that never have a hostname.\n hostlessProtocol = {\n 'javascript': true,\n 'javascript:': true\n },\n // protocols that always contain a // bit.\n slashedProtocol = {\n 'http': true,\n 'https': true,\n 'ftp': true,\n 'gopher': true,\n 'file': true,\n 'http:': true,\n 'https:': true,\n 'ftp:': true,\n 'gopher:': true,\n 'file:': true\n },\n querystring = require('querystring');\n\nfunction urlParse(url, parseQueryString, slashesDenoteHost) {\n if (url && util.isObject(url) && url instanceof Url) return url;\n\n var u = new Url;\n u.parse(url, parseQueryString, slashesDenoteHost);\n return u;\n}\n\nUrl.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {\n if (!util.isString(url)) {\n throw new TypeError(\"Parameter 'url' must be a string, not \" + typeof url);\n }\n\n // Copy chrome, IE, opera backslash-handling behavior.\n // Back slashes before the query string get converted to forward slashes\n // See: ht
"'use strict';\n\nmodule.exports = {\n isString: function(arg) {\n return typeof(arg) === 'string';\n },\n isObject: function(arg) {\n return typeof(arg) === 'object' && arg !== null;\n },\n isNull: function(arg) {\n return arg === null;\n },\n isNullOrUndefined: function(arg) {\n return arg == null;\n }\n};\n",
2021-08-11 18:56:57 +00:00
"/*\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\n// allow camelcase as these are things that go onto the wire\n/* eslint-disable camelcase */\n\nexport enum PushRuleActionName {\n DontNotify = \"dont_notify\",\n Notify = \"notify\",\n Coalesce = \"coalesce\",\n}\n\nexport enum TweakName {\n Highlight = \"highlight\",\n Sound = \"sound\",\n}\n\nexport type Tweak<N extends TweakName, V> = {\n set_tweak: N;\n value: V;\n};\n\nexport type TweakHighlight = Tweak<TweakName.Highlight, boolean>;\nexport type TweakSound = Tweak<TweakName.Sound, string>;\n\nexport type Tweaks = TweakHighlight | TweakSound;\n\nexport enum ConditionOperator {\n ExactEquals = \"==\",\n LessThan = \"<\",\n GreaterThan = \">\",\n GreaterThanOrEqual = \">=\",\n LessThanOrEqual = \"<=\",\n}\n\nexport type PushRuleAction = Tweaks | PushRuleActionName;\n\nexport type MemberCountCondition\n <N extends number, Op extends ConditionOperator = ConditionOperator.ExactEquals>\n = `${Op}${N}` | (Op extends ConditionOperator.ExactEquals ? `${N}` : never);\n\nexport type AnyMemberCountCondition = MemberCountCondition<number, ConditionOperator>;\n\nexport const DMMemberCountCondition: MemberCountCondition<2> = \"2\";\n\nexport function isDmMemberCountCondition(condition: AnyMemberCountCondition): boolean {\n return condition === \"==2\" || condition === \"2\";\n}\n\nexport enum ConditionKind {\n EventMatch = \"event_match\",\n ContainsDisplayName = \"contains_display_name\",\n RoomMemberCount = \"room_member_count\",\n SenderNotificationPermission = \"sender_notification_permission\",\n}\n\nexport interface IPushRuleCondition<N extends ConditionKind | string> {\n [k: string]: any; // for custom conditions, there can be other fields here\n kind: N;\n}\n\nexport interface IEventMatchCondition extends IPushRuleCondition<ConditionKind.EventMatch> {\n key: string;\n pattern: string;\n}\n\nexport interface IContainsDisplayNameCondition extends IPushRuleCondition<ConditionKind.ContainsDisplayName> {\n // no additional fields\n}\n\nexport interface IRoomMemberCountCondition extends IPushRuleCondition<ConditionKind.RoomMemberCount> {\n is: AnyMemberCountCondition;\n}\n\nexport interface ISenderNotificationPermissionCondition\n extends IPushRuleCondition<ConditionKind.SenderNotificationPermission> {\n key: string;\n}\n\nexport type PushRuleCondition = IPushRuleCondition<string>\n | IEventMatchCondition\n | IContainsDisplayNameCondition\n | IRoomMemberCountCondition\n | ISenderNotificationPermissionCondition;\n\nexport enum PushRuleKind {\n Override = \"override\",\n ContentSpecific = \"content\",\n RoomSpecific = \"room\",\n SenderSpecific = \"sender\",\n Underride = \"underride\",\n}\n\nexport enum RuleId {\n Master = \".m.rule.master\",\n ContainsDisplayName = \".m.rule.contains_display_name\",\n ContainsUserName = \".m.rule.contains_user_name\",\n AtRoomNotification = \".m.rule.roomnotif\",\n DM = \".m.rule.room_one_to_one\",\n EncryptedDM = \".m.rule.encrypted_room_one_to_one\",\n Message = \".m.rule.message\",\n EncryptedMessage = \".m.rule.encrypted\",\n InviteToSelf = \".m.rule.invite_for_me\",\n MemberEvent = \".m.rule.member_event\",\n IncomingCall = \".m.rule.call\",\n SuppressNotices = \".m.rule.suppress_notices\",\n Tombstone = \".m.rule.tombstone\",\n}\n\nexport type PushRuleSet = {\n [k in PushRuleKind]?: IPushRule[];\n};\n\nexport interface IPushRule {\n actions: Pu
"/*\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\nimport { UnstableValue } from \"../NamespacedValue\";\n\nexport enum EventType {\n // Room state events\n RoomCanonicalAlias = \"m.room.canonical_alias\",\n RoomCreate = \"m.room.create\",\n RoomJoinRules = \"m.room.join_rules\",\n RoomMember = \"m.room.member\",\n RoomThirdPartyInvite = \"m.room.third_party_invite\",\n RoomPowerLevels = \"m.room.power_levels\",\n RoomName = \"m.room.name\",\n RoomTopic = \"m.room.topic\",\n RoomAvatar = \"m.room.avatar\",\n RoomPinnedEvents = \"m.room.pinned_events\",\n RoomEncryption = \"m.room.encryption\",\n RoomHistoryVisibility = \"m.room.history_visibility\",\n RoomGuestAccess = \"m.room.guest_access\",\n RoomServerAcl = \"m.room.server_acl\",\n RoomTombstone = \"m.room.tombstone\",\n /**\n * @deprecated Should not be used.\n */\n RoomAliases = \"m.room.aliases\", // deprecated https://matrix.org/docs/spec/client_server/r0.6.1#historical-events\n\n SpaceChild = \"m.space.child\",\n SpaceParent = \"m.space.parent\",\n\n // Room timeline events\n RoomRedaction = \"m.room.redaction\",\n RoomMessage = \"m.room.message\",\n RoomMessageEncrypted = \"m.room.encrypted\",\n Sticker = \"m.sticker\",\n CallInvite = \"m.call.invite\",\n CallCandidates = \"m.call.candidates\",\n CallAnswer = \"m.call.answer\",\n CallHangup = \"m.call.hangup\",\n CallReject = \"m.call.reject\",\n CallSelectAnswer = \"m.call.select_answer\",\n CallNegotiate = \"m.call.negotiate\",\n CallSDPStreamMetadataChanged = \"m.call.sdp_stream_metadata_changed\",\n CallSDPStreamMetadataChangedPrefix = \"org.matrix.call.sdp_stream_metadata_changed\",\n CallReplaces = \"m.call.replaces\",\n CallAssertedIdentity = \"m.call.asserted_identity\",\n CallAssertedIdentityPrefix = \"org.matrix.call.asserted_identity\",\n KeyVerificationRequest = \"m.key.verification.request\",\n KeyVerificationStart = \"m.key.verification.start\",\n KeyVerificationCancel = \"m.key.verification.cancel\",\n KeyVerificationMac = \"m.key.verification.mac\",\n KeyVerificationDone = \"m.key.verification.done\",\n // use of this is discouraged https://matrix.org/docs/spec/client_server/r0.6.1#m-room-message-feedback\n RoomMessageFeedback = \"m.room.message.feedback\",\n Reaction = \"m.reaction\",\n\n // Room ephemeral events\n Typing = \"m.typing\",\n Receipt = \"m.receipt\",\n Presence = \"m.presence\",\n\n // Room account_data events\n FullyRead = \"m.fully_read\",\n Tag = \"m.tag\",\n SpaceOrder = \"org.matrix.msc3230.space_order\", // MSC3230\n\n // User account_data events\n PushRules = \"m.push_rules\",\n Direct = \"m.direct\",\n IgnoredUserList = \"m.ignored_user_list\",\n\n // to_device events\n RoomKey = \"m.room_key\",\n RoomKeyRequest = \"m.room_key_request\",\n ForwardedRoomKey = \"m.forwarded_room_key\",\n Dummy = \"m.dummy\",\n}\n\nexport enum RelationType {\n Annotation = \"m.annotation\",\n Replace = \"m.replace\",\n}\n\nexport enum MsgType {\n Text = \"m.text\",\n Emote = \"m.emote\",\n Notice = \"m.notice\",\n Image = \"m.image\",\n File = \"m.file\",\n Audio = \"m.audio\",\n Location = \"m.location\",\n Video = \"m.video\",\n}\n\nexport const RoomCreateTypeField = \"type\";\n\nexport enum RoomType {\n Space = \"m.space\",\n}\n\n/**\n * Identifier for an [MSC3088](https://github.com/matrix-org/matrix-doc/pull/3088)\n * ro
"/*\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\nexport interface IImageInfo {\n size?: number;\n mimetype?: string;\n thumbnail_info?: { // eslint-disable-line camelcase\n w?: number;\n h?: number;\n size?: number;\n mimetype?: string;\n };\n w?: number;\n h?: number;\n}\n\nexport enum Visibility {\n Public = \"public\",\n Private = \"private\",\n}\n\nexport enum Preset {\n PrivateChat = \"private_chat\",\n TrustedPrivateChat = \"trusted_private_chat\",\n PublicChat = \"public_chat\",\n}\n\nexport type ResizeMethod = \"crop\" | \"scale\";\n\n// TODO move to http-api after TSification\nexport interface IAbortablePromise<T> extends Promise<T> {\n abort(): void;\n}\n\nexport type IdServerUnbindResult = \"no-support\" | \"success\";\n\n// Knock and private are reserved keywords which are not yet implemented.\nexport enum JoinRule {\n Public = \"public\",\n Invite = \"invite\",\n /**\n * @deprecated Reserved keyword. Should not be used. Not yet implemented.\n */\n Private = \"private\",\n Knock = \"knock\", // MSC2403 - only valid inside experimental room versions at this time.\n Restricted = \"restricted\", // MSC3083 - only valid inside experimental room versions at this time.\n}\n\nexport enum RestrictedAllowType {\n RoomMembership = \"m.room_membership\", // MSC3083 - only valid inside experimental room versions at this time.\n}\n\nexport enum GuestAccess {\n CanJoin = \"can_join\",\n Forbidden = \"forbidden\",\n}\n\nexport enum HistoryVisibility {\n Invited = \"invited\",\n Joined = \"joined\",\n Shared = \"shared\",\n WorldReadable = \"world_readable\",\n}\n\n// XXX move to OlmDevice when converted\nexport interface InboundGroupSessionData {\n room_id: string; // eslint-disable-line camelcase\n session: string;\n keysClaimed: Record<string, string>;\n forwardingCurve25519KeyChain: string[];\n}\n",
"/*\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\n// Types relating to the /search API\n\nimport { IRoomEvent, IStateEvent } from \"../sync-accumulator\";\nimport { IRoomEventFilter } from \"../filter\";\nimport { SearchResult } from \"../models/search-result\";\n\n/* eslint-disable camelcase */\nexport interface IEventWithRoomId extends IRoomEvent {\n room_id: string;\n}\n\nexport interface IStateEventWithRoomId extends IStateEvent {\n room_id: string;\n}\n\nexport interface IMatrixProfile {\n avatar_url?: string;\n displayname?: string;\n}\n\nexport interface IResultContext {\n events_before: IEventWithRoomId[];\n events_after: IEventWithRoomId[];\n profile_info: Record<string, IMatrixProfile>;\n start?: string;\n end?: string;\n}\n\nexport interface ISearchResult {\n rank: number;\n result: IEventWithRoomId;\n context: IResultContext;\n}\n\nenum GroupKey {\n RoomId = \"room_id\",\n Sender = \"sender\",\n}\n\nexport interface IResultRoomEvents {\n count: number;\n highlights: string[];\n results: ISearchResult[];\n state?: { [roomId: string]: IStateEventWithRoomId[] };\n groups?: {\n [groupKey in GroupKey]: {\n [value: string]: {\n next_batch?: string;\n order: number;\n results: string[];\n };\n };\n };\n next_batch?: string;\n}\n\ninterface IResultCategories {\n room_events: IResultRoomEvents;\n}\n\nexport type SearchKey = \"content.body\" | \"content.name\" | \"content.topic\";\n\nexport enum SearchOrderBy {\n Recent = \"recent\",\n Rank = \"rank\",\n}\n\nexport interface ISearchRequestBody {\n search_categories: {\n room_events: {\n search_term: string;\n keys?: SearchKey[];\n filter?: IRoomEventFilter;\n order_by?: SearchOrderBy;\n event_context?: {\n before_limit?: number;\n after_limit?: number;\n include_profile?: boolean;\n };\n include_state?: boolean;\n groupings?: {\n group_by: {\n key: GroupKey;\n }[];\n };\n };\n };\n}\n\nexport interface ISearchResponse {\n search_categories: IResultCategories;\n}\n\nexport interface ISearchResults {\n _query?: ISearchRequestBody;\n results: SearchResult[];\n highlights: string[];\n count?: number;\n next_batch?: string;\n pendingRequest?: Promise<ISearchResults>;\n}\n/* eslint-enable camelcase */\n",
"/*\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\n/**\n * Represents a simple Matrix namespaced value. This will assume that if a stable prefix\n * is provided that the stable prefix should be used when representing the identifier.\n */\nexport class NamespacedValue<S extends string, U extends string> {\n // Stable is optional, but one of the two parameters is required, hence the weird-looking types.\n // Goal is to to have developers explicitly say there is no stable value (if applicable).\n public constructor(public readonly stable: S | null | undefined, public readonly unstable?: U) {\n if (!this.unstable && !this.stable) {\n throw new Error(\"One of stable or unstable values must be supplied\");\n }\n }\n\n public get name(): U | S {\n if (this.stable) {\n return this.stable;\n }\n return this.unstable;\n }\n\n public get altName(): U | S | null {\n if (!this.stable) {\n return null;\n }\n return this.unstable;\n }\n\n public matches(val: string): boolean {\n return this.name === val || this.altName === val;\n }\n\n // this desperately wants https://github.com/microsoft/TypeScript/pull/26349 at the top level of the class\n // so we can instantiate `NamespacedValue<string, _, _>` as a default type for that namespace.\n public findIn<T>(obj: any): T {\n let val: T;\n if (this.name) {\n val = obj?.[this.name];\n }\n if (!val && this.altName) {\n val = obj?.[this.altName];\n }\n return val;\n }\n\n public includedIn(arr: any[]): boolean {\n let included = false;\n if (this.name) {\n included = arr.includes(this.name);\n }\n if (!included && this.altName) {\n included = arr.includes(this.altName);\n }\n return included;\n }\n}\n\n/**\n * Represents a namespaced value which prioritizes the unstable value over the stable\n * value.\n */\nexport class UnstableValue<S extends string, U extends string> extends NamespacedValue<S, U> {\n // Note: Constructor difference is that `unstable` is *required*.\n public constructor(stable: S, unstable: U) {\n super(stable, unstable);\n if (!this.unstable) {\n throw new Error(\"Unstable value must be supplied\");\n }\n }\n\n public get name(): U {\n return this.unstable;\n }\n\n public get altName(): S {\n return this.stable;\n }\n}\n",
"/*\nCopyright 2015, 2016 OpenMarket Ltd\nCopyright 2017 Vector Creations Ltd\nCopyright 2017 New Vector Ltd\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 { EventEmitter } from \"events\";\n\nexport class ReEmitter {\n private target: EventEmitter;\n\n constructor(target: EventEmitter) {\n this.target = target;\n }\n\n reEmit(source: EventEmitter, eventNames: string[]) {\n for (const eventName of eventNames) {\n // We include the source as the last argument for event handlers which may need it,\n // such as read receipt listeners on the client class which won't have the context\n // of the room.\n const forSource = (...args) => {\n // EventEmitter special cases 'error' to make the emit function throw if no\n // handler is attached, which sort of makes sense for making sure that something\n // handles an error, but for re-emitting, there could be a listener on the original\n // source object so the test doesn't really work. We *could* try to replicate the\n // same logic and throw if there is no listener on either the source or the target,\n // but this behaviour is fairly undesireable for us anyway: the main place we throw\n // 'error' events is for calls, where error events are usually emitted some time\n // later by a different part of the code where 'emit' throwing because the app hasn't\n // added an error handler isn't terribly helpful. (A better fix in retrospect may\n // have been to just avoid using the event name 'error', but backwards compat...)\n if (eventName === 'error' && this.target.listenerCount('error') === 0) return;\n this.target.emit(eventName, ...args, source);\n };\n source.on(eventName, forSource);\n }\n }\n}\n",
"/*\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\n/** @module auto-discovery */\n\nimport { logger } from './logger';\nimport { URL as NodeURL } from \"url\";\n\n// Dev note: Auto discovery is part of the spec.\n// See: https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery\n\n/**\n * Description for what an automatically discovered client configuration\n * would look like. Although this is a class, it is recommended that it\n * be treated as an interface definition rather than as a class.\n *\n * Additional properties than those defined here may be present, and\n * should follow the Java package naming convention.\n */\nclass DiscoveredClientConfig { // eslint-disable-line no-unused-vars\n // Dev note: this is basically a copy/paste of the .well-known response\n // object as defined in the spec. It does have additional information,\n // however. Overall, this exists to serve as a place for documentation\n // and not functionality.\n // See https://matrix.org/docs/spec/client_server/r0.4.0.html#get-well-known-matrix-client\n\n constructor() {\n /**\n * The homeserver configuration the client should use. This will\n * always be present on the object.\n * @type {{state: string, base_url: string}} The configuration.\n */\n this[\"m.homeserver\"] = {\n /**\n * The lookup result state. If this is anything other than\n * AutoDiscovery.SUCCESS then base_url may be falsey. Additionally,\n * if this is not AutoDiscovery.SUCCESS then the client should\n * assume the other properties in the client config (such as\n * the identity server configuration) are not valid.\n */\n state: AutoDiscovery.PROMPT,\n\n /**\n * If the state is AutoDiscovery.FAIL_ERROR or .FAIL_PROMPT\n * then this will contain a human-readable (English) message\n * for what went wrong. If the state is none of those previously\n * mentioned, this will be falsey.\n */\n error: \"Something went wrong\",\n\n /**\n * The base URL clients should use to talk to the homeserver,\n * particularly for the login process. May be falsey if the\n * state is not AutoDiscovery.SUCCESS.\n */\n base_url: \"https://matrix.org\",\n };\n\n /**\n * The identity server configuration the client should use. This\n * will always be present on teh object.\n * @type {{state: string, base_url: string}} The configuration.\n */\n this[\"m.identity_server\"] = {\n /**\n * The lookup result state. If this is anything other than\n * AutoDiscovery.SUCCESS then base_url may be falsey.\n */\n state: AutoDiscovery.PROMPT,\n\n /**\n * The base URL clients should use for interacting with the\n * identity server. May be falsey if the state is not\n * AutoDiscovery.SUCCESS.\n */\n base_url: \"https://vector.im\",\n };\n }\n}\n\n/**\n * Utilities for automatically discovery resources, such as homeservers\n * for users to log in to.\n */\nexport class AutoDiscovery {\n // Dev note: the constants defined here are related to but not\n // exactly the same as those in the spec. This is to hopefully\n // translate the m
"/*\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 * as matrixcs from \"./matrix\";\nimport request from \"browser-request\";\nimport queryString from \"qs\";\n\nmatrixcs.request(function(opts, fn) {\n // We manually fix the query string for browser-request because\n // it doesn't correctly handle cases like ?via=one&via=two. Instead\n // we mimic `request`'s query string interface to make it all work\n // as expected.\n // browser-request will happily take the constructed string as the\n // query string without trying to modify it further.\n opts.qs = queryString.stringify(opts.qs || {}, opts.qsStringifyOptions);\n return request(opts, fn);\n});\n\n// just *accessing* indexedDB throws an exception in firefox with\n// indexeddb disabled.\nlet indexedDB;\ntry {\n indexedDB = global.indexedDB;\n} catch (e) {}\n\n// if our browser (appears to) support indexeddb, use an indexeddb crypto store.\nif (indexedDB) {\n matrixcs.setCryptoStoreFactory(\n function() {\n return new matrixcs.IndexedDBCryptoStore(\n indexedDB, \"matrix-js-sdk:crypto\",\n );\n },\n );\n}\n\n// We export 3 things to make browserify happy as well as downstream projects.\n// It's awkward, but required.\nexport * from \"./matrix\";\nexport default matrixcs; // keep export for browserify package deps\nglobal.matrixcs = matrixcs;\n",
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2015-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 * This is an internal module. See {@link MatrixClient} for the public class.\n * @module client\n */\n\nimport { EventEmitter } from \"events\";\nimport { ISyncStateData, SyncApi } from \"./sync\";\nimport { EventStatus, IContent, IDecryptOptions, IEvent, MatrixEvent } from \"./models/event\";\nimport { StubStore } from \"./store/stub\";\nimport { createNewMatrixCall, MatrixCall, ConstraintsType, getUserMediaContraints } from \"./webrtc/call\";\nimport { Filter, IFilterDefinition } from \"./filter\";\nimport { CallEventHandler } from './webrtc/callEventHandler';\nimport * as utils from './utils';\nimport { sleep } from './utils';\nimport { Group } from \"./models/group\";\nimport { Direction, EventTimeline } from \"./models/event-timeline\";\nimport { PushAction, PushProcessor } from \"./pushprocessor\";\nimport { AutoDiscovery } from \"./autodiscovery\";\nimport * as olmlib from \"./crypto/olmlib\";\nimport { decodeBase64, encodeBase64 } from \"./crypto/olmlib\";\nimport { ReEmitter } from './ReEmitter';\nimport { IRoomEncryption, RoomList } from './crypto/RoomList';\nimport { logger } from './logger';\nimport { SERVICE_TYPES } from './service-types';\nimport {\n MatrixError,\n MatrixHttpApi,\n PREFIX_IDENTITY_V2,\n PREFIX_MEDIA_R0,\n PREFIX_R0,\n PREFIX_UNSTABLE,\n retryNetworkOperation,\n} from \"./http-api\";\nimport {\n Crypto,\n fixBackupKey,\n IBootstrapCrossSigningOpts,\n ICheckOwnCrossSigningTrustOpts,\n IMegolmSessionData,\n isCryptoAvailable,\n VerificationMethod,\n} from './crypto';\nimport { DeviceInfo, IDevice } from \"./crypto/deviceinfo\";\nimport { decodeRecoveryKey } from './crypto/recoverykey';\nimport { keyFromAuthData } from './crypto/key_passphrase';\nimport { User } from \"./models/user\";\nimport { getHttpUriForMxc } from \"./content-repo\";\nimport { SearchResult } from \"./models/search-result\";\nimport {\n DEHYDRATION_ALGORITHM,\n IDehydratedDevice,\n IDehydratedDeviceKeyInfo,\n IDeviceKeys,\n IOneTimeKey,\n} from \"./crypto/dehydration\";\nimport {\n IKeyBackupInfo,\n IKeyBackupPrepareOpts,\n IKeyBackupRestoreOpts,\n IKeyBackupRestoreResult,\n IKeyBackupSession,\n} from \"./crypto/keybackup\";\nimport { IIdentityServerProvider } from \"./@types/IIdentityServerProvider\";\nimport type Request from \"request\";\nimport { MatrixScheduler } from \"./scheduler\";\nimport { ICryptoCallbacks, IMinimalEvent, IRoomEvent, IStateEvent, NotificationCountType } from \"./matrix\";\nimport {\n CrossSigningKey,\n IAddSecretStorageKeyOpts,\n ICreateSecretStorageOpts,\n IEncryptedEventInfo,\n IImportRoomKeysOpts,\n IRecoveryKey,\n ISecretStorageKeyInfo,\n} from \"./crypto/api\";\nimport { SyncState } from \"./sync.api\";\nimport { EventTimelineSet } from \"./models/event-timeline-set\";\nimport { VerificationRequest } from \"./crypto/verification/request/VerificationRequest\";\nimport { Base as Verification } from \"./crypto/verification/Base\";\nimport * as ContentHelpers from \"./content-helpers\";\nimport { CrossSigningInfo, DeviceTrustLevel, ICacheCallbacks, UserTrustLevel } from \"./crypto/CrossSigning\";\nimport { Room } from \"./models/room\";\nimport {\n IAddThreePidOnlyBody,\n IBindThreePidBody,\n ICreateRoomOpts,\n IEventSearchOpts,\n IGuestAccessOpts,\n IJoinRoomOpts,\n IPaginateOpts,\n IPresenceOpts,\n IRedactOpts,\n IRoomDirectoryOptions,\n ISearchOpts,\n ISendEvent
"/*\nCopyright 2018 New Vector Ltd\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/** @module ContentHelpers */\n\nimport { MsgType } from \"./@types/event\";\n\n/**\n * Generates the content for a HTML Message event\n * @param {string} body the plaintext body of the message\n * @param {string} htmlBody the HTML representation of the message\n * @returns {{msgtype: string, format: string, body: string, formatted_body: string}}\n */\nexport function makeHtmlMessage(body: string, htmlBody: string) {\n return {\n msgtype: MsgType.Text,\n format: \"org.matrix.custom.html\",\n body: body,\n formatted_body: htmlBody,\n };\n}\n\n/**\n * Generates the content for a HTML Notice event\n * @param {string} body the plaintext body of the notice\n * @param {string} htmlBody the HTML representation of the notice\n * @returns {{msgtype: string, format: string, body: string, formatted_body: string}}\n */\nexport function makeHtmlNotice(body: string, htmlBody: string) {\n return {\n msgtype: MsgType.Notice,\n format: \"org.matrix.custom.html\",\n body: body,\n formatted_body: htmlBody,\n };\n}\n\n/**\n * Generates the content for a HTML Emote event\n * @param {string} body the plaintext body of the emote\n * @param {string} htmlBody the HTML representation of the emote\n * @returns {{msgtype: string, format: string, body: string, formatted_body: string}}\n */\nexport function makeHtmlEmote(body: string, htmlBody: string) {\n return {\n msgtype: MsgType.Emote,\n format: \"org.matrix.custom.html\",\n body: body,\n formatted_body: htmlBody,\n };\n}\n\n/**\n * Generates the content for a Plaintext Message event\n * @param {string} body the plaintext body of the emote\n * @returns {{msgtype: string, body: string}}\n */\nexport function makeTextMessage(body: string) {\n return {\n msgtype: MsgType.Text,\n body: body,\n };\n}\n\n/**\n * Generates the content for a Plaintext Notice event\n * @param {string} body the plaintext body of the notice\n * @returns {{msgtype: string, body: string}}\n */\nexport function makeNotice(body: string) {\n return {\n msgtype: MsgType.Notice,\n body: body,\n };\n}\n\n/**\n * Generates the content for a Plaintext Emote event\n * @param {string} body the plaintext body of the emote\n * @returns {{msgtype: string, body: string}}\n */\nexport function makeEmoteMessage(body: string) {\n return {\n msgtype: MsgType.Emote,\n body: body,\n };\n}\n",
"/*\nCopyright 2015 - 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 * @module content-repo\n */\n\nimport * as utils from \"./utils\";\n\n/**\n * Get the HTTP URL for an MXC URI.\n * @param {string} baseUrl The base homeserver url which has a content repo.\n * @param {string} mxc The mxc:// URI.\n * @param {Number} width The desired width of the thumbnail.\n * @param {Number} height The desired height of the thumbnail.\n * @param {string} resizeMethod The thumbnail resize method to use, either\n * \"crop\" or \"scale\".\n * @param {Boolean} allowDirectLinks If true, return any non-mxc URLs\n * directly. Fetching such URLs will leak information about the user to\n * anyone they share a room with. If false, will return the emptry string\n * for such URLs.\n * @return {string} The complete URL to the content.\n */\nexport function getHttpUriForMxc(\n baseUrl: string,\n mxc: string,\n width: number,\n height: number,\n resizeMethod: string,\n allowDirectLinks = false,\n): string {\n if (typeof mxc !== \"string\" || !mxc) {\n return '';\n }\n if (mxc.indexOf(\"mxc://\") !== 0) {\n if (allowDirectLinks) {\n return mxc;\n } else {\n return '';\n }\n }\n let serverAndMediaId = mxc.slice(6); // strips mxc://\n let prefix = \"/_matrix/media/r0/download/\";\n const params = {};\n\n if (width) {\n params[\"width\"] = Math.round(width);\n }\n if (height) {\n params[\"height\"] = Math.round(height);\n }\n if (resizeMethod) {\n params[\"method\"] = resizeMethod;\n }\n if (Object.keys(params).length > 0) {\n // these are thumbnailing params so they probably want the\n // thumbnailing API...\n prefix = \"/_matrix/media/r0/thumbnail/\";\n }\n\n const fragmentOffset = serverAndMediaId.indexOf(\"#\");\n let fragment = \"\";\n if (fragmentOffset >= 0) {\n fragment = serverAndMediaId.substr(fragmentOffset);\n serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset);\n }\n\n const urlParams = (Object.keys(params).length === 0 ? \"\" : (\"?\" + utils.encodeParams(params)));\n return baseUrl + prefix + serverAndMediaId + urlParams + fragment;\n}\n",
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2019 - 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 * Cross signing methods\n * @module crypto/CrossSigning\n */\n\nimport { EventEmitter } from 'events';\n\nimport { decodeBase64, encodeBase64, pkSign, pkVerify } from './olmlib';\nimport { logger } from '../logger';\nimport { IndexedDBCryptoStore } from '../crypto/store/indexeddb-crypto-store';\nimport { decryptAES, encryptAES } from './aes';\nimport { PkSigning } from \"@matrix-org/olm\";\nimport { DeviceInfo } from \"./deviceinfo\";\nimport { SecretStorage } from \"./SecretStorage\";\nimport { ICrossSigningKey, ISignedKey, MatrixClient } from \"../client\";\nimport { OlmDevice } from \"./OlmDevice\";\nimport { ICryptoCallbacks } from \"../matrix\";\nimport { ISignatures } from \"../@types/signed\";\nimport { CryptoStore } from \"./store/base\";\n\nconst KEY_REQUEST_TIMEOUT_MS = 1000 * 60;\n\nfunction publicKeyFromKeyInfo(keyInfo: ICrossSigningKey): string {\n // `keys` is an object with { [`ed25519:${pubKey}`]: pubKey }\n // We assume only a single key, and we want the bare form without type\n // prefix, so we select the values.\n return Object.values(keyInfo.keys)[0];\n}\n\nexport interface ICacheCallbacks {\n getCrossSigningKeyCache?(type: string, expectedPublicKey?: string): Promise<Uint8Array>;\n storeCrossSigningKeyCache?(type: string, key: Uint8Array): Promise<void>;\n}\n\nexport interface ICrossSigningInfo {\n keys: Record<string, ICrossSigningKey>;\n firstUse: boolean;\n crossSigningVerifiedBefore: boolean;\n}\n\nexport class CrossSigningInfo extends EventEmitter {\n public keys: Record<string, ICrossSigningKey> = {};\n public firstUse = true;\n // This tracks whether we've ever verified this user with any identity.\n // When you verify a user, any devices online at the time that receive\n // the verifying signature via the homeserver will latch this to true\n // and can use it in the future to detect cases where the user has\n // become unverified later for any reason.\n private crossSigningVerifiedBefore = false;\n\n /**\n * Information about a user's cross-signing keys\n *\n * @class\n *\n * @param {string} userId the user that the information is about\n * @param {object} callbacks Callbacks used to interact with the app\n * Requires getCrossSigningKey and saveCrossSigningKeys\n * @param {object} cacheCallbacks Callbacks used to interact with the cache\n */\n constructor(\n public readonly userId: string,\n private callbacks: ICryptoCallbacks = {},\n private cacheCallbacks: ICacheCallbacks = {},\n ) {\n super();\n }\n\n public static fromStorage(obj: ICrossSigningInfo, userId: string): CrossSigningInfo {\n const res = new CrossSigningInfo(userId);\n for (const prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n res[prop] = obj[prop];\n }\n }\n return res;\n }\n\n public toStorage(): ICrossSigningInfo {\n return {\n keys: this.keys,\n firstUse: this.firstUse,\n crossSigningVerifiedBefore: this.crossSigningVerifiedBefore,\n };\n }\n\n /**\n * Calls the app callback to ask for a private key\n *\n * @param {string} type The key type (\"master\", \"self_signing\", or \"user_signing\")\n * @param {string} expectedPubkey The matching public key or undefined to use\n * the stored public key for the given key type.\n * @returns {A
"/*\nCopyright 2017 - 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 * @module crypto/DeviceList\n *\n * Manages the list of other users' devices\n */\n\nimport { EventEmitter } from 'events';\n\nimport { logger } from '../logger';\nimport { DeviceInfo, IDevice } from './deviceinfo';\nimport { CrossSigningInfo, ICrossSigningInfo } from './CrossSigning';\nimport * as olmlib from './olmlib';\nimport { IndexedDBCryptoStore } from './store/indexeddb-crypto-store';\nimport { chunkPromises, defer, IDeferred, sleep } from '../utils';\nimport { MatrixClient } from \"../client\";\nimport { OlmDevice } from \"./OlmDevice\";\nimport { CryptoStore } from \"./store/base\";\n\n/* State transition diagram for DeviceList.deviceTrackingStatus\n *\n * |\n * stopTrackingDeviceList V\n * +---------------------> NOT_TRACKED\n * | |\n * +<--------------------+ | startTrackingDeviceList\n * | | V\n * | +-------------> PENDING_DOWNLOAD <--------------------+-+\n * | | ^ | | |\n * | | restart download | | start download | | invalidateUserDeviceList\n * | | client failed | | | |\n * | | | V | |\n * | +------------ DOWNLOAD_IN_PROGRESS -------------------+ |\n * | | | |\n * +<-------------------+ | download successful |\n * ^ V |\n * +----------------------- UP_TO_DATE ------------------------+\n */\n\n// constants for DeviceList.deviceTrackingStatus\nexport enum TrackingStatus {\n NotTracked,\n PendingDownload,\n DownloadInProgress,\n UpToDate,\n}\n\nexport type DeviceInfoMap = Record<string, Record<string, DeviceInfo>>;\n\n/**\n * @alias module:crypto/DeviceList\n */\nexport class DeviceList extends EventEmitter {\n private devices: { [userId: string]: { [deviceId: string]: IDevice } } = {};\n\n public crossSigningInfo: { [userId: string]: ICrossSigningInfo } = {};\n\n // map of identity keys to the user who owns it\n private userByIdentityKey: Record<string, string> = {};\n\n // which users we are tracking device status for.\n private deviceTrackingStatus: { [userId: string]: TrackingStatus } = {}; // loaded from storage in load()\n\n // The 'next_batch' sync token at the point the data was written,\n // ie. a token representing the point immediately after the\n // moment represented by the snapshot in the db.\n private syncToken: string = null;\n\n private keyDownloadsInProgressByUser: { [userId: string]: Promise<void> } = {};\n\n // Set whenever changes are made other than setting the sync token\n private dirty = false;\n\n // Promise resolved when device data is saved\n private savePromise: Promise<boolean> = null;\n // Function that resolves the save promise\n private resolveSavePromise: (saved: boolean) => void = null;\n // The time the save is scheduled for\n private savePromiseTime: number = null;\n // The timer used to delay the save\n private saveTimer: number = null;\n // True if we have fetched data from the server or loaded a non-empty\n // set of device data from the store\n private hasFetched: boolean = null;\n\n private readonly serialiser: DeviceListUpdateSerialiser;\n\n constructor(\n baseApis:
"/*\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 { logger } from \"../logger\";\nimport { MatrixEvent } from \"../models/event\";\nimport { EventEmitter } from \"events\";\nimport { createCryptoStoreCacheCallbacks, ICacheCallbacks } from \"./CrossSigning\";\nimport { IndexedDBCryptoStore } from './store/indexeddb-crypto-store';\nimport { PREFIX_UNSTABLE } from \"../http-api\";\nimport { Crypto, IBootstrapCrossSigningOpts } from \"./index\";\nimport {\n CrossSigningKeys,\n ICrossSigningKey,\n ICryptoCallbacks,\n ISignedKey,\n KeySignatures,\n} from \"../matrix\";\nimport { ISecretStorageKeyInfo } from \"./api\";\nimport { IKeyBackupInfo } from \"./keybackup\";\n\ninterface ICrossSigningKeys {\n authUpload: IBootstrapCrossSigningOpts[\"authUploadDeviceSigningKeys\"];\n keys: Record<string, ICrossSigningKey>;\n}\n\n/**\n * Builds an EncryptionSetupOperation by calling any of the add.. methods.\n * Once done, `buildOperation()` can be called which allows to apply to operation.\n *\n * This is used as a helper by Crypto to keep track of all the network requests\n * and other side-effects of bootstrapping, so it can be applied in one go (and retried in the future)\n * Also keeps track of all the private keys created during bootstrapping, so we don't need to prompt for them\n * more than once.\n */\nexport class EncryptionSetupBuilder {\n public readonly accountDataClientAdapter: AccountDataClientAdapter;\n public readonly crossSigningCallbacks: CrossSigningCallbacks;\n public readonly ssssCryptoCallbacks: SSSSCryptoCallbacks;\n\n private crossSigningKeys: ICrossSigningKeys = null;\n private keySignatures: KeySignatures = null;\n private keyBackupInfo: IKeyBackupInfo = null;\n private sessionBackupPrivateKey: Uint8Array;\n\n /**\n * @param {Object.<String, MatrixEvent>} accountData pre-existing account data, will only be read, not written.\n * @param {CryptoCallbacks} delegateCryptoCallbacks crypto callbacks to delegate to if the key isn't in cache yet\n */\n constructor(accountData: Record<string, MatrixEvent>, delegateCryptoCallbacks: ICryptoCallbacks) {\n this.accountDataClientAdapter = new AccountDataClientAdapter(accountData);\n this.crossSigningCallbacks = new CrossSigningCallbacks();\n this.ssssCryptoCallbacks = new SSSSCryptoCallbacks(delegateCryptoCallbacks);\n }\n\n /**\n * Adds new cross-signing public keys\n *\n * @param {function} authUpload Function called to await an interactive auth\n * flow when uploading device signing keys.\n * Args:\n * {function} A function that makes the request requiring auth. Receives\n * the auth data as an object. Can be called multiple times, first with\n * an empty authDict, to obtain the flows.\n * @param {Object} keys the new keys\n */\n public addCrossSigningKeys(authUpload: ICrossSigningKeys[\"authUpload\"], keys: ICrossSigningKeys[\"keys\"]): void {\n this.crossSigningKeys = { authUpload, keys };\n }\n\n /**\n * Adds the key backup info to be updated on the server\n *\n * Used either to create a new key backup, or add signatures\n * from the new MSK.\n *\n * @param {Object} keyBackupInfo as received from/sent to the server\n */\n public addSessionBackup(keyBackupInfo: IKeyBackupInfo): void {\n this.keyBackupInfo = keyBackupInfo;\n }\n\n /**\n * Adds the session backup private key to be updated in the local cache\n *\n
"/*\nCopyright 2016 OpenMarket Ltd\nCopyright 2017, 2019 New Vector Ltd\nCopyright 2019, 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\nimport { logger } from '../logger';\nimport { IndexedDBCryptoStore } from './store/indexeddb-crypto-store';\nimport * as algorithms from './algorithms';\n\n// The maximum size of an event is 65K, and we base64 the content, so this is a\n// reasonable approximation to the biggest plaintext we can encrypt.\nconst MAX_PLAINTEXT_LENGTH = 65536 * 3 / 4;\n\nfunction checkPayloadLength(payloadString) {\n if (payloadString === undefined) {\n throw new Error(\"payloadString undefined\");\n }\n\n if (payloadString.length > MAX_PLAINTEXT_LENGTH) {\n // might as well fail early here rather than letting the olm library throw\n // a cryptic memory allocation error.\n //\n // Note that even if we manage to do the encryption, the message send may fail,\n // because by the time we've wrapped the ciphertext in the event object, it may\n // exceed 65K. But at least we won't just fail with \"abort()\" in that case.\n const err = new Error(\"Message too long (\" + payloadString.length + \" bytes). \" +\n \"The maximum for an encrypted message is \" +\n MAX_PLAINTEXT_LENGTH + \" bytes.\");\n // TODO: [TypeScript] We should have our own error types\n err.data = {\n errcode: \"M_TOO_LARGE\",\n error: \"Payload too large for encrypted message\",\n };\n throw err;\n }\n}\n\n/**\n * The type of object we use for importing and exporting megolm session data.\n *\n * @typedef {Object} module:crypto/OlmDevice.MegolmSessionData\n * @property {String} sender_key Sender's Curve25519 device key\n * @property {String[]} forwarding_curve25519_key_chain Devices which forwarded\n * this session to us (normally empty).\n * @property {Object<string, string>} sender_claimed_keys Other keys the sender claims.\n * @property {String} room_id Room this session is used in\n * @property {String} session_id Unique id for the session\n * @property {String} session_key Base64'ed key data\n */\n\n/**\n * Manages the olm cryptography functions. Each OlmDevice has a single\n * OlmAccount and a number of OlmSessions.\n *\n * Accounts and sessions are kept pickled in the cryptoStore.\n *\n * @constructor\n * @alias module:crypto/OlmDevice\n *\n * @param {Object} cryptoStore A store for crypto data\n *\n * @property {string} deviceCurve25519Key Curve25519 key for the account\n * @property {string} deviceEd25519Key Ed25519 key for the account\n */\nexport function OlmDevice(cryptoStore) {\n this._cryptoStore = cryptoStore;\n this._pickleKey = \"DEFAULT_KEY\";\n\n // don't know these until we load the account from storage in init()\n this.deviceCurve25519Key = null;\n this.deviceEd25519Key = null;\n this._maxOneTimeKeys = null;\n\n // we don't bother stashing outboundgroupsessions in the cryptoStore -\n // instead we keep them here.\n this._outboundGroupSessionStore = {};\n\n // Store a set of decrypted message indexes for each group session.\n // This partially mitigates a replay attack where a MITM resends a group\n // message into the room.\n //\n // When we decrypt a message and the message index matches a previously\n // decrypted message, one possible cause of that is that we are decrypting\n // the same event, and may not indicate an actual replay attack. For\n // example, thi
"/*\nCopyright 2017 - 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 { MatrixClient } from \"../client\";\nimport { IRoomKeyRequestBody, IRoomKeyRequestRecipient } from \"./index\";\nimport { CryptoStore, OutgoingRoomKeyRequest } from './store/base';\nimport { EventType } from \"../@types/event\";\n\n/**\n * Internal module. Management of outgoing room key requests.\n *\n * See https://docs.google.com/document/d/1m4gQkcnJkxNuBmb5NoFCIadIY-DyqqNAS3lloE73BlQ\n * for draft documentation on what we're supposed to be implementing here.\n *\n * @module\n */\n\n// delay between deciding we want some keys, and sending out the request, to\n// allow for (a) it turning up anyway, (b) grouping requests together\nconst SEND_KEY_REQUESTS_DELAY_MS = 500;\n\n/** possible states for a room key request\n *\n * The state machine looks like:\n *\n * | (cancellation sent)\n * | .-------------------------------------------------.\n * | | |\n * V V (cancellation requested) |\n * UNSENT -----------------------------+ |\n * | | |\n * | | |\n * | (send successful) | CANCELLATION_PENDING_AND_WILL_RESEND\n * V | Λ\n * SENT | |\n * |-------------------------------- | --------------'\n * | | (cancellation requested with intent\n * | | to resend the original request)\n * | |\n * | (cancellation requested) |\n * V |\n * CANCELLATION_PENDING |\n * | |\n * | (cancellation sent) |\n * V |\n * (deleted) <---------------------------+\n *\n * @enum {number}\n */\nexport enum RoomKeyRequestState {\n /** request not yet sent */\n Unsent,\n /** request sent, awaiting reply */\n Sent,\n /** reply received, cancellation not yet sent */\n CancellationPending,\n /**\n * Cancellation not yet sent and will transition to UNSENT instead of\n * being deleted once the cancellation has been sent.\n */\n CancellationPendingAndWillResend,\n}\n\nexport class OutgoingRoomKeyRequestManager {\n // handle for the delayed call to sendOutgoingRoomKeyRequests. Non-null\n // if the callback has been set, or if it is still running.\n private sendOutgoingRoomKeyRequestsTimer: number = null;\n\n // sanity check to ensure that we don't end up with two concurrent runs\n // of sendOutgoingRoomKeyRequests\n private sendOutgoingRoomKeyRequestsRunning = false;\n\n private clientRunning = false;\n\n constructor(\n private readonly baseApis: MatrixClient,\n private readonly deviceId: string,\n private readonly cryptoStore: CryptoStore,\n ) {}\n\n /**\n * Called when the client is started. Sets background processes running.\n */\n public start(): void {\n this.clientRunning = true;\n }\n\n /**\n * Called when the client is stopped. Stops any running background processes.\n */\n public stop(): void {\n logger.log('stopping OutgoingRoomKeyRequestManager');\n // stop the timer on t
"/*\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 * @module crypto/RoomList\n *\n * Manages the list of encrypted rooms\n */\n\nimport { CryptoStore } from './store/base';\nimport { IndexedDBCryptoStore } from './store/indexeddb-crypto-store';\n\n/* eslint-disable camelcase */\nexport interface IRoomEncryption {\n algorithm: string;\n rotation_period_ms?: number;\n rotation_period_msgs?: number;\n}\n/* eslint-enable camelcase */\n\n/**\n * @alias module:crypto/RoomList\n */\nexport class RoomList {\n // Object of roomId -> room e2e info object (body of the m.room.encryption event)\n private roomEncryption: Record<string, IRoomEncryption> = {};\n\n constructor(private readonly cryptoStore: CryptoStore) {}\n\n public async init(): Promise<void> {\n await this.cryptoStore.doTxn(\n 'readwrite', [IndexedDBCryptoStore.STORE_ROOMS], (txn) => {\n this.cryptoStore.getEndToEndRooms(txn, (result) => {\n this.roomEncryption = result;\n });\n },\n );\n }\n\n public getRoomEncryption(roomId: string): IRoomEncryption {\n return this.roomEncryption[roomId] || null;\n }\n\n public isRoomEncrypted(roomId: string): boolean {\n return Boolean(this.getRoomEncryption(roomId));\n }\n\n public async setRoomEncryption(roomId: string, roomInfo: IRoomEncryption): Promise<void> {\n // important that this happens before calling into the store\n // as it prevents the Crypto::setRoomEncryption from calling\n // this twice for consecutive m.room.encryption events\n this.roomEncryption[roomId] = roomInfo;\n await this.cryptoStore.doTxn(\n 'readwrite', [IndexedDBCryptoStore.STORE_ROOMS], (txn) => {\n this.cryptoStore.storeEndToEndRoom(roomId, roomInfo, txn);\n },\n );\n }\n}\n",
"/*\nCopyright 2019 - 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 * as olmlib from './olmlib';\nimport { randomString } from '../randomstring';\nimport { encryptAES, decryptAES, IEncryptedPayload, calculateKeyCheck } from './aes';\nimport { encodeBase64 } from \"./olmlib\";\nimport { ICryptoCallbacks, MatrixClient, MatrixEvent } from '../matrix';\nimport { IAddSecretStorageKeyOpts, ISecretStorageKeyInfo } from './api';\nimport { EventEmitter } from 'stream';\n\nexport const SECRET_STORAGE_ALGORITHM_V1_AES = \"m.secret_storage.v1.aes-hmac-sha2\";\n\n// Some of the key functions use a tuple and some use an object...\nexport type SecretStorageKeyTuple = [keyId: string, keyInfo: ISecretStorageKeyInfo];\nexport type SecretStorageKeyObject = {keyId: string, keyInfo: ISecretStorageKeyInfo};\n\nexport interface ISecretRequest {\n requestId: string;\n promise: Promise<string>;\n cancel: (reason: string) => void;\n}\n\nexport interface IAccountDataClient extends EventEmitter {\n // Subset of MatrixClient (which also uses any for the event content)\n getAccountDataFromServer: (eventType: string) => Promise<Record<string, any>>;\n getAccountData: (eventType: string) => MatrixEvent;\n setAccountData: (eventType: string, content: any) => Promise<{}>;\n}\n\ninterface ISecretRequestInternal {\n name: string;\n devices: string[];\n resolve: (reason: string) => void;\n reject: (error: Error) => void;\n}\n\ninterface IDecryptors {\n encrypt: (plaintext: string) => Promise<IEncryptedPayload>;\n decrypt: (ciphertext: IEncryptedPayload) => Promise<string>;\n}\n\n/**\n * Implements Secure Secret Storage and Sharing (MSC1946)\n * @module crypto/SecretStorage\n */\nexport class SecretStorage {\n private requests = new Map<string, ISecretRequestInternal>();\n\n // In it's pure javascript days, this was relying on some proper Javascript-style\n // type-abuse where sometimes we'd pass in a fake client object with just the account\n // data methods implemented, which is all this class needs unless you use the secret\n // sharing code, so it was fine. As a low-touch TypeScript migration, this now has\n // an extra, optional param for a real matrix client, so you can not pass it as long\n // as you don't request any secrets.\n // A better solution would probably be to split this class up into secret storage and\n // secret sharing which are really two separate things, even though they share an MSC.\n constructor(\n private readonly accountDataAdapter: IAccountDataClient,\n private readonly cryptoCallbacks: ICryptoCallbacks,\n private readonly baseApis?: MatrixClient,\n ) {}\n\n public async getDefaultKeyId(): Promise<string> {\n const defaultKey = await this.accountDataAdapter.getAccountDataFromServer(\n 'm.secret_storage.default_key',\n );\n if (!defaultKey) return null;\n return defaultKey.key;\n }\n\n public setDefaultKeyId(keyId: string): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const listener = (ev: MatrixEvent): void => {\n if (\n ev.getType() === 'm.secret_storage.default_key' &&\n ev.getContent().key === keyId\n ) {\n this.accountDataAdapter.removeListener('accountData', listener);\n resolve();\n }\n };\n this.accountDataAdapter.on('accountD
"/*\nCopyright 2020 - 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 type { BinaryLike } from \"crypto\";\n\nimport { getCrypto } from '../utils';\nimport { decodeBase64, encodeBase64 } from './olmlib';\n\nconst subtleCrypto = (typeof window !== \"undefined\" && window.crypto) ?\n (window.crypto.subtle || window.crypto.webkitSubtle) : null;\n\n// salt for HKDF, with 8 bytes of zeros\nconst zeroSalt = new Uint8Array(8);\n\nexport interface IEncryptedPayload {\n iv: string;\n ciphertext: string;\n mac: string;\n}\n\n/**\n * encrypt a string in Node.js\n *\n * @param {string} data the plaintext to encrypt\n * @param {Uint8Array} key the encryption key to use\n * @param {string} name the name of the secret\n * @param {string} ivStr the initialization vector to use\n */\nasync function encryptNode(data: string, key: Uint8Array, name: string, ivStr?: string): Promise<IEncryptedPayload> {\n const crypto = getCrypto();\n if (!crypto) {\n throw new Error(\"No usable crypto implementation\");\n }\n\n let iv;\n if (ivStr) {\n iv = decodeBase64(ivStr);\n } else {\n iv = crypto.randomBytes(16);\n\n // clear bit 63 of the IV to stop us hitting the 64-bit counter boundary\n // (which would mean we wouldn't be able to decrypt on Android). The loss\n // of a single bit of iv is a price we have to pay.\n iv[8] &= 0x7f;\n }\n\n const [aesKey, hmacKey] = deriveKeysNode(key, name);\n\n const cipher = crypto.createCipheriv(\"aes-256-ctr\", aesKey, iv);\n const ciphertext = Buffer.concat([\n cipher.update(data, \"utf8\"),\n cipher.final(),\n ]);\n\n const hmac = crypto.createHmac(\"sha256\", hmacKey)\n .update(ciphertext).digest(\"base64\");\n\n return {\n iv: encodeBase64(iv),\n ciphertext: ciphertext.toString(\"base64\"),\n mac: hmac,\n };\n}\n\n/**\n * decrypt a string in Node.js\n *\n * @param {object} data the encrypted data\n * @param {string} data.ciphertext the ciphertext in base64\n * @param {string} data.iv the initialization vector in base64\n * @param {string} data.mac the HMAC in base64\n * @param {Uint8Array} key the encryption key to use\n * @param {string} name the name of the secret\n */\nasync function decryptNode(data: IEncryptedPayload, key: Uint8Array, name: string): Promise<string> {\n const crypto = getCrypto();\n if (!crypto) {\n throw new Error(\"No usable crypto implementation\");\n }\n\n const [aesKey, hmacKey] = deriveKeysNode(key, name);\n\n const hmac = crypto.createHmac(\"sha256\", hmacKey)\n .update(Buffer.from(data.ciphertext, \"base64\"))\n .digest(\"base64\").replace(/=+$/g, '');\n\n if (hmac !== data.mac.replace(/=+$/g, '')) {\n throw new Error(`Error decrypting secret ${name}: bad MAC`);\n }\n\n const decipher = crypto.createDecipheriv(\n \"aes-256-ctr\", aesKey, decodeBase64(data.iv),\n );\n return decipher.update(data.ciphertext, \"base64\", \"utf8\")\n + decipher.final(\"utf8\");\n}\n\nfunction deriveKeysNode(key: BinaryLike, name: string): [Buffer, Buffer] {\n const crypto = getCrypto();\n const prk = crypto.createHmac(\"sha256\", zeroSalt).update(key).digest();\n\n const b = Buffer.alloc(1, 1);\n const aesKey = crypto.createHmac(\"sha256\", prk)\n .update(name, \"utf8\").update(b).digest();\n b[0] = 2;\n const hmacKey = crypto.createHmac(\"sha256\", prk)\n .update(aesKey).update(name, \"utf8\").update(b).digest();\n
"/*\nCopyright 2016 - 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 * Internal module. Defines the base classes of the encryption implementations\n *\n * @module\n */\n\nimport { MatrixClient } from \"../../client\";\nimport { Room } from \"../../models/room\";\nimport { OlmDevice } from \"../OlmDevice\";\nimport { MatrixEvent, RoomMember } from \"../..\";\nimport { Crypto, IEventDecryptionResult, IMegolmSessionData, IncomingRoomKeyRequest } from \"..\";\nimport { DeviceInfo } from \"../deviceinfo\";\nimport { IRoomEncryption } from \"../RoomList\";\n\n/**\n * map of registered encryption algorithm classes. A map from string to {@link\n * module:crypto/algorithms/base.EncryptionAlgorithm|EncryptionAlgorithm} class\n *\n * @type {Object.<string, function(new: module:crypto/algorithms/base.EncryptionAlgorithm)>}\n */\nexport const ENCRYPTION_CLASSES: Record<string, new (params: IParams) => EncryptionAlgorithm> = {};\n\ntype DecryptionClassParams = Omit<IParams, \"deviceId\" | \"config\">;\n\n/**\n * map of registered encryption algorithm classes. Map from string to {@link\n * module:crypto/algorithms/base.DecryptionAlgorithm|DecryptionAlgorithm} class\n *\n * @type {Object.<string, function(new: module:crypto/algorithms/base.DecryptionAlgorithm)>}\n */\nexport const DECRYPTION_CLASSES: Record<string, new (params: DecryptionClassParams) => DecryptionAlgorithm> = {};\n\ninterface IParams {\n userId: string;\n deviceId: string;\n crypto: Crypto;\n olmDevice: OlmDevice;\n baseApis: MatrixClient;\n roomId: string;\n config: IRoomEncryption & object;\n}\n\n/**\n * base type for encryption implementations\n *\n * @alias module:crypto/algorithms/base.EncryptionAlgorithm\n *\n * @param {object} params parameters\n * @param {string} params.userId The UserID for the local user\n * @param {string} params.deviceId The identifier for this device.\n * @param {module:crypto} params.crypto crypto core\n * @param {module:crypto/OlmDevice} params.olmDevice olm.js wrapper\n * @param {MatrixClient} baseApis base matrix api interface\n * @param {string} params.roomId The ID of the room we will be sending to\n * @param {object} params.config The body of the m.room.encryption event\n */\nexport abstract class EncryptionAlgorithm {\n protected readonly userId: string;\n protected readonly deviceId: string;\n protected readonly crypto: Crypto;\n protected readonly olmDevice: OlmDevice;\n protected readonly baseApis: MatrixClient;\n protected readonly roomId: string;\n\n constructor(params: IParams) {\n this.userId = params.userId;\n this.deviceId = params.deviceId;\n this.crypto = params.crypto;\n this.olmDevice = params.olmDevice;\n this.baseApis = params.baseApis;\n this.roomId = params.roomId;\n }\n\n /**\n * Perform any background tasks that can be done before a message is ready to\n * send, in order to speed up sending of the message.\n *\n * @param {module:models/room} room the room the event is in\n */\n public prepareToEncrypt(room: Room): void {}\n\n /**\n * Encrypt a message event\n *\n * @method module:crypto/algorithms/base.EncryptionAlgorithm.encryptMessage\n * @public\n * @abstract\n *\n * @param {module:models/room} room\n * @param {string} eventType\n * @param {object} content event content\n *\n * @return {Promise} Promise which resolves to the new event body\n */\n public abstract encryptMessage(room: Room, eventType: strin
"/*\nCopyright 2016 - 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 * @module crypto/algorithms\n */\n\nimport \"./olm\";\nimport \"./megolm\";\n\nexport * from \"./base\";\n",
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2015 - 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 * Defines m.olm encryption/decryption\n *\n * @module crypto/algorithms/megolm\n */\n\nimport { logger } from '../../logger';\nimport * as olmlib from \"../olmlib\";\nimport {\n DecryptionAlgorithm,\n DecryptionError,\n EncryptionAlgorithm,\n registerAlgorithm,\n UnknownDeviceError,\n} from \"./base\";\nimport { WITHHELD_MESSAGES } from '../OlmDevice';\nimport { Room } from '../../models/room';\nimport { DeviceInfo } from \"../deviceinfo\";\nimport { IOlmSessionResult } from \"../olmlib\";\nimport { DeviceInfoMap } from \"../DeviceList\";\nimport { MatrixEvent } from \"../..\";\nimport { IEventDecryptionResult, IMegolmSessionData, IncomingRoomKeyRequest } from \"../index\";\n\n// determine whether the key can be shared with invitees\nexport function isRoomSharedHistory(room: Room): boolean {\n const visibilityEvent = room?.currentState?.getStateEvents(\"m.room.history_visibility\", \"\");\n // NOTE: if the room visibility is unset, it would normally default to\n // \"world_readable\".\n // (https://spec.matrix.org/unstable/client-server-api/#server-behaviour-5)\n // But we will be paranoid here, and treat it as a situation where the room\n // is not shared-history\n const visibility = visibilityEvent?.getContent()?.history_visibility;\n return [\"world_readable\", \"shared\"].includes(visibility);\n}\n\ninterface IBlockedDevice {\n code: string;\n reason: string;\n deviceInfo: DeviceInfo;\n}\n\ninterface IBlockedMap {\n [userId: string]: {\n [deviceId: string]: IBlockedDevice;\n };\n}\n\nexport interface IOlmDevice<T = DeviceInfo> {\n userId: string;\n deviceInfo: T;\n}\n\n/* eslint-disable camelcase */\ninterface IOutboundGroupSessionKey {\n chain_index: number;\n key: string;\n}\n\ninterface IMessage {\n type: string;\n content: {\n algorithm: string;\n room_id: string;\n sender_key?: string;\n sender_claimed_ed25519_key?: string;\n session_id: string;\n session_key: string;\n chain_index: number;\n forwarding_curve25519_key_chain?: string[];\n \"org.matrix.msc3061.shared_history\": boolean;\n };\n}\n\ninterface IKeyForwardingMessage extends IMessage {\n type: \"m.forwarded_room_key\";\n}\n\ninterface IPayload extends Partial<IMessage> {\n code?: string;\n reason?: string;\n room_id?: string;\n session_id?: string;\n algorithm?: string;\n sender_key?: string;\n}\n/* eslint-enable camelcase */\n\n/**\n * @private\n * @constructor\n *\n * @param {string} sessionId\n * @param {boolean} sharedHistory whether the session can be freely shared with\n * other group members, according to the room history visibility settings\n *\n * @property {string} sessionId\n * @property {Number} useCount number of times this session has been used\n * @property {Number} creationTime when the session was created (ms since the epoch)\n *\n * @property {object} sharedWithDevices\n * devices with which we have shared the session key\n * userId -> {deviceId -> msgindex}\n */\nclass OutboundSessionInfo {\n public useCount = 0;\n public creationTime: number;\n public sharedWithDevices: Record<string, Record<string, number>> = {};\n public blockedDevicesNotified: Record<string, Record<string, boolean>> = {};\n\n constructor(public readonly sessionId: string, public readonly sharedHistory = false) {\n this.creationTime = new Date().getTime();
"/*\nCopyright 2016 - 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 * Defines m.olm encryption/decryption\n *\n * @module crypto/algorithms/olm\n */\n\nimport { logger } from '../../logger';\nimport * as olmlib from \"../olmlib\";\nimport { DeviceInfo } from \"../deviceinfo\";\nimport {\n DecryptionAlgorithm,\n DecryptionError,\n EncryptionAlgorithm,\n registerAlgorithm,\n} from \"./base\";\nimport { Room } from '../../models/room';\nimport { MatrixEvent } from \"../..\";\nimport { IEventDecryptionResult } from \"../index\";\n\nconst DeviceVerification = DeviceInfo.DeviceVerification;\n\ninterface IMessage {\n type: number | string;\n body: string;\n}\n\n/**\n * Olm encryption implementation\n *\n * @constructor\n * @extends {module:crypto/algorithms/EncryptionAlgorithm}\n *\n * @param {object} params parameters, as per\n * {@link module:crypto/algorithms/EncryptionAlgorithm}\n */\nclass OlmEncryption extends EncryptionAlgorithm {\n private sessionPrepared = false;\n private prepPromise: Promise<void> = null;\n\n /**\n * @private\n\n * @param {string[]} roomMembers list of currently-joined users in the room\n * @return {Promise} Promise which resolves when setup is complete\n */\n private ensureSession(roomMembers: string[]): Promise<void> {\n if (this.prepPromise) {\n // prep already in progress\n return this.prepPromise;\n }\n\n if (this.sessionPrepared) {\n // prep already done\n return Promise.resolve();\n }\n\n this.prepPromise = this.crypto.downloadKeys(roomMembers).then((res) => {\n return this.crypto.ensureOlmSessionsForUsers(roomMembers);\n }).then(() => {\n this.sessionPrepared = true;\n }).finally(() => {\n this.prepPromise = null;\n });\n\n return this.prepPromise;\n }\n\n /**\n * @inheritdoc\n *\n * @param {module:models/room} room\n * @param {string} eventType\n * @param {object} content plaintext event content\n *\n * @return {Promise} Promise which resolves to the new event body\n */\n public async encryptMessage(room: Room, eventType: string, content: object): Promise<object> {\n // pick the list of recipients based on the membership list.\n //\n // TODO: there is a race condition here! What if a new user turns up\n // just as you are sending a secret message?\n\n const members = await room.getEncryptionTargetMembers();\n\n const users = members.map(function(u) {\n return u.userId;\n });\n\n await this.ensureSession(users);\n\n const payloadFields = {\n room_id: room.roomId,\n type: eventType,\n content: content,\n };\n\n const encryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: this.olmDevice.deviceCurve25519Key,\n ciphertext: {},\n };\n\n const promises = [];\n\n for (let i = 0; i < users.length; ++i) {\n const userId = users[i];\n const devices = this.crypto.getStoredDevicesForUser(userId);\n\n for (let j = 0; j < devices.length; ++j) {\n const deviceInfo = devices[j];\n const key = deviceInfo.getIdentityKey();\n if (key == this.olmDevice.deviceCurve25519Key) {\n // don't bother sending to ourself\n continue;\n }\n
"/*\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 { DeviceInfo } from \"./deviceinfo\";\nimport { IKeyBackupInfo } from \"./keybackup\";\n\n// TODO: Merge this with crypto.js once converted\n\nexport enum CrossSigningKey {\n Master = \"master\",\n SelfSigning = \"self_signing\",\n UserSigning = \"user_signing\",\n}\n\nexport interface IEncryptedEventInfo {\n /**\n * whether the event is encrypted (if not encrypted, some of the other properties may not be set)\n */\n encrypted: boolean;\n\n /**\n * the sender's key\n */\n senderKey: string;\n\n /**\n * the algorithm used to encrypt the event\n */\n algorithm: string;\n\n /**\n * whether we can be sure that the owner of the senderKey sent the event\n */\n authenticated: boolean;\n\n /**\n * the sender's device information, if available\n */\n sender?: DeviceInfo;\n\n /**\n * if the event's ed25519 and curve25519 keys don't match (only meaningful if `sender` is set)\n */\n mismatchedSender: boolean;\n}\n\nexport interface IRecoveryKey {\n keyInfo: {\n pubkey: string;\n passphrase?: {\n algorithm: string;\n iterations: number;\n salt: string;\n };\n };\n privateKey: Uint8Array;\n encodedPrivateKey: string;\n}\n\nexport interface ICreateSecretStorageOpts {\n /**\n * Function called to await a secret storage key creation flow.\n * Returns:\n * {Promise<Object>} Object with public key metadata, encoded private\n * recovery key which should be disposed of after displaying to the user,\n * and raw private key to avoid round tripping if needed.\n */\n createSecretStorageKey?: () => Promise<IRecoveryKey>;\n\n /**\n * The current key backup object. If passed,\n * the passphrase and recovery key from this backup will be used.\n */\n keyBackupInfo?: IKeyBackupInfo;\n\n /**\n * If true, a new key backup version will be\n * created and the private key stored in the new SSSS store. Ignored if keyBackupInfo\n * is supplied.\n */\n setupNewKeyBackup?: boolean;\n\n /**\n * Reset even if keys already exist.\n */\n setupNewSecretStorage?: boolean;\n\n /**\n * Function called to get the user's\n * current key backup passphrase. Should return a promise that resolves with a Uint8Array\n * containing the key, or rejects if the key cannot be obtained.\n */\n getKeyBackupPassphrase?: () => Promise<Uint8Array>;\n}\n\nexport interface ISecretStorageKeyInfo {\n name: string;\n algorithm: string;\n // technically the below are specific to AES keys. If we ever introduce another type,\n // we can split into separate interfaces.\n iv: string;\n mac: string;\n passphrase: IPassphraseInfo;\n}\n\nexport interface ISecretStorageKey {\n keyId: string;\n keyInfo: ISecretStorageKeyInfo;\n}\n\nexport interface IPassphraseInfo {\n algorithm: \"m.pbkdf2\";\n iterations: number;\n salt: string;\n bits: number;\n}\n\nexport interface IAddSecretStorageKeyOpts {\n name: string;\n passphrase: IPassphraseInfo;\n key: Uint8Array;\n}\n\nexport interface IImportOpts {\n stage: string; // TODO: Enum\n successes: number;\n failures: number;\n total: number;\n}\n\nexport interface IImportRoomKeysOpts {\n progressCallback: (stage: IImportOpts) => void;\n untrusted?: boolean;\n source?: string; // TODO: Enum\n}\n",
2021-08-11 18:56:57 +00:00
"/*\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\n/**\n * @module crypto/backup\n *\n * Classes for dealing with key backup.\n */\n\nimport { MatrixClient } from \"../client\";\nimport { logger } from \"../logger\";\nimport { MEGOLM_ALGORITHM, verifySignature } from \"./olmlib\";\nimport { DeviceInfo } from \"./deviceinfo\";\nimport { DeviceTrustLevel } from './CrossSigning';\nimport { keyFromPassphrase } from './key_passphrase';\nimport { sleep } from \"../utils\";\nimport { IndexedDBCryptoStore } from './store/indexeddb-crypto-store';\nimport { encodeRecoveryKey } from './recoverykey';\nimport { encryptAES, decryptAES, calculateKeyCheck } from './aes';\nimport { getCrypto } from '../utils';\nimport { ICurve25519AuthData, IAes256AuthData, IKeyBackupInfo, IKeyBackupSession } from \"./keybackup\";\nimport { UnstableValue } from \"../NamespacedValue\";\n\nconst KEY_BACKUP_KEYS_PER_REQUEST = 200;\n\ntype AuthData = IKeyBackupInfo[\"auth_data\"];\n\ntype SigInfo = {\n deviceId: string;\n valid?: boolean | null; // true: valid, false: invalid, null: cannot attempt validation\n device?: DeviceInfo | null;\n crossSigningId?: boolean;\n deviceTrust?: DeviceTrustLevel;\n};\n\nexport type TrustInfo = {\n usable: boolean; // is the backup trusted, true iff there is a sig that is valid & from a trusted device\n sigs: SigInfo[];\n};\n\nexport interface IKeyBackupCheck {\n backupInfo: IKeyBackupInfo;\n trustInfo: TrustInfo;\n}\n\n/* eslint-disable camelcase */\nexport interface IPreparedKeyBackupVersion {\n algorithm: string;\n auth_data: AuthData;\n recovery_key: string;\n privateKey: Uint8Array;\n}\n/* eslint-enable camelcase */\n\n/** A function used to get the secret key for a backup.\n */\ntype GetKey = () => Promise<ArrayLike<number>>;\n\ninterface BackupAlgorithmClass {\n algorithmName: string;\n // initialize from an existing backup\n init(authData: AuthData, getKey: GetKey): Promise<BackupAlgorithm>;\n\n // prepare a brand new backup\n prepare(\n key: string | Uint8Array | null,\n ): Promise<[Uint8Array, AuthData]>;\n\n checkBackupVersion(info: IKeyBackupInfo): void;\n}\n\ninterface BackupAlgorithm {\n untrusted: boolean;\n encryptSession(data: Record<string, any>): Promise<any>;\n decryptSessions(ciphertexts: Record<string, IKeyBackupSession>): Promise<Record<string, any>[]>;\n authData: AuthData;\n keyMatches(key: ArrayLike<number>): Promise<boolean>;\n free(): void;\n}\n\nexport interface IKeyBackup {\n rooms: {\n [roomId: string]: {\n sessions: {\n [sessionId: string]: IKeyBackupSession;\n };\n };\n };\n}\n\n/**\n * Manages the key backup.\n */\nexport class BackupManager {\n private algorithm: BackupAlgorithm | undefined;\n public backupInfo: IKeyBackupInfo | undefined; // The info dict from /room_keys/version\n public checkedForBackup: boolean; // Have we checked the server for a backup we can use?\n private sendingBackups: boolean; // Are we currently sending backups?\n constructor(private readonly baseApis: MatrixClient, public readonly getKey: GetKey) {\n this.checkedForBackup = false;\n this.sendingBackups = false;\n }\n\n public get version(): string | undefined {\n return this.backupInfo && this.backupInfo.version;\n }\n\n /**\n * Performs a quick check to ensure that the backup info looks sane.\n *\n * Throws an error if a problem is detected.\n *\n * @param {IK
"/*\nCopyright 2020-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 { decodeBase64, encodeBase64 } from './olmlib';\nimport { IndexedDBCryptoStore } from '../crypto/store/indexeddb-crypto-store';\nimport { decryptAES, encryptAES } from './aes';\nimport anotherjson from \"another-json\";\nimport { logger } from '../logger';\nimport { ISecretStorageKeyInfo } from \"./api\";\n\n// FIXME: these types should eventually go in a different file\ntype Signatures = Record<string, Record<string, string>>;\n\nexport interface IDehydratedDevice {\n device_id: string; // eslint-disable-line camelcase\n device_data: ISecretStorageKeyInfo & { // eslint-disable-line camelcase\n algorithm: string;\n account: string; // pickle\n };\n}\n\nexport interface IDehydratedDeviceKeyInfo {\n passphrase?: string;\n}\n\nexport interface IDeviceKeys {\n algorithms: Array<string>;\n device_id: string; // eslint-disable-line camelcase\n user_id: string; // eslint-disable-line camelcase\n keys: Record<string, string>;\n signatures?: Signatures;\n}\n\nexport interface IOneTimeKey {\n key: string;\n fallback?: boolean;\n signatures?: Signatures;\n}\n\nexport const DEHYDRATION_ALGORITHM = \"org.matrix.msc2697.v1.olm.libolm_pickle\";\n\nconst oneweek = 7 * 24 * 60 * 60 * 1000;\n\nexport class DehydrationManager {\n private inProgress = false;\n private timeoutId: any;\n private key: Uint8Array;\n private keyInfo: {[props: string]: any};\n private deviceDisplayName: string;\n constructor(private crypto) {\n this.getDehydrationKeyFromCache();\n }\n async getDehydrationKeyFromCache(): Promise<void> {\n return await this.crypto.cryptoStore.doTxn(\n 'readonly',\n [IndexedDBCryptoStore.STORE_ACCOUNT],\n (txn) => {\n this.crypto.cryptoStore.getSecretStorePrivateKey(\n txn,\n async (result) => {\n if (result) {\n const { key, keyInfo, deviceDisplayName, time } = result;\n const pickleKey = Buffer.from(this.crypto.olmDevice._pickleKey);\n const decrypted = await decryptAES(key, pickleKey, DEHYDRATION_ALGORITHM);\n this.key = decodeBase64(decrypted);\n this.keyInfo = keyInfo;\n this.deviceDisplayName = deviceDisplayName;\n const now = Date.now();\n const delay = Math.max(1, time + oneweek - now);\n this.timeoutId = global.setTimeout(\n this.dehydrateDevice.bind(this), delay,\n );\n }\n },\n \"dehydration\",\n );\n },\n );\n }\n\n /** set the key, and queue periodic dehydration to the server in the background */\n async setKeyAndQueueDehydration(\n key: Uint8Array, keyInfo: {[props: string]: any} = {},\n deviceDisplayName: string = undefined,\n ): Promise<void> {\n const matches = await this.setKey(key, keyInfo, deviceDisplayName);\n if (!matches) {\n // start dehydration in the background\n this.dehydrateDevice();\n }\n }\n\n async setKey(\n key: Uint8Array, keyInfo: {[props: string]: any} = {},\n deviceDisplayName: string = undefined,\n ): Promise<boolean>
"/*\nCopyright 2016 - 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 { ISignatures } from \"../@types/signed\";\n\n/**\n * @module crypto/deviceinfo\n */\n\nexport interface IDevice {\n keys: Record<string, string>;\n algorithms: string[];\n verified: DeviceVerification;\n known: boolean;\n unsigned?: Record<string, any>;\n signatures?: ISignatures;\n}\n\nenum DeviceVerification {\n Blocked = -1,\n Unverified = 0,\n Verified = 1,\n}\n\n/**\n * Information about a user's device\n *\n * @constructor\n * @alias module:crypto/deviceinfo\n *\n * @property {string} deviceId the ID of this device\n *\n * @property {string[]} algorithms list of algorithms supported by this device\n *\n * @property {Object.<string,string>} keys a map from\n * &lt;key type&gt;:&lt;id&gt; -> &lt;base64-encoded key&gt;>\n *\n * @property {module:crypto/deviceinfo.DeviceVerification} verified\n * whether the device has been verified/blocked by the user\n *\n * @property {boolean} known\n * whether the user knows of this device's existence (useful when warning\n * the user that a user has added new devices)\n *\n * @property {Object} unsigned additional data from the homeserver\n *\n * @param {string} deviceId id of the device\n */\nexport class DeviceInfo {\n /**\n * rehydrate a DeviceInfo from the session store\n *\n * @param {object} obj raw object from session store\n * @param {string} deviceId id of the device\n *\n * @return {module:crypto~DeviceInfo} new DeviceInfo\n */\n public static fromStorage(obj: IDevice, deviceId: string): DeviceInfo {\n const res = new DeviceInfo(deviceId);\n for (const prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n res[prop] = obj[prop];\n }\n }\n return res;\n }\n\n /**\n * @enum\n */\n public static DeviceVerification = {\n VERIFIED: DeviceVerification.Verified,\n UNVERIFIED: DeviceVerification.Unverified,\n BLOCKED: DeviceVerification.Blocked,\n };\n\n public algorithms: string[];\n public keys: Record<string, string> = {};\n public verified = DeviceVerification.Unverified;\n public known = false;\n public unsigned: Record<string, any> = {};\n public signatures: ISignatures = {};\n\n constructor(public readonly deviceId: string) {}\n\n /**\n * Prepare a DeviceInfo for JSON serialisation in the session store\n *\n * @return {object} deviceinfo with non-serialised members removed\n */\n public toStorage(): IDevice {\n return {\n algorithms: this.algorithms,\n keys: this.keys,\n verified: this.verified,\n known: this.known,\n unsigned: this.unsigned,\n signatures: this.signatures,\n };\n }\n\n /**\n * Get the fingerprint for this device (ie, the Ed25519 key)\n *\n * @return {string} base64-encoded fingerprint of this device\n */\n public getFingerprint(): string {\n return this.keys[\"ed25519:\" + this.deviceId];\n }\n\n /**\n * Get the identity key for this device (ie, the Curve25519 key)\n *\n * @return {string} base64-encoded identity key of this device\n */\n public getIdentityKey(): string {\n return this.keys[\"curve25519:\" + this.deviceId];\n }\n\n /**\n * Get the configured display name for this device, if any\n *\n * @return {string?} displayname\n */\n
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2016 OpenMarket Ltd\nCopyright 2017 Vector Creations Ltd\nCopyright 2018-2019 New Vector Ltd\nCopyright 2019-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 * @module crypto\n */\n\nimport anotherjson from \"another-json\";\nimport { EventEmitter } from 'events';\n\nimport { ReEmitter } from '../ReEmitter';\nimport { logger } from '../logger';\nimport { OlmDevice } from \"./OlmDevice\";\nimport * as olmlib from \"./olmlib\";\nimport { DeviceInfoMap, DeviceList } from \"./DeviceList\";\nimport { DeviceInfo, IDevice } from \"./deviceinfo\";\nimport * as algorithms from \"./algorithms\";\nimport { createCryptoStoreCacheCallbacks, CrossSigningInfo, DeviceTrustLevel, UserTrustLevel } from './CrossSigning';\nimport { EncryptionSetupBuilder } from \"./EncryptionSetup\";\nimport {\n SECRET_STORAGE_ALGORITHM_V1_AES,\n SecretStorage,\n SecretStorageKeyTuple,\n ISecretRequest,\n SecretStorageKeyObject,\n} from './SecretStorage';\nimport { IAddSecretStorageKeyOpts, ISecretStorageKeyInfo } from \"./api\";\nimport { OutgoingRoomKeyRequestManager } from './OutgoingRoomKeyRequestManager';\nimport { IndexedDBCryptoStore } from './store/indexeddb-crypto-store';\nimport { ReciprocateQRCode, SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD } from './verification/QRCode';\nimport { SAS as SASVerification } from './verification/SAS';\nimport { keyFromPassphrase } from './key_passphrase';\nimport { decodeRecoveryKey, encodeRecoveryKey } from './recoverykey';\nimport { VerificationRequest } from \"./verification/request/VerificationRequest\";\nimport { InRoomChannel, InRoomRequests } from \"./verification/request/InRoomChannel\";\nimport { ToDeviceChannel, ToDeviceRequests } from \"./verification/request/ToDeviceChannel\";\nimport { IllegalMethod } from \"./verification/IllegalMethod\";\nimport { KeySignatureUploadError } from \"../errors\";\nimport { decryptAES, encryptAES, calculateKeyCheck } from './aes';\nimport { DehydrationManager, IDeviceKeys, IOneTimeKey } from './dehydration';\nimport { BackupManager } from \"./backup\";\nimport { IStore } from \"../store\";\nimport { Room } from \"../models/room\";\nimport { RoomMember } from \"../models/room-member\";\nimport { MatrixEvent } from \"../models/event\";\nimport { MatrixClient, IKeysUploadResponse, SessionStore, ISignedKey } from \"../client\";\nimport type { EncryptionAlgorithm, DecryptionAlgorithm } from \"./algorithms/base\";\nimport type { IRoomEncryption, RoomList } from \"./RoomList\";\nimport { IRecoveryKey, IEncryptedEventInfo } from \"./api\";\nimport { IKeyBackupInfo } from \"./keybackup\";\nimport { ISyncStateData } from \"../sync\";\nimport { CryptoStore } from \"./store/base\";\n\nconst DeviceVerification = DeviceInfo.DeviceVerification;\n\nconst defaultVerificationMethods = {\n [ReciprocateQRCode.NAME]: ReciprocateQRCode,\n [SASVerification.NAME]: SASVerification,\n\n // These two can't be used for actual verification, but we do\n // need to be able to define them here for the verification flows\n // to start.\n [SHOW_QR_CODE_METHOD]: IllegalMethod,\n [SCAN_QR_CODE_METHOD]: IllegalMethod,\n};\n\n/**\n * verification method names\n */\n// legacy export identifier\nexport enum verificationMethods {\n RECIPROCATE_QR_CODE = ReciprocateQRCode.NAME,\n SAS = SASVerification.NAME,\n}\n\nexport type VerificationMethod = verificationMethods;\n\nexport function isCryptoAvailable(): boolean {\n return Boolean(global.Olm);\n}\n\nconst MIN_FORCE_SESSION_INTERVAL_MS = 60 * 60 * 1000;\n\ninterface II
"/*\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 { randomString } from '../randomstring';\n\nconst DEFAULT_ITERATIONS = 500000;\n\nconst DEFAULT_BITSIZE = 256;\n\n/* eslint-disable camelcase */\ninterface IAuthData {\n private_key_salt?: string;\n private_key_iterations?: number;\n private_key_bits?: number;\n}\n/* eslint-enable camelcase */\n\ninterface IKey {\n key: Uint8Array;\n salt: string;\n iterations: number;\n}\n\nexport async function keyFromAuthData(authData: IAuthData, password: string): Promise<Uint8Array> {\n if (!global.Olm) {\n throw new Error(\"Olm is not available\");\n }\n\n if (!authData.private_key_salt || !authData.private_key_iterations) {\n throw new Error(\n \"Salt and/or iterations not found: \" +\n \"this backup cannot be restored with a passphrase\",\n );\n }\n\n return await deriveKey(\n password, authData.private_key_salt,\n authData.private_key_iterations,\n authData.private_key_bits || DEFAULT_BITSIZE,\n );\n}\n\nexport async function keyFromPassphrase(password: string): Promise<IKey> {\n if (!global.Olm) {\n throw new Error(\"Olm is not available\");\n }\n\n const salt = randomString(32);\n\n const key = await deriveKey(password, salt, DEFAULT_ITERATIONS, DEFAULT_BITSIZE);\n\n return { key, salt, iterations: DEFAULT_ITERATIONS };\n}\n\nexport async function deriveKey(\n password: string,\n salt: string,\n iterations: number,\n numBits = DEFAULT_BITSIZE,\n): Promise<Uint8Array> {\n const subtleCrypto = global.crypto.subtle;\n const TextEncoder = global.TextEncoder;\n if (!subtleCrypto || !TextEncoder) {\n // TODO: Implement this for node\n throw new Error(\"Password-based backup is not avaiable on this platform\");\n }\n\n const key = await subtleCrypto.importKey(\n 'raw',\n new TextEncoder().encode(password),\n { name: 'PBKDF2' },\n false,\n ['deriveBits'],\n );\n\n const keybits = await subtleCrypto.deriveBits(\n {\n name: 'PBKDF2',\n salt: new TextEncoder().encode(salt),\n iterations: iterations,\n hash: 'SHA-512',\n },\n key,\n numBits,\n );\n\n return new Uint8Array(keybits);\n}\n",
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2016 - 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 * @module olmlib\n *\n * Utilities common to olm encryption algorithms\n */\n\nimport anotherjson from \"another-json\";\nimport type { PkSigning } from \"@matrix-org/olm\";\nimport { Logger } from \"loglevel\";\n\nimport OlmDevice from \"./OlmDevice\";\nimport { DeviceInfo } from \"./deviceinfo\";\nimport { logger } from '../logger';\nimport * as utils from \"../utils\";\nimport { IOneTimeKey } from \"./dehydration\";\nimport { MatrixClient } from \"../client\";\n\nenum Algorithm {\n Olm = \"m.olm.v1.curve25519-aes-sha2\",\n Megolm = \"m.megolm.v1.aes-sha2\",\n MegolmBackup = \"m.megolm_backup.v1.curve25519-aes-sha2\",\n}\n\n/**\n * matrix algorithm tag for olm\n */\nexport const OLM_ALGORITHM = Algorithm.Olm;\n\n/**\n * matrix algorithm tag for megolm\n */\nexport const MEGOLM_ALGORITHM = Algorithm.Megolm;\n\n/**\n * matrix algorithm tag for megolm backups\n */\nexport const MEGOLM_BACKUP_ALGORITHM = Algorithm.MegolmBackup;\n\nexport interface IOlmSessionResult {\n device: DeviceInfo;\n sessionId?: string;\n}\n\n/**\n * Encrypt an event payload for an Olm device\n *\n * @param {Object<string, string>} resultsObject The `ciphertext` property\n * of the m.room.encrypted event to which to add our result\n *\n * @param {string} ourUserId\n * @param {string} ourDeviceId\n * @param {module:crypto/OlmDevice} olmDevice olm.js wrapper\n * @param {string} recipientUserId\n * @param {module:crypto/deviceinfo} recipientDevice\n * @param {object} payloadFields fields to include in the encrypted payload\n *\n * Returns a promise which resolves (to undefined) when the payload\n * has been encrypted into `resultsObject`\n */\nexport async function encryptMessageForDevice(\n resultsObject: Record<string, string>,\n ourUserId: string,\n ourDeviceId: string,\n olmDevice: OlmDevice,\n recipientUserId: string,\n recipientDevice: DeviceInfo,\n payloadFields: Record<string, any>,\n) {\n const deviceKey = recipientDevice.getIdentityKey();\n const sessionId = await olmDevice.getSessionIdForDevice(deviceKey);\n if (sessionId === null) {\n // If we don't have a session for a device then\n // we can't encrypt a message for it.\n return;\n }\n\n logger.log(\n \"Using sessionid \" + sessionId + \" for device \" +\n recipientUserId + \":\" + recipientDevice.deviceId,\n );\n\n const payload = {\n sender: ourUserId,\n // TODO this appears to no longer be used whatsoever\n sender_device: ourDeviceId,\n\n // Include the Ed25519 key so that the recipient knows what\n // device this message came from.\n // We don't need to include the curve25519 key since the\n // recipient will already know this from the olm headers.\n // When combined with the device keys retrieved from the\n // homeserver signed by the ed25519 key this proves that\n // the curve25519 key and the ed25519 key are owned by\n // the same device.\n keys: {\n \"ed25519\": olmDevice.deviceEd25519Key,\n },\n\n // include the recipient device details in the payload,\n // to avoid unknown key attacks, per\n // https://github.com/vector-im/vector-web/issues/2483\n recipient: recipientUserId,\n recipient_keys: {\n \"ed25519\": recipientDevice.getFingerprint(),\n },\n };\n\n // TODO: technically, a bunch of that stuff only needs to b
"/*\nCopyright 2018 New Vector Ltd\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 bs58 from 'bs58';\n\n// picked arbitrarily but to try & avoid clashing with any bitcoin ones\n// (which are also base58 encoded, but bitcoin's involve a lot more hashing)\nconst OLM_RECOVERY_KEY_PREFIX = [0x8B, 0x01];\n\nexport function encodeRecoveryKey(key: ArrayLike<number>): string {\n const buf = new Buffer(OLM_RECOVERY_KEY_PREFIX.length + key.length + 1);\n buf.set(OLM_RECOVERY_KEY_PREFIX, 0);\n buf.set(key, OLM_RECOVERY_KEY_PREFIX.length);\n\n let parity = 0;\n for (let i = 0; i < buf.length - 1; ++i) {\n parity ^= buf[i];\n }\n buf[buf.length - 1] = parity;\n const base58key = bs58.encode(buf);\n\n return base58key.match(/.{1,4}/g).join(\" \");\n}\n\nexport function decodeRecoveryKey(recoveryKey: string): Uint8Array {\n const result = bs58.decode(recoveryKey.replace(/ /g, ''));\n\n let parity = 0;\n for (const b of result) {\n parity ^= b;\n }\n if (parity !== 0) {\n throw new Error(\"Incorrect parity\");\n }\n\n for (let i = 0; i < OLM_RECOVERY_KEY_PREFIX.length; ++i) {\n if (result[i] !== OLM_RECOVERY_KEY_PREFIX[i]) {\n throw new Error(\"Incorrect prefix\");\n }\n }\n\n if (\n result.length !==\n OLM_RECOVERY_KEY_PREFIX.length + global.Olm.PRIVATE_KEY_LENGTH + 1\n ) {\n throw new Error(\"Incorrect length\");\n }\n\n return Uint8Array.from(result.slice(\n OLM_RECOVERY_KEY_PREFIX.length,\n OLM_RECOVERY_KEY_PREFIX.length + global.Olm.PRIVATE_KEY_LENGTH,\n ));\n}\n",
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2017 - 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, PrefixedLogger } from '../../logger';\nimport * as utils from \"../../utils\";\nimport {\n CryptoStore,\n IDeviceData,\n IProblem,\n ISession,\n ISessionInfo,\n IWithheld,\n Mode,\n OutgoingRoomKeyRequest,\n} from \"./base\";\nimport { IRoomKeyRequestBody } from \"../index\";\nimport { ICrossSigningKey } from \"../../client\";\nimport { IOlmDevice } from \"../algorithms/megolm\";\nimport { IRoomEncryption } from \"../RoomList\";\nimport { InboundGroupSessionData } from \"../../@types/partials\";\nimport { IEncryptedPayload } from \"../aes\";\n\nexport const VERSION = 10;\nconst PROFILE_TRANSACTIONS = false;\n\n/**\n * Implementation of a CryptoStore which is backed by an existing\n * IndexedDB connection. Generally you want IndexedDBCryptoStore\n * which connects to the database and defers to one of these.\n *\n * @implements {module:crypto/store/base~CryptoStore}\n */\nexport class Backend implements CryptoStore {\n private nextTxnId = 0;\n\n /**\n * @param {IDBDatabase} db\n */\n constructor(private db: IDBDatabase) {\n // make sure we close the db on `onversionchange` - otherwise\n // attempts to delete the database will block (and subsequent\n // attempts to re-create it will also block).\n db.onversionchange = () => {\n logger.log(`versionchange for indexeddb ${this.db.name}: closing`);\n db.close();\n };\n }\n\n public async startup(): Promise<CryptoStore> {\n // No work to do, as the startup is done by the caller (e.g IndexedDBCryptoStore)\n // by passing us a ready IDBDatabase instance\n return this;\n }\n public async deleteAllData(): Promise<void> {\n throw Error(\"This is not implemented, call IDBFactory::deleteDatabase(dbName) instead.\");\n }\n\n /**\n * Look for an existing outgoing room key request, and if none is found,\n * add a new one\n *\n * @param {module:crypto/store/base~OutgoingRoomKeyRequest} request\n *\n * @returns {Promise} resolves to\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the\n * same instance as passed in, or the existing one.\n */\n public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {\n const requestBody = request.requestBody;\n\n return new Promise((resolve, reject) => {\n const txn = this.db.transaction(\"outgoingRoomKeyRequests\", \"readwrite\");\n txn.onerror = reject;\n\n // first see if we already have an entry for this request.\n this._getOutgoingRoomKeyRequest(txn, requestBody, (existing) => {\n if (existing) {\n // this entry matches the request - return it.\n logger.log(\n `already have key request outstanding for ` +\n `${requestBody.room_id} / ${requestBody.session_id}: ` +\n `not sending another`,\n );\n resolve(existing);\n return;\n }\n\n // we got to the end of the list without finding a match\n // - add the new request.\n logger.log(\n `enqueueing key request for ${requestBody.room_id} / ` +\n requestBody.session_id,\n );\n
"/*\nCopyright 2017 - 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, PrefixedLogger } from '../../logger';\nimport { LocalStorageCryptoStore } from './localStorage-crypto-store';\nimport { MemoryCryptoStore } from './memory-crypto-store';\nimport * as IndexedDBCryptoStoreBackend from './indexeddb-crypto-store-backend';\nimport { InvalidCryptoStoreError } from '../../errors';\nimport * as IndexedDBHelpers from \"../../indexeddb-helpers\";\nimport {\n CryptoStore,\n IDeviceData,\n IProblem,\n ISession,\n ISessionInfo,\n IWithheld,\n Mode,\n OutgoingRoomKeyRequest,\n} from \"./base\";\nimport { IRoomKeyRequestBody } from \"../index\";\nimport { ICrossSigningKey } from \"../../client\";\nimport { IOlmDevice } from \"../algorithms/megolm\";\nimport { IRoomEncryption } from \"../RoomList\";\nimport { InboundGroupSessionData } from \"../../@types/partials\";\nimport { IEncryptedPayload } from \"../aes\";\n\n/**\n * Internal module. indexeddb storage for e2e.\n *\n * @module\n */\n\n/**\n * An implementation of CryptoStore, which is normally backed by an indexeddb,\n * but with fallback to MemoryCryptoStore.\n *\n * @implements {module:crypto/store/base~CryptoStore}\n */\nexport class IndexedDBCryptoStore implements CryptoStore {\n public static STORE_ACCOUNT = 'account';\n public static STORE_SESSIONS = 'sessions';\n public static STORE_INBOUND_GROUP_SESSIONS = 'inbound_group_sessions';\n public static STORE_INBOUND_GROUP_SESSIONS_WITHHELD = 'inbound_group_sessions_withheld';\n public static STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS = 'shared_history_inbound_group_sessions';\n public static STORE_DEVICE_DATA = 'device_data';\n public static STORE_ROOMS = 'rooms';\n public static STORE_BACKUP = 'sessions_needing_backup';\n\n public static exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> {\n return IndexedDBHelpers.exists(indexedDB, dbName);\n }\n\n private backendPromise: Promise<CryptoStore> = null;\n private backend: CryptoStore = null;\n\n /**\n * Create a new IndexedDBCryptoStore\n *\n * @param {IDBFactory} indexedDB global indexedDB instance\n * @param {string} dbName name of db to connect to\n */\n constructor(private readonly indexedDB: IDBFactory, private readonly dbName: string) {}\n\n /**\n * Ensure the database exists and is up-to-date, or fall back to\n * a local storage or in-memory store.\n *\n * This must be called before the store can be used.\n *\n * @return {Promise} resolves to either an IndexedDBCryptoStoreBackend.Backend,\n * or a MemoryCryptoStore\n */\n public startup(): Promise<CryptoStore> {\n if (this.backendPromise) {\n return this.backendPromise;\n }\n\n this.backendPromise = new Promise<CryptoStore>((resolve, reject) => {\n if (!this.indexedDB) {\n reject(new Error('no indexeddb support available'));\n return;\n }\n\n logger.log(`connecting to indexeddb ${this.dbName}`);\n\n const req = this.indexedDB.open(this.dbName, IndexedDBCryptoStoreBackend.VERSION);\n\n req.onupgradeneeded = (ev) => {\n const db = req.result;\n const oldVersion = ev.oldVersion;\n IndexedDBCryptoStoreBackend.upgradeDatabase(db, oldVersion);\n };\n\n req.onblocked = () => {\n logger.log(\n `can't yet open IndexedDBCr
"/*\nCopyright 2017 - 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 { MemoryCryptoStore } from './memory-crypto-store';\nimport { IDeviceData, IProblem, ISession, ISessionInfo, IWithheld, Mode } from \"./base\";\nimport { IOlmDevice } from \"../algorithms/megolm\";\nimport { IRoomEncryption } from \"../RoomList\";\nimport { ICrossSigningKey } from \"../../client\";\nimport { InboundGroupSessionData } from \"../../@types/partials\";\nimport { IEncryptedPayload } from \"../aes\";\n\n/**\n * Internal module. Partial localStorage backed storage for e2e.\n * This is not a full crypto store, just the in-memory store with\n * some things backed by localStorage. It exists because indexedDB\n * is broken in Firefox private mode or set to, \"will not remember\n * history\".\n *\n * @module\n */\n\nconst E2E_PREFIX = \"crypto.\";\nconst KEY_END_TO_END_ACCOUNT = E2E_PREFIX + \"account\";\nconst KEY_CROSS_SIGNING_KEYS = E2E_PREFIX + \"cross_signing_keys\";\nconst KEY_NOTIFIED_ERROR_DEVICES = E2E_PREFIX + \"notified_error_devices\";\nconst KEY_DEVICE_DATA = E2E_PREFIX + \"device_data\";\nconst KEY_INBOUND_SESSION_PREFIX = E2E_PREFIX + \"inboundgroupsessions/\";\nconst KEY_INBOUND_SESSION_WITHHELD_PREFIX = E2E_PREFIX + \"inboundgroupsessions.withheld/\";\nconst KEY_ROOMS_PREFIX = E2E_PREFIX + \"rooms/\";\nconst KEY_SESSIONS_NEEDING_BACKUP = E2E_PREFIX + \"sessionsneedingbackup\";\n\nfunction keyEndToEndSessions(deviceKey: string): string {\n return E2E_PREFIX + \"sessions/\" + deviceKey;\n}\n\nfunction keyEndToEndSessionProblems(deviceKey: string): string {\n return E2E_PREFIX + \"session.problems/\" + deviceKey;\n}\n\nfunction keyEndToEndInboundGroupSession(senderKey: string, sessionId: string): string {\n return KEY_INBOUND_SESSION_PREFIX + senderKey + \"/\" + sessionId;\n}\n\nfunction keyEndToEndInboundGroupSessionWithheld(senderKey: string, sessionId: string): string {\n return KEY_INBOUND_SESSION_WITHHELD_PREFIX + senderKey + \"/\" + sessionId;\n}\n\nfunction keyEndToEndRoomsPrefix(roomId: string): string {\n return KEY_ROOMS_PREFIX + roomId;\n}\n\n/**\n * @implements {module:crypto/store/base~CryptoStore}\n */\nexport class LocalStorageCryptoStore extends MemoryCryptoStore {\n public static exists(store: Storage): boolean {\n const length = store.length;\n for (let i = 0; i < length; i++) {\n if (store.key(i).startsWith(E2E_PREFIX)) {\n return true;\n }\n }\n return false;\n }\n\n constructor(private readonly store: Storage) {\n super();\n }\n\n // Olm Sessions\n\n public countEndToEndSessions(txn: unknown, func: (count: number) => void): void {\n let count = 0;\n for (let i = 0; i < this.store.length; ++i) {\n if (this.store.key(i).startsWith(keyEndToEndSessions(''))) ++count;\n }\n func(count);\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private _getEndToEndSessions(deviceKey: string): Record<string, ISessionInfo> {\n const sessions = getJsonItem(this.store, keyEndToEndSessions(deviceKey));\n const fixedSessions: Record<string, ISessionInfo> = {};\n\n // fix up any old sessions to be objects rather than just the base64 pickle\n for (const [sid, val] of Object.entries(sessions || {})) {\n if (typeof val === 'string') {\n fixedSessions[sid] = {\n session: val,\n };\n } el
"/*\nCopyright 2017 - 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 * as utils from \"../../utils\";\nimport {\n CryptoStore,\n IDeviceData,\n IProblem,\n ISession,\n ISessionInfo,\n IWithheld,\n Mode,\n OutgoingRoomKeyRequest,\n} from \"./base\";\nimport { IRoomKeyRequestBody } from \"../index\";\nimport { ICrossSigningKey } from \"../../client\";\nimport { IOlmDevice } from \"../algorithms/megolm\";\nimport { IRoomEncryption } from \"../RoomList\";\nimport { InboundGroupSessionData } from \"../../@types/partials\";\nimport { IEncryptedPayload } from \"../aes\";\n\n/**\n * Internal module. in-memory storage for e2e.\n *\n * @module\n */\n\n/**\n * @implements {module:crypto/store/base~CryptoStore}\n */\nexport class MemoryCryptoStore implements CryptoStore {\n private outgoingRoomKeyRequests: OutgoingRoomKeyRequest[] = [];\n private account: string = null;\n private crossSigningKeys: Record<string, ICrossSigningKey> = null;\n private privateKeys: Record<string, IEncryptedPayload> = {};\n\n private sessions: { [deviceKey: string]: { [sessionId: string]: ISessionInfo } } = {};\n private sessionProblems: { [deviceKey: string]: IProblem[] } = {};\n private notifiedErrorDevices: { [userId: string]: { [deviceId: string]: boolean } } = {};\n private inboundGroupSessions: { [sessionKey: string]: InboundGroupSessionData } = {};\n private inboundGroupSessionsWithheld: Record<string, IWithheld> = {};\n // Opaque device data object\n private deviceData: IDeviceData = null;\n private rooms: { [roomId: string]: IRoomEncryption } = {};\n private sessionsNeedingBackup: { [sessionKey: string]: boolean } = {};\n private sharedHistoryInboundGroupSessions: { [roomId: string]: [senderKey: string, sessionId: string][] } = {};\n\n /**\n * Ensure the database exists and is up-to-date.\n *\n * This must be called before the store can be used.\n *\n * @return {Promise} resolves to the store.\n */\n public async startup(): Promise<CryptoStore> {\n // No startup work to do for the memory store.\n return this;\n }\n\n /**\n * Delete all data from this store.\n *\n * @returns {Promise} Promise which resolves when the store has been cleared.\n */\n public deleteAllData(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Look for an existing outgoing room key request, and if none is found,\n * add a new one\n *\n * @param {module:crypto/store/base~OutgoingRoomKeyRequest} request\n *\n * @returns {Promise} resolves to\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the\n * same instance as passed in, or the existing one.\n */\n public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {\n const requestBody = request.requestBody;\n\n return utils.promiseTry(() => {\n // first see if we already have an entry for this request.\n const existing = this._getOutgoingRoomKeyRequest(requestBody);\n\n if (existing) {\n // this entry matches the request - return it.\n logger.log(\n `already have key request outstanding for ` +\n `${requestBody.room_id} / ${requestBody.session_id}: ` +\n `not sending another`,\n );\n return existing;\n }\n\n
"/*\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 * @module crypto/verification/Base\n */\n\nimport { MatrixEvent } from '../../models/event';\nimport { EventEmitter } from 'events';\nimport { logger } from '../../logger';\nimport { DeviceInfo } from '../deviceinfo';\nimport { newTimeoutError } from \"./Error\";\nimport { requestKeysDuringVerification } from \"../CrossSigning\";\n\nconst timeoutException = new Error(\"Verification timed out\");\n\nexport class SwitchStartEventError extends Error {\n constructor(startEvent) {\n super();\n this.startEvent = startEvent;\n }\n}\n\nexport class VerificationBase extends EventEmitter {\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 * @class\n *\n * @param {Object} channel the verification channel to send verification messages over.\n * TODO: Channel types\n *\n * @param {MatrixClient} baseApis base matrix api interface\n *\n * @param {string} userId the user ID that is being verified\n *\n * @param {string} deviceId the device ID that is being verified\n *\n * @param {object} [startEvent] the m.key.verification.start event that\n * initiated this verification, if any\n *\n * @param {object} [request] the key verification request object related to\n * this verification, if any\n */\n constructor(channel, baseApis, userId, deviceId, startEvent, request) {\n super();\n this._channel = channel;\n this._baseApis = baseApis;\n this.userId = userId;\n this.deviceId = deviceId;\n this.startEvent = startEvent;\n this.request = request;\n\n this.cancelled = false;\n this._done = false;\n this._promise = null;\n this._transactionTimeoutTimer = null;\n }\n\n get initiatedByMe() {\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() &&\n content.from_device === this._baseApis.getDeviceId();\n }\n\n _resetTimer() {\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 _endTimer() {\n if (this._transactionTimeoutTimer !== null) {\n clearTimeout(this._transactionTimeoutTimer);\n this._transactionTimeoutTimer = null;\n }\n }\n\n _send(type, uncompletedContent) {\n return this._channel.send(type, uncompletedContent);\n }\n\n _waitForEvent(type
"/*\nCopyright 2018 New Vector Ltd\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 * @module crypto/verification/Error\n */\n\nimport { MatrixEvent } from \"../../models/event\";\n\nexport function newVerificationError(code, reason, extradata) {\n const content = Object.assign({}, { code, reason }, extradata);\n return new MatrixEvent({\n type: \"m.key.verification.cancel\",\n content,\n });\n}\n\nexport function errorFactory(code, reason) {\n return function(extradata) {\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 * The transaction is unknown.\n */\nexport const newUnknownTransactionError = errorFactory(\n \"m.unknown_transaction\", \"Unknown transaction\",\n);\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(\n \"m.unexpected_message\", \"Unexpected message\",\n);\n\n/**\n * The key does not match.\n */\nexport const newKeyMismatchError = errorFactory(\n \"m.key_mismatch\", \"Key mismatch\",\n);\n\n/**\n * The user does not match.\n */\nexport const newUserMismatchError = errorFactory(\"m.user_error\", \"User mismatch\");\n\n/**\n * An invalid message was sent.\n */\nexport const newInvalidMessageError = errorFactory(\n \"m.invalid_message\", \"Invalid message\",\n);\n\nexport function errorFromEvent(event) {\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",
"/*\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 * @module crypto/verification/IllegalMethod\n */\n\nimport { VerificationBase as Base } from \"./Base\";\n\n/**\n * @class crypto/verification/IllegalMethod/IllegalMethod\n * @extends {module:crypto/verification/Base}\n */\nexport class IllegalMethod extends Base {\n static factory(...args) {\n return new IllegalMethod(...args);\n }\n\n static get NAME() {\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 async _doVerification() {\n throw new Error(\"Verification is not possible with this method\");\n }\n}\n",
"/*\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 * QR code key verification.\n * @module crypto/verification/QRCode\n */\n\nimport { VerificationBase as Base } from \"./Base\";\nimport {\n newKeyMismatchError,\n newUserCancelledError,\n} from './Error';\nimport { encodeUnpaddedBase64, decodeBase64 } from \"../olmlib\";\nimport { logger } from '../../logger';\n\nexport const SHOW_QR_CODE_METHOD = \"m.qr_code.show.v1\";\nexport const SCAN_QR_CODE_METHOD = \"m.qr_code.scan.v1\";\n\n/**\n * @class crypto/verification/QRCode/ReciprocateQRCode\n * @extends {module:crypto/verification/Base}\n */\nexport class ReciprocateQRCode extends Base {\n static factory(...args) {\n return new ReciprocateQRCode(...args);\n }\n\n static get NAME() {\n return \"m.reciprocate.v1\";\n }\n\n async _doVerification() {\n if (!this.startEvent) {\n // TODO: Support scanning QR codes\n throw new Error(\"It is not currently possible to start verification\" +\n \"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((resolve, reject) => {\n this.reciprocateQREvent = {\n confirm: resolve,\n cancel: () => reject(newUserCancelledError()),\n };\n this.emit(\"show_reciprocate_qr\", this.reciprocateQREvent);\n });\n\n // 3. determine key to sign / mark as trusted\n const keys = {};\n\n switch (qrCodeData.mode) {\n case MODE_VERIFY_OTHER_USER: {\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_VERIFY_SELF_TRUSTED: {\n const deviceId = this.request.targetDevice.deviceId;\n keys[`ed25519:${deviceId}`] = qrCodeData.otherDeviceKey;\n break;\n }\n case MODE_VERIFY_SELF_UNTRUSTED: {\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
"/*\nCopyright 2018 New Vector Ltd\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 * @module crypto/verification/SAS\n */\n\nimport { VerificationBase as Base, SwitchStartEventError } from \"./Base\";\nimport anotherjson from 'another-json';\nimport {\n errorFactory,\n newInvalidMessageError,\n newKeyMismatchError,\n newUnknownMethodError,\n newUserCancelledError,\n} from './Error';\nimport { logger } from '../../logger';\n\nconst START_TYPE = \"m.key.verification.start\";\n\nconst EVENTS = [\n \"m.key.verification.accept\",\n \"m.key.verification.key\",\n \"m.key.verification.mac\",\n];\n\nlet olmutil;\n\nconst newMismatchedSASError = errorFactory(\n \"m.mismatched_sas\", \"Mismatched short authentication string\",\n);\n\nconst newMismatchedCommitmentError = errorFactory(\n \"m.mismatched_commitment\", \"Mismatched commitment\",\n);\n\nfunction generateDecimalSas(sasBytes) {\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\nconst 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 [\"🏁\", \"fla
"/*\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 {\n VerificationRequest,\n REQUEST_TYPE,\n READY_TYPE,\n START_TYPE,\n} from \"./VerificationRequest\";\nimport { logger } from '../../../logger';\n\nconst MESSAGE_TYPE = \"m.room.message\";\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 {\n /**\n * @param {MatrixClient} client the matrix client, to send messages with and get current user & device from.\n * @param {string} roomId id of the room where verification events should be posted in, should be a DM with the given user.\n * @param {string} userId id of user that the verification request is directed at, should be present in the room.\n */\n constructor(client, roomId, userId = null) {\n this._client = client;\n this._roomId = roomId;\n this.userId = userId;\n this._requestEventId = null;\n }\n\n get receiveStartFromOtherDevices() {\n return true;\n }\n\n get roomId() {\n return this._roomId;\n }\n\n /** The transaction id generated/used by this verification channel */\n get transactionId() {\n return this._requestEventId;\n }\n\n static getOtherPartyUserId(event, client) {\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 {MatrixEvent} event the event to get the timestamp of\n * @return {number} the timestamp when the event was sent\n */\n getTimestamp(event) {\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 {string} type the event type to check\n * @returns {bool} boolean flag\n */\n static canCreateRequest(type) {\n return type === REQUEST_TYPE;\n }\n\n /**\n * Extract the transaction id used by a given key verification event, if any\n * @param {MatrixEvent} event the event\n * @returns {string} the transaction id\n */\n static getTransactionId(event) {\n if (InRoomChannel.getEventType(event) === REQUEST_TYPE) {\n return event.getId();\n } else {\n const relation = event.getRelation();\n if (relation && 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 {MatrixEvent} event the event to validate\n * @param {MatrixClient} client the client to get the current user and device id from\n * @returns {bool} whether the
"/*\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\";\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 {\n // userId and devices of user we're about to verify\n constructor(client, userId, devices, transactionId = null, deviceId = null) {\n this._client = client;\n this.userId = userId;\n this._devices = devices;\n this.transactionId = transactionId;\n this._deviceId = deviceId;\n }\n\n isToDevices(devices) {\n if (devices.length === this._devices.length) {\n for (const device of devices) {\n const d = this._devices.find(d => d.deviceId === device.deviceId);\n if (!d) {\n return false;\n }\n }\n return true;\n } else {\n return false;\n }\n }\n\n get deviceId() {\n return this._deviceId;\n }\n\n static getEventType(event) {\n return event.getType();\n }\n\n /**\n * Extract the transaction id used by a given key verification event, if any\n * @param {MatrixEvent} event the event\n * @returns {string} the transaction id\n */\n static getTransactionId(event) {\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 {string} type the event type to check\n * @returns {bool} boolean flag\n */\n static canCreateRequest(type) {\n return type === REQUEST_TYPE || type === START_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 {MatrixEvent} event the event to validate\n * @param {MatrixClient} client the client to get the current user and device id from\n * @returns {bool} whether the event is valid and should be passed to handleEvent\n */\n static validateEvent(event, client) {\n if (event.isCancelled()) {\n logger.warn(\"Ignoring flagged verification request from \"\n + 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.val
"/*\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 { logger } from '../../../logger';\nimport { EventEmitter } from 'events';\nimport {\n errorFactory,\n errorFromEvent,\n newUnexpectedMessageError,\n newUnknownMethodError,\n} from \"../Error\";\nimport { QRCodeData, SCAN_QR_CODE_METHOD } from \"../QRCode\";\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 const PHASE_UNSENT = 1;\nexport const PHASE_REQUESTED = 2;\nexport const PHASE_READY = 3;\nexport const PHASE_STARTED = 4;\nexport const PHASE_CANCELLED = 5;\nexport const PHASE_DONE = 6;\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 * @event \"change\" whenever the state of the request object has changed.\n */\nexport class VerificationRequest extends EventEmitter {\n constructor(channel, verificationMethods, client) {\n super();\n this.channel = channel;\n this.channel._request = this;\n this._verificationMethods = verificationMethods;\n this._client = client;\n this._commonMethods = [];\n this._setPhase(PHASE_UNSENT, false);\n this._eventsByUs = new Map();\n this._eventsByThem = new Map();\n this._observeOnly = false;\n this._timeoutTimer = null;\n this._accepting = false;\n this._declining = false;\n this._verifierHasFinished = false;\n this._cancelled = false;\n this._chosenMethod = 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 this._qrCodeData = null;\n\n // The timestamp when we received the request event from the other side\n this._requestReceivedAt = null;\n }\n\n /**\n * Stateless validation logic not specific to the channel.\n * Invoked by the same static method in either channel.\n * @param {string} type the \"symbolic\" event type, as returned by the `getEventType` function on the channel.\n * @param {MatrixEvent} event the event to validate. Don't call getType() on it but use the `type` parameter instead.\n * @param {MatrixClient} client the client to get the current user and device id from\n * @returns {bool} whether the event is valid and should be passed to handleEvent\n */\n static validateEvent(type, event, client) {\n const content = event.getContent();\n\n if (!type || !ty
"// can't just do InvalidStoreError extends Error\n// because of http://babeljs.io/docs/usage/caveats/#classes\nexport function InvalidStoreError(reason, value) {\n const message = `Store is invalid because ${reason}, ` +\n `please stop the client, delete all data and start the client again`;\n const instance = Reflect.construct(Error, [message]);\n Reflect.setPrototypeOf(instance, Reflect.getPrototypeOf(this));\n instance.reason = reason;\n instance.value = value;\n return instance;\n}\n\nInvalidStoreError.TOGGLED_LAZY_LOADING = \"TOGGLED_LAZY_LOADING\";\n\nInvalidStoreError.prototype = Object.create(Error.prototype, {\n constructor: {\n value: Error,\n enumerable: false,\n writable: true,\n configurable: true,\n },\n});\nReflect.setPrototypeOf(InvalidStoreError, Error);\n\nexport function InvalidCryptoStoreError(reason) {\n const message = `Crypto store is invalid because ${reason}, ` +\n `please stop the client, delete all data and start the client again`;\n const instance = Reflect.construct(Error, [message]);\n Reflect.setPrototypeOf(instance, Reflect.getPrototypeOf(this));\n instance.reason = reason;\n instance.name = 'InvalidCryptoStoreError';\n return instance;\n}\n\nInvalidCryptoStoreError.TOO_NEW = \"TOO_NEW\";\n\nInvalidCryptoStoreError.prototype = Object.create(Error.prototype, {\n constructor: {\n value: Error,\n enumerable: false,\n writable: true,\n configurable: true,\n },\n});\nReflect.setPrototypeOf(InvalidCryptoStoreError, Error);\n\nexport class KeySignatureUploadError extends Error {\n constructor(message, value) {\n super(message);\n this.value = value;\n }\n}\n",
2021-08-11 18:56:57 +00:00
"/*\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 { MatrixClient } from \"./client\";\nimport { IEvent, MatrixEvent } from \"./models/event\";\n\nexport type EventMapper = (obj: Partial<IEvent>) => MatrixEvent;\n\nexport interface MapperOpts {\n preventReEmit?: boolean;\n decrypt?: boolean;\n}\n\nexport function eventMapperFor(client: MatrixClient, options: MapperOpts): EventMapper {\n const preventReEmit = Boolean(options.preventReEmit);\n const decrypt = options.decrypt !== false;\n\n function mapper(plainOldJsObject: Partial<IEvent>) {\n const event = new MatrixEvent(plainOldJsObject);\n if (event.isEncrypted()) {\n if (!preventReEmit) {\n client.reEmitter.reEmit(event, [\n \"Event.decrypted\",\n ]);\n }\n if (decrypt) {\n client.decryptEventIfNeeded(event);\n }\n }\n if (!preventReEmit) {\n client.reEmitter.reEmit(event, [\"Event.replaced\"]);\n }\n return event;\n }\n\n return mapper;\n}\n",
"/*\nCopyright 2016 - 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\";\n\n/**\n * @module filter-component\n */\n\n/**\n * Checks if a value matches a given field value, which may be a * terminated\n * wildcard pattern.\n * @param {String} actualValue The value to be compared\n * @param {String} filterValue The filter pattern to be compared\n * @return {boolean} true if the actualValue matches the filterValue\n */\nfunction matchesWildcard(actualValue: string, filterValue: string): boolean {\n if (filterValue.endsWith(\"*\")) {\n const typePrefix = filterValue.slice(0, -1);\n return actualValue.substr(0, typePrefix.length) === typePrefix;\n } else {\n return actualValue === filterValue;\n }\n}\n\n/* eslint-disable camelcase */\nexport interface IFilterComponent {\n types?: string[];\n not_types?: string[];\n rooms?: string[];\n not_rooms?: string[];\n senders?: string[];\n not_senders?: string[];\n contains_url?: boolean;\n limit?: number;\n}\n/* eslint-enable camelcase */\n\n/**\n * FilterComponent is a section of a Filter definition which defines the\n * types, rooms, senders filters etc to be applied to a particular type of resource.\n * This is all ported over from synapse's Filter object.\n *\n * N.B. that synapse refers to these as 'Filters', and what js-sdk refers to as\n * 'Filters' are referred to as 'FilterCollections'.\n *\n * @constructor\n * @param {Object} filterJson the definition of this filter JSON, e.g. { 'contains_url': true }\n */\nexport class FilterComponent {\n constructor(private filterJson: IFilterComponent) {}\n\n /**\n * Checks with the filter component matches the given event\n * @param {MatrixEvent} event event to be checked against the filter\n * @return {boolean} true if the event matches the filter\n */\n public check(event: MatrixEvent): boolean {\n return this.checkFields(\n event.getRoomId(),\n event.getSender(),\n event.getType(),\n event.getContent() ? event.getContent().url !== undefined : false,\n );\n }\n\n /**\n * Converts the filter component into the form expected over the wire\n */\n public toJSON(): object {\n return {\n types: this.filterJson.types || null,\n not_types: this.filterJson.not_types || [],\n rooms: this.filterJson.rooms || null,\n not_rooms: this.filterJson.not_rooms || [],\n senders: this.filterJson.senders || null,\n not_senders: this.filterJson.not_senders || [],\n contains_url: this.filterJson.contains_url || null,\n };\n }\n\n /**\n * Checks whether the filter component matches the given event fields.\n * @param {String} roomId the roomId for the event being checked\n * @param {String} sender the sender of the event being checked\n * @param {String} eventType the type of the event being checked\n * @param {boolean} containsUrl whether the event contains a content.url field\n * @return {boolean} true if the event fields match the filter\n */\n private checkFields(roomId: string, sender: string, eventType: string, containsUrl: boolean): boolean {\n const literalKeys = {\n \"rooms\": function(v: string): boolean {\n return roomId === v;\n },\n \"senders\": function(v: string): boolean {\n return sender === v;\n
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2015 - 2021 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 * @module filter\n */\n\nimport { FilterComponent, IFilterComponent } from \"./filter-component\";\nimport { MatrixEvent } from \"./models/event\";\n\n/**\n * @param {Object} obj\n * @param {string} keyNesting\n * @param {*} val\n */\nfunction setProp(obj: object, keyNesting: string, val: any) {\n const nestedKeys = keyNesting.split(\".\");\n let currentObj = obj;\n for (let i = 0; i < (nestedKeys.length - 1); i++) {\n if (!currentObj[nestedKeys[i]]) {\n currentObj[nestedKeys[i]] = {};\n }\n currentObj = currentObj[nestedKeys[i]];\n }\n currentObj[nestedKeys[nestedKeys.length - 1]] = val;\n}\n\n/* eslint-disable camelcase */\nexport interface IFilterDefinition {\n event_fields?: string[];\n event_format?: \"client\" | \"federation\";\n presence?: IFilterComponent;\n account_data?: IFilterComponent;\n room?: IRoomFilter;\n}\n\nexport interface IRoomEventFilter extends IFilterComponent {\n lazy_load_members?: boolean;\n include_redundant_members?: boolean;\n}\n\ninterface IStateFilter extends IRoomEventFilter {}\n\ninterface IRoomFilter {\n not_rooms?: string[];\n rooms?: string[];\n ephemeral?: IRoomEventFilter;\n include_leave?: boolean;\n state?: IStateFilter;\n timeline?: IRoomEventFilter;\n account_data?: IRoomEventFilter;\n}\n/* eslint-enable camelcase */\n\n/**\n * Construct a new Filter.\n * @constructor\n * @param {string} userId The user ID for this filter.\n * @param {string=} filterId The filter ID if known.\n * @prop {string} userId The user ID of the filter\n * @prop {?string} filterId The filter ID\n */\nexport class Filter {\n static LAZY_LOADING_MESSAGES_FILTER = {\n lazy_load_members: true,\n };\n\n /**\n * Create a filter from existing data.\n * @static\n * @param {string} userId\n * @param {string} filterId\n * @param {Object} jsonObj\n * @return {Filter}\n */\n public static fromJson(userId: string, filterId: string, jsonObj: IFilterDefinition): Filter {\n const filter = new Filter(userId, filterId);\n filter.setDefinition(jsonObj);\n return filter;\n }\n\n private definition: IFilterDefinition = {};\n private roomFilter: FilterComponent;\n private roomTimelineFilter: FilterComponent;\n\n constructor(public readonly userId: string, public filterId?: string) {}\n\n /**\n * Get the ID of this filter on your homeserver (if known)\n * @return {?string} The filter ID\n */\n getFilterId(): string | null {\n return this.filterId;\n }\n\n /**\n * Get the JSON body of the filter.\n * @return {Object} The filter definition\n */\n getDefinition(): IFilterDefinition {\n return this.definition;\n }\n\n /**\n * Set the JSON body of the filter\n * @param {Object} definition The filter definition\n */\n setDefinition(definition: IFilterDefinition) {\n this.definition = definition;\n\n // This is all ported from synapse's FilterCollection()\n\n // definitions look something like:\n // {\n // \"room\": {\n // \"rooms\": [\"!abcde:example.com\"],\n // \"not_rooms\": [\"!123456:example.com\"],\n // \"state\": {\n // \"types\": [\"m.room.*\"],\n // \"not_rooms\": [\"!726s6s6q:example.com\"],\n // \"lazy_load_members\": true,\n // },\n // \"timeline\"
"/*\nCopyright 2015, 2016 OpenMarket 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\n/**\n * This is an internal module. See {@link MatrixHttpApi} for the public class.\n * @module http-api\n */\n\nimport { parse as parseContentType } from \"content-type\";\nimport * as utils from \"./utils\";\nimport { logger } from './logger';\n\n// we use our own implementation of setTimeout, so that if we get suspended in\n// the middle of a /sync, we cancel the sync as soon as we awake, rather than\n// waiting for the delay to elapse.\nimport * as callbacks from \"./realtime-callbacks\";\n\n/*\nTODO:\n- CS: complete register function (doing stages)\n- Identity server: linkEmail, authEmail, bindEmail, lookup3pid\n*/\n\n/**\n * A constant representing the URI path for release 0 of the Client-Server HTTP API.\n */\nexport const PREFIX_R0 = \"/_matrix/client/r0\";\n\n/**\n * A constant representing the URI path for as-yet unspecified Client-Server HTTP APIs.\n */\nexport const PREFIX_UNSTABLE = \"/_matrix/client/unstable\";\n\n/**\n * URI path for v1 of the the identity API\n * @deprecated Use v2.\n */\nexport const PREFIX_IDENTITY_V1 = \"/_matrix/identity/api/v1\";\n\n/**\n * URI path for the v2 identity API\n */\nexport const PREFIX_IDENTITY_V2 = \"/_matrix/identity/v2\";\n\n/**\n * URI path for the media repo API\n */\nexport const PREFIX_MEDIA_R0 = \"/_matrix/media/r0\";\n\n/**\n * Construct a MatrixHttpApi.\n * @constructor\n * @param {EventEmitter} event_emitter The event emitter to use for emitting events\n * @param {Object} opts The options to use for this HTTP API.\n * @param {string} opts.baseUrl Required. The base client-server URL e.g.\n * 'http://localhost:8008'.\n * @param {Function} opts.request Required. The function to call for HTTP\n * requests. This function must look like function(opts, callback){ ... }.\n * @param {string} opts.prefix Required. The matrix client prefix to use, e.g.\n * '/_matrix/client/r0'. See PREFIX_R0 and PREFIX_UNSTABLE for constants.\n *\n * @param {boolean} opts.onlyData True to return only the 'data' component of the\n * response (e.g. the parsed HTTP body). If false, requests will return an\n * object with the properties <tt>code</tt>, <tt>headers</tt> and <tt>data</tt>.\n *\n * @param {string} opts.accessToken The access_token to send with requests. Can be\n * null to not send an access token.\n * @param {Object=} opts.extraParams Optional. Extra query parameters to send on\n * requests.\n * @param {Number=} opts.localTimeoutMs The default maximum amount of time to wait\n * before timing out the request. If not specified, there is no timeout.\n * @param {boolean} [opts.useAuthorizationHeader = false] Set to true to use\n * Authorization header instead of query param to send the access token to the server.\n */\nexport function MatrixHttpApi(event_emitter, opts) {\n utils.checkObjectHasKeys(opts, [\"baseUrl\", \"request\", \"prefix\"]);\n opts.onlyData = opts.onlyData || false;\n this.event_emitter = event_emitter;\n this.opts = opts;\n this.useAuthorizationHeader = Boolean(opts.useAuthorizationHeader);\n this.uploads = [];\n}\n\nMatrixHttpApi.prototype = {\n /**\n * Sets the baase URL for the identity server\n * @param {string} url The new base url\n */\n setIdBaseUrl: function(url) {\n this.opts.idBaseUrl = url;\n },\n\n /**\n * Get the content repository url with query parameters.\n * @return {Object} An object with a 'base', 'path' and 'params' for base URL,\n * path and
"/*\nCopyright 2019 New Vector Ltd\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 * Check if an IndexedDB database exists. The only way to do so is to try opening it, so\n * we do that and then delete it did not exist before.\n *\n * @param {Object} indexedDB The `indexedDB` interface\n * @param {string} dbName The database name to test for\n * @returns {boolean} Whether the database exists\n */\nexport function exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> {\n return new Promise<boolean>((resolve, reject) => {\n let exists = true;\n const req = indexedDB.open(dbName);\n req.onupgradeneeded = () => {\n // Since we did not provide an explicit version when opening, this event\n // should only fire if the DB did not exist before at any version.\n exists = false;\n };\n req.onblocked = () => reject(req.error);\n req.onsuccess = () => {\n const db = req.result;\n db.close();\n if (!exists) {\n // The DB did not exist before, but has been created as part of this\n // existence check. Delete it now to restore previous state. Delete can\n // actually take a while to complete in some browsers, so don't wait for\n // it. This won't block future open calls that a store might issue next to\n // properly set up the DB.\n indexedDB.deleteDatabase(dbName);\n }\n resolve(exists);\n };\n req.onerror = ev => reject(req.error);\n });\n}\n",
"/*\nCopyright 2016 OpenMarket Ltd\nCopyright 2017 Vector Creations 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\n/** @module interactive-auth */\n\nimport * as utils from \"./utils\";\nimport { logger } from './logger';\n\nconst EMAIL_STAGE_TYPE = \"m.login.email.identity\";\nconst MSISDN_STAGE_TYPE = \"m.login.msisdn\";\n\n/**\n * Abstracts the logic used to drive the interactive auth process.\n *\n * <p>Components implementing an interactive auth flow should instantiate one of\n * these, passing in the necessary callbacks to the constructor. They should\n * then call attemptAuth, which will return a promise which will resolve or\n * reject when the interactive-auth process completes.\n *\n * <p>Meanwhile, calls will be made to the startAuthStage and doRequest\n * callbacks, and information gathered from the user can be submitted with\n * submitAuthDict.\n *\n * @constructor\n * @alias module:interactive-auth\n *\n * @param {object} opts options object\n *\n * @param {object} opts.matrixClient A matrix client to use for the auth process\n *\n * @param {object?} opts.authData error response from the last request. If\n * null, a request will be made with no auth before starting.\n *\n * @param {function(object?): Promise} opts.doRequest\n * called with the new auth dict to submit the request. Also passes a\n * second deprecated arg which is a flag set to true if this request\n * is a background request. The busyChanged callback should be used\n * instead of the backfround flag. Should return a promise which resolves\n * to the successful response or rejects with a MatrixError.\n *\n * @param {function(bool): Promise} opts.busyChanged\n * called whenever the interactive auth logic becomes busy submitting\n * information provided by the user or finsihes. After this has been\n * called with true the UI should indicate that a request is in progress\n * until it is called again with false.\n *\n * @param {function(string, object?)} opts.stateUpdated\n * called when the status of the UI auth changes, ie. when the state of\n * an auth stage changes of when the auth flow moves to a new stage.\n * The arguments are: the login type (eg m.login.password); and an object\n * which is either an error or an informational object specific to the\n * login type. If the 'errcode' key is defined, the object is an error,\n * and has keys:\n * errcode: string, the textual error code, eg. M_UNKNOWN\n * error: string, human readable string describing the error\n *\n * The login type specific objects are as follows:\n * m.login.email.identity:\n * * emailSid: string, the sid of the active email auth session\n *\n * @param {object?} opts.inputs Inputs provided by the user and used by different\n * stages of the auto process. The inputs provided will affect what flow is chosen.\n *\n * @param {string?} opts.inputs.emailAddress An email address. If supplied, a flow\n * using email verification will be chosen.\n *\n * @param {string?} opts.inputs.phoneCountry An ISO two letter country code. Gives\n * the country that opts.phoneNumber should be resolved relative to.\n *\n * @param {string?} opts.inputs.phoneNumber A phone number. If supplied, a flow\n * using phone number validation will be chosen.\n *\n * @param {string?} opts.sessionId If resuming an existing interactive auth session,\n * the sessionId of that session.\n *\n * @param {string?} opts.clientSecret If resuming an exis
"/*\nCopyright 2018 André Jaenisch\nCopyright 2019, 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 * @module logger\n */\n\nimport log, { Logger } from \"loglevel\";\n\n// This is to demonstrate, that you can use any namespace you want.\n// Namespaces allow you to turn on/off the logging for specific parts of the\n// application.\n// An idea would be to control this via an environment variable (on Node.js).\n// See https://www.npmjs.com/package/debug to see how this could be implemented\n// Part of #332 is introducing a logging library in the first place.\nconst DEFAULT_NAMESPACE = \"matrix\";\n\n// because rageshakes in react-sdk hijack the console log, also at module load time,\n// initializing the logger here races with the initialization of rageshakes.\n// to avoid the issue, we override the methodFactory of loglevel that binds to the\n// console methods at initialization time by a factory that looks up the console methods\n// when logging so we always get the current value of console methods.\nlog.methodFactory = function(methodName, logLevel, loggerName) {\n return function(...args) {\n /* eslint-disable @typescript-eslint/no-invalid-this */\n if (this.prefix) {\n args.unshift(this.prefix);\n }\n /* eslint-enable @typescript-eslint/no-invalid-this */\n const supportedByConsole = methodName === \"error\" ||\n methodName === \"warn\" ||\n methodName === \"trace\" ||\n methodName === \"info\";\n /* eslint-disable no-console */\n if (supportedByConsole) {\n return console[methodName](...args);\n } else {\n return console.log(...args);\n }\n /* eslint-enable no-console */\n };\n};\n\n/**\n * Drop-in replacement for <code>console</code> using {@link https://www.npmjs.com/package/loglevel|loglevel}.\n * Can be tailored down to specific use cases if needed.\n */\nexport const logger: PrefixedLogger = log.getLogger(DEFAULT_NAMESPACE);\nlogger.setLevel(log.levels.DEBUG);\n\nexport interface PrefixedLogger extends Logger {\n withPrefix?: (prefix: string) => PrefixedLogger;\n prefix?: string;\n}\n\nfunction extendLogger(logger: PrefixedLogger) {\n logger.withPrefix = function(prefix: string): PrefixedLogger {\n const existingPrefix = this.prefix || \"\";\n return getPrefixedLogger(existingPrefix + prefix);\n };\n}\n\nextendLogger(logger);\n\nfunction getPrefixedLogger(prefix): PrefixedLogger {\n const prefixLogger: PrefixedLogger = log.getLogger(`${DEFAULT_NAMESPACE}-${prefix}`);\n if (prefixLogger.prefix !== prefix) {\n // Only do this setup work the first time through, as loggers are saved by name.\n extendLogger(prefixLogger);\n prefixLogger.prefix = prefix;\n prefixLogger.setLevel(log.levels.DEBUG);\n }\n return prefixLogger;\n}\n",
"/*\nCopyright 2015-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 { MemoryCryptoStore } from \"./crypto/store/memory-crypto-store\";\nimport { MemoryStore } from \"./store/memory\";\nimport { MatrixScheduler } from \"./scheduler\";\nimport { MatrixClient } from \"./client\";\nimport { ICreateClientOpts } from \"./client\";\nimport { DeviceTrustLevel } from \"./crypto/CrossSigning\";\nimport { ISecretStorageKeyInfo } from \"./crypto/api\";\n\nexport * from \"./client\";\nexport * from \"./http-api\";\nexport * from \"./autodiscovery\";\nexport * from \"./sync-accumulator\";\nexport * from \"./errors\";\nexport * from \"./models/event\";\nexport * from \"./models/room\";\nexport * from \"./models/group\";\nexport * from \"./models/event-timeline\";\nexport * from \"./models/event-timeline-set\";\nexport * from \"./models/room-member\";\nexport * from \"./models/room-state\";\nexport * from \"./models/user\";\nexport * from \"./scheduler\";\nexport * from \"./filter\";\nexport * from \"./timeline-window\";\nexport * from \"./interactive-auth\";\nexport * from \"./service-types\";\nexport * from \"./store/memory\";\nexport * from \"./store/indexeddb\";\nexport * from \"./store/session/webstorage\";\nexport * from \"./crypto/store/memory-crypto-store\";\nexport * from \"./crypto/store/indexeddb-crypto-store\";\nexport * from \"./content-repo\";\nexport * as ContentHelpers from \"./content-helpers\";\nexport {\n createNewMatrixCall,\n setAudioInput as setMatrixCallAudioInput,\n setVideoInput as setMatrixCallVideoInput,\n} from \"./webrtc/call\";\n\n// expose the underlying request object so different environments can use\n// different request libs (e.g. request or browser-request)\nlet requestInstance;\n\n/**\n * The function used to perform HTTP requests. Only use this if you want to\n * use a different HTTP library, e.g. Angular's <code>$http</code>. This should\n * be set prior to calling {@link createClient}.\n * @param {requestFunction} r The request function to use.\n */\nexport function request(r) {\n requestInstance = r;\n}\n\n/**\n * Return the currently-set request function.\n * @return {requestFunction} The current request function.\n */\nexport function getRequest() {\n return requestInstance;\n}\n\n/**\n * Apply wrapping code around the request function. The wrapper function is\n * installed as the new request handler, and when invoked it is passed the\n * previous value, along with the options and callback arguments.\n * @param {requestWrapperFunction} wrapper The wrapping function.\n */\nexport function wrapRequest(wrapper) {\n const origRequest = requestInstance;\n requestInstance = function(options, callback) {\n return wrapper(origRequest, options, callback);\n };\n}\n\nlet cryptoStoreFactory = () => new MemoryCryptoStore;\n\n/**\n * Configure a different factory to be used for creating crypto stores\n *\n * @param {Function} fac a function which will return a new\n * {@link module:crypto.store.base~CryptoStore}.\n */\nexport function setCryptoStoreFactory(fac) {\n cryptoStoreFactory = fac;\n}\n\nexport interface ICryptoCallbacks {\n getCrossSigningKey?: (keyType: string, pubKey: string) => Promise<Uint8Array>;\n saveCrossSigningKeys?: (keys: Record<string, Uint8Array>) => void;\n shouldUpgradeDeviceVerifications?: (\n users: Record<string, any>\n ) => Promise<string[]>;\n getSecretStorageKey?: (\n keys: {keys: Record<string, ISecretStorageKeyInfo>}, name: string\n ) => Promise<[string, Uint8Array]
"/*\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 { MatrixClient } from \"../client\";\nimport { IEncryptedFile, UNSTABLE_MSC3089_BRANCH } from \"../@types/event\";\nimport { MatrixEvent } from \"./event\";\n\n/**\n * Represents a [MSC3089](https://github.com/matrix-org/matrix-doc/pull/3089) branch - a reference\n * to a file (leaf) in the tree. Note that this is UNSTABLE and subject to breaking changes\n * without notice.\n */\nexport class MSC3089Branch {\n public constructor(private client: MatrixClient, public readonly indexEvent: MatrixEvent) {\n // Nothing to do\n }\n\n /**\n * The file ID.\n */\n public get id(): string {\n return this.indexEvent.getStateKey();\n }\n\n /**\n * Whether this branch is active/valid.\n */\n public get isActive(): boolean {\n return this.indexEvent.getContent()[\"active\"] === true;\n }\n\n private get roomId(): string {\n return this.indexEvent.getRoomId();\n }\n\n /**\n * Deletes the file from the tree.\n * @returns {Promise<void>} Resolves when complete.\n */\n public async delete(): Promise<void> {\n await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, {}, this.id);\n await this.client.redactEvent(this.roomId, this.id);\n\n // TODO: Delete edit history as well\n }\n\n /**\n * Gets the name for this file.\n * @returns {string} The name, or \"Unnamed File\" if unknown.\n */\n public getName(): string {\n return this.indexEvent.getContent()['name'] || \"Unnamed File\";\n }\n\n /**\n * Sets the name for this file.\n * @param {string} name The new name for this file.\n * @returns {Promise<void>} Resolves when complete.\n */\n public async setName(name: string): Promise<void> {\n await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, {\n ...this.indexEvent.getContent(),\n name: name,\n }, this.id);\n }\n\n /**\n * Gets information about the file needed to download it.\n * @returns {Promise<{info: IEncryptedFile, httpUrl: string}>} Information about the file.\n */\n public async getFileInfo(): Promise<{ info: IEncryptedFile, httpUrl: string }> {\n const event = await this.getFileEvent();\n\n const file = event.getContent()['file'];\n const httpUrl = this.client.mxcUrlToHttp(file['url']);\n\n return { info: file, httpUrl: httpUrl };\n }\n\n /**\n * Gets the event the file points to.\n * @returns {Promise<MatrixEvent>} Resolves to the file's event.\n */\n public async getFileEvent(): Promise<MatrixEvent> {\n const room = this.client.getRoom(this.roomId);\n if (!room) throw new Error(\"Unknown room\");\n\n const timeline = await this.client.getEventTimeline(room.getUnfilteredTimelineSet(), this.id);\n if (!timeline) throw new Error(\"Failed to get timeline for room event\");\n\n const event = timeline.getEvents().find(e => e.getId() === this.id);\n if (!event) throw new Error(\"Failed to find event\");\n\n // Sometimes the event context doesn't decrypt for us, so do that.\n await this.client.decryptEventIfNeeded(event, { emit: false, isRetry: false });\n\n return event;\n }\n}\n",
"/*\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 { MatrixClient } from \"../client\";\nimport { EventType, IEncryptedFile, MsgType, UNSTABLE_MSC3089_BRANCH, UNSTABLE_MSC3089_LEAF } from \"../@types/event\";\nimport { Room } from \"./room\";\nimport { logger } from \"../logger\";\nimport { MatrixEvent } from \"./event\";\nimport {\n averageBetweenStrings,\n DEFAULT_ALPHABET,\n lexicographicCompare,\n nextString,\n prevString,\n simpleRetryOperation,\n} from \"../utils\";\nimport { MSC3089Branch } from \"./MSC3089Branch\";\nimport promiseRetry from \"p-retry\";\nimport { isRoomSharedHistory } from \"../crypto/algorithms/megolm\";\n\n/**\n * The recommended defaults for a tree space's power levels. Note that this\n * is UNSTABLE and subject to breaking changes without notice.\n */\nexport const DEFAULT_TREE_POWER_LEVELS_TEMPLATE = {\n // Owner\n invite: 100,\n kick: 100,\n ban: 100,\n\n // Editor\n redact: 50,\n state_default: 50,\n events_default: 50,\n\n // Viewer\n users_default: 0,\n\n // Mixed\n events: {\n [EventType.RoomPowerLevels]: 100,\n [EventType.RoomHistoryVisibility]: 100,\n [EventType.RoomTombstone]: 100,\n [EventType.RoomEncryption]: 100,\n [EventType.RoomName]: 50,\n [EventType.RoomMessage]: 50,\n [EventType.RoomMessageEncrypted]: 50,\n [EventType.Sticker]: 50,\n },\n\n users: {}, // defined by calling code\n};\n\n/**\n * Ease-of-use representation for power levels represented as simple roles.\n * Note that this is UNSTABLE and subject to breaking changes without notice.\n */\nexport enum TreePermissions {\n Viewer = \"viewer\", // Default\n Editor = \"editor\", // \"Moderator\" or ~PL50\n Owner = \"owner\", // \"Admin\" or PL100\n}\n\n/**\n * Represents a [MSC3089](https://github.com/matrix-org/matrix-doc/pull/3089)\n * file tree Space. Note that this is UNSTABLE and subject to breaking changes\n * without notice.\n */\nexport class MSC3089TreeSpace {\n public readonly room: Room;\n\n public constructor(private client: MatrixClient, public readonly roomId: string) {\n this.room = this.client.getRoom(this.roomId);\n\n if (!this.room) throw new Error(\"Unknown room\");\n }\n\n /**\n * Syntactic sugar for room ID of the Space.\n */\n public get id(): string {\n return this.roomId;\n }\n\n /**\n * Whether or not this is a top level space.\n */\n public get isTopLevel(): boolean {\n // XXX: This is absolutely not how you find out if the space is top level\n // but is safe for a managed usecase like we offer in the SDK.\n const parentEvents = this.room.currentState.getStateEvents(EventType.SpaceParent);\n if (!parentEvents?.length) return true;\n return parentEvents.every(e => !e.getContent()?.['via']);\n }\n\n /**\n * Sets the name of the tree space.\n * @param {string} name The new name for the space.\n * @returns {Promise<void>} Resolves when complete.\n */\n public async setName(name: string): Promise<void> {\n await this.client.sendStateEvent(this.roomId, EventType.RoomName, { name }, \"\");\n }\n\n /**\n * Invites a user to the tree space. They will be given the default Viewer\n * permission level unless specified elsewhere.\n * @param {string} userId The user ID to invite.\n * @param {boolean} andSubspaces True (default) to invite the user to all\n * directories/subspaces too, r
"/*\nCopyright 2015 - 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 \"./event\";\nimport { Direction } from \"./event-timeline\";\n\n/**\n * @module models/event-context\n */\nexport class EventContext {\n private timeline: MatrixEvent[];\n private ourEventIndex = 0;\n private paginateTokens: Record<Direction, string | null> = {\n [Direction.Backward]: null,\n [Direction.Forward]: null,\n };\n\n /**\n * Construct a new EventContext\n *\n * An eventcontext is used for circumstances such as search results, when we\n * have a particular event of interest, and a bunch of events before and after\n * it.\n *\n * It also stores pagination tokens for going backwards and forwards in the\n * timeline.\n *\n * @param {MatrixEvent} ourEvent the event at the centre of this context\n *\n * @constructor\n */\n constructor(ourEvent: MatrixEvent) {\n this.timeline = [ourEvent];\n }\n\n /**\n * Get the main event of interest\n *\n * This is a convenience function for getTimeline()[getOurEventIndex()].\n *\n * @return {MatrixEvent} The event at the centre of this context.\n */\n public getEvent(): MatrixEvent {\n return this.timeline[this.ourEventIndex];\n }\n\n /**\n * Get the list of events in this context\n *\n * @return {Array} An array of MatrixEvents\n */\n public getTimeline(): MatrixEvent[] {\n return this.timeline;\n }\n\n /**\n * Get the index in the timeline of our event\n *\n * @return {Number}\n */\n public getOurEventIndex(): number {\n return this.ourEventIndex;\n }\n\n /**\n * Get a pagination token.\n *\n * @param {boolean} backwards true to get the pagination token for going\n * backwards in time\n * @return {string}\n */\n public getPaginateToken(backwards = false): string {\n return this.paginateTokens[backwards ? Direction.Backward : Direction.Forward];\n }\n\n /**\n * Set a pagination token.\n *\n * Generally this will be used only by the matrix js sdk.\n *\n * @param {string} token pagination token\n * @param {boolean} backwards true to set the pagination token for going\n * backwards in time\n */\n public setPaginateToken(token: string, backwards = false): void {\n this.paginateTokens[backwards ? Direction.Backward : Direction.Forward] = token;\n }\n\n /**\n * Add more events to the timeline\n *\n * @param {Array} events new events, in timeline order\n * @param {boolean} atStart true to insert new events at the start\n */\n public addEvents(events: MatrixEvent[], atStart = false): void {\n // TODO: should we share logic with Room.addEventsToTimeline?\n // Should Room even use EventContext?\n\n if (atStart) {\n this.timeline = events.concat(this.timeline);\n this.ourEventIndex += events.length;\n } else {\n this.timeline = this.timeline.concat(events);\n }\n }\n}\n",
"/*\nCopyright 2016 - 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 * @module models/event-timeline-set\n */\n\nimport { EventEmitter } from \"events\";\n\nimport { EventTimeline } from \"./event-timeline\";\nimport { EventStatus, MatrixEvent } from \"./event\";\nimport { logger } from '../logger';\nimport { Relations } from './relations';\nimport { Room } from \"./room\";\nimport { Filter } from \"../filter\";\nimport { EventType, RelationType } from \"../@types/event\";\n\n// var DEBUG = false;\nconst DEBUG = true;\n\nlet debuglog;\nif (DEBUG) {\n // using bind means that we get to keep useful line numbers in the console\n debuglog = logger.log.bind(logger);\n} else {\n debuglog = function() {};\n}\n\ninterface IOpts {\n timelineSupport?: boolean;\n filter?: Filter;\n unstableClientRelationAggregation?: boolean;\n}\n\nexport class EventTimelineSet extends EventEmitter {\n private readonly timelineSupport: boolean;\n private unstableClientRelationAggregation: boolean;\n private liveTimeline: EventTimeline;\n private timelines: EventTimeline[];\n private _eventIdToTimeline: Record<string, EventTimeline>;\n private filter?: Filter;\n private relations: Record<string, Record<string, Record<RelationType, Relations>>>;\n\n /**\n * Construct a set of EventTimeline objects, typically on behalf of a given\n * room. A room may have multiple EventTimelineSets for different levels\n * of filtering. The global notification list is also an EventTimelineSet, but\n * lacks a room.\n *\n * <p>This is an ordered sequence of timelines, which may or may not\n * be continuous. Each timeline lists a series of events, as well as tracking\n * the room state at the start and the end of the timeline (if appropriate).\n * It also tracks forward and backward pagination tokens, as well as containing\n * links to the next timeline in the sequence.\n *\n * <p>There is one special timeline - the 'live' timeline, which represents the\n * timeline to which events are being added in real-time as they are received\n * from the /sync API. Note that you should not retain references to this\n * timeline - even if it is the current timeline right now, it may not remain\n * so if the server gives us a timeline gap in /sync.\n *\n * <p>In order that we can find events from their ids later, we also maintain a\n * map from event_id to timeline and index.\n *\n * @constructor\n * @param {?Room} room\n * Room for this timelineSet. May be null for non-room cases, such as the\n * notification timeline.\n * @param {Object} opts Options inherited from Room.\n *\n * @param {boolean} [opts.timelineSupport = false]\n * Set to true to enable improved timeline support.\n * @param {Object} [opts.filter = null]\n * The filter object, if any, for this timelineSet.\n * @param {boolean} [opts.unstableClientRelationAggregation = false]\n * Optional. Set to true to enable client-side aggregation of event relations\n * via `getRelationsForEvent`.\n * This feature is currently unstable and the API may change without notice.\n */\n constructor(public readonly room: Room, opts: IOpts) {\n super();\n\n this.timelineSupport = Boolean(opts.timelineSupport);\n this.liveTimeline = new EventTimeline(this);\n this.unstableClientRelationAggregation = !!opts.unstableClientRelationAggregation;\n\n // just a list - *not* ordered.\n
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2016 - 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 * @module models/event-timeline\n */\n\nimport { RoomState } from \"./room-state\";\nimport { EventTimelineSet } from \"./event-timeline-set\";\nimport { MatrixEvent } from \"./event\";\nimport { Filter } from \"../filter\";\nimport { EventType } from \"../@types/event\";\n\nexport enum Direction {\n Backward = \"b\",\n Forward = \"f\",\n}\n\nexport class EventTimeline {\n /**\n * Symbolic constant for methods which take a 'direction' argument:\n * refers to the start of the timeline, or backwards in time.\n */\n static BACKWARDS = Direction.Backward;\n\n /**\n * Symbolic constant for methods which take a 'direction' argument:\n * refers to the end of the timeline, or forwards in time.\n */\n static FORWARDS = Direction.Forward;\n\n /**\n * Static helper method to set sender and target properties\n *\n * @param {MatrixEvent} event the event whose metadata is to be set\n * @param {RoomState} stateContext the room state to be queried\n * @param {boolean} toStartOfTimeline if true the event's forwardLooking flag is set false\n */\n static setEventMetadata(event: MatrixEvent, stateContext: RoomState, toStartOfTimeline: boolean): void {\n // When we try to generate a sentinel member before we have that member\n // in the members object, we still generate a sentinel but it doesn't\n // have a membership event, so test to see if events.member is set. We\n // check this to avoid overriding non-sentinel members by sentinel ones\n // when adding the event to a filtered timeline\n if (!event.sender?.events?.member) {\n event.sender = stateContext.getSentinelMember(event.getSender());\n }\n if (!event.target?.events?.member && event.getType() === EventType.RoomMember) {\n event.target = stateContext.getSentinelMember(event.getStateKey());\n }\n\n if (event.isState()) {\n // room state has no concept of 'old' or 'current', but we want the\n // room state to regress back to previous values if toStartOfTimeline\n // is set, which means inspecting prev_content if it exists. This\n // is done by toggling the forwardLooking flag.\n if (toStartOfTimeline) {\n event.forwardLooking = false;\n }\n }\n }\n\n private readonly roomId: string | null;\n private readonly name: string;\n private events: MatrixEvent[] = [];\n private baseIndex = 0;\n private startState: RoomState;\n private endState: RoomState;\n private prevTimeline?: EventTimeline;\n private nextTimeline?: EventTimeline;\n public paginationRequests: Record<Direction, Promise<boolean>> = {\n [Direction.Backward]: null,\n [Direction.Forward]: null,\n };\n\n /**\n * Construct a new EventTimeline\n *\n * <p>An EventTimeline represents a contiguous sequence of events in a room.\n *\n * <p>As well as keeping track of the events themselves, it stores the state of\n * the room at the beginning and end of the timeline, and pagination tokens for\n * going backwards and forwards in the timeline.\n *\n * <p>In order that clients can meaningfully maintain an index into a timeline,\n * the EventTimeline object tracks a 'baseIndex'. This starts at zero, but is\n * incremented when events are prepended to the timeline. The index of an event\n
"/*\nCopyright 2015 - 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 * This is an internal module. See {@link MatrixEvent} and {@link RoomEvent} for\n * the public classes.\n * @module models/event\n */\n\nimport { EventEmitter } from 'events';\n\nimport { logger } from '../logger';\nimport { VerificationRequest } from \"../crypto/verification/request/VerificationRequest\";\nimport { EventType, MsgType, RelationType } from \"../@types/event\";\nimport { Crypto } from \"../crypto\";\nimport { deepSortedObjectEntries } from \"../utils\";\nimport { RoomMember } from \"./room-member\";\n\n/**\n * Enum for event statuses.\n * @readonly\n * @enum {string}\n */\nexport enum EventStatus {\n /** The event was not sent and will no longer be retried. */\n NOT_SENT = \"not_sent\",\n\n /** The message is being encrypted */\n ENCRYPTING = \"encrypting\",\n\n /** The event is in the process of being sent. */\n SENDING = \"sending\",\n\n /** The event is in a queue waiting to be sent. */\n QUEUED = \"queued\",\n\n /** The event has been sent to the server, but we have not yet received the echo. */\n SENT = \"sent\",\n\n /** The event was cancelled before it was successfully sent. */\n CANCELLED = \"cancelled\",\n}\n\nconst interns: Record<string, string> = {};\nfunction intern(str: string): string {\n if (!interns[str]) {\n interns[str] = str;\n }\n return interns[str];\n}\n\n/* eslint-disable camelcase */\nexport interface IContent {\n [key: string]: any;\n msgtype?: MsgType | string;\n membership?: string;\n avatar_url?: string;\n displayname?: string;\n \"m.relates_to\"?: IEventRelation;\n}\n\ntype StrippedState = Required<Pick<IEvent, \"content\" | \"state_key\" | \"type\" | \"sender\">>;\n\nexport interface IUnsigned {\n age?: number;\n prev_sender?: string;\n prev_content?: IContent;\n redacted_because?: IEvent;\n transaction_id?: string;\n invite_room_state?: StrippedState[];\n}\n\nexport interface IEvent {\n event_id: string;\n type: string;\n content: IContent;\n sender: string;\n room_id: string;\n origin_server_ts: number;\n txn_id?: string;\n state_key?: string;\n membership?: string;\n unsigned: IUnsigned;\n redacts?: string;\n\n // v1 legacy fields\n user_id?: string;\n prev_content?: IContent;\n age?: number;\n}\n\ninterface IAggregatedRelation {\n origin_server_ts: number;\n event_id?: string;\n sender?: string;\n type?: string;\n count?: number;\n key?: string;\n}\n\ninterface IEventRelation {\n rel_type: RelationType | string;\n event_id: string;\n key?: string;\n}\n\ninterface IDecryptionResult {\n clearEvent: {\n room_id?: string;\n type: string;\n content: IContent;\n unsigned?: IUnsigned;\n };\n forwardingCurve25519KeyChain?: string[];\n senderCurve25519Key?: string;\n claimedEd25519Key?: string;\n untrusted?: boolean;\n}\n/* eslint-enable camelcase */\n\nexport interface IClearEvent {\n type: string;\n content: Omit<IContent, \"membership\" | \"avatar_url\" | \"displayname\" | \"m.relates_to\">;\n unsigned?: IUnsigned;\n}\n\ninterface IKeyRequestRecipient {\n userId: string;\n deviceId: \"*\" | string;\n}\n\nexport interface IDecryptOptions {\n emit?: boolean;\n isRetry?: boolean;\n}\n\nexport class MatrixEvent extends EventEmitter {\n private pushActions: object = null;\n private _replacingEvent: MatrixEvent = null;\n private _localRedactionE
"/*\nCopyright 2017 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\n/**\n * @module models/group\n */\n\nimport * as utils from \"../utils\";\nimport { EventEmitter } from \"events\";\n\n/**\n * Construct a new Group.\n *\n * @param {string} groupId The ID of this group.\n *\n * @prop {string} groupId The ID of this group.\n * @prop {string} name The human-readable display name for this group.\n * @prop {string} avatarUrl The mxc URL for this group's avatar.\n * @prop {string} myMembership The logged in user's membership of this group\n * @prop {Object} inviter Infomation about the user who invited the logged in user\n * to the group, if myMembership is 'invite'.\n * @prop {string} inviter.userId The user ID of the inviter\n */\nexport function Group(groupId) {\n this.groupId = groupId;\n this.name = null;\n this.avatarUrl = null;\n this.myMembership = null;\n this.inviter = null;\n}\nutils.inherits(Group, EventEmitter);\n\nGroup.prototype.setProfile = function(name, avatarUrl) {\n if (this.name === name && this.avatarUrl === avatarUrl) return;\n\n this.name = name || this.groupId;\n this.avatarUrl = avatarUrl;\n\n this.emit(\"Group.profile\", this);\n};\n\nGroup.prototype.setMyMembership = function(membership) {\n if (this.myMembership === membership) return;\n\n this.myMembership = membership;\n\n this.emit(\"Group.myMembership\", this);\n};\n\n/**\n * Sets the 'inviter' property. This does not emit an event (the inviter\n * will only change when the user is revited / reinvited to a room),\n * so set this before setting myMembership.\n * @param {Object} inviter Infomation about who invited us to the room\n */\nGroup.prototype.setInviter = function(inviter) {\n this.inviter = inviter;\n};\n\n/**\n * Fires whenever a group's profile information is updated.\n * This means the 'name' and 'avatarUrl' properties.\n * @event module:client~MatrixClient#\"Group.profile\"\n * @param {Group} group The group whose profile was updated.\n * @example\n * matrixClient.on(\"Group.profile\", function(group){\n * var name = group.name;\n * });\n */\n\n/**\n * Fires whenever the logged in user's membership status of\n * the group is updated.\n * @event module:client~MatrixClient#\"Group.myMembership\"\n * @param {Group} group The group in which the user's membership changed\n * @example\n * matrixClient.on(\"Group.myMembership\", function(group){\n * var myMembership = group.myMembership;\n * });\n */\n",
"/*\nCopyright 2019, 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 { EventEmitter } from 'events';\n\nimport { EventStatus, MatrixEvent } from './event';\nimport { Room } from './room';\nimport { logger } from '../logger';\nimport { RelationType } from \"../@types/event\";\n\n/**\n * A container for relation events that supports easy access to common ways of\n * aggregating such events. Each instance holds events that of a single relation\n * type and event type. All of the events also relate to the same original event.\n *\n * The typical way to get one of these containers is via\n * EventTimelineSet#getRelationsForEvent.\n */\nexport class Relations extends EventEmitter {\n private relationEventIds = new Set<string>();\n private relations = new Set<MatrixEvent>();\n private annotationsByKey: Record<string, Set<MatrixEvent>> = {};\n private annotationsBySender: Record<string, Set<MatrixEvent>> = {};\n private sortedAnnotationsByKey: [string, Set<MatrixEvent>][] = [];\n private targetEvent: MatrixEvent = null;\n private creationEmitted = false;\n\n /**\n * @param {RelationType} relationType\n * The type of relation involved, such as \"m.annotation\", \"m.reference\",\n * \"m.replace\", etc.\n * @param {String} eventType\n * The relation event's type, such as \"m.reaction\", etc.\n * @param {?Room} room\n * Room for this container. May be null for non-room cases, such as the\n * notification timeline.\n */\n constructor(\n public readonly relationType: RelationType | string,\n public readonly eventType: string,\n private readonly room: Room,\n ) {\n super();\n }\n\n /**\n * Add relation events to this collection.\n *\n * @param {MatrixEvent} event\n * The new relation event to be added.\n */\n public async addEvent(event: MatrixEvent) {\n if (this.relationEventIds.has(event.getId())) {\n return;\n }\n\n const relation = event.getRelation();\n if (!relation) {\n logger.error(\"Event must have relation info\");\n return;\n }\n\n const relationType = relation.rel_type;\n const eventType = event.getType();\n\n if (this.relationType !== relationType || this.eventType !== eventType) {\n logger.error(\"Event relation info doesn't match this container\");\n return;\n }\n\n // If the event is in the process of being sent, listen for cancellation\n // so we can remove the event from the collection.\n if (event.isSending()) {\n event.on(\"Event.status\", this.onEventStatus);\n }\n\n this.relations.add(event);\n this.relationEventIds.add(event.getId());\n\n if (this.relationType === RelationType.Annotation) {\n this.addAnnotationToAggregation(event);\n } else if (this.relationType === RelationType.Replace && this.targetEvent) {\n const lastReplacement = await this.getLastReplacement();\n this.targetEvent.makeReplaced(lastReplacement);\n }\n\n event.on(\"Event.beforeRedaction\", this.onBeforeRedaction);\n\n this.emit(\"Relations.add\", event);\n\n this.maybeEmitCreated();\n }\n\n /**\n * Remove relation event from this collection.\n *\n * @param {MatrixEvent} event\n * The relation event to remove.\n */\n private async removeEvent(event: MatrixEvent) {\n if (!this.relations.has(event)) {\n
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2015 - 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 * @module models/room-member\n */\n\nimport { EventEmitter } from \"events\";\n\nimport { getHttpUriForMxc } from \"../content-repo\";\nimport * as utils from \"../utils\";\nimport { User } from \"./user\";\nimport { MatrixEvent } from \"./event\";\nimport { RoomState } from \"./room-state\";\n\nexport class RoomMember extends EventEmitter {\n private _isOutOfBand = false;\n private _modified: number;\n public _requestedProfileInfo: boolean; // used by sync.ts\n\n // XXX these should be read-only\n public typing = false;\n public name: string;\n public rawDisplayName: string;\n public powerLevel = 0;\n public powerLevelNorm = 0;\n public user?: User = null;\n public membership: string = null;\n public disambiguate = false;\n public events: {\n member?: MatrixEvent;\n } = {\n member: null,\n };\n\n /**\n * Construct a new room member.\n *\n * @constructor\n * @alias module:models/room-member\n *\n * @param {string} roomId The room ID of the member.\n * @param {string} userId The user ID of the member.\n * @prop {string} roomId The room ID for this member.\n * @prop {string} userId The user ID of this member.\n * @prop {boolean} typing True if the room member is currently typing.\n * @prop {string} name The human-readable name for this room member. This will be\n * disambiguated with a suffix of \" (@user_id:matrix.org)\" if another member shares the\n * same displayname.\n * @prop {string} rawDisplayName The ambiguous displayname of this room member.\n * @prop {Number} powerLevel The power level for this room member.\n * @prop {Number} powerLevelNorm The normalised power level (0-100) for this\n * room member.\n * @prop {User} user The User object for this room member, if one exists.\n * @prop {string} membership The membership state for this room member e.g. 'join'.\n * @prop {Object} events The events describing this RoomMember.\n * @prop {MatrixEvent} events.member The m.room.member event for this RoomMember.\n * @prop {boolean} disambiguate True if the member's name is disambiguated.\n */\n constructor(public readonly roomId: string, public readonly userId: string) {\n super();\n\n this.name = userId;\n this.rawDisplayName = userId;\n this.updateModifiedTime();\n }\n\n /**\n * Mark the member as coming from a channel that is not sync\n */\n public markOutOfBand(): void {\n this._isOutOfBand = true;\n }\n\n /**\n * @return {boolean} does the member come from a channel that is not sync?\n * This is used to store the member seperately\n * from the sync state so it available across browser sessions.\n */\n public isOutOfBand(): boolean {\n return this._isOutOfBand;\n }\n\n /**\n * Update this room member's membership event. May fire \"RoomMember.name\" if\n * this event updates this member's name.\n * @param {MatrixEvent} event The <code>m.room.member</code> event\n * @param {RoomState} roomState Optional. The room state to take into account\n * when calculating (e.g. for disambiguating users with the same name).\n * @fires module:client~MatrixClient#event:\"RoomMember.name\"\n * @fires module:client~MatrixClient#event:\"RoomMember.membership\"\n */\n public setMembershipEvent(event: MatrixEvent, roomState: RoomState): void {\n con
"/*\nCopyright 2015 - 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 * @module models/room-state\n */\n\nimport { EventEmitter } from \"events\";\n\nimport { RoomMember } from \"./room-member\";\nimport { logger } from '../logger';\nimport * as utils from \"../utils\";\nimport { EventType } from \"../@types/event\";\nimport { MatrixEvent } from \"./event\";\nimport { MatrixClient } from \"../client\";\n\n// possible statuses for out-of-band member loading\nenum OobStatus {\n NotStarted,\n InProgress,\n Finished,\n}\n\nexport class RoomState extends EventEmitter {\n private sentinels: Record<string, RoomMember> = {}; // userId: RoomMember\n // stores fuzzy matches to a list of userIDs (applies utils.removeHiddenChars to keys)\n private displayNameToUserIds: Record<string, string[]> = {};\n private userIdsToDisplayNames: Record<string, string> = {};\n private tokenToInvite: Record<string, MatrixEvent> = {}; // 3pid invite state_key to m.room.member invite\n private joinedMemberCount: number = null; // cache of the number of joined members\n // joined members count from summary api\n // once set, we know the server supports the summary api\n // and we should only trust that\n // we could also only trust that before OOB members\n // are loaded but doesn't seem worth the hassle atm\n private summaryJoinedMemberCount: number = null;\n // same for invited member count\n private invitedMemberCount: number = null;\n private summaryInvitedMemberCount: number = null;\n private modified: number;\n\n // XXX: Should be read-only\n public members: Record<string, RoomMember> = {}; // userId: RoomMember\n public events = new Map<string, Map<string, MatrixEvent>>(); // Map<eventType, Map<stateKey, MatrixEvent>>\n public paginationToken: string = null;\n\n /**\n * Construct room state.\n *\n * Room State represents the state of the room at a given point.\n * It can be mutated by adding state events to it.\n * There are two types of room member associated with a state event:\n * normal member objects (accessed via getMember/getMembers) which mutate\n * with the state to represent the current state of that room/user, eg.\n * the object returned by getMember('@bob:example.com') will mutate to\n * get a different display name if Bob later changes his display name\n * in the room.\n * There are also 'sentinel' members (accessed via getSentinelMember).\n * These also represent the state of room members at the point in time\n * represented by the RoomState object, but unlike objects from getMember,\n * sentinel objects will always represent the room state as at the time\n * getSentinelMember was called, so if Bob subsequently changes his display\n * name, a room member object previously acquired with getSentinelMember\n * will still have his old display name. Calling getSentinelMember again\n * after the display name change will return a new RoomMember object\n * with Bob's new display name.\n *\n * @constructor\n * @param {?string} roomId Optional. The ID of the room which has this state.\n * If none is specified it just tracks paginationTokens, useful for notifTimelineSet\n * @param {?object} oobMemberFlags Optional. The state of loading out of bound members.\n * As the timeline might get reset while they are loading, this state needs to be inherited\n * and shared when the room state is cloned for the new timeline.\n * This sho
"/*\nCopyright 2015 - 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 * @module models/room-summary\n */\n\nexport interface IRoomSummary {\n \"m.heroes\": string[];\n \"m.joined_member_count\": number;\n \"m.invited_member_count\": number;\n}\n\ninterface IInfo {\n title: string;\n desc?: string;\n numMembers?: number;\n aliases?: string[];\n timestamp?: number;\n}\n\n/**\n * Construct a new Room Summary. A summary can be used for display on a recent\n * list, without having to load the entire room list into memory.\n * @constructor\n * @param {string} roomId Required. The ID of this room.\n * @param {Object} info Optional. The summary info. Additional keys are supported.\n * @param {string} info.title The title of the room (e.g. <code>m.room.name</code>)\n * @param {string} info.desc The description of the room (e.g.\n * <code>m.room.topic</code>)\n * @param {Number} info.numMembers The number of joined users.\n * @param {string[]} info.aliases The list of aliases for this room.\n * @param {Number} info.timestamp The timestamp for this room.\n */\nexport class RoomSummary {\n constructor(public readonly roomId: string, info?: IInfo) {}\n}\n\n",
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2015 - 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 * @module models/room\n */\n\nimport { EventEmitter } from \"events\";\n\nimport { EventTimelineSet } from \"./event-timeline-set\";\nimport { EventTimeline } from \"./event-timeline\";\nimport { getHttpUriForMxc } from \"../content-repo\";\nimport * as utils from \"../utils\";\nimport { normalize } from \"../utils\";\nimport { EventStatus, IEvent, MatrixEvent } from \"./event\";\nimport { RoomMember } from \"./room-member\";\nimport { IRoomSummary, RoomSummary } from \"./room-summary\";\nimport { logger } from '../logger';\nimport { ReEmitter } from '../ReEmitter';\nimport { EventType, RoomCreateTypeField, RoomType, UNSTABLE_ELEMENT_FUNCTIONAL_USERS } from \"../@types/event\";\nimport { IRoomVersionsCapability, MatrixClient, PendingEventOrdering, RoomVersionStability } from \"../client\";\nimport { ResizeMethod } from \"../@types/partials\";\nimport { Filter } from \"../filter\";\nimport { RoomState } from \"./room-state\";\n\n// These constants are used as sane defaults when the homeserver doesn't support\n// the m.room_versions capability. In practice, KNOWN_SAFE_ROOM_VERSION should be\n// the same as the common default room version whereas SAFE_ROOM_VERSIONS are the\n// room versions which are considered okay for people to run without being asked\n// to upgrade (ie: \"stable\"). Eventually, we should remove these when all homeservers\n// return an m.room_versions capability.\nconst KNOWN_SAFE_ROOM_VERSION = '6';\nconst SAFE_ROOM_VERSIONS = ['1', '2', '3', '4', '5', '6'];\n\nfunction synthesizeReceipt(userId: string, event: MatrixEvent, receiptType: string): MatrixEvent {\n // console.log(\"synthesizing receipt for \"+event.getId());\n // This is really ugly because JS has no way to express an object literal\n // where the name of a key comes from an expression\n const fakeReceipt = {\n content: {},\n type: \"m.receipt\",\n room_id: event.getRoomId(),\n };\n fakeReceipt.content[event.getId()] = {};\n fakeReceipt.content[event.getId()][receiptType] = {};\n fakeReceipt.content[event.getId()][receiptType][userId] = {\n ts: event.getTs(),\n };\n return new MatrixEvent(fakeReceipt);\n}\n\ninterface IOpts {\n storageToken?: string;\n pendingEventOrdering?: PendingEventOrdering;\n timelineSupport?: boolean;\n unstableClientRelationAggregation?: boolean;\n lazyLoadMembers?: boolean;\n}\n\nexport interface IRecommendedVersion {\n version: string;\n needsUpgrade: boolean;\n urgent: boolean;\n}\n\ninterface IReceipt {\n ts: number;\n}\n\ninterface IWrappedReceipt {\n eventId: string;\n data: IReceipt;\n}\n\ninterface ICachedReceipt {\n type: string;\n userId: string;\n data: IReceipt;\n}\n\ntype ReceiptCache = Record<string, ICachedReceipt[]>;\n\ninterface IReceiptContent {\n [eventId: string]: {\n [type: string]: {\n [userId: string]: IReceipt;\n };\n };\n}\n\ntype Receipts = Record<string, Record<string, IWrappedReceipt>>;\n\nexport enum NotificationCountType {\n Highlight = \"highlight\",\n Total = \"total\",\n}\n\nexport class Room extends EventEmitter {\n private readonly reEmitter: ReEmitter;\n private txnToEvent: Record<string, MatrixEvent> = {}; // Pending in-flight requests { string: MatrixEvent }\n // receipts should clobber based on receipt_type and user_id pairs hence\n // the form of this structure. This is sub-optimal for the exposed APIs\n // which pass in a
"/*\nCopyright 2015 - 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 * @module models/search-result\n */\n\nimport { EventContext } from \"./event-context\";\nimport { EventMapper } from \"../event-mapper\";\nimport { IResultContext, ISearchResult } from \"../@types/search\";\n\nexport class SearchResult {\n /**\n * Create a SearchResponse from the response to /search\n * @static\n * @param {Object} jsonObj\n * @param {function} eventMapper\n * @return {SearchResult}\n */\n\n static fromJson(jsonObj: ISearchResult, eventMapper: EventMapper): SearchResult {\n const jsonContext = jsonObj.context || {} as IResultContext;\n const eventsBefore = jsonContext.events_before || [];\n const eventsAfter = jsonContext.events_after || [];\n\n const context = new EventContext(eventMapper(jsonObj.result));\n\n context.setPaginateToken(jsonContext.start, true);\n context.addEvents(eventsBefore.map(eventMapper), true);\n context.addEvents(eventsAfter.map(eventMapper), false);\n context.setPaginateToken(jsonContext.end, false);\n\n return new SearchResult(jsonObj.rank, context);\n }\n\n /**\n * Construct a new SearchResult\n *\n * @param {number} rank where this SearchResult ranks in the results\n * @param {event-context.EventContext} context the matching event and its\n * context\n *\n * @constructor\n */\n constructor(public readonly rank: number, public readonly context: EventContext) {}\n}\n\n",
"/*\nCopyright 2015 - 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 * @module models/user\n */\n\nimport { EventEmitter } from \"events\";\n\nimport { MatrixEvent } from \"./event\";\n\nexport class User extends EventEmitter {\n // eslint-disable-next-line camelcase\n private modified: number;\n\n // XXX these should be read-only\n public displayName: string;\n public rawDisplayName: string;\n public avatarUrl: string;\n public presenceStatusMsg: string = null;\n public presence = \"offline\";\n public lastActiveAgo = 0;\n public lastPresenceTs = 0;\n public currentlyActive = false;\n public events: {\n presence?: MatrixEvent;\n profile?: MatrixEvent;\n } = {\n presence: null,\n profile: null,\n };\n // eslint-disable-next-line camelcase\n public unstable_statusMessage = \"\";\n\n /**\n * Construct a new User. A User must have an ID and can optionally have extra\n * information associated with it.\n * @constructor\n * @param {string} userId Required. The ID of this user.\n * @prop {string} userId The ID of the user.\n * @prop {Object} info The info object supplied in the constructor.\n * @prop {string} displayName The 'displayname' of the user if known.\n * @prop {string} avatarUrl The 'avatar_url' of the user if known.\n * @prop {string} presence The presence enum if known.\n * @prop {string} presenceStatusMsg The presence status message if known.\n * @prop {Number} lastActiveAgo The time elapsed in ms since the user interacted\n * proactively with the server, or we saw a message from the user\n * @prop {Number} lastPresenceTs Timestamp (ms since the epoch) for when we last\n * received presence data for this user. We can subtract\n * lastActiveAgo from this to approximate an absolute value for\n * when a user was last active.\n * @prop {Boolean} currentlyActive Whether we should consider lastActiveAgo to be\n * an approximation and that the user should be seen as active 'now'\n * @prop {string} unstable_statusMessage The status message for the user, if known. This is\n * different from the presenceStatusMsg in that this is not tied to\n * the user's presence, and should be represented differently.\n * @prop {Object} events The events describing this user.\n * @prop {MatrixEvent} events.presence The m.presence event for this user.\n */\n constructor(public readonly userId: string) {\n super();\n this.displayName = userId;\n this.rawDisplayName = userId;\n this.avatarUrl = null;\n this.updateModifiedTime();\n }\n\n /**\n * Update this User with the given presence event. May fire \"User.presence\",\n * \"User.avatarUrl\" and/or \"User.displayName\" if this event updates this user's\n * properties.\n * @param {MatrixEvent} event The <code>m.presence</code> event.\n * @fires module:client~MatrixClient#event:\"User.presence\"\n * @fires module:client~MatrixClient#event:\"User.displayName\"\n * @fires module:client~MatrixClient#event:\"User.avatarUrl\"\n */\n public setPresenceEvent(event: MatrixEvent): void {\n if (event.getType() !== \"m.presence\") {\n return;\n }\n const firstFire = this.events.presence === null;\n this.events.presence = event;\n\n const eventsToFire = [];\n if
"/*\nCopyright 2015, 2016 OpenMarket Ltd\nCopyright 2017 New Vector Ltd\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 { escapeRegExp, globToRegexp, isNullOrUndefined } from \"./utils\";\nimport { logger } from './logger';\n\n/**\n * @module pushprocessor\n */\n\nconst RULEKINDS_IN_ORDER = ['override', 'content', 'room', 'sender', 'underride'];\n\n// The default override rules to apply to the push rules that arrive from the server.\n// We do this for two reasons:\n// 1. Synapse is unlikely to send us the push rule in an incremental sync - see\n// https://github.com/matrix-org/synapse/pull/4867#issuecomment-481446072 for\n// more details.\n// 2. We often want to start using push rules ahead of the server supporting them,\n// and so we can put them here.\nconst DEFAULT_OVERRIDE_RULES = [\n {\n // For homeservers which don't support MSC1930 yet\n rule_id: \".m.rule.tombstone\",\n default: true,\n enabled: true,\n conditions: [\n {\n kind: \"event_match\",\n key: \"type\",\n pattern: \"m.room.tombstone\",\n },\n {\n kind: \"event_match\",\n key: \"state_key\",\n pattern: \"\",\n },\n ],\n actions: [\n \"notify\",\n {\n set_tweak: \"highlight\",\n value: true,\n },\n ],\n },\n {\n // For homeservers which don't support MSC2153 yet\n rule_id: \".m.rule.reaction\",\n default: true,\n enabled: true,\n conditions: [\n {\n kind: \"event_match\",\n key: \"type\",\n pattern: \"m.reaction\",\n },\n ],\n actions: [\n \"dont_notify\",\n ],\n },\n];\n\n/**\n * Construct a Push Processor.\n * @constructor\n * @param {Object} client The Matrix client object to use\n */\nexport function PushProcessor(client) {\n const cachedGlobToRegex = {\n // $glob: RegExp,\n };\n\n const matchingRuleFromKindSet = (ev, kindset) => {\n for (let ruleKindIndex = 0;\n ruleKindIndex < RULEKINDS_IN_ORDER.length;\n ++ruleKindIndex) {\n const kind = RULEKINDS_IN_ORDER[ruleKindIndex];\n const ruleset = kindset[kind];\n if (!ruleset) {\n continue;\n }\n\n for (let ruleIndex = 0; ruleIndex < ruleset.length; ++ruleIndex) {\n const rule = ruleset[ruleIndex];\n if (!rule.enabled) {\n continue;\n }\n\n const rawrule = templateRuleToRaw(kind, rule);\n if (!rawrule) {\n continue;\n }\n\n if (this.ruleMatchesEvent(rawrule, ev)) {\n rule.kind = kind;\n return rule;\n }\n }\n }\n return null;\n };\n\n const templateRuleToRaw = function(kind, tprule) {\n const rawrule = {\n 'rule_id': tprule.rule_id,\n 'actions': tprule.actions,\n 'conditions': [],\n };\n switch (kind) {\n case 'underride':\n case 'override':\n rawrule.conditions = tprule.conditions;\n break;\n case 'room':\n if (!tprule.rule_id) {\n return null;\n }\n rawrule.conditions.pus
"/*\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\nconst LOWERCASE = \"abcdefghijklmnopqrstuvwxyz\";\nconst UPPERCASE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nconst DIGITS = \"0123456789\";\n\nexport function randomString(len: number): string {\n return randomStringFrom(len, UPPERCASE + LOWERCASE + DIGITS);\n}\n\nexport function randomLowercaseString(len: number): string {\n return randomStringFrom(len, LOWERCASE);\n}\n\nexport function randomUppercaseString(len: number): string {\n return randomStringFrom(len, UPPERCASE);\n}\n\nfunction randomStringFrom(len: number, chars: string): string {\n let ret = \"\";\n\n for (let i = 0; i < len; ++i) {\n ret += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n\n return ret;\n}\n",
"/*\nCopyright 2016 OpenMarket 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\n/* A re-implementation of the javascript callback functions (setTimeout,\n * clearTimeout; setInterval and clearInterval are not yet implemented) which\n * try to improve handling of large clock jumps (as seen when\n * suspending/resuming the system).\n *\n * In particular, if a timeout would have fired while the system was suspended,\n * it will instead fire as soon as possible after resume.\n */\n\nimport { logger } from './logger';\n\n// we schedule a callback at least this often, to check if we've missed out on\n// some wall-clock time due to being suspended.\nconst TIMER_CHECK_PERIOD_MS = 1000;\n\n// counter, for making up ids to return from setTimeout\nlet _count = 0;\n\n// the key for our callback with the real global.setTimeout\nlet _realCallbackKey;\n\n// a sorted list of the callbacks to be run.\n// each is an object with keys [runAt, func, params, key].\nconst _callbackList = [];\n\n// var debuglog = logger.log.bind(logger);\nconst debuglog = function() {};\n\n/**\n * Replace the function used by this module to get the current time.\n *\n * Intended for use by the unit tests.\n *\n * @param {function} [f] function which should return a millisecond counter\n *\n * @internal\n */\nexport function setNow(f) {\n _now = f || Date.now;\n}\nlet _now = Date.now;\n\n/**\n * reimplementation of window.setTimeout, which will call the callback if\n * the wallclock time goes past the deadline.\n *\n * @param {function} func callback to be called after a delay\n * @param {Number} delayMs number of milliseconds to delay by\n *\n * @return {Number} an identifier for this callback, which may be passed into\n * clearTimeout later.\n */\nexport function setTimeout(func, delayMs) {\n delayMs = delayMs || 0;\n if (delayMs < 0) {\n delayMs = 0;\n }\n\n const params = Array.prototype.slice.call(arguments, 2);\n const runAt = _now() + delayMs;\n const key = _count++;\n debuglog(\"setTimeout: scheduling cb\", key, \"at\", runAt,\n \"(delay\", delayMs, \")\");\n const data = {\n runAt: runAt,\n func: func,\n params: params,\n key: key,\n };\n\n // figure out where it goes in the list\n const idx = binarySearch(\n _callbackList, function(el) {\n return el.runAt - runAt;\n },\n );\n\n _callbackList.splice(idx, 0, data);\n _scheduleRealCallback();\n\n return key;\n}\n\n/**\n * reimplementation of window.clearTimeout, which mirrors setTimeout\n *\n * @param {Number} key result from an earlier setTimeout call\n */\nexport function clearTimeout(key) {\n if (_callbackList.length === 0) {\n return;\n }\n\n // remove the element from the list\n let i;\n for (i = 0; i < _callbackList.length; i++) {\n const cb = _callbackList[i];\n if (cb.key == key) {\n _callbackList.splice(i, 1);\n break;\n }\n }\n\n // iff it was the first one in the list, reschedule our callback.\n if (i === 0) {\n _scheduleRealCallback();\n }\n}\n\n// use the real global.setTimeout to schedule a callback to _runCallbacks.\nfunction _scheduleRealCallback() {\n if (_realCallbackKey) {\n global.clearTimeout(_realCallbackKey);\n }\n\n const first = _callbackList[0];\n\n if (!first) {\n debuglog(\"_scheduleRealCallback: no more callbacks, not rescheduling\");\n return;\n }\n\n const now = _now(
"/*\nCopyright 2015, 2016 OpenMarket 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\n/**\n * This is an internal module which manages queuing, scheduling and retrying\n * of requests.\n * @module scheduler\n */\nimport * as utils from \"./utils\";\nimport { logger } from './logger';\n\nconst DEBUG = false; // set true to enable console logging.\n\n/**\n * Construct a scheduler for Matrix. Requires\n * {@link module:scheduler~MatrixScheduler#setProcessFunction} to be provided\n * with a way of processing events.\n * @constructor\n * @param {module:scheduler~retryAlgorithm} retryAlgorithm Optional. The retry\n * algorithm to apply when determining when to try to send an event again.\n * Defaults to {@link module:scheduler~MatrixScheduler.RETRY_BACKOFF_RATELIMIT}.\n * @param {module:scheduler~queueAlgorithm} queueAlgorithm Optional. The queuing\n * algorithm to apply when determining which events should be sent before the\n * given event. Defaults to {@link module:scheduler~MatrixScheduler.QUEUE_MESSAGES}.\n */\nexport function MatrixScheduler(retryAlgorithm, queueAlgorithm) {\n this.retryAlgorithm = retryAlgorithm || MatrixScheduler.RETRY_BACKOFF_RATELIMIT;\n this.queueAlgorithm = queueAlgorithm || MatrixScheduler.QUEUE_MESSAGES;\n this._queues = {\n // queueName: [{\n // event: MatrixEvent, // event to send\n // defer: Deferred, // defer to resolve/reject at the END of the retries\n // attempts: Number // number of times we've called processFn\n // }, ...]\n };\n this._activeQueues = [];\n this._procFn = null;\n}\n\n/**\n * Retrieve a queue based on an event. The event provided does not need to be in\n * the queue.\n * @param {MatrixEvent} event An event to get the queue for.\n * @return {?Array<MatrixEvent>} A shallow copy of events in the queue or null.\n * Modifying this array will not modify the list itself. Modifying events in\n * this array <i>will</i> modify the underlying event in the queue.\n * @see MatrixScheduler.removeEventFromQueue To remove an event from the queue.\n */\nMatrixScheduler.prototype.getQueueForEvent = function(event) {\n const name = this.queueAlgorithm(event);\n if (!name || !this._queues[name]) {\n return null;\n }\n return this._queues[name].map(function(obj) {\n return obj.event;\n });\n};\n\n/**\n * Remove this event from the queue. The event is equal to another event if they\n * have the same ID returned from event.getId().\n * @param {MatrixEvent} event The event to remove.\n * @return {boolean} True if this event was removed.\n */\nMatrixScheduler.prototype.removeEventFromQueue = function(event) {\n const name = this.queueAlgorithm(event);\n if (!name || !this._queues[name]) {\n return false;\n }\n let removed = false;\n utils.removeElement(this._queues[name], function(element) {\n if (element.event.getId() === event.getId()) {\n // XXX we should probably reject the promise?\n // https://github.com/matrix-org/matrix-js-sdk/issues/496\n removed = true;\n return true;\n }\n });\n return removed;\n};\n\n/**\n * Set the process function. Required for events in the queue to be processed.\n * If set after events have been added to the queue, this will immediately start\n * processing them.\n * @param {module:scheduler~processFn} fn The function that can process events\n * in the queue.\n */\nMatrixScheduler.prototype.setProcessFunction = function(fn) {\n this._procFn = f
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2019 - 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\nexport enum SERVICE_TYPES {\n IS = 'SERVICE_TYPE_IS', // An identity server\n IM = 'SERVICE_TYPE_IM', // An integration manager\n}\n",
"/*\nCopyright 2017 - 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 { IMinimalEvent, ISyncData, ISyncResponse, SyncAccumulator } from \"../sync-accumulator\";\nimport * as utils from \"../utils\";\nimport * as IndexedDBHelpers from \"../indexeddb-helpers\";\nimport { logger } from '../logger';\nimport { IEvent, IStartClientOpts } from \"..\";\nimport { ISavedSync } from \"./index\";\nimport { IIndexedDBBackend, UserTuple } from \"./indexeddb-backend\";\n\nconst VERSION = 3;\n\nfunction createDatabase(db: IDBDatabase): void {\n // Make user store, clobber based on user ID. (userId property of User objects)\n db.createObjectStore(\"users\", { keyPath: [\"userId\"] });\n\n // Make account data store, clobber based on event type.\n // (event.type property of MatrixEvent objects)\n db.createObjectStore(\"accountData\", { keyPath: [\"type\"] });\n\n // Make /sync store (sync tokens, room data, etc), always clobber (const key).\n db.createObjectStore(\"sync\", { keyPath: [\"clobber\"] });\n}\n\nfunction upgradeSchemaV2(db: IDBDatabase): void {\n const oobMembersStore = db.createObjectStore(\n \"oob_membership_events\", {\n keyPath: [\"room_id\", \"state_key\"],\n });\n oobMembersStore.createIndex(\"room\", \"room_id\");\n}\n\nfunction upgradeSchemaV3(db: IDBDatabase): void {\n db.createObjectStore(\"client_options\",\n { keyPath: [\"clobber\"] });\n}\n\n/**\n * Helper method to collect results from a Cursor and promiseify it.\n * @param {ObjectStore|Index} store The store to perform openCursor on.\n * @param {IDBKeyRange=} keyRange Optional key range to apply on the cursor.\n * @param {Function} resultMapper A function which is repeatedly called with a\n * Cursor.\n * Return the data you want to keep.\n * @return {Promise<T[]>} Resolves to an array of whatever you returned from\n * resultMapper.\n */\nfunction selectQuery<T>(\n store: IDBObjectStore,\n keyRange: IDBKeyRange | IDBValidKey | undefined,\n resultMapper: (cursor: IDBCursorWithValue) => T,\n): Promise<T[]> {\n const query = store.openCursor(keyRange);\n return new Promise((resolve, reject) => {\n const results = [];\n query.onerror = () => {\n reject(new Error(\"Query failed: \" + query.error));\n };\n // collect results\n query.onsuccess = () => {\n const cursor = query.result;\n if (!cursor) {\n resolve(results);\n return; // end of results\n }\n results.push(resultMapper(cursor));\n cursor.continue();\n };\n });\n}\n\nfunction txnAsPromise(txn: IDBTransaction): Promise<Event> {\n return new Promise((resolve, reject) => {\n txn.oncomplete = function(event) {\n resolve(event);\n };\n txn.onerror = function() {\n reject(txn.error);\n };\n });\n}\n\nfunction reqAsEventPromise(req: IDBRequest): Promise<Event> {\n return new Promise((resolve, reject) => {\n req.onsuccess = function(event) {\n resolve(event);\n };\n req.onerror = function() {\n reject(req.error);\n };\n });\n}\n\nfunction reqAsPromise(req: IDBRequest): Promise<IDBRequest> {\n return new Promise((resolve, reject) => {\n req.onsuccess = () => resolve(req);\n req.onerror = (err) => reject(err);\n });\n}\n\nfunction reqAsCursorPromise(req: IDBRequest<IDBCursor | null>): Promise<IDBCursor> {\n return reqAsEventPromise(req
"/*\nCopyright 2017 - 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 { defer, IDeferred } from \"../utils\";\nimport { ISavedSync } from \"./index\";\nimport { IStartClientOpts } from \"../client\";\nimport { IEvent, ISyncResponse } from \"..\";\nimport { IIndexedDBBackend, UserTuple } from \"./indexeddb-backend\";\n\nexport class RemoteIndexedDBStoreBackend implements IIndexedDBBackend {\n private worker: Worker;\n private nextSeq = 0;\n // The currently in-flight requests to the actual backend\n private inFlight: Record<number, IDeferred<any>> = {}; // seq: promise\n // Once we start connecting, we keep the promise and re-use it\n // if we try to connect again\n private startPromise: Promise<void> = null;\n\n /**\n * An IndexedDB store backend where the actual backend sits in a web\n * worker.\n *\n * Construct a new Indexed Database store backend. This requires a call to\n * <code>connect()</code> before this store can be used.\n * @constructor\n * @param {Function} workerFactory Factory which produces a Worker\n * @param {string=} dbName Optional database name. The same name must be used\n * to open the same database.\n */\n constructor(\n private readonly workerFactory: () => Worker,\n private readonly dbName: string,\n ) {}\n\n /**\n * Attempt to connect to the database. This can fail if the user does not\n * grant permission.\n * @return {Promise} Resolves if successfully connected.\n */\n public connect(): Promise<void> {\n return this.ensureStarted().then(() => this.doCmd('connect'));\n }\n\n /**\n * Clear the entire database. This should be used when logging out of a client\n * to prevent mixing data between accounts.\n * @return {Promise} Resolved when the database is cleared.\n */\n public clearDatabase(): Promise<void> {\n return this.ensureStarted().then(() => this.doCmd('clearDatabase'));\n }\n\n /** @return {Promise<boolean>} whether or not the database was newly created in this session. */\n public isNewlyCreated(): Promise<boolean> {\n return this.doCmd('isNewlyCreated');\n }\n\n /**\n * @return {Promise} Resolves with a sync response to restore the\n * client state to where it was at the last save, or null if there\n * is no saved sync data.\n */\n public getSavedSync(): Promise<ISavedSync> {\n return this.doCmd('getSavedSync');\n }\n\n public getNextBatchToken(): Promise<string> {\n return this.doCmd('getNextBatchToken');\n }\n\n public setSyncData(syncData: ISyncResponse): Promise<void> {\n return this.doCmd('setSyncData', [syncData]);\n }\n\n public syncToDatabase(userTuples: UserTuple[]): Promise<void> {\n return this.doCmd('syncToDatabase', [userTuples]);\n }\n\n /**\n * Returns the out-of-band membership events for this room that\n * were previously loaded.\n * @param {string} roomId\n * @returns {event[]} the events, potentially an empty array if OOB loading didn't yield any new members\n * @returns {null} in case the members for this room haven't been stored yet\n */\n public getOutOfBandMembers(roomId: string): Promise<IEvent[] | null> {\n return this.doCmd('getOutOfBandMembers', [roomId]);\n }\n\n /**\n * Stores the out-of-band membership events for this room. Note that\n * it still makes sense to store an empty array as the OOB stat
"/*\nCopyright 2017 - 2021 Vector Creations Ltd\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/* eslint-disable @babel/no-invalid-this */\n\nimport { EventEmitter } from 'events';\n\nimport { MemoryStore, IOpts as IBaseOpts } from \"./memory\";\nimport { LocalIndexedDBStoreBackend } from \"./indexeddb-local-backend\";\nimport { RemoteIndexedDBStoreBackend } from \"./indexeddb-remote-backend\";\nimport { User } from \"../models/user\";\nimport { IEvent, MatrixEvent } from \"../models/event\";\nimport { logger } from '../logger';\nimport { ISavedSync } from \"./index\";\nimport { IIndexedDBBackend } from \"./indexeddb-backend\";\nimport { ISyncResponse } from \"../sync-accumulator\";\n\n/**\n * This is an internal module. See {@link IndexedDBStore} for the public class.\n * @module store/indexeddb\n */\n\n// If this value is too small we'll be writing very often which will cause\n// noticeable stop-the-world pauses. If this value is too big we'll be writing\n// so infrequently that the /sync size gets bigger on reload. Writing more\n// often does not affect the length of the pause since the entire /sync\n// response is persisted each time.\nconst WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes\n\ninterface IOpts extends IBaseOpts {\n indexedDB: IDBFactory;\n dbName?: string;\n workerFactory?: () => Worker;\n}\n\nexport class IndexedDBStore extends MemoryStore {\n static exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> {\n return LocalIndexedDBStoreBackend.exists(indexedDB, dbName);\n }\n\n public readonly backend: IIndexedDBBackend;\n\n private startedUp = false;\n private syncTs = 0;\n // Records the last-modified-time of each user at the last point we saved\n // the database, such that we can derive the set if users that have been\n // modified since we last saved.\n private userModifiedMap: Record<string, number> = {}; // user_id : timestamp\n private emitter = new EventEmitter();\n\n /**\n * Construct a new Indexed Database store, which extends MemoryStore.\n *\n * This store functions like a MemoryStore except it periodically persists\n * the contents of the store to an IndexedDB backend.\n *\n * All data is still kept in-memory but can be loaded from disk by calling\n * <code>startup()</code>. This can make startup times quicker as a complete\n * sync from the server is not required. This does not reduce memory usage as all\n * the data is eagerly fetched when <code>startup()</code> is called.\n * <pre>\n * let opts = { indexedDB: window.indexedDB, localStorage: window.localStorage };\n * let store = new IndexedDBStore(opts);\n * await store.startup(); // load from indexed db\n * let client = sdk.createClient({\n * store: store,\n * });\n * client.startClient();\n * client.on(\"sync\", function(state, prevState, data) {\n * if (state === \"PREPARED\") {\n * console.log(\"Started up, now with go faster stripes!\");\n * }\n * });\n * </pre>\n *\n * @constructor\n * @extends MemoryStore\n * @param {Object} opts Options object.\n * @param {Object} opts.indexedDB The Indexed DB interface e.g.\n * <code>window.indexedDB</code>\n * @param {string=} opts.dbName Optional database name. The same name must be used\n * to open the same database.\n * @param {string=} opts.workerScript Optional URL to a script to invoke a web\n * worker with to run IndexedDB queries on the web worker. The IndexedDbStoreWorker\n
"/*\nCopyright 2015 - 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 * This is an internal module. See {@link MemoryStore} for the public class.\n * @module store/memory\n */\n\nimport { EventType } from \"../@types/event\";\nimport { Group } from \"../models/group\";\nimport { Room } from \"../models/room\";\nimport { User } from \"../models/user\";\nimport { IEvent, MatrixEvent } from \"../models/event\";\nimport { RoomState } from \"../models/room-state\";\nimport { RoomMember } from \"../models/room-member\";\nimport { Filter } from \"../filter\";\nimport { ISavedSync, IStore } from \"./index\";\nimport { RoomSummary } from \"../models/room-summary\";\nimport { ISyncResponse } from \"../sync-accumulator\";\n\nfunction isValidFilterId(filterId: string): boolean {\n const isValidStr = typeof filterId === \"string\" &&\n !!filterId &&\n filterId !== \"undefined\" && // exclude these as we've serialized undefined in localStorage before\n filterId !== \"null\";\n\n return isValidStr || typeof filterId === \"number\";\n}\n\nexport interface IOpts {\n localStorage?: Storage;\n}\n\n/**\n * Construct a new in-memory data store for the Matrix Client.\n * @constructor\n * @param {Object=} opts Config options\n * @param {LocalStorage} opts.localStorage The local storage instance to persist\n * some forms of data such as tokens. Rooms will NOT be stored.\n */\nexport class MemoryStore implements IStore {\n private rooms: Record<string, Room> = {}; // roomId: Room\n private groups: Record<string, Group> = {}; // groupId: Group\n private users: Record<string, User> = {}; // userId: User\n private syncToken: string = null;\n // userId: {\n // filterId: Filter\n // }\n private filters: Record<string, Record<string, Filter>> = {};\n public accountData: Record<string, MatrixEvent> = {}; // type : content\n private readonly localStorage: Storage;\n private oobMembers: Record<string, IEvent[]> = {}; // roomId: [member events]\n private clientOptions = {};\n\n constructor(opts: IOpts = {}) {\n this.localStorage = opts.localStorage;\n }\n\n /**\n * Retrieve the token to stream from.\n * @return {string} The token or null.\n */\n public getSyncToken(): string | null {\n return this.syncToken;\n }\n\n /** @return {Promise<boolean>} whether or not the database was newly created in this session. */\n public isNewlyCreated(): Promise<boolean> {\n return Promise.resolve(true);\n }\n\n /**\n * Set the token to stream from.\n * @param {string} token The token to stream from.\n */\n public setSyncToken(token: string) {\n this.syncToken = token;\n }\n\n /**\n * Store the given room.\n * @param {Group} group The group to be stored\n */\n public storeGroup(group: Group) {\n this.groups[group.groupId] = group;\n }\n\n /**\n * Retrieve a group by its group ID.\n * @param {string} groupId The group ID.\n * @return {Group} The group or null.\n */\n public getGroup(groupId: string): Group | null {\n return this.groups[groupId] || null;\n }\n\n /**\n * Retrieve all known groups.\n * @return {Group[]} A list of groups, which may be empty.\n */\n public getGroups(): Group[] {\n return Object.values(this.groups);\n }\n\n /**\n * Store the given room.\n * @param {Room} room The room to be stored. All properties must be stored.\n */\n public storeRoom(room: Room) {\n
"/*\nCopyright 2015, 2016 OpenMarket Ltd\nCopyright 2017 New Vector Ltd\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\n/**\n * @module store/session/webstorage\n */\n\nimport * as utils from \"../../utils\";\nimport { logger } from '../../logger';\n\nconst DEBUG = false; // set true to enable console logging.\nconst E2E_PREFIX = \"session.e2e.\";\n\n/**\n * Construct a web storage session store, capable of storing account keys,\n * session keys and access tokens.\n * @constructor\n * @param {WebStorage} webStore A web storage implementation, e.g.\n * 'window.localStorage' or 'window.sessionStorage' or a custom implementation.\n * @throws if the supplied 'store' does not meet the Storage interface of the\n * WebStorage API.\n */\nexport function WebStorageSessionStore(webStore) {\n this.store = webStore;\n if (!utils.isFunction(webStore.getItem) ||\n !utils.isFunction(webStore.setItem) ||\n !utils.isFunction(webStore.removeItem) ||\n !utils.isFunction(webStore.key) ||\n typeof(webStore.length) !== 'number'\n ) {\n throw new Error(\n \"Supplied webStore does not meet the WebStorage API interface\",\n );\n }\n}\n\nWebStorageSessionStore.prototype = {\n /**\n * Remove the stored end to end account for the logged-in user.\n */\n removeEndToEndAccount: function() {\n this.store.removeItem(KEY_END_TO_END_ACCOUNT);\n },\n\n /**\n * Load the end to end account for the logged-in user.\n * Note that the end-to-end account is now stored in the\n * crypto store rather than here: this remains here so\n * old sessions can be migrated out of the session store.\n * @return {?string} Base64 encoded account.\n */\n getEndToEndAccount: function() {\n return this.store.getItem(KEY_END_TO_END_ACCOUNT);\n },\n\n /**\n * Retrieves the known devices for all users.\n * @return {object} A map from user ID to map of device ID to keys for the device.\n */\n getAllEndToEndDevices: function() {\n const prefix = keyEndToEndDevicesForUser('');\n const devices = {};\n for (let i = 0; i < this.store.length; ++i) {\n const key = this.store.key(i);\n const userId = key.substr(prefix.length);\n if (key.startsWith(prefix)) devices[userId] = getJsonItem(this.store, key);\n }\n return devices;\n },\n\n getEndToEndDeviceTrackingStatus: function() {\n return getJsonItem(this.store, KEY_END_TO_END_DEVICE_LIST_TRACKING_STATUS);\n },\n\n /**\n * Get the sync token corresponding to the device list.\n *\n * @return {String?} token\n */\n getEndToEndDeviceSyncToken: function() {\n return getJsonItem(this.store, KEY_END_TO_END_DEVICE_SYNC_TOKEN);\n },\n\n /**\n * Removes all end to end device data from the store\n */\n removeEndToEndDeviceData: function() {\n removeByPrefix(this.store, keyEndToEndDevicesForUser(''));\n removeByPrefix(this.store, KEY_END_TO_END_DEVICE_LIST_TRACKING_STATUS);\n removeByPrefix(this.store, KEY_END_TO_END_DEVICE_SYNC_TOKEN);\n },\n\n /**\n * Retrieve the end-to-end sessions between the logged-in user and another\n * device.\n * @param {string} deviceKey The public key of the other device.\n * @return {object} A map from sessionId to Base64 end-to-end session.\n */\n getEndToEndSessions: function(deviceKey) {\n return getJsonItem(this.st
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2015 - 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 * This is an internal module.\n * @module store/stub\n */\n\nimport { EventType } from \"../@types/event\";\nimport { Group } from \"../models/group\";\nimport { Room } from \"../models/room\";\nimport { User } from \"../models/user\";\nimport { IEvent, MatrixEvent } from \"../models/event\";\nimport { Filter } from \"../filter\";\nimport { ISavedSync, IStore } from \"./index\";\nimport { RoomSummary } from \"../models/room-summary\";\nimport { ISyncResponse } from \"../sync-accumulator\";\n\n/**\n * Construct a stub store. This does no-ops on most store methods.\n * @constructor\n */\nexport class StubStore implements IStore {\n public readonly accountData = {}; // stub\n private fromToken: string = null;\n\n /** @return {Promise<boolean>} whether or not the database was newly created in this session. */\n public isNewlyCreated(): Promise<boolean> {\n return Promise.resolve(true);\n }\n\n /**\n * Get the sync token.\n * @return {string}\n */\n public getSyncToken(): string | null {\n return this.fromToken;\n }\n\n /**\n * Set the sync token.\n * @param {string} token\n */\n public setSyncToken(token: string) {\n this.fromToken = token;\n }\n\n /**\n * No-op.\n * @param {Group} group\n */\n public storeGroup(group: Group) {}\n\n /**\n * No-op.\n * @param {string} groupId\n * @return {null}\n */\n public getGroup(groupId: string): Group | null {\n return null;\n }\n\n /**\n * No-op.\n * @return {Array} An empty array.\n */\n public getGroups(): Group[] {\n return [];\n }\n\n /**\n * No-op.\n * @param {Room} room\n */\n public storeRoom(room: Room) {}\n\n /**\n * No-op.\n * @param {string} roomId\n * @return {null}\n */\n public getRoom(roomId: string): Room | null {\n return null;\n }\n\n /**\n * No-op.\n * @return {Array} An empty array.\n */\n public getRooms(): Room[] {\n return [];\n }\n\n /**\n * Permanently delete a room.\n * @param {string} roomId\n */\n public removeRoom(roomId: string) {\n return;\n }\n\n /**\n * No-op.\n * @return {Array} An empty array.\n */\n public getRoomSummaries(): RoomSummary[] {\n return [];\n }\n\n /**\n * No-op.\n * @param {User} user\n */\n public storeUser(user: User) {}\n\n /**\n * No-op.\n * @param {string} userId\n * @return {null}\n */\n public getUser(userId: string): User | null {\n return null;\n }\n\n /**\n * No-op.\n * @return {User[]}\n */\n public getUsers(): User[] {\n return [];\n }\n\n /**\n * No-op.\n * @param {Room} room\n * @param {integer} limit\n * @return {Array}\n */\n public scrollback(room: Room, limit: number): MatrixEvent[] {\n return [];\n }\n\n /**\n * Store events for a room.\n * @param {Room} room The room to store events for.\n * @param {Array<MatrixEvent>} events The events to store.\n * @param {string} token The token associated with these events.\n * @param {boolean} toStart True if these are paginated results.\n */\n public storeEvents(room: Room, events: MatrixEvent[], token: string, toStart: boolean) {}\n\n /**\n * Store a filter.\n * @param {Filter} filter\n */\n public storeFilter(filter: Filter)
"/*\nCopyright 2017 - 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 * This is an internal module. See {@link SyncAccumulator} for the public class.\n * @module sync-accumulator\n */\n\nimport { logger } from './logger';\nimport { deepCopy } from \"./utils\";\nimport { IContent, IUnsigned } from \"./models/event\";\nimport { IRoomSummary } from \"./models/room-summary\";\nimport { EventType } from \"./@types/event\";\n\ninterface IOpts {\n maxTimelineEntries?: number;\n}\n\nexport interface IMinimalEvent {\n content: IContent;\n type: EventType | string;\n}\n\nexport interface IEphemeral {\n events: IMinimalEvent[];\n}\n\n/* eslint-disable camelcase */\ninterface IUnreadNotificationCounts {\n highlight_count?: number;\n notification_count?: number;\n}\n\nexport interface IRoomEvent extends IMinimalEvent {\n event_id: string;\n sender: string;\n origin_server_ts: number;\n unsigned?: IUnsigned;\n /** @deprecated - legacy field */\n age?: number;\n}\n\nexport interface IStateEvent extends IRoomEvent {\n prev_content?: IContent;\n state_key: string;\n}\n\ninterface IState {\n events: IStateEvent[];\n}\n\nexport interface ITimeline {\n events: Array<IRoomEvent | IStateEvent>;\n limited?: boolean;\n prev_batch: string;\n}\n\nexport interface IJoinedRoom {\n summary: IRoomSummary;\n state: IState;\n timeline: ITimeline;\n ephemeral: IEphemeral;\n account_data: IAccountData;\n unread_notifications: IUnreadNotificationCounts;\n}\n\nexport interface IStrippedState {\n content: IContent;\n state_key: string;\n type: EventType | string;\n sender: string;\n}\n\nexport interface IInviteState {\n events: IStrippedState[];\n}\n\nexport interface IInvitedRoom {\n invite_state: IInviteState;\n}\n\nexport interface ILeftRoom {\n state: IState;\n timeline: ITimeline;\n account_data: IAccountData;\n}\n\nexport interface IRooms {\n [Category.Join]: Record<string, IJoinedRoom>;\n [Category.Invite]: Record<string, IInvitedRoom>;\n [Category.Leave]: Record<string, ILeftRoom>;\n}\n\ninterface IPresence {\n events: IMinimalEvent[];\n}\n\ninterface IAccountData {\n events: IMinimalEvent[];\n}\n\ninterface IToDeviceEvent {\n content: IContent;\n sender: string;\n type: string;\n}\n\ninterface IToDevice {\n events: IToDeviceEvent[];\n}\n\ninterface IDeviceLists {\n changed: string[];\n left: string[];\n}\n\nexport interface IGroups {\n [Category.Join]: object;\n [Category.Invite]: object;\n [Category.Leave]: object;\n}\n\nexport interface ISyncResponse {\n next_batch: string;\n rooms: IRooms;\n presence?: IPresence;\n account_data: IAccountData;\n to_device?: IToDevice;\n device_lists?: IDeviceLists;\n device_one_time_keys_count?: Record<string, number>;\n\n groups: IGroups; // unspecced\n}\n/* eslint-enable camelcase */\n\nexport enum Category {\n Invite = \"invite\",\n Leave = \"leave\",\n Join = \"join\",\n}\n\ninterface IRoom {\n _currentState: { [eventType: string]: { [stateKey: string]: IStateEvent } };\n _timeline: {\n event: IRoomEvent | IStateEvent;\n token: string | null;\n }[];\n _summary: Partial<IRoomSummary>;\n _accountData: { [eventType: string]: IMinimalEvent };\n _unreadNotifications: Partial<IUnreadNotificationCounts>;\n _readReceipts: {\n [userId: string]: {\n data: IMinimalEvent;\n eventId: string;\n };\n };\n}\n\nexport interface ISyncData {\n
"/*\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\n// TODO: Merge this with sync.js once converted\n\nexport enum SyncState {\n Error = \"ERROR\",\n Prepared = \"PREPARED\",\n Stopped = \"STOPPED\",\n Syncing = \"SYNCING\",\n Catchup = \"CATCHUP\",\n Reconnecting = \"RECONNECTING\",\n}\n",
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2015 - 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 * TODO:\n * This class mainly serves to take all the syncing logic out of client.js and\n * into a separate file. It's all very fluid, and this class gut wrenches a lot\n * of MatrixClient props (e.g. http). Given we want to support WebSockets as\n * an alternative syncing API, we may want to have a proper syncing interface\n * for HTTP and WS at some point.\n */\n\nimport { User } from \"./models/user\";\nimport { NotificationCountType, Room } from \"./models/room\";\nimport { Group } from \"./models/group\";\nimport * as utils from \"./utils\";\nimport { IDeferred } from \"./utils\";\nimport { Filter } from \"./filter\";\nimport { EventTimeline } from \"./models/event-timeline\";\nimport { PushProcessor } from \"./pushprocessor\";\nimport { logger } from './logger';\nimport { InvalidStoreError } from './errors';\nimport { IStoredClientOpts, MatrixClient, PendingEventOrdering } from \"./client\";\nimport { SyncState } from \"./sync.api\";\nimport {\n Category,\n IInvitedRoom,\n IInviteState,\n IJoinedRoom,\n ILeftRoom,\n IStateEvent,\n IRoomEvent,\n IStrippedState,\n ISyncResponse,\n ITimeline,\n IEphemeral,\n IMinimalEvent,\n} from \"./sync-accumulator\";\nimport { MatrixEvent } from \"./models/event\";\nimport { MatrixError } from \"./http-api\";\nimport { ISavedSync } from \"./store\";\n\nconst DEBUG = true;\n\n// /sync requests allow you to set a timeout= but the request may continue\n// beyond that and wedge forever, so we need to track how long we are willing\n// to keep open the connection. This constant is *ADDED* to the timeout= value\n// to determine the max time we're willing to wait.\nconst BUFFER_PERIOD_MS = 80 * 1000;\n\n// Number of consecutive failed syncs that will lead to a syncState of ERROR as opposed\n// to RECONNECTING. This is needed to inform the client of server issues when the\n// keepAlive is successful but the server /sync fails.\nconst FAILED_SYNC_ERROR_THRESHOLD = 3;\n\nfunction getFilterName(userId: string, suffix?: string): string {\n // scope this on the user ID because people may login on many accounts\n // and they all need to be stored!\n return \"FILTER_SYNC_\" + userId + (suffix ? \"_\" + suffix : \"\");\n}\n\nfunction debuglog(...params) {\n if (!DEBUG) {\n return;\n }\n logger.log(...params);\n}\n\ninterface ISyncOptions {\n filterId?: string;\n hasSyncedBefore?: boolean;\n}\n\nexport interface ISyncStateData {\n error?: Error;\n oldSyncToken?: string;\n nextSyncToken?: string;\n catchingUp?: boolean;\n fromCache?: boolean;\n}\n\ninterface ISyncParams {\n filter?: string;\n timeout: number;\n since?: string;\n // eslint-disable-next-line camelcase\n full_state?: boolean;\n // eslint-disable-next-line camelcase\n set_presence?: \"offline\" | \"online\" | \"unavailable\";\n _cacheBuster?: string | number; // not part of the API itself\n}\n\n// http-api mangles an abort method onto its promises\ninterface IRequestPromise<T> extends Promise<T> {\n abort(): void;\n}\n\ntype WrappedRoom<T> = T & {\n room: Room;\n isBrandNewRoom: boolean;\n};\n\n/**\n * <b>Internal class - unstable.</b>\n * Construct an entity which is able to sync with a homeserver.\n * @constructor\n * @param {MatrixClient} client The matrix client instance to use.\n * @param {Object} opts Config options\n * @param {module:crypto=} opts.crypto Crypto manager\n * @param {Function=} opts.canResetEntire
"/*\nCopyright 2016 - 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/** @module timeline-window */\n\nimport { Direction, EventTimeline } from './models/event-timeline';\nimport { logger } from './logger';\nimport { MatrixClient } from \"./client\";\nimport { EventTimelineSet } from \"./models/event-timeline-set\";\nimport { MatrixEvent } from \"./models/event\";\n\n/**\n * @private\n */\nconst DEBUG = false;\n\n/**\n * @private\n */\nconst debuglog = DEBUG ? logger.log.bind(logger) : function() {};\n\n/**\n * the number of times we ask the server for more events before giving up\n *\n * @private\n */\nconst DEFAULT_PAGINATE_LOOP_LIMIT = 5;\n\ninterface IOpts {\n windowLimit?: number;\n}\n\nexport class TimelineWindow {\n private readonly windowLimit: number;\n // these will be TimelineIndex objects; they delineate the 'start' and\n // 'end' of the window.\n //\n // start.index is inclusive; end.index is exclusive.\n private start?: TimelineIndex = null;\n private end?: TimelineIndex = null;\n private eventCount = 0;\n\n /**\n * Construct a TimelineWindow.\n *\n * <p>This abstracts the separate timelines in a Matrix {@link\n * module:models/room|Room} into a single iterable thing. It keeps track of\n * the start and endpoints of the window, which can be advanced with the help\n * of pagination requests.\n *\n * <p>Before the window is useful, it must be initialised by calling {@link\n * module:timeline-window~TimelineWindow#load|load}.\n *\n * <p>Note that the window will not automatically extend itself when new events\n * are received from /sync; you should arrange to call {@link\n * module:timeline-window~TimelineWindow#paginate|paginate} on {@link\n * module:client~MatrixClient.event:\"Room.timeline\"|Room.timeline} events.\n *\n * @param {MatrixClient} client MatrixClient to be used for context/pagination\n * requests.\n *\n * @param {EventTimelineSet} timelineSet The timelineSet to track\n *\n * @param {Object} [opts] Configuration options for this window\n *\n * @param {number} [opts.windowLimit = 1000] maximum number of events to keep\n * in the window. If more events are retrieved via pagination requests,\n * excess events will be dropped from the other end of the window.\n *\n * @constructor\n */\n constructor(\n private readonly client: MatrixClient,\n private readonly timelineSet: EventTimelineSet,\n opts: IOpts = {},\n ) {\n this.windowLimit = opts.windowLimit || 1000;\n }\n\n /**\n * Initialise the window to point at a given event, or the live timeline\n *\n * @param {string} [initialEventId] If given, the window will contain the\n * given event\n * @param {number} [initialWindowSize = 20] Size of the initial window\n *\n * @return {Promise}\n */\n public load(initialEventId: string, initialWindowSize = 20): Promise<any> {\n // given an EventTimeline, find the event we were looking for, and initialise our\n // fields so that the event in question is in the middle of the window.\n const initFields = (timeline: EventTimeline) => {\n let eventIndex;\n\n const events = timeline.getEvents();\n\n if (!initialEventId) {\n // we were looking for the live timeline: initialise to the end\n eventIndex = events.length;\n } else {\n for
2021-08-11 18:56:57 +00:00
"/*\nCopyright 2015, 2016 OpenMarket 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\n/**\n * This is an internal module.\n * @module utils\n */\n\nimport unhomoglyph from \"unhomoglyph\";\nimport promiseRetry from \"p-retry\";\nimport type NodeCrypto from \"crypto\";\n\n/**\n * Encode a dictionary of query parameters.\n * @param {Object} params A dict of key/values to encode e.g.\n * {\"foo\": \"bar\", \"baz\": \"taz\"}\n * @return {string} The encoded string e.g. foo=bar&baz=taz\n */\nexport function encodeParams(params: Record<string, string>): string {\n return new URLSearchParams(params).toString();\n}\n\nexport type QueryDict = Record<string, string | string[]>;\n\n/**\n * Decode a query string in `application/x-www-form-urlencoded` format.\n * @param {string} query A query string to decode e.g.\n * foo=bar&via=server1&server2\n * @return {Object} The decoded object, if any keys occurred multiple times\n * then the value will be an array of strings, else it will be an array.\n * This behaviour matches Node's qs.parse but is built on URLSearchParams\n * for native web compatibility\n */\nexport function decodeParams(query: string): QueryDict {\n const o: QueryDict = {};\n const params = new URLSearchParams(query);\n for (const key of params.keys()) {\n const val = params.getAll(key);\n o[key] = val.length === 1 ? val[0] : val;\n }\n return o;\n}\n\n/**\n * Encodes a URI according to a set of template variables. Variables will be\n * passed through encodeURIComponent.\n * @param {string} pathTemplate The path with template variables e.g. '/foo/$bar'.\n * @param {Object} variables The key/value pairs to replace the template\n * variables with. E.g. { \"$bar\": \"baz\" }.\n * @return {string} The result of replacing all template variables e.g. '/foo/baz'.\n */\nexport function encodeUri(pathTemplate: string,\n variables: Record<string, string>): string {\n for (const key in variables) {\n if (!variables.hasOwnProperty(key)) {\n continue;\n }\n pathTemplate = pathTemplate.replace(\n key, encodeURIComponent(variables[key]),\n );\n }\n return pathTemplate;\n}\n\n/**\n * The removeElement() method removes the first element in the array that\n * satisfies (returns true) the provided testing function.\n * @param {Array} array The array.\n * @param {Function} fn Function to execute on each value in the array, with the\n * function signature <code>fn(element, index, array)</code>. Return true to\n * remove this element and break.\n * @param {boolean} reverse True to search in reverse order.\n * @return {boolean} True if an element was removed.\n */\nexport function removeElement<T>(\n array: T[],\n fn: (t: T, i?: number, a?: T[]) => boolean,\n reverse?: boolean,\n) {\n let i;\n let removed;\n if (reverse) {\n for (i = array.length - 1; i >= 0; i--) {\n if (fn(array[i], i, array)) {\n removed = array[i];\n array.splice(i, 1);\n return removed;\n }\n }\n } else {\n for (i = 0; i < array.length; i++) {\n if (fn(array[i], i, array)) {\n removed = array[i];\n array.splice(i, 1);\n return removed;\n }\n }\n }\n return false;\n}\n\n/**\n * Checks if the given thing is a function.\n * @param {*} value The thing to check.\n * @return {boolean} True if it is a function.\n */\nexport function isFunction(value: any
2021-08-20 21:43:16 +00:00
"/*\nCopyright 2015, 2016 OpenMarket Ltd\nCopyright 2017 New Vector Ltd\nCopyright 2019, 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 * This is an internal module. See {@link createNewMatrixCall} for the public API.\n * @module webrtc/call\n */\n\nimport { logger } from '../logger';\nimport { EventEmitter } from 'events';\nimport * as utils from '../utils';\nimport { MatrixEvent } from '../models/event';\nimport { EventType } from '../@types/event';\nimport { RoomMember } from '../models/room-member';\nimport { randomString } from '../randomstring';\nimport {\n MCallReplacesEvent,\n MCallAnswer,\n MCallOfferNegotiate,\n CallCapabilities,\n SDPStreamMetadataPurpose,\n SDPStreamMetadata,\n SDPStreamMetadataKey,\n MCallSDPStreamMetadataChanged,\n} from './callEventTypes';\nimport { CallFeed } from './callFeed';\n\n// events: hangup, error(err), replaced(call), state(state, oldState)\n\n/**\n * Fires whenever an error occurs when call.js encounters an issue with setting up the call.\n * <p>\n * The error given will have a code equal to either `MatrixCall.ERR_LOCAL_OFFER_FAILED` or\n * `MatrixCall.ERR_NO_USER_MEDIA`. `ERR_LOCAL_OFFER_FAILED` is emitted when the local client\n * fails to create an offer. `ERR_NO_USER_MEDIA` is emitted when the user has denied access\n * to their audio/video hardware.\n *\n * @event module:webrtc/call~MatrixCall#\"error\"\n * @param {Error} err The error raised by MatrixCall.\n * @example\n * matrixCall.on(\"error\", function(err){\n * console.error(err.code, err);\n * });\n */\n\ninterface CallOpts {\n roomId?: string;\n invitee?: string;\n client?: any; // Fix when client is TSified\n forceTURN?: boolean;\n turnServers?: Array<TurnServer>;\n}\n\ninterface TurnServer {\n urls: Array<string>;\n username?: string;\n password?: string;\n ttl?: number;\n}\n\ninterface AssertedIdentity {\n id: string;\n displayName: string;\n}\n\nexport enum CallState {\n Fledgling = 'fledgling',\n InviteSent = 'invite_sent',\n WaitLocalMedia = 'wait_local_media',\n CreateOffer = 'create_offer',\n CreateAnswer = 'create_answer',\n Connecting = 'connecting',\n Connected = 'connected',\n Ringing = 'ringing',\n Ended = 'ended',\n}\n\nexport enum CallType {\n Voice = 'voice',\n Video = 'video',\n}\n\nexport enum CallDirection {\n Inbound = 'inbound',\n Outbound = 'outbound',\n}\n\nexport enum CallParty {\n Local = 'local',\n Remote = 'remote',\n}\n\nexport enum CallEvent {\n Hangup = 'hangup',\n State = 'state',\n Error = 'error',\n Replaced = 'replaced',\n\n // The value of isLocalOnHold() has changed\n LocalHoldUnhold = 'local_hold_unhold',\n // The value of isRemoteOnHold() has changed\n RemoteHoldUnhold = 'remote_hold_unhold',\n // backwards compat alias for LocalHoldUnhold: remove in a major version bump\n HoldUnhold = 'hold_unhold',\n // Feeds have changed\n FeedsChanged = 'feeds_changed',\n\n AssertedIdentityChanged = 'asserted_identity_changed',\n}\n\nexport enum CallErrorCode {\n /** The user chose to end the call */\n UserHangup = 'user_hangup',\n\n /** An error code when the local client failed to create an offer. */\n LocalOfferFailed = 'local_offer_failed',\n /**\n * An error code when there is no local mic/camera to use. This may be because\n * the hardware isn't plugged in, or the user has explicitly denied access.\n */\n NoUserMedia = 'no_user_media',\n\n /**\n * Error code used when a
"/*\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\nimport { MatrixEvent } from '../models/event';\nimport { logger } from '../logger';\nimport { createNewMatrixCall, MatrixCall, CallErrorCode, CallState, CallDirection } from './call';\nimport { EventType } from '../@types/event';\nimport { MatrixClient } from '../client';\n\n// Don't ring unless we'd be ringing for at least 3 seconds: the user needs some\n// time to press the 'accept' button\nconst RING_GRACE_PERIOD = 3000;\n\nexport class CallEventHandler {\n client: MatrixClient;\n calls: Map<string, MatrixCall>;\n callEventBuffer: MatrixEvent[];\n candidateEventsByCall: Map<string, Array<MatrixEvent>>;\n\n constructor(client: MatrixClient) {\n this.client = client;\n this.calls = new Map<string, MatrixCall>();\n // The sync code always emits one event at a time, so it will patiently\n // wait for us to finish processing a call invite before delivering the\n // next event, even if that next event is a hangup. We therefore accumulate\n // all our call events and then process them on the 'sync' event, ie.\n // each time a sync has completed. This way, we can avoid emitting incoming\n // call events if we get both the invite and answer/hangup in the same sync.\n // This happens quite often, eg. replaying sync from storage, catchup sync\n // after loading and after we've been offline for a bit.\n this.callEventBuffer = [];\n this.candidateEventsByCall = new Map<string, Array<MatrixEvent>>();\n }\n\n public start() {\n this.client.on(\"sync\", this.evaluateEventBuffer);\n this.client.on(\"Room.timeline\", this.onRoomTimeline);\n }\n\n public stop() {\n this.client.removeListener(\"sync\", this.evaluateEventBuffer);\n this.client.removeListener(\"Room.timeline\", this.onRoomTimeline);\n }\n\n private evaluateEventBuffer = async () => {\n if (this.client.getSyncState() === \"SYNCING\") {\n await Promise.all(this.callEventBuffer.map(event => {\n this.client.decryptEventIfNeeded(event);\n }));\n\n const ignoreCallIds = new Set<String>();\n // inspect the buffer and mark all calls which have been answered\n // or hung up before passing them to the call event handler.\n for (const ev of this.callEventBuffer) {\n if (ev.getType() === EventType.CallAnswer ||\n ev.getType() === EventType.CallHangup) {\n ignoreCallIds.add(ev.getContent().call_id);\n }\n }\n // now loop through the buffer chronologically and inject them\n for (const e of this.callEventBuffer) {\n if (\n e.getType() === EventType.CallInvite &&\n ignoreCallIds.has(e.getContent().call_id)\n ) {\n // This call has previously been answered or hung up: ignore it\n continue;\n }\n try {\n this.handleCallEvent(e);\n } catch (e) {\n logger.error(\"Caught exception handling call event\", e);\n }\n }\n this.callEventBuffer = [];\n }\n };\n\n private onRoomTimeline = (event: MatrixEvent) => {\n this.client.decryptEventIfNeeded(event);\n // any call events or ones that might be once they're decrypted\n
2021-08-11 18:56:57 +00:00
"// allow non-camelcase as these are events type that go onto the wire\n/* eslint-disable camelcase */\n\n// TODO: Change to \"sdp_stream_metadata\" when MSC3077 is merged\nexport const SDPStreamMetadataKey = \"org.matrix.msc3077.sdp_stream_metadata\";\n\nexport enum SDPStreamMetadataPurpose {\n Usermedia = \"m.usermedia\",\n Screenshare = \"m.screenshare\",\n}\n\nexport interface SDPStreamMetadataObject {\n purpose: SDPStreamMetadataPurpose;\n audio_muted: boolean;\n video_muted: boolean;\n}\n\nexport interface SDPStreamMetadata {\n [key: string]: SDPStreamMetadataObject;\n}\n\ninterface CallOfferAnswer {\n type: string;\n sdp: string;\n}\n\nexport interface CallCapabilities {\n 'm.call.transferee': boolean;\n 'm.call.dtmf': boolean;\n}\n\nexport interface CallReplacesTarget {\n id: string;\n display_name: string;\n avatar_url: string;\n}\n\nexport interface MCallAnswer {\n answer: CallOfferAnswer;\n capabilities: CallCapabilities;\n [SDPStreamMetadataKey]: SDPStreamMetadata;\n}\n\nexport interface MCallOfferNegotiate {\n offer: CallOfferAnswer;\n description: CallOfferAnswer;\n lifetime: number;\n capabilities: CallCapabilities;\n invitee?: string;\n [SDPStreamMetadataKey]: SDPStreamMetadata;\n}\n\nexport interface MCallSDPStreamMetadataChanged {\n [SDPStreamMetadataKey]: SDPStreamMetadata;\n}\n\nexport interface MCallReplacesEvent {\n replacement_id: string;\n target_user: CallReplacesTarget;\n create_call: string;\n await_call: string;\n target_room: string;\n}\n/* eslint-enable camelcase */\n",
"/*\nCopyright 2021 Šimon Brandner <simon.bra.ag@gmail.com>\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 EventEmitter from \"events\";\nimport { SDPStreamMetadataPurpose } from \"./callEventTypes\";\nimport { MatrixClient } from \"../client\";\nimport { RoomMember } from \"../models/room-member\";\n\nexport enum CallFeedEvent {\n NewStream = \"new_stream\",\n MuteStateChanged = \"mute_state_changed\"\n}\n\nexport class CallFeed extends EventEmitter {\n constructor(\n public stream: MediaStream,\n public userId: string,\n public purpose: SDPStreamMetadataPurpose,\n private client: MatrixClient,\n private roomId: string,\n private audioMuted: boolean,\n private videoMuted: boolean,\n ) {\n super();\n }\n\n /**\n * Returns callRoom member\n * @returns member of the callRoom\n */\n public getMember(): RoomMember {\n const callRoom = this.client.getRoom(this.roomId);\n return callRoom.getMember(this.userId);\n }\n\n /**\n * Returns true if CallFeed is local, otherwise returns false\n * @returns {boolean} is local?\n */\n public isLocal(): boolean {\n return this.userId === this.client.getUserId();\n }\n\n /**\n * Returns true if audio is muted or if there are no audio\n * tracks, otherwise returns false\n * @returns {boolean} is audio muted?\n */\n public isAudioMuted(): boolean {\n return this.stream.getAudioTracks().length === 0 || this.audioMuted;\n }\n\n /**\n * Returns true video is muted or if there are no video\n * tracks, otherwise returns false\n * @returns {boolean} is video muted?\n */\n public isVideoMuted(): boolean {\n // We assume only one video track\n return this.stream.getVideoTracks().length === 0 || this.videoMuted;\n }\n\n /**\n * Replaces the current MediaStream with a new one.\n * This method should be only used by MatrixCall.\n * @param newStream new stream with which to replace the current one\n */\n public setNewStream(newStream: MediaStream) {\n this.stream = newStream;\n this.emit(CallFeedEvent.NewStream, this.stream);\n }\n\n public setAudioMuted(muted: boolean): void {\n this.audioMuted = muted;\n this.emit(CallFeedEvent.MuteStateChanged, this.audioMuted, this.videoMuted);\n }\n\n public setVideoMuted(muted: boolean): void {\n this.videoMuted = muted;\n this.emit(CallFeedEvent.MuteStateChanged, this.audioMuted, this.videoMuted);\n }\n}\n"
]
}