@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,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AppserviceJoinRoomStrategy = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* A join strategy for application services that proxies joins to an underlying join
|
|
6
|
+
* strategy while also trying to use the appservice's bot user to invite the underlying
|
|
7
|
+
* user if needed.
|
|
8
|
+
* @category Join strategies
|
|
9
|
+
*/
|
|
10
|
+
class AppserviceJoinRoomStrategy {
|
|
11
|
+
constructor(underlyingStrategy, appservice) {
|
|
12
|
+
this.underlyingStrategy = underlyingStrategy;
|
|
13
|
+
this.appservice = appservice;
|
|
14
|
+
}
|
|
15
|
+
async joinRoom(roomIdOrAlias, userId, apiCall) {
|
|
16
|
+
try {
|
|
17
|
+
// First just try joining via the apiCall
|
|
18
|
+
return await apiCall(roomIdOrAlias);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
// If the user being joined is *not* the bridge bot, try and get the bridge bot to
|
|
22
|
+
// join them to the room.
|
|
23
|
+
if (userId !== this.appservice.botUserId) {
|
|
24
|
+
const client = this.appservice.botIntent.underlyingClient;
|
|
25
|
+
const roomId = await client.resolveRoom(roomIdOrAlias);
|
|
26
|
+
try {
|
|
27
|
+
// First start with having the bridge bot invite the user to the room
|
|
28
|
+
await client.inviteUser(userId, roomId);
|
|
29
|
+
}
|
|
30
|
+
catch (inviteErr) {
|
|
31
|
+
// The invite failed - use the underlying join strategy to join the room, just in case.
|
|
32
|
+
// If there's no join strategy, we want to fall through to an error.
|
|
33
|
+
if (this.underlyingStrategy)
|
|
34
|
+
return this.underlyingStrategy.joinRoom(roomId, userId, apiCall);
|
|
35
|
+
throw inviteErr;
|
|
36
|
+
}
|
|
37
|
+
// The invite succeeded - use the underlying join strategy to join the room or just call use
|
|
38
|
+
// the apiCall if no strategy exists. We are expecting success.
|
|
39
|
+
if (this.underlyingStrategy)
|
|
40
|
+
return this.underlyingStrategy.joinRoom(roomId, userId, apiCall);
|
|
41
|
+
else
|
|
42
|
+
return apiCall(roomId);
|
|
43
|
+
}
|
|
44
|
+
else if (this.underlyingStrategy) {
|
|
45
|
+
// If the user being joined *is* the bridge bot, try and use the join strategy to join.
|
|
46
|
+
return this.underlyingStrategy.joinRoom(roomIdOrAlias, userId, apiCall);
|
|
47
|
+
}
|
|
48
|
+
// Finally, if all else fails, throw.
|
|
49
|
+
throw err;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.AppserviceJoinRoomStrategy = AppserviceJoinRoomStrategy;
|
|
54
|
+
//# sourceMappingURL=AppserviceJoinRoomStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppserviceJoinRoomStrategy.js","sourceRoot":"","sources":["../../src/strategies/AppserviceJoinRoomStrategy.ts"],"names":[],"mappings":";;;AAGA;;;;;GAKG;AACH,MAAa,0BAA0B;IACnC,YAAoB,kBAAqC,EAAU,UAAsB;QAArE,uBAAkB,GAAlB,kBAAkB,CAAmB;QAAU,eAAU,GAAV,UAAU,CAAY;IACzF,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,aAAqB,EAAE,MAAc,EAAE,OAAyD;QAClH,IAAI,CAAC;YACD,yCAAyC;YACzC,OAAO,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,kFAAkF;YAClF,yBAAyB;YACzB,IAAI,MAAM,KAAK,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;gBACvC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,gBAAgB,CAAC;gBAC1D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;gBACvD,IAAI,CAAC;oBACD,qEAAqE;oBACrE,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAC5C,CAAC;gBAAC,OAAO,SAAS,EAAE,CAAC;oBACjB,uFAAuF;oBACvF,oEAAoE;oBACpE,IAAI,IAAI,CAAC,kBAAkB;wBAAE,OAAO,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;oBAC9F,MAAM,SAAS,CAAC;gBACpB,CAAC;gBAED,4FAA4F;gBAC5F,+DAA+D;gBAC/D,IAAI,IAAI,CAAC,kBAAkB;oBAAE,OAAO,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;;oBACzF,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC;iBAAM,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACjC,uFAAuF;gBACvF,OAAO,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YAC5E,CAAC;YAED,qCAAqC;YACrC,MAAM,GAAG,CAAC;QACd,CAAC;IACL,CAAC;CACJ;AArCD,gEAqCC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface IJoinRoomStrategy {
|
|
2
|
+
joinRoom(roomIdOrAlias: string, userId: string, apiCall: (targetRoomIdOrAlias: string) => Promise<string>): Promise<string>;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* A join strategy that keeps trying to join the room on a set interval.
|
|
6
|
+
* @category Join strategies
|
|
7
|
+
*/
|
|
8
|
+
export declare class SimpleRetryJoinStrategy implements IJoinRoomStrategy {
|
|
9
|
+
private schedule;
|
|
10
|
+
joinRoom(roomIdOrAlias: string, userId: string, apiCall: (targetRoomIdOrAlias: string) => Promise<string>): Promise<string>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SimpleRetryJoinStrategy = void 0;
|
|
4
|
+
const __1 = require("..");
|
|
5
|
+
/**
|
|
6
|
+
* A join strategy that keeps trying to join the room on a set interval.
|
|
7
|
+
* @category Join strategies
|
|
8
|
+
*/
|
|
9
|
+
class SimpleRetryJoinStrategy {
|
|
10
|
+
constructor() {
|
|
11
|
+
// Note: The schedule must not have duplicate values to avoid problems in positioning.
|
|
12
|
+
this.schedule = [
|
|
13
|
+
0, // Right away
|
|
14
|
+
1000, // 1 second
|
|
15
|
+
30 * 1000, // 30 seconds
|
|
16
|
+
5 * 60 * 1000, // 5 minutes
|
|
17
|
+
15 * 60 * 1000, // 15 minutes
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
joinRoom(roomIdOrAlias, userId, apiCall) {
|
|
21
|
+
let currentSchedule = this.schedule[0];
|
|
22
|
+
const doJoin = () => waitPromise(currentSchedule).then(() => apiCall(roomIdOrAlias));
|
|
23
|
+
const errorHandler = err => {
|
|
24
|
+
__1.LogService.error("SimpleRetryJoinStrategy", (0, __1.extractRequestError)(err));
|
|
25
|
+
const idx = this.schedule.indexOf(currentSchedule);
|
|
26
|
+
if (idx === this.schedule.length - 1) {
|
|
27
|
+
__1.LogService.warn("SimpleRetryJoinStrategy", "Failed to join room " + roomIdOrAlias);
|
|
28
|
+
return Promise.reject(err);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
currentSchedule = this.schedule[idx + 1];
|
|
32
|
+
return doJoin().catch(errorHandler);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
return doJoin().catch(errorHandler);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.SimpleRetryJoinStrategy = SimpleRetryJoinStrategy;
|
|
39
|
+
function waitPromise(interval) {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
setTimeout(resolve, interval);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=JoinRoomStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JoinRoomStrategy.js","sourceRoot":"","sources":["../../src/strategies/JoinRoomStrategy.ts"],"names":[],"mappings":";;;AAAA,0BAAqD;AAMrD;;;GAGG;AACH,MAAa,uBAAuB;IAApC;QACI,sFAAsF;QAC9E,aAAQ,GAAG;YACf,CAAC,EAAe,aAAa;YAC7B,IAAI,EAAY,WAAW;YAC3B,EAAE,GAAG,IAAI,EAAO,aAAa;YAC7B,CAAC,GAAG,EAAE,GAAG,IAAI,EAAG,YAAY;YAC5B,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;SAChC,CAAC;IAoBN,CAAC;IAlBU,QAAQ,CAAC,aAAqB,EAAE,MAAc,EAAE,OAAyD;QAC5G,IAAI,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAEvC,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;QACrF,MAAM,YAAY,GAAG,GAAG,CAAC,EAAE;YACvB,cAAU,CAAC,KAAK,CAAC,yBAAyB,EAAE,IAAA,uBAAmB,EAAC,GAAG,CAAC,CAAC,CAAC;YACtE,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACnD,IAAI,GAAG,KAAK,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnC,cAAU,CAAC,IAAI,CAAC,yBAAyB,EAAE,sBAAsB,GAAG,aAAa,CAAC,CAAC;gBACnF,OAAO,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACJ,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;gBACzC,OAAO,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACxC,CAAC;QACL,CAAC,CAAC;QAEF,OAAO,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC;CACJ;AA5BD,0DA4BC;AAED,SAAS,WAAW,CAAC,QAAgB;IACjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,138 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jeongsu816/matrix-bot-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.8.1",
|
|
4
|
+
"description": "Fork of matrix-bot-sdk with cross-signing, secret storage and dependency security fixes",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/jeongsu816/matrix-bot-sdk.git"
|
|
8
|
+
},
|
|
9
|
+
"author": "turt2live",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/jeongsu816/matrix-bot-sdk/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/jeongsu816/matrix-bot-sdk#readme",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"prepublishOnly": "npm run build",
|
|
17
|
+
"docs": "jsdoc -c jsdoc.json -P package.json -u docs/tutorials",
|
|
18
|
+
"build": "tsc --listEmittedFiles -p tsconfig-release.json",
|
|
19
|
+
"lint": "eslint \"{src,test,examples}/**/*.ts\"",
|
|
20
|
+
"lint:fix": "eslint \"{src,test,examples}/**/*.ts\" --fix",
|
|
21
|
+
"test": "jest",
|
|
22
|
+
"build:examples": "tsc -p tsconfig-examples.json",
|
|
23
|
+
"example:bot": "npm run build:examples && node lib/examples/bot.js",
|
|
24
|
+
"example:appservice": "npm run build:examples && node lib/examples/appservice.js",
|
|
25
|
+
"example:login_register": "npm run build:examples && node lib/examples/login_register.js",
|
|
26
|
+
"example:encryption_bot": "npm run build:examples && node lib/examples/encryption_bot.js",
|
|
27
|
+
"example:encryption_appservice": "npm run build:examples && node lib/examples/encryption_appservice.js"
|
|
28
|
+
},
|
|
29
|
+
"main": "./lib/index.js",
|
|
30
|
+
"typings": "./lib/index.d.ts",
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=22.12.0"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"matrix",
|
|
36
|
+
"bot",
|
|
37
|
+
"sdk",
|
|
38
|
+
"js",
|
|
39
|
+
"ts",
|
|
40
|
+
"node",
|
|
41
|
+
"helpers",
|
|
42
|
+
"snippets",
|
|
43
|
+
"chat",
|
|
44
|
+
"modules",
|
|
45
|
+
"bot-sdk",
|
|
46
|
+
"appservices"
|
|
47
|
+
],
|
|
48
|
+
"files": [
|
|
49
|
+
"src/*",
|
|
50
|
+
"lib/*",
|
|
51
|
+
"scripts/*",
|
|
52
|
+
"tsconfig.json"
|
|
53
|
+
],
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@matrix-org/matrix-sdk-crypto-nodejs": "0.6.1",
|
|
59
|
+
"@types/express": "^4.17.20",
|
|
60
|
+
"another-json": "^0.2.0",
|
|
61
|
+
"async-lock": "^1.4.0",
|
|
62
|
+
"chalk": "4",
|
|
63
|
+
"express": "^4.18.2",
|
|
64
|
+
"glob-to-regexp": "^0.4.1",
|
|
65
|
+
"hash.js": "^1.1.7",
|
|
66
|
+
"html-to-text": "^9.0.5",
|
|
67
|
+
"htmlencode": "^0.0.4",
|
|
68
|
+
"lowdb": "1",
|
|
69
|
+
"lru-cache": "^10.0.1",
|
|
70
|
+
"mkdirp": "^3.0.1",
|
|
71
|
+
"morgan": "^1.10.0",
|
|
72
|
+
"postgres": "^3.4.1",
|
|
73
|
+
"request": "npm:@cypress/request@^4.0.1",
|
|
74
|
+
"sanitize-html": "^2.18.1"
|
|
75
|
+
},
|
|
76
|
+
"devDependencies": {
|
|
77
|
+
"@babel/core": "^7.28.6",
|
|
78
|
+
"@babel/eslint-parser": "^7.28.6",
|
|
79
|
+
"@babel/eslint-plugin": "^7.27.1",
|
|
80
|
+
"@eslint/eslintrc": "^3.3.3",
|
|
81
|
+
"@eslint/js": "^9.39.2",
|
|
82
|
+
"@stylistic/eslint-plugin": "^5.7.0",
|
|
83
|
+
"@testcontainers/postgresql": "^10.2.2",
|
|
84
|
+
"@types/async-lock": "^1.4.1",
|
|
85
|
+
"@types/jest": "^30.0.0",
|
|
86
|
+
"@types/lowdb": "^1.0.14",
|
|
87
|
+
"@types/mocha": "^10.0.3",
|
|
88
|
+
"@types/node": "22",
|
|
89
|
+
"@types/request-promise": "^4.1.51",
|
|
90
|
+
"@types/sanitize-html": "^2.9.3",
|
|
91
|
+
"@types/simple-mock": "^0.8.4",
|
|
92
|
+
"@typescript-eslint/eslint-plugin": "^8.53.0",
|
|
93
|
+
"@typescript-eslint/parser": "^8.53.0",
|
|
94
|
+
"better-docs": "^2.7.3",
|
|
95
|
+
"eslint": "^9.39.2",
|
|
96
|
+
"eslint-config-google": "^0.14.0",
|
|
97
|
+
"eslint-config-prettier": "^10.1.8",
|
|
98
|
+
"eslint-plugin-deprecate": "^0.8.7",
|
|
99
|
+
"eslint-plugin-import": "^2.32.0",
|
|
100
|
+
"eslint-plugin-matrix-org": "^3.0.0",
|
|
101
|
+
"eslint-plugin-unicorn": "^62.0.0",
|
|
102
|
+
"get-port": "5",
|
|
103
|
+
"globals": "^17.0.0",
|
|
104
|
+
"jest": "^30.2.0",
|
|
105
|
+
"jsdoc": "^4.0.5",
|
|
106
|
+
"matrix-mock-request": "^2.6.0",
|
|
107
|
+
"request-promise": "^4.2.6",
|
|
108
|
+
"simple-mock": "^0.8.0",
|
|
109
|
+
"taffydb": "^2.7.3",
|
|
110
|
+
"testcontainers": "^10.2.2",
|
|
111
|
+
"tmp": "^0.2.1",
|
|
112
|
+
"ts-jest": "^29.4.6",
|
|
113
|
+
"typescript": "^5.9.3"
|
|
114
|
+
},
|
|
115
|
+
"jest": {
|
|
116
|
+
"preset": "ts-jest",
|
|
117
|
+
"testEnvironment": "node",
|
|
118
|
+
"testMatch": [
|
|
119
|
+
"<rootDir>/test/**/*Test.ts"
|
|
120
|
+
],
|
|
121
|
+
"transform": {
|
|
122
|
+
"^.+\\.ts$": "ts-jest",
|
|
123
|
+
"^.+\\.js$": [
|
|
124
|
+
"ts-jest",
|
|
125
|
+
{
|
|
126
|
+
"tsconfig": {
|
|
127
|
+
"allowJs": true,
|
|
128
|
+
"module": "commonjs"
|
|
129
|
+
},
|
|
130
|
+
"isolatedModules": true
|
|
131
|
+
}
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
"transformIgnorePatterns": [
|
|
135
|
+
"/node_modules/(?!(htmlparser2|domhandler|domutils|dom-serializer|domelementtype|entities)/)[^/]+/(?!.*node_modules)"
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
}
|
package/src/AdminApis.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { MatrixClient } from "./MatrixClient";
|
|
2
|
+
import { SynapseAdminApis } from "./SynapseAdminApis";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Whois information about a user.
|
|
6
|
+
* See https://matrix.org/docs/spec/client_server/r0.5.0#get-matrix-client-r0-admin-whois-userid for more information.
|
|
7
|
+
* @category Admin APIs
|
|
8
|
+
*/
|
|
9
|
+
export interface WhoisInfo {
|
|
10
|
+
user_id: string;
|
|
11
|
+
devices: {
|
|
12
|
+
[device_id: string]: {
|
|
13
|
+
sessions: [{
|
|
14
|
+
connections: WhoisConnectionInfo[];
|
|
15
|
+
}];
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface WhoisConnectionInfo {
|
|
21
|
+
/**
|
|
22
|
+
* Most recently seen IP address of the session.
|
|
23
|
+
*/
|
|
24
|
+
ip: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Unix timestamp that the session was last active.
|
|
28
|
+
*/
|
|
29
|
+
last_seen: number;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* User agent string last seen in the session.
|
|
33
|
+
*/
|
|
34
|
+
user_agent: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Access to various administrative APIs.
|
|
39
|
+
* @category Admin APIs
|
|
40
|
+
*/
|
|
41
|
+
export class AdminApis {
|
|
42
|
+
constructor(private client: MatrixClient) {
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Gets access to the Synapse administrative APIs object.
|
|
47
|
+
*/
|
|
48
|
+
public get synapse(): SynapseAdminApis {
|
|
49
|
+
return new SynapseAdminApis(this.client);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Gets information about a particular user.
|
|
54
|
+
* @param {string} userId the user ID to lookup
|
|
55
|
+
* @returns {Promise<WhoisInfo>} resolves to the whois information
|
|
56
|
+
*/
|
|
57
|
+
public whoisUser(userId: string): Promise<WhoisInfo> {
|
|
58
|
+
return this.client.doRequest("GET", "/_matrix/client/v3/admin/whois/" + encodeURIComponent(userId));
|
|
59
|
+
}
|
|
60
|
+
}
|
package/src/DMs.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { MatrixClient } from "./MatrixClient";
|
|
2
|
+
import { EncryptionAlgorithm } from "./models/Crypto";
|
|
3
|
+
import { LogService } from "./logging/LogService";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Handles DM (direct messages) matching between users. Note that bots which
|
|
7
|
+
* existed prior to this might not have DM rooms populated correctly - the
|
|
8
|
+
* account data can be populated externally and that will be reflected here.
|
|
9
|
+
*
|
|
10
|
+
* Note that DM status is persisted across all access tokens for a user and
|
|
11
|
+
* is not persisted with the regular stores. The DM map is instead tracked
|
|
12
|
+
* on the homeserver as account data and thus survives the bot's own storage
|
|
13
|
+
* being wiped.
|
|
14
|
+
* @category Utilities
|
|
15
|
+
*/
|
|
16
|
+
export class DMs {
|
|
17
|
+
private cached = new Map<string, string[]>();
|
|
18
|
+
private ready: Promise<void>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new DM map.
|
|
22
|
+
* @param {MatrixClient} client The client the DM map is for.
|
|
23
|
+
*/
|
|
24
|
+
public constructor(private client: MatrixClient) {
|
|
25
|
+
this.client.on("account_data", (ev) => {
|
|
26
|
+
if (ev['type'] !== 'm.direct') return;
|
|
27
|
+
|
|
28
|
+
// noinspection JSIgnoredPromiseFromCall
|
|
29
|
+
this.updateFromAccountData();
|
|
30
|
+
});
|
|
31
|
+
this.client.on("room.invite", (rid, ev) => this.handleInvite(rid, ev));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private async updateFromAccountData() {
|
|
35
|
+
// Don't trust the sync update
|
|
36
|
+
let map = {};
|
|
37
|
+
try {
|
|
38
|
+
map = await this.client.getAccountData("m.direct");
|
|
39
|
+
} catch (e) {
|
|
40
|
+
if (e.body?.errcode !== "M_NOT_FOUND" && e.statusCode !== 404) {
|
|
41
|
+
LogService.warn("DMs", "Error getting m.direct account data: ", e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this.cached = new Map<string, string[]>();
|
|
46
|
+
|
|
47
|
+
for (const [userId, roomIds] of Object.entries(map)) {
|
|
48
|
+
this.cached.set(userId, roomIds as string[]);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private async handleInvite(roomId: string, ev: any) {
|
|
53
|
+
if (ev['content']?.['is_direct'] === true) {
|
|
54
|
+
const userId = ev['sender'];
|
|
55
|
+
if (!this.cached.has(userId)) this.cached.set(userId, []);
|
|
56
|
+
this.cached.set(userId, [roomId, ...this.cached.get(userId)]);
|
|
57
|
+
await this.persistCache();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private async persistCache() {
|
|
62
|
+
const obj: Record<string, string[]> = {};
|
|
63
|
+
for (const [uid, rids] of this.cached.entries()) {
|
|
64
|
+
obj[uid] = rids;
|
|
65
|
+
}
|
|
66
|
+
await this.client.setAccountData("m.direct", obj);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private async fixDms(userId: string) {
|
|
70
|
+
const currentRooms = this.cached.get(userId);
|
|
71
|
+
if (!currentRooms) return;
|
|
72
|
+
|
|
73
|
+
const toKeep: string[] = [];
|
|
74
|
+
for (const roomId of currentRooms) {
|
|
75
|
+
try {
|
|
76
|
+
const members = await this.client.getAllRoomMembers(roomId);
|
|
77
|
+
const joined = members.filter(m => m.effectiveMembership === "join" || m.effectiveMembership === "invite");
|
|
78
|
+
if (joined.some(m => m.membershipFor === userId)) {
|
|
79
|
+
toKeep.push(roomId);
|
|
80
|
+
}
|
|
81
|
+
} catch (e) {
|
|
82
|
+
LogService.warn("DMs", `Unable to check ${roomId} for room members - assuming invalid DM`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (toKeep.length === currentRooms.length) return; // no change
|
|
87
|
+
|
|
88
|
+
if (toKeep.length > 0) {
|
|
89
|
+
this.cached.set(userId, toKeep);
|
|
90
|
+
} else {
|
|
91
|
+
this.cached.delete(userId);
|
|
92
|
+
}
|
|
93
|
+
await this.persistCache();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Forces an update of the DM cache.
|
|
98
|
+
* @returns {Promise<void>} Resolves when complete.
|
|
99
|
+
*/
|
|
100
|
+
public async update(): Promise<void> {
|
|
101
|
+
await this.ready; // finish the existing call if present
|
|
102
|
+
this.ready = this.updateFromAccountData();
|
|
103
|
+
return this.ready;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Gets or creates a DM with a given user. If a DM needs to be created, it will
|
|
108
|
+
* be created as an encrypted DM (if both the MatrixClient and target user support
|
|
109
|
+
* crypto). Otherwise, the createFn can be used to override the call. Note that
|
|
110
|
+
* when creating a DM room the room should have `is_direct: true` set.
|
|
111
|
+
* @param {string} userId The user ID to get/create a DM for.
|
|
112
|
+
* @param {Function} createFn Optional function to use to create the room. Resolves
|
|
113
|
+
* to the created room ID.
|
|
114
|
+
* @returns {Promise<string>} Resolves to the DM room ID.
|
|
115
|
+
*/
|
|
116
|
+
public async getOrCreateDm(userId: string, createFn?: (targetUserId: string) => Promise<string>): Promise<string> {
|
|
117
|
+
await this.ready;
|
|
118
|
+
await this.fixDms(userId);
|
|
119
|
+
const rooms = this.cached.get(userId);
|
|
120
|
+
if (rooms?.length) return rooms[0];
|
|
121
|
+
|
|
122
|
+
let roomId: string;
|
|
123
|
+
if (createFn) {
|
|
124
|
+
roomId = await createFn(userId);
|
|
125
|
+
} else {
|
|
126
|
+
let hasKeys = false;
|
|
127
|
+
if (!!this.client.crypto) {
|
|
128
|
+
const keys = await this.client.getUserDevices([userId]);
|
|
129
|
+
const userKeys = keys?.device_keys?.[userId] ?? {};
|
|
130
|
+
hasKeys = Object.values(userKeys).filter(device => Object.values(device).length > 0).length > 0;
|
|
131
|
+
}
|
|
132
|
+
roomId = await this.client.createRoom({
|
|
133
|
+
invite: [userId],
|
|
134
|
+
is_direct: true,
|
|
135
|
+
preset: "trusted_private_chat",
|
|
136
|
+
initial_state: hasKeys ? [{
|
|
137
|
+
type: "m.room.encryption",
|
|
138
|
+
state_key: "",
|
|
139
|
+
content: { algorithm: EncryptionAlgorithm.MegolmV1AesSha2 },
|
|
140
|
+
}] : [],
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (!this.cached.has(userId)) this.cached.set(userId, []);
|
|
145
|
+
this.cached.set(userId, [roomId, ...this.cached.get(userId)]);
|
|
146
|
+
await this.persistCache();
|
|
147
|
+
|
|
148
|
+
return roomId;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Determines if a given room is a DM according to the cache.
|
|
153
|
+
* @param {string} roomId The room ID.
|
|
154
|
+
* @returns {boolean} True if the room ID is a cached DM room ID.
|
|
155
|
+
*/
|
|
156
|
+
public isDm(roomId: string): boolean {
|
|
157
|
+
for (const val of this.cached.values()) {
|
|
158
|
+
if (val.includes(roomId)) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
}
|
package/src/IFilter.ts
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { MatrixClient } from "./MatrixClient";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Functions for interacting with Matrix prior to having an access token. Intended
|
|
5
|
+
* to be used for logging in/registering to get a MatrixClient instance.
|
|
6
|
+
*
|
|
7
|
+
* By design, this limits the options used to create the MatrixClient. To specify
|
|
8
|
+
* custom elements to the client, get the access token from the returned client
|
|
9
|
+
* and create a new MatrixClient instance. Due to the nature of Matrix, it is
|
|
10
|
+
* also recommended to use the homeserverUrl from the generated MatrixClient as
|
|
11
|
+
* it may be different from that given to the MatrixAuth class.
|
|
12
|
+
*/
|
|
13
|
+
export class MatrixAuth {
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new MatrixAuth class for creating a MatrixClient
|
|
16
|
+
* @param {string} homeserverUrl The homeserver URL to authenticate against.
|
|
17
|
+
*/
|
|
18
|
+
public constructor(private homeserverUrl: string) {
|
|
19
|
+
// nothing to do
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generate a client with no access token so we can reuse the doRequest
|
|
24
|
+
* logic already written.
|
|
25
|
+
*/
|
|
26
|
+
private createTemplateClient(): MatrixClient {
|
|
27
|
+
return new MatrixClient(this.homeserverUrl, "");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Performs simple registration using a password for the account. This will
|
|
32
|
+
* assume the server supports the m.login.password flow for registration, and
|
|
33
|
+
* will attempt to complete only that stage. The caller is expected to determine
|
|
34
|
+
* if the homeserver supports registration prior to invocation.
|
|
35
|
+
* @param {string} localpart The localpart (username) to register
|
|
36
|
+
* @param {string} password The password to register with
|
|
37
|
+
* @param {string} deviceName The name of the newly created device. Optional.
|
|
38
|
+
* @returns {Promise<MatrixClient>} Resolves to a logged-in MatrixClient
|
|
39
|
+
*/
|
|
40
|
+
public async passwordRegister(localpart: string, password: string, deviceName?: string): Promise<MatrixClient> {
|
|
41
|
+
// First try and complete the stage without UIA in hopes the server is kind to us:
|
|
42
|
+
const body = {
|
|
43
|
+
username: localpart,
|
|
44
|
+
password: password,
|
|
45
|
+
initial_device_display_name: deviceName,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
let response;
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/v3/register", null, body);
|
|
52
|
+
} catch (e) {
|
|
53
|
+
if (e.statusCode === 401) {
|
|
54
|
+
if (typeof (e.body) === "string") e.body = JSON.parse(e.body);
|
|
55
|
+
if (!e.body) throw new Error(JSON.stringify(Object.keys(e)));
|
|
56
|
+
|
|
57
|
+
// 401 means we need to do UIA, so try and complete a stage
|
|
58
|
+
const sessionId = e.body['session'];
|
|
59
|
+
const expectedFlow = ["m.login.dummy"];
|
|
60
|
+
|
|
61
|
+
let hasFlow = false;
|
|
62
|
+
for (const flow of e.body['flows']) {
|
|
63
|
+
const stages = flow['stages'];
|
|
64
|
+
if (stages.length !== expectedFlow.length) continue;
|
|
65
|
+
|
|
66
|
+
let stagesMatch = true;
|
|
67
|
+
for (let i = 0; i < stages.length; i++) {
|
|
68
|
+
if (stages[i] !== expectedFlow[i]) {
|
|
69
|
+
stagesMatch = false;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (stagesMatch) {
|
|
75
|
+
hasFlow = true;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!hasFlow) throw new Error("Failed to find appropriate login flow in User-Interactive Authentication");
|
|
81
|
+
|
|
82
|
+
body['auth'] = {
|
|
83
|
+
type: expectedFlow[0], // HACK: We assume we only have one entry here
|
|
84
|
+
session: sessionId,
|
|
85
|
+
};
|
|
86
|
+
response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/v3/register", null, body);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (!response) throw new Error("Failed to register");
|
|
91
|
+
|
|
92
|
+
const accessToken = response['access_token'];
|
|
93
|
+
if (!accessToken) throw new Error("No access token returned");
|
|
94
|
+
|
|
95
|
+
return new MatrixClient(this.homeserverUrl, accessToken);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Performs simple password login with the homeserver. The caller is
|
|
100
|
+
* expected to confirm if the homeserver supports this login flow prior
|
|
101
|
+
* to invocation.
|
|
102
|
+
* @param {string} username The username (localpart or user ID) to log in with
|
|
103
|
+
* @param {string} password The password for the account
|
|
104
|
+
* @param {string} deviceName The name of the newly created device. Optional.
|
|
105
|
+
* @returns {Promise<MatrixClient>} Resolves to a logged-in MatrixClient
|
|
106
|
+
*/
|
|
107
|
+
public async passwordLogin(username: string, password: string, deviceName?: string): Promise<MatrixClient> {
|
|
108
|
+
const body = {
|
|
109
|
+
type: "m.login.password",
|
|
110
|
+
identifier: {
|
|
111
|
+
type: "m.id.user",
|
|
112
|
+
user: username,
|
|
113
|
+
},
|
|
114
|
+
password: password,
|
|
115
|
+
initial_device_display_name: deviceName,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const response = await this.createTemplateClient().doRequest("POST", "/_matrix/client/v3/login", null, body);
|
|
119
|
+
const accessToken = response["access_token"];
|
|
120
|
+
if (!accessToken) throw new Error("Expected access token in response - got nothing");
|
|
121
|
+
|
|
122
|
+
let homeserverUrl = this.homeserverUrl;
|
|
123
|
+
if (response['well_known'] && response['well_known']['m.homeserver'] && response['well_known']['m.homeserver']['base_url']) {
|
|
124
|
+
homeserverUrl = response['well_known']['m.homeserver']['base_url'];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return new MatrixClient(homeserverUrl, accessToken);
|
|
128
|
+
}
|
|
129
|
+
}
|