@kya-os/agentshield-nextjs 0.1.41 → 0.1.43
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/.tsbuildinfo +1 -0
- package/dist/api-client.d.mts +145 -0
- package/dist/api-client.d.ts +145 -0
- package/dist/api-client.js +130 -0
- package/dist/api-client.js.map +1 -0
- package/dist/api-client.mjs +126 -0
- package/dist/api-client.mjs.map +1 -0
- package/dist/api-middleware.d.mts +118 -0
- package/dist/api-middleware.d.ts +118 -0
- package/dist/api-middleware.js +295 -0
- package/dist/api-middleware.js.map +1 -0
- package/dist/api-middleware.mjs +292 -0
- package/dist/api-middleware.mjs.map +1 -0
- package/dist/create-middleware.d.mts +2 -1
- package/dist/create-middleware.d.ts +2 -1
- package/dist/create-middleware.js +474 -200
- package/dist/create-middleware.js.map +1 -1
- package/dist/create-middleware.mjs +454 -200
- package/dist/create-middleware.mjs.map +1 -1
- package/dist/edge/index.d.mts +110 -0
- package/dist/edge/index.d.ts +110 -0
- package/dist/edge/index.js +253 -0
- package/dist/edge/index.js.map +1 -0
- package/dist/edge/index.mjs +251 -0
- package/dist/edge/index.mjs.map +1 -0
- package/dist/edge-detector-wrapper.d.mts +6 -15
- package/dist/edge-detector-wrapper.d.ts +6 -15
- package/dist/edge-detector-wrapper.js +314 -95
- package/dist/edge-detector-wrapper.js.map +1 -1
- package/dist/edge-detector-wrapper.mjs +294 -95
- package/dist/edge-detector-wrapper.mjs.map +1 -1
- package/dist/edge-runtime-loader.d.mts +1 -1
- package/dist/edge-runtime-loader.d.ts +1 -1
- package/dist/edge-runtime-loader.js +10 -25
- package/dist/edge-runtime-loader.js.map +1 -1
- package/dist/edge-runtime-loader.mjs +11 -23
- package/dist/edge-runtime-loader.mjs.map +1 -1
- package/dist/edge-wasm-middleware.js +2 -1
- package/dist/edge-wasm-middleware.js.map +1 -1
- package/dist/edge-wasm-middleware.mjs +2 -1
- package/dist/edge-wasm-middleware.mjs.map +1 -1
- package/dist/enhanced-middleware.d.mts +153 -0
- package/dist/enhanced-middleware.d.ts +153 -0
- package/dist/enhanced-middleware.js +1074 -0
- package/dist/enhanced-middleware.js.map +1 -0
- package/dist/enhanced-middleware.mjs +1072 -0
- package/dist/enhanced-middleware.mjs.map +1 -0
- package/dist/index.d.mts +8 -153
- package/dist/index.d.ts +8 -153
- package/dist/index.js +821 -233
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +797 -234
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.d.mts +2 -1
- package/dist/middleware.d.ts +2 -1
- package/dist/middleware.js +474 -200
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +454 -200
- package/dist/middleware.mjs.map +1 -1
- package/dist/session-tracker.d.mts +1 -1
- package/dist/session-tracker.d.ts +1 -1
- package/dist/session-tracker.js.map +1 -1
- package/dist/session-tracker.mjs.map +1 -1
- package/dist/signature-verifier.d.mts +1 -0
- package/dist/signature-verifier.d.ts +1 -0
- package/dist/signature-verifier.js +204 -44
- package/dist/signature-verifier.js.map +1 -1
- package/dist/signature-verifier.mjs +184 -44
- package/dist/signature-verifier.mjs.map +1 -1
- package/dist/{types-BJTEUa4T.d.mts → types-DVmy9NE3.d.mts} +19 -2
- package/dist/{types-BJTEUa4T.d.ts → types-DVmy9NE3.d.ts} +19 -2
- package/dist/wasm-middleware.js +15 -6
- package/dist/wasm-middleware.js.map +1 -1
- package/dist/wasm-middleware.mjs +15 -6
- package/dist/wasm-middleware.mjs.map +1 -1
- package/package.json +42 -22
- package/wasm/agentshield_wasm.js +209 -152
- package/wasm/agentshield_wasm_bg.wasm +0 -0
- package/wasm/package.json +30 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/edge/index.ts"],"names":["response"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Edge Runtime Middleware with WASM Support\n *\n * This module provides Next.js middleware that uses the unified WASM runtime.\n * For Edge Runtime, consumers must provide a pre-compiled WASM module via static import:\n *\n * ```typescript\n * // In your middleware.ts\n * import wasmModule from '@kya-os/agentshield-wasm-runtime/wasm?module';\n * import { createEdgeMiddleware } from '@kya-os/agentshield-nextjs/edge';\n *\n * export const middleware = createEdgeMiddleware({\n * wasmModule,\n * apiKey: process.env.AGENTSHIELD_API_KEY,\n * onAgentDetected: 'block',\n * });\n * ```\n *\n * When an API key is provided, the middleware will:\n * 1. Load customer policies (deny lists, allow lists, thresholds) from AgentShield API\n * 2. Automatically block agents that match deny list entries\n * 3. Cache policies for 5 minutes with background refresh\n */\n\nimport { NextRequest, NextResponse } from 'next/server';\nimport type { DetectionResult } from '@kya-os/agentshield-shared';\n\n/**\n * Edge middleware configuration\n */\nexport interface EdgeMiddlewareConfig {\n /**\n * Pre-compiled WebAssembly.Module for Edge Runtime\n * Use static import: `import wasmModule from '@kya-os/agentshield-wasm-runtime/wasm?module'`\n */\n wasmModule?: WebAssembly.Module;\n\n /**\n * API key for loading customer policies from AgentShield dashboard\n * When provided, enables policy enforcement (deny lists, allow lists, thresholds)\n */\n apiKey?: string;\n\n /**\n * Custom URL for the policy API\n * @default 'https://api.agentshield.io'\n */\n policyApiUrl?: string;\n\n /**\n * Action to take when an agent is detected\n * @default 'log'\n */\n onAgentDetected?: 'block' | 'redirect' | 'rewrite' | 'log' | 'allow';\n\n /**\n * Custom handler called when an agent is detected\n * Return a NextResponse to override default behavior\n */\n onDetection?: (\n request: NextRequest,\n result: DetectionResult\n ) => Promise<NextResponse | void> | NextResponse | void;\n\n /**\n * Paths to skip detection (can be string prefixes or RegExp)\n */\n skipPaths?: (string | RegExp)[];\n\n /**\n * Minimum confidence threshold (0-100 scale) for considering a request as agent traffic\n * @default 70\n */\n confidenceThreshold?: number;\n\n /**\n * Response to send when blocking agents\n */\n blockedResponse?: {\n status?: number;\n message?: string;\n headers?: Record<string, string>;\n };\n\n /**\n * URL to redirect to when redirecting agents\n */\n redirectUrl?: string;\n\n /**\n * URL to rewrite to when rewriting agent requests\n */\n rewriteUrl?: string;\n\n /**\n * Enable debug logging\n */\n debug?: boolean;\n}\n\n/**\n * Detection input extracted from request\n */\ninterface DetectionInput {\n userAgent?: string;\n ipAddress?: string;\n headers: Record<string, string>;\n url?: string;\n method?: string;\n}\n\n/**\n * Simple edge-safe detector that uses pattern matching\n * Falls back to this when WASM is not available\n */\nasync function patternDetect(input: DetectionInput): Promise<DetectionResult> {\n const userAgent = input.userAgent?.toLowerCase() || '';\n const reasons: string[] = [];\n let confidence = 0;\n let detectedAgent: { type: string; name: string } | undefined;\n\n // AI agent patterns with confidence scores (0-100 scale)\n const patterns = [\n { pattern: /chatgpt-user/i, name: 'ChatGPT', confidence: 95 },\n { pattern: /claude-web/i, name: 'Claude', confidence: 95 },\n { pattern: /claude-?bot/i, name: 'ClaudeBot', confidence: 95 },\n { pattern: /anthropic/i, name: 'Claude', confidence: 90 },\n { pattern: /gptbot/i, name: 'GPTBot', confidence: 90 },\n { pattern: /perplexity/i, name: 'Perplexity', confidence: 90 },\n { pattern: /openai/i, name: 'OpenAI', confidence: 85 },\n { pattern: /copilot/i, name: 'Copilot', confidence: 85 },\n { pattern: /gemini/i, name: 'Gemini', confidence: 85 },\n { pattern: /bard/i, name: 'Bard', confidence: 85 },\n // HTTP client libraries (often used by AI agents/scrapers)\n { pattern: /^axios\\//i, name: 'HTTP Client (axios)', confidence: 75 },\n { pattern: /^node-fetch\\//i, name: 'HTTP Client (node-fetch)', confidence: 75 },\n { pattern: /^got\\//i, name: 'HTTP Client (got)', confidence: 75 },\n { pattern: /^python-requests\\//i, name: 'HTTP Client (requests)', confidence: 75 },\n { pattern: /^python-urllib/i, name: 'HTTP Client (urllib)', confidence: 75 },\n { pattern: /^curl\\//i, name: 'HTTP Client (curl)', confidence: 60 },\n { pattern: /^wget\\//i, name: 'HTTP Client (wget)', confidence: 60 },\n { pattern: /^httpie\\//i, name: 'HTTP Client (httpie)', confidence: 70 },\n { pattern: /^undici\\//i, name: 'HTTP Client (undici)', confidence: 75 },\n ];\n\n for (const { pattern, name, confidence: patternConfidence } of patterns) {\n if (pattern.test(userAgent)) {\n confidence = patternConfidence;\n detectedAgent = { type: name.toLowerCase(), name };\n reasons.push(`known_pattern:${name.toLowerCase()}`);\n break;\n }\n }\n\n // Check for AI-specific headers\n const aiHeaders = ['x-openai-', 'x-anthropic-', 'x-ai-', 'signature-agent'];\n for (const [key] of Object.entries(input.headers)) {\n if (aiHeaders.some((prefix) => key.toLowerCase().startsWith(prefix))) {\n confidence = Math.max(confidence, 45);\n reasons.push(`ai_headers:${key}`);\n break;\n }\n }\n\n return {\n isAgent: confidence > 30,\n confidence,\n detectionClass:\n confidence > 30 && detectedAgent\n ? { type: 'AiAgent' as const, agentType: detectedAgent.name }\n : confidence > 30\n ? { type: 'Unknown' as const }\n : { type: 'Human' as const },\n signals: [],\n ...(detectedAgent && { detectedAgent }),\n reasons,\n verificationMethod: 'pattern' as const,\n forgeabilityRisk: confidence > 80 ? 'medium' : 'high',\n timestamp: new Date(),\n };\n}\n\n/**\n * Extended detection result with policy enforcement\n */\ninterface PolicyEnforcedResult extends DetectionResult {\n shouldBlock?: boolean;\n blockReason?: 'deny_list' | 'not_in_allow_list' | 'threshold';\n}\n\n/**\n * Create detector using WASM runtime or fallback\n * When apiKey is provided, policy enforcement is enabled\n */\nasync function createDetector(config: EdgeMiddlewareConfig) {\n let detector: {\n detect: (input: DetectionInput) => Promise<PolicyEnforcedResult>;\n isReady: () => boolean;\n };\n\n // Try to use wasm-runtime if WASM module is provided\n if (config.wasmModule) {\n try {\n const { StaticWasmLoader, WasmDetector, PolicyLoader } = await import(\n '@kya-os/agentshield-wasm-runtime/edge'\n );\n const loader = new StaticWasmLoader(config.wasmModule);\n\n // Create policy loader if API key is provided\n const policyLoader = config.apiKey\n ? new PolicyLoader({\n apiUrl: config.policyApiUrl,\n })\n : undefined;\n\n // Create detector with policy support\n const wasmDetector = new WasmDetector(loader, policyLoader, {\n apiKey: config.apiKey,\n debug: config.debug,\n });\n\n await wasmDetector.ensureReady();\n\n if (config.debug) {\n console.debug('[AgentShield] WASM detector initialized in Edge Runtime', {\n policyEnabled: !!config.apiKey,\n });\n }\n\n detector = {\n detect: async (input: DetectionInput): Promise<PolicyEnforcedResult> => {\n const result = await wasmDetector.detect(input);\n // Convert IDetectionResult to DetectionResult by adding required fields\n // Type assertion needed due to different DetectionClass definitions\n return {\n isAgent: result.isAgent,\n confidence: result.confidence,\n detectionClass: result.detectionClass as DetectionResult['detectionClass'],\n detectedAgent: result.detectedAgent,\n verificationMethod: result.verificationMethod,\n forgeabilityRisk: result.forgeabilityRisk,\n reasons: result.reasons,\n timestamp: result.timestamp,\n signals: [], // Required by DetectionResult, empty for WASM results\n shouldBlock: result.shouldBlock,\n blockReason: result.blockReason as PolicyEnforcedResult['blockReason'],\n };\n },\n isReady: () => wasmDetector.isReady(),\n };\n } catch (error) {\n if (config.debug) {\n console.warn('[AgentShield] WASM runtime not available, using pattern detection:', error);\n }\n detector = {\n detect: patternDetect,\n isReady: () => true,\n };\n }\n } else {\n // Use pattern-based detection\n if (config.debug) {\n console.debug('[AgentShield] No WASM module provided, using pattern detection');\n }\n detector = {\n detect: patternDetect,\n isReady: () => true,\n };\n }\n\n return detector;\n}\n\n/**\n * Create Edge middleware with WASM support\n *\n * @example\n * ```typescript\n * // middleware.ts\n * import wasmModule from '@kya-os/agentshield-wasm-runtime/wasm?module';\n * import { createEdgeMiddleware } from '@kya-os/agentshield-nextjs/edge';\n *\n * export const middleware = createEdgeMiddleware({\n * wasmModule,\n * onAgentDetected: 'block',\n * confidenceThreshold: 70,\n * });\n *\n * export const config = {\n * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],\n * };\n * ```\n */\nexport function createEdgeMiddleware(config: EdgeMiddlewareConfig = {}) {\n let detectorPromise: Promise<Awaited<ReturnType<typeof createDetector>>> | null = null;\n\n const {\n onAgentDetected = 'log',\n onDetection,\n skipPaths = [],\n confidenceThreshold = 70,\n blockedResponse = {\n status: 403,\n message: 'Access denied: Automated agent detected',\n headers: { 'Content-Type': 'application/json' },\n },\n redirectUrl = '/blocked',\n rewriteUrl = '/blocked',\n debug = false,\n } = config;\n\n return async (request: NextRequest): Promise<NextResponse> => {\n try {\n // Initialize detector lazily\n if (!detectorPromise) {\n detectorPromise = createDetector({ ...config, debug });\n }\n const detector = await detectorPromise;\n\n // Check if path should be skipped\n const shouldSkip = skipPaths.some((pattern) => {\n if (typeof pattern === 'string') {\n return request.nextUrl.pathname.startsWith(pattern);\n }\n return pattern.test(request.nextUrl.pathname);\n });\n\n if (shouldSkip) {\n return NextResponse.next();\n }\n\n // Extract request context\n const url = new URL(request.url);\n // Parse X-Forwarded-For header to get client IP (first in comma-separated list)\n const xForwardedFor = request.headers.get('x-forwarded-for');\n const clientIp = xForwardedFor?.split(',')[0]?.trim();\n const input: DetectionInput = {\n userAgent: request.headers.get('user-agent') || undefined,\n ipAddress: request.ip || clientIp || undefined,\n headers: Object.fromEntries(request.headers.entries()),\n url: url.pathname + url.search,\n method: request.method,\n };\n\n // Run detection\n const result = await detector.detect(input);\n\n // POLICY ENFORCEMENT: Check shouldBlock from policy rules (deny list, allow list, threshold)\n // This takes precedence over the general threshold check below\n if (result.shouldBlock) {\n if (debug) {\n console.debug('[AgentShield] Blocked by policy', {\n reason: result.blockReason,\n agent: result.detectedAgent?.name,\n confidence: result.confidence,\n pathname: request.nextUrl.pathname,\n });\n }\n\n // Call custom detection handler if provided\n if (onDetection) {\n const customResponse = await onDetection(request, result);\n if (customResponse) {\n return customResponse;\n }\n }\n\n // Return 403 with policy block reason\n return NextResponse.json(\n {\n error: 'Access denied by policy',\n reason: result.blockReason,\n detected: true,\n confidence: result.confidence,\n agent: result.detectedAgent?.name,\n timestamp: result.timestamp,\n },\n {\n status: 403,\n headers: { 'Content-Type': 'application/json' },\n }\n );\n }\n\n // Check if agent detected above threshold (when policy doesn't block)\n // Skip if shouldBlock === false (agent explicitly allowed by policy)\n if (\n result.shouldBlock !== false &&\n result.isAgent &&\n result.confidence >= confidenceThreshold\n ) {\n // Call custom detection handler if provided\n if (onDetection) {\n const customResponse = await onDetection(request, result);\n if (customResponse) {\n return customResponse;\n }\n }\n\n // Handle based on configuration\n switch (onAgentDetected) {\n case 'block': {\n const response = NextResponse.json(\n {\n error: blockedResponse.message,\n detected: true,\n confidence: result.confidence,\n timestamp: result.timestamp,\n },\n { status: blockedResponse.status }\n );\n\n if (blockedResponse.headers) {\n Object.entries(blockedResponse.headers).forEach(([key, value]) => {\n response.headers.set(key, value);\n });\n }\n\n return response;\n }\n\n case 'redirect':\n return NextResponse.redirect(new URL(redirectUrl, request.url));\n\n case 'rewrite':\n return NextResponse.rewrite(new URL(rewriteUrl, request.url));\n\n case 'log':\n if (debug || process.env.NODE_ENV !== 'production') {\n console.debug('AgentShield: Agent detected', {\n ipAddress: input.ipAddress,\n userAgent: input.userAgent,\n confidence: result.confidence,\n agent: result.detectedAgent?.name,\n pathname: request.nextUrl.pathname,\n });\n }\n break;\n\n case 'allow':\n default:\n break;\n }\n }\n\n // Continue with request\n const response = NextResponse.next();\n\n // Add detection headers\n response.headers.set('x-agentshield-detected', result.isAgent.toString());\n response.headers.set('x-agentshield-confidence', result.confidence.toString());\n if (result.detectedAgent?.name) {\n response.headers.set('x-agentshield-agent', result.detectedAgent.name);\n }\n\n return response;\n } catch (error) {\n console.error('AgentShield middleware error:', error);\n return NextResponse.next();\n }\n };\n}\n\n// Re-export types for convenience\nexport type { DetectionResult };\n"]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { DetectionResult } from '@kya-os/agentshield-shared';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Wrapper for EdgeAgentDetector to match AgentDetector interface
|
|
3
5
|
* This allows the middleware to work with EdgeAgentDetector in Edge Runtime
|
|
@@ -14,29 +16,18 @@ type DetectionInput = {
|
|
|
14
16
|
method?: string;
|
|
15
17
|
timestamp?: Date;
|
|
16
18
|
};
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
confidence: number;
|
|
20
|
-
detectedAgent?: {
|
|
21
|
-
type: string;
|
|
22
|
-
name: string;
|
|
23
|
-
};
|
|
24
|
-
reasons: string[];
|
|
25
|
-
verificationMethod?: string;
|
|
26
|
-
forgeabilityRisk?: 'low' | 'medium' | 'high';
|
|
27
|
-
timestamp: Date;
|
|
28
|
-
};
|
|
29
|
-
type EventHandler = (...args: any[]) => void;
|
|
19
|
+
|
|
20
|
+
type EventHandler = (...args: unknown[]) => void;
|
|
30
21
|
/**
|
|
31
22
|
* Wrapper that provides event emitter functionality
|
|
32
23
|
*/
|
|
33
24
|
declare class EdgeAgentDetectorWrapper {
|
|
34
25
|
private detector;
|
|
35
26
|
private events;
|
|
36
|
-
constructor(_config?:
|
|
27
|
+
constructor(_config?: unknown);
|
|
37
28
|
analyze(input: DetectionInput): Promise<DetectionResult>;
|
|
38
29
|
on(event: string, handler: EventHandler): void;
|
|
39
|
-
emit(event: string, ...args:
|
|
30
|
+
emit(event: string, ...args: unknown[]): void;
|
|
40
31
|
init(): Promise<void>;
|
|
41
32
|
}
|
|
42
33
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { DetectionResult } from '@kya-os/agentshield-shared';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Wrapper for EdgeAgentDetector to match AgentDetector interface
|
|
3
5
|
* This allows the middleware to work with EdgeAgentDetector in Edge Runtime
|
|
@@ -14,29 +16,18 @@ type DetectionInput = {
|
|
|
14
16
|
method?: string;
|
|
15
17
|
timestamp?: Date;
|
|
16
18
|
};
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
confidence: number;
|
|
20
|
-
detectedAgent?: {
|
|
21
|
-
type: string;
|
|
22
|
-
name: string;
|
|
23
|
-
};
|
|
24
|
-
reasons: string[];
|
|
25
|
-
verificationMethod?: string;
|
|
26
|
-
forgeabilityRisk?: 'low' | 'medium' | 'high';
|
|
27
|
-
timestamp: Date;
|
|
28
|
-
};
|
|
29
|
-
type EventHandler = (...args: any[]) => void;
|
|
19
|
+
|
|
20
|
+
type EventHandler = (...args: unknown[]) => void;
|
|
30
21
|
/**
|
|
31
22
|
* Wrapper that provides event emitter functionality
|
|
32
23
|
*/
|
|
33
24
|
declare class EdgeAgentDetectorWrapper {
|
|
34
25
|
private detector;
|
|
35
26
|
private events;
|
|
36
|
-
constructor(_config?:
|
|
27
|
+
constructor(_config?: unknown);
|
|
37
28
|
analyze(input: DetectionInput): Promise<DetectionResult>;
|
|
38
29
|
on(event: string, handler: EventHandler): void;
|
|
39
|
-
emit(event: string, ...args:
|
|
30
|
+
emit(event: string, ...args: unknown[]): void;
|
|
40
31
|
init(): Promise<void>;
|
|
41
32
|
}
|
|
42
33
|
|
|
@@ -1,17 +1,150 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var ed25519 = require('@noble/ed25519');
|
|
4
|
+
var sha2_js = require('@noble/hashes/sha2.js');
|
|
5
|
+
var agentshieldShared = require('@kya-os/agentshield-shared');
|
|
6
|
+
|
|
7
|
+
function _interopNamespace(e) {
|
|
8
|
+
if (e && e.__esModule) return e;
|
|
9
|
+
var n = Object.create(null);
|
|
10
|
+
if (e) {
|
|
11
|
+
Object.keys(e).forEach(function (k) {
|
|
12
|
+
if (k !== 'default') {
|
|
13
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return e[k]; }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
n.default = e;
|
|
22
|
+
return Object.freeze(n);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var ed25519__namespace = /*#__PURE__*/_interopNamespace(ed25519);
|
|
26
|
+
|
|
3
27
|
// src/signature-verifier.ts
|
|
28
|
+
ed25519__namespace.etc.sha512Sync = (...m) => sha2_js.sha512(ed25519__namespace.etc.concatBytes(...m));
|
|
4
29
|
var KNOWN_KEYS = {
|
|
5
30
|
chatgpt: [
|
|
6
31
|
{
|
|
7
32
|
kid: "otMqcjr17mGyruktGvJU8oojQTSMHlVm7uO-lrcqbdg",
|
|
8
33
|
// ChatGPT's current Ed25519 public key (base64)
|
|
34
|
+
// Source: https://chatgpt.com/.well-known/http-message-signatures-directory
|
|
9
35
|
publicKey: "7F_3jDlxaquwh291MiACkcS3Opq88NksyHiakzS-Y1g",
|
|
10
|
-
validFrom:
|
|
11
|
-
|
|
36
|
+
validFrom: 1735689600,
|
|
37
|
+
// Jan 1, 2025 (from OpenAI's nbf)
|
|
38
|
+
// Extended expiration as fallback safety - API fetch should provide fresh keys
|
|
39
|
+
// Check OpenAI's well-known endpoint for actual expiration dates
|
|
40
|
+
validUntil: 1799625600
|
|
41
|
+
// Jan 1, 2027 (extended for fallback safety)
|
|
12
42
|
}
|
|
13
43
|
]
|
|
14
44
|
};
|
|
45
|
+
var keyCache = /* @__PURE__ */ new Map();
|
|
46
|
+
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
47
|
+
var CACHE_MAX_SIZE = 100;
|
|
48
|
+
function getApiBaseUrl() {
|
|
49
|
+
if (typeof window !== "undefined") {
|
|
50
|
+
return "/api/internal";
|
|
51
|
+
}
|
|
52
|
+
const baseUrl = process.env.NEXT_PUBLIC_APP_URL || process.env.NEXT_PUBLIC_API_URL || process.env.API_URL || (process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : null);
|
|
53
|
+
if (baseUrl) {
|
|
54
|
+
return baseUrl.replace(/\/$/, "") + "/api/internal";
|
|
55
|
+
}
|
|
56
|
+
if (process.env.NODE_ENV !== "production") {
|
|
57
|
+
console.warn(
|
|
58
|
+
"[Signature] No base URL configured for server-side fetch. Using localhost fallback."
|
|
59
|
+
);
|
|
60
|
+
return "http://localhost:3000/api/internal";
|
|
61
|
+
}
|
|
62
|
+
console.error(
|
|
63
|
+
"[Signature] CRITICAL: No base URL configured for server-side fetch in production!"
|
|
64
|
+
);
|
|
65
|
+
return "/api/internal";
|
|
66
|
+
}
|
|
67
|
+
function cleanupExpiredCache() {
|
|
68
|
+
const now = Date.now();
|
|
69
|
+
const entriesToDelete = [];
|
|
70
|
+
for (const [agent, cached] of keyCache.entries()) {
|
|
71
|
+
if (now - cached.cachedAt > CACHE_TTL_MS) {
|
|
72
|
+
entriesToDelete.push(agent);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const agent of entriesToDelete) {
|
|
76
|
+
keyCache.delete(agent);
|
|
77
|
+
}
|
|
78
|
+
if (keyCache.size > CACHE_MAX_SIZE) {
|
|
79
|
+
const entries = Array.from(keyCache.entries()).map(([agent, cached]) => ({
|
|
80
|
+
agent,
|
|
81
|
+
cachedAt: cached.cachedAt
|
|
82
|
+
}));
|
|
83
|
+
entries.sort((a, b) => a.cachedAt - b.cachedAt);
|
|
84
|
+
const toRemove = entries.slice(0, keyCache.size - CACHE_MAX_SIZE);
|
|
85
|
+
for (const entry of toRemove) {
|
|
86
|
+
keyCache.delete(entry.agent);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function fetchKeysFromApi(agent) {
|
|
91
|
+
if (keyCache.size > CACHE_MAX_SIZE) {
|
|
92
|
+
cleanupExpiredCache();
|
|
93
|
+
}
|
|
94
|
+
const cached = keyCache.get(agent);
|
|
95
|
+
if (cached && Date.now() - cached.cachedAt < CACHE_TTL_MS) {
|
|
96
|
+
return cached.keys;
|
|
97
|
+
}
|
|
98
|
+
if (typeof fetch === "undefined") {
|
|
99
|
+
console.warn("[Signature] fetch() not available in this environment");
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const apiBaseUrl = getApiBaseUrl();
|
|
104
|
+
const url = `${apiBaseUrl}/signature-keys?agent=${encodeURIComponent(agent)}`;
|
|
105
|
+
const response = await fetch(url, {
|
|
106
|
+
method: "GET",
|
|
107
|
+
headers: {
|
|
108
|
+
"Content-Type": "application/json"
|
|
109
|
+
},
|
|
110
|
+
// 5 second timeout
|
|
111
|
+
signal: AbortSignal.timeout(5e3)
|
|
112
|
+
});
|
|
113
|
+
if (!response.ok) {
|
|
114
|
+
console.warn(`[Signature] Failed to fetch keys from API: ${response.status}`);
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const data = await response.json();
|
|
118
|
+
if (!data.keys || !Array.isArray(data.keys) || data.keys.length === 0) {
|
|
119
|
+
console.warn(`[Signature] No keys returned from API for agent: ${agent}`);
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
keyCache.set(agent, {
|
|
123
|
+
keys: data.keys,
|
|
124
|
+
cachedAt: Date.now()
|
|
125
|
+
});
|
|
126
|
+
return data.keys;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.warn("[Signature] Error fetching keys from API, using fallback", {
|
|
129
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
130
|
+
agent
|
|
131
|
+
});
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function isValidAgent(agent) {
|
|
136
|
+
return agent in KNOWN_KEYS;
|
|
137
|
+
}
|
|
138
|
+
async function getKeysForAgent(agent) {
|
|
139
|
+
const apiKeys = await fetchKeysFromApi(agent);
|
|
140
|
+
if (apiKeys && apiKeys.length > 0) {
|
|
141
|
+
return apiKeys;
|
|
142
|
+
}
|
|
143
|
+
if (isValidAgent(agent)) {
|
|
144
|
+
return KNOWN_KEYS[agent];
|
|
145
|
+
}
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
15
148
|
function parseSignatureInput(signatureInput) {
|
|
16
149
|
try {
|
|
17
150
|
const match = signatureInput.match(/sig1=\((.*?)\);(.+)/);
|
|
@@ -47,21 +180,29 @@ function buildSignatureBase(method, path, headers, signedHeaders) {
|
|
|
47
180
|
case "@authority":
|
|
48
181
|
value = headers["host"] || headers["Host"] || "";
|
|
49
182
|
break;
|
|
50
|
-
default:
|
|
51
|
-
const key = Object.keys(headers).find(
|
|
52
|
-
(k) => k.toLowerCase() === headerName.toLowerCase()
|
|
53
|
-
);
|
|
183
|
+
default: {
|
|
184
|
+
const key = Object.keys(headers).find((k) => k.toLowerCase() === headerName.toLowerCase());
|
|
54
185
|
value = key ? headers[key] || "" : "";
|
|
55
186
|
break;
|
|
187
|
+
}
|
|
56
188
|
}
|
|
57
189
|
components.push(`"${headerName}": ${value}`);
|
|
58
190
|
}
|
|
59
191
|
return components.join("\n");
|
|
60
192
|
}
|
|
193
|
+
function base64ToBytes(base64) {
|
|
194
|
+
let standardBase64 = base64.replace(/-/g, "+").replace(/_/g, "/");
|
|
195
|
+
const padding = standardBase64.length % 4;
|
|
196
|
+
if (padding) {
|
|
197
|
+
standardBase64 += "=".repeat(4 - padding);
|
|
198
|
+
}
|
|
199
|
+
const binaryString = atob(standardBase64);
|
|
200
|
+
return Uint8Array.from(binaryString, (c) => c.charCodeAt(0));
|
|
201
|
+
}
|
|
61
202
|
async function verifyEd25519Signature(publicKeyBase64, signatureBase64, message) {
|
|
62
203
|
try {
|
|
63
|
-
const publicKeyBytes =
|
|
64
|
-
const signatureBytes =
|
|
204
|
+
const publicKeyBytes = base64ToBytes(publicKeyBase64);
|
|
205
|
+
const signatureBytes = base64ToBytes(signatureBase64);
|
|
65
206
|
const messageBytes = new TextEncoder().encode(message);
|
|
66
207
|
if (publicKeyBytes.length !== 32) {
|
|
67
208
|
console.error("[Signature] Invalid public key length:", publicKeyBytes.length);
|
|
@@ -71,34 +212,36 @@ async function verifyEd25519Signature(publicKeyBase64, signatureBase64, message)
|
|
|
71
212
|
console.error("[Signature] Invalid signature length:", signatureBytes.length);
|
|
72
213
|
return false;
|
|
73
214
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
215
|
+
return ed25519__namespace.verify(signatureBytes, messageBytes, publicKeyBytes);
|
|
216
|
+
} catch (nobleError) {
|
|
217
|
+
console.warn("[Signature] @noble/ed25519 failed, trying Web Crypto fallback:", nobleError);
|
|
218
|
+
try {
|
|
219
|
+
const publicKeyBytes = base64ToBytes(publicKeyBase64);
|
|
220
|
+
const signatureBytes = base64ToBytes(signatureBase64);
|
|
221
|
+
const messageBytes = new TextEncoder().encode(message);
|
|
222
|
+
const publicKey = await crypto.subtle.importKey(
|
|
223
|
+
"raw",
|
|
224
|
+
publicKeyBytes.buffer,
|
|
225
|
+
{
|
|
226
|
+
name: "Ed25519",
|
|
227
|
+
namedCurve: "Ed25519"
|
|
228
|
+
},
|
|
229
|
+
false,
|
|
230
|
+
["verify"]
|
|
231
|
+
);
|
|
232
|
+
return await crypto.subtle.verify(
|
|
233
|
+
"Ed25519",
|
|
234
|
+
publicKey,
|
|
235
|
+
signatureBytes.buffer,
|
|
236
|
+
messageBytes
|
|
237
|
+
);
|
|
238
|
+
} catch (cryptoError) {
|
|
239
|
+
console.error("[Signature] Both @noble/ed25519 and Web Crypto failed:", {
|
|
240
|
+
nobleError: nobleError instanceof Error ? nobleError.message : "Unknown",
|
|
241
|
+
cryptoError: cryptoError instanceof Error ? cryptoError.message : "Unknown"
|
|
242
|
+
});
|
|
243
|
+
return false;
|
|
100
244
|
}
|
|
101
|
-
return false;
|
|
102
245
|
}
|
|
103
246
|
}
|
|
104
247
|
async function verifyAgentSignature(method, path, headers) {
|
|
@@ -143,12 +286,12 @@ async function verifyAgentSignature(method, path, headers) {
|
|
|
143
286
|
}
|
|
144
287
|
}
|
|
145
288
|
let agent;
|
|
146
|
-
let
|
|
289
|
+
let agentKey;
|
|
147
290
|
if (signatureAgent === '"https://chatgpt.com"' || signatureAgent?.includes("chatgpt.com")) {
|
|
148
291
|
agent = "ChatGPT";
|
|
149
|
-
|
|
292
|
+
agentKey = "chatgpt";
|
|
150
293
|
}
|
|
151
|
-
if (!agent || !
|
|
294
|
+
if (!agent || !agentKey) {
|
|
152
295
|
return {
|
|
153
296
|
isValid: false,
|
|
154
297
|
confidence: 0,
|
|
@@ -156,6 +299,15 @@ async function verifyAgentSignature(method, path, headers) {
|
|
|
156
299
|
verificationMethod: "none"
|
|
157
300
|
};
|
|
158
301
|
}
|
|
302
|
+
const knownKeys = await getKeysForAgent(agentKey);
|
|
303
|
+
if (knownKeys.length === 0) {
|
|
304
|
+
return {
|
|
305
|
+
isValid: false,
|
|
306
|
+
confidence: 0,
|
|
307
|
+
reason: "No keys available for agent",
|
|
308
|
+
verificationMethod: "none"
|
|
309
|
+
};
|
|
310
|
+
}
|
|
159
311
|
const key = knownKeys.find((k) => k.kid === parsed.keyid);
|
|
160
312
|
if (!key) {
|
|
161
313
|
return {
|
|
@@ -182,11 +334,7 @@ async function verifyAgentSignature(method, path, headers) {
|
|
|
182
334
|
if (signatureValue.endsWith(":")) {
|
|
183
335
|
signatureValue = signatureValue.slice(0, -1);
|
|
184
336
|
}
|
|
185
|
-
const isValid = await verifyEd25519Signature(
|
|
186
|
-
key.publicKey,
|
|
187
|
-
signatureValue,
|
|
188
|
-
signatureBase
|
|
189
|
-
);
|
|
337
|
+
const isValid = await verifyEd25519Signature(key.publicKey, signatureValue, signatureBase);
|
|
190
338
|
if (isValid) {
|
|
191
339
|
return {
|
|
192
340
|
isValid: true,
|
|
@@ -210,27 +358,27 @@ function hasSignatureHeaders(headers) {
|
|
|
210
358
|
}
|
|
211
359
|
function isChatGPTSignature(headers) {
|
|
212
360
|
const signatureAgent = headers["signature-agent"] || headers["Signature-Agent"];
|
|
213
|
-
|
|
361
|
+
if (!signatureAgent) {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
const agentUrlStr = signatureAgent.replace(/^"+|"+$/g, "");
|
|
365
|
+
if (agentUrlStr === "https://chatgpt.com") {
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
try {
|
|
369
|
+
const agentUrl = new URL(agentUrlStr);
|
|
370
|
+
const allowedHosts = ["chatgpt.com", "www.chatgpt.com"];
|
|
371
|
+
return allowedHosts.includes(agentUrl.host);
|
|
372
|
+
} catch {
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
214
375
|
}
|
|
215
|
-
|
|
216
|
-
// src/edge-detector-wrapper.ts
|
|
217
|
-
var AI_AGENT_PATTERNS = [
|
|
218
|
-
{ pattern: /chatgpt-user/i, type: "chatgpt", name: "ChatGPT" },
|
|
219
|
-
{ pattern: /claude-web/i, type: "claude", name: "Claude" },
|
|
220
|
-
{ pattern: /perplexitybot/i, type: "perplexity", name: "Perplexity" },
|
|
221
|
-
{ pattern: /perplexity-user/i, type: "perplexity", name: "Perplexity" },
|
|
222
|
-
{ pattern: /perplexity-ai/i, type: "perplexity", name: "Perplexity" },
|
|
223
|
-
{ pattern: /perplexity/i, type: "perplexity", name: "Perplexity" },
|
|
224
|
-
// Fallback
|
|
225
|
-
{ pattern: /bingbot/i, type: "bing", name: "Bing AI" },
|
|
226
|
-
{ pattern: /anthropic-ai/i, type: "anthropic", name: "Anthropic" }
|
|
227
|
-
];
|
|
228
|
-
var CLOUD_PROVIDERS = {
|
|
229
|
-
aws: ["54.", "52.", "35.", "18.", "3."],
|
|
230
|
-
gcp: ["35.", "34.", "104.", "107.", "108."],
|
|
231
|
-
azure: ["13.", "20.", "40.", "52.", "104."]
|
|
232
|
-
};
|
|
376
|
+
var rules = agentshieldShared.loadRulesSync();
|
|
233
377
|
var EdgeAgentDetector = class {
|
|
378
|
+
rules;
|
|
379
|
+
constructor() {
|
|
380
|
+
this.rules = rules;
|
|
381
|
+
}
|
|
234
382
|
async analyze(input) {
|
|
235
383
|
const reasons = [];
|
|
236
384
|
let detectedAgent;
|
|
@@ -249,7 +397,7 @@ var EdgeAgentDetector = class {
|
|
|
249
397
|
headers
|
|
250
398
|
);
|
|
251
399
|
if (signatureResult.isValid) {
|
|
252
|
-
confidence = signatureResult.confidence;
|
|
400
|
+
confidence = signatureResult.confidence * 100;
|
|
253
401
|
reasons.push(`verified_signature:${signatureResult.agent?.toLowerCase() || "unknown"}`);
|
|
254
402
|
if (signatureResult.agent) {
|
|
255
403
|
detectedAgent = {
|
|
@@ -262,7 +410,13 @@ var EdgeAgentDetector = class {
|
|
|
262
410
|
reasons.push(`keyid:${signatureResult.keyid}`);
|
|
263
411
|
}
|
|
264
412
|
} else {
|
|
265
|
-
|
|
413
|
+
console.warn("[EdgeAgentDetector] Signature verification failed:", {
|
|
414
|
+
reason: signatureResult.reason,
|
|
415
|
+
agent: signatureResult.agent,
|
|
416
|
+
hasSignatureAgent: !!headers["signature-agent"] || !!headers["Signature-Agent"],
|
|
417
|
+
signatureAgentValue: headers["signature-agent"] || headers["Signature-Agent"]
|
|
418
|
+
});
|
|
419
|
+
confidence = Math.max(confidence, 30);
|
|
266
420
|
reasons.push("invalid_signature");
|
|
267
421
|
if (signatureResult.reason) {
|
|
268
422
|
reasons.push(`signature_error:${signatureResult.reason}`);
|
|
@@ -274,68 +428,133 @@ var EdgeAgentDetector = class {
|
|
|
274
428
|
}
|
|
275
429
|
} catch (error) {
|
|
276
430
|
console.error("[EdgeAgentDetector] Signature verification error:", error);
|
|
277
|
-
confidence = Math.max(confidence,
|
|
431
|
+
confidence = Math.max(confidence, 20);
|
|
278
432
|
reasons.push("signature_verification_error");
|
|
279
433
|
}
|
|
280
434
|
}
|
|
281
435
|
const userAgent = input.userAgent || input.headers?.["user-agent"] || "";
|
|
282
436
|
if (userAgent) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
437
|
+
const userAgentEntries = Object.entries(this.rules.rules.userAgents);
|
|
438
|
+
const genericKeys = ["generic_bot", "dev_tools", "automation_tools"];
|
|
439
|
+
const sortedEntries = userAgentEntries.sort((a, b) => {
|
|
440
|
+
const aIsGeneric = genericKeys.includes(a[0]);
|
|
441
|
+
const bIsGeneric = genericKeys.includes(b[0]);
|
|
442
|
+
if (aIsGeneric && !bIsGeneric) return 1;
|
|
443
|
+
if (!aIsGeneric && bIsGeneric) return -1;
|
|
444
|
+
return 0;
|
|
445
|
+
});
|
|
446
|
+
for (const [agentKey, agentRule] of sortedEntries) {
|
|
447
|
+
const rule = agentRule;
|
|
448
|
+
const matched = rule.patterns.some((pattern) => {
|
|
449
|
+
const regex = new RegExp(pattern, "i");
|
|
450
|
+
return regex.test(userAgent);
|
|
451
|
+
});
|
|
452
|
+
if (matched) {
|
|
453
|
+
const agentType = this.getAgentType(agentKey);
|
|
454
|
+
const agentName = this.getAgentName(agentKey);
|
|
455
|
+
confidence = Math.max(confidence, rule.confidence * 100);
|
|
456
|
+
reasons.push(`known_pattern:${agentType}`);
|
|
294
457
|
if (!detectedAgent) {
|
|
295
|
-
detectedAgent = { type, name };
|
|
458
|
+
detectedAgent = { type: agentType, name: agentName };
|
|
296
459
|
verificationMethod = "pattern";
|
|
297
460
|
}
|
|
298
461
|
break;
|
|
299
462
|
}
|
|
300
463
|
}
|
|
301
464
|
}
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
"anthropic-client-id",
|
|
306
|
-
"x-goog-api-client",
|
|
307
|
-
"x-ms-copilot-id"
|
|
308
|
-
];
|
|
309
|
-
const foundAiHeaders = aiHeaders.filter(
|
|
310
|
-
(header) => normalizedHeaders[header]
|
|
465
|
+
const suspiciousHeaders = this.rules.rules.headers.suspicious;
|
|
466
|
+
const foundAiHeaders = suspiciousHeaders.filter(
|
|
467
|
+
(headerRule) => normalizedHeaders[headerRule.name.toLowerCase()]
|
|
311
468
|
);
|
|
312
469
|
if (foundAiHeaders.length > 0) {
|
|
313
|
-
|
|
470
|
+
const maxConfidence = Math.max(...foundAiHeaders.map((h) => h.confidence * 100));
|
|
471
|
+
confidence = Math.max(confidence, maxConfidence);
|
|
314
472
|
reasons.push(`ai_headers:${foundAiHeaders.length}`);
|
|
315
473
|
}
|
|
316
474
|
const ip = input.ip || input.ipAddress;
|
|
317
475
|
if (ip && !normalizedHeaders["x-forwarded-for"] && !normalizedHeaders["x-real-ip"]) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
476
|
+
const ipRanges = "providers" in this.rules.rules.ipRanges ? this.rules.rules.ipRanges.providers : this.rules.rules.ipRanges;
|
|
477
|
+
for (const [provider, ipRule] of Object.entries(ipRanges)) {
|
|
478
|
+
if (!ipRule || typeof ipRule !== "object" || !("ranges" in ipRule) || !Array.isArray(ipRule.ranges))
|
|
479
|
+
continue;
|
|
480
|
+
const matched = ipRule.ranges.some((range) => {
|
|
481
|
+
const prefix = range.split("/")[0];
|
|
482
|
+
const prefixParts = prefix.split(".");
|
|
483
|
+
const ipParts = ip.split(".");
|
|
484
|
+
for (let i = 0; i < Math.min(prefixParts.length - 1, 2); i++) {
|
|
485
|
+
if (prefixParts[i] !== ipParts[i] && prefixParts[i] !== "0") {
|
|
486
|
+
return false;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return true;
|
|
490
|
+
});
|
|
491
|
+
if (matched) {
|
|
492
|
+
const rule = ipRule;
|
|
493
|
+
confidence = Math.max(confidence, rule.confidence * 40);
|
|
321
494
|
reasons.push(`cloud_provider:${provider}`);
|
|
322
495
|
break;
|
|
323
496
|
}
|
|
324
497
|
}
|
|
325
498
|
}
|
|
326
|
-
if (reasons.length > 2 && confidence <
|
|
327
|
-
confidence = Math.min(confidence * 1.2,
|
|
499
|
+
if (reasons.length > 2 && confidence < 100) {
|
|
500
|
+
confidence = Math.min(confidence * 1.2, 95);
|
|
328
501
|
}
|
|
502
|
+
confidence = Math.min(Math.max(confidence, 0), 100);
|
|
329
503
|
return {
|
|
330
|
-
isAgent: confidence >
|
|
504
|
+
isAgent: confidence > 30,
|
|
505
|
+
// Updated to 0-100 scale (was 0.3)
|
|
331
506
|
confidence,
|
|
507
|
+
detectionClass: confidence > 30 && detectedAgent ? { type: "AiAgent", agentType: detectedAgent.name } : confidence > 30 ? { type: "Unknown" } : { type: "Human" },
|
|
508
|
+
signals: [],
|
|
509
|
+
// Will be populated by enhanced detection engine in future tasks
|
|
332
510
|
...detectedAgent && { detectedAgent },
|
|
333
511
|
reasons,
|
|
334
|
-
...verificationMethod && {
|
|
335
|
-
|
|
512
|
+
...verificationMethod && {
|
|
513
|
+
verificationMethod
|
|
514
|
+
},
|
|
515
|
+
forgeabilityRisk: verificationMethod === "signature" ? "low" : confidence > 80 ? "medium" : "high",
|
|
516
|
+
// Updated to 0-100 scale
|
|
336
517
|
timestamp: /* @__PURE__ */ new Date()
|
|
337
518
|
};
|
|
338
519
|
}
|
|
520
|
+
/**
|
|
521
|
+
* Get agent type from rule key
|
|
522
|
+
*/
|
|
523
|
+
getAgentType(agentKey) {
|
|
524
|
+
const typeMap = {
|
|
525
|
+
openai_gptbot: "openai",
|
|
526
|
+
anthropic_claude: "anthropic",
|
|
527
|
+
perplexity_bot: "perplexity",
|
|
528
|
+
google_ai: "google",
|
|
529
|
+
microsoft_ai: "microsoft",
|
|
530
|
+
meta_ai: "meta",
|
|
531
|
+
cohere_bot: "cohere",
|
|
532
|
+
huggingface_bot: "huggingface",
|
|
533
|
+
generic_bot: "generic",
|
|
534
|
+
dev_tools: "dev",
|
|
535
|
+
automation_tools: "automation"
|
|
536
|
+
};
|
|
537
|
+
return typeMap[agentKey] || agentKey;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Get agent name from rule key
|
|
541
|
+
*/
|
|
542
|
+
getAgentName(agentKey) {
|
|
543
|
+
const nameMap = {
|
|
544
|
+
openai_gptbot: "ChatGPT/GPTBot",
|
|
545
|
+
anthropic_claude: "Claude",
|
|
546
|
+
perplexity_bot: "Perplexity",
|
|
547
|
+
google_ai: "Google AI",
|
|
548
|
+
microsoft_ai: "Microsoft Copilot",
|
|
549
|
+
meta_ai: "Meta AI",
|
|
550
|
+
cohere_bot: "Cohere",
|
|
551
|
+
huggingface_bot: "HuggingFace",
|
|
552
|
+
generic_bot: "Generic Bot",
|
|
553
|
+
dev_tools: "Development Tool",
|
|
554
|
+
automation_tools: "Automation Tool"
|
|
555
|
+
};
|
|
556
|
+
return nameMap[agentKey] || agentKey;
|
|
557
|
+
}
|
|
339
558
|
};
|
|
340
559
|
var EdgeAgentDetectorWrapper = class {
|
|
341
560
|
detector;
|