@rubytech/create-maxy-code 0.1.549 → 0.1.551
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/package.json +1 -1
- package/payload/platform/lib/agent-dispatch-rule/dist/index.d.ts +22 -8
- package/payload/platform/lib/agent-dispatch-rule/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/agent-dispatch-rule/dist/index.js +47 -13
- package/payload/platform/lib/agent-dispatch-rule/dist/index.js.map +1 -1
- package/payload/platform/lib/agent-dispatch-rule/src/__tests__/rule.test.ts +68 -9
- package/payload/platform/lib/agent-dispatch-rule/src/index.ts +60 -16
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +3 -3
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +8 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +2 -2
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch.test.js +2 -2
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-sync-provision.test.js +2 -2
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-sync-provision.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-sync-provision.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-sync-provision.js +21 -8
- package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-sync-provision.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-embedding.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-embedding.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-embedding.test.js +142 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-update-embedding.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js +41 -5
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
- package/payload/platform/plugins/telegram/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/telegram/PLUGIN.md +6 -4
- package/payload/platform/plugins/telegram/mcp/dist/index.js +62 -38
- package/payload/platform/plugins/telegram/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.d.ts +18 -5
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.js +34 -6
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-token.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.d.ts +25 -8
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.js +28 -16
- package/payload/platform/plugins/telegram/mcp/dist/lib/account-write.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.d.ts +12 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.d.ts.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.js +26 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/agent-active.js.map +1 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/secret-path.d.ts +16 -13
- package/payload/platform/plugins/telegram/mcp/dist/lib/secret-path.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/secret-path.js +19 -23
- package/payload/platform/plugins/telegram/mcp/dist/lib/secret-path.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/webhook-url.d.ts +9 -7
- package/payload/platform/plugins/telegram/mcp/dist/lib/webhook-url.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/webhook-url.js +11 -8
- package/payload/platform/plugins/telegram/mcp/dist/lib/webhook-url.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/tools/message.d.ts +4 -0
- package/payload/platform/plugins/telegram/mcp/dist/tools/message.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/tools/message.js +13 -3
- package/payload/platform/plugins/telegram/mcp/dist/tools/message.js.map +1 -1
- package/payload/platform/plugins/telegram/references/setup-guide.md +16 -8
- package/payload/platform/plugins/telegram/skills/configure/SKILL.md +30 -32
- package/payload/server/server.js +511 -240
|
@@ -5,13 +5,14 @@ import { z } from "zod";
|
|
|
5
5
|
import { message } from "./tools/message.js";
|
|
6
6
|
import { messageHistory } from "./tools/message-history.js";
|
|
7
7
|
import { setWebhook, getWebhookInfo } from "./lib/telegram.js";
|
|
8
|
-
import {
|
|
8
|
+
import { persistTelegramBot, botIdFromToken, CANONICAL_TELEGRAM_PREFIX } from "./lib/account-write.js";
|
|
9
9
|
const server = new McpServer({
|
|
10
10
|
name: "maxy-messaging",
|
|
11
11
|
version: "0.1.0",
|
|
12
12
|
});
|
|
13
13
|
eagerTool(server, "message", "Send a message via Telegram. Supports text with HTML formatting and inline keyboards for interactive choices.", {
|
|
14
14
|
channel: z.literal("telegram").describe("Delivery channel"),
|
|
15
|
+
botId: z.string().describe("Which registered bot to send as (its numeric Telegram id, the token's colon-prefix). This account may hold several; if you do not know the id, call with your best guess and the error lists every bot registered here."),
|
|
15
16
|
chatId: z
|
|
16
17
|
.union([z.string(), z.number()])
|
|
17
18
|
.describe("Telegram chat ID to send to"),
|
|
@@ -99,17 +100,19 @@ eagerTool(server, "message-history", "Query conversation history from the messag
|
|
|
99
100
|
};
|
|
100
101
|
}
|
|
101
102
|
});
|
|
102
|
-
import {
|
|
103
|
-
import { configDirName, resolveSecretFilePath,
|
|
103
|
+
import { mkdirSync } from "node:fs";
|
|
104
|
+
import { configDirName, resolveSecretFilePath, telegramSecretsDir } from "./lib/secret-path.js";
|
|
105
|
+
import { accountDirFor, isActiveAgentSlug } from "./lib/agent-active.js";
|
|
104
106
|
import { buildWebhookUrl } from "./lib/webhook-url.js";
|
|
105
107
|
eagerTool(server, "telegram-webhook-register", "Register or re-register a Telegram bot webhook. Generates a cryptographic secret, persists it to disk, and passes it to the Telegram Bot API. Call this after obtaining a bot token from BotFather.", {
|
|
106
108
|
botToken: z.string().describe("Telegram bot token from BotFather"),
|
|
107
|
-
webhookUrl: z.string().url().describe("Full webhook URL; path MUST be under /api/telegram/ (the maxy edge-admitted path)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
webhookUrl: z.string().url().describe("Full webhook URL; path MUST be under /api/telegram/ (the maxy edge-admitted path). Do NOT add ?bot= or ?account= — this tool stamps the bot id on for you."),
|
|
110
|
+
role: z.enum(["admin", "public"]).describe("Bot role — an admin bot answers only the operator's numeric IDs and runs as the admin agent; a public bot is customer-facing and runs as the agent named in `agent`. This selects the spawn path, so it is a privilege decision and is never derived."),
|
|
111
|
+
agent: z.string().optional().describe("Public bots only, and required for them: the account's own agent slug this bot answers as. Must be an active agent."),
|
|
112
|
+
adminUsers: z.array(z.number()).optional().describe("Admin numeric user IDs admitted on THIS bot (admin bots only). Not shared with the account's other bots."),
|
|
113
|
+
dmPolicy: z.enum(["open", "allowlist", "disabled"]).optional().describe("DM policy for THIS bot (public bots only)"),
|
|
114
|
+
allowFrom: z.array(z.number()).optional().describe("Allowlisted numeric user IDs for THIS bot (public bot, allowlist policy)"),
|
|
115
|
+
}, async ({ botToken, webhookUrl, role, agent, adminUsers, dmPolicy, allowFrom }) => {
|
|
113
116
|
// Task 2365 — the account comes first, because the secret path and the
|
|
114
117
|
// registered URL are both per-account now and neither can be built without
|
|
115
118
|
// it. This guard used to sit after setWebhook, where a missing ACCOUNT_ID
|
|
@@ -123,7 +126,38 @@ eagerTool(server, "telegram-webhook-register", "Register or re-register a Telegr
|
|
|
123
126
|
isError: true,
|
|
124
127
|
};
|
|
125
128
|
}
|
|
126
|
-
|
|
129
|
+
// Task 2368 — the bot id is the token's colon-prefix. It keys the secret
|
|
130
|
+
// file, the registered URL and the config entry, so a malformed token has
|
|
131
|
+
// nowhere to land and is refused before anything is written or registered.
|
|
132
|
+
const botId = botIdFromToken(botToken);
|
|
133
|
+
if (!botId) {
|
|
134
|
+
console.error(`[telegram-setup] op=token-write-rejected reason=malformed-token`);
|
|
135
|
+
return {
|
|
136
|
+
content: [{ type: "text", text: `Bot token is malformed — it must look like 123456:ABC-DEF…` }],
|
|
137
|
+
isError: true,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
// A public bot must name the agent it answers as. An admin bot names none:
|
|
141
|
+
// it reads agents/admin by construction, so an `agent` field there would be
|
|
142
|
+
// stored and never consumed.
|
|
143
|
+
if (role === "public") {
|
|
144
|
+
if (!agent || agent.length === 0) {
|
|
145
|
+
console.error(`[telegram-setup] op=token-write-rejected reason=no-agent botId=${botId}`);
|
|
146
|
+
return {
|
|
147
|
+
content: [{ type: "text", text: `A public bot must name the agent it answers as. Pass \`agent\` with one of this account's active agent slugs.` }],
|
|
148
|
+
isError: true,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
if (!isActiveAgentSlug(accountDirFor(platformRoot, accountId), agent)) {
|
|
152
|
+
console.error(`[telegram-setup] op=token-write-rejected reason=agent-inactive botId=${botId} agent=${agent}`);
|
|
153
|
+
return {
|
|
154
|
+
content: [{ type: "text", text: `Agent "${agent}" is not an active agent on this account, so a bot cannot answer as it.` }],
|
|
155
|
+
isError: true,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
mkdirSync(telegramSecretsDir(), { recursive: true, mode: 0o700 });
|
|
160
|
+
const secretFilePath = resolveSecretFilePath(botId);
|
|
127
161
|
// Assert the webhook path is the one canonical maxy edge-admitted path
|
|
128
162
|
// before touching Telegram. A /channels/telegram URL (the official plugin's
|
|
129
163
|
// path) is rejected at the maxy edge, so registering it would silently fail
|
|
@@ -137,7 +171,7 @@ eagerTool(server, "telegram-webhook-register", "Register or re-register a Telegr
|
|
|
137
171
|
}
|
|
138
172
|
})();
|
|
139
173
|
const admitted = webhookPath.startsWith(CANONICAL_TELEGRAM_PREFIX);
|
|
140
|
-
console.error(`[telegram-setup] op=webhook-register path=${webhookPath} account=${accountId} admitted=${admitted}`);
|
|
174
|
+
console.error(`[telegram-setup] op=webhook-register path=${webhookPath} botId=${botId} account=${accountId} admitted=${admitted}`);
|
|
141
175
|
if (!admitted) {
|
|
142
176
|
return {
|
|
143
177
|
content: [{
|
|
@@ -147,10 +181,10 @@ eagerTool(server, "telegram-webhook-register", "Register or re-register a Telegr
|
|
|
147
181
|
isError: true,
|
|
148
182
|
};
|
|
149
183
|
}
|
|
150
|
-
// Task
|
|
184
|
+
// Task 2368 — the URL Telegram is actually given. buildWebhookUrl only
|
|
151
185
|
// touches the query, so the admitted check above still describes the path
|
|
152
186
|
// that gets registered.
|
|
153
|
-
const registeredUrl = buildWebhookUrl(webhookUrl,
|
|
187
|
+
const registeredUrl = buildWebhookUrl(webhookUrl, botId);
|
|
154
188
|
try {
|
|
155
189
|
// Verify the token is valid by calling getMe
|
|
156
190
|
const meRes = await fetch(`https://api.telegram.org/bot${botToken}/getMe`);
|
|
@@ -180,16 +214,17 @@ eagerTool(server, "telegram-webhook-register", "Register or re-register a Telegr
|
|
|
180
214
|
isError: true,
|
|
181
215
|
};
|
|
182
216
|
}
|
|
183
|
-
// Persist
|
|
184
|
-
//
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
//
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
217
|
+
// Persist this bot's entry into account.json's telegram.bots array, under
|
|
218
|
+
// THIS spawn's account. Task 2368 — the inbound receiver resolves the same
|
|
219
|
+
// entry by the bot id on the registered URL, and the write replaces only
|
|
220
|
+
// the entry with that id, so registering a second bot cannot disturb the
|
|
221
|
+
// first. persistTelegramBot asserts the resolved dir is under the brand
|
|
222
|
+
// install BEFORE writing (non-brand-path is rejected, not written), so a
|
|
223
|
+
// failure here means nothing was persisted.
|
|
224
|
+
const entry = role === "admin"
|
|
225
|
+
? { id: botId, token: botToken, role: "admin", ...(adminUsers ? { adminUsers } : {}) }
|
|
226
|
+
: { id: botId, token: botToken, role: "public", agent: agent, ...(dmPolicy ? { dmPolicy } : {}), ...(allowFrom ? { allowFrom } : {}) };
|
|
227
|
+
const persisted = persistTelegramBot(platformRoot, accountId, entry);
|
|
193
228
|
if (!persisted.ok) {
|
|
194
229
|
console.error(`[telegram-setup] op=token-write-rejected reason=${persisted.error}${persisted.dir ? ` dir=${persisted.dir}` : ""}`);
|
|
195
230
|
const text = persisted.error === "non-brand-path"
|
|
@@ -198,20 +233,9 @@ eagerTool(server, "telegram-webhook-register", "Register or re-register a Telegr
|
|
|
198
233
|
return { content: [{ type: "text", text }], isError: true };
|
|
199
234
|
}
|
|
200
235
|
console.error(`[telegram-setup] op=token-write dir=${persisted.dir} brand=${configDirName()}`);
|
|
201
|
-
// Task
|
|
202
|
-
//
|
|
203
|
-
//
|
|
204
|
-
// in place. Absent is the normal case on a fresh install, not an error.
|
|
205
|
-
const legacy = legacySecretFilePath(botType);
|
|
206
|
-
try {
|
|
207
|
-
if (existsSync(legacy)) {
|
|
208
|
-
rmSync(legacy);
|
|
209
|
-
console.error(`[telegram-setup] op=legacy-secret-removed path=${legacy}`);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
catch (e) {
|
|
213
|
-
console.error(`[telegram-setup] op=legacy-secret-remove-failed path=${legacy} error="${e.message}"`);
|
|
214
|
-
}
|
|
236
|
+
// Task 2368 — the pre-registry secret files are removed by the boot
|
|
237
|
+
// converter (server/telegram-migrate.ts), which owns the whole two-slot
|
|
238
|
+
// shape. This tool no longer deletes anything of its own.
|
|
215
239
|
// Verify registration — guarded because getWebhookInfo can fail
|
|
216
240
|
// independently of a successful registration (e.g., transient API error).
|
|
217
241
|
let verifyInfo = "";
|
|
@@ -226,7 +250,7 @@ eagerTool(server, "telegram-webhook-register", "Register or re-register a Telegr
|
|
|
226
250
|
content: [
|
|
227
251
|
{
|
|
228
252
|
type: "text",
|
|
229
|
-
text: `Webhook registered for @${botUsername}` +
|
|
253
|
+
text: `Webhook registered for @${botUsername} (bot ${botId}, role ${role}${role === "public" ? `, answering as ${agent}` : ""})` +
|
|
230
254
|
`\nURL: ${registeredUrl}` +
|
|
231
255
|
`\nSecret: generated and saved to ${secretFilePath}` +
|
|
232
256
|
verifyInfo,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
export interface RegisteredBot {
|
|
2
|
+
id: string;
|
|
3
|
+
role: string;
|
|
4
|
+
agent?: string;
|
|
5
|
+
}
|
|
6
|
+
/** Every bot registered on this account, for the caller that must name one.
|
|
7
|
+
* Task 2368 — an account holds N bots and each has its own token, so "the
|
|
8
|
+
* account's token" no longer exists. Nothing else surfaces the ids to an agent,
|
|
9
|
+
* so the send tool reports them on a miss rather than failing opaquely. */
|
|
10
|
+
export declare function listRegisteredBots(platformRoot: string, accountId: string): RegisteredBot[];
|
|
11
|
+
/** Resolve one bot's token from the per-account registry.
|
|
12
|
+
*
|
|
13
|
+
* Task 2368 — the caller names the bot. There is no admin-then-public
|
|
14
|
+
* preference to express any more, because "the account's token" is no longer a
|
|
15
|
+
* thing that exists: an account holds N bots and each has its own. Returns null
|
|
16
|
+
* when no entry with that id is present. Brand-isolated: account.json lives
|
|
17
|
+
* under the install's data/accounts, never ~/.claude. */
|
|
18
|
+
export declare function resolveBotToken(platformRoot: string, accountId: string, botId: string): string | null;
|
|
6
19
|
//# sourceMappingURL=account-token.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-token.d.ts","sourceRoot":"","sources":["../../src/lib/account-token.ts"],"names":[],"mappings":"AAGA;;;4EAG4E;AAC5E,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"account-token.d.ts","sourceRoot":"","sources":["../../src/lib/account-token.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;4EAG4E;AAC5E,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE,CAgB3F;AAED;;;;;;0DAM0D;AAC1D,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAerG"}
|
|
@@ -1,17 +1,45 @@
|
|
|
1
1
|
import { resolve, join } from "node:path";
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
export function
|
|
3
|
+
/** Every bot registered on this account, for the caller that must name one.
|
|
4
|
+
* Task 2368 — an account holds N bots and each has its own token, so "the
|
|
5
|
+
* account's token" no longer exists. Nothing else surfaces the ids to an agent,
|
|
6
|
+
* so the send tool reports them on a miss rather than failing opaquely. */
|
|
7
|
+
export function listRegisteredBots(platformRoot, accountId) {
|
|
8
|
+
const configPath = join(resolve(platformRoot, "..", "data", "accounts"), accountId, "account.json");
|
|
9
|
+
if (!existsSync(configPath))
|
|
10
|
+
return [];
|
|
11
|
+
try {
|
|
12
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
13
|
+
const bots = config.telegram?.bots;
|
|
14
|
+
if (!Array.isArray(bots))
|
|
15
|
+
return [];
|
|
16
|
+
return bots
|
|
17
|
+
.filter((b) => !!b && typeof b.id === "string" && typeof b.role === "string")
|
|
18
|
+
.map((b) => ({ id: b.id, role: b.role, ...(typeof b.agent === "string" ? { agent: b.agent } : {}) }));
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Resolve one bot's token from the per-account registry.
|
|
25
|
+
*
|
|
26
|
+
* Task 2368 — the caller names the bot. There is no admin-then-public
|
|
27
|
+
* preference to express any more, because "the account's token" is no longer a
|
|
28
|
+
* thing that exists: an account holds N bots and each has its own. Returns null
|
|
29
|
+
* when no entry with that id is present. Brand-isolated: account.json lives
|
|
30
|
+
* under the install's data/accounts, never ~/.claude. */
|
|
31
|
+
export function resolveBotToken(platformRoot, accountId, botId) {
|
|
8
32
|
const accountsDir = resolve(platformRoot, "..", "data", "accounts");
|
|
9
33
|
const configPath = join(accountsDir, accountId, "account.json");
|
|
10
34
|
if (!existsSync(configPath))
|
|
11
35
|
return null;
|
|
12
36
|
try {
|
|
13
37
|
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
14
|
-
|
|
38
|
+
const bots = config.telegram?.bots;
|
|
39
|
+
if (!Array.isArray(bots))
|
|
40
|
+
return null;
|
|
41
|
+
const hit = bots.find((b) => b && b.id === botId);
|
|
42
|
+
return typeof hit?.token === "string" && hit.token.length > 0 ? hit.token : null;
|
|
15
43
|
}
|
|
16
44
|
catch {
|
|
17
45
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-token.js","sourceRoot":"","sources":["../../src/lib/account-token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"account-token.js","sourceRoot":"","sources":["../../src/lib/account-token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQnD;;;4EAG4E;AAC5E,MAAM,UAAU,kBAAkB,CAAC,YAAoB,EAAE,SAAiB;IACxE,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IACpG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAE1D,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC;QACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QACpC,OAAO,IAAI;aACR,MAAM,CAAC,CAAC,CAAC,EAAqD,EAAE,CAC/D,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;aAC/D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1G,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;;0DAM0D;AAC1D,MAAM,UAAU,eAAe,CAAC,YAAoB,EAAE,SAAiB,EAAE,KAAa;IACpF,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IACpE,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IAChE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAE1D,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC;QACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;QAClD,OAAO,OAAO,GAAG,EAAE,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -2,18 +2,35 @@
|
|
|
2
2
|
* with platform/ui/server/public-host-gate.ts PUBLIC_ALLOWED_PREFIXES — a unit
|
|
3
3
|
* test asserts they agree. The official plugin's /channels/telegram is NOT this. */
|
|
4
4
|
export declare const CANONICAL_TELEGRAM_PREFIX = "/api/telegram/";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
/** Task 2368 — duplicated from platform/ui/app/lib/telegram/bot-registry.ts.
|
|
6
|
+
* The plugin cannot import from platform/ui/app, the same boundary that makes
|
|
7
|
+
* configDirName and the secret path duplicates; telegram-account-write.test.ts
|
|
8
|
+
* asserts the two derivations agree. */
|
|
9
|
+
export declare function botIdFromToken(token: string): string | null;
|
|
10
|
+
export type TelegramBotEntryInput = {
|
|
11
|
+
id: string;
|
|
12
|
+
token: string;
|
|
13
|
+
role: "admin";
|
|
8
14
|
adminUsers?: number[];
|
|
15
|
+
} | {
|
|
16
|
+
id: string;
|
|
17
|
+
token: string;
|
|
18
|
+
role: "public";
|
|
19
|
+
agent: string;
|
|
9
20
|
dmPolicy?: "open" | "allowlist" | "disabled";
|
|
10
21
|
allowFrom?: number[];
|
|
11
|
-
}
|
|
12
|
-
/** Persist
|
|
22
|
+
};
|
|
23
|
+
/** Persist one bot entry into account.json's `telegram.bots` array, replacing
|
|
24
|
+
* any entry with the same id and leaving every other entry byte-identical.
|
|
25
|
+
*
|
|
26
|
+
* Task 2368 — registering, re-pointing or removing one bot cannot disturb
|
|
27
|
+
* another, which the two-slot shape could not promise: a second admin bot
|
|
28
|
+
* overwrote the first's token AND its adminUsers in one write.
|
|
29
|
+
*
|
|
13
30
|
* Brand-isolated: account.json lives under the install's data/accounts. Returns
|
|
14
|
-
* the resolved account.json directory so the caller can log + assert it is
|
|
15
|
-
* the brand install (never ~/.claude). */
|
|
16
|
-
export declare function
|
|
31
|
+
* the resolved account.json directory so the caller can log + assert it is
|
|
32
|
+
* under the brand install (never ~/.claude). */
|
|
33
|
+
export declare function persistTelegramBot(platformRoot: string, accountId: string, entry: TelegramBotEntryInput): {
|
|
17
34
|
ok: boolean;
|
|
18
35
|
dir?: string;
|
|
19
36
|
error?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-write.d.ts","sourceRoot":"","sources":["../../src/lib/account-write.ts"],"names":[],"mappings":"AAGA;;qFAEqF;AACrF,eAAO,MAAM,yBAAyB,mBAAmB,CAAC;AAE1D,MAAM,
|
|
1
|
+
{"version":3,"file":"account-write.d.ts","sourceRoot":"","sources":["../../src/lib/account-write.ts"],"names":[],"mappings":"AAGA;;qFAEqF;AACrF,eAAO,MAAM,yBAAyB,mBAAmB,CAAC;AAE1D;;;yCAGyC;AACzC,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK3D;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GACnE;IACE,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAEN;;;;;;;;;iDASiD;AACjD,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,qBAAqB,GAC3B;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAgC/C"}
|
|
@@ -4,11 +4,28 @@ import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
4
4
|
* with platform/ui/server/public-host-gate.ts PUBLIC_ALLOWED_PREFIXES — a unit
|
|
5
5
|
* test asserts they agree. The official plugin's /channels/telegram is NOT this. */
|
|
6
6
|
export const CANONICAL_TELEGRAM_PREFIX = "/api/telegram/";
|
|
7
|
-
/**
|
|
7
|
+
/** Task 2368 — duplicated from platform/ui/app/lib/telegram/bot-registry.ts.
|
|
8
|
+
* The plugin cannot import from platform/ui/app, the same boundary that makes
|
|
9
|
+
* configDirName and the secret path duplicates; telegram-account-write.test.ts
|
|
10
|
+
* asserts the two derivations agree. */
|
|
11
|
+
export function botIdFromToken(token) {
|
|
12
|
+
const i = token.indexOf(":");
|
|
13
|
+
if (i <= 0)
|
|
14
|
+
return null;
|
|
15
|
+
const id = token.slice(0, i);
|
|
16
|
+
return /^\d+$/.test(id) ? id : null;
|
|
17
|
+
}
|
|
18
|
+
/** Persist one bot entry into account.json's `telegram.bots` array, replacing
|
|
19
|
+
* any entry with the same id and leaving every other entry byte-identical.
|
|
20
|
+
*
|
|
21
|
+
* Task 2368 — registering, re-pointing or removing one bot cannot disturb
|
|
22
|
+
* another, which the two-slot shape could not promise: a second admin bot
|
|
23
|
+
* overwrote the first's token AND its adminUsers in one write.
|
|
24
|
+
*
|
|
8
25
|
* Brand-isolated: account.json lives under the install's data/accounts. Returns
|
|
9
|
-
* the resolved account.json directory so the caller can log + assert it is
|
|
10
|
-
* the brand install (never ~/.claude). */
|
|
11
|
-
export function
|
|
26
|
+
* the resolved account.json directory so the caller can log + assert it is
|
|
27
|
+
* under the brand install (never ~/.claude). */
|
|
28
|
+
export function persistTelegramBot(platformRoot, accountId, entry) {
|
|
12
29
|
const accountsDir = resolve(platformRoot, "..", "data", "accounts");
|
|
13
30
|
const dir = join(accountsDir, accountId);
|
|
14
31
|
const configPath = join(dir, "account.json");
|
|
@@ -33,18 +50,13 @@ export function persistTelegramConfig(platformRoot, accountId, input) {
|
|
|
33
50
|
return { ok: false, error: `account.json parse failed: ${e.message}` };
|
|
34
51
|
}
|
|
35
52
|
const telegram = config.telegram ?? {};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (input.dmPolicy)
|
|
44
|
-
telegram.dmPolicy = input.dmPolicy;
|
|
45
|
-
if (input.allowFrom)
|
|
46
|
-
telegram.allowFrom = input.allowFrom;
|
|
47
|
-
}
|
|
53
|
+
const bots = Array.isArray(telegram.bots) ? telegram.bots : [];
|
|
54
|
+
const at = bots.findIndex((b) => b && typeof b === "object" && b.id === entry.id);
|
|
55
|
+
if (at >= 0)
|
|
56
|
+
bots[at] = entry;
|
|
57
|
+
else
|
|
58
|
+
bots.push(entry);
|
|
59
|
+
telegram.bots = bots;
|
|
48
60
|
config.telegram = telegram;
|
|
49
61
|
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
50
62
|
return { ok: true, dir };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-write.js","sourceRoot":"","sources":["../../src/lib/account-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAElE;;qFAEqF;AACrF,MAAM,CAAC,MAAM,yBAAyB,GAAG,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"account-write.js","sourceRoot":"","sources":["../../src/lib/account-write.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** The account's own directory under the brand install. */
|
|
2
|
+
export declare function accountDirFor(platformRoot: string, accountId: string): string;
|
|
3
|
+
/** Task 2368 — is `slug` an ACTIVE agent on this account?
|
|
4
|
+
*
|
|
5
|
+
* Duplicated from platform/ui/app/lib/claude-agent/account.ts
|
|
6
|
+
* `isActiveAgentSlug`, which the plugin cannot import across the
|
|
7
|
+
* plugin/platform boundary. Same predicate: status must be exactly "active",
|
|
8
|
+
* and a missing agent dir or config resolves to no status, so this also
|
|
9
|
+
* rejects a nonexistent slug. telegram-agent-active.test.ts asserts the two
|
|
10
|
+
* agree. A bot may only be paired to an agent that can actually answer. */
|
|
11
|
+
export declare function isActiveAgentSlug(accountDir: string, slug: string): boolean;
|
|
12
|
+
//# sourceMappingURL=agent-active.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-active.d.ts","sourceRoot":"","sources":["../../src/lib/agent-active.ts"],"names":[],"mappings":"AAGA,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED;;;;;;;4EAO4E;AAC5E,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQ3E"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { resolve, join } from "node:path";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
/** The account's own directory under the brand install. */
|
|
4
|
+
export function accountDirFor(platformRoot, accountId) {
|
|
5
|
+
return join(resolve(platformRoot, "..", "data", "accounts"), accountId);
|
|
6
|
+
}
|
|
7
|
+
/** Task 2368 — is `slug` an ACTIVE agent on this account?
|
|
8
|
+
*
|
|
9
|
+
* Duplicated from platform/ui/app/lib/claude-agent/account.ts
|
|
10
|
+
* `isActiveAgentSlug`, which the plugin cannot import across the
|
|
11
|
+
* plugin/platform boundary. Same predicate: status must be exactly "active",
|
|
12
|
+
* and a missing agent dir or config resolves to no status, so this also
|
|
13
|
+
* rejects a nonexistent slug. telegram-agent-active.test.ts asserts the two
|
|
14
|
+
* agree. A bot may only be paired to an agent that can actually answer. */
|
|
15
|
+
export function isActiveAgentSlug(accountDir, slug) {
|
|
16
|
+
const configPath = join(accountDir, "agents", slug, "config.json");
|
|
17
|
+
if (!existsSync(configPath))
|
|
18
|
+
return false;
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(readFileSync(configPath, "utf-8")).status === "active";
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=agent-active.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-active.js","sourceRoot":"","sources":["../../src/lib/agent-active.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnD,2DAA2D;AAC3D,MAAM,UAAU,aAAa,CAAC,YAAoB,EAAE,SAAiB;IACnE,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;;4EAO4E;AAC5E,MAAM,UAAU,iBAAiB,CAAC,UAAkB,EAAE,IAAY;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;IACnE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,CAAC;QACH,OAAQ,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAA0B,CAAC,MAAM,KAAK,QAAQ,CAAC;IACrG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
export declare function configDirName(): string;
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
2
|
+
/** The directory holding one secret file per registered bot. Created mode 700
|
|
3
|
+
* by the register tool; the secrets themselves are 600. */
|
|
4
|
+
export declare function telegramSecretsDir(): string;
|
|
5
|
+
/** Task 2368 — the webhook secret path, keyed on the bot's own Telegram id.
|
|
4
6
|
*
|
|
5
|
-
* Task 2365
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
|
|
7
|
+
* Task 2365 keyed on (account, botType), which cannot express N bots in one
|
|
8
|
+
* account: a second admin bot in one account would overwrite the first's
|
|
9
|
+
* secret and break it with no signal. The bot id can, and it is the same
|
|
10
|
+
* value the registered URL names, so the file and the URL cannot disagree.
|
|
11
|
+
* The reader (platform/ui/server/routes/telegram.ts secretPath) builds the
|
|
12
|
+
* same string; the duplication across the plugin/platform boundary is
|
|
13
|
+
* deliberate and ui/server/__tests__/telegram-secret-path.test.ts asserts the
|
|
14
|
+
* two agree.
|
|
15
|
+
*
|
|
16
|
+
* `botId` is digits by construction (botIdFromToken rejects anything else), so
|
|
17
|
+
* it cannot contribute a traversal. */
|
|
18
|
+
export declare function resolveSecretFilePath(botId: string): string;
|
|
16
19
|
//# sourceMappingURL=secret-path.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-path.d.ts","sourceRoot":"","sources":["../../src/lib/secret-path.ts"],"names":[],"mappings":"AAYA,wBAAgB,aAAa,IAAI,MAAM,CAWtC;AAED
|
|
1
|
+
{"version":3,"file":"secret-path.d.ts","sourceRoot":"","sources":["../../src/lib/secret-path.ts"],"names":[],"mappings":"AAYA,wBAAgB,aAAa,IAAI,MAAM,CAWtC;AAED;4DAC4D;AAC5D,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;;;;;;;;;wCAYwC;AACxC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D"}
|
|
@@ -22,29 +22,25 @@ export function configDirName() {
|
|
|
22
22
|
}
|
|
23
23
|
return ".maxy";
|
|
24
24
|
}
|
|
25
|
-
/**
|
|
26
|
-
*
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* per bot type, so a second account registering an admin bot overwrote the
|
|
30
|
-
* first account's secret and broke it with no signal. The reader
|
|
31
|
-
* (platform/ui/server/routes/telegram.ts secretPath) builds the same string;
|
|
32
|
-
* the duplication across the plugin/platform boundary is deliberate and
|
|
33
|
-
* ui/server/__tests__/telegram-secret-path.test.ts asserts the two agree. */
|
|
34
|
-
export function resolveSecretFilePath(botType, accountId) {
|
|
35
|
-
const maxyDir = resolve(homedir(), configDirName());
|
|
36
|
-
const stem = botType === "admin"
|
|
37
|
-
? ".telegram-admin-webhook-secret"
|
|
38
|
-
: ".telegram-webhook-secret";
|
|
39
|
-
return resolve(maxyDir, `${stem}.${accountId}`);
|
|
25
|
+
/** The directory holding one secret file per registered bot. Created mode 700
|
|
26
|
+
* by the register tool; the secrets themselves are 600. */
|
|
27
|
+
export function telegramSecretsDir() {
|
|
28
|
+
return resolve(homedir(), configDirName(), "telegram-secrets");
|
|
40
29
|
}
|
|
41
|
-
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
30
|
+
/** Task 2368 — the webhook secret path, keyed on the bot's own Telegram id.
|
|
31
|
+
*
|
|
32
|
+
* Task 2365 keyed on (account, botType), which cannot express N bots in one
|
|
33
|
+
* account: a second admin bot in one account would overwrite the first's
|
|
34
|
+
* secret and break it with no signal. The bot id can, and it is the same
|
|
35
|
+
* value the registered URL names, so the file and the URL cannot disagree.
|
|
36
|
+
* The reader (platform/ui/server/routes/telegram.ts secretPath) builds the
|
|
37
|
+
* same string; the duplication across the plugin/platform boundary is
|
|
38
|
+
* deliberate and ui/server/__tests__/telegram-secret-path.test.ts asserts the
|
|
39
|
+
* two agree.
|
|
40
|
+
*
|
|
41
|
+
* `botId` is digits by construction (botIdFromToken rejects anything else), so
|
|
42
|
+
* it cannot contribute a traversal. */
|
|
43
|
+
export function resolveSecretFilePath(botId) {
|
|
44
|
+
return resolve(telegramSecretsDir(), botId);
|
|
49
45
|
}
|
|
50
46
|
//# sourceMappingURL=secret-path.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-path.js","sourceRoot":"","sources":["../../src/lib/secret-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnD,2EAA2E;AAC3E,uEAAuE;AACvE,mCAAmC;AACnC,EAAE;AACF,wDAAwD;AACxD,6EAA6E;AAC7E,0EAA0E;AAC1E,kEAAkE;AAClE,MAAM,UAAU,aAAa;IAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC/C,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC7D,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC;YAC3E,CAAC;YAAC,MAAM,CAAC,CAAC,wBAAwB,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"secret-path.js","sourceRoot":"","sources":["../../src/lib/secret-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnD,2EAA2E;AAC3E,uEAAuE;AACvE,mCAAmC;AACnC,EAAE;AACF,wDAAwD;AACxD,6EAA6E;AAC7E,0EAA0E;AAC1E,kEAAkE;AAClE,MAAM,UAAU,aAAa;IAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC/C,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC7D,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC;YAC3E,CAAC;YAAC,MAAM,CAAC,CAAC,wBAAwB,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;4DAC4D;AAC5D,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;;;;;;;wCAYwC;AACxC,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,OAAO,OAAO,CAAC,kBAAkB,EAAE,EAAE,KAAK,CAAC,CAAC;AAC9C,CAAC"}
|