@mulmobridge/line 1.0.1 → 1.0.3

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/dist/index.js CHANGED
@@ -95,8 +95,8 @@ async function pushMessage(userId, text) {
95
95
  const app = createWebhookApp();
96
96
  const webhookRateLimit = createWebhookRateLimit();
97
97
  app.post("/webhook", webhookRateLimit, async (req, res) => {
98
- const signature = req.headers["x-line-signature"];
99
- const bodyStr = req.body;
98
+ const signature = typeof req.headers["x-line-signature"] === "string" ? req.headers["x-line-signature"] : "";
99
+ const bodyStr = typeof req.body === "string" ? req.body : "";
100
100
  if (!signature || !verifyHmacSignature(bodyStr, signature, channelSecret)) {
101
101
  res.status(401).send("Invalid signature");
102
102
  return;
package/dist/parse.d.ts CHANGED
@@ -41,5 +41,7 @@ export type IncomingLineMessage = {
41
41
  * unsupported media). Pure — no side effects, no allowlist check.
42
42
  */
43
43
  export declare function extractIncomingLineMessage(event: LineEvent): IncomingLineMessage | null;
44
- /** Best-effort JSON parse for the webhook body — null on malformed input. */
44
+ /** Best-effort JSON parse for the webhook body — null on malformed input.
45
+ * Events that don't match `LineEvent` are dropped rather than handed on as if
46
+ * they did: a `null` element used to throw inside the delivery loop. */
45
47
  export declare function parseLineWebhookBody(raw: string): LineWebhookBody | null;
package/dist/parse.js CHANGED
@@ -24,14 +24,46 @@ export function extractIncomingLineMessage(event) {
24
24
  }
25
25
  return null;
26
26
  }
27
- /** Best-effort JSON parse for the webhook body — null on malformed input. */
27
+ const isOptionalString = (value) => value === undefined || typeof value === "string";
28
+ function isLineEventSource(value) {
29
+ if (typeof value !== "object" || value === null)
30
+ return false;
31
+ if ("userId" in value && !isOptionalString(value.userId))
32
+ return false;
33
+ return !("type" in value) || isOptionalString(value.type);
34
+ }
35
+ function isLineMessage(value) {
36
+ if (typeof value !== "object" || value === null)
37
+ return false;
38
+ if (!("type" in value) || typeof value.type !== "string")
39
+ return false;
40
+ if ("text" in value && !isOptionalString(value.text))
41
+ return false;
42
+ return !("id" in value) || isOptionalString(value.id);
43
+ }
44
+ /** True only when every field `LineEvent` declares is present in the shape it
45
+ * declares. Extra platform fields we don't model are left untouched. */
46
+ function isLineEvent(value) {
47
+ if (typeof value !== "object" || value === null)
48
+ return false;
49
+ if (!("type" in value) || typeof value.type !== "string")
50
+ return false;
51
+ if ("replyToken" in value && !isOptionalString(value.replyToken))
52
+ return false;
53
+ if ("source" in value && value.source !== undefined && !isLineEventSource(value.source))
54
+ return false;
55
+ return !("message" in value) || value.message === undefined || isLineMessage(value.message);
56
+ }
57
+ /** Best-effort JSON parse for the webhook body — null on malformed input.
58
+ * Events that don't match `LineEvent` are dropped rather than handed on as if
59
+ * they did: a `null` element used to throw inside the delivery loop. */
28
60
  export function parseLineWebhookBody(raw) {
29
61
  try {
30
62
  const parsed = JSON.parse(raw);
31
- if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.events)) {
63
+ if (typeof parsed !== "object" || parsed === null || !("events" in parsed))
32
64
  return null;
33
- }
34
- return parsed;
65
+ const { events } = parsed;
66
+ return Array.isArray(events) ? { events: events.filter(isLineEvent) } : null;
35
67
  }
36
68
  catch {
37
69
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mulmobridge/line",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "LINE bridge for MulmoBridge — connect a LINE bot to MulmoClaude",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -24,14 +24,14 @@
24
24
  "dependencies": {
25
25
  "@mulmobridge/client": "^1.0.1",
26
26
  "@mulmobridge/protocol": "^1.0.1",
27
- "@mulmobridge/webhook-runtime": "^1.0.2",
27
+ "@mulmobridge/webhook-runtime": "^1.0.3",
28
28
  "dotenv": "^17.0.0",
29
29
  "express": "^5.1.0",
30
- "express-rate-limit": "^8.6.0"
30
+ "express-rate-limit": "^8.6.1"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/express": "^5.0.0",
34
- "@types/node": "^26.1.1",
34
+ "@types/node": "^26.1.2",
35
35
  "tsx": "^4.23.1",
36
36
  "typescript": "^6.0.3"
37
37
  },