pi-harness-runtime 1.1.161 → 1.1.162
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/harness/telegram-auth.ts +150 -0
- package/harness/telegram-content-filter.ts +223 -0
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/dist/adapters/telegram-adapter.d.ts.map +1 -1
- package/packages/notification/dist/adapters/telegram-adapter.js +17 -12
- package/packages/notification/dist/adapters/telegram-adapter.js.map +1 -1
- package/packages/notification/dist/mask-secrets.d.ts.map +1 -1
- package/packages/notification/dist/mask-secrets.js +9 -0
- package/packages/notification/dist/mask-secrets.js.map +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/notification/src/adapters/telegram-adapter.ts +19 -12
- package/packages/notification/src/mask-secrets.ts +11 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
- package/scripts/telegram-webhook-server.ts +85 -6
- package/scripts/tsconfig.json +9 -0
|
@@ -17,7 +17,8 @@ import { createServer } from "node:http";
|
|
|
17
17
|
|
|
18
18
|
// --- Configuration ---
|
|
19
19
|
const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
|
|
20
|
-
|
|
20
|
+
// SECURITY: Require webhook secret - fail closed if not set
|
|
21
|
+
const WEBHOOK_SECRET = process.env.TELEGRAM_WEBHOOK_SECRET;
|
|
21
22
|
const WEBHOOK_URL = process.env.TELEGRAM_WEBHOOK_URL;
|
|
22
23
|
const CALLBACK_QUEUE_FILE = process.env.CALLBACK_QUEUE_FILE || join(process.env.HOME || "/tmp", ".pi-harness-runtime", "callback-queue.jsonl");
|
|
23
24
|
const PORT = parseInt(process.env.PORT || "3000", 10);
|
|
@@ -26,10 +27,70 @@ const PORT = parseInt(process.env.PORT || "3000", 10);
|
|
|
26
27
|
if (!BOT_TOKEN) {
|
|
27
28
|
console.error("[TelegramWebhook] ERROR: TELEGRAM_BOT_TOKEN not set");
|
|
28
29
|
console.error("[TelegramWebhook] Usage:");
|
|
29
|
-
console.error("[TelegramWebhook] TELEGRAM_BOT_TOKEN=xxx bun run scripts/telegram-webhook-server.ts");
|
|
30
|
+
console.error("[TelegramWebhook] TELEGRAM_BOT_TOKEN=xxx TELEGRAM_WEBHOOK_SECRET=xxx bun run scripts/telegram-webhook-server.ts");
|
|
30
31
|
process.exit(1);
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
// SECURITY: Require webhook secret - fail closed in production
|
|
35
|
+
if (!WEBHOOK_SECRET) {
|
|
36
|
+
console.error("[TelegramWebhook] ERROR: TELEGRAM_WEBHOOK_SECRET not set");
|
|
37
|
+
console.error("[TelegramWebhook] SECURITY: Webhook secret is required for production");
|
|
38
|
+
console.error("[TelegramWebhook] Usage:");
|
|
39
|
+
console.error("[TelegramWebhook] TELEGRAM_WEBHOOK_SECRET=<high-entropy-secret> bun run scripts/telegram-webhook-server.ts");
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// --- Authorization helpers ---
|
|
44
|
+
function getAllowedUserIds(): Set<number> {
|
|
45
|
+
const ids = new Set<number>();
|
|
46
|
+
|
|
47
|
+
// Priority 1: Environment variable
|
|
48
|
+
const envUsers = process.env.TELEGRAM_ALLOWED_USERS;
|
|
49
|
+
if (envUsers) {
|
|
50
|
+
for (const part of envUsers.split(",")) {
|
|
51
|
+
const num = parseInt(part.trim(), 10);
|
|
52
|
+
if (!isNaN(num) && num > 0) ids.add(num);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Priority 2: Key file (telegram-allowed-users.txt)
|
|
57
|
+
const allowedFile = join(process.env.HOME || "/tmp", ".pi-harness-runtime", "keys", "telegram-allowed-users.txt");
|
|
58
|
+
if (existsSync(allowedFile)) {
|
|
59
|
+
const content = readFileSync(allowedFile, "utf8").trim();
|
|
60
|
+
for (const part of content.split(",")) {
|
|
61
|
+
const num = parseInt(part.trim(), 10);
|
|
62
|
+
if (!isNaN(num) && num > 0) ids.add(num);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Priority 3: Legacy chat ID file
|
|
67
|
+
const legacyFile = join(process.env.HOME || "/tmp", ".pi-harness-runtime", "keys", "telegram-chat-id.txt");
|
|
68
|
+
if (existsSync(legacyFile) && ids.size === 0) {
|
|
69
|
+
const content = readFileSync(legacyFile, "utf8").trim();
|
|
70
|
+
const num = parseInt(content, 10);
|
|
71
|
+
if (!isNaN(num) && num > 0) ids.add(num);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return ids;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function isAuthorizedUser(userId: number): boolean {
|
|
78
|
+
const allowed = getAllowedUserIds();
|
|
79
|
+
// SECURITY: Fail closed - deny if no allowlist configured
|
|
80
|
+
if (allowed.size === 0) {
|
|
81
|
+
console.warn("[TelegramWebhook] SECURITY: No TELEGRAM_ALLOWED_USERS configured - denying access");
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
return allowed.has(userId);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// SECURITY: Sanitize URLs from error messages
|
|
88
|
+
function sanitizeError(error: unknown): string {
|
|
89
|
+
const msg = String(error);
|
|
90
|
+
// Remove any bot token URLs
|
|
91
|
+
return msg.replace(/https?:\/\/[^/]*\/bot[^/]+\/[^\s]*/gi, "[REDACTED_URL]");
|
|
92
|
+
}
|
|
93
|
+
|
|
33
94
|
// --- Types ---
|
|
34
95
|
interface CallbackQuery {
|
|
35
96
|
id: string;
|
|
@@ -275,7 +336,24 @@ function handleRequest(req: import("node:http").IncomingMessage, res: import("no
|
|
|
275
336
|
const cq = update.callback_query;
|
|
276
337
|
const parsed = parseCallbackData(cq.data);
|
|
277
338
|
|
|
278
|
-
|
|
339
|
+
// SECURITY: Validate sender is authorized user
|
|
340
|
+
if (!isAuthorizedUser(cq.from.id)) {
|
|
341
|
+
console.warn(`[TelegramWebhook] Unauthorized user: ${cq.from.id} (${cq.from.username || cq.from.first_name})`);
|
|
342
|
+
// Answer callback query to remove loading state
|
|
343
|
+
await fetch(`https://api.telegram.org/bot${BOT_TOKEN}/answerCallbackQuery`, {
|
|
344
|
+
method: "POST",
|
|
345
|
+
headers: { "Content-Type": "application/json" },
|
|
346
|
+
body: JSON.stringify({
|
|
347
|
+
callback_query_id: cq.id,
|
|
348
|
+
text: "Unauthorized. Please contact the bot owner.",
|
|
349
|
+
}),
|
|
350
|
+
});
|
|
351
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
352
|
+
res.end(JSON.stringify({ ok: true }));
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
console.log(`[TelegramWebhook] Callback: ${cq.data} from user_id=${cq.from.id}`);
|
|
279
357
|
|
|
280
358
|
// Queue for pi-harness to process
|
|
281
359
|
const queued: QueuedCallback = {
|
|
@@ -318,7 +396,7 @@ function handleRequest(req: import("node:http").IncomingMessage, res: import("no
|
|
|
318
396
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
319
397
|
res.end(JSON.stringify({ ok: true }));
|
|
320
398
|
} catch (err) {
|
|
321
|
-
console.error("[TelegramWebhook] Error:", err);
|
|
399
|
+
console.error("[TelegramWebhook] Error:", sanitizeError(err));
|
|
322
400
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
323
401
|
res.end(JSON.stringify({ error: "Internal error" }));
|
|
324
402
|
}
|
|
@@ -330,7 +408,8 @@ async function setupWebhook(): Promise<void> {
|
|
|
330
408
|
if (!WEBHOOK_URL) {
|
|
331
409
|
console.log("[TelegramWebhook] TELEGRAM_WEBHOOK_URL not set — skipping webhook setup");
|
|
332
410
|
console.log("[TelegramWebhook] To set webhook manually:");
|
|
333
|
-
console.log(
|
|
411
|
+
console.log("[TelegramWebhook] Configure webhook URL via environment or secret provider");
|
|
412
|
+
console.log("[TelegramWebhook] Then run: curl -X POST https://api.telegram.org/botYOUR_BOT_TOKEN/setWebhook -d json_with_secrets_removed");
|
|
334
413
|
return;
|
|
335
414
|
}
|
|
336
415
|
|
|
@@ -347,7 +426,7 @@ async function setupWebhook(): Promise<void> {
|
|
|
347
426
|
if (result.ok) {
|
|
348
427
|
console.log(`[TelegramWebhook] Webhook set to: ${WEBHOOK_URL}`);
|
|
349
428
|
} else {
|
|
350
|
-
console.error(`[TelegramWebhook] Webhook setup failed: ${result.description}`);
|
|
429
|
+
console.error(`[TelegramWebhook] Webhook setup failed: ${sanitizeError(result.description)}`);
|
|
351
430
|
}
|
|
352
431
|
}
|
|
353
432
|
|