Co-authored-by: domfelipe <53182096+domfelipe@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot] 2026-05-23 17:55:11 +00:00
parent 1674e4c2cf
commit 262ff41baa
3 changed files with 47 additions and 1 deletions

View file

@ -114,6 +114,7 @@ Deno.serve(async (req) => {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${serviceKey}`,
"X-Internal-Secret": Deno.env.get("INTERNAL_FUNCTION_SECRET") ?? "",
},
body: JSON.stringify({
agent_instance_id: agent.id,

View file

@ -53,6 +53,20 @@ Deno.serve(async (req) => {
return ack();
}
// Verificação de origem: se TELEGRAM_MANAGER_BOT_WEBHOOK_SECRET estiver
// configurado, exige o header X-Telegram-Bot-Api-Secret-Token correspondente.
// Caso contrário, opera em modo permissivo (comportamento anterior) + log.
const expectedSecret = Deno.env.get("TELEGRAM_MANAGER_BOT_WEBHOOK_SECRET") ?? "";
if (expectedSecret) {
const incoming = req.headers.get("X-Telegram-Bot-Api-Secret-Token") ?? "";
if (incoming !== expectedSecret) {
console.warn("managed-bot-webhook: invalid telegram secret token");
return new Response("unauthorized", { status: 401 });
}
} else {
console.warn("managed-bot-webhook: TELEGRAM_MANAGER_BOT_WEBHOOK_SECRET ausente — modo permissivo");
}
if (!managerToken) {
console.error("TELEGRAM_MANAGER_BOT_TOKEN ausente");
return ack();
@ -165,6 +179,7 @@ Deno.serve(async (req) => {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${serviceKey}`,
"X-Internal-Secret": Deno.env.get("INTERNAL_FUNCTION_SECRET") ?? "",
},
body: JSON.stringify({
agent_instance_id: agentInstance.id,

View file

@ -48,9 +48,39 @@ Deno.serve(async (req) => {
return jsonResponse(200, { ignored: true, reason: "method not allowed" });
}
const rawBody = await req.text();
// Verificação de assinatura: modo permissivo se RAILWAY_WEBHOOK_SECRET não estiver
// configurado (mantém comportamento atual). Quando configurado, exige HMAC SHA-256.
const railwaySecret = Deno.env.get("RAILWAY_WEBHOOK_SECRET") ?? "";
if (railwaySecret) {
const sig = req.headers.get("X-Railway-Signature") ?? "";
try {
const key = await crypto.subtle.importKey(
"raw",
new TextEncoder().encode(railwaySecret),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"],
);
const macBuf = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(rawBody));
const macHex = Array.from(new Uint8Array(macBuf)).map((b) => b.toString(16).padStart(2, "0")).join("");
const expected = sig.startsWith("sha256=") ? sig.slice(7) : sig;
if (expected !== macHex) {
console.warn("railway-webhook: invalid signature");
return jsonResponse(401, { error: "invalid signature" });
}
} catch (e) {
console.error("railway-webhook: signature verify failed:", String(e));
return jsonResponse(401, { error: "signature verification failed" });
}
} else {
console.warn("railway-webhook: RAILWAY_WEBHOOK_SECRET ausente — modo permissivo");
}
let payload: Record<string, unknown>;
try {
payload = await req.json();
payload = JSON.parse(rawBody);
} catch {
console.log("railway-webhook: invalid json body");
return jsonResponse(200, { ignored: true, reason: "invalid json" });