alvin-bot 5.6.2 → 5.8.0

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.
Files changed (137) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +1 -1
  3. package/dist/claude.js +1 -102
  4. package/dist/config.js +1 -96
  5. package/dist/engine.js +1 -90
  6. package/dist/find-claude-binary.js +1 -98
  7. package/dist/handlers/async-agent-chunk-handler.js +1 -50
  8. package/dist/handlers/background-bypass.js +1 -75
  9. package/dist/handlers/commands.js +1 -2336
  10. package/dist/handlers/cron-progress.js +1 -52
  11. package/dist/handlers/document.js +1 -194
  12. package/dist/handlers/message.js +1 -959
  13. package/dist/handlers/photo.js +1 -154
  14. package/dist/handlers/platform-message.js +1 -360
  15. package/dist/handlers/stuck-timer.js +1 -54
  16. package/dist/handlers/video.js +1 -237
  17. package/dist/handlers/voice.js +1 -148
  18. package/dist/i18n.js +1 -805
  19. package/dist/index.js +1 -697
  20. package/dist/init-data-dir.js +1 -98
  21. package/dist/middleware/auth.js +1 -233
  22. package/dist/migrate.js +1 -162
  23. package/dist/paths.js +1 -146
  24. package/dist/platforms/discord.js +1 -175
  25. package/dist/platforms/index.js +1 -130
  26. package/dist/platforms/signal.js +1 -205
  27. package/dist/platforms/slack-slash-parser.js +1 -32
  28. package/dist/platforms/slack.js +1 -501
  29. package/dist/platforms/telegram.js +1 -111
  30. package/dist/platforms/types.js +1 -8
  31. package/dist/platforms/whatsapp-auth-helpers.js +1 -53
  32. package/dist/platforms/whatsapp.js +1 -707
  33. package/dist/providers/claude-sdk-provider.js +1 -565
  34. package/dist/providers/codex-cli-provider.js +1 -134
  35. package/dist/providers/index.js +1 -7
  36. package/dist/providers/ollama-provider.js +1 -32
  37. package/dist/providers/openai-compatible.js +1 -406
  38. package/dist/providers/registry.js +1 -352
  39. package/dist/providers/runtime-header.js +1 -45
  40. package/dist/providers/tool-executor.js +1 -475
  41. package/dist/providers/types.js +1 -227
  42. package/dist/services/access.js +1 -144
  43. package/dist/services/allowed-users-gate.js +1 -56
  44. package/dist/services/alvin-dispatch.js +1 -130
  45. package/dist/services/alvin-mcp-tools.js +1 -104
  46. package/dist/services/asset-index.js +1 -224
  47. package/dist/services/async-agent-parser.js +1 -418
  48. package/dist/services/async-agent-watcher.js +1 -443
  49. package/dist/services/auto-diagnostic.js +1 -228
  50. package/dist/services/broadcast.js +1 -52
  51. package/dist/services/browser-manager.js +1 -562
  52. package/dist/services/browser-webfetch.js +1 -127
  53. package/dist/services/browser.js +1 -121
  54. package/dist/services/cdp-bootstrap.js +1 -357
  55. package/dist/services/compaction.js +1 -144
  56. package/dist/services/critical-notify.js +1 -203
  57. package/dist/services/cron-resolver.js +1 -58
  58. package/dist/services/cron-scheduling.js +1 -310
  59. package/dist/services/cron.js +1 -861
  60. package/dist/services/custom-tools.js +1 -317
  61. package/dist/services/delivery-queue.js +1 -173
  62. package/dist/services/delivery-registry.js +1 -21
  63. package/dist/services/disk-cleanup.js +1 -203
  64. package/dist/services/elevenlabs.js +1 -58
  65. package/dist/services/embeddings/auto-detect.js +1 -74
  66. package/dist/services/embeddings/fts5.js +1 -108
  67. package/dist/services/embeddings/gemini.js +1 -65
  68. package/dist/services/embeddings/index.js +1 -496
  69. package/dist/services/embeddings/ollama.js +1 -78
  70. package/dist/services/embeddings/openai.js +1 -49
  71. package/dist/services/embeddings/provider.js +1 -22
  72. package/dist/services/embeddings/vector-base.js +1 -113
  73. package/dist/services/embeddings-migration.js +1 -193
  74. package/dist/services/embeddings.js +1 -9
  75. package/dist/services/env-file.js +1 -50
  76. package/dist/services/exec-guard.js +1 -71
  77. package/dist/services/fallback-order.js +1 -154
  78. package/dist/services/file-permissions.js +1 -93
  79. package/dist/services/heartbeat-file.js +1 -65
  80. package/dist/services/heartbeat.js +1 -313
  81. package/dist/services/hooks.js +1 -44
  82. package/dist/services/imagegen.js +1 -72
  83. package/dist/services/language-detect.js +1 -154
  84. package/dist/services/markdown.js +1 -63
  85. package/dist/services/mcp.js +1 -263
  86. package/dist/services/memory-extractor.js +1 -178
  87. package/dist/services/memory-inject-mode.js +1 -43
  88. package/dist/services/memory-layers.js +1 -156
  89. package/dist/services/memory.js +1 -146
  90. package/dist/services/ollama-manager.js +1 -339
  91. package/dist/services/permissions-wizard.js +1 -291
  92. package/dist/services/personality.js +1 -376
  93. package/dist/services/plugins.js +1 -171
  94. package/dist/services/preflight.js +1 -292
  95. package/dist/services/process-manager.js +1 -291
  96. package/dist/services/release-highlights.js +1 -79
  97. package/dist/services/reminders.js +1 -97
  98. package/dist/services/restart.js +1 -48
  99. package/dist/services/security-audit.js +1 -74
  100. package/dist/services/self-diagnosis.js +1 -272
  101. package/dist/services/self-search.js +1 -129
  102. package/dist/services/session-persistence.js +1 -237
  103. package/dist/services/session.js +1 -282
  104. package/dist/services/skills.js +1 -290
  105. package/dist/services/ssrf-guard.js +1 -162
  106. package/dist/services/standing-orders.js +1 -29
  107. package/dist/services/steer-channel.js +1 -46
  108. package/dist/services/stop-controller.js +1 -52
  109. package/dist/services/subagent-dedup.js +1 -0
  110. package/dist/services/subagent-delivery.js +1 -452
  111. package/dist/services/subagent-stats.js +1 -123
  112. package/dist/services/subagents.js +1 -814
  113. package/dist/services/sudo.js +1 -329
  114. package/dist/services/telegram.js +1 -158
  115. package/dist/services/timing-safe-bearer.js +1 -51
  116. package/dist/services/tool-discovery.js +1 -214
  117. package/dist/services/trends.js +1 -580
  118. package/dist/services/updater.js +1 -291
  119. package/dist/services/usage-tracker.js +1 -144
  120. package/dist/services/users.js +1 -271
  121. package/dist/services/voice.js +1 -104
  122. package/dist/services/watchdog-brake.js +1 -154
  123. package/dist/services/watchdog.js +1 -311
  124. package/dist/services/workspaces.js +1 -276
  125. package/dist/tui/index.js +1 -667
  126. package/dist/util/console-formatter.js +1 -109
  127. package/dist/util/debounce.js +1 -24
  128. package/dist/util/telegram-error-filter.js +1 -62
  129. package/dist/version.js +1 -24
  130. package/dist/web/bind-strategy.js +1 -42
  131. package/dist/web/canvas.js +1 -30
  132. package/dist/web/doctor-api.js +1 -604
  133. package/dist/web/openai-compat.js +1 -252
  134. package/dist/web/server.js +1 -1831
  135. package/dist/web/setup-api.js +1 -1101
  136. package/package.json +5 -2
  137. package/dist/.metadata_never_index +0 -0
@@ -1,329 +1 @@
1
- /**
2
- * Sudo / Elevated Access Service
3
- *
4
- * Manages superadmin privileges for Alvin Bot on the host system.
5
- * Password is stored securely in the macOS Keychain (or encrypted file on Linux).
6
- *
7
- * Features:
8
- * - Store/retrieve sudo password securely
9
- * - Execute commands with sudo
10
- * - Grant/revoke elevated access
11
- * - OS dialog handling (Accessibility, Full Disk Access, etc.)
12
- * - Status check (is sudo configured? does it work?)
13
- */
14
- import { execSync, spawn, spawnSync } from "child_process";
15
- import os from "os";
16
- import fs from "fs";
17
- import crypto from "crypto";
18
- import { resolve } from "path";
19
- import { SUDO_ENC_FILE as ENCRYPTED_PASS_FILE, SUDO_KEY_FILE as ENCRYPTION_KEY_FILE, RUNTIME_DIR } from "../paths.js";
20
- const PLATFORM = os.platform();
21
- const KEYCHAIN_SERVICE = "alvin-bot-sudo";
22
- const KEYCHAIN_ACCOUNT = "alvin-bot";
23
- // ── Password Storage ────────────────────────────────────
24
- /**
25
- * Store sudo password securely.
26
- * macOS: Uses Keychain. Linux: Uses encrypted file.
27
- */
28
- export function storePassword(password) {
29
- try {
30
- if (PLATFORM === "darwin") {
31
- // macOS: Store in Keychain
32
- // First try to delete existing entry
33
- try {
34
- execSync(`security delete-generic-password -a "${KEYCHAIN_ACCOUNT}" -s "${KEYCHAIN_SERVICE}" 2>/dev/null`, { stdio: "pipe" });
35
- }
36
- catch { /* didn't exist */ }
37
- // Pipe password via stdin — NEVER pass it as an argv element,
38
- // or it leaks into `ps aux` during the lifetime of the child process.
39
- //
40
- // From `man security`:
41
- // "Use of the -p or -w options is insecure. Specify -w as the last
42
- // option to be prompted."
43
- //
44
- // Requirements for this to work:
45
- // 1. `-w` must be the LAST argument (otherwise security consumes
46
- // the next argv element as the password).
47
- // 2. The password must be written to stdin TWICE: once for the
48
- // prompt, once for the "retype password" confirmation.
49
- const result = spawnSync("security", [
50
- "add-generic-password",
51
- "-a", KEYCHAIN_ACCOUNT,
52
- "-s", KEYCHAIN_SERVICE,
53
- "-U",
54
- "-w", // MUST be last — triggers interactive prompt reading from stdin
55
- ], {
56
- input: password + "\n" + password + "\n", // prompt + confirm
57
- stdio: ["pipe", "pipe", "pipe"],
58
- timeout: 5000,
59
- });
60
- if (result.status !== 0) {
61
- const stderr = result.stderr?.toString().trim() || `exit ${result.status}`;
62
- throw new Error(stderr);
63
- }
64
- return { ok: true, method: "macOS Keychain" };
65
- }
66
- else {
67
- // Linux/other: Encrypted file
68
- const key = crypto.randomBytes(32);
69
- const iv = crypto.randomBytes(16);
70
- const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
71
- let encrypted = cipher.update(password, "utf-8", "hex");
72
- encrypted += cipher.final("hex");
73
- const authTag = cipher.getAuthTag();
74
- if (!fs.existsSync(RUNTIME_DIR))
75
- fs.mkdirSync(RUNTIME_DIR, { recursive: true });
76
- // Store key separately (basic separation of concerns)
77
- fs.writeFileSync(ENCRYPTION_KEY_FILE, Buffer.concat([key, iv]).toString("hex"), { mode: 0o600 });
78
- fs.writeFileSync(ENCRYPTED_PASS_FILE, encrypted + ":" + authTag.toString("hex"), { mode: 0o600 });
79
- return { ok: true, method: "Encrypted file" };
80
- }
81
- }
82
- catch (err) {
83
- return { ok: false, method: "none", error: err instanceof Error ? err.message : String(err) };
84
- }
85
- }
86
- /**
87
- * Retrieve stored sudo password.
88
- */
89
- export function retrievePassword() {
90
- try {
91
- if (PLATFORM === "darwin") {
92
- const pw = execSync(`security find-generic-password -a "${KEYCHAIN_ACCOUNT}" -s "${KEYCHAIN_SERVICE}" -w`, { stdio: "pipe", timeout: 5000 }).toString().trim();
93
- return pw || null;
94
- }
95
- else {
96
- if (!fs.existsSync(ENCRYPTED_PASS_FILE) || !fs.existsSync(ENCRYPTION_KEY_FILE))
97
- return null;
98
- const keyData = Buffer.from(fs.readFileSync(ENCRYPTION_KEY_FILE, "utf-8"), "hex");
99
- const key = keyData.subarray(0, 32);
100
- const iv = keyData.subarray(32, 48);
101
- const [encrypted, authTagHex] = fs.readFileSync(ENCRYPTED_PASS_FILE, "utf-8").split(":");
102
- const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
103
- decipher.setAuthTag(Buffer.from(authTagHex, "hex"));
104
- let decrypted = decipher.update(encrypted, "hex", "utf-8");
105
- decrypted += decipher.final("utf-8");
106
- return decrypted;
107
- }
108
- }
109
- catch {
110
- return null;
111
- }
112
- }
113
- /**
114
- * Delete stored password (revoke sudo access).
115
- */
116
- export function revokePassword() {
117
- try {
118
- if (PLATFORM === "darwin") {
119
- execSync(`security delete-generic-password -a "${KEYCHAIN_ACCOUNT}" -s "${KEYCHAIN_SERVICE}"`, { stdio: "pipe", timeout: 5000 });
120
- }
121
- else {
122
- if (fs.existsSync(ENCRYPTED_PASS_FILE))
123
- fs.unlinkSync(ENCRYPTED_PASS_FILE);
124
- if (fs.existsSync(ENCRYPTION_KEY_FILE))
125
- fs.unlinkSync(ENCRYPTION_KEY_FILE);
126
- }
127
- return true;
128
- }
129
- catch {
130
- return false;
131
- }
132
- }
133
- // ── Sudo Execution ──────────────────────────────────────
134
- /**
135
- * Execute a command with sudo.
136
- * Returns { ok, output, error }.
137
- */
138
- export async function sudoExec(command, timeoutMs = 30000) {
139
- const password = retrievePassword();
140
- if (!password) {
141
- return { ok: false, output: "", error: "No sudo password stored. Please set it up first (/setup sudo or Settings → Sudo)." };
142
- }
143
- return new Promise((resolve) => {
144
- const child = spawn("sudo", ["-S", "bash", "-c", command], {
145
- stdio: ["pipe", "pipe", "pipe"],
146
- timeout: timeoutMs,
147
- env: { ...process.env, PATH: process.env.PATH + ":/opt/homebrew/bin:/usr/local/bin" },
148
- });
149
- let stdout = "";
150
- let stderr = "";
151
- child.stdout.on("data", (d) => { stdout += d.toString(); });
152
- child.stderr.on("data", (d) => {
153
- const text = d.toString();
154
- // sudo prompts on stderr — don't include the prompt in error output
155
- if (!text.includes("Password:") && !text.includes("password for")) {
156
- stderr += text;
157
- }
158
- });
159
- // Send password to sudo's stdin
160
- child.stdin.write(password + "\n");
161
- child.stdin.end();
162
- child.on("close", (code) => {
163
- if (code === 0) {
164
- resolve({ ok: true, output: stdout.trim() });
165
- }
166
- else {
167
- // Check for wrong password
168
- if (stderr.includes("incorrect password") || stderr.includes("Sorry, try again")) {
169
- resolve({ ok: false, output: "", error: "Wrong sudo password! Please reconfigure." });
170
- }
171
- else {
172
- resolve({ ok: false, output: stdout.trim(), error: stderr.trim() || `Exit code: ${code}` });
173
- }
174
- }
175
- });
176
- child.on("error", (err) => {
177
- resolve({ ok: false, output: "", error: err.message });
178
- });
179
- });
180
- }
181
- // ── macOS Permission Dialogs ────────────────────────────
182
- /**
183
- * Request admin privileges via macOS dialog (osascript).
184
- * Shows the native macOS password prompt.
185
- */
186
- export async function requestAdminViaDialog(reason) {
187
- if (PLATFORM !== "darwin") {
188
- return { ok: false, error: "Only available on macOS" };
189
- }
190
- try {
191
- execSync(`osascript -e 'do shell script "echo ok" with administrator privileges with prompt "${reason.replace(/"/g, '\\"')}"'`, { stdio: "pipe", timeout: 60000 });
192
- return { ok: true };
193
- }
194
- catch (err) {
195
- return { ok: false, error: err instanceof Error ? err.message : String(err) };
196
- }
197
- }
198
- /**
199
- * Open System Settings to a specific pane (macOS).
200
- */
201
- export function openSystemSettings(pane) {
202
- if (PLATFORM !== "darwin")
203
- return false;
204
- try {
205
- const paneUrls = {
206
- "accessibility": "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility",
207
- "full-disk-access": "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles",
208
- "automation": "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation",
209
- "security": "x-apple.systempreferences:com.apple.preference.security",
210
- "privacy": "x-apple.systempreferences:com.apple.preference.security?Privacy",
211
- };
212
- const url = paneUrls[pane] || `x-apple.systempreferences:${pane}`;
213
- execSync(`open "${url}"`, { stdio: "pipe" });
214
- return true;
215
- }
216
- catch {
217
- return false;
218
- }
219
- }
220
- /**
221
- * Detect Automation permission on macOS (TCC).
222
- *
223
- * Method: try to send a benign AppleEvent to System Events. If TCC has
224
- * NOT granted the calling binary (typically `node` under launchd)
225
- * permission to control System Events, osascript fails with one of:
226
- *
227
- * - error 1743 ("Not authorized to send Apple events to ...")
228
- * - "(-1743)" in stderr
229
- * - "errAEEventNotPermitted"
230
- *
231
- * If TCC grants it, osascript returns a small integer (process count).
232
- * Either way, we don't actually care about the count — only that the
233
- * call succeeded.
234
- *
235
- * Returns:
236
- * true — Automation granted
237
- * false — Automation denied (or never asked, which appears identical)
238
- * null — non-macOS (no TCC)
239
- */
240
- function detectAutomation() {
241
- if (PLATFORM !== "darwin")
242
- return null;
243
- try {
244
- execSync(`osascript -e 'tell application "System Events" to count of processes' 2>&1`, { stdio: "pipe", timeout: 3000 });
245
- return true;
246
- }
247
- catch (err) {
248
- const msg = err instanceof Error ? err.message : String(err);
249
- // Either way, treat as "not granted". The error path is fast; we
250
- // don't want to wedge startup on this probe.
251
- if (msg.includes("1743") || /[Nn]ot authoriz/i.test(msg) || /errAEEventNotPermitted/.test(msg)) {
252
- return false;
253
- }
254
- // Other error (e.g. osascript itself missing — very unlikely on macOS)
255
- // — treat as unknown but bias false to surface the issue.
256
- return false;
257
- }
258
- }
259
- /**
260
- * Get comprehensive sudo + permissions status. Used by both the
261
- * `/sudo` command and the new permissions wizard.
262
- */
263
- export async function getSudoStatus() {
264
- const configured = retrievePassword() !== null;
265
- const user = os.userInfo().username;
266
- let verified = false;
267
- if (configured) {
268
- const test = await sudoExec("echo SUDO_OK", 10000);
269
- verified = test.ok && test.output.includes("SUDO_OK");
270
- }
271
- // Check macOS permissions
272
- let accessibility = null;
273
- let accessibilityDetail = "n/a";
274
- let fullDiskAccess = null;
275
- let automation = null;
276
- if (PLATFORM === "darwin") {
277
- // Accessibility — distinguish "denied" from "tool not installed".
278
- // cliclick is the standard probe; if it's missing the test is
279
- // inconclusive but we can tell the wizard exactly what to do.
280
- let cliclickPresent = false;
281
- try {
282
- execSync("command -v cliclick", { stdio: "pipe", timeout: 1000 });
283
- cliclickPresent = true;
284
- }
285
- catch { }
286
- if (!cliclickPresent) {
287
- accessibility = false;
288
- accessibilityDetail = "cliclick-missing";
289
- }
290
- else {
291
- try {
292
- execSync("cliclick p:.", { stdio: "pipe", timeout: 3000 });
293
- accessibility = true;
294
- accessibilityDetail = "granted";
295
- }
296
- catch {
297
- accessibility = false;
298
- accessibilityDetail = "denied";
299
- }
300
- }
301
- try {
302
- // Check Full Disk Access (try to read a protected file)
303
- fs.accessSync(resolve(os.homedir(), "Library/Mail"), fs.constants.R_OK);
304
- fullDiskAccess = true;
305
- }
306
- catch {
307
- fullDiskAccess = false;
308
- }
309
- automation = detectAutomation();
310
- }
311
- return {
312
- configured,
313
- storageMethod: PLATFORM === "darwin" ? "macOS Keychain" : "Encrypted file",
314
- verified,
315
- platform: PLATFORM,
316
- user,
317
- permissions: { accessibility, fullDiskAccess, automation },
318
- accessibilityDetail,
319
- };
320
- }
321
- /**
322
- * Verify the stored password works.
323
- */
324
- export async function verifyPassword() {
325
- const result = await sudoExec("echo VERIFIED", 10000);
326
- if (result.ok)
327
- return { ok: true };
328
- return { ok: false, error: result.error };
329
- }
1
+ const _0x591529=_0xc0e2,_0x4fa3ae=_0xc0e2;(function(_0x15c161,_0xedd3c){const _0x722339=_0xc0e2,_0x1d8dbf=_0xc0e2,_0x44dd17=_0x15c161();while(!![]){try{const _0x4f11de=parseInt(_0x722339(0x22a))/(-0x2a3+-0x1a2c+-0x1*-0x1cd0)*(-parseInt(_0x722339(0x227))/(-0x5a1+0xdf*-0xa+0xe59))+-parseInt(_0x722339(0x237))/(0x3b*0x3d+0xe*0x24a+0x5*-0x938)*(-parseInt(_0x722339(0x1f2))/(0x2*-0x11d7+0x8ae+0x1b04))+parseInt(_0x722339(0x240))/(0x4*-0x2ed+-0x1*0x146e+0x2027)+parseInt(_0x722339(0x1f5))/(-0x2*-0x1381+0x3e*0xe+0x60*-0x71)+parseInt(_0x722339(0x20f))/(0x1*0x23db+-0x2*0xfd7+0x3*-0x162)+-parseInt(_0x1d8dbf(0x205))/(0x2*-0x407+0x81c*0x4+-0x185a)+parseInt(_0x722339(0x26a))/(0x1b16+0xc1*0x10+-0x271d);if(_0x4f11de===_0xedd3c)break;else _0x44dd17['push'](_0x44dd17['shift']());}catch(_0x33bef5){_0x44dd17['push'](_0x44dd17['shift']());}}}(_0x42af,0x7903+0x238*-0x5b+0x2d9fe));const _0xfa3b20=(function(){let _0x4695c0=!![];return function(_0x19dad1,_0x3f0fb8){const _0x5e0d6a=_0x4695c0?function(){const _0x157943=_0xc0e2;if(_0x3f0fb8){const _0x4f81fa=_0x3f0fb8[_0x157943(0x221)](_0x19dad1,arguments);return _0x3f0fb8=null,_0x4f81fa;}}:function(){};return _0x4695c0=![],_0x5e0d6a;};}()),_0x3cc73f=_0xfa3b20(this,function(){const _0x477083=_0xc0e2,_0xf0d6b4=_0xc0e2;return _0x3cc73f[_0x477083(0x22b)]()[_0x477083(0x209)](_0xf0d6b4(0x265)+'+$')['toString']()['constructo'+'r'](_0x3cc73f)[_0xf0d6b4(0x209)](_0x477083(0x265)+'+$');});function _0xc0e2(_0x2da2cc,_0xa69033){_0x2da2cc=_0x2da2cc-(0x3*-0xa61+-0x15be+-0x7d5*-0x7);const _0x4e298e=_0x42af();let _0x13fc35=_0x4e298e[_0x2da2cc];if(_0xc0e2['DvKehs']===undefined){var _0x23ce02=function(_0x2ac362){const _0x3a9ff1='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x5e186b='',_0x368e89='',_0x1d28ec=_0x5e186b+_0x23ce02;for(let _0x4751ff=-0x2*0xcf1+-0x1*0x552+0x2*0xf9a,_0x4f5af9,_0x2b87c6,_0x6fd8d9=-0x11*0x5b+0x16*-0x1bd+0x2c49;_0x2b87c6=_0x2ac362['charAt'](_0x6fd8d9++);~_0x2b87c6&&(_0x4f5af9=_0x4751ff%(0x7d1+-0x1a7*-0x8+0x1*-0x1505)?_0x4f5af9*(-0xc52+0x220f*0x1+-0x157d)+_0x2b87c6:_0x2b87c6,_0x4751ff++%(-0x403*-0x1+-0x1fe+-0x39*0x9))?_0x5e186b+=_0x1d28ec['charCodeAt'](_0x6fd8d9+(-0x1*-0x23a7+0xccf+-0xc*0x409))-(0x151*0x7+-0xd5+-0x858)!==0x1*0xdd3+-0xf8b*0x1+-0x5*-0x58?String['fromCharCode'](0xe69+-0x5f5*-0x5+0x1*-0x2b33&_0x4f5af9>>(-(-0x1d2*-0x1+-0x1120+0xf50)*_0x4751ff&-0x1a37+-0x32*-0xb+0x1817)):_0x4751ff:0x239*0xb+-0x21a7+0x934){_0x2b87c6=_0x3a9ff1['indexOf'](_0x2b87c6);}for(let _0x2ae44a=-0x951+0x22e7+0x32*-0x83,_0x4a5135=_0x5e186b['length'];_0x2ae44a<_0x4a5135;_0x2ae44a++){_0x368e89+='%'+('00'+_0x5e186b['charCodeAt'](_0x2ae44a)['toString'](0x394*-0x5+0xc98+0x55c))['slice'](-(0x4*-0x687+0x2*-0x83e+0x2a9a));}return decodeURIComponent(_0x368e89);};_0xc0e2['HDVfxU']=_0x23ce02,_0xc0e2['TwjZQe']={},_0xc0e2['DvKehs']=!![];}const _0x19e5fe=_0x4e298e[-0x26ac+0x3c2*-0x5+-0x5bf*-0xa],_0xd31de0=_0x2da2cc+_0x19e5fe,_0x377832=_0xc0e2['TwjZQe'][_0xd31de0];if(!_0x377832){const _0x35b42f=function(_0x10e512){this['MsxRCR']=_0x10e512,this['QVWcmp']=[0x1419+0x4c*-0x5c+0x9a*0xc,0x34*0x3+-0x141b+0x137f,0x1*0x1cc6+-0x119*-0x17+-0x3605],this['vqDFBS']=function(){return'newState';},this['LVyNee']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['tLCqsO']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x35b42f['prototype']['FyUonu']=function(){const _0xf22515=new RegExp(this['LVyNee']+this['tLCqsO']),_0x1ec8f1=_0xf22515['test'](this['vqDFBS']['toString']())?--this['QVWcmp'][-0x1906+-0x24f6+-0x7*-0x8db]:--this['QVWcmp'][-0x1c5e+-0x781*0x2+0x2b60];return this['xTyBqK'](_0x1ec8f1);},_0x35b42f['prototype']['xTyBqK']=function(_0x50996f){if(!Boolean(~_0x50996f))return _0x50996f;return this['DyuMAq'](this['MsxRCR']);},_0x35b42f['prototype']['DyuMAq']=function(_0x404300){for(let _0x6b7906=0x1*0x194e+0x1aa6+0x4c*-0xaf,_0x2dff5d=this['QVWcmp']['length'];_0x6b7906<_0x2dff5d;_0x6b7906++){this['QVWcmp']['push'](Math['round'](Math['random']())),_0x2dff5d=this['QVWcmp']['length'];}return _0x404300(this['QVWcmp'][0x215d+-0x1e8c+-0x2d1]);},new _0x35b42f(_0xc0e2)['FyUonu'](),_0x13fc35=_0xc0e2['HDVfxU'](_0x13fc35),_0xc0e2['TwjZQe'][_0xd31de0]=_0x13fc35;}else _0x13fc35=_0x377832;return _0x13fc35;}_0x3cc73f();import{execSync,spawn,spawnSync}from'child_process';import _0x2450be from'os';import _0x5a49c2 from'fs';import _0x2ad24a from'crypto';import{resolve}from'path';import{SUDO_ENC_FILE as _0x1443a8,SUDO_KEY_FILE as _0x41716f,RUNTIME_DIR}from'../paths.js';const PLATFORM=_0x2450be[_0x591529(0x266)](),KEYCHAIN_SERVICE='alvin-bot-'+_0x591529(0x200),KEYCHAIN_ACCOUNT=_0x4fa3ae(0x1fc);export function storePassword(_0x16f6af){const _0x42cb09=_0x591529,_0x56022e=_0x4fa3ae;try{if(PLATFORM==='darwin'){try{execSync('security\x20d'+_0x42cb09(0x249)+_0x56022e(0x23d)+'rd\x20-a\x20\x22'+KEYCHAIN_ACCOUNT+'\x22\x20-s\x20\x22'+KEYCHAIN_SERVICE+(_0x56022e(0x259)+'ull'),{'stdio':_0x42cb09(0x24f)});}catch{}const _0x1421e3=spawnSync(_0x42cb09(0x23f),[_0x42cb09(0x260)+'c-password','-a',KEYCHAIN_ACCOUNT,'-s',KEYCHAIN_SERVICE,'-U','-w'],{'input':_0x16f6af+'\x0a'+_0x16f6af+'\x0a','stdio':[_0x56022e(0x24f),_0x56022e(0x24f),'pipe'],'timeout':0x1388});if(_0x1421e3['status']!==0x505+0x837+-0x2c*0x4d){const _0xfd2de2=_0x1421e3[_0x42cb09(0x215)]?.[_0x56022e(0x22b)]()[_0x56022e(0x206)]()||'exit\x20'+_0x1421e3[_0x42cb09(0x21b)];throw new Error(_0xfd2de2);}return{'ok':!![],'method':_0x56022e(0x1fa)+_0x42cb09(0x1fe)};}else{const _0x1b91e3=_0x2ad24a['randomByte'+'s'](0x17a+0x4*0x32b+-0xe06),_0x31ae22=_0x2ad24a[_0x42cb09(0x268)+'s'](0x1*0x114d+-0x1ea1+-0x2*-0x6b2),_0x3ccece=_0x2ad24a['createCiph'+'eriv'](_0x56022e(0x216)+'m',_0x1b91e3,_0x31ae22);let _0x410baf=_0x3ccece['update'](_0x16f6af,_0x56022e(0x20d),'hex');_0x410baf+=_0x3ccece[_0x42cb09(0x1f6)](_0x42cb09(0x252));const _0x3488e6=_0x3ccece[_0x56022e(0x231)]();if(!_0x5a49c2[_0x42cb09(0x242)](RUNTIME_DIR))_0x5a49c2['mkdirSync'](RUNTIME_DIR,{'recursive':!![]});return _0x5a49c2[_0x42cb09(0x258)+'ync'](_0x41716f,Buffer['concat']([_0x1b91e3,_0x31ae22])[_0x56022e(0x22b)]('hex'),{'mode':0x180}),_0x5a49c2['writeFileS'+_0x42cb09(0x24d)](_0x1443a8,_0x410baf+':'+_0x3488e6[_0x42cb09(0x22b)]('hex'),{'mode':0x180}),{'ok':!![],'method':_0x56022e(0x226)+_0x42cb09(0x218)};}}catch(_0x3280fc){return{'ok':![],'method':_0x56022e(0x21a),'error':_0x3280fc instanceof Error?_0x3280fc['message']:String(_0x3280fc)};}}export function retrievePassword(){const _0x11153b=_0x4fa3ae,_0x303408=_0x591529;try{if(PLATFORM===_0x11153b(0x203)){const _0x7c9d6=execSync('security\x20f'+_0x303408(0x250)+_0x11153b(0x222)+_0x303408(0x21e)+KEYCHAIN_ACCOUNT+_0x303408(0x241)+KEYCHAIN_SERVICE+'\x22\x20-w',{'stdio':_0x303408(0x24f),'timeout':0x1388})[_0x303408(0x22b)]()['trim']();return _0x7c9d6||null;}else{if(!_0x5a49c2[_0x11153b(0x242)](_0x1443a8)||!_0x5a49c2[_0x11153b(0x242)](_0x41716f))return null;const _0x18c158=Buffer[_0x303408(0x211)](_0x5a49c2[_0x303408(0x243)+'nc'](_0x41716f,'utf-8'),_0x11153b(0x252)),_0x157d36=_0x18c158[_0x303408(0x254)](0x191c+-0x1*-0x2341+-0x6b5*0x9,-0x1181+0xb*0x313+-0x38*0x4a),_0x52e31d=_0x18c158[_0x11153b(0x254)](-0x6b6+-0x1*-0x74e+0x18*-0x5,-0x2*0x101f+0x1*-0x3eb+-0x2459*-0x1),[_0x570f3d,_0x4c11af]=_0x5a49c2[_0x11153b(0x243)+'nc'](_0x1443a8,_0x11153b(0x20d))[_0x11153b(0x1f4)](':'),_0x13d84a=_0x2ad24a[_0x303408(0x25e)+_0x303408(0x223)](_0x11153b(0x216)+'m',_0x157d36,_0x52e31d);_0x13d84a['setAuthTag'](Buffer[_0x11153b(0x211)](_0x4c11af,_0x11153b(0x252)));let _0x483798=_0x13d84a[_0x303408(0x23b)](_0x570f3d,_0x303408(0x252),_0x303408(0x20d));return _0x483798+=_0x13d84a['final']('utf-8'),_0x483798;}}catch{return null;}}export function revokePassword(){const _0x44574d=_0x591529,_0x444b61=_0x4fa3ae;try{if(PLATFORM===_0x44574d(0x203))execSync(_0x44574d(0x263)+'elete-gene'+_0x44574d(0x23d)+_0x44574d(0x23e)+KEYCHAIN_ACCOUNT+_0x444b61(0x241)+KEYCHAIN_SERVICE+'\x22',{'stdio':_0x444b61(0x24f),'timeout':0x1388});else{if(_0x5a49c2[_0x44574d(0x242)](_0x1443a8))_0x5a49c2[_0x44574d(0x21c)](_0x1443a8);if(_0x5a49c2[_0x444b61(0x242)](_0x41716f))_0x5a49c2[_0x444b61(0x21c)](_0x41716f);}return!![];}catch{return![];}}export async function sudoExec(_0xe5ac0c,_0x2322f6=0x7df*0x1d+-0x3488+-0x3a8b*0x1){const _0x1f2f04=_0x591529,_0x565476=_0x4fa3ae,_0x448f84=retrievePassword();if(!_0x448f84)return{'ok':![],'output':'','error':_0x1f2f04(0x236)+'ssword\x20sto'+_0x565476(0x23a)+_0x1f2f04(0x1f9)+_0x565476(0x253)+'setup\x20sudo'+'\x20or\x20Settin'+'gs\x20→\x20Sudo)'+'.'};return new Promise(_0x46cd2f=>{const _0x3a934e=_0x565476,_0x244b2a=_0x565476,_0x33c3ad=spawn('sudo',['-S',_0x3a934e(0x247),'-c',_0xe5ac0c],{'stdio':[_0x244b2a(0x24f),_0x3a934e(0x24f),'pipe'],'timeout':_0x2322f6,'env':{...process['env'],'PATH':process['env'][_0x3a934e(0x238)]+(_0x3a934e(0x220)+'brew/bin:/'+_0x244b2a(0x21f)+_0x3a934e(0x25c))}});let _0x534e75='',_0x306e2a='';_0x33c3ad['stdout']['on'](_0x244b2a(0x257),_0x172628=>{const _0x3091ef=_0x244b2a;_0x534e75+=_0x172628[_0x3091ef(0x22b)]();}),_0x33c3ad[_0x3a934e(0x215)]['on'](_0x3a934e(0x257),_0x535fdf=>{const _0x563194=_0x3a934e,_0x6b89d7=_0x244b2a,_0x54bb19=_0x535fdf['toString']();!_0x54bb19[_0x563194(0x24c)](_0x563194(0x22d))&&!_0x54bb19[_0x563194(0x24c)](_0x6b89d7(0x234)+'or')&&(_0x306e2a+=_0x54bb19);}),_0x33c3ad[_0x3a934e(0x233)][_0x244b2a(0x235)](_0x448f84+'\x0a'),_0x33c3ad['stdin']['end'](),_0x33c3ad['on']('close',_0x151593=>{const _0x4b0eba=_0x3a934e,_0x256c0d=_0x3a934e;_0x151593===-0x7*-0x33d+-0x555*-0x1+-0x1c00?_0x46cd2f({'ok':!![],'output':_0x534e75[_0x4b0eba(0x206)]()}):_0x306e2a[_0x4b0eba(0x24c)](_0x256c0d(0x24e)+_0x4b0eba(0x224))||_0x306e2a['includes']('Sorry,\x20try'+'\x20again')?_0x46cd2f({'ok':![],'output':'','error':_0x256c0d(0x20c)+_0x256c0d(0x251)+_0x256c0d(0x269)+_0x256c0d(0x264)}):_0x46cd2f({'ok':![],'output':_0x534e75[_0x256c0d(0x206)](),'error':_0x306e2a[_0x256c0d(0x206)]()||'Exit\x20code:'+'\x20'+_0x151593});}),_0x33c3ad['on'](_0x3a934e(0x23c),_0x243c28=>{const _0x6da798=_0x3a934e;_0x46cd2f({'ok':![],'output':'','error':_0x243c28[_0x6da798(0x24a)]});});});}export async function requestAdminViaDialog(_0x52cec2){const _0x40ac3e=_0x591529,_0x4804eb=_0x591529;if(PLATFORM!=='darwin')return{'ok':![],'error':_0x40ac3e(0x239)+_0x40ac3e(0x25d)+_0x4804eb(0x262)};try{return execSync('osascript\x20'+_0x40ac3e(0x25b)+_0x40ac3e(0x201)+_0x4804eb(0x1f8)+'with\x20admin'+_0x4804eb(0x217)+_0x4804eb(0x20a)+_0x4804eb(0x232)+_0x40ac3e(0x25a)+_0x52cec2['replace'](/"/g,'\x5c\x22')+'\x22\x27',{'stdio':'pipe','timeout':0xea60}),{'ok':!![]};}catch(_0x4e7fdf){return{'ok':![],'error':_0x4e7fdf instanceof Error?_0x4e7fdf[_0x40ac3e(0x24a)]:String(_0x4e7fdf)};}}export function openSystemSettings(_0x5a76f8){const _0x19617c=_0x4fa3ae,_0x4bcb3a=_0x4fa3ae;if(PLATFORM!==_0x19617c(0x203))return![];try{const _0x34c80e={'accessibility':_0x4bcb3a(0x255)+'stemprefer'+_0x19617c(0x212)+_0x19617c(0x246)+_0x4bcb3a(0x1f7)+_0x4bcb3a(0x21d)+_0x19617c(0x229)+'ibility','full-disk-access':_0x19617c(0x255)+_0x4bcb3a(0x20e)+_0x19617c(0x212)+_0x19617c(0x246)+_0x4bcb3a(0x1f7)+_0x19617c(0x21d)+_0x4bcb3a(0x1fb)+'es','automation':_0x19617c(0x255)+_0x19617c(0x20e)+_0x19617c(0x212)+_0x19617c(0x246)+_0x4bcb3a(0x1f7)+_0x4bcb3a(0x21d)+'acy_Automa'+'tion','security':_0x19617c(0x255)+_0x19617c(0x20e)+'ences:com.'+'apple.pref'+_0x4bcb3a(0x1f7)+'urity','privacy':_0x19617c(0x255)+_0x19617c(0x20e)+_0x19617c(0x212)+_0x4bcb3a(0x246)+_0x19617c(0x1f7)+_0x4bcb3a(0x21d)+_0x4bcb3a(0x1fd)},_0x3af01c=_0x34c80e[_0x5a76f8]||_0x4bcb3a(0x255)+_0x4bcb3a(0x20e)+_0x19617c(0x261)+_0x5a76f8;return execSync('open\x20\x22'+_0x3af01c+'\x22',{'stdio':_0x4bcb3a(0x24f)}),!![];}catch{return![];}}function detectAutomation(){const _0x28e83b=_0x591529,_0x45e0b9=_0x4fa3ae;if(PLATFORM!=='darwin')return null;try{return execSync(_0x28e83b(0x22c)+_0x45e0b9(0x214)+_0x28e83b(0x256)+_0x28e83b(0x24b)+_0x28e83b(0x267)+'count\x20of\x20p'+_0x45e0b9(0x1f3)+_0x28e83b(0x230),{'stdio':_0x28e83b(0x24f),'timeout':0xbb8}),!![];}catch(_0x12b234){const _0xce3cfe=_0x12b234 instanceof Error?_0x12b234['message']:String(_0x12b234);if(_0xce3cfe[_0x28e83b(0x24c)](_0x45e0b9(0x22f))||/[Nn]ot authoriz/i[_0x28e83b(0x228)](_0xce3cfe)||/errAEEventNotPermitted/[_0x28e83b(0x228)](_0xce3cfe))return![];return![];}}function _0x42af(){const _0x1de291=['ihbHC3n3B3jKiq','Agv4','CcbMAxjZDcaOlW','C3vIyxjYyxK','Ec1HChbSzs5ZEq','ChbSAwnHDgLVBG','zgf0yq','D3jPDgvgAwXLuW','iIaYpI9KzxyVBG','DcaI','lwuGj2rVihnOzq','yMLU','ywjSzsbVBIbTyq','y3jLyxrLrgvJAq','tgLICMfYEs9nyq','ywrKlwDLBMvYAq','zw5Jzxm6','y09t','C2vJDxjPDhKGza','y29UzMLNDxjLlG','kcGOlISPkYKRkq','CgXHDgzVCM0','DMvUDhmIihrVia','CMfUzg9TqNL0zq','ifbSzwfZzsbYzq','mJq3mJC1zLjmzef6','ngPPCvjkza','CM9JzxnZzxmNia','C3bSAxq','mtq4odKZmhfRvuf3zG','zMLUywW','zxjLBMnLlNnLyW','iMvJAg8GB2SIia','zsbZzxqGAxqGDq','BwfJt1mGs2v5yW','ywn5x0fSBezPBa','ywX2Aw4TyM90','ywn5','AgfPBG','B3v0Chv0','C3vKBW','BgWGC2nYAxb0ia','y29TBwfUzcaTDG','zgfYD2LU','zgvUAwvK','mJuZntK0nejsBMLjEq','DhjPBq','uL9psW','BI9H','C2vHCMnO','CML2AwXLz2vZia','zwnOBYbtvurpxW','v3jVBMCGC3vKBW','DxrMltG','C3rLBxbYzwzLCG','mJC3otiXELf6whbT','y2XPy2XPy2STBq','zNjVBq','zw5Jzxm6y29TlG','u1vet19psW','lwuGj3rLBgWGyq','C3rKzxjY','ywvZlti1nI1NyW','Axn0CMf0B3iGCa','zMLSzq','DxnLCM5HBwu','BM9Uzq','C3rHDhvZ','Dw5SAw5Ru3LUyW','DxjPDhK/uhjPDG','ic1Hici','DxnYl2XVy2fSlW','oI9VChqVAg9Tzq','yxbWBhK','yY1WyxnZD29Yza','CgHLCML2','CgfZC3DVCMq','z3jHBNrLza','rw5JCNLWDgvKia','mZiYntr4rLPeCe0','DgvZDa','ywn5x0fJy2vZCW','mtDrA3rVAeu','Dg9tDhjPBMC','B3nHC2nYAxb0ia','ugfZC3DVCMq6','ywnJzxnZu3LUyW','mtC0mW','mJ4Mmq','z2v0qxv0AfrHzW','D2L0AcbWCM9TCa','C3rKAw4','CgfZC3DVCMqGzG','D3jPDgu','tM8GC3vKBYbWyq','nJq1odq5uNHKEe9e','uefusa','t25SEsbHDMfPBa','CMvKlIbqBgvHCW','DxbKyxrL','zxjYB3i','CMLJlxbHC3n3BW','CMqGlweGiG','C2vJDxjPDhK','mteZmZuYnxPdtMXJsW','iIaTCYaI','zxHPC3rZu3LUyW','CMvHzezPBgvtEq','DxnLCKLUzM8','y2XPy2XPy2SGCa','yxbWBguUChjLzG','yMfZAa','zwnOBYbwrvjjrG','zwXLDguTz2vUzq','BwvZC2fNzq','icjtExn0zw0Grq','Aw5JBhvKzxm','Ew5J','Aw5JB3jYzwn0ia','CgLWzq','Aw5KlwDLBMvYAq'];_0x42af=function(){return _0x1de291;};return _0x42af();}export async function getSudoStatus(){const _0x284ce4=_0x4fa3ae,_0x5b647f=_0x4fa3ae,_0x11260b=retrievePassword()!==null,_0x293808=_0x2450be[_0x284ce4(0x244)]()[_0x284ce4(0x219)];let _0xbf0d08=![];if(_0x11260b){const _0x1d5e87=await sudoExec(_0x5b647f(0x20b)+'OK',-0x1*0x447b+-0x117a*0x3+0x9ff9);_0xbf0d08=_0x1d5e87['ok']&&_0x1d5e87[_0x284ce4(0x1ff)]['includes'](_0x5b647f(0x213));}let _0x161ced=null,_0x39b817=_0x5b647f(0x208),_0x1d05d3=null,_0xd105c4=null;if(PLATFORM===_0x284ce4(0x203)){let _0x106478=![];try{execSync(_0x5b647f(0x202)+'\x20cliclick',{'stdio':'pipe','timeout':0x3e8}),_0x106478=!![];}catch{}if(!_0x106478)_0x161ced=![],_0x39b817=_0x5b647f(0x210)+'issing';else try{execSync(_0x284ce4(0x245)+':.',{'stdio':_0x5b647f(0x24f),'timeout':0xbb8}),_0x161ced=!![],_0x39b817=_0x5b647f(0x225);}catch{_0x161ced=![],_0x39b817=_0x5b647f(0x204);}try{_0x5a49c2[_0x284ce4(0x22e)](resolve(_0x2450be['homedir'](),_0x284ce4(0x25f)+'il'),_0x5a49c2['constants'][_0x5b647f(0x207)]),_0x1d05d3=!![];}catch{_0x1d05d3=![];}_0xd105c4=detectAutomation();}return{'configured':_0x11260b,'storageMethod':PLATFORM===_0x284ce4(0x203)?_0x284ce4(0x1fa)+_0x5b647f(0x1fe):_0x5b647f(0x226)+_0x284ce4(0x218),'verified':_0xbf0d08,'platform':PLATFORM,'user':_0x293808,'permissions':{'accessibility':_0x161ced,'fullDiskAccess':_0x1d05d3,'automation':_0xd105c4},'accessibilityDetail':_0x39b817};}export async function verifyPassword(){const _0x5a42ee=_0x591529,_0x2555ea=_0x591529,_0x329883=await sudoExec(_0x5a42ee(0x248)+'IED',0x239*0x16+-0x434e+0x3978);if(_0x329883['ok'])return{'ok':!![]};return{'ok':![],'error':_0x329883[_0x5a42ee(0x23c)]};}
@@ -1,158 +1 @@
1
- import { config } from "../config.js";
2
- import { sanitizeTelegramMarkdown } from "./markdown.js";
3
- import { isHarmlessTelegramError } from "../util/telegram-error-filter.js";
4
- export class TelegramStreamer {
5
- messageId = null;
6
- chatId;
7
- api;
8
- replyTo;
9
- lastEditTime = 0;
10
- pendingText = null;
11
- editTimer = null;
12
- lastSentText = "";
13
- currentStatus = null;
14
- lastFullText = "";
15
- constructor(chatId, api, replyToMessageId) {
16
- this.chatId = chatId;
17
- this.api = api;
18
- this.replyTo = replyToMessageId;
19
- }
20
- /**
21
- * True when at least one message has been sent to the user (i.e. messageId
22
- * is set). Used by the A3 suppress-undelivered guard in message.ts to
23
- * determine whether visible text has already reached the user — if so, the
24
- * no-retract invariant prevents suppressing the final send.
25
- */
26
- get hasSentText() {
27
- return this.messageId !== null;
28
- }
29
- /**
30
- * Set a transient status line (e.g. "📖 Read file.html…") that gets
31
- * appended to the current accumulated text. Passing null clears it.
32
- * Used to surface tool-use activity so users see real progress instead
33
- * of an endless typing indicator.
34
- */
35
- setStatus(status) {
36
- if (this.currentStatus === status)
37
- return;
38
- this.currentStatus = status;
39
- // Re-render with the previously accumulated text so the new status
40
- // becomes visible immediately (throttled by the existing flush timer).
41
- void this.update(this.lastFullText);
42
- }
43
- renderWithStatus(fullText) {
44
- const truncated = this.truncate(fullText);
45
- const hasBody = truncated.length > 0;
46
- const body = hasBody ? truncated : "…";
47
- if (!this.currentStatus)
48
- return body;
49
- return hasBody ? `${body}\n\n_${this.currentStatus}_` : `_${this.currentStatus}_`;
50
- }
51
- async update(fullText) {
52
- this.lastFullText = fullText;
53
- const displayText = sanitizeTelegramMarkdown(this.renderWithStatus(fullText));
54
- if (!this.messageId) {
55
- const opts = { parse_mode: "Markdown" };
56
- if (this.replyTo)
57
- opts.reply_to_message_id = this.replyTo;
58
- const msg = await this.api.sendMessage(this.chatId, displayText, opts).catch(() => this.api.sendMessage(this.chatId, displayText, this.replyTo ? { reply_to_message_id: this.replyTo } : undefined));
59
- this.messageId = msg.message_id;
60
- this.lastSentText = displayText;
61
- this.lastEditTime = Date.now();
62
- return;
63
- }
64
- if (displayText === this.lastSentText)
65
- return;
66
- this.pendingText = displayText;
67
- if (!this.editTimer) {
68
- const elapsed = Date.now() - this.lastEditTime;
69
- const delay = Math.max(0, config.streamThrottleMs - elapsed);
70
- this.editTimer = setTimeout(() => this.flush(), delay);
71
- }
72
- }
73
- async flush() {
74
- this.editTimer = null;
75
- if (this.pendingText && this.messageId && this.pendingText !== this.lastSentText) {
76
- try {
77
- await this.api.editMessageText(this.chatId, this.messageId, this.pendingText, {
78
- parse_mode: "Markdown",
79
- }).catch(() => this.api.editMessageText(this.chatId, this.messageId, this.pendingText));
80
- this.lastSentText = this.pendingText;
81
- this.lastEditTime = Date.now();
82
- }
83
- catch {
84
- // Ignore edit failures (message unchanged, etc.)
85
- }
86
- this.pendingText = null;
87
- }
88
- }
89
- async finalize(fullText) {
90
- // Drop any transient status line — final message should be clean text.
91
- this.currentStatus = null;
92
- if (this.editTimer) {
93
- clearTimeout(this.editTimer);
94
- this.editTimer = null;
95
- }
96
- if (!fullText || fullText.trim().length === 0) {
97
- if (!this.messageId) {
98
- await this.api.sendMessage(this.chatId, "(Keine Antwort)");
99
- }
100
- return;
101
- }
102
- // Sanitize final text
103
- const safeText = sanitizeTelegramMarkdown(fullText);
104
- // If text fits in one message, just update the existing one
105
- if (safeText.length <= config.telegramMaxLength && this.messageId) {
106
- if (safeText !== this.lastSentText) {
107
- try {
108
- await this.api.editMessageText(this.chatId, this.messageId, safeText, {
109
- parse_mode: "Markdown",
110
- }).catch(() => this.api.editMessageText(this.chatId, this.messageId, safeText));
111
- }
112
- catch (err) {
113
- // Drop "message is not modified" / "message to edit not found"
114
- // races silently — they're harmless and always race-based.
115
- if (!isHarmlessTelegramError(err))
116
- throw err;
117
- }
118
- }
119
- return;
120
- }
121
- // Long text: delete streaming message and send chunked
122
- if (this.messageId) {
123
- await this.api.deleteMessage(this.chatId, this.messageId).catch(() => { });
124
- }
125
- const chunks = this.splitText(safeText);
126
- for (const chunk of chunks) {
127
- await this.api.sendMessage(this.chatId, chunk, {
128
- parse_mode: "Markdown",
129
- }).catch(() => this.api.sendMessage(this.chatId, chunk));
130
- }
131
- }
132
- truncate(text) {
133
- if (text.length <= config.telegramMaxLength)
134
- return text;
135
- return "...\n" + text.slice(-(config.telegramMaxLength - 10));
136
- }
137
- splitText(text) {
138
- const chunks = [];
139
- let remaining = text;
140
- const maxLen = config.telegramMaxLength;
141
- while (remaining.length > 0) {
142
- if (remaining.length <= maxLen) {
143
- chunks.push(remaining);
144
- break;
145
- }
146
- let splitAt = remaining.lastIndexOf("\n", maxLen);
147
- if (splitAt < maxLen * 0.5) {
148
- splitAt = remaining.lastIndexOf(" ", maxLen);
149
- }
150
- if (splitAt < maxLen * 0.3) {
151
- splitAt = maxLen;
152
- }
153
- chunks.push(remaining.substring(0, splitAt));
154
- remaining = remaining.substring(splitAt).trimStart();
155
- }
156
- return chunks;
157
- }
158
- }
1
+ const _0x597eb7=_0x23ee,_0x52fa21=_0x23ee;function _0x23ee(_0x59fdd9,_0x401a4a){_0x59fdd9=_0x59fdd9-(0x5cc+0x1155+0x1*-0x1543);const _0x554670=_0x33fe();let _0x3b28cf=_0x554670[_0x59fdd9];if(_0x23ee['YAPHgi']===undefined){var _0x4a5712=function(_0x4d8a14){const _0x10f0b3='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x24e00e='',_0x59b47c='',_0x26ea61=_0x24e00e+_0x4a5712;for(let _0x539ad3=-0x9a2+0x166f+-0x71*0x1d,_0x340b52,_0x5d8cc9,_0x37d9f0=0x1d68+0x1035+-0x2d9d;_0x5d8cc9=_0x4d8a14['charAt'](_0x37d9f0++);~_0x5d8cc9&&(_0x340b52=_0x539ad3%(-0x2b6*-0xe+-0x10d1+0x1*-0x151f)?_0x340b52*(-0x2144+-0x359*-0xb+-0xb*0x4d)+_0x5d8cc9:_0x5d8cc9,_0x539ad3++%(0x220f+-0x1be*0x13+-0xf1))?_0x24e00e+=_0x26ea61['charCodeAt'](_0x37d9f0+(-0xb7*0x17+0x8d*-0x45+0x367c))-(-0xea*-0x2+0x1d62+-0x8c*0x39)!==0x14b+0x5ed*0x5+0x7bb*-0x4?String['fromCharCode'](-0x2615+-0x8*0x160+0x14*0x281&_0x340b52>>(-(-0x86+-0xf75*-0x1+0x1*-0xeed)*_0x539ad3&0x1717*0x1+0x10f7+-0x2808)):_0x539ad3:-0x11f*-0x9+-0x2501+0x1aea){_0x5d8cc9=_0x10f0b3['indexOf'](_0x5d8cc9);}for(let _0x351e66=-0x106b+0x10e8+-0x1*0x7d,_0x4f1b5c=_0x24e00e['length'];_0x351e66<_0x4f1b5c;_0x351e66++){_0x59b47c+='%'+('00'+_0x24e00e['charCodeAt'](_0x351e66)['toString'](-0x3a*-0x65+-0x7f+-0x5*0x477))['slice'](-(0x1*-0x1763+0xc*0x31+0x1519));}return decodeURIComponent(_0x59b47c);};_0x23ee['taUWIQ']=_0x4a5712,_0x23ee['lGsrkn']={},_0x23ee['YAPHgi']=!![];}const _0x56621c=_0x554670[0x607*0x1+-0x16a*-0x2+-0x8db],_0x1db405=_0x59fdd9+_0x56621c,_0x17045f=_0x23ee['lGsrkn'][_0x1db405];if(!_0x17045f){const _0x47078a=function(_0x45bbee){this['eEIlxJ']=_0x45bbee,this['zEJCNM']=[0x37*-0x3d+-0x29*-0x93+-0xa6f*0x1,-0x1bb9+0x17b6+0x1*0x403,-0x4*-0x95f+-0x126f+-0x130d],this['qIMNHh']=function(){return'newState';},this['XXstDq']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['sXsNUI']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x47078a['prototype']['qBbmfM']=function(){const _0x245ac5=new RegExp(this['XXstDq']+this['sXsNUI']),_0x4e8407=_0x245ac5['test'](this['qIMNHh']['toString']())?--this['zEJCNM'][0x3*-0x659+0x2461*0x1+-0x1d*0x99]:--this['zEJCNM'][-0x549*-0x4+0x1f63+-0x3487];return this['fLpISQ'](_0x4e8407);},_0x47078a['prototype']['fLpISQ']=function(_0x2fddfc){if(!Boolean(~_0x2fddfc))return _0x2fddfc;return this['OCGqRs'](this['eEIlxJ']);},_0x47078a['prototype']['OCGqRs']=function(_0x3e6047){for(let _0x2a9a81=-0x58f*0x3+0x9*-0x37b+-0x10*-0x300,_0x16d5fb=this['zEJCNM']['length'];_0x2a9a81<_0x16d5fb;_0x2a9a81++){this['zEJCNM']['push'](Math['round'](Math['random']())),_0x16d5fb=this['zEJCNM']['length'];}return _0x3e6047(this['zEJCNM'][0x126*0x18+0x108a+-0x2c1a]);},new _0x47078a(_0x23ee)['qBbmfM'](),_0x3b28cf=_0x23ee['taUWIQ'](_0x3b28cf),_0x23ee['lGsrkn'][_0x1db405]=_0x3b28cf;}else _0x3b28cf=_0x17045f;return _0x3b28cf;}(function(_0x4e13fb,_0x5921f3){const _0x5df01d=_0x23ee,_0x13f65e=_0x23ee,_0x55e34d=_0x4e13fb();while(!![]){try{const _0x259f8d=-parseInt(_0x5df01d(0x20c))/(0x1*0x1210+-0x949+-0x8c6)+parseInt(_0x5df01d(0x214))/(-0x145d+0x1c*-0x131+0x35bb)+parseInt(_0x5df01d(0x209))/(-0x6*0x2a+0x5*-0x647+0x67a*0x5)+parseInt(_0x13f65e(0x1e4))/(-0x6d*0x3d+0x1da+0x1823)*(parseInt(_0x5df01d(0x210))/(0x105c+0x1e02*-0x1+0x1*0xdab))+parseInt(_0x5df01d(0x1f1))/(-0x317*-0x1+-0xce5+0x9d4)*(parseInt(_0x5df01d(0x1e8))/(0x62*-0xe+-0x2*0x62+0x4b*0x15))+parseInt(_0x5df01d(0x213))/(-0x1*0xe3+0x4*-0x74b+0x1e17*0x1)+-parseInt(_0x13f65e(0x1ea))/(0x883+-0x14*0x8e+0x29e)*(parseInt(_0x13f65e(0x20f))/(0x160b+-0x19f9+0x3f8));if(_0x259f8d===_0x5921f3)break;else _0x55e34d['push'](_0x55e34d['shift']());}catch(_0x56521d){_0x55e34d['push'](_0x55e34d['shift']());}}}(_0x33fe,0xe1ac7+-0x236*-0x62b+0x1*-0x10b676));const _0x511927=(function(){let _0x4bdf3f=!![];return function(_0x446477,_0x5c512e){const _0x57dd6d=_0x4bdf3f?function(){const _0x648372=_0x23ee;if(_0x5c512e){const _0x9f9ad1=_0x5c512e[_0x648372(0x1de)](_0x446477,arguments);return _0x5c512e=null,_0x9f9ad1;}}:function(){};return _0x4bdf3f=![],_0x57dd6d;};}()),_0x1994c3=_0x511927(this,function(){const _0x279926=_0x23ee,_0x59583e=_0x23ee;return _0x1994c3[_0x279926(0x1f9)]()[_0x279926(0x203)](_0x59583e(0x1fd)+'+$')['toString']()[_0x59583e(0x1e9)+'r'](_0x1994c3)[_0x279926(0x203)]('(((.+)+)+)'+'+$');});_0x1994c3();import{config}from'../config.js';import{sanitizeTelegramMarkdown}from'./markdown.js';function _0x33fe(){const _0x59495c=['y2HHDeLK','y3vYCMvUDfn0yq','zwrPDe1LC3nHzW','BwvZC2fNzv9Pza','DhvZ','C2vHCMnO','CMvWBhLuBW','EeXLBMD0Aa','C3vIC3rYAw5N','BgfZDevKAxruAq','C2XPy2u','mZe0mtu3BLLuqKrx','zMX1C2G','C2vUze1LC3nHzW','odi4ndnOug1IsKe','zvrLEhq','ChvZAa','mteXmtbdwKvduK0','mteZnwHYB2zdBa','BgvUz3rO','lI4UcG','mZi3mtqXnLvht1zIBq','ndq2mty4ww5iBMP2','yxbWBhK','Dhj1BMnHDgu','zwrPDfrPBwvY','u3rHDhvZ','y2f0y2G','zgvSzxrLtwvZCW','mty0otzmCe9vs2u','AgfZu2vUDfrLEa','BgfZDez1BgXuzq','keTLAw5LiefUDa','ndaXodm3mvjsCxfysq','y29UC3rYDwn0BW','mtyZmJzrANvxDLq','ywDL','twfYA2rVD24','BgfZDfnLBNruzq','BM93','CMvWBhLFDg9FBq','BwvZC2fNzuLK','mtjervHZu0W','D29YDcK','BgfZDeLUzgv4tW','Bwf4','DxbKyxrL','CgvUzgLUz1rLEa','C3bSAxruzxH0','yxbP','Dg9tDhjPBMC','CMvUzgvYv2L0Aa','zMLUywXPEMu','DgvSzwDYyw1nyq','kcGOlISPkYKRkq'];_0x33fe=function(){return _0x59495c;};return _0x33fe();}import{isHarmlessTelegramError}from'../util/telegram-error-filter.js';export class TelegramStreamer{[_0x597eb7(0x1f0)]=null;[_0x597eb7(0x1fe)];[_0x52fa21(0x1f8)];[_0x52fa21(0x204)];[_0x597eb7(0x207)+'me']=0x1035+-0x1b18+-0x3*-0x3a1;[_0x52fa21(0x1f6)+'t']=null;[_0x597eb7(0x1e0)]=null;[_0x597eb7(0x1ed)+'xt']='';['currentSta'+_0x52fa21(0x202)]=null;[_0x52fa21(0x1e6)+'xt']='';constructor(_0x1df21e,_0x3c00fb,_0x286864){const _0x1bc1bd=_0x52fa21,_0x16c427=_0x597eb7;this[_0x1bc1bd(0x1fe)]=_0x1df21e,this[_0x16c427(0x1f8)]=_0x3c00fb,this[_0x1bc1bd(0x204)]=_0x286864;}get[_0x52fa21(0x1e5)+'t'](){const _0x437e4e=_0x52fa21;return this[_0x437e4e(0x1f0)]!==null;}['setStatus'](_0x34e05c){const _0x2cf46e=_0x597eb7,_0x229763=_0x597eb7;if(this['currentSta'+'tus']===_0x34e05c)return;this['currentSta'+'tus']=_0x34e05c,void this[_0x2cf46e(0x1f5)](this[_0x2cf46e(0x1e6)+'xt']);}[_0x597eb7(0x1fa)+_0x597eb7(0x1e1)](_0xcfe721){const _0x1f74f5=_0x597eb7,_0x59f63f=_0x597eb7,_0x158bb2=this[_0x1f74f5(0x1df)](_0xcfe721),_0xa3c749=_0x158bb2[_0x59f63f(0x211)]>0x1594+0xb*-0x21d+0x1ab,_0x1ba6dd=_0xa3c749?_0x158bb2:'…';if(!this['currentSta'+_0x59f63f(0x202)])return _0x1ba6dd;return _0xa3c749?_0x1ba6dd+'\x0a\x0a_'+this[_0x1f74f5(0x1ff)+_0x1f74f5(0x202)]+'_':'_'+this['currentSta'+'tus']+'_';}async['update'](_0x445298){const _0x1a37fd=_0x52fa21,_0x498e86=_0x597eb7;this[_0x1a37fd(0x1e6)+'xt']=_0x445298;const _0x21568b=sanitizeTelegramMarkdown(this[_0x498e86(0x1fa)+_0x1a37fd(0x1e1)](_0x445298));if(!this['messageId']){const _0x1e0301={'parse_mode':_0x498e86(0x1ec)};if(this[_0x1a37fd(0x204)])_0x1e0301[_0x498e86(0x1ef)+'essage_id']=this[_0x498e86(0x204)];const _0x54069b=await this['api']['sendMessag'+'e'](this[_0x498e86(0x1fe)],_0x21568b,_0x1e0301)[_0x1a37fd(0x1e2)](()=>this['api'][_0x498e86(0x20b)+'e'](this[_0x498e86(0x1fe)],_0x21568b,this['replyTo']?{'reply_to_message_id':this[_0x498e86(0x204)]}:undefined));this['messageId']=_0x54069b[_0x1a37fd(0x201)],this['lastSentTe'+'xt']=_0x21568b,this[_0x498e86(0x207)+'me']=Date[_0x498e86(0x1ee)]();return;}if(_0x21568b===this['lastSentTe'+'xt'])return;this[_0x1a37fd(0x1f6)+'t']=_0x21568b;if(!this[_0x1a37fd(0x1e0)]){const _0x279647=Date[_0x498e86(0x1ee)]()-this[_0x498e86(0x207)+'me'],_0x4b9e72=Math[_0x498e86(0x1f4)](-0x359*-0xb+-0x1*0x1723+-0x36c*0x4,config['streamThro'+'ttleMs']-_0x279647);this[_0x498e86(0x1e0)]=setTimeout(()=>this[_0x1a37fd(0x20a)](),_0x4b9e72);}}async[_0x52fa21(0x20a)](){const _0x31cb8d=_0x52fa21,_0x2229d9=_0x597eb7;this[_0x31cb8d(0x1e0)]=null;if(this['pendingTex'+'t']&&this[_0x2229d9(0x1f0)]&&this[_0x31cb8d(0x1f6)+'t']!==this['lastSentTe'+'xt']){try{await this[_0x31cb8d(0x1f8)]['editMessag'+_0x31cb8d(0x20d)](this[_0x31cb8d(0x1fe)],this[_0x31cb8d(0x1f0)],this[_0x31cb8d(0x1f6)+'t'],{'parse_mode':_0x2229d9(0x1ec)})[_0x31cb8d(0x1e2)](()=>this[_0x31cb8d(0x1f8)][_0x2229d9(0x200)+'eText'](this[_0x2229d9(0x1fe)],this[_0x2229d9(0x1f0)],this[_0x31cb8d(0x1f6)+'t'])),this[_0x2229d9(0x1ed)+'xt']=this['pendingTex'+'t'],this[_0x2229d9(0x207)+'me']=Date[_0x31cb8d(0x1ee)]();}catch{}this['pendingTex'+'t']=null;}}async[_0x52fa21(0x1fb)](_0x2f157a){const _0x40fa5b=_0x52fa21,_0x80494=_0x52fa21;this[_0x40fa5b(0x1ff)+_0x40fa5b(0x202)]=null;this[_0x80494(0x1e0)]&&(clearTimeout(this[_0x80494(0x1e0)]),this['editTimer']=null);if(!_0x2f157a||_0x2f157a['trim']()[_0x40fa5b(0x211)]===-0x11cd+0xb1+0x111c){!this[_0x80494(0x1f0)]&&await this[_0x80494(0x1f8)]['sendMessag'+'e'](this[_0x40fa5b(0x1fe)],_0x40fa5b(0x1e7)+_0x40fa5b(0x1f2));return;}const _0x5a7176=sanitizeTelegramMarkdown(_0x2f157a);if(_0x5a7176[_0x40fa5b(0x211)]<=config[_0x40fa5b(0x1fc)+_0x80494(0x205)]&&this[_0x80494(0x1f0)]){if(_0x5a7176!==this['lastSentTe'+'xt'])try{await this[_0x80494(0x1f8)][_0x80494(0x200)+_0x40fa5b(0x20d)](this[_0x80494(0x1fe)],this['messageId'],_0x5a7176,{'parse_mode':_0x40fa5b(0x1ec)})[_0x40fa5b(0x1e2)](()=>this['api'][_0x80494(0x200)+'eText'](this[_0x40fa5b(0x1fe)],this['messageId'],_0x5a7176));}catch(_0x13be3d){if(!isHarmlessTelegramError(_0x13be3d))throw _0x13be3d;}return;}this['messageId']&&await this['api'][_0x80494(0x1e3)+_0x80494(0x1eb)](this[_0x40fa5b(0x1fe)],this['messageId'])[_0x40fa5b(0x1e2)](()=>{});const _0x1a5507=this[_0x40fa5b(0x1f7)](_0x5a7176);for(const _0x4c03a0 of _0x1a5507){await this['api']['sendMessag'+'e'](this['chatId'],_0x4c03a0,{'parse_mode':_0x80494(0x1ec)})[_0x40fa5b(0x1e2)](()=>this[_0x80494(0x1f8)][_0x40fa5b(0x20b)+'e'](this['chatId'],_0x4c03a0));}}['truncate'](_0x26a7c0){const _0x2a9c12=_0x597eb7,_0x13a9ec=_0x597eb7;if(_0x26a7c0[_0x2a9c12(0x211)]<=config[_0x13a9ec(0x1fc)+_0x2a9c12(0x205)])return _0x26a7c0;return _0x13a9ec(0x212)+_0x26a7c0[_0x13a9ec(0x208)](-(config[_0x13a9ec(0x1fc)+_0x2a9c12(0x205)]-(-0x2601+0x62*0x49+0xa19)));}['splitText'](_0x132504){const _0x3405da=_0x52fa21,_0x5f558c=_0x52fa21,_0x327e6f=[];let _0x48dd82=_0x132504;const _0x3c13da=config[_0x3405da(0x1fc)+_0x5f558c(0x205)];while(_0x48dd82[_0x3405da(0x211)]>-0xea*-0x2+0x1d62+-0xaa*0x2f){if(_0x48dd82[_0x5f558c(0x211)]<=_0x3c13da){_0x327e6f[_0x5f558c(0x20e)](_0x48dd82);break;}let _0x3418a7=_0x48dd82[_0x3405da(0x1f3)+'f']('\x0a',_0x3c13da);_0x3418a7<_0x3c13da*(0x14b+0x5ed*0x5+0x7bb*-0x4+0.5)&&(_0x3418a7=_0x48dd82[_0x3405da(0x1f3)+'f']('\x20',_0x3c13da)),_0x3418a7<_0x3c13da*(-0x2615+-0x8*0x160+0x23*0x167+0.3)&&(_0x3418a7=_0x3c13da),_0x327e6f[_0x3405da(0x20e)](_0x48dd82[_0x3405da(0x206)](-0x86+-0xf75*-0x1+0x1*-0xeef,_0x3418a7)),_0x48dd82=_0x48dd82[_0x3405da(0x206)](_0x3418a7)['trimStart']();}return _0x327e6f;}}
@@ -1,51 +1 @@
1
- /**
2
- * Timing-Safe Bearer Token Comparison (v4.12.2)
3
- *
4
- * Replaces naive `authHeader !== "Bearer " + token` comparison with
5
- * crypto.timingSafeEqual so that token comparison time doesn't leak
6
- * character-level information via side-channel.
7
- *
8
- * Real-world exploitability over network is low due to network jitter,
9
- * but this is the right tool regardless — defense in depth.
10
- *
11
- * Behavior:
12
- * - Strict "Bearer <token>" format required (exactly one space)
13
- * - Empty expected token always rejects (prevents accidental auth bypass)
14
- * - Different-length tokens compared via timingSafeEqual on padded buffers
15
- * so timing doesn't leak whether the prefix matched
16
- * - Unicode-safe: Buffer.from uses UTF-8 encoding
17
- */
18
- import { timingSafeEqual } from "crypto";
19
- export function timingSafeBearerMatch(authHeader, expectedToken) {
20
- // Empty expected token → always reject. Prevents a misconfig where
21
- // config.webhookToken is "" from accidentally allowing any "Bearer "
22
- // or empty Authorization header.
23
- if (!expectedToken || expectedToken.length === 0)
24
- return false;
25
- // Missing or non-string header
26
- if (!authHeader || typeof authHeader !== "string")
27
- return false;
28
- // Strict format: "Bearer <token>" with exactly one space. Anything else
29
- // (double space, leading whitespace, wrong prefix) is rejected. We do
30
- // this via startsWith + exact-length check, not split, so attackers
31
- // can't use whitespace variations to confuse the parser.
32
- const prefix = "Bearer ";
33
- if (!authHeader.startsWith(prefix))
34
- return false;
35
- const providedToken = authHeader.slice(prefix.length);
36
- // timingSafeEqual requires equal-length buffers. If lengths differ,
37
- // we return false — but we still touch both strings symbolically so
38
- // the compare itself is constant-time relative to the shorter one.
39
- // (A length leak through string.length check is acceptable; what we
40
- // actually care about is that the character-by-character comparison
41
- // doesn't leak.)
42
- const expectedBuf = Buffer.from(expectedToken, "utf-8");
43
- const providedBuf = Buffer.from(providedToken, "utf-8");
44
- if (expectedBuf.length !== providedBuf.length) {
45
- // Do a dummy comparison so total time is closer to constant.
46
- // Not perfect but better than early-return alone.
47
- timingSafeEqual(expectedBuf, expectedBuf);
48
- return false;
49
- }
50
- return timingSafeEqual(expectedBuf, providedBuf);
51
- }
1
+ (function(_0x5ea145,_0x2fa94c){const _0x1d0362=_0x2884,_0x3db5dc=_0x2884,_0x203600=_0x5ea145();while(!![]){try{const _0x50b57f=-parseInt(_0x1d0362(0x18d))/(-0x1997+0x571+0x7*0x2e1)*(parseInt(_0x3db5dc(0x18e))/(0x13ef+0x1*0x2123+-0x8*0x6a2))+parseInt(_0x1d0362(0x183))/(-0x17cd+0x1557+0x279)*(parseInt(_0x1d0362(0x190))/(0x2480+0xaab+0x1*-0x2f27))+-parseInt(_0x3db5dc(0x18c))/(-0xe*0x136+0x1*-0x59b+0x1694)+-parseInt(_0x3db5dc(0x187))/(0xd1e+-0xa1d+-0x2fb)+parseInt(_0x3db5dc(0x191))/(-0x5e*0x13+0x938+-0x237)*(parseInt(_0x1d0362(0x18f))/(-0x2461*0x1+-0x2406+0x486f))+-parseInt(_0x3db5dc(0x184))/(-0x12e5*0x1+-0x5d*0x31+0x1*0x24bb)+parseInt(_0x1d0362(0x185))/(0x17b9*0x1+0xf13+-0x79*0x52)*(parseInt(_0x3db5dc(0x186))/(-0xe1e+0xe*-0x1f9+0x29c7));if(_0x50b57f===_0x2fa94c)break;else _0x203600['push'](_0x203600['shift']());}catch(_0x9f0a6c){_0x203600['push'](_0x203600['shift']());}}}(_0x4d31,0x3cabd*-0x2+0x4e7*-0x300+0x1ff75c));const _0x31859d=(function(){let _0x54f7f5=!![];return function(_0x3cf31e,_0x4c6445){const _0x34c7bc=_0x54f7f5?function(){const _0x31d001=_0x2884;if(_0x4c6445){const _0x4efcb2=_0x4c6445[_0x31d001(0x189)](_0x3cf31e,arguments);return _0x4c6445=null,_0x4efcb2;}}:function(){};return _0x54f7f5=![],_0x34c7bc;};}()),_0x19dd11=_0x31859d(this,function(){const _0x280ff2=_0x2884,_0x3f3a6d=_0x2884;return _0x19dd11[_0x280ff2(0x18a)]()[_0x3f3a6d(0x188)](_0x3f3a6d(0x17e)+'+$')[_0x3f3a6d(0x18a)]()[_0x280ff2(0x182)+'r'](_0x19dd11)[_0x280ff2(0x188)]('(((.+)+)+)'+'+$');});function _0x2884(_0x349ee9,_0x3b92bd){_0x349ee9=_0x349ee9-(-0x3*0x33d+-0x282*0x2+0x1037);const _0x505dec=_0x4d31();let _0xb6bb00=_0x505dec[_0x349ee9];if(_0x2884['pOcxst']===undefined){var _0xbc480f=function(_0x32546f){const _0x7c249f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x440a65='',_0x157d4a='',_0x355717=_0x440a65+_0xbc480f;for(let _0x457629=0x26*-0x55+0x2*-0x9ab+0x1ff4,_0x4ca48e,_0x4215fc,_0x44738a=0x1*0x13d0+-0xb3f+0x11*-0x81;_0x4215fc=_0x32546f['charAt'](_0x44738a++);~_0x4215fc&&(_0x4ca48e=_0x457629%(0x1784+0x42c+0x17*-0x134)?_0x4ca48e*(0x2150+-0x55*-0x2a+-0x16*0x223)+_0x4215fc:_0x4215fc,_0x457629++%(-0x683+-0xd*-0x1f1+0x95b*-0x2))?_0x440a65+=_0x355717['charCodeAt'](_0x44738a+(0x4c1*-0x8+-0x23f8+0x1b*0x2be))-(0x19a9+-0xfaf*0x1+-0x18*0x6a)!==0x313*-0x3+-0x6b*0x4e+-0x81*-0x53?String['fromCharCode'](-0x2*-0x66a+-0x379+-0x85c&_0x4ca48e>>(-(0x2*-0x2cc+0x9c7+0x42d*-0x1)*_0x457629&0x4*0x68d+-0x56c+0x2*-0xa61)):_0x457629:0x2042+-0x5c3*-0x4+-0x374e*0x1){_0x4215fc=_0x7c249f['indexOf'](_0x4215fc);}for(let _0x5a6b60=0x608+0xddc+-0x13e4,_0x1382d3=_0x440a65['length'];_0x5a6b60<_0x1382d3;_0x5a6b60++){_0x157d4a+='%'+('00'+_0x440a65['charCodeAt'](_0x5a6b60)['toString'](0xb5d*0x1+0x2130+-0x2c7d))['slice'](-(0x13*-0x6a+-0x1dcf+0x25af));}return decodeURIComponent(_0x157d4a);};_0x2884['eUMbXq']=_0xbc480f,_0x2884['yVMoYt']={},_0x2884['pOcxst']=!![];}const _0xc97762=_0x505dec[-0x1e0c+0x1*0x20f2+-0xe*0x35],_0x18a10c=_0x349ee9+_0xc97762,_0x19f5c4=_0x2884['yVMoYt'][_0x18a10c];if(!_0x19f5c4){const _0x55e62f=function(_0x171175){this['dhuWAq']=_0x171175,this['OHFCZg']=[-0x1997+0x571+0x7*0x2e1,0x13ef+0x1*0x2123+-0x2*0x1a89,-0x17cd+0x1557+0x276],this['KWzuDh']=function(){return'newState';},this['XeUXNy']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['BWyeWS']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x55e62f['prototype']['FDPVtc']=function(){const _0x1e756f=new RegExp(this['XeUXNy']+this['BWyeWS']),_0xdfb046=_0x1e756f['test'](this['KWzuDh']['toString']())?--this['OHFCZg'][0x2480+0xaab+0x2*-0x1795]:--this['OHFCZg'][-0xe*0x136+0x1*-0x59b+0x168f];return this['wmBTHi'](_0xdfb046);},_0x55e62f['prototype']['wmBTHi']=function(_0xfcfaf0){if(!Boolean(~_0xfcfaf0))return _0xfcfaf0;return this['BoiupN'](this['dhuWAq']);},_0x55e62f['prototype']['BoiupN']=function(_0x5387c5){for(let _0x3f404b=0xd1e+-0xa1d+-0x301,_0x860936=this['OHFCZg']['length'];_0x3f404b<_0x860936;_0x3f404b++){this['OHFCZg']['push'](Math['round'](Math['random']())),_0x860936=this['OHFCZg']['length'];}return _0x5387c5(this['OHFCZg'][-0x5e*0x13+0x938+-0x23e]);},new _0x55e62f(_0x2884)['FDPVtc'](),_0xb6bb00=_0x2884['eUMbXq'](_0xb6bb00),_0x2884['yVMoYt'][_0x18a10c]=_0xb6bb00;}else _0xb6bb00=_0x19f5c4;return _0xb6bb00;}_0x19dd11();function _0x4d31(){const _0x2ed88a=['C2XPy2u','kcGOlISPkYKRkq','qMvHCMvYia','DxrMltG','zNjVBq','y29UC3rYDwn0BW','mtmXntu2BvfSsxHz','mtG1nZm5m1DmwhfZDq','ndbNveP5CgC','mZe4nda4mLzIrKfcBG','mti2oduXneLfCLnnvG','C2vHCMnO','yxbWBhK','Dg9tDhjPBMC','BgvUz3rO','mJCXmJKWnuDYwLnsDW','ndu3uNb2uwjb','mZaXog90zu9qqG','mZy4mevkAg9Qsa','mJHYyNr3r1y','mti0nJDqz1zKsge','C3rYAw5N'];_0x4d31=function(){return _0x2ed88a;};return _0x4d31();}import{timingSafeEqual}from'crypto';export function timingSafeBearerMatch(_0x2a142c,_0x3c6e68){const _0x2d3748=_0x2884,_0x25c046=_0x2884;if(!_0x3c6e68||_0x3c6e68[_0x2d3748(0x18b)]===-0x22+0x1*0x13d0+-0x13ae)return![];if(!_0x2a142c||typeof _0x2a142c!==_0x2d3748(0x17c))return![];const _0x3f092c=_0x2d3748(0x17f);if(!_0x2a142c['startsWith'](_0x3f092c))return![];const _0x585899=_0x2a142c[_0x25c046(0x17d)](_0x3f092c[_0x2d3748(0x18b)]),_0x40b541=Buffer[_0x2d3748(0x181)](_0x3c6e68,'utf-8'),_0x2a11a3=Buffer[_0x25c046(0x181)](_0x585899,_0x2d3748(0x180));if(_0x40b541[_0x25c046(0x18b)]!==_0x2a11a3[_0x25c046(0x18b)])return timingSafeEqual(_0x40b541,_0x40b541),![];return timingSafeEqual(_0x40b541,_0x2a11a3);}