@openclaw/matrix 2026.3.12 → 2026.5.9-beta.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/dist/account-config-D2W-V1eQ.js +96 -0
- package/dist/account-selection-BWwIruri.js +158 -0
- package/dist/accounts-Bm90Rzvp.js +130 -0
- package/dist/active-client-uhlxdhEy.js +20 -0
- package/dist/allowlist-sTzpCn5d.js +68 -0
- package/dist/api.js +12 -0
- package/dist/approval-handler.runtime-DWTQfd4m.js +370 -0
- package/dist/approval-ids-DoC2z7tR.js +7 -0
- package/dist/approval-reaction-auth-DbcA1gGd.js +27 -0
- package/dist/approval-reactions-o2_tuH8D.js +162 -0
- package/dist/async-lock-uQfhfQIY.js +19 -0
- package/dist/auth-presence.js +26 -0
- package/dist/backup-health-Cabu_WQC.js +60 -0
- package/dist/channel-DJNir3Rb.js +1116 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel.runtime-BQu0hTih.js +246 -0
- package/dist/cli-BmfTmg7x.js +1340 -0
- package/dist/cli-metadata-B-PCEzrA.js +22 -0
- package/dist/cli-metadata.js +2 -0
- package/dist/client-DkcXnm0X.js +25 -0
- package/dist/client-_hckQNGW.js +31 -0
- package/dist/client-bootstrap-Rb8oHvhH.js +114 -0
- package/dist/config--5-S2Akv.js +452 -0
- package/dist/config-paths-nsVaysCu.js +19 -0
- package/dist/config-schema-nPLpEgHl.js +200 -0
- package/dist/config-secret-input.runtime-DiKFehsE.js +2 -0
- package/dist/config-update-wZX-HLMn.js +143 -0
- package/dist/contract-api.js +9 -0
- package/dist/create-client-DCnqDaqd.js +64 -0
- package/dist/credentials-DV6fWXhC.js +56 -0
- package/dist/credentials-read-cmHgousK.js +112 -0
- package/dist/credentials-write.runtime-zniTq-Gr.js +17 -0
- package/dist/crypto-node.runtime-pihzdpY7.js +12 -0
- package/dist/crypto-runtime-ZI0zAtn3.js +1214 -0
- package/dist/deps-C6WqKY7m.js +235 -0
- package/dist/device-health-UVYpbA_W.js +16 -0
- package/dist/direct-management-DMMMgtTB.js +249 -0
- package/dist/direct-room-XkutHjES.js +76 -0
- package/dist/directory-live-DmOtMhyr.js +150 -0
- package/dist/doctor-C4__7c-U.js +153 -0
- package/dist/doctor-contract-D4-64QuJ.js +246 -0
- package/dist/doctor-contract-api.js +2 -0
- package/dist/draft-stream-BE2QevQQ.js +144 -0
- package/dist/encryption-guidance-BPi3A_m3.js +15 -0
- package/dist/env-auth-BJqGI8M6.js +63 -0
- package/dist/env-vars-C7uQCTKn.js +63 -0
- package/dist/errors-CTcpEDq-.js +17 -0
- package/dist/exec-approval-resolver-Bza9Dhlm.js +15 -0
- package/dist/exec-approvals-Crnh543m.js +196 -0
- package/dist/helper-api.js +4 -0
- package/dist/http-client-C7AeVJay.js +319 -0
- package/dist/index.js +46 -0
- package/dist/legacy-crypto-inspector-poDWldgy.js +41 -0
- package/dist/legacy-crypto-restore-Biw-w2ng.js +85 -0
- package/dist/logger-CnZRVrux.js +78 -0
- package/dist/logging-DZHSPP5N.js +99 -0
- package/dist/matrix-migration.runtime-WY6ffcrf.js +525 -0
- package/dist/media-text-DU6nWZuj.js +146 -0
- package/dist/messages-BpihMh82.js +140 -0
- package/dist/migration-snapshot-backup-DaCHTp8C.js +69 -0
- package/dist/migration-snapshot.runtime-CKHE3xF9.js +2 -0
- package/dist/monitor-C_81r_Ck.js +4125 -0
- package/dist/plugin-entry.handlers.runtime.js +51 -0
- package/dist/probe.runtime-BvAzYAIe.js +3 -0
- package/dist/profile-BlHu0wDX.js +111 -0
- package/dist/profile-update-DjeBNgIV.js +69 -0
- package/dist/reaction-common-ejrL19w-.js +71 -0
- package/dist/reaction-events-CiARZfjk.js +121 -0
- package/dist/record-shared-CHWJCTWf.js +2 -0
- package/dist/recovery-key-store-BTJ6jz5v.js +294 -0
- package/dist/resolve-targets-YtJnw1Tb.js +140 -0
- package/dist/resolver.runtime-D9piiGEl.js +5 -0
- package/dist/rolldown-runtime-DUslC3ob.js +14 -0
- package/dist/route-D6rg-iXN.js +161 -0
- package/dist/runtime-C6X4h_SJ.js +6 -0
- package/dist/runtime-Dog86njy.js +8 -0
- package/dist/runtime-api-BXWBFIqm.js +25 -0
- package/dist/runtime-api.js +25 -0
- package/dist/runtime-heavy-api.js +3 -0
- package/dist/runtime-setter-api.js +2 -0
- package/dist/sdk-B2vZA27-.js +1416 -0
- package/dist/secret-contract-DcrJWCQI.js +120 -0
- package/dist/secret-contract-api.js +2 -0
- package/dist/send-Bo0DU1ca.js +1200 -0
- package/dist/session-store-metadata-DI5SCofx.js +77 -0
- package/dist/setup-bootstrap-ImenBsMt.js +62 -0
- package/dist/setup-core-CfZy05oW.js +116 -0
- package/dist/setup-dm-policy-2-r1FrQh.js +194 -0
- package/dist/setup-entry.js +19 -0
- package/dist/setup-plugin-api.js +44 -0
- package/dist/setup-surface-CqT_o61M.js +540 -0
- package/dist/shared-CpMoYKm1.js +195 -0
- package/dist/startup-abort-56edvmbM.js +32 -0
- package/dist/startup-verification-Demyp0bP.js +132 -0
- package/dist/storage-paths-BJLdnCjV.js +52 -0
- package/dist/storage-tC3ujLiW.js +281 -0
- package/dist/subagent-hooks-DQbyqq9V.js +149 -0
- package/dist/subagent-hooks-api.js +23 -0
- package/dist/sync-state-C_beeevA.js +12 -0
- package/dist/target-ids-80nQ2gql.js +77 -0
- package/dist/test-api.js +4 -0
- package/dist/thread-binding-api-Cq_E-E1K.js +17 -0
- package/dist/thread-binding-api.js +2 -0
- package/dist/thread-bindings-B9mesxXk.js +352 -0
- package/dist/thread-bindings-runtime.js +2 -0
- package/dist/thread-bindings-shared-DK-d-oYX.js +97 -0
- package/dist/timeout-abort-signal-CtaIaP1v.js +2 -0
- package/dist/tool-actions.runtime-BIH49vRr.js +532 -0
- package/dist/url-validation-DiK9j7jz.js +36 -0
- package/dist/verification-CZ2rDeHL.js +345 -0
- package/openclaw.plugin.json +788 -1
- package/package.json +82 -16
- package/CHANGELOG.md +0 -98
- package/index.ts +0 -22
- package/src/actions.ts +0 -195
- package/src/channel.directory.test.ts +0 -154
- package/src/channel.ts +0 -461
- package/src/config-schema.test.ts +0 -26
- package/src/config-schema.ts +0 -62
- package/src/directory-live.test.ts +0 -85
- package/src/directory-live.ts +0 -209
- package/src/group-mentions.ts +0 -52
- package/src/matrix/accounts.test.ts +0 -131
- package/src/matrix/accounts.ts +0 -114
- package/src/matrix/actions/client.ts +0 -47
- package/src/matrix/actions/limits.test.ts +0 -15
- package/src/matrix/actions/limits.ts +0 -6
- package/src/matrix/actions/messages.ts +0 -126
- package/src/matrix/actions/pins.test.ts +0 -74
- package/src/matrix/actions/pins.ts +0 -84
- package/src/matrix/actions/reactions.test.ts +0 -109
- package/src/matrix/actions/reactions.ts +0 -102
- package/src/matrix/actions/room.ts +0 -85
- package/src/matrix/actions/summary.ts +0 -75
- package/src/matrix/actions/types.ts +0 -85
- package/src/matrix/actions.ts +0 -15
- package/src/matrix/active-client.ts +0 -32
- package/src/matrix/client/config.ts +0 -245
- package/src/matrix/client/create-client.ts +0 -125
- package/src/matrix/client/logging.ts +0 -46
- package/src/matrix/client/runtime.ts +0 -4
- package/src/matrix/client/shared.test.ts +0 -85
- package/src/matrix/client/shared.ts +0 -210
- package/src/matrix/client/startup.test.ts +0 -49
- package/src/matrix/client/startup.ts +0 -29
- package/src/matrix/client/storage.ts +0 -131
- package/src/matrix/client/types.ts +0 -34
- package/src/matrix/client-bootstrap.ts +0 -47
- package/src/matrix/client.test.ts +0 -56
- package/src/matrix/client.ts +0 -14
- package/src/matrix/credentials.ts +0 -125
- package/src/matrix/deps.test.ts +0 -74
- package/src/matrix/deps.ts +0 -126
- package/src/matrix/format.test.ts +0 -33
- package/src/matrix/format.ts +0 -22
- package/src/matrix/index.ts +0 -11
- package/src/matrix/monitor/access-policy.ts +0 -126
- package/src/matrix/monitor/allowlist.test.ts +0 -45
- package/src/matrix/monitor/allowlist.ts +0 -100
- package/src/matrix/monitor/auto-join.ts +0 -72
- package/src/matrix/monitor/direct.test.ts +0 -400
- package/src/matrix/monitor/direct.ts +0 -152
- package/src/matrix/monitor/events.test.ts +0 -172
- package/src/matrix/monitor/events.ts +0 -168
- package/src/matrix/monitor/handler.body-for-agent.test.ts +0 -196
- package/src/matrix/monitor/handler.ts +0 -767
- package/src/matrix/monitor/inbound-body.test.ts +0 -73
- package/src/matrix/monitor/inbound-body.ts +0 -28
- package/src/matrix/monitor/index.test.ts +0 -18
- package/src/matrix/monitor/index.ts +0 -414
- package/src/matrix/monitor/location.ts +0 -100
- package/src/matrix/monitor/media.test.ts +0 -86
- package/src/matrix/monitor/media.ts +0 -118
- package/src/matrix/monitor/mentions.test.ts +0 -154
- package/src/matrix/monitor/mentions.ts +0 -62
- package/src/matrix/monitor/replies.test.ts +0 -184
- package/src/matrix/monitor/replies.ts +0 -124
- package/src/matrix/monitor/room-info.ts +0 -55
- package/src/matrix/monitor/rooms.test.ts +0 -124
- package/src/matrix/monitor/rooms.ts +0 -47
- package/src/matrix/monitor/threads.ts +0 -68
- package/src/matrix/monitor/types.ts +0 -39
- package/src/matrix/poll-types.test.ts +0 -21
- package/src/matrix/poll-types.ts +0 -167
- package/src/matrix/probe.ts +0 -69
- package/src/matrix/sdk-runtime.ts +0 -18
- package/src/matrix/send/client.ts +0 -99
- package/src/matrix/send/formatting.ts +0 -93
- package/src/matrix/send/media.ts +0 -230
- package/src/matrix/send/targets.test.ts +0 -98
- package/src/matrix/send/targets.ts +0 -150
- package/src/matrix/send/types.ts +0 -110
- package/src/matrix/send-queue.test.ts +0 -154
- package/src/matrix/send-queue.ts +0 -28
- package/src/matrix/send.test.ts +0 -326
- package/src/matrix/send.ts +0 -267
- package/src/onboarding.ts +0 -462
- package/src/outbound.test.ts +0 -159
- package/src/outbound.ts +0 -58
- package/src/resolve-targets.test.ts +0 -67
- package/src/resolve-targets.ts +0 -125
- package/src/runtime.ts +0 -6
- package/src/secret-input.ts +0 -13
- package/src/tool-actions.ts +0 -164
- package/src/types.ts +0 -118
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
import type { MatrixClient } from "@vector-im/matrix-bot-sdk";
|
|
2
|
-
import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
3
|
-
import type { CoreConfig } from "../../types.js";
|
|
4
|
-
import { getMatrixLogService } from "../sdk-runtime.js";
|
|
5
|
-
import { resolveMatrixAuth } from "./config.js";
|
|
6
|
-
import { createMatrixClient } from "./create-client.js";
|
|
7
|
-
import { startMatrixClientWithGrace } from "./startup.js";
|
|
8
|
-
import { DEFAULT_ACCOUNT_KEY } from "./storage.js";
|
|
9
|
-
import type { MatrixAuth } from "./types.js";
|
|
10
|
-
|
|
11
|
-
type SharedMatrixClientState = {
|
|
12
|
-
client: MatrixClient;
|
|
13
|
-
key: string;
|
|
14
|
-
started: boolean;
|
|
15
|
-
cryptoReady: boolean;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
// Support multiple accounts with separate clients
|
|
19
|
-
const sharedClientStates = new Map<string, SharedMatrixClientState>();
|
|
20
|
-
const sharedClientPromises = new Map<string, Promise<SharedMatrixClientState>>();
|
|
21
|
-
const sharedClientStartPromises = new Map<string, Promise<void>>();
|
|
22
|
-
|
|
23
|
-
function buildSharedClientKey(auth: MatrixAuth, accountId?: string | null): string {
|
|
24
|
-
const normalizedAccountId = normalizeAccountId(accountId);
|
|
25
|
-
return [
|
|
26
|
-
auth.homeserver,
|
|
27
|
-
auth.userId,
|
|
28
|
-
auth.accessToken,
|
|
29
|
-
auth.encryption ? "e2ee" : "plain",
|
|
30
|
-
normalizedAccountId || DEFAULT_ACCOUNT_KEY,
|
|
31
|
-
].join("|");
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async function createSharedMatrixClient(params: {
|
|
35
|
-
auth: MatrixAuth;
|
|
36
|
-
timeoutMs?: number;
|
|
37
|
-
accountId?: string | null;
|
|
38
|
-
}): Promise<SharedMatrixClientState> {
|
|
39
|
-
const client = await createMatrixClient({
|
|
40
|
-
homeserver: params.auth.homeserver,
|
|
41
|
-
userId: params.auth.userId,
|
|
42
|
-
accessToken: params.auth.accessToken,
|
|
43
|
-
encryption: params.auth.encryption,
|
|
44
|
-
localTimeoutMs: params.timeoutMs,
|
|
45
|
-
accountId: params.accountId,
|
|
46
|
-
});
|
|
47
|
-
return {
|
|
48
|
-
client,
|
|
49
|
-
key: buildSharedClientKey(params.auth, params.accountId),
|
|
50
|
-
started: false,
|
|
51
|
-
cryptoReady: false,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async function ensureSharedClientStarted(params: {
|
|
56
|
-
state: SharedMatrixClientState;
|
|
57
|
-
timeoutMs?: number;
|
|
58
|
-
initialSyncLimit?: number;
|
|
59
|
-
encryption?: boolean;
|
|
60
|
-
}): Promise<void> {
|
|
61
|
-
if (params.state.started) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const key = params.state.key;
|
|
65
|
-
const existingStartPromise = sharedClientStartPromises.get(key);
|
|
66
|
-
if (existingStartPromise) {
|
|
67
|
-
await existingStartPromise;
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
const startPromise = (async () => {
|
|
71
|
-
const client = params.state.client;
|
|
72
|
-
|
|
73
|
-
// Initialize crypto if enabled
|
|
74
|
-
if (params.encryption && !params.state.cryptoReady) {
|
|
75
|
-
try {
|
|
76
|
-
const joinedRooms = await client.getJoinedRooms();
|
|
77
|
-
if (client.crypto) {
|
|
78
|
-
await (client.crypto as { prepare: (rooms?: string[]) => Promise<void> }).prepare(
|
|
79
|
-
joinedRooms,
|
|
80
|
-
);
|
|
81
|
-
params.state.cryptoReady = true;
|
|
82
|
-
}
|
|
83
|
-
} catch (err) {
|
|
84
|
-
const LogService = getMatrixLogService();
|
|
85
|
-
LogService.warn("MatrixClientLite", "Failed to prepare crypto:", err);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
await startMatrixClientWithGrace({
|
|
90
|
-
client,
|
|
91
|
-
onError: (err: unknown) => {
|
|
92
|
-
params.state.started = false;
|
|
93
|
-
const LogService = getMatrixLogService();
|
|
94
|
-
LogService.error("MatrixClientLite", "client.start() error:", err);
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
params.state.started = true;
|
|
98
|
-
})();
|
|
99
|
-
sharedClientStartPromises.set(key, startPromise);
|
|
100
|
-
try {
|
|
101
|
-
await startPromise;
|
|
102
|
-
} finally {
|
|
103
|
-
sharedClientStartPromises.delete(key);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export async function resolveSharedMatrixClient(
|
|
108
|
-
params: {
|
|
109
|
-
cfg?: CoreConfig;
|
|
110
|
-
env?: NodeJS.ProcessEnv;
|
|
111
|
-
timeoutMs?: number;
|
|
112
|
-
auth?: MatrixAuth;
|
|
113
|
-
startClient?: boolean;
|
|
114
|
-
accountId?: string | null;
|
|
115
|
-
} = {},
|
|
116
|
-
): Promise<MatrixClient> {
|
|
117
|
-
const accountId = normalizeAccountId(params.accountId);
|
|
118
|
-
const auth =
|
|
119
|
-
params.auth ?? (await resolveMatrixAuth({ cfg: params.cfg, env: params.env, accountId }));
|
|
120
|
-
const key = buildSharedClientKey(auth, accountId);
|
|
121
|
-
const shouldStart = params.startClient !== false;
|
|
122
|
-
|
|
123
|
-
// Check if we already have a client for this key
|
|
124
|
-
const existingState = sharedClientStates.get(key);
|
|
125
|
-
if (existingState) {
|
|
126
|
-
if (shouldStart) {
|
|
127
|
-
await ensureSharedClientStarted({
|
|
128
|
-
state: existingState,
|
|
129
|
-
timeoutMs: params.timeoutMs,
|
|
130
|
-
initialSyncLimit: auth.initialSyncLimit,
|
|
131
|
-
encryption: auth.encryption,
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
return existingState.client;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Check if there's a pending creation for this key
|
|
138
|
-
const existingPromise = sharedClientPromises.get(key);
|
|
139
|
-
if (existingPromise) {
|
|
140
|
-
const pending = await existingPromise;
|
|
141
|
-
if (shouldStart) {
|
|
142
|
-
await ensureSharedClientStarted({
|
|
143
|
-
state: pending,
|
|
144
|
-
timeoutMs: params.timeoutMs,
|
|
145
|
-
initialSyncLimit: auth.initialSyncLimit,
|
|
146
|
-
encryption: auth.encryption,
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
return pending.client;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Create a new client for this account
|
|
153
|
-
const createPromise = createSharedMatrixClient({
|
|
154
|
-
auth,
|
|
155
|
-
timeoutMs: params.timeoutMs,
|
|
156
|
-
accountId,
|
|
157
|
-
});
|
|
158
|
-
sharedClientPromises.set(key, createPromise);
|
|
159
|
-
try {
|
|
160
|
-
const created = await createPromise;
|
|
161
|
-
sharedClientStates.set(key, created);
|
|
162
|
-
if (shouldStart) {
|
|
163
|
-
await ensureSharedClientStarted({
|
|
164
|
-
state: created,
|
|
165
|
-
timeoutMs: params.timeoutMs,
|
|
166
|
-
initialSyncLimit: auth.initialSyncLimit,
|
|
167
|
-
encryption: auth.encryption,
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
return created.client;
|
|
171
|
-
} finally {
|
|
172
|
-
sharedClientPromises.delete(key);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export async function waitForMatrixSync(_params: {
|
|
177
|
-
client: MatrixClient;
|
|
178
|
-
timeoutMs?: number;
|
|
179
|
-
abortSignal?: AbortSignal;
|
|
180
|
-
}): Promise<void> {
|
|
181
|
-
// @vector-im/matrix-bot-sdk handles sync internally in start()
|
|
182
|
-
// This is kept for API compatibility but is essentially a no-op now
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export function stopSharedClient(key?: string): void {
|
|
186
|
-
if (key) {
|
|
187
|
-
// Stop a specific client
|
|
188
|
-
const state = sharedClientStates.get(key);
|
|
189
|
-
if (state) {
|
|
190
|
-
state.client.stop();
|
|
191
|
-
sharedClientStates.delete(key);
|
|
192
|
-
}
|
|
193
|
-
} else {
|
|
194
|
-
// Stop all clients (backward compatible behavior)
|
|
195
|
-
for (const state of sharedClientStates.values()) {
|
|
196
|
-
state.client.stop();
|
|
197
|
-
}
|
|
198
|
-
sharedClientStates.clear();
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Stop the shared client for a specific account.
|
|
204
|
-
* Use this instead of stopSharedClient() when shutting down a single account
|
|
205
|
-
* to avoid stopping all accounts.
|
|
206
|
-
*/
|
|
207
|
-
export function stopSharedClientForAccount(auth: MatrixAuth, accountId?: string | null): void {
|
|
208
|
-
const key = buildSharedClientKey(auth, normalizeAccountId(accountId));
|
|
209
|
-
stopSharedClient(key);
|
|
210
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { MATRIX_CLIENT_STARTUP_GRACE_MS, startMatrixClientWithGrace } from "./startup.js";
|
|
3
|
-
|
|
4
|
-
describe("startMatrixClientWithGrace", () => {
|
|
5
|
-
it("resolves after grace when start loop keeps running", async () => {
|
|
6
|
-
vi.useFakeTimers();
|
|
7
|
-
const client = {
|
|
8
|
-
start: vi.fn().mockReturnValue(new Promise<void>(() => {})),
|
|
9
|
-
};
|
|
10
|
-
const startPromise = startMatrixClientWithGrace({ client });
|
|
11
|
-
await vi.advanceTimersByTimeAsync(MATRIX_CLIENT_STARTUP_GRACE_MS);
|
|
12
|
-
await expect(startPromise).resolves.toBeUndefined();
|
|
13
|
-
vi.useRealTimers();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it("rejects when startup fails during grace", async () => {
|
|
17
|
-
vi.useFakeTimers();
|
|
18
|
-
const startError = new Error("invalid token");
|
|
19
|
-
const client = {
|
|
20
|
-
start: vi.fn().mockRejectedValue(startError),
|
|
21
|
-
};
|
|
22
|
-
const startPromise = startMatrixClientWithGrace({ client });
|
|
23
|
-
const startupExpectation = expect(startPromise).rejects.toBe(startError);
|
|
24
|
-
await vi.advanceTimersByTimeAsync(MATRIX_CLIENT_STARTUP_GRACE_MS);
|
|
25
|
-
await startupExpectation;
|
|
26
|
-
vi.useRealTimers();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it("calls onError for late failures after startup returns", async () => {
|
|
30
|
-
vi.useFakeTimers();
|
|
31
|
-
const lateError = new Error("late disconnect");
|
|
32
|
-
let rejectStart: ((err: unknown) => void) | undefined;
|
|
33
|
-
const startLoop = new Promise<void>((_resolve, reject) => {
|
|
34
|
-
rejectStart = reject;
|
|
35
|
-
});
|
|
36
|
-
const onError = vi.fn();
|
|
37
|
-
const client = {
|
|
38
|
-
start: vi.fn().mockReturnValue(startLoop),
|
|
39
|
-
};
|
|
40
|
-
const startPromise = startMatrixClientWithGrace({ client, onError });
|
|
41
|
-
await vi.advanceTimersByTimeAsync(MATRIX_CLIENT_STARTUP_GRACE_MS);
|
|
42
|
-
await expect(startPromise).resolves.toBeUndefined();
|
|
43
|
-
|
|
44
|
-
rejectStart?.(lateError);
|
|
45
|
-
await Promise.resolve();
|
|
46
|
-
expect(onError).toHaveBeenCalledWith(lateError);
|
|
47
|
-
vi.useRealTimers();
|
|
48
|
-
});
|
|
49
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { MatrixClient } from "@vector-im/matrix-bot-sdk";
|
|
2
|
-
|
|
3
|
-
export const MATRIX_CLIENT_STARTUP_GRACE_MS = 2000;
|
|
4
|
-
|
|
5
|
-
export async function startMatrixClientWithGrace(params: {
|
|
6
|
-
client: Pick<MatrixClient, "start">;
|
|
7
|
-
graceMs?: number;
|
|
8
|
-
onError?: (err: unknown) => void;
|
|
9
|
-
}): Promise<void> {
|
|
10
|
-
const graceMs = params.graceMs ?? MATRIX_CLIENT_STARTUP_GRACE_MS;
|
|
11
|
-
let startFailed = false;
|
|
12
|
-
let startError: unknown = undefined;
|
|
13
|
-
let startPromise: Promise<unknown>;
|
|
14
|
-
try {
|
|
15
|
-
startPromise = params.client.start();
|
|
16
|
-
} catch (err) {
|
|
17
|
-
params.onError?.(err);
|
|
18
|
-
throw err;
|
|
19
|
-
}
|
|
20
|
-
void startPromise.catch((err: unknown) => {
|
|
21
|
-
startFailed = true;
|
|
22
|
-
startError = err;
|
|
23
|
-
params.onError?.(err);
|
|
24
|
-
});
|
|
25
|
-
await new Promise((resolve) => setTimeout(resolve, graceMs));
|
|
26
|
-
if (startFailed) {
|
|
27
|
-
throw startError;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import { getMatrixRuntime } from "../../runtime.js";
|
|
6
|
-
import type { MatrixStoragePaths } from "./types.js";
|
|
7
|
-
|
|
8
|
-
export const DEFAULT_ACCOUNT_KEY = "default";
|
|
9
|
-
const STORAGE_META_FILENAME = "storage-meta.json";
|
|
10
|
-
|
|
11
|
-
function sanitizePathSegment(value: string): string {
|
|
12
|
-
const cleaned = value
|
|
13
|
-
.trim()
|
|
14
|
-
.toLowerCase()
|
|
15
|
-
.replace(/[^a-z0-9._-]+/g, "_")
|
|
16
|
-
.replace(/^_+|_+$/g, "");
|
|
17
|
-
return cleaned || "unknown";
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function resolveHomeserverKey(homeserver: string): string {
|
|
21
|
-
try {
|
|
22
|
-
const url = new URL(homeserver);
|
|
23
|
-
if (url.host) {
|
|
24
|
-
return sanitizePathSegment(url.host);
|
|
25
|
-
}
|
|
26
|
-
} catch {
|
|
27
|
-
// fall through
|
|
28
|
-
}
|
|
29
|
-
return sanitizePathSegment(homeserver);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function hashAccessToken(accessToken: string): string {
|
|
33
|
-
return crypto.createHash("sha256").update(accessToken).digest("hex").slice(0, 16);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function resolveLegacyStoragePaths(env: NodeJS.ProcessEnv = process.env): {
|
|
37
|
-
storagePath: string;
|
|
38
|
-
cryptoPath: string;
|
|
39
|
-
} {
|
|
40
|
-
const stateDir = getMatrixRuntime().state.resolveStateDir(env, os.homedir);
|
|
41
|
-
return {
|
|
42
|
-
storagePath: path.join(stateDir, "matrix", "bot-storage.json"),
|
|
43
|
-
cryptoPath: path.join(stateDir, "matrix", "crypto"),
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function resolveMatrixStoragePaths(params: {
|
|
48
|
-
homeserver: string;
|
|
49
|
-
userId: string;
|
|
50
|
-
accessToken: string;
|
|
51
|
-
accountId?: string | null;
|
|
52
|
-
env?: NodeJS.ProcessEnv;
|
|
53
|
-
}): MatrixStoragePaths {
|
|
54
|
-
const env = params.env ?? process.env;
|
|
55
|
-
const stateDir = getMatrixRuntime().state.resolveStateDir(env, os.homedir);
|
|
56
|
-
const accountKey = sanitizePathSegment(params.accountId ?? DEFAULT_ACCOUNT_KEY);
|
|
57
|
-
const userKey = sanitizePathSegment(params.userId);
|
|
58
|
-
const serverKey = resolveHomeserverKey(params.homeserver);
|
|
59
|
-
const tokenHash = hashAccessToken(params.accessToken);
|
|
60
|
-
const rootDir = path.join(
|
|
61
|
-
stateDir,
|
|
62
|
-
"matrix",
|
|
63
|
-
"accounts",
|
|
64
|
-
accountKey,
|
|
65
|
-
`${serverKey}__${userKey}`,
|
|
66
|
-
tokenHash,
|
|
67
|
-
);
|
|
68
|
-
return {
|
|
69
|
-
rootDir,
|
|
70
|
-
storagePath: path.join(rootDir, "bot-storage.json"),
|
|
71
|
-
cryptoPath: path.join(rootDir, "crypto"),
|
|
72
|
-
metaPath: path.join(rootDir, STORAGE_META_FILENAME),
|
|
73
|
-
accountKey,
|
|
74
|
-
tokenHash,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function maybeMigrateLegacyStorage(params: {
|
|
79
|
-
storagePaths: MatrixStoragePaths;
|
|
80
|
-
env?: NodeJS.ProcessEnv;
|
|
81
|
-
}): void {
|
|
82
|
-
const legacy = resolveLegacyStoragePaths(params.env);
|
|
83
|
-
const hasLegacyStorage = fs.existsSync(legacy.storagePath);
|
|
84
|
-
const hasLegacyCrypto = fs.existsSync(legacy.cryptoPath);
|
|
85
|
-
const hasNewStorage =
|
|
86
|
-
fs.existsSync(params.storagePaths.storagePath) || fs.existsSync(params.storagePaths.cryptoPath);
|
|
87
|
-
|
|
88
|
-
if (!hasLegacyStorage && !hasLegacyCrypto) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
if (hasNewStorage) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
fs.mkdirSync(params.storagePaths.rootDir, { recursive: true });
|
|
96
|
-
if (hasLegacyStorage) {
|
|
97
|
-
try {
|
|
98
|
-
fs.renameSync(legacy.storagePath, params.storagePaths.storagePath);
|
|
99
|
-
} catch {
|
|
100
|
-
// Ignore migration failures; new store will be created.
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (hasLegacyCrypto) {
|
|
104
|
-
try {
|
|
105
|
-
fs.renameSync(legacy.cryptoPath, params.storagePaths.cryptoPath);
|
|
106
|
-
} catch {
|
|
107
|
-
// Ignore migration failures; new store will be created.
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export function writeStorageMeta(params: {
|
|
113
|
-
storagePaths: MatrixStoragePaths;
|
|
114
|
-
homeserver: string;
|
|
115
|
-
userId: string;
|
|
116
|
-
accountId?: string | null;
|
|
117
|
-
}): void {
|
|
118
|
-
try {
|
|
119
|
-
const payload = {
|
|
120
|
-
homeserver: params.homeserver,
|
|
121
|
-
userId: params.userId,
|
|
122
|
-
accountId: params.accountId ?? DEFAULT_ACCOUNT_KEY,
|
|
123
|
-
accessTokenHash: params.storagePaths.tokenHash,
|
|
124
|
-
createdAt: new Date().toISOString(),
|
|
125
|
-
};
|
|
126
|
-
fs.mkdirSync(params.storagePaths.rootDir, { recursive: true });
|
|
127
|
-
fs.writeFileSync(params.storagePaths.metaPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
128
|
-
} catch {
|
|
129
|
-
// ignore meta write failures
|
|
130
|
-
}
|
|
131
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
export type MatrixResolvedConfig = {
|
|
2
|
-
homeserver: string;
|
|
3
|
-
userId: string;
|
|
4
|
-
accessToken?: string;
|
|
5
|
-
password?: string;
|
|
6
|
-
deviceName?: string;
|
|
7
|
-
initialSyncLimit?: number;
|
|
8
|
-
encryption?: boolean;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Authenticated Matrix configuration.
|
|
13
|
-
* Note: deviceId is NOT included here because it's implicit in the accessToken.
|
|
14
|
-
* The crypto storage assumes the device ID (and thus access token) does not change
|
|
15
|
-
* between restarts. If the access token becomes invalid or crypto storage is lost,
|
|
16
|
-
* both will need to be recreated together.
|
|
17
|
-
*/
|
|
18
|
-
export type MatrixAuth = {
|
|
19
|
-
homeserver: string;
|
|
20
|
-
userId: string;
|
|
21
|
-
accessToken: string;
|
|
22
|
-
deviceName?: string;
|
|
23
|
-
initialSyncLimit?: number;
|
|
24
|
-
encryption?: boolean;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export type MatrixStoragePaths = {
|
|
28
|
-
rootDir: string;
|
|
29
|
-
storagePath: string;
|
|
30
|
-
cryptoPath: string;
|
|
31
|
-
metaPath: string;
|
|
32
|
-
accountKey: string;
|
|
33
|
-
tokenHash: string;
|
|
34
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { createMatrixClient } from "./client/create-client.js";
|
|
2
|
-
import { startMatrixClientWithGrace } from "./client/startup.js";
|
|
3
|
-
import { getMatrixLogService } from "./sdk-runtime.js";
|
|
4
|
-
|
|
5
|
-
type MatrixClientBootstrapAuth = {
|
|
6
|
-
homeserver: string;
|
|
7
|
-
userId: string;
|
|
8
|
-
accessToken: string;
|
|
9
|
-
encryption?: boolean;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
type MatrixCryptoPrepare = {
|
|
13
|
-
prepare: (rooms?: string[]) => Promise<void>;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
type MatrixBootstrapClient = Awaited<ReturnType<typeof createMatrixClient>>;
|
|
17
|
-
|
|
18
|
-
export async function createPreparedMatrixClient(opts: {
|
|
19
|
-
auth: MatrixClientBootstrapAuth;
|
|
20
|
-
timeoutMs?: number;
|
|
21
|
-
accountId?: string;
|
|
22
|
-
}): Promise<MatrixBootstrapClient> {
|
|
23
|
-
const client = await createMatrixClient({
|
|
24
|
-
homeserver: opts.auth.homeserver,
|
|
25
|
-
userId: opts.auth.userId,
|
|
26
|
-
accessToken: opts.auth.accessToken,
|
|
27
|
-
encryption: opts.auth.encryption,
|
|
28
|
-
localTimeoutMs: opts.timeoutMs,
|
|
29
|
-
accountId: opts.accountId,
|
|
30
|
-
});
|
|
31
|
-
if (opts.auth.encryption && client.crypto) {
|
|
32
|
-
try {
|
|
33
|
-
const joinedRooms = await client.getJoinedRooms();
|
|
34
|
-
await (client.crypto as MatrixCryptoPrepare).prepare(joinedRooms);
|
|
35
|
-
} catch {
|
|
36
|
-
// Ignore crypto prep failures for one-off requests.
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
await startMatrixClientWithGrace({
|
|
40
|
-
client,
|
|
41
|
-
onError: (err: unknown) => {
|
|
42
|
-
const LogService = getMatrixLogService();
|
|
43
|
-
LogService.error("MatrixClientBootstrap", "client.start() error:", err);
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
return client;
|
|
47
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import type { CoreConfig } from "../types.js";
|
|
3
|
-
import { resolveMatrixConfig } from "./client.js";
|
|
4
|
-
|
|
5
|
-
describe("resolveMatrixConfig", () => {
|
|
6
|
-
it("prefers config over env", () => {
|
|
7
|
-
const cfg = {
|
|
8
|
-
channels: {
|
|
9
|
-
matrix: {
|
|
10
|
-
homeserver: "https://cfg.example.org",
|
|
11
|
-
userId: "@cfg:example.org",
|
|
12
|
-
accessToken: "cfg-token",
|
|
13
|
-
password: "cfg-pass",
|
|
14
|
-
deviceName: "CfgDevice",
|
|
15
|
-
initialSyncLimit: 5,
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
} as CoreConfig;
|
|
19
|
-
const env = {
|
|
20
|
-
MATRIX_HOMESERVER: "https://env.example.org",
|
|
21
|
-
MATRIX_USER_ID: "@env:example.org",
|
|
22
|
-
MATRIX_ACCESS_TOKEN: "env-token",
|
|
23
|
-
MATRIX_PASSWORD: "env-pass",
|
|
24
|
-
MATRIX_DEVICE_NAME: "EnvDevice",
|
|
25
|
-
} as NodeJS.ProcessEnv;
|
|
26
|
-
const resolved = resolveMatrixConfig(cfg, env);
|
|
27
|
-
expect(resolved).toEqual({
|
|
28
|
-
homeserver: "https://cfg.example.org",
|
|
29
|
-
userId: "@cfg:example.org",
|
|
30
|
-
accessToken: "cfg-token",
|
|
31
|
-
password: "cfg-pass",
|
|
32
|
-
deviceName: "CfgDevice",
|
|
33
|
-
initialSyncLimit: 5,
|
|
34
|
-
encryption: false,
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("uses env when config is missing", () => {
|
|
39
|
-
const cfg = {} as CoreConfig;
|
|
40
|
-
const env = {
|
|
41
|
-
MATRIX_HOMESERVER: "https://env.example.org",
|
|
42
|
-
MATRIX_USER_ID: "@env:example.org",
|
|
43
|
-
MATRIX_ACCESS_TOKEN: "env-token",
|
|
44
|
-
MATRIX_PASSWORD: "env-pass",
|
|
45
|
-
MATRIX_DEVICE_NAME: "EnvDevice",
|
|
46
|
-
} as NodeJS.ProcessEnv;
|
|
47
|
-
const resolved = resolveMatrixConfig(cfg, env);
|
|
48
|
-
expect(resolved.homeserver).toBe("https://env.example.org");
|
|
49
|
-
expect(resolved.userId).toBe("@env:example.org");
|
|
50
|
-
expect(resolved.accessToken).toBe("env-token");
|
|
51
|
-
expect(resolved.password).toBe("env-pass");
|
|
52
|
-
expect(resolved.deviceName).toBe("EnvDevice");
|
|
53
|
-
expect(resolved.initialSyncLimit).toBeUndefined();
|
|
54
|
-
expect(resolved.encryption).toBe(false);
|
|
55
|
-
});
|
|
56
|
-
});
|
package/src/matrix/client.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export type { MatrixAuth, MatrixResolvedConfig } from "./client/types.js";
|
|
2
|
-
export { isBunRuntime } from "./client/runtime.js";
|
|
3
|
-
export {
|
|
4
|
-
resolveMatrixConfig,
|
|
5
|
-
resolveMatrixConfigForAccount,
|
|
6
|
-
resolveMatrixAuth,
|
|
7
|
-
} from "./client/config.js";
|
|
8
|
-
export { createMatrixClient } from "./client/create-client.js";
|
|
9
|
-
export {
|
|
10
|
-
resolveSharedMatrixClient,
|
|
11
|
-
waitForMatrixSync,
|
|
12
|
-
stopSharedClient,
|
|
13
|
-
stopSharedClientForAccount,
|
|
14
|
-
} from "./client/shared.js";
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import os from "node:os";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
5
|
-
import { getMatrixRuntime } from "../runtime.js";
|
|
6
|
-
|
|
7
|
-
export type MatrixStoredCredentials = {
|
|
8
|
-
homeserver: string;
|
|
9
|
-
userId: string;
|
|
10
|
-
accessToken: string;
|
|
11
|
-
deviceId?: string;
|
|
12
|
-
createdAt: string;
|
|
13
|
-
lastUsedAt?: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
function credentialsFilename(accountId?: string | null): string {
|
|
17
|
-
const normalized = normalizeAccountId(accountId);
|
|
18
|
-
if (normalized === DEFAULT_ACCOUNT_ID) {
|
|
19
|
-
return "credentials.json";
|
|
20
|
-
}
|
|
21
|
-
// normalizeAccountId produces lowercase [a-z0-9-] strings, already filesystem-safe.
|
|
22
|
-
// Different raw IDs that normalize to the same value are the same logical account.
|
|
23
|
-
return `credentials-${normalized}.json`;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function resolveMatrixCredentialsDir(
|
|
27
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
28
|
-
stateDir?: string,
|
|
29
|
-
): string {
|
|
30
|
-
const resolvedStateDir = stateDir ?? getMatrixRuntime().state.resolveStateDir(env, os.homedir);
|
|
31
|
-
return path.join(resolvedStateDir, "credentials", "matrix");
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function resolveMatrixCredentialsPath(
|
|
35
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
36
|
-
accountId?: string | null,
|
|
37
|
-
): string {
|
|
38
|
-
const dir = resolveMatrixCredentialsDir(env);
|
|
39
|
-
return path.join(dir, credentialsFilename(accountId));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function loadMatrixCredentials(
|
|
43
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
44
|
-
accountId?: string | null,
|
|
45
|
-
): MatrixStoredCredentials | null {
|
|
46
|
-
const credPath = resolveMatrixCredentialsPath(env, accountId);
|
|
47
|
-
try {
|
|
48
|
-
if (!fs.existsSync(credPath)) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
const raw = fs.readFileSync(credPath, "utf-8");
|
|
52
|
-
const parsed = JSON.parse(raw) as Partial<MatrixStoredCredentials>;
|
|
53
|
-
if (
|
|
54
|
-
typeof parsed.homeserver !== "string" ||
|
|
55
|
-
typeof parsed.userId !== "string" ||
|
|
56
|
-
typeof parsed.accessToken !== "string"
|
|
57
|
-
) {
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
return parsed as MatrixStoredCredentials;
|
|
61
|
-
} catch {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function saveMatrixCredentials(
|
|
67
|
-
credentials: Omit<MatrixStoredCredentials, "createdAt" | "lastUsedAt">,
|
|
68
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
69
|
-
accountId?: string | null,
|
|
70
|
-
): void {
|
|
71
|
-
const dir = resolveMatrixCredentialsDir(env);
|
|
72
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
73
|
-
|
|
74
|
-
const credPath = resolveMatrixCredentialsPath(env, accountId);
|
|
75
|
-
|
|
76
|
-
const existing = loadMatrixCredentials(env, accountId);
|
|
77
|
-
const now = new Date().toISOString();
|
|
78
|
-
|
|
79
|
-
const toSave: MatrixStoredCredentials = {
|
|
80
|
-
...credentials,
|
|
81
|
-
createdAt: existing?.createdAt ?? now,
|
|
82
|
-
lastUsedAt: now,
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
fs.writeFileSync(credPath, JSON.stringify(toSave, null, 2), "utf-8");
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export function touchMatrixCredentials(
|
|
89
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
90
|
-
accountId?: string | null,
|
|
91
|
-
): void {
|
|
92
|
-
const existing = loadMatrixCredentials(env, accountId);
|
|
93
|
-
if (!existing) {
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
existing.lastUsedAt = new Date().toISOString();
|
|
98
|
-
const credPath = resolveMatrixCredentialsPath(env, accountId);
|
|
99
|
-
fs.writeFileSync(credPath, JSON.stringify(existing, null, 2), "utf-8");
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export function clearMatrixCredentials(
|
|
103
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
104
|
-
accountId?: string | null,
|
|
105
|
-
): void {
|
|
106
|
-
const credPath = resolveMatrixCredentialsPath(env, accountId);
|
|
107
|
-
try {
|
|
108
|
-
if (fs.existsSync(credPath)) {
|
|
109
|
-
fs.unlinkSync(credPath);
|
|
110
|
-
}
|
|
111
|
-
} catch {
|
|
112
|
-
// ignore
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export function credentialsMatchConfig(
|
|
117
|
-
stored: MatrixStoredCredentials,
|
|
118
|
-
config: { homeserver: string; userId: string },
|
|
119
|
-
): boolean {
|
|
120
|
-
// If userId is empty (token-based auth), only match homeserver
|
|
121
|
-
if (!config.userId) {
|
|
122
|
-
return stored.homeserver === config.homeserver;
|
|
123
|
-
}
|
|
124
|
-
return stored.homeserver === config.homeserver && stored.userId === config.userId;
|
|
125
|
-
}
|