@jeongsu816/matrix-bot-sdk 0.0.0-stage → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +50 -2
- package/lib/AdminApis.d.ts +52 -0
- package/lib/AdminApis.js +29 -0
- package/lib/AdminApis.js.map +1 -0
- package/lib/DMs.d.ts +48 -0
- package/lib/DMs.js +160 -0
- package/lib/DMs.js.map +1 -0
- package/lib/IFilter.d.ts +7 -0
- package/lib/IFilter.js +3 -0
- package/lib/IFilter.js.map +1 -0
- package/lib/MatrixAuth.d.ts +45 -0
- package/lib/MatrixAuth.js +125 -0
- package/lib/MatrixAuth.js.map +1 -0
- package/lib/MatrixClient.d.ts +834 -0
- package/lib/MatrixClient.js +2268 -0
- package/lib/MatrixClient.js.map +1 -0
- package/lib/PantalaimonClient.d.ts +42 -0
- package/lib/PantalaimonClient.js +44 -0
- package/lib/PantalaimonClient.js.map +1 -0
- package/lib/SynapseAdminApis.d.ts +350 -0
- package/lib/SynapseAdminApis.js +244 -0
- package/lib/SynapseAdminApis.js.map +1 -0
- package/lib/SynchronousMatrixClient.d.ts +82 -0
- package/lib/SynchronousMatrixClient.js +130 -0
- package/lib/SynchronousMatrixClient.js.map +1 -0
- package/lib/UnstableApis.d.ts +43 -0
- package/lib/UnstableApis.js +74 -0
- package/lib/UnstableApis.js.map +1 -0
- package/lib/appservice/Appservice.d.ts +328 -0
- package/lib/appservice/Appservice.js +803 -0
- package/lib/appservice/Appservice.js.map +1 -0
- package/lib/appservice/Intent.d.ts +113 -0
- package/lib/appservice/Intent.js +363 -0
- package/lib/appservice/Intent.js.map +1 -0
- package/lib/appservice/MatrixBridge.d.ts +85 -0
- package/lib/appservice/MatrixBridge.js +111 -0
- package/lib/appservice/MatrixBridge.js.map +1 -0
- package/lib/appservice/UnstableAppserviceApis.d.ts +41 -0
- package/lib/appservice/UnstableAppserviceApis.js +62 -0
- package/lib/appservice/UnstableAppserviceApis.js.map +1 -0
- package/lib/appservice/http_responses.d.ts +77 -0
- package/lib/appservice/http_responses.js +3 -0
- package/lib/appservice/http_responses.js.map +1 -0
- package/lib/b64.d.ts +42 -0
- package/lib/b64.js +68 -0
- package/lib/b64.js.map +1 -0
- package/lib/e2ee/CrossSigningBootstrap.d.ts +73 -0
- package/lib/e2ee/CrossSigningBootstrap.js +86 -0
- package/lib/e2ee/CrossSigningBootstrap.js.map +1 -0
- package/lib/e2ee/CryptoClient.d.ts +163 -0
- package/lib/e2ee/CryptoClient.js +382 -0
- package/lib/e2ee/CryptoClient.js.map +1 -0
- package/lib/e2ee/ICryptoRoomInformation.d.ts +8 -0
- package/lib/e2ee/ICryptoRoomInformation.js +3 -0
- package/lib/e2ee/ICryptoRoomInformation.js.map +1 -0
- package/lib/e2ee/RoomTracker.d.ts +41 -0
- package/lib/e2ee/RoomTracker.js +96 -0
- package/lib/e2ee/RoomTracker.js.map +1 -0
- package/lib/e2ee/RustEngine.d.ts +149 -0
- package/lib/e2ee/RustEngine.js +467 -0
- package/lib/e2ee/RustEngine.js.map +1 -0
- package/lib/e2ee/decorators.d.ts +10 -0
- package/lib/e2ee/decorators.js +37 -0
- package/lib/e2ee/decorators.js.map +1 -0
- package/lib/helpers/MatrixEntity.d.ts +37 -0
- package/lib/helpers/MatrixEntity.js +67 -0
- package/lib/helpers/MatrixEntity.js.map +1 -0
- package/lib/helpers/MatrixGlob.d.ts +22 -0
- package/lib/helpers/MatrixGlob.js +35 -0
- package/lib/helpers/MatrixGlob.js.map +1 -0
- package/lib/helpers/MentionPill.d.ts +40 -0
- package/lib/helpers/MentionPill.js +91 -0
- package/lib/helpers/MentionPill.js.map +1 -0
- package/lib/helpers/Permalinks.d.ts +58 -0
- package/lib/helpers/Permalinks.js +73 -0
- package/lib/helpers/Permalinks.js.map +1 -0
- package/lib/helpers/ProfileCache.d.ts +48 -0
- package/lib/helpers/ProfileCache.js +114 -0
- package/lib/helpers/ProfileCache.js.map +1 -0
- package/lib/helpers/RichReply.d.ts +17 -0
- package/lib/helpers/RichReply.js +47 -0
- package/lib/helpers/RichReply.js.map +1 -0
- package/lib/helpers/UnpaddedBase64.d.ts +31 -0
- package/lib/helpers/UnpaddedBase64.js +45 -0
- package/lib/helpers/UnpaddedBase64.js.map +1 -0
- package/lib/http.d.ts +17 -0
- package/lib/http.js +147 -0
- package/lib/http.js.map +1 -0
- package/lib/identity/IdentityClient.d.ts +93 -0
- package/lib/identity/IdentityClient.js +248 -0
- package/lib/identity/IdentityClient.js.map +1 -0
- package/lib/index.d.ts +91 -0
- package/lib/index.js +125 -0
- package/lib/index.js.map +1 -0
- package/lib/logging/ConsoleLogger.d.ts +12 -0
- package/lib/logging/ConsoleLogger.js +28 -0
- package/lib/logging/ConsoleLogger.js.map +1 -0
- package/lib/logging/ILogger.d.ts +36 -0
- package/lib/logging/ILogger.js +3 -0
- package/lib/logging/ILogger.js.map +1 -0
- package/lib/logging/LogService.d.ts +100 -0
- package/lib/logging/LogService.js +169 -0
- package/lib/logging/LogService.js.map +1 -0
- package/lib/logging/RichConsoleLogger.d.ts +20 -0
- package/lib/logging/RichConsoleLogger.js +41 -0
- package/lib/logging/RichConsoleLogger.js.map +1 -0
- package/lib/metrics/IMetricListener.d.ts +52 -0
- package/lib/metrics/IMetricListener.js +3 -0
- package/lib/metrics/IMetricListener.js.map +1 -0
- package/lib/metrics/Metrics.d.ts +66 -0
- package/lib/metrics/Metrics.js +128 -0
- package/lib/metrics/Metrics.js.map +1 -0
- package/lib/metrics/contexts.d.ts +51 -0
- package/lib/metrics/contexts.js +3 -0
- package/lib/metrics/contexts.js.map +1 -0
- package/lib/metrics/decorators.d.ts +15 -0
- package/lib/metrics/decorators.js +92 -0
- package/lib/metrics/decorators.js.map +1 -0
- package/lib/metrics/names.d.ts +45 -0
- package/lib/metrics/names.js +49 -0
- package/lib/metrics/names.js.map +1 -0
- package/lib/mixins/AutojoinRoomsMixin.d.ts +10 -0
- package/lib/mixins/AutojoinRoomsMixin.js +25 -0
- package/lib/mixins/AutojoinRoomsMixin.js.map +1 -0
- package/lib/mixins/AutojoinUpgradedRoomsMixin.d.ts +10 -0
- package/lib/mixins/AutojoinUpgradedRoomsMixin.js +40 -0
- package/lib/mixins/AutojoinUpgradedRoomsMixin.js.map +1 -0
- package/lib/models/Account.d.ts +8 -0
- package/lib/models/Account.js +3 -0
- package/lib/models/Account.js.map +1 -0
- package/lib/models/CreateRoom.d.ts +125 -0
- package/lib/models/CreateRoom.js +3 -0
- package/lib/models/CreateRoom.js.map +1 -0
- package/lib/models/Crypto.d.ts +167 -0
- package/lib/models/Crypto.js +31 -0
- package/lib/models/Crypto.js.map +1 -0
- package/lib/models/EventContext.d.ts +19 -0
- package/lib/models/EventContext.js +3 -0
- package/lib/models/EventContext.js.map +1 -0
- package/lib/models/IdentityServerModels.d.ts +20 -0
- package/lib/models/IdentityServerModels.js +3 -0
- package/lib/models/IdentityServerModels.js.map +1 -0
- package/lib/models/MSC2176.d.ts +42 -0
- package/lib/models/MSC2176.js +3 -0
- package/lib/models/MSC2176.js.map +1 -0
- package/lib/models/MatrixError.d.ts +38 -0
- package/lib/models/MatrixError.js +30 -0
- package/lib/models/MatrixError.js.map +1 -0
- package/lib/models/MatrixProfile.d.ts +43 -0
- package/lib/models/MatrixProfile.js +43 -0
- package/lib/models/MatrixProfile.js.map +1 -0
- package/lib/models/OpenIDConnect.d.ts +10 -0
- package/lib/models/OpenIDConnect.js +3 -0
- package/lib/models/OpenIDConnect.js.map +1 -0
- package/lib/models/Policies.d.ts +25 -0
- package/lib/models/Policies.js +3 -0
- package/lib/models/Policies.js.map +1 -0
- package/lib/models/PowerLevelAction.d.ts +27 -0
- package/lib/models/PowerLevelAction.js +32 -0
- package/lib/models/PowerLevelAction.js.map +1 -0
- package/lib/models/PowerLevelBounds.d.ts +15 -0
- package/lib/models/PowerLevelBounds.js +3 -0
- package/lib/models/PowerLevelBounds.js.map +1 -0
- package/lib/models/Presence.d.ts +25 -0
- package/lib/models/Presence.js +38 -0
- package/lib/models/Presence.js.map +1 -0
- package/lib/models/ServerVersions.d.ts +8 -0
- package/lib/models/ServerVersions.js +3 -0
- package/lib/models/ServerVersions.js.map +1 -0
- package/lib/models/Spaces.d.ts +116 -0
- package/lib/models/Spaces.js +91 -0
- package/lib/models/Spaces.js.map +1 -0
- package/lib/models/Threepid.d.ts +8 -0
- package/lib/models/Threepid.js +3 -0
- package/lib/models/Threepid.js.map +1 -0
- package/lib/models/events/AliasesEvent.d.ts +27 -0
- package/lib/models/events/AliasesEvent.js +27 -0
- package/lib/models/events/AliasesEvent.js.map +1 -0
- package/lib/models/events/CanonicalAliasEvent.d.ts +23 -0
- package/lib/models/events/CanonicalAliasEvent.js +21 -0
- package/lib/models/events/CanonicalAliasEvent.js.map +1 -0
- package/lib/models/events/CreateEvent.d.ts +63 -0
- package/lib/models/events/CreateEvent.js +33 -0
- package/lib/models/events/CreateEvent.js.map +1 -0
- package/lib/models/events/EncryptedRoomEvent.d.ts +42 -0
- package/lib/models/events/EncryptedRoomEvent.js +28 -0
- package/lib/models/events/EncryptedRoomEvent.js.map +1 -0
- package/lib/models/events/EncryptionEvent.d.ts +47 -0
- package/lib/models/events/EncryptionEvent.js +42 -0
- package/lib/models/events/EncryptionEvent.js.map +1 -0
- package/lib/models/events/Event.d.ts +26 -0
- package/lib/models/events/Event.js +40 -0
- package/lib/models/events/Event.js.map +1 -0
- package/lib/models/events/EventKind.d.ts +15 -0
- package/lib/models/events/EventKind.js +20 -0
- package/lib/models/events/EventKind.js.map +1 -0
- package/lib/models/events/InvalidEventError.d.ts +14 -0
- package/lib/models/events/InvalidEventError.js +24 -0
- package/lib/models/events/InvalidEventError.js.map +1 -0
- package/lib/models/events/JoinRulesEvent.d.ts +29 -0
- package/lib/models/events/JoinRulesEvent.js +21 -0
- package/lib/models/events/JoinRulesEvent.js.map +1 -0
- package/lib/models/events/MembershipEvent.d.ts +54 -0
- package/lib/models/events/MembershipEvent.js +49 -0
- package/lib/models/events/MembershipEvent.js.map +1 -0
- package/lib/models/events/MessageEvent.d.ts +233 -0
- package/lib/models/events/MessageEvent.js +49 -0
- package/lib/models/events/MessageEvent.js.map +1 -0
- package/lib/models/events/PinnedEventsEvent.d.ts +23 -0
- package/lib/models/events/PinnedEventsEvent.js +21 -0
- package/lib/models/events/PinnedEventsEvent.js.map +1 -0
- package/lib/models/events/PowerLevelsEvent.d.ts +96 -0
- package/lib/models/events/PowerLevelsEvent.js +70 -0
- package/lib/models/events/PowerLevelsEvent.js.map +1 -0
- package/lib/models/events/PresenceEvent.d.ts +56 -0
- package/lib/models/events/PresenceEvent.js +21 -0
- package/lib/models/events/PresenceEvent.js.map +1 -0
- package/lib/models/events/RedactionEvent.d.ts +28 -0
- package/lib/models/events/RedactionEvent.js +36 -0
- package/lib/models/events/RedactionEvent.js.map +1 -0
- package/lib/models/events/RoomAvatarEvent.d.ts +28 -0
- package/lib/models/events/RoomAvatarEvent.js +21 -0
- package/lib/models/events/RoomAvatarEvent.js.map +1 -0
- package/lib/models/events/RoomEvent.d.ts +58 -0
- package/lib/models/events/RoomEvent.js +57 -0
- package/lib/models/events/RoomEvent.js.map +1 -0
- package/lib/models/events/RoomNameEvent.d.ts +20 -0
- package/lib/models/events/RoomNameEvent.js +21 -0
- package/lib/models/events/RoomNameEvent.js.map +1 -0
- package/lib/models/events/RoomTopicEvent.d.ts +20 -0
- package/lib/models/events/RoomTopicEvent.js +21 -0
- package/lib/models/events/RoomTopicEvent.js.map +1 -0
- package/lib/models/events/SpaceChildEvent.d.ts +53 -0
- package/lib/models/events/SpaceChildEvent.js +49 -0
- package/lib/models/events/SpaceChildEvent.js.map +1 -0
- package/lib/models/events/converter.d.ts +8 -0
- package/lib/models/events/converter.js +50 -0
- package/lib/models/events/converter.js.map +1 -0
- package/lib/models/unstable/MediaInfo.d.ts +16 -0
- package/lib/models/unstable/MediaInfo.js +3 -0
- package/lib/models/unstable/MediaInfo.js.map +1 -0
- package/lib/preprocessors/IPreprocessor.d.ts +22 -0
- package/lib/preprocessors/IPreprocessor.js +3 -0
- package/lib/preprocessors/IPreprocessor.js.map +1 -0
- package/lib/preprocessors/RichRepliesPreprocessor.d.ts +67 -0
- package/lib/preprocessors/RichRepliesPreprocessor.js +112 -0
- package/lib/preprocessors/RichRepliesPreprocessor.js.map +1 -0
- package/lib/request.d.ts +13 -0
- package/lib/request.js +23 -0
- package/lib/request.js.map +1 -0
- package/lib/simple-validation.d.ts +10 -0
- package/lib/simple-validation.js +30 -0
- package/lib/simple-validation.js.map +1 -0
- package/lib/storage/IAppserviceStorageProvider.d.ts +48 -0
- package/lib/storage/IAppserviceStorageProvider.js +3 -0
- package/lib/storage/IAppserviceStorageProvider.js.map +1 -0
- package/lib/storage/ICryptoStorageProvider.d.ts +32 -0
- package/lib/storage/ICryptoStorageProvider.js +3 -0
- package/lib/storage/ICryptoStorageProvider.js.map +1 -0
- package/lib/storage/IStorageProvider.d.ts +47 -0
- package/lib/storage/IStorageProvider.js +3 -0
- package/lib/storage/IStorageProvider.js.map +1 -0
- package/lib/storage/MemoryStorageProvider.d.ts +26 -0
- package/lib/storage/MemoryStorageProvider.js +55 -0
- package/lib/storage/MemoryStorageProvider.js.map +1 -0
- package/lib/storage/RustSdkCryptoStorageProvider.d.ts +38 -0
- package/lib/storage/RustSdkCryptoStorageProvider.js +69 -0
- package/lib/storage/RustSdkCryptoStorageProvider.js.map +1 -0
- package/lib/storage/SimpleFsStorageProvider.d.ts +31 -0
- package/lib/storage/SimpleFsStorageProvider.js +122 -0
- package/lib/storage/SimpleFsStorageProvider.js.map +1 -0
- package/lib/storage/SimplePostgresStorageProvider.d.ts +32 -0
- package/lib/storage/SimplePostgresStorageProvider.js +148 -0
- package/lib/storage/SimplePostgresStorageProvider.js.map +1 -0
- package/lib/strategies/AppserviceJoinRoomStrategy.d.ts +14 -0
- package/lib/strategies/AppserviceJoinRoomStrategy.js +54 -0
- package/lib/strategies/AppserviceJoinRoomStrategy.js.map +1 -0
- package/lib/strategies/JoinRoomStrategy.d.ts +11 -0
- package/lib/strategies/JoinRoomStrategy.js +44 -0
- package/lib/strategies/JoinRoomStrategy.js.map +1 -0
- package/package.json +136 -4
- package/src/AdminApis.ts +60 -0
- package/src/DMs.ts +164 -0
- package/src/IFilter.ts +7 -0
- package/src/MatrixAuth.ts +129 -0
- package/src/MatrixClient.ts +2046 -0
- package/src/PantalaimonClient.ts +62 -0
- package/src/SynapseAdminApis.ts +482 -0
- package/src/SynchronousMatrixClient.ts +129 -0
- package/src/UnstableApis.ts +75 -0
- package/src/appservice/Appservice.ts +1089 -0
- package/src/appservice/Intent.ts +342 -0
- package/src/appservice/MatrixBridge.ts +139 -0
- package/src/appservice/UnstableAppserviceApis.ts +63 -0
- package/src/appservice/http_responses.ts +77 -0
- package/src/b64.ts +63 -0
- package/src/e2ee/CrossSigningBootstrap.ts +141 -0
- package/src/e2ee/CryptoClient.ts +378 -0
- package/src/e2ee/ICryptoRoomInformation.ts +9 -0
- package/src/e2ee/RoomTracker.ts +99 -0
- package/src/e2ee/RustEngine.ts +580 -0
- package/src/e2ee/decorators.ts +38 -0
- package/src/helpers/MatrixEntity.ts +65 -0
- package/src/helpers/MatrixGlob.ts +38 -0
- package/src/helpers/MentionPill.ts +95 -0
- package/src/helpers/Permalinks.ts +101 -0
- package/src/helpers/ProfileCache.ts +119 -0
- package/src/helpers/RichReply.ts +46 -0
- package/src/helpers/UnpaddedBase64.ts +44 -0
- package/src/http.ts +166 -0
- package/src/identity/IdentityClient.ts +225 -0
- package/src/index.ts +125 -0
- package/src/logging/ConsoleLogger.ts +31 -0
- package/src/logging/ILogger.ts +40 -0
- package/src/logging/LogService.ts +167 -0
- package/src/logging/RichConsoleLogger.ts +70 -0
- package/src/metrics/IMetricListener.ts +57 -0
- package/src/metrics/Metrics.ts +134 -0
- package/src/metrics/contexts.ts +56 -0
- package/src/metrics/decorators.ts +94 -0
- package/src/metrics/names.ts +53 -0
- package/src/mixins/AutojoinRoomsMixin.ts +24 -0
- package/src/mixins/AutojoinUpgradedRoomsMixin.ts +37 -0
- package/src/models/Account.ts +8 -0
- package/src/models/CreateRoom.ts +144 -0
- package/src/models/Crypto.ts +188 -0
- package/src/models/EventContext.ts +23 -0
- package/src/models/IdentityServerModels.ts +18 -0
- package/src/models/MSC2176.ts +47 -0
- package/src/models/MatrixError.ts +39 -0
- package/src/models/MatrixProfile.ts +55 -0
- package/src/models/OpenIDConnect.ts +10 -0
- package/src/models/Policies.ts +28 -0
- package/src/models/PowerLevelAction.ts +31 -0
- package/src/models/PowerLevelBounds.ts +16 -0
- package/src/models/Presence.ts +38 -0
- package/src/models/ServerVersions.ts +8 -0
- package/src/models/Spaces.ts +167 -0
- package/src/models/Threepid.ts +8 -0
- package/src/models/events/AliasesEvent.ts +37 -0
- package/src/models/events/CanonicalAliasEvent.ts +30 -0
- package/src/models/events/CreateEvent.ts +82 -0
- package/src/models/events/EncryptedRoomEvent.ts +58 -0
- package/src/models/events/EncryptionEvent.ts +63 -0
- package/src/models/events/Event.ts +38 -0
- package/src/models/events/EventKind.ts +16 -0
- package/src/models/events/InvalidEventError.ts +19 -0
- package/src/models/events/JoinRulesEvent.ts +37 -0
- package/src/models/events/MembershipEvent.ts +77 -0
- package/src/models/events/MessageEvent.ts +292 -0
- package/src/models/events/PinnedEventsEvent.ts +30 -0
- package/src/models/events/PowerLevelsEvent.ts +135 -0
- package/src/models/events/PresenceEvent.ts +69 -0
- package/src/models/events/RedactionEvent.ts +44 -0
- package/src/models/events/RoomAvatarEvent.ts +36 -0
- package/src/models/events/RoomEvent.ts +83 -0
- package/src/models/events/RoomNameEvent.ts +27 -0
- package/src/models/events/RoomTopicEvent.ts +27 -0
- package/src/models/events/SpaceChildEvent.ts +74 -0
- package/src/models/events/_MissingEvents.md +35 -0
- package/src/models/events/converter.ts +47 -0
- package/src/models/unstable/MediaInfo.ts +16 -0
- package/src/preprocessors/IPreprocessor.ts +24 -0
- package/src/preprocessors/RichRepliesPreprocessor.ts +159 -0
- package/src/request.ts +21 -0
- package/src/simple-validation.ts +30 -0
- package/src/storage/IAppserviceStorageProvider.ts +54 -0
- package/src/storage/ICryptoStorageProvider.ts +36 -0
- package/src/storage/IStorageProvider.ts +53 -0
- package/src/storage/MemoryStorageProvider.ts +65 -0
- package/src/storage/RustSdkCryptoStorageProvider.ts +81 -0
- package/src/storage/SimpleFsStorageProvider.ts +142 -0
- package/src/storage/SimplePostgresStorageProvider.ts +168 -0
- package/src/strategies/AppserviceJoinRoomStrategy.ts +47 -0
- package/src/strategies/JoinRoomStrategy.ts +45 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as globToRegexp from "glob-to-regexp";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a common Matrix glob. This is commonly used
|
|
5
|
+
* for server ACLs and similar functions.
|
|
6
|
+
* @category Utilities
|
|
7
|
+
*/
|
|
8
|
+
export class MatrixGlob {
|
|
9
|
+
/**
|
|
10
|
+
* The regular expression which represents this glob.
|
|
11
|
+
*/
|
|
12
|
+
public readonly regex: RegExp;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new Matrix Glob
|
|
16
|
+
* @param {string} glob The glob to convert. Eg: "*.example.org"
|
|
17
|
+
*/
|
|
18
|
+
constructor(glob: string) {
|
|
19
|
+
const globRegex = globToRegexp(glob, {
|
|
20
|
+
extended: false,
|
|
21
|
+
globstar: false,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// We need to convert `?` manually because globToRegexp's extended mode
|
|
25
|
+
// does more than we want it to.
|
|
26
|
+
const replaced = globRegex.toString().replace(/\\\?/g, ".");
|
|
27
|
+
this.regex = new RegExp(replaced.substring(1, replaced.length - 1));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Tests the glob against a value, returning true if it matches.
|
|
32
|
+
* @param {string} val The value to test.
|
|
33
|
+
* @returns {boolean} True if the value matches the glob, false otherwise.
|
|
34
|
+
*/
|
|
35
|
+
public test(val: string): boolean {
|
|
36
|
+
return this.regex.test(val);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { MatrixClient } from "../MatrixClient";
|
|
2
|
+
import { Permalinks } from "./Permalinks";
|
|
3
|
+
import { extractRequestError, LogService } from "..";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents a system for generating a mention pill for an entity.
|
|
7
|
+
* @category Utilities
|
|
8
|
+
*/
|
|
9
|
+
export class MentionPill {
|
|
10
|
+
private constructor(private entityPermalink: string, private displayName: string) {
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The HTML component of the mention.
|
|
15
|
+
*/
|
|
16
|
+
public get html(): string {
|
|
17
|
+
return `<a href="${this.entityPermalink}">${this.displayName}</a>`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The plain text component of the mention.
|
|
22
|
+
*/
|
|
23
|
+
public get text(): string {
|
|
24
|
+
return this.displayName;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new mention for a user in an optional room.
|
|
29
|
+
* @param {string} userId The user ID the mention is for.
|
|
30
|
+
* @param {String} inRoomId Optional room ID the user is being mentioned in, for the aesthetics of the mention.
|
|
31
|
+
* @param {MatrixClient} client Optional client for creating a more pleasing mention.
|
|
32
|
+
* @returns {Promise<MentionPill>} Resolves to the user's mention.
|
|
33
|
+
*/
|
|
34
|
+
public static async forUser(userId: string, inRoomId: string = null, client: MatrixClient = null): Promise<MentionPill> {
|
|
35
|
+
const permalink = Permalinks.forUser(userId);
|
|
36
|
+
|
|
37
|
+
let displayName = userId;
|
|
38
|
+
try {
|
|
39
|
+
if (client) {
|
|
40
|
+
let profile = null;
|
|
41
|
+
|
|
42
|
+
if (inRoomId) {
|
|
43
|
+
profile = await client.getRoomStateEvent(inRoomId, "m.room.member", userId);
|
|
44
|
+
}
|
|
45
|
+
if (!profile) {
|
|
46
|
+
profile = await client.getUserProfile(userId);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (profile['displayname']) {
|
|
50
|
+
displayName = profile['displayname'];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
} catch (e) {
|
|
54
|
+
LogService.warn("MentionPill", "Error getting profile", extractRequestError(e));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return new MentionPill(permalink, displayName);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Creates a new mention for a room (not @room, but the room itself to be linked).
|
|
62
|
+
* @param {string} roomIdOrAlias The room ID or alias to mention.
|
|
63
|
+
* @param {MatrixClient} client Optional client for creating a more pleasing mention.
|
|
64
|
+
* @returns {Promise<MentionPill>} Resolves to the room's mention.
|
|
65
|
+
*/
|
|
66
|
+
public static async forRoom(roomIdOrAlias: string, client: MatrixClient = null): Promise<MentionPill> {
|
|
67
|
+
let permalink = Permalinks.forRoom(roomIdOrAlias);
|
|
68
|
+
let displayProp = roomIdOrAlias;
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
if (client) {
|
|
72
|
+
const roomId = await client.resolveRoom(roomIdOrAlias);
|
|
73
|
+
const canonicalAlias = await client.getRoomStateEvent(roomId, "m.room.canonical_alias", "");
|
|
74
|
+
if (canonicalAlias?.alias) {
|
|
75
|
+
displayProp = canonicalAlias.alias;
|
|
76
|
+
permalink = Permalinks.forRoom(displayProp);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
} catch (e) {
|
|
80
|
+
LogService.warn("MentionPill", "Error getting room information", extractRequestError(e));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return new MentionPill(permalink, displayProp);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Creates a mention from static information.
|
|
88
|
+
* @param {string} userId The user ID the mention is for.
|
|
89
|
+
* @param {string} displayName The user's display name.
|
|
90
|
+
* @returns {MentionPill} The mention for the user.
|
|
91
|
+
*/
|
|
92
|
+
public static withDisplayName(userId: string, displayName: string): MentionPill {
|
|
93
|
+
return new MentionPill(Permalinks.forUser(userId), displayName || userId);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parts of a permalink.
|
|
3
|
+
* @see Permalinks
|
|
4
|
+
* @category Utilities
|
|
5
|
+
*/
|
|
6
|
+
export interface PermalinkParts {
|
|
7
|
+
/**
|
|
8
|
+
* The room ID or alias the permalink references. May be undefined.
|
|
9
|
+
*/
|
|
10
|
+
roomIdOrAlias: string;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The user ID the permalink references. May be undefined.
|
|
14
|
+
*/
|
|
15
|
+
userId: string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The event ID the permalink references. May be undefined.
|
|
19
|
+
*/
|
|
20
|
+
eventId: string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The servers the permalink is routed through. May be undefined or empty.
|
|
24
|
+
*/
|
|
25
|
+
viaServers: string[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Functions for handling permalinks
|
|
30
|
+
* @category Utilities
|
|
31
|
+
*/
|
|
32
|
+
export class Permalinks {
|
|
33
|
+
private constructor() {
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// TODO: Encode permalinks
|
|
37
|
+
|
|
38
|
+
private static encodeViaArgs(servers: string[]): string {
|
|
39
|
+
if (!servers || !servers.length) return "";
|
|
40
|
+
|
|
41
|
+
return `?via=${servers.join("&via=")}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Creates a room permalink.
|
|
46
|
+
* @param {string} roomIdOrAlias The room ID or alias to create a permalink for.
|
|
47
|
+
* @param {string[]} viaServers The servers to route the permalink through.
|
|
48
|
+
* @returns {string} A room permalink.
|
|
49
|
+
*/
|
|
50
|
+
public static forRoom(roomIdOrAlias: string, viaServers: string[] = []): string {
|
|
51
|
+
return `https://matrix.to/#/${roomIdOrAlias}${Permalinks.encodeViaArgs(viaServers)}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Creates a user permalink.
|
|
56
|
+
* @param {string} userId The user ID to create a permalink for.
|
|
57
|
+
* @returns {string} A user permalink.
|
|
58
|
+
*/
|
|
59
|
+
public static forUser(userId: string): string {
|
|
60
|
+
return `https://matrix.to/#/${userId}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Creates an event permalink.
|
|
65
|
+
* @param {string} roomIdOrAlias The room ID or alias to create a permalink in.
|
|
66
|
+
* @param {string} eventId The event ID to reference in the permalink.
|
|
67
|
+
* @param {string[]} viaServers The servers to route the permalink through.
|
|
68
|
+
* @returns {string} An event permalink.
|
|
69
|
+
*/
|
|
70
|
+
public static forEvent(roomIdOrAlias: string, eventId: string, viaServers: string[] = []): string {
|
|
71
|
+
return `https://matrix.to/#/${roomIdOrAlias}/${eventId}${Permalinks.encodeViaArgs(viaServers)}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Parses a permalink URL into usable parts.
|
|
76
|
+
* @param {string} matrixTo The matrix.to URL to parse.
|
|
77
|
+
* @returns {PermalinkParts} The parts of the permalink.
|
|
78
|
+
*/
|
|
79
|
+
public static parseUrl(matrixTo: string): PermalinkParts {
|
|
80
|
+
const matrixToRegexp = /^https:\/\/matrix\.to\/#\/(?<entity>[^/?]+)\/?(?<eventId>[^?]+)?(?<query>\?[^]*)?$/;
|
|
81
|
+
|
|
82
|
+
const url = matrixToRegexp.exec(matrixTo)?.groups;
|
|
83
|
+
if (!url) {
|
|
84
|
+
throw new Error("Not a valid matrix.to URL");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const entity = decodeURIComponent(url.entity);
|
|
88
|
+
if (entity[0] === '@') {
|
|
89
|
+
return { userId: entity, roomIdOrAlias: undefined, eventId: undefined, viaServers: undefined };
|
|
90
|
+
} else if (entity[0] === '#' || entity[0] === '!') {
|
|
91
|
+
return {
|
|
92
|
+
userId: undefined,
|
|
93
|
+
roomIdOrAlias: entity,
|
|
94
|
+
eventId: url.eventId && decodeURIComponent(url.eventId),
|
|
95
|
+
viaServers: new URLSearchParams(url.query).getAll('via'),
|
|
96
|
+
};
|
|
97
|
+
} else {
|
|
98
|
+
throw new Error("Unexpected entity");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import * as LRU from "lru-cache";
|
|
2
|
+
|
|
3
|
+
import { extractRequestError, LogService, MatrixClient, MatrixProfile } from "..";
|
|
4
|
+
import { MembershipEvent } from "../models/events/MembershipEvent";
|
|
5
|
+
import { Appservice } from "../appservice/Appservice";
|
|
6
|
+
|
|
7
|
+
type CacheKey = `${string}@${string | '<none>'}`;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Functions for avoiding calls to profile endpoints. Useful for bots when
|
|
11
|
+
* people are mentioned often or bridges which need profile information
|
|
12
|
+
* often.
|
|
13
|
+
* @category Utilities
|
|
14
|
+
*/
|
|
15
|
+
export class ProfileCache {
|
|
16
|
+
private cache: LRU.LRUCache<CacheKey, MatrixProfile>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new profile cache.
|
|
20
|
+
* @param {number} maxEntries The maximum number of entries to cache.
|
|
21
|
+
* @param {number} maxAgeMs The maximum age of an entry in milliseconds.
|
|
22
|
+
* @param {MatrixClient} client The client to use to get profile updates.
|
|
23
|
+
*/
|
|
24
|
+
constructor(maxEntries: number, maxAgeMs: number, private client: MatrixClient) {
|
|
25
|
+
this.cache = new LRU.LRUCache({
|
|
26
|
+
max: maxEntries,
|
|
27
|
+
ttl: maxAgeMs,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private getCacheKey(userId: string, roomId: string | null): CacheKey {
|
|
32
|
+
return `${userId}@${roomId || '<none>'}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Watch for profile changes to cached entries with the provided client. The
|
|
37
|
+
* same client will also be used to update the user's profile in the cache.
|
|
38
|
+
* @param {MatrixClient} client The client to watch for profile changes with.
|
|
39
|
+
*/
|
|
40
|
+
public watchWithClient(client: MatrixClient) {
|
|
41
|
+
client.on("room.event", async (roomId: string, event: string) => {
|
|
42
|
+
if (!event['state_key'] || !event['content'] || event['type'] !== 'm.room.member') return;
|
|
43
|
+
await this.tryUpdateProfile(roomId, new MembershipEvent(event), client);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Watch for profile changes to cached entries with the provided application
|
|
49
|
+
* service. The clientFn will be called to get the relevant client for any
|
|
50
|
+
* updates. If the clientFn is null, the appservice's bot user will be used.
|
|
51
|
+
* The clientFn takes two arguments: the user ID being updated and the room ID
|
|
52
|
+
* they are being updated in (shouldn't be null). The return value should be the
|
|
53
|
+
* MatrixClient to use, or null to use the appservice's bot client. The same
|
|
54
|
+
* client will be used to update the user's general profile, if that profile
|
|
55
|
+
* is cached.
|
|
56
|
+
* @param {Appservice} appservice The application service to watch for profile changes with.
|
|
57
|
+
* @param {Function} clientFn The function to use to acquire profile updates with. If null, the appservice's bot client will be used.
|
|
58
|
+
*/
|
|
59
|
+
public watchWithAppservice(appservice: Appservice, clientFn: (userId: string, roomId: string) => MatrixClient = null) {
|
|
60
|
+
if (!clientFn) clientFn = () => appservice.botClient;
|
|
61
|
+
appservice.on("room.event", async (roomId: string, event: string) => {
|
|
62
|
+
if (!event['state_key'] || !event['content'] || event['type'] !== 'm.room.member') return;
|
|
63
|
+
|
|
64
|
+
const memberEvent = new MembershipEvent(event);
|
|
65
|
+
let client = clientFn(memberEvent.membershipFor, roomId);
|
|
66
|
+
if (!client) client = appservice.botClient;
|
|
67
|
+
|
|
68
|
+
await this.tryUpdateProfile(roomId, memberEvent, client);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Gets a profile for a user in optional room.
|
|
74
|
+
* @param {string} userId The user ID to get a profile for.
|
|
75
|
+
* @param {string|null} roomId Optional room ID to get a per-room profile for the user.
|
|
76
|
+
* @returns {Promise<MatrixProfile>} Resolves to the user's profile.
|
|
77
|
+
*/
|
|
78
|
+
public async getUserProfile(userId: string, roomId: string = null): Promise<MatrixProfile> {
|
|
79
|
+
const cacheKey = this.getCacheKey(userId, roomId);
|
|
80
|
+
const cached = this.cache.get(cacheKey);
|
|
81
|
+
if (cached) return Promise.resolve(<MatrixProfile>cached);
|
|
82
|
+
|
|
83
|
+
const profile = await this.getUserProfileWith(userId, roomId, this.client);
|
|
84
|
+
this.cache.set(cacheKey, profile);
|
|
85
|
+
return profile;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private async getUserProfileWith(userId: string, roomId: string, client: MatrixClient): Promise<MatrixProfile> {
|
|
89
|
+
try {
|
|
90
|
+
if (roomId) {
|
|
91
|
+
const membership = await client.getRoomStateEvent(roomId, "m.room.member", userId);
|
|
92
|
+
return new MatrixProfile(userId, membership);
|
|
93
|
+
} else {
|
|
94
|
+
const profile = await client.getUserProfile(userId);
|
|
95
|
+
return new MatrixProfile(userId, profile);
|
|
96
|
+
}
|
|
97
|
+
} catch (e) {
|
|
98
|
+
LogService.warn("ProfileCache", "Non-fatal error getting user profile. They might not exist.");
|
|
99
|
+
LogService.warn("ProfileCache", extractRequestError(e));
|
|
100
|
+
return new MatrixProfile(userId, {});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private async tryUpdateProfile(roomId: string, memberEvent: MembershipEvent, client: MatrixClient) {
|
|
105
|
+
const roomCacheKey = this.getCacheKey(memberEvent.membershipFor, roomId);
|
|
106
|
+
const generalCacheKey = this.getCacheKey(memberEvent.membershipFor, null);
|
|
107
|
+
|
|
108
|
+
if (this.cache.has(roomCacheKey)) {
|
|
109
|
+
this.cache.set(roomCacheKey, new MatrixProfile(memberEvent.membershipFor, memberEvent.content));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// TODO: Try and figure out semantics for this updating.
|
|
113
|
+
// Large accounts could cause hammering on the profile endpoint, but hopefully it is cached by the server.
|
|
114
|
+
if (this.cache.has(generalCacheKey)) {
|
|
115
|
+
const profile = await this.getUserProfileWith(memberEvent.membershipFor, null, client);
|
|
116
|
+
this.cache.set(generalCacheKey, profile);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as sanitizeHtml from "sanitize-html";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Helper for creating rich replies.
|
|
5
|
+
* @category Utilities
|
|
6
|
+
*/
|
|
7
|
+
export class RichReply {
|
|
8
|
+
private constructor() {
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Generates the event content required to reply to the provided event with the
|
|
13
|
+
* provided text.
|
|
14
|
+
* @param {string} roomId the room ID the event being replied to resides in
|
|
15
|
+
* @param {any} event the event to reply to
|
|
16
|
+
* @param {string} withText the plain text to reply with
|
|
17
|
+
* @param {string} withHtml the HTML to reply with
|
|
18
|
+
* @returns {any} the content of the event representing the reply
|
|
19
|
+
*/
|
|
20
|
+
public static createFor(roomId: string, event: any, withText: string, withHtml: string): any {
|
|
21
|
+
const originalBody = (event["content"] ? event["content"]["body"] : "") || "";
|
|
22
|
+
let originalHtml = (event["content"] ? event["content"]["formatted_body"] : "") || null;
|
|
23
|
+
if (originalHtml === null) {
|
|
24
|
+
originalHtml = sanitizeHtml(originalBody);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const fallbackText = "> <" + event["sender"] + "> " + originalBody.split("\n").join("\n> ");
|
|
28
|
+
const fallbackHtml = "<mx-reply><blockquote>"
|
|
29
|
+
+ `<a href="https://matrix.to/#/${roomId}/${event["event_id"]}">In reply to</a> `
|
|
30
|
+
+ `<a href="https://matrix.to/#/${event["sender"]}">${event["sender"]}</a>`
|
|
31
|
+
+ "<br />" + originalHtml
|
|
32
|
+
+ "</blockquote></mx-reply>";
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
"m.relates_to": {
|
|
36
|
+
"m.in_reply_to": {
|
|
37
|
+
"event_id": event["event_id"],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
"msgtype": "m.text", // for those who just want to send the reply as-is
|
|
41
|
+
"body": fallbackText + "\n\n" + withText,
|
|
42
|
+
"format": "org.matrix.custom.html",
|
|
43
|
+
"formatted_body": fallbackHtml + withHtml,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unpadded Base64 utilities for Matrix.
|
|
3
|
+
* @category Utilities
|
|
4
|
+
*/
|
|
5
|
+
export class UnpaddedBase64 {
|
|
6
|
+
private constructor() {
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Encodes a buffer to Unpadded Base64
|
|
11
|
+
* @param {Buffer} buf The buffer to encode.
|
|
12
|
+
* @returns {string} The Unpadded Base64 string
|
|
13
|
+
*/
|
|
14
|
+
public static encodeBuffer(buf: Buffer): string {
|
|
15
|
+
return buf.toString('base64').replace(/[=]*$/g, '');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Encodes a string to Unpadded Base64
|
|
20
|
+
* @param {string} str The string to encode.
|
|
21
|
+
* @returns {string} The Unpadded Base64 string
|
|
22
|
+
*/
|
|
23
|
+
public static encodeString(str: string): string {
|
|
24
|
+
return UnpaddedBase64.encodeBuffer(Buffer.from(str));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Encodes a buffer to Unpadded Base64 (URL Safe Edition)
|
|
29
|
+
* @param {Buffer} buf The buffer to encode.
|
|
30
|
+
* @returns {string} The Unpadded Base64 string
|
|
31
|
+
*/
|
|
32
|
+
public static encodeBufferUrlSafe(buf: Buffer): string {
|
|
33
|
+
return UnpaddedBase64.encodeBuffer(buf).replace(/\+/g, '-').replace(/\//g, '_');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Encodes a string to Unpadded Base64 (URL Safe Edition)
|
|
38
|
+
* @param {string} str The string to encode.
|
|
39
|
+
* @returns {string} The Unpadded Base64 string
|
|
40
|
+
*/
|
|
41
|
+
public static encodeStringUrlSafe(str: string): string {
|
|
42
|
+
return UnpaddedBase64.encodeBufferUrlSafe(Buffer.from(str));
|
|
43
|
+
}
|
|
44
|
+
}
|
package/src/http.ts
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { LogLevel, LogService } from "./logging/LogService";
|
|
2
|
+
import { getRequestFn } from "./request";
|
|
3
|
+
import { MatrixError } from "./models/MatrixError";
|
|
4
|
+
|
|
5
|
+
let lastRequestId = 0;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Performs a web request to a server.
|
|
9
|
+
* @category Unit testing
|
|
10
|
+
* @param {string} baseUrl The base URL to apply to the call.
|
|
11
|
+
* @param {"GET"|"POST"|"PUT"|"DELETE"} method The HTTP method to use in the request
|
|
12
|
+
* @param {string} endpoint The endpoint to call. For example: "/_matrix/client/v3/account/whoami"
|
|
13
|
+
* @param {any} qs The query string to send. Optional.
|
|
14
|
+
* @param {any} body The request body to send. Optional. Will be converted to JSON unless the type is a Buffer.
|
|
15
|
+
* @param {any} headers Additional headers to send in the request.
|
|
16
|
+
* @param {number} timeout The number of milliseconds to wait before timing out.
|
|
17
|
+
* @param {boolean} raw If true, the raw response will be returned instead of the response body.
|
|
18
|
+
* @param {string} contentType The content type to send. Only used if the `body` is a Buffer.
|
|
19
|
+
* @param {string} noEncoding Set to true to disable encoding, and return a Buffer. Defaults to false
|
|
20
|
+
* @returns {Promise<any>} Resolves to the response (body), rejected if a non-2xx status code was returned.
|
|
21
|
+
*/
|
|
22
|
+
export async function doHttpRequest(
|
|
23
|
+
baseUrl: string,
|
|
24
|
+
method: "GET" | "POST" | "PUT" | "DELETE",
|
|
25
|
+
endpoint: string,
|
|
26
|
+
qs = null,
|
|
27
|
+
body = null,
|
|
28
|
+
headers = {},
|
|
29
|
+
timeout = 60000,
|
|
30
|
+
raw = false,
|
|
31
|
+
contentType = "application/json",
|
|
32
|
+
noEncoding = false,
|
|
33
|
+
): Promise<any> {
|
|
34
|
+
if (!endpoint.startsWith('/')) {
|
|
35
|
+
endpoint = '/' + endpoint;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const requestId = ++lastRequestId;
|
|
39
|
+
const url = baseUrl + endpoint;
|
|
40
|
+
|
|
41
|
+
// This is logged at info so that when a request fails people can figure out which one.
|
|
42
|
+
LogService.debug("MatrixHttpClient", "(REQ-" + requestId + ")", method + " " + url);
|
|
43
|
+
|
|
44
|
+
// Don't log the request unless we're in debug mode. It can be large.
|
|
45
|
+
if (LogService.level.includes(LogLevel.TRACE)) {
|
|
46
|
+
if (qs) LogService.trace("MatrixHttpClient", "(REQ-" + requestId + ")", "qs = " + JSON.stringify(qs));
|
|
47
|
+
if (body && !Buffer.isBuffer(body)) LogService.trace("MatrixHttpClient", "(REQ-" + requestId + ")", "body = " + JSON.stringify(redactObjectForLogging(body)));
|
|
48
|
+
if (body && Buffer.isBuffer(body)) LogService.trace("MatrixHttpClient", "(REQ-" + requestId + ")", "body = <Buffer>");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const params: { uri: string, [k: string]: any } = {
|
|
52
|
+
uri: url,
|
|
53
|
+
method: method,
|
|
54
|
+
qs: qs,
|
|
55
|
+
// If this is undefined, then a string will be returned. If it's null, a Buffer will be returned.
|
|
56
|
+
encoding: noEncoding === false ? undefined : null,
|
|
57
|
+
useQuerystring: true,
|
|
58
|
+
qsStringifyOptions: {
|
|
59
|
+
options: { arrayFormat: 'repeat' },
|
|
60
|
+
},
|
|
61
|
+
timeout: timeout,
|
|
62
|
+
headers: headers,
|
|
63
|
+
// Enable KeepAlive for HTTP
|
|
64
|
+
forever: true,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
if (body) {
|
|
68
|
+
if (Buffer.isBuffer(body)) {
|
|
69
|
+
params.headers["Content-Type"] = contentType;
|
|
70
|
+
params.body = body;
|
|
71
|
+
} else {
|
|
72
|
+
params.headers["Content-Type"] = "application/json";
|
|
73
|
+
params.body = JSON.stringify(body);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const { response, resBody } = await new Promise<{ response: any, resBody: any }>((resolve, reject) => {
|
|
78
|
+
getRequestFn()(params, (err, res, rBody) => {
|
|
79
|
+
if (err) {
|
|
80
|
+
LogService.error("MatrixHttpClient", "(REQ-" + requestId + ")", err);
|
|
81
|
+
reject(err);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (typeof (rBody) === 'string') {
|
|
86
|
+
try {
|
|
87
|
+
rBody = JSON.parse(rBody);
|
|
88
|
+
} catch (e) {
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (typeof (res.body) === 'string') {
|
|
93
|
+
try {
|
|
94
|
+
res.body = JSON.parse(res.body);
|
|
95
|
+
} catch (e) {
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
resolve({ response: res, resBody: rBody });
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const respIsBuffer = (response.body instanceof Buffer);
|
|
104
|
+
|
|
105
|
+
// Check for errors.
|
|
106
|
+
const errBody = response.body || resBody;
|
|
107
|
+
if (typeof (errBody) === "object" && 'errcode' in errBody) {
|
|
108
|
+
const redactedBody = respIsBuffer ? '<Buffer>' : redactObjectForLogging(errBody);
|
|
109
|
+
LogService.error("MatrixHttpClient", "(REQ-" + requestId + ")", redactedBody);
|
|
110
|
+
throw new MatrixError(errBody, response.statusCode);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Don't log the body unless we're in debug mode. They can be large.
|
|
114
|
+
if (LogService.level.includes(LogLevel.TRACE)) {
|
|
115
|
+
const redactedBody = respIsBuffer ? '<Buffer>' : redactObjectForLogging(response.body);
|
|
116
|
+
LogService.trace("MatrixHttpClient", "(REQ-" + requestId + " RESP-H" + response.statusCode + ")", redactedBody);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
120
|
+
const redactedBody = respIsBuffer ? '<Buffer>' : redactObjectForLogging(response.body);
|
|
121
|
+
LogService.error("MatrixHttpClient", "(REQ-" + requestId + ")", redactedBody);
|
|
122
|
+
throw response;
|
|
123
|
+
}
|
|
124
|
+
return raw ? response : resBody;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function redactObjectForLogging(input: any): any {
|
|
128
|
+
if (!input) return input;
|
|
129
|
+
|
|
130
|
+
const fieldsToRedact = [
|
|
131
|
+
'access_token',
|
|
132
|
+
'password',
|
|
133
|
+
'new_password',
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
const redactFn = (i) => {
|
|
137
|
+
if (!i) return i;
|
|
138
|
+
|
|
139
|
+
// Don't treat strings like arrays/objects
|
|
140
|
+
if (typeof i === 'string') return i;
|
|
141
|
+
|
|
142
|
+
if (Array.isArray(i)) {
|
|
143
|
+
const rebuilt = [];
|
|
144
|
+
for (const v of i) {
|
|
145
|
+
rebuilt.push(redactFn(v));
|
|
146
|
+
}
|
|
147
|
+
return rebuilt;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (i instanceof Object) {
|
|
151
|
+
const rebuilt = {};
|
|
152
|
+
for (const key of Object.keys(i)) {
|
|
153
|
+
if (fieldsToRedact.includes(key)) {
|
|
154
|
+
rebuilt[key] = '<redacted>';
|
|
155
|
+
} else {
|
|
156
|
+
rebuilt[key] = redactFn(i[key]);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return rebuilt;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return i; // It's a primitive value
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
return redactFn(input);
|
|
166
|
+
}
|