From 612eb4921b12bbbf02b0648d7e678435439195da Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 12 Jun 2026 23:30:06 -0400 Subject: [PATCH] x --- apps/backend/src/routes/line.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/backend/src/routes/line.ts b/apps/backend/src/routes/line.ts index 22fa2d7..cbd63bb 100644 --- a/apps/backend/src/routes/line.ts +++ b/apps/backend/src/routes/line.ts @@ -12,21 +12,32 @@ export const lineRoutes = new Elysia({ prefix: '/line' }) return { error: 'Missing Signature' }; } - // get raw body string - const rawBody = await request.clone().text(); + // In Elysia, application/json is automatically parsed into an object. + // We stringify it back to a string for signature validation. + // Note: This works if the original payload didn't have special formatting spaces. + const rawBody = typeof body === 'string' ? body : JSON.stringify(body); + + if (!rawBody) { + set.status = 400; + return { error: 'Empty Body' }; + } const hash = crypto .createHmac('SHA256', lineConfig.channelSecret) .update(rawBody) .digest('base64'); + console.log('[LINE Webhook] Signature Check - Received:', signature, 'Calculated:', hash); + if (hash !== signature) { + console.error('[LINE Webhook] Invalid Signature Blocked'); set.status = 401; return { error: 'Invalid Signature' }; } try { - const events: line.WebhookEvent[] = (body as any).events || []; + const parsedBody = typeof body === 'string' ? JSON.parse(body) : body; + const events: line.WebhookEvent[] = parsedBody.events || []; for (const event of events) { if (event.type === 'message' && event.message.type === 'text') { @@ -51,4 +62,6 @@ export const lineRoutes = new Elysia({ prefix: '/line' }) set.status = 500; return { error: 'Webhook processing failed' }; } + }, { + type: 'text' });