@kodelyth/matrix 2026.5.39 → 2026.5.42
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/CHANGELOG.md +321 -0
- package/SPEC-SUPPORT.md +116 -0
- package/api.ts +38 -0
- package/auth-presence.ts +56 -0
- package/channel-plugin-api.ts +3 -0
- package/cli-metadata.ts +11 -0
- package/contract-api.ts +17 -0
- package/dist/account-selection-Y50DNJ2l.js +158 -0
- package/dist/active-client-CmFdvPdO.js +20 -0
- package/dist/api.js +12 -0
- package/dist/approval-handler.runtime-BIi4fL0R.js +377 -0
- package/dist/approval-ids-BGHK7PnZ.js +7 -0
- package/dist/approval-reaction-auth-CL0-nCNV.js +27 -0
- package/dist/approval-reactions-nDm2x-K5.js +162 -0
- package/dist/async-lock-SsmtFXtt.js +19 -0
- package/dist/auth-presence.js +26 -0
- package/dist/backup-health-3BHbHxyd.js +60 -0
- package/dist/channel-C0kCyTNB.js +1380 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel.runtime-CdrdEN-0.js +250 -0
- package/dist/cli-FtY6Nuzw.js +1338 -0
- package/dist/cli-metadata-Dkwua7CB.js +22 -0
- package/dist/cli-metadata.js +2 -0
- package/dist/client-BnohYygh.js +25 -0
- package/dist/client-PhrTwuC4.js +30 -0
- package/dist/client-bootstrap-Mcj8ChJ5.js +114 -0
- package/dist/config-paths-DVvt6vM3.js +114 -0
- package/dist/config-schema-BMGOlhdI.js +308 -0
- package/dist/config-secret-input.runtime-Dv_4Br_f.js +2 -0
- package/dist/contract-api.js +8 -0
- package/dist/create-client-J0htTaRj.js +64 -0
- package/dist/credentials-B7GsBbgQ.js +56 -0
- package/dist/credentials-read-8fE4qoWs.js +112 -0
- package/dist/credentials-write.runtime-BibplB4Y.js +17 -0
- package/dist/crypto-node.runtime-D9qxgRPa.js +12 -0
- package/dist/crypto-runtime-1pKW4O2F.js +1214 -0
- package/dist/deps-DVpDS81G.js +208 -0
- package/dist/device-health-Ct2wDSPG.js +16 -0
- package/dist/directory-live-i3T8uORc.js +150 -0
- package/dist/doctor-contract-BLzYHl_9.js +246 -0
- package/dist/doctor-contract-api.js +2 -0
- package/dist/doctor-diR5gE7D.js +153 -0
- package/dist/draft-stream-HpPJ_VJt.js +143 -0
- package/dist/encryption-guidance-BNEgckrZ.js +15 -0
- package/dist/env-auth-UFiTGkDM.js +63 -0
- package/dist/env-vars-EQKQv-FE.js +63 -0
- package/dist/errors-BETj3zr9.js +17 -0
- package/dist/exec-approval-resolver-BxPorU_t.js +15 -0
- package/dist/helper-api.js +4 -0
- package/dist/http-client-DoQgbQsU.js +331 -0
- package/dist/index.js +46 -0
- package/dist/legacy-crypto-inspector-zK0hDCbt.js +41 -0
- package/dist/legacy-crypto-restore-DSFIXuDo.js +85 -0
- package/dist/logging-Df7aPD1z.js +99 -0
- package/dist/matrix-migration.runtime-BNoT1Prt.js +525 -0
- package/dist/media-text-ZhGA8Pcs.js +146 -0
- package/dist/messages-CRA9WGg0.js +140 -0
- package/dist/migration-snapshot-backup-BR-xD7Ew.js +69 -0
- package/dist/migration-snapshot.runtime-BLcy_Nvw.js +2 -0
- package/dist/monitor-DQm7_13y.js +4331 -0
- package/dist/plugin-entry.handlers.runtime.js +51 -0
- package/dist/probe.runtime-CjJS53Kz.js +3 -0
- package/dist/profile-update-DqkPgZ1P.js +68 -0
- package/dist/reaction-common-CmVLzP-u.js +71 -0
- package/dist/reaction-events-D0nUJuZV.js +121 -0
- package/dist/record-shared-DGvSFn5M.js +2 -0
- package/dist/resolve-targets-ChECUzD2.js +140 -0
- package/dist/resolver.runtime-hdY3n0GO.js +5 -0
- package/dist/rolldown-runtime-DUslC3ob.js +14 -0
- package/dist/route-xRKj_ESW.js +161 -0
- package/dist/runtime-B-Fyrmxo.js +8 -0
- package/dist/runtime-api-BYXXkxq2.js +24 -0
- package/dist/runtime-api.js +25 -0
- package/dist/runtime-heavy-api.js +3 -0
- package/dist/runtime-lwTSy9Yt.js +6 -0
- package/dist/runtime-setter-api.js +2 -0
- package/dist/sdk-Jhq7mLtD.js +1704 -0
- package/dist/secret-contract-DEMcDsjl.js +120 -0
- package/dist/secret-contract-api.js +2 -0
- package/dist/send-CJunc6QM.js +1517 -0
- package/dist/setup-bootstrap-rJ0qZWPe.js +62 -0
- package/dist/setup-core-BEYoXF3J.js +677 -0
- package/dist/setup-entry.js +19 -0
- package/dist/setup-plugin-api.js +43 -0
- package/dist/setup-surface-c28ON6jq.js +537 -0
- package/dist/shared-D6MFMnpG.js +642 -0
- package/dist/startup-abort-B2J3MU_h.js +109 -0
- package/dist/startup-verification-CkD4Cwce.js +132 -0
- package/dist/storage-nyO0DOFE.js +281 -0
- package/dist/storage-paths-BTAketfg.js +52 -0
- package/dist/subagent-hooks-api-Dr_xnMRG.js +170 -0
- package/dist/subagent-hooks-api.js +2 -0
- package/dist/sync-state-Bx0gPaGA.js +12 -0
- package/dist/target-ids-Bsazo8si.js +77 -0
- package/dist/test-api.js +4 -0
- package/dist/thread-binding-api-IGU0-L70.js +17 -0
- package/dist/thread-binding-api.js +2 -0
- package/dist/thread-bindings-FjAZmDUP.js +352 -0
- package/dist/thread-bindings-runtime.js +2 -0
- package/dist/thread-bindings-shared-fvfP7jVs.js +97 -0
- package/dist/timeout-abort-signal-DpSHDHhR.js +2 -0
- package/dist/tool-actions.runtime-Cbo7YcYZ.js +532 -0
- package/dist/url-validation-DlrXNjAE.js +36 -0
- package/dist/verification-7tDPRpJU.js +345 -0
- package/doctor-contract-api.ts +1 -0
- package/helper-api.ts +3 -0
- package/index.ts +55 -0
- package/klaw.plugin.json +3 -891
- package/package.json +4 -4
- package/plugin-entry.handlers.runtime.ts +1 -0
- package/runtime-api.ts +72 -0
- package/runtime-heavy-api.ts +1 -0
- package/runtime-setter-api.ts +3 -0
- package/secret-contract-api.ts +5 -0
- package/setup-entry.ts +17 -0
- package/setup-plugin-api.ts +3 -0
- package/src/account-selection.ts +223 -0
- package/src/actions.ts +346 -0
- package/src/approval-auth.ts +25 -0
- package/src/approval-handler.runtime.ts +592 -0
- package/src/approval-ids.ts +6 -0
- package/src/approval-native.ts +345 -0
- package/src/approval-reaction-auth.ts +45 -0
- package/src/approval-reactions.ts +313 -0
- package/src/auth-precedence.ts +61 -0
- package/src/channel-account-paths.ts +97 -0
- package/src/channel.runtime.ts +17 -0
- package/src/channel.setup.ts +48 -0
- package/src/channel.ts +667 -0
- package/src/cli-metadata.ts +19 -0
- package/src/cli.ts +2298 -0
- package/src/config-adapter.ts +41 -0
- package/src/config-schema.ts +159 -0
- package/src/config-ui-hints.ts +56 -0
- package/src/directory-live.ts +238 -0
- package/src/doctor-contract.ts +287 -0
- package/src/doctor.ts +262 -0
- package/src/env-vars.ts +92 -0
- package/src/exec-approval-resolver.ts +23 -0
- package/src/exec-approvals.ts +287 -0
- package/src/group-mentions.ts +41 -0
- package/src/legacy-crypto-inspector-availability.ts +60 -0
- package/src/legacy-crypto.ts +531 -0
- package/src/legacy-state.ts +156 -0
- package/src/matrix/account-config.ts +175 -0
- package/src/matrix/accounts.ts +194 -0
- package/src/matrix/actions/client.ts +31 -0
- package/src/matrix/actions/devices.ts +34 -0
- package/src/matrix/actions/limits.ts +6 -0
- package/src/matrix/actions/messages.ts +129 -0
- package/src/matrix/actions/pins.ts +63 -0
- package/src/matrix/actions/polls.ts +109 -0
- package/src/matrix/actions/profile.ts +37 -0
- package/src/matrix/actions/reactions.ts +59 -0
- package/src/matrix/actions/room.ts +71 -0
- package/src/matrix/actions/summary.ts +88 -0
- package/src/matrix/actions/types.ts +63 -0
- package/src/matrix/actions/verification.ts +589 -0
- package/src/matrix/actions.ts +37 -0
- package/src/matrix/active-client.ts +26 -0
- package/src/matrix/async-lock.ts +18 -0
- package/src/matrix/backup-health.ts +124 -0
- package/src/matrix/client/config-runtime-api.ts +9 -0
- package/src/matrix/client/config-secret-input.runtime.ts +1 -0
- package/src/matrix/client/config.ts +853 -0
- package/src/matrix/client/create-client.ts +105 -0
- package/src/matrix/client/env-auth.ts +95 -0
- package/src/matrix/client/file-sync-store.ts +289 -0
- package/src/matrix/client/logging.ts +140 -0
- package/src/matrix/client/migration-snapshot.runtime.ts +1 -0
- package/src/matrix/client/private-network-host.ts +1 -0
- package/src/matrix/client/runtime.ts +4 -0
- package/src/matrix/client/shared.ts +316 -0
- package/src/matrix/client/storage.ts +543 -0
- package/src/matrix/client/types.ts +50 -0
- package/src/matrix/client/url-validation.ts +73 -0
- package/src/matrix/client-bootstrap.ts +173 -0
- package/src/matrix/client.ts +23 -0
- package/src/matrix/config-paths.ts +31 -0
- package/src/matrix/config-update.ts +292 -0
- package/src/matrix/credentials-read.ts +208 -0
- package/src/matrix/credentials-write.runtime.ts +35 -0
- package/src/matrix/credentials.ts +95 -0
- package/src/matrix/deps.ts +309 -0
- package/src/matrix/device-health.ts +29 -0
- package/src/matrix/direct-management.ts +349 -0
- package/src/matrix/direct-room.ts +128 -0
- package/src/matrix/draft-stream.ts +225 -0
- package/src/matrix/encryption-guidance.ts +24 -0
- package/src/matrix/errors.ts +21 -0
- package/src/matrix/format.ts +426 -0
- package/src/matrix/legacy-crypto-inspector.ts +95 -0
- package/src/matrix/media-errors.ts +20 -0
- package/src/matrix/media-text.ts +162 -0
- package/src/matrix/monitor/access-state.ts +145 -0
- package/src/matrix/monitor/ack-config.ts +27 -0
- package/src/matrix/monitor/allowlist.ts +89 -0
- package/src/matrix/monitor/auto-join.ts +86 -0
- package/src/matrix/monitor/config.ts +569 -0
- package/src/matrix/monitor/context-summary.ts +43 -0
- package/src/matrix/monitor/direct.ts +296 -0
- package/src/matrix/monitor/events.ts +397 -0
- package/src/matrix/monitor/handler.ts +2266 -0
- package/src/matrix/monitor/inbound-dedupe.ts +267 -0
- package/src/matrix/monitor/index.ts +540 -0
- package/src/matrix/monitor/legacy-crypto-restore.ts +139 -0
- package/src/matrix/monitor/location.ts +108 -0
- package/src/matrix/monitor/media.ts +119 -0
- package/src/matrix/monitor/mentions.ts +256 -0
- package/src/matrix/monitor/reaction-events.ts +197 -0
- package/src/matrix/monitor/recent-invite.ts +30 -0
- package/src/matrix/monitor/replies.ts +136 -0
- package/src/matrix/monitor/reply-context.ts +92 -0
- package/src/matrix/monitor/room-history.ts +301 -0
- package/src/matrix/monitor/room-info.ts +126 -0
- package/src/matrix/monitor/rooms.ts +52 -0
- package/src/matrix/monitor/route.ts +179 -0
- package/src/matrix/monitor/runtime-api.ts +28 -0
- package/src/matrix/monitor/startup-verification.ts +237 -0
- package/src/matrix/monitor/startup.ts +218 -0
- package/src/matrix/monitor/status.ts +120 -0
- package/src/matrix/monitor/sync-lifecycle.ts +91 -0
- package/src/matrix/monitor/task-runner.ts +38 -0
- package/src/matrix/monitor/test-events.ts +21 -0
- package/src/matrix/monitor/thread-context.ts +108 -0
- package/src/matrix/monitor/threads.ts +85 -0
- package/src/matrix/monitor/types.ts +30 -0
- package/src/matrix/monitor/verification-events.ts +643 -0
- package/src/matrix/monitor/verification-utils.ts +46 -0
- package/src/matrix/outbound-media-runtime.ts +1 -0
- package/src/matrix/poll-summary.ts +110 -0
- package/src/matrix/poll-types.ts +429 -0
- package/src/matrix/probe.runtime.ts +4 -0
- package/src/matrix/probe.ts +97 -0
- package/src/matrix/profile.ts +184 -0
- package/src/matrix/reaction-common.ts +147 -0
- package/src/matrix/sdk/crypto-bootstrap.ts +438 -0
- package/src/matrix/sdk/crypto-facade.ts +242 -0
- package/src/matrix/sdk/crypto-node.runtime.ts +17 -0
- package/src/matrix/sdk/crypto-runtime.ts +14 -0
- package/src/matrix/sdk/decrypt-bridge.ts +410 -0
- package/src/matrix/sdk/event-helpers.ts +83 -0
- package/src/matrix/sdk/http-client.ts +87 -0
- package/src/matrix/sdk/idb-persistence-lock.ts +51 -0
- package/src/matrix/sdk/idb-persistence.ts +288 -0
- package/src/matrix/sdk/logger.ts +108 -0
- package/src/matrix/sdk/read-response-with-limit.ts +19 -0
- package/src/matrix/sdk/recovery-key-store.ts +453 -0
- package/src/matrix/sdk/timeout-abort-signal.ts +1 -0
- package/src/matrix/sdk/transport-runtime-api.ts +18 -0
- package/src/matrix/sdk/transport.ts +352 -0
- package/src/matrix/sdk/types.ts +245 -0
- package/src/matrix/sdk/verification-manager.ts +795 -0
- package/src/matrix/sdk/verification-status.ts +23 -0
- package/src/matrix/sdk.ts +2152 -0
- package/src/matrix/send/client.ts +93 -0
- package/src/matrix/send/formatting.ts +189 -0
- package/src/matrix/send/media.ts +244 -0
- package/src/matrix/send/targets.ts +104 -0
- package/src/matrix/send/types.ts +131 -0
- package/src/matrix/send.ts +660 -0
- package/src/matrix/session-store-metadata.ts +108 -0
- package/src/matrix/startup-abort.ts +44 -0
- package/src/matrix/subagent-hooks.ts +308 -0
- package/src/matrix/sync-state.ts +27 -0
- package/src/matrix/target-ids.ts +79 -0
- package/src/matrix/thread-bindings-shared.ts +206 -0
- package/src/matrix/thread-bindings.ts +580 -0
- package/src/matrix-migration.runtime.ts +9 -0
- package/src/migration-config.ts +243 -0
- package/src/migration-snapshot-backup.ts +116 -0
- package/src/migration-snapshot.ts +53 -0
- package/src/onboarding.ts +775 -0
- package/src/outbound.ts +248 -0
- package/src/plugin-entry.runtime.js +115 -0
- package/src/plugin-entry.runtime.ts +70 -0
- package/src/profile-update.ts +71 -0
- package/src/record-shared.ts +3 -0
- package/src/resolve-targets.ts +175 -0
- package/src/resolver.runtime.ts +5 -0
- package/src/resolver.ts +21 -0
- package/src/runtime-api.ts +106 -0
- package/src/runtime.ts +13 -0
- package/src/secret-contract.ts +174 -0
- package/src/session-route.ts +126 -0
- package/src/setup-bootstrap.ts +102 -0
- package/src/setup-config.ts +222 -0
- package/src/setup-contract.ts +90 -0
- package/src/setup-core.ts +146 -0
- package/src/setup-dm-policy.ts +15 -0
- package/src/setup-surface.ts +4 -0
- package/src/startup-maintenance.ts +114 -0
- package/src/storage-paths.ts +92 -0
- package/src/thread-binding-api.ts +23 -0
- package/src/tool-actions.runtime.ts +1 -0
- package/src/tool-actions.ts +498 -0
- package/src/types.ts +257 -0
- package/subagent-hooks-api.ts +31 -0
- package/test-api.ts +21 -0
- package/thread-binding-api.ts +4 -0
- package/thread-bindings-runtime.ts +4 -0
- package/tsconfig.json +16 -0
- package/api.js +0 -7
- package/auth-presence.js +0 -7
- package/channel-plugin-api.js +0 -7
- package/cli-metadata.js +0 -7
- package/contract-api.js +0 -7
- package/doctor-contract-api.js +0 -7
- package/helper-api.js +0 -7
- package/index.js +0 -7
- package/plugin-entry.handlers.runtime.js +0 -7
- package/runtime-api.js +0 -7
- package/runtime-heavy-api.js +0 -7
- package/runtime-setter-api.js +0 -7
- package/secret-contract-api.js +0 -7
- package/setup-entry.js +0 -7
- package/setup-plugin-api.js +0 -7
- package/subagent-hooks-api.js +0 -7
- package/test-api.js +0 -7
- package/thread-binding-api.js +0 -7
- package/thread-bindings-runtime.js +0 -7
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { t as getMatrixRuntime } from "./runtime-B-Fyrmxo.js";
|
|
2
|
+
import { format } from "node:util";
|
|
3
|
+
import { redactSensitiveText } from "klaw/plugin-sdk/logging-core";
|
|
4
|
+
//#region extensions/matrix/src/matrix/sdk/logger.ts
|
|
5
|
+
function noop() {}
|
|
6
|
+
let forceConsoleLogging = false;
|
|
7
|
+
function setMatrixConsoleLogging(enabled) {
|
|
8
|
+
forceConsoleLogging = enabled;
|
|
9
|
+
}
|
|
10
|
+
function resolveRuntimeLogger(module) {
|
|
11
|
+
if (forceConsoleLogging) return null;
|
|
12
|
+
try {
|
|
13
|
+
return getMatrixRuntime().logging.getChildLogger({ module: `matrix:${module}` });
|
|
14
|
+
} catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function formatMessage(module, messageOrObject) {
|
|
19
|
+
if (messageOrObject.length === 0) return `[${module}]`;
|
|
20
|
+
return redactSensitiveText(`[${module}] ${format(...messageOrObject)}`);
|
|
21
|
+
}
|
|
22
|
+
var ConsoleLogger = class {
|
|
23
|
+
emit(level, module, ...messageOrObject) {
|
|
24
|
+
const runtimeLogger = resolveRuntimeLogger(module);
|
|
25
|
+
const message = formatMessage(module, messageOrObject);
|
|
26
|
+
if (runtimeLogger) {
|
|
27
|
+
if (level === "debug") {
|
|
28
|
+
runtimeLogger.debug?.(message);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
runtimeLogger[level](message);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (level === "debug") {
|
|
35
|
+
console.debug(message);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
console[level](message);
|
|
39
|
+
}
|
|
40
|
+
trace(module, ...messageOrObject) {
|
|
41
|
+
this.emit("debug", module, ...messageOrObject);
|
|
42
|
+
}
|
|
43
|
+
debug(module, ...messageOrObject) {
|
|
44
|
+
this.emit("debug", module, ...messageOrObject);
|
|
45
|
+
}
|
|
46
|
+
info(module, ...messageOrObject) {
|
|
47
|
+
this.emit("info", module, ...messageOrObject);
|
|
48
|
+
}
|
|
49
|
+
warn(module, ...messageOrObject) {
|
|
50
|
+
this.emit("warn", module, ...messageOrObject);
|
|
51
|
+
}
|
|
52
|
+
error(module, ...messageOrObject) {
|
|
53
|
+
this.emit("error", module, ...messageOrObject);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
let activeLogger = new ConsoleLogger();
|
|
57
|
+
const LogService = {
|
|
58
|
+
setLogger(logger) {
|
|
59
|
+
activeLogger = logger;
|
|
60
|
+
},
|
|
61
|
+
trace(module, ...messageOrObject) {
|
|
62
|
+
activeLogger.trace(module, ...messageOrObject);
|
|
63
|
+
},
|
|
64
|
+
debug(module, ...messageOrObject) {
|
|
65
|
+
activeLogger.debug(module, ...messageOrObject);
|
|
66
|
+
},
|
|
67
|
+
info(module, ...messageOrObject) {
|
|
68
|
+
activeLogger.info(module, ...messageOrObject);
|
|
69
|
+
},
|
|
70
|
+
warn(module, ...messageOrObject) {
|
|
71
|
+
activeLogger.warn(module, ...messageOrObject);
|
|
72
|
+
},
|
|
73
|
+
error(module, ...messageOrObject) {
|
|
74
|
+
activeLogger.error(module, ...messageOrObject);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region extensions/matrix/src/matrix/startup-abort.ts
|
|
79
|
+
function createMatrixStartupAbortError() {
|
|
80
|
+
const error = /* @__PURE__ */ new Error("Matrix startup aborted");
|
|
81
|
+
error.name = "AbortError";
|
|
82
|
+
return error;
|
|
83
|
+
}
|
|
84
|
+
function throwIfMatrixStartupAborted(abortSignal) {
|
|
85
|
+
if (abortSignal?.aborted === true) throw createMatrixStartupAbortError();
|
|
86
|
+
}
|
|
87
|
+
function isMatrixStartupAbortError(error) {
|
|
88
|
+
return error instanceof Error && error.name === "AbortError";
|
|
89
|
+
}
|
|
90
|
+
async function awaitMatrixStartupWithAbort(promise, abortSignal) {
|
|
91
|
+
if (!abortSignal) return await promise;
|
|
92
|
+
if (abortSignal.aborted) throw createMatrixStartupAbortError();
|
|
93
|
+
return await new Promise((resolve, reject) => {
|
|
94
|
+
const onAbort = () => {
|
|
95
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
96
|
+
reject(createMatrixStartupAbortError());
|
|
97
|
+
};
|
|
98
|
+
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
99
|
+
promise.then((value) => {
|
|
100
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
101
|
+
resolve(value);
|
|
102
|
+
}, (error) => {
|
|
103
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
104
|
+
reject(error);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
export { ConsoleLogger as a, setMatrixConsoleLogging as c, throwIfMatrixStartupAborted as i, createMatrixStartupAbortError as n, LogService as o, isMatrixStartupAbortError as r, noop as s, awaitMatrixStartupWithAbort as t };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { t as formatMatrixErrorMessage } from "./errors-BETj3zr9.js";
|
|
2
|
+
import { a as resolveMatrixStoragePaths } from "./storage-nyO0DOFE.js";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { readJsonFileWithFallback, writeJsonFileAtomically } from "klaw/plugin-sdk/json-store";
|
|
5
|
+
import fs from "node:fs/promises";
|
|
6
|
+
//#region extensions/matrix/src/matrix/monitor/startup-verification.ts
|
|
7
|
+
const STARTUP_VERIFICATION_STATE_FILENAME = "startup-verification.json";
|
|
8
|
+
const DEFAULT_STARTUP_VERIFICATION_MODE = "if-unverified";
|
|
9
|
+
const DEFAULT_STARTUP_VERIFICATION_COOLDOWN_HOURS = 24;
|
|
10
|
+
const DEFAULT_STARTUP_VERIFICATION_FAILURE_COOLDOWN_MS = 3600 * 1e3;
|
|
11
|
+
function normalizeCooldownHours(value) {
|
|
12
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return DEFAULT_STARTUP_VERIFICATION_COOLDOWN_HOURS;
|
|
13
|
+
return Math.max(0, value);
|
|
14
|
+
}
|
|
15
|
+
function resolveStartupVerificationStatePath(params) {
|
|
16
|
+
const storagePaths = resolveMatrixStoragePaths({
|
|
17
|
+
homeserver: params.auth.homeserver,
|
|
18
|
+
userId: params.auth.userId,
|
|
19
|
+
accessToken: params.auth.accessToken,
|
|
20
|
+
accountId: params.auth.accountId,
|
|
21
|
+
deviceId: params.auth.deviceId,
|
|
22
|
+
env: params.env
|
|
23
|
+
});
|
|
24
|
+
return path.join(storagePaths.rootDir, STARTUP_VERIFICATION_STATE_FILENAME);
|
|
25
|
+
}
|
|
26
|
+
async function readStartupVerificationState(filePath) {
|
|
27
|
+
const { value } = await readJsonFileWithFallback(filePath, null);
|
|
28
|
+
return value && typeof value === "object" ? value : null;
|
|
29
|
+
}
|
|
30
|
+
async function clearStartupVerificationState(filePath) {
|
|
31
|
+
await fs.rm(filePath, { force: true }).catch(() => {});
|
|
32
|
+
}
|
|
33
|
+
function resolveStateCooldownMs(state, cooldownMs) {
|
|
34
|
+
if (state?.outcome === "failed") return Math.min(cooldownMs, DEFAULT_STARTUP_VERIFICATION_FAILURE_COOLDOWN_MS);
|
|
35
|
+
return cooldownMs;
|
|
36
|
+
}
|
|
37
|
+
function resolveRetryAfterMs(params) {
|
|
38
|
+
const attemptedAtMs = Date.parse(params.attemptedAt ?? "");
|
|
39
|
+
if (!Number.isFinite(attemptedAtMs)) return;
|
|
40
|
+
const remaining = attemptedAtMs + params.cooldownMs - params.nowMs;
|
|
41
|
+
return remaining > 0 ? remaining : void 0;
|
|
42
|
+
}
|
|
43
|
+
function shouldHonorCooldown(params) {
|
|
44
|
+
if (!params.state || params.stateCooldownMs <= 0) return false;
|
|
45
|
+
if (params.state.userId && params.verification.userId && params.state.userId !== params.verification.userId) return false;
|
|
46
|
+
if (params.state.deviceId && params.verification.deviceId && params.state.deviceId !== params.verification.deviceId) return false;
|
|
47
|
+
return resolveRetryAfterMs({
|
|
48
|
+
attemptedAt: params.state.attemptedAt,
|
|
49
|
+
cooldownMs: params.stateCooldownMs,
|
|
50
|
+
nowMs: params.nowMs
|
|
51
|
+
}) !== void 0;
|
|
52
|
+
}
|
|
53
|
+
function hasPendingSelfVerification(verifications) {
|
|
54
|
+
return verifications.some((entry) => entry.isSelfVerification && !entry.completed && entry.pending);
|
|
55
|
+
}
|
|
56
|
+
async function ensureMatrixStartupVerification(params) {
|
|
57
|
+
if (params.auth.encryption !== true || !params.client.crypto) return { kind: "unsupported" };
|
|
58
|
+
const verification = await params.client.getOwnDeviceVerificationStatus();
|
|
59
|
+
const statePath = params.stateFilePath ?? resolveStartupVerificationStatePath({
|
|
60
|
+
auth: params.auth,
|
|
61
|
+
env: params.env
|
|
62
|
+
});
|
|
63
|
+
if (verification.verified) {
|
|
64
|
+
await clearStartupVerificationState(statePath);
|
|
65
|
+
return {
|
|
66
|
+
kind: "verified",
|
|
67
|
+
verification
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if ((params.accountConfig.startupVerification ?? DEFAULT_STARTUP_VERIFICATION_MODE) === "off") {
|
|
71
|
+
await clearStartupVerificationState(statePath);
|
|
72
|
+
return {
|
|
73
|
+
kind: "disabled",
|
|
74
|
+
verification
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (hasPendingSelfVerification(await params.client.crypto.listVerifications().catch(() => []))) return {
|
|
78
|
+
kind: "pending",
|
|
79
|
+
verification
|
|
80
|
+
};
|
|
81
|
+
const cooldownMs = normalizeCooldownHours(params.accountConfig.startupVerificationCooldownHours) * 60 * 60 * 1e3;
|
|
82
|
+
const nowMs = params.nowMs ?? Date.now();
|
|
83
|
+
const state = await readStartupVerificationState(statePath);
|
|
84
|
+
const stateCooldownMs = resolveStateCooldownMs(state, cooldownMs);
|
|
85
|
+
if (shouldHonorCooldown({
|
|
86
|
+
state,
|
|
87
|
+
verification,
|
|
88
|
+
stateCooldownMs,
|
|
89
|
+
nowMs
|
|
90
|
+
})) return {
|
|
91
|
+
kind: "cooldown",
|
|
92
|
+
verification,
|
|
93
|
+
retryAfterMs: resolveRetryAfterMs({
|
|
94
|
+
attemptedAt: state?.attemptedAt,
|
|
95
|
+
cooldownMs: stateCooldownMs,
|
|
96
|
+
nowMs
|
|
97
|
+
})
|
|
98
|
+
};
|
|
99
|
+
try {
|
|
100
|
+
const request = await params.client.crypto.requestVerification({ ownUser: true });
|
|
101
|
+
await writeJsonFileAtomically(statePath, {
|
|
102
|
+
userId: verification.userId,
|
|
103
|
+
deviceId: verification.deviceId,
|
|
104
|
+
attemptedAt: new Date(nowMs).toISOString(),
|
|
105
|
+
outcome: "requested",
|
|
106
|
+
requestId: request.id,
|
|
107
|
+
transactionId: request.transactionId
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
kind: "requested",
|
|
111
|
+
verification,
|
|
112
|
+
requestId: request.id,
|
|
113
|
+
transactionId: request.transactionId ?? void 0
|
|
114
|
+
};
|
|
115
|
+
} catch (err) {
|
|
116
|
+
const error = formatMatrixErrorMessage(err);
|
|
117
|
+
await writeJsonFileAtomically(statePath, {
|
|
118
|
+
userId: verification.userId,
|
|
119
|
+
deviceId: verification.deviceId,
|
|
120
|
+
attemptedAt: new Date(nowMs).toISOString(),
|
|
121
|
+
outcome: "failed",
|
|
122
|
+
error
|
|
123
|
+
}).catch(() => {});
|
|
124
|
+
return {
|
|
125
|
+
kind: "request-failed",
|
|
126
|
+
verification,
|
|
127
|
+
error
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//#endregion
|
|
132
|
+
export { ensureMatrixStartupVerification };
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { a as resolveMatrixDefaultOrOnlyAccountId, n as requiresExplicitMatrixDefaultAccount } from "./account-selection-Y50DNJ2l.js";
|
|
2
|
+
import { t as getMatrixRuntime } from "./runtime-B-Fyrmxo.js";
|
|
3
|
+
import { n as resolveMatrixAccountStorageRoot, s as resolveMatrixLegacyFlatStoragePaths } from "./storage-paths-BTAketfg.js";
|
|
4
|
+
import { normalizeAccountId } from "klaw/plugin-sdk/account-id";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { loadJsonFile, saveJsonFile } from "klaw/plugin-sdk/json-store";
|
|
9
|
+
//#region extensions/matrix/src/matrix/client/storage.ts
|
|
10
|
+
const DEFAULT_ACCOUNT_KEY = "default";
|
|
11
|
+
const STORAGE_META_FILENAME = "storage-meta.json";
|
|
12
|
+
const THREAD_BINDINGS_FILENAME = "thread-bindings.json";
|
|
13
|
+
const LEGACY_CRYPTO_MIGRATION_FILENAME = "legacy-crypto-migration.json";
|
|
14
|
+
const RECOVERY_KEY_FILENAME = "recovery-key.json";
|
|
15
|
+
const IDB_SNAPSHOT_FILENAME = "crypto-idb-snapshot.json";
|
|
16
|
+
const STARTUP_VERIFICATION_FILENAME = "startup-verification.json";
|
|
17
|
+
function resolveLegacyStoragePaths(env = process.env) {
|
|
18
|
+
const legacy = resolveMatrixLegacyFlatStoragePaths(getMatrixRuntime().state.resolveStateDir(env, os.homedir));
|
|
19
|
+
return {
|
|
20
|
+
storagePath: legacy.storagePath,
|
|
21
|
+
cryptoPath: legacy.cryptoPath
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function assertLegacyMigrationAccountSelection(params) {
|
|
25
|
+
const cfg = getMatrixRuntime().config.current();
|
|
26
|
+
if (!cfg.channels?.matrix || typeof cfg.channels.matrix !== "object") return;
|
|
27
|
+
if (requiresExplicitMatrixDefaultAccount(cfg)) throw new Error("Legacy Matrix client storage cannot be migrated automatically because multiple Matrix accounts are configured and channels.matrix.defaultAccount is not set.");
|
|
28
|
+
const selectedAccountId = normalizeAccountId(resolveMatrixDefaultOrOnlyAccountId(cfg));
|
|
29
|
+
const currentAccountId = normalizeAccountId(params.accountKey);
|
|
30
|
+
if (selectedAccountId !== currentAccountId) throw new Error(`Legacy Matrix client storage targets account "${selectedAccountId}", but the current client is starting account "${currentAccountId}". Start the selected account first so flat legacy storage is not migrated into the wrong account directory.`);
|
|
31
|
+
}
|
|
32
|
+
function scoreStorageRoot(rootDir) {
|
|
33
|
+
let score = 0;
|
|
34
|
+
if (fs.existsSync(path.join(rootDir, "bot-storage.json"))) score += 8;
|
|
35
|
+
if (fs.existsSync(path.join(rootDir, "crypto"))) score += 8;
|
|
36
|
+
if (fs.existsSync(path.join(rootDir, THREAD_BINDINGS_FILENAME))) score += 4;
|
|
37
|
+
if (fs.existsSync(path.join(rootDir, LEGACY_CRYPTO_MIGRATION_FILENAME))) score += 3;
|
|
38
|
+
if (fs.existsSync(path.join(rootDir, RECOVERY_KEY_FILENAME))) score += 2;
|
|
39
|
+
if (fs.existsSync(path.join(rootDir, IDB_SNAPSHOT_FILENAME))) score += 2;
|
|
40
|
+
if (fs.existsSync(path.join(rootDir, STORAGE_META_FILENAME))) score += 1;
|
|
41
|
+
return score;
|
|
42
|
+
}
|
|
43
|
+
function resolveStorageRootMtimeMs(rootDir) {
|
|
44
|
+
try {
|
|
45
|
+
return fs.statSync(rootDir).mtimeMs;
|
|
46
|
+
} catch {
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function readStoredRootMetadata(rootDir) {
|
|
51
|
+
const metadata = {};
|
|
52
|
+
const parsed = loadJsonFile(path.join(rootDir, STORAGE_META_FILENAME));
|
|
53
|
+
if (parsed) {
|
|
54
|
+
if (typeof parsed.homeserver === "string" && parsed.homeserver.trim()) metadata.homeserver = parsed.homeserver.trim();
|
|
55
|
+
if (typeof parsed.userId === "string" && parsed.userId.trim()) metadata.userId = parsed.userId.trim();
|
|
56
|
+
if (typeof parsed.accountId === "string" && parsed.accountId.trim()) metadata.accountId = parsed.accountId.trim();
|
|
57
|
+
if (typeof parsed.accessTokenHash === "string" && parsed.accessTokenHash.trim()) metadata.accessTokenHash = parsed.accessTokenHash.trim();
|
|
58
|
+
if (typeof parsed.deviceId === "string" && parsed.deviceId.trim()) metadata.deviceId = parsed.deviceId.trim();
|
|
59
|
+
if (parsed.currentTokenStateClaimed === true) metadata.currentTokenStateClaimed = true;
|
|
60
|
+
if (typeof parsed.createdAt === "string" && parsed.createdAt.trim()) metadata.createdAt = parsed.createdAt.trim();
|
|
61
|
+
}
|
|
62
|
+
const verification = loadJsonFile(path.join(rootDir, STARTUP_VERIFICATION_FILENAME));
|
|
63
|
+
if (!metadata.deviceId && typeof verification?.deviceId === "string" && verification.deviceId.trim()) metadata.deviceId = verification.deviceId.trim();
|
|
64
|
+
return metadata;
|
|
65
|
+
}
|
|
66
|
+
function isCompatibleStorageRoot(params) {
|
|
67
|
+
const metadata = readStoredRootMetadata(params.candidateRootDir);
|
|
68
|
+
if (metadata.homeserver && metadata.homeserver !== params.homeserver) return false;
|
|
69
|
+
if (metadata.userId && metadata.userId !== params.userId) return false;
|
|
70
|
+
if (metadata.accountId && normalizeAccountId(metadata.accountId) !== normalizeAccountId(params.accountKey)) return false;
|
|
71
|
+
if (params.deviceId && metadata.deviceId && metadata.deviceId.trim() && metadata.deviceId.trim() !== params.deviceId.trim()) return false;
|
|
72
|
+
if (params.requireExplicitDeviceMatch && params.deviceId && (!metadata.deviceId || metadata.deviceId.trim() !== params.deviceId.trim())) return false;
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
function resolvePreferredMatrixStorageRoot(params) {
|
|
76
|
+
const parentDir = path.dirname(params.canonicalRootDir);
|
|
77
|
+
const bestCurrentScore = scoreStorageRoot(params.canonicalRootDir);
|
|
78
|
+
let best = {
|
|
79
|
+
rootDir: params.canonicalRootDir,
|
|
80
|
+
tokenHash: params.canonicalTokenHash,
|
|
81
|
+
score: bestCurrentScore,
|
|
82
|
+
mtimeMs: resolveStorageRootMtimeMs(params.canonicalRootDir)
|
|
83
|
+
};
|
|
84
|
+
if (!params.deviceId?.trim()) return {
|
|
85
|
+
rootDir: best.rootDir,
|
|
86
|
+
tokenHash: best.tokenHash
|
|
87
|
+
};
|
|
88
|
+
const canonicalMetadata = readStoredRootMetadata(params.canonicalRootDir);
|
|
89
|
+
if (canonicalMetadata.accessTokenHash === params.canonicalTokenHash && canonicalMetadata.deviceId?.trim() === params.deviceId.trim() && canonicalMetadata.currentTokenStateClaimed === true) return {
|
|
90
|
+
rootDir: best.rootDir,
|
|
91
|
+
tokenHash: best.tokenHash
|
|
92
|
+
};
|
|
93
|
+
let siblingEntries = [];
|
|
94
|
+
try {
|
|
95
|
+
siblingEntries = fs.readdirSync(parentDir, { withFileTypes: true });
|
|
96
|
+
} catch {
|
|
97
|
+
return {
|
|
98
|
+
rootDir: best.rootDir,
|
|
99
|
+
tokenHash: best.tokenHash
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
for (const entry of siblingEntries) {
|
|
103
|
+
if (!entry.isDirectory()) continue;
|
|
104
|
+
if (entry.name === params.canonicalTokenHash) continue;
|
|
105
|
+
const candidateRootDir = path.join(parentDir, entry.name);
|
|
106
|
+
if (!isCompatibleStorageRoot({
|
|
107
|
+
candidateRootDir,
|
|
108
|
+
homeserver: params.homeserver,
|
|
109
|
+
userId: params.userId,
|
|
110
|
+
accountKey: params.accountKey,
|
|
111
|
+
deviceId: params.deviceId,
|
|
112
|
+
requireExplicitDeviceMatch: Boolean(params.deviceId)
|
|
113
|
+
})) continue;
|
|
114
|
+
const candidateScore = scoreStorageRoot(candidateRootDir);
|
|
115
|
+
if (candidateScore <= 0) continue;
|
|
116
|
+
const candidateMtimeMs = resolveStorageRootMtimeMs(candidateRootDir);
|
|
117
|
+
if (candidateScore > best.score || best.rootDir !== params.canonicalRootDir && candidateScore === best.score && candidateMtimeMs > best.mtimeMs) best = {
|
|
118
|
+
rootDir: candidateRootDir,
|
|
119
|
+
tokenHash: entry.name,
|
|
120
|
+
score: candidateScore,
|
|
121
|
+
mtimeMs: candidateMtimeMs
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
rootDir: best.rootDir,
|
|
126
|
+
tokenHash: best.tokenHash
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function resolveMatrixStoragePaths(params) {
|
|
130
|
+
const env = params.env ?? process.env;
|
|
131
|
+
const canonical = resolveMatrixAccountStorageRoot({
|
|
132
|
+
stateDir: params.stateDir ?? getMatrixRuntime().state.resolveStateDir(env, os.homedir),
|
|
133
|
+
homeserver: params.homeserver,
|
|
134
|
+
userId: params.userId,
|
|
135
|
+
accessToken: params.accessToken,
|
|
136
|
+
accountId: params.accountId
|
|
137
|
+
});
|
|
138
|
+
const { rootDir, tokenHash } = resolvePreferredMatrixStorageRoot({
|
|
139
|
+
canonicalRootDir: canonical.rootDir,
|
|
140
|
+
canonicalTokenHash: canonical.tokenHash,
|
|
141
|
+
homeserver: params.homeserver,
|
|
142
|
+
userId: params.userId,
|
|
143
|
+
accountKey: canonical.accountKey,
|
|
144
|
+
deviceId: params.deviceId
|
|
145
|
+
});
|
|
146
|
+
return {
|
|
147
|
+
rootDir,
|
|
148
|
+
storagePath: path.join(rootDir, "bot-storage.json"),
|
|
149
|
+
cryptoPath: path.join(rootDir, "crypto"),
|
|
150
|
+
metaPath: path.join(rootDir, STORAGE_META_FILENAME),
|
|
151
|
+
recoveryKeyPath: path.join(rootDir, "recovery-key.json"),
|
|
152
|
+
idbSnapshotPath: path.join(rootDir, IDB_SNAPSHOT_FILENAME),
|
|
153
|
+
accountKey: canonical.accountKey,
|
|
154
|
+
tokenHash
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function resolveMatrixStateFilePath(params) {
|
|
158
|
+
const storagePaths = resolveMatrixStoragePaths({
|
|
159
|
+
homeserver: params.auth.homeserver,
|
|
160
|
+
userId: params.auth.userId,
|
|
161
|
+
accessToken: params.auth.accessToken,
|
|
162
|
+
accountId: params.accountId ?? params.auth.accountId,
|
|
163
|
+
deviceId: params.auth.deviceId,
|
|
164
|
+
env: params.env,
|
|
165
|
+
stateDir: params.stateDir
|
|
166
|
+
});
|
|
167
|
+
return path.join(storagePaths.rootDir, params.filename);
|
|
168
|
+
}
|
|
169
|
+
async function maybeMigrateLegacyStorage(params) {
|
|
170
|
+
const legacy = resolveLegacyStoragePaths(params.env);
|
|
171
|
+
const hasLegacyStorage = fs.existsSync(legacy.storagePath);
|
|
172
|
+
const hasLegacyCrypto = fs.existsSync(legacy.cryptoPath);
|
|
173
|
+
if (!hasLegacyStorage && !hasLegacyCrypto) return;
|
|
174
|
+
const hasTargetStorage = fs.existsSync(params.storagePaths.storagePath);
|
|
175
|
+
const hasTargetCrypto = fs.existsSync(params.storagePaths.cryptoPath);
|
|
176
|
+
const shouldMigrateStorage = hasLegacyStorage && !hasTargetStorage;
|
|
177
|
+
const shouldMigrateCrypto = hasLegacyCrypto && !hasTargetCrypto;
|
|
178
|
+
if (!shouldMigrateStorage && !shouldMigrateCrypto) return;
|
|
179
|
+
assertLegacyMigrationAccountSelection({ accountKey: params.storagePaths.accountKey });
|
|
180
|
+
const logger = getMatrixRuntime().logging.getChildLogger({ module: "matrix-storage" });
|
|
181
|
+
const { maybeCreateMatrixMigrationSnapshot } = await import("./migration-snapshot.runtime-BLcy_Nvw.js");
|
|
182
|
+
await maybeCreateMatrixMigrationSnapshot({
|
|
183
|
+
trigger: "matrix-client-fallback",
|
|
184
|
+
env: params.env,
|
|
185
|
+
log: logger
|
|
186
|
+
});
|
|
187
|
+
fs.mkdirSync(params.storagePaths.rootDir, { recursive: true });
|
|
188
|
+
const moved = [];
|
|
189
|
+
const skippedExistingTargets = [];
|
|
190
|
+
try {
|
|
191
|
+
if (shouldMigrateStorage) moveLegacyStoragePathOrThrow({
|
|
192
|
+
sourcePath: legacy.storagePath,
|
|
193
|
+
targetPath: params.storagePaths.storagePath,
|
|
194
|
+
label: "sync store",
|
|
195
|
+
moved
|
|
196
|
+
});
|
|
197
|
+
else if (hasLegacyStorage) skippedExistingTargets.push(`- sync store remains at ${legacy.storagePath} because ${params.storagePaths.storagePath} already exists`);
|
|
198
|
+
if (shouldMigrateCrypto) moveLegacyStoragePathOrThrow({
|
|
199
|
+
sourcePath: legacy.cryptoPath,
|
|
200
|
+
targetPath: params.storagePaths.cryptoPath,
|
|
201
|
+
label: "crypto store",
|
|
202
|
+
moved
|
|
203
|
+
});
|
|
204
|
+
else if (hasLegacyCrypto) skippedExistingTargets.push(`- crypto store remains at ${legacy.cryptoPath} because ${params.storagePaths.cryptoPath} already exists`);
|
|
205
|
+
} catch (err) {
|
|
206
|
+
const rollbackError = rollbackLegacyMoves(moved);
|
|
207
|
+
throw new Error(rollbackError ? `Failed migrating legacy Matrix client storage: ${String(err)}. Rollback also failed: ${rollbackError}` : `Failed migrating legacy Matrix client storage: ${String(err)}`, { cause: err });
|
|
208
|
+
}
|
|
209
|
+
if (moved.length > 0) logger.info(`matrix: migrated legacy client storage into ${params.storagePaths.rootDir}\n${moved.map((entry) => `- ${entry.label}: ${entry.sourcePath} -> ${entry.targetPath}`).join("\n")}`);
|
|
210
|
+
if (skippedExistingTargets.length > 0) logger.warn?.(`matrix: legacy client storage still exists in the flat path because some account-scoped targets already existed.\n${skippedExistingTargets.join("\n")}`);
|
|
211
|
+
}
|
|
212
|
+
function moveLegacyStoragePathOrThrow(params) {
|
|
213
|
+
if (!fs.existsSync(params.sourcePath)) return;
|
|
214
|
+
if (fs.existsSync(params.targetPath)) throw new Error(`legacy Matrix ${params.label} target already exists (${params.targetPath}); refusing to overwrite it automatically`);
|
|
215
|
+
fs.renameSync(params.sourcePath, params.targetPath);
|
|
216
|
+
params.moved.push({
|
|
217
|
+
sourcePath: params.sourcePath,
|
|
218
|
+
targetPath: params.targetPath,
|
|
219
|
+
label: params.label
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
function rollbackLegacyMoves(moved) {
|
|
223
|
+
for (const entry of moved.toReversed()) try {
|
|
224
|
+
if (!fs.existsSync(entry.targetPath) || fs.existsSync(entry.sourcePath)) continue;
|
|
225
|
+
fs.renameSync(entry.targetPath, entry.sourcePath);
|
|
226
|
+
} catch (err) {
|
|
227
|
+
return `${entry.label} (${entry.targetPath} -> ${entry.sourcePath}): ${String(err)}`;
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
function writeStoredRootMetadata(metaPath, payload) {
|
|
232
|
+
try {
|
|
233
|
+
saveJsonFile(metaPath, payload);
|
|
234
|
+
return true;
|
|
235
|
+
} catch {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function writeStorageMeta(params) {
|
|
240
|
+
const existing = readStoredRootMetadata(params.storagePaths.rootDir);
|
|
241
|
+
return writeStoredRootMetadata(params.storagePaths.metaPath, {
|
|
242
|
+
homeserver: params.homeserver,
|
|
243
|
+
userId: params.userId,
|
|
244
|
+
accountId: params.accountId ?? DEFAULT_ACCOUNT_KEY,
|
|
245
|
+
accessTokenHash: params.storagePaths.tokenHash,
|
|
246
|
+
deviceId: params.deviceId ?? null,
|
|
247
|
+
currentTokenStateClaimed: params.currentTokenStateClaimed ?? existing.currentTokenStateClaimed === true,
|
|
248
|
+
createdAt: existing.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
function claimCurrentTokenStorageState(params) {
|
|
252
|
+
const metadata = readStoredRootMetadata(params.rootDir);
|
|
253
|
+
if (!metadata.accessTokenHash?.trim()) return false;
|
|
254
|
+
return writeStoredRootMetadata(path.join(params.rootDir, STORAGE_META_FILENAME), {
|
|
255
|
+
homeserver: metadata.homeserver,
|
|
256
|
+
userId: metadata.userId,
|
|
257
|
+
accountId: metadata.accountId ?? DEFAULT_ACCOUNT_KEY,
|
|
258
|
+
accessTokenHash: metadata.accessTokenHash,
|
|
259
|
+
deviceId: metadata.deviceId ?? null,
|
|
260
|
+
currentTokenStateClaimed: true,
|
|
261
|
+
createdAt: metadata.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
function repairCurrentTokenStorageMetaDeviceId(params) {
|
|
265
|
+
return writeStorageMeta({
|
|
266
|
+
storagePaths: resolveMatrixStoragePaths({
|
|
267
|
+
homeserver: params.homeserver,
|
|
268
|
+
userId: params.userId,
|
|
269
|
+
accessToken: params.accessToken,
|
|
270
|
+
accountId: params.accountId,
|
|
271
|
+
env: params.env,
|
|
272
|
+
stateDir: params.stateDir
|
|
273
|
+
}),
|
|
274
|
+
homeserver: params.homeserver,
|
|
275
|
+
userId: params.userId,
|
|
276
|
+
accountId: params.accountId,
|
|
277
|
+
deviceId: params.deviceId
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
//#endregion
|
|
281
|
+
export { resolveMatrixStoragePaths as a, resolveMatrixStateFilePath as i, maybeMigrateLegacyStorage as n, writeStorageMeta as o, repairCurrentTokenStorageMetaDeviceId as r, claimCurrentTokenStorageState as t };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "klaw/plugin-sdk/account-id";
|
|
2
|
+
import { normalizeLowercaseStringOrEmpty } from "klaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import crypto from "node:crypto";
|
|
5
|
+
//#region extensions/matrix/src/storage-paths.ts
|
|
6
|
+
function sanitizeMatrixPathSegment(value) {
|
|
7
|
+
return normalizeLowercaseStringOrEmpty(value).replace(/[^a-z0-9._-]+/g, "_").replace(/^_+|_+$/g, "") || "unknown";
|
|
8
|
+
}
|
|
9
|
+
function resolveMatrixHomeserverKey(homeserver) {
|
|
10
|
+
try {
|
|
11
|
+
const url = new URL(homeserver);
|
|
12
|
+
if (url.host) return sanitizeMatrixPathSegment(url.host);
|
|
13
|
+
} catch {}
|
|
14
|
+
return sanitizeMatrixPathSegment(homeserver);
|
|
15
|
+
}
|
|
16
|
+
function hashMatrixAccessToken(accessToken) {
|
|
17
|
+
return crypto.createHash("sha256").update(accessToken).digest("hex").slice(0, 16);
|
|
18
|
+
}
|
|
19
|
+
function resolveMatrixCredentialsFilename(accountId) {
|
|
20
|
+
const normalized = normalizeAccountId(accountId);
|
|
21
|
+
return normalized === DEFAULT_ACCOUNT_ID ? "credentials.json" : `credentials-${normalized}.json`;
|
|
22
|
+
}
|
|
23
|
+
function resolveMatrixCredentialsDir(stateDir) {
|
|
24
|
+
return path.join(stateDir, "credentials", "matrix");
|
|
25
|
+
}
|
|
26
|
+
function resolveMatrixCredentialsPath(params) {
|
|
27
|
+
return path.join(resolveMatrixCredentialsDir(params.stateDir), resolveMatrixCredentialsFilename(params.accountId));
|
|
28
|
+
}
|
|
29
|
+
function resolveMatrixLegacyFlatStoreRoot(stateDir) {
|
|
30
|
+
return path.join(stateDir, "matrix");
|
|
31
|
+
}
|
|
32
|
+
function resolveMatrixLegacyFlatStoragePaths(stateDir) {
|
|
33
|
+
const rootDir = resolveMatrixLegacyFlatStoreRoot(stateDir);
|
|
34
|
+
return {
|
|
35
|
+
rootDir,
|
|
36
|
+
storagePath: path.join(rootDir, "bot-storage.json"),
|
|
37
|
+
cryptoPath: path.join(rootDir, "crypto")
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function resolveMatrixAccountStorageRoot(params) {
|
|
41
|
+
const accountKey = sanitizeMatrixPathSegment(params.accountId ?? DEFAULT_ACCOUNT_ID);
|
|
42
|
+
const userKey = sanitizeMatrixPathSegment(params.userId);
|
|
43
|
+
const serverKey = resolveMatrixHomeserverKey(params.homeserver);
|
|
44
|
+
const tokenHash = hashMatrixAccessToken(params.accessToken);
|
|
45
|
+
return {
|
|
46
|
+
rootDir: path.join(params.stateDir, "matrix", "accounts", accountKey, `${serverKey}__${userKey}`, tokenHash),
|
|
47
|
+
accountKey,
|
|
48
|
+
tokenHash
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { resolveMatrixCredentialsPath as a, resolveMatrixLegacyFlatStoreRoot as c, resolveMatrixCredentialsFilename as i, sanitizeMatrixPathSegment as l, resolveMatrixAccountStorageRoot as n, resolveMatrixHomeserverKey as o, resolveMatrixCredentialsDir as r, resolveMatrixLegacyFlatStoragePaths as s, hashMatrixAccessToken as t };
|