@kya-os/agentshield-nextjs 0.1.29 → 0.1.31

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.
Files changed (46) hide show
  1. package/dist/create-middleware.js +591 -12
  2. package/dist/create-middleware.js.map +1 -1
  3. package/dist/create-middleware.mjs +591 -12
  4. package/dist/create-middleware.mjs.map +1 -1
  5. package/dist/edge-detector-wrapper.js +251 -12
  6. package/dist/edge-detector-wrapper.js.map +1 -1
  7. package/dist/edge-detector-wrapper.mjs +251 -12
  8. package/dist/edge-detector-wrapper.mjs.map +1 -1
  9. package/dist/index.js +591 -12
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +591 -12
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/middleware.js +587 -8
  14. package/dist/middleware.js.map +1 -1
  15. package/dist/middleware.mjs +587 -8
  16. package/dist/middleware.mjs.map +1 -1
  17. package/dist/signature-verifier.js +220 -0
  18. package/dist/signature-verifier.js.map +1 -0
  19. package/dist/signature-verifier.mjs +216 -0
  20. package/dist/signature-verifier.mjs.map +1 -0
  21. package/package.json +2 -2
  22. package/wasm/agentshield_wasm.d.ts +121 -0
  23. package/wasm/agentshield_wasm.js +576 -0
  24. package/wasm/agentshield_wasm_bg.wasm +0 -0
  25. package/dist/create-middleware.d.mts +0 -16
  26. package/dist/create-middleware.d.ts +0 -16
  27. package/dist/edge-detector-wrapper.d.mts +0 -42
  28. package/dist/edge-detector-wrapper.d.ts +0 -42
  29. package/dist/edge-runtime-loader.d.mts +0 -49
  30. package/dist/edge-runtime-loader.d.ts +0 -49
  31. package/dist/edge-wasm-middleware.d.mts +0 -58
  32. package/dist/edge-wasm-middleware.d.ts +0 -58
  33. package/dist/index.d.mts +0 -19
  34. package/dist/index.d.ts +0 -19
  35. package/dist/middleware.d.mts +0 -20
  36. package/dist/middleware.d.ts +0 -20
  37. package/dist/nodejs-wasm-loader.d.mts +0 -25
  38. package/dist/nodejs-wasm-loader.d.ts +0 -25
  39. package/dist/session-tracker.d.mts +0 -55
  40. package/dist/session-tracker.d.ts +0 -55
  41. package/dist/types-BJTEUa4T.d.mts +0 -88
  42. package/dist/types-BJTEUa4T.d.ts +0 -88
  43. package/dist/wasm-middleware.d.mts +0 -62
  44. package/dist/wasm-middleware.d.ts +0 -62
  45. package/dist/wasm-setup.d.mts +0 -46
  46. package/dist/wasm-setup.d.ts +0 -46
package/dist/index.js CHANGED
@@ -4,6 +4,219 @@ var server = require('next/server');
4
4
 
5
5
  // src/create-middleware.ts
6
6
 
7
+ // src/signature-verifier.ts
8
+ var KNOWN_KEYS = {
9
+ chatgpt: [
10
+ {
11
+ kid: "otMqcjr17mGyruktGvJU8oojQTSMHlVm7uO-lrcqbdg",
12
+ // ChatGPT's current Ed25519 public key (base64)
13
+ publicKey: "7F_3jDlxaquwh291MiACkcS3Opq88NksyHiakzS-Y1g",
14
+ validFrom: (/* @__PURE__ */ new Date("2025-01-01")).getTime() / 1e3,
15
+ validUntil: (/* @__PURE__ */ new Date("2025-04-11")).getTime() / 1e3
16
+ }
17
+ ]
18
+ };
19
+ function parseSignatureInput(signatureInput) {
20
+ try {
21
+ const match = signatureInput.match(/sig1=\((.*?)\);(.+)/);
22
+ if (!match) return null;
23
+ const [, headersList, params] = match;
24
+ const signedHeaders = headersList.split(" ").map((h) => h.replace(/"/g, "").trim()).filter((h) => h.length > 0);
25
+ const keyidMatch = params.match(/keyid="([^"]+)"/);
26
+ const createdMatch = params.match(/created=(\d+)/);
27
+ const expiresMatch = params.match(/expires=(\d+)/);
28
+ if (!keyidMatch) return null;
29
+ return {
30
+ keyid: keyidMatch[1],
31
+ created: createdMatch ? parseInt(createdMatch[1]) : void 0,
32
+ expires: expiresMatch ? parseInt(expiresMatch[1]) : void 0,
33
+ signedHeaders
34
+ };
35
+ } catch (error) {
36
+ console.error("[Signature] Failed to parse Signature-Input:", error);
37
+ return null;
38
+ }
39
+ }
40
+ function buildSignatureBase(method, path, headers, signedHeaders) {
41
+ const components = [];
42
+ for (const headerName of signedHeaders) {
43
+ let value;
44
+ switch (headerName) {
45
+ case "@method":
46
+ value = method.toUpperCase();
47
+ break;
48
+ case "@path":
49
+ value = path;
50
+ break;
51
+ case "@authority":
52
+ value = headers["host"] || headers["Host"] || "";
53
+ break;
54
+ default:
55
+ const key = Object.keys(headers).find(
56
+ (k) => k.toLowerCase() === headerName.toLowerCase()
57
+ );
58
+ value = key ? headers[key] : "";
59
+ break;
60
+ }
61
+ components.push(`"${headerName}": ${value}`);
62
+ }
63
+ return components.join("\n");
64
+ }
65
+ async function verifyEd25519Signature(publicKeyBase64, signatureBase64, message) {
66
+ try {
67
+ const publicKeyBytes = Uint8Array.from(atob(publicKeyBase64), (c) => c.charCodeAt(0));
68
+ const signatureBytes = Uint8Array.from(atob(signatureBase64), (c) => c.charCodeAt(0));
69
+ const messageBytes = new TextEncoder().encode(message);
70
+ if (publicKeyBytes.length !== 32) {
71
+ console.error("[Signature] Invalid public key length:", publicKeyBytes.length);
72
+ return false;
73
+ }
74
+ if (signatureBytes.length !== 64) {
75
+ console.error("[Signature] Invalid signature length:", signatureBytes.length);
76
+ return false;
77
+ }
78
+ const publicKey = await crypto.subtle.importKey(
79
+ "raw",
80
+ publicKeyBytes,
81
+ {
82
+ name: "Ed25519",
83
+ namedCurve: "Ed25519"
84
+ },
85
+ false,
86
+ ["verify"]
87
+ );
88
+ const isValid = await crypto.subtle.verify(
89
+ "Ed25519",
90
+ publicKey,
91
+ signatureBytes,
92
+ messageBytes
93
+ );
94
+ return isValid;
95
+ } catch (error) {
96
+ console.error("[Signature] Ed25519 verification failed:", error);
97
+ if (typeof window === "undefined") {
98
+ try {
99
+ console.warn("[Signature] Ed25519 not supported in this environment");
100
+ return false;
101
+ } catch {
102
+ return false;
103
+ }
104
+ }
105
+ return false;
106
+ }
107
+ }
108
+ async function verifyAgentSignature(method, path, headers) {
109
+ const signature = headers["signature"] || headers["Signature"];
110
+ const signatureInput = headers["signature-input"] || headers["Signature-Input"];
111
+ const signatureAgent = headers["signature-agent"] || headers["Signature-Agent"];
112
+ if (!signature || !signatureInput) {
113
+ return {
114
+ isValid: false,
115
+ confidence: 0,
116
+ reason: "No signature headers present",
117
+ verificationMethod: "none"
118
+ };
119
+ }
120
+ const parsed = parseSignatureInput(signatureInput);
121
+ if (!parsed) {
122
+ return {
123
+ isValid: false,
124
+ confidence: 0,
125
+ reason: "Invalid Signature-Input header",
126
+ verificationMethod: "none"
127
+ };
128
+ }
129
+ if (parsed.created) {
130
+ const now2 = Math.floor(Date.now() / 1e3);
131
+ const age = now2 - parsed.created;
132
+ if (age > 300) {
133
+ return {
134
+ isValid: false,
135
+ confidence: 0,
136
+ reason: "Signature expired (older than 5 minutes)",
137
+ verificationMethod: "none"
138
+ };
139
+ }
140
+ if (age < -30) {
141
+ return {
142
+ isValid: false,
143
+ confidence: 0,
144
+ reason: "Signature timestamp is in the future",
145
+ verificationMethod: "none"
146
+ };
147
+ }
148
+ }
149
+ let agent;
150
+ let knownKeys;
151
+ if (signatureAgent === '"https://chatgpt.com"' || signatureAgent?.includes("chatgpt.com")) {
152
+ agent = "ChatGPT";
153
+ knownKeys = KNOWN_KEYS.chatgpt;
154
+ }
155
+ if (!agent || !knownKeys) {
156
+ return {
157
+ isValid: false,
158
+ confidence: 0,
159
+ reason: "Unknown signature agent",
160
+ verificationMethod: "none"
161
+ };
162
+ }
163
+ const key = knownKeys.find((k) => k.kid === parsed.keyid);
164
+ if (!key) {
165
+ return {
166
+ isValid: false,
167
+ confidence: 0,
168
+ reason: `Unknown key ID: ${parsed.keyid}`,
169
+ verificationMethod: "none"
170
+ };
171
+ }
172
+ const now = Math.floor(Date.now() / 1e3);
173
+ if (now < key.validFrom || now > key.validUntil) {
174
+ return {
175
+ isValid: false,
176
+ confidence: 0,
177
+ reason: "Key is not valid at current time",
178
+ verificationMethod: "none"
179
+ };
180
+ }
181
+ const signatureBase = buildSignatureBase(method, path, headers, parsed.signedHeaders);
182
+ let signatureValue = signature;
183
+ if (signatureValue.startsWith("sig1=:")) {
184
+ signatureValue = signatureValue.substring(6);
185
+ }
186
+ if (signatureValue.endsWith(":")) {
187
+ signatureValue = signatureValue.slice(0, -1);
188
+ }
189
+ const isValid = await verifyEd25519Signature(
190
+ key.publicKey,
191
+ signatureValue,
192
+ signatureBase
193
+ );
194
+ if (isValid) {
195
+ return {
196
+ isValid: true,
197
+ agent,
198
+ keyid: parsed.keyid,
199
+ confidence: 1,
200
+ // 100% confidence for valid signature
201
+ verificationMethod: "signature"
202
+ };
203
+ } else {
204
+ return {
205
+ isValid: false,
206
+ confidence: 0,
207
+ reason: "Signature verification failed",
208
+ verificationMethod: "none"
209
+ };
210
+ }
211
+ }
212
+ function hasSignatureHeaders(headers) {
213
+ return !!((headers["signature"] || headers["Signature"]) && (headers["signature-input"] || headers["Signature-Input"]));
214
+ }
215
+ function isChatGPTSignature(headers) {
216
+ const signatureAgent = headers["signature-agent"] || headers["Signature-Agent"];
217
+ return signatureAgent === '"https://chatgpt.com"' || (signatureAgent?.includes("chatgpt.com") || false);
218
+ }
219
+
7
220
  // src/edge-detector-wrapper.ts
8
221
  var AI_AGENT_PATTERNS = [
9
222
  { pattern: /chatgpt-user/i, type: "chatgpt", name: "ChatGPT" },
@@ -23,6 +236,312 @@ var CLOUD_PROVIDERS = {
23
236
  };
24
237
  var EdgeAgentDetector = class {
25
238
  async analyze(input) {
239
+ const reasons = [];
240
+ let detectedAgent;
241
+ let verificationMethod;
242
+ let confidence = 0;
243
+ const headers = input.headers || {};
244
+ const normalizedHeaders = {};
245
+ for (const [key, value] of Object.entries(headers)) {
246
+ normalizedHeaders[key.toLowerCase()] = value;
247
+ }
248
+ if (hasSignatureHeaders(headers)) {
249
+ try {
250
+ const signatureResult = await verifyAgentSignature(
251
+ input.method || "GET",
252
+ input.url || "/",
253
+ headers
254
+ );
255
+ if (signatureResult.isValid) {
256
+ confidence = signatureResult.confidence;
257
+ reasons.push(`verified_signature:${signatureResult.agent?.toLowerCase() || "unknown"}`);
258
+ if (signatureResult.agent) {
259
+ detectedAgent = {
260
+ type: signatureResult.agent.toLowerCase(),
261
+ name: signatureResult.agent
262
+ };
263
+ }
264
+ verificationMethod = signatureResult.verificationMethod;
265
+ if (signatureResult.keyid) {
266
+ reasons.push(`keyid:${signatureResult.keyid}`);
267
+ }
268
+ } else {
269
+ confidence = Math.max(confidence, 0.3);
270
+ reasons.push("invalid_signature");
271
+ if (signatureResult.reason) {
272
+ reasons.push(`signature_error:${signatureResult.reason}`);
273
+ }
274
+ if (isChatGPTSignature(headers)) {
275
+ reasons.push("claims_chatgpt");
276
+ detectedAgent = { type: "chatgpt", name: "ChatGPT (unverified)" };
277
+ }
278
+ }
279
+ } catch (error) {
280
+ console.error("[EdgeAgentDetector] Signature verification error:", error);
281
+ confidence = Math.max(confidence, 0.2);
282
+ reasons.push("signature_verification_error");
283
+ }
284
+ }
285
+ const userAgent = input.userAgent || input.headers?.["user-agent"] || "";
286
+ if (userAgent) {
287
+ for (const { pattern, type, name } of AI_AGENT_PATTERNS) {
288
+ if (pattern.test(userAgent)) {
289
+ const highConfidenceAgents = [
290
+ "chatgpt",
291
+ "claude",
292
+ "perplexity",
293
+ "anthropic"
294
+ ];
295
+ const patternConfidence = highConfidenceAgents.includes(type) ? 0.85 : 0.5;
296
+ confidence = Math.max(confidence, patternConfidence);
297
+ reasons.push(`known_pattern:${type}`);
298
+ if (!detectedAgent) {
299
+ detectedAgent = { type, name };
300
+ verificationMethod = "pattern";
301
+ }
302
+ break;
303
+ }
304
+ }
305
+ }
306
+ const aiHeaders = [
307
+ "openai-conversation-id",
308
+ "openai-ephemeral-user-id",
309
+ "anthropic-client-id",
310
+ "x-goog-api-client",
311
+ "x-ms-copilot-id"
312
+ ];
313
+ const foundAiHeaders = aiHeaders.filter(
314
+ (header) => normalizedHeaders[header]
315
+ );
316
+ if (foundAiHeaders.length > 0) {
317
+ confidence = Math.max(confidence, 0.6);
318
+ reasons.push(`ai_headers:${foundAiHeaders.length}`);
319
+ }
320
+ const ip = input.ip || input.ipAddress;
321
+ if (ip && !normalizedHeaders["x-forwarded-for"] && !normalizedHeaders["x-real-ip"]) {
322
+ for (const [provider, prefixes] of Object.entries(CLOUD_PROVIDERS)) {
323
+ if (prefixes.some((prefix) => ip.startsWith(prefix))) {
324
+ confidence = Math.max(confidence, 0.4);
325
+ reasons.push(`cloud_provider:${provider}`);
326
+ break;
327
+ }
328
+ }
329
+ }
330
+ if (reasons.length > 2 && confidence < 1) {
331
+ confidence = Math.min(confidence * 1.2, 0.95);
332
+ }
333
+ return {
334
+ isAgent: confidence > 0.3,
335
+ confidence,
336
+ ...detectedAgent && { detectedAgent },
337
+ reasons,
338
+ ...verificationMethod && { verificationMethod },
339
+ forgeabilityRisk: verificationMethod === "signature" ? "low" : confidence > 0.8 ? "medium" : "high",
340
+ timestamp: /* @__PURE__ */ new Date()
341
+ };
342
+ }
343
+ };
344
+ var EdgeAgentDetectorWrapper = class {
345
+ detector;
346
+ events = /* @__PURE__ */ new Map();
347
+ constructor(_config) {
348
+ this.detector = new EdgeAgentDetector();
349
+ }
350
+ async analyze(input) {
351
+ const result = await this.detector.analyze(input);
352
+ if (result.isAgent && this.events.has("agent.detected")) {
353
+ const handlers = this.events.get("agent.detected") || [];
354
+ handlers.forEach((handler) => handler(result, input));
355
+ }
356
+ return result;
357
+ }
358
+ on(event, handler) {
359
+ if (!this.events.has(event)) {
360
+ this.events.set(event, []);
361
+ }
362
+ this.events.get(event).push(handler);
363
+ }
364
+ emit(event, ...args) {
365
+ const handlers = this.events.get(event) || [];
366
+ handlers.forEach((handler) => handler(...args));
367
+ }
368
+ async init() {
369
+ return;
370
+ }
371
+ };
372
+
373
+ // src/wasm-loader.ts
374
+ var wasmInstance = null;
375
+ var wasmExports = null;
376
+ var initPromise = null;
377
+ var WASM_PATH = "/wasm/agentshield_wasm_bg.wasm";
378
+ async function initWasm() {
379
+ if (wasmExports) return true;
380
+ if (initPromise) {
381
+ await initPromise;
382
+ return !!wasmExports;
383
+ }
384
+ initPromise = (async () => {
385
+ try {
386
+ if (typeof WebAssembly.instantiateStreaming === "function") {
387
+ try {
388
+ const response2 = await fetch(WASM_PATH);
389
+ if (!response2.ok) {
390
+ throw new Error(`Failed to fetch WASM: ${response2.status}`);
391
+ }
392
+ const streamResponse = response2.clone();
393
+ const { instance } = await WebAssembly.instantiateStreaming(
394
+ streamResponse,
395
+ {
396
+ wbg: {
397
+ __wbg_log_1d3ae13c3d5e6b8e: (ptr, len) => {
398
+ console.log("WASM:", ptr, len);
399
+ },
400
+ __wbindgen_throw: (ptr, len) => {
401
+ throw new Error(`WASM Error at ${ptr}, length ${len}`);
402
+ }
403
+ }
404
+ }
405
+ );
406
+ wasmInstance = instance;
407
+ wasmExports = instance.exports;
408
+ console.log("[AgentShield] \u2705 WASM module initialized with streaming");
409
+ return;
410
+ } catch (streamError) {
411
+ console.log("[AgentShield] Streaming compilation failed, falling back to standard compilation");
412
+ }
413
+ }
414
+ const response = await fetch(WASM_PATH);
415
+ if (!response.ok) {
416
+ throw new Error(`Failed to fetch WASM: ${response.status}`);
417
+ }
418
+ const wasmArrayBuffer = await response.arrayBuffer();
419
+ const compiledModule = await WebAssembly.compile(wasmArrayBuffer);
420
+ const imports = {
421
+ wbg: {
422
+ __wbg_log_1d3ae13c3d5e6b8e: (ptr, len) => {
423
+ console.log("WASM:", ptr, len);
424
+ },
425
+ __wbindgen_throw: (ptr, len) => {
426
+ throw new Error(`WASM Error at ${ptr}, length ${len}`);
427
+ }
428
+ }
429
+ };
430
+ wasmInstance = await WebAssembly.instantiate(compiledModule, imports);
431
+ wasmExports = wasmInstance.exports;
432
+ console.log("[AgentShield] \u2705 WASM module initialized via fallback");
433
+ } catch (error) {
434
+ console.error("[AgentShield] Failed to initialize WASM:", error);
435
+ wasmExports = null;
436
+ }
437
+ })();
438
+ await initPromise;
439
+ return !!wasmExports;
440
+ }
441
+ async function detectAgentWithWasm(userAgent, headers, ipAddress) {
442
+ const initialized = await initWasm();
443
+ if (!initialized || !wasmExports) {
444
+ return null;
445
+ }
446
+ try {
447
+ const headersJson = JSON.stringify(headers);
448
+ if (typeof wasmExports.detect_agent === "function") {
449
+ const result = wasmExports.detect_agent(
450
+ userAgent || "",
451
+ headersJson,
452
+ ipAddress || "",
453
+ (/* @__PURE__ */ new Date()).toISOString()
454
+ );
455
+ return {
456
+ isAgent: result.is_agent || false,
457
+ confidence: result.confidence || 0,
458
+ agent: result.agent,
459
+ verificationMethod: result.verification_method || "wasm",
460
+ riskLevel: result.risk_level || "low"
461
+ };
462
+ }
463
+ console.warn("[AgentShield] WASM exports do not include detect_agent function");
464
+ return null;
465
+ } catch (error) {
466
+ console.error("[AgentShield] WASM detection failed:", error);
467
+ return null;
468
+ }
469
+ }
470
+ async function getWasmVersion() {
471
+ const initialized = await initWasm();
472
+ if (!initialized || !wasmExports) {
473
+ return null;
474
+ }
475
+ if (typeof wasmExports.version === "function") {
476
+ return wasmExports.version();
477
+ }
478
+ return "unknown";
479
+ }
480
+ async function isWasmAvailable() {
481
+ try {
482
+ const initialized = await initWasm();
483
+ if (!initialized) return false;
484
+ const version = await getWasmVersion();
485
+ return version !== null;
486
+ } catch {
487
+ return false;
488
+ }
489
+ }
490
+
491
+ // src/edge-detector-with-wasm.ts
492
+ var AI_AGENT_PATTERNS2 = [
493
+ { pattern: /chatgpt-user/i, type: "chatgpt", name: "ChatGPT" },
494
+ { pattern: /claude-web/i, type: "claude", name: "Claude" },
495
+ { pattern: /perplexitybot/i, type: "perplexity", name: "Perplexity" },
496
+ { pattern: /perplexity-user/i, type: "perplexity", name: "Perplexity" },
497
+ { pattern: /perplexity-ai/i, type: "perplexity", name: "Perplexity" },
498
+ { pattern: /perplexity/i, type: "perplexity", name: "Perplexity" },
499
+ { pattern: /bingbot/i, type: "bing", name: "Bing AI" },
500
+ { pattern: /anthropic-ai/i, type: "anthropic", name: "Anthropic" }
501
+ ];
502
+ var CLOUD_PROVIDERS2 = {
503
+ aws: ["54.", "52.", "35.", "18.", "3."],
504
+ gcp: ["35.", "34.", "104.", "107.", "108."],
505
+ azure: ["13.", "20.", "40.", "52.", "104."]
506
+ };
507
+ var EdgeAgentDetectorWithWasm = class {
508
+ constructor(enableWasm = true) {
509
+ this.enableWasm = enableWasm;
510
+ }
511
+ wasmEnabled = false;
512
+ initPromise = null;
513
+ /**
514
+ * Initialize the detector (including WASM if enabled)
515
+ */
516
+ async init() {
517
+ if (!this.enableWasm) {
518
+ this.wasmEnabled = false;
519
+ return;
520
+ }
521
+ if (this.initPromise) {
522
+ await this.initPromise;
523
+ return;
524
+ }
525
+ this.initPromise = (async () => {
526
+ try {
527
+ const wasmAvailable = await isWasmAvailable();
528
+ this.wasmEnabled = wasmAvailable;
529
+ if (this.wasmEnabled) {
530
+ console.log("[AgentShield] WASM detection enabled");
531
+ } else {
532
+ console.log("[AgentShield] WASM not available, using pattern detection");
533
+ }
534
+ } catch (error) {
535
+ console.error("[AgentShield] Failed to initialize WASM:", error);
536
+ this.wasmEnabled = false;
537
+ }
538
+ })();
539
+ await this.initPromise;
540
+ }
541
+ /**
542
+ * Pattern-based detection (fallback)
543
+ */
544
+ async patternDetection(input) {
26
545
  const reasons = [];
27
546
  let detectedAgent;
28
547
  let verificationMethod;
@@ -45,7 +564,7 @@ var EdgeAgentDetector = class {
45
564
  }
46
565
  const userAgent = input.userAgent || input.headers?.["user-agent"] || "";
47
566
  if (userAgent) {
48
- for (const { pattern, type, name } of AI_AGENT_PATTERNS) {
567
+ for (const { pattern, type, name } of AI_AGENT_PATTERNS2) {
49
568
  if (pattern.test(userAgent)) {
50
569
  const highConfidenceAgents = [
51
570
  "chatgpt",
@@ -80,7 +599,7 @@ var EdgeAgentDetector = class {
80
599
  }
81
600
  const ip = input.ip || input.ipAddress;
82
601
  if (ip && !normalizedHeaders["x-forwarded-for"] && !normalizedHeaders["x-real-ip"]) {
83
- for (const [provider, prefixes] of Object.entries(CLOUD_PROVIDERS)) {
602
+ for (const [provider, prefixes] of Object.entries(CLOUD_PROVIDERS2)) {
84
603
  if (prefixes.some((prefix) => ip.startsWith(prefix))) {
85
604
  confidence = Math.max(confidence, 0.4);
86
605
  reasons.push(`cloud_provider:${provider}`);
@@ -101,12 +620,69 @@ var EdgeAgentDetector = class {
101
620
  timestamp: /* @__PURE__ */ new Date()
102
621
  };
103
622
  }
623
+ /**
624
+ * Analyze request with WASM enhancement when available
625
+ */
626
+ async analyze(input) {
627
+ await this.init();
628
+ if (this.wasmEnabled) {
629
+ try {
630
+ const wasmResult = await detectAgentWithWasm(
631
+ input.userAgent || input.headers?.["user-agent"],
632
+ input.headers || {},
633
+ input.ip || input.ipAddress
634
+ );
635
+ if (wasmResult) {
636
+ console.log("[AgentShield] Using WASM detection result");
637
+ const detectedAgent = wasmResult.agent ? this.mapAgentName(wasmResult.agent) : void 0;
638
+ return {
639
+ isAgent: wasmResult.isAgent,
640
+ confidence: wasmResult.confidence,
641
+ ...detectedAgent && { detectedAgent },
642
+ reasons: [`wasm:${wasmResult.verificationMethod}`],
643
+ verificationMethod: wasmResult.verificationMethod,
644
+ forgeabilityRisk: wasmResult.verificationMethod === "signature" ? "low" : wasmResult.confidence > 0.9 ? "medium" : "high",
645
+ timestamp: /* @__PURE__ */ new Date()
646
+ };
647
+ }
648
+ } catch (error) {
649
+ console.error("[AgentShield] WASM detection error:", error);
650
+ }
651
+ }
652
+ const patternResult = await this.patternDetection(input);
653
+ if (this.wasmEnabled && patternResult.confidence >= 0.85) {
654
+ patternResult.confidence = Math.min(0.95, patternResult.confidence + 0.1);
655
+ patternResult.reasons.push("wasm_enhanced");
656
+ if (!patternResult.verificationMethod) {
657
+ patternResult.verificationMethod = "wasm-enhanced";
658
+ }
659
+ }
660
+ return patternResult;
661
+ }
662
+ /**
663
+ * Map agent names from WASM to consistent format
664
+ */
665
+ mapAgentName(agent) {
666
+ const lowerAgent = agent.toLowerCase();
667
+ if (lowerAgent.includes("chatgpt")) {
668
+ return { type: "chatgpt", name: "ChatGPT" };
669
+ } else if (lowerAgent.includes("claude")) {
670
+ return { type: "claude", name: "Claude" };
671
+ } else if (lowerAgent.includes("perplexity")) {
672
+ return { type: "perplexity", name: "Perplexity" };
673
+ } else if (lowerAgent.includes("bing")) {
674
+ return { type: "bing", name: "Bing AI" };
675
+ } else if (lowerAgent.includes("anthropic")) {
676
+ return { type: "anthropic", name: "Anthropic" };
677
+ }
678
+ return { type: "unknown", name: agent };
679
+ }
104
680
  };
105
- var EdgeAgentDetectorWrapper = class {
681
+ var EdgeAgentDetectorWrapperWithWasm = class {
106
682
  detector;
107
683
  events = /* @__PURE__ */ new Map();
108
- constructor(_config) {
109
- this.detector = new EdgeAgentDetector();
684
+ constructor(config) {
685
+ this.detector = new EdgeAgentDetectorWithWasm(config?.enableWasm ?? true);
110
686
  }
111
687
  async analyze(input) {
112
688
  const result = await this.detector.analyze(input);
@@ -127,7 +703,7 @@ var EdgeAgentDetectorWrapper = class {
127
703
  handlers.forEach((handler) => handler(...args));
128
704
  }
129
705
  async init() {
130
- return;
706
+ await this.detector.init();
131
707
  }
132
708
  };
133
709
 
@@ -303,7 +879,7 @@ var StatelessSessionChecker = class {
303
879
 
304
880
  // src/middleware.ts
305
881
  function createAgentShieldMiddleware(config = {}) {
306
- const detector = new EdgeAgentDetectorWrapper(config);
882
+ const detector = config.enableWasm ? new EdgeAgentDetectorWrapperWithWasm({ enableWasm: true }) : new EdgeAgentDetectorWrapper(config);
307
883
  const sessionTracker = config.sessionTracking?.enabled || config.enableWasm ? new EdgeSessionTracker({
308
884
  enabled: true,
309
885
  ...config.sessionTracking
@@ -372,11 +948,14 @@ function createAgentShieldMiddleware(config = {}) {
372
948
  }
373
949
  const userAgent = request.headers.get("user-agent");
374
950
  const ipAddress = request.ip ?? request.headers.get("x-forwarded-for");
951
+ const url = new URL(request.url);
952
+ const pathWithQuery = url.pathname + url.search;
375
953
  const context = {
376
954
  ...userAgent && { userAgent },
377
955
  ...ipAddress && { ipAddress },
378
956
  headers: Object.fromEntries(request.headers.entries()),
379
- url: request.url,
957
+ url: pathWithQuery,
958
+ // Use path instead of full URL for signature verification
380
959
  method: request.method,
381
960
  timestamp: /* @__PURE__ */ new Date()
382
961
  };
@@ -459,19 +1038,19 @@ function createAgentShieldMiddleware(config = {}) {
459
1038
  // src/create-middleware.ts
460
1039
  var middlewareInstance = null;
461
1040
  var isInitializing = false;
462
- var initPromise = null;
1041
+ var initPromise2 = null;
463
1042
  function createAgentShieldMiddleware2(config) {
464
1043
  return async function agentShieldMiddleware(request) {
465
1044
  if (!middlewareInstance) {
466
1045
  if (!isInitializing) {
467
1046
  isInitializing = true;
468
- initPromise = (async () => {
1047
+ initPromise2 = (async () => {
469
1048
  middlewareInstance = createAgentShieldMiddleware(config);
470
1049
  return middlewareInstance;
471
1050
  })();
472
1051
  }
473
- if (initPromise) {
474
- middlewareInstance = await initPromise;
1052
+ if (initPromise2) {
1053
+ middlewareInstance = await initPromise2;
475
1054
  }
476
1055
  }
477
1056
  return middlewareInstance ? middlewareInstance(request) : server.NextResponse.next();