@kya-os/agentshield-nextjs 0.3.0 → 0.3.2
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/api-client.d.mts +6 -10
- package/dist/api-client.d.ts +6 -10
- package/dist/api-client.js.map +1 -1
- package/dist/api-client.mjs.map +1 -1
- package/dist/api-middleware.d.mts +1 -0
- package/dist/api-middleware.d.ts +1 -0
- package/dist/api-middleware.js.map +1 -1
- package/dist/api-middleware.mjs.map +1 -1
- package/dist/edge/index.js +1 -0
- package/dist/edge/index.js.map +1 -1
- package/dist/edge/index.mjs +1 -0
- package/dist/edge/index.mjs.map +1 -1
- package/dist/edge-runtime-loader.js +1 -0
- package/dist/edge-runtime-loader.js.map +1 -1
- package/dist/edge-runtime-loader.mjs +1 -0
- package/dist/edge-runtime-loader.mjs.map +1 -1
- package/dist/enhanced-middleware.js +1 -0
- package/dist/enhanced-middleware.js.map +1 -1
- package/dist/enhanced-middleware.mjs +1 -0
- package/dist/enhanced-middleware.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/edge-runtime-loader.ts"],"names":["exports"],"mappings":"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","file":"edge-runtime-loader.js","sourcesContent":["/**\n * Utility functions for agentshield-nextjs\n */\n\nimport type { NextRequest } from 'next/server';\n\n/**\n * Extract client IP address from a NextRequest.\n * In Next.js 15+, the `ip` property was removed from NextRequest.\n * This function uses headers to determine the client IP.\n *\n * @param request - The NextRequest object\n * @returns The client IP address or undefined if not available\n */\nexport function getClientIp(request: NextRequest): string | undefined {\n // Check x-forwarded-for header (standard for proxies/load balancers)\n const forwardedFor = request.headers.get('x-forwarded-for');\n if (forwardedFor) {\n // Take the first IP in the chain (original client)\n const ip = forwardedFor.split(',')[0]?.trim();\n if (ip) return ip;\n }\n\n // Check x-real-ip header (commonly used by nginx)\n const realIp = request.headers.get('x-real-ip');\n if (realIp) return realIp;\n\n // Check cf-connecting-ip header (Cloudflare)\n const cfIp = request.headers.get('cf-connecting-ip');\n if (cfIp) return cfIp;\n\n // Check x-client-ip header (some proxies use this)\n const clientIp = request.headers.get('x-client-ip');\n if (clientIp) return clientIp;\n\n return undefined;\n}\n\n/**\n * Safely extract the hostname from a URL string.\n * Returns a friendly fallback when parsing fails so UX copy doesn't leak\n * \"undefined\" or similar to end users.\n */\nexport function safeHostname(url: string): string {\n try {\n return new URL(url).hostname;\n } catch {\n return 'this site';\n }\n}\n","/**\n * Edge Runtime Compatible WASM Loader for AgentShield\n *\n * This module provides a pre-built solution for loading WASM in Edge Runtime.\n * It requires the WASM file to be manually placed in the project.\n */\n\nimport type { NextRequest } from 'next/server';\nimport { getClientIp } from './utils';\n\n// User must provide the WASM module via import\n// This is intentionally not imported here to allow user control\nexport interface WasmModule {\n default: WebAssembly.Module;\n}\n\nexport interface DetectionResult {\n isAgent: boolean;\n isAiCrawler?: boolean;\n confidence: number;\n agent?: string;\n verificationMethod: 'cryptographic' | 'pattern';\n riskLevel?: 'low' | 'medium' | 'high' | 'critical';\n timestamp: string;\n}\n\nexport interface AgentShieldConfig {\n wasmModule?: WebAssembly.Module;\n enableWasm?: boolean;\n onAgentDetected?: (result: DetectionResult) => void;\n blockAgents?: boolean;\n allowedAgents?: string[];\n debug?: boolean;\n}\n\ninterface WasmExports {\n detect_agent(metadataPtr: number, metadataLen: number): number;\n get_version(): number;\n __wbindgen_malloc(size: number): number;\n __wbindgen_free(ptr: number, size: number): void;\n __wbindgen_realloc(ptr: number, oldSize: number, newSize: number): number;\n memory: WebAssembly.Memory;\n}\n\nclass EdgeRuntimeAgentShield {\n private wasmInstance: WebAssembly.Instance | null = null;\n private wasmMemory: WebAssembly.Memory | null = null;\n private config: AgentShieldConfig;\n private initialized = false;\n\n constructor(config: AgentShieldConfig = {}) {\n this.config = config;\n }\n\n async init(wasmModule?: WebAssembly.Module): Promise<void> {\n if (this.initialized) return;\n\n const module = wasmModule || this.config.wasmModule;\n\n if (module && this.config.enableWasm !== false) {\n try {\n this.wasmMemory = new WebAssembly.Memory({ initial: 17, maximum: 256 });\n\n const imports = {\n wbg: {\n __wbindgen_throw: (ptr: number, len: number) => {\n throw new Error(this.readString(ptr, len));\n },\n __wbg_log_: (ptr: number, len: number) => {\n if (this.config.debug) {\n console.log(this.readString(ptr, len));\n }\n },\n },\n env: {\n memory: this.wasmMemory,\n },\n };\n\n this.wasmInstance = await WebAssembly.instantiate(module, imports);\n this.initialized = true;\n\n if (this.config.debug) {\n console.log('✅ AgentShield WASM initialized in Edge Runtime');\n }\n } catch (error) {\n console.warn('⚠️ WASM initialization failed, using pattern detection:', error);\n this.initialized = true;\n }\n } else {\n this.initialized = true;\n }\n }\n\n private readString(ptr: number, len: number): string {\n if (!this.wasmInstance || !this.wasmMemory) {\n throw new Error('WASM not initialized');\n }\n const memory = new Uint8Array(this.wasmMemory.buffer);\n const bytes = memory.slice(ptr, ptr + len);\n return new TextDecoder().decode(bytes);\n }\n\n private writeString(str: string): [number, number] {\n if (!this.wasmInstance) {\n throw new Error('WASM not initialized');\n }\n const exports = this.wasmInstance.exports as unknown as WasmExports;\n\n const encoded = new TextEncoder().encode(str);\n const ptr = exports.__wbindgen_malloc(encoded.length);\n\n const memory = new Uint8Array(exports.memory.buffer);\n memory.set(encoded, ptr);\n\n return [ptr, encoded.length];\n }\n\n async detect(request: NextRequest): Promise<DetectionResult> {\n if (!this.initialized) {\n await this.init();\n }\n\n const metadata = {\n userAgent: request.headers.get('user-agent') || '',\n ipAddress: getClientIp(request) || '',\n headers: Object.fromEntries(request.headers.entries()),\n };\n\n // Try WASM detection first\n if (this.wasmInstance && this.config.enableWasm !== false) {\n try {\n const exports = this.wasmInstance.exports as unknown as WasmExports;\n const [ptr, len] = this.writeString(JSON.stringify(metadata));\n\n const resultPtr = exports.detect_agent(ptr, len);\n // Read result with dynamic size\n let resultStr = '';\n let offset = 0;\n const memory = new Uint8Array((exports.memory as WebAssembly.Memory).buffer);\n\n // Read until we find the end of the JSON string\n while (offset < 4096) {\n // Max 4KB result\n const byte = memory[resultPtr + offset];\n if (byte === 0 || byte === undefined) break;\n offset++;\n }\n\n if (offset > 0) {\n resultStr = this.readString(resultPtr, offset);\n }\n\n exports.__wbindgen_free(ptr, len);\n if (offset > 0) {\n exports.__wbindgen_free(resultPtr, offset);\n }\n\n const result = JSON.parse(resultStr);\n\n const detection: DetectionResult = {\n ...result,\n verificationMethod: 'cryptographic',\n timestamp: new Date().toISOString(),\n };\n\n if (this.config.onAgentDetected && detection.isAgent) {\n this.config.onAgentDetected(detection);\n }\n\n return detection;\n } catch (error) {\n if (this.config.debug) {\n console.error('WASM detection failed:', error);\n }\n // Fall through to pattern detection\n }\n }\n\n // Fallback: Pattern-based detection\n return this.patternDetection(metadata);\n }\n\n private patternDetection(metadata: {\n userAgent: string;\n ipAddress: string;\n headers: Record<string, string>;\n }): DetectionResult {\n const userAgent = metadata.userAgent.toLowerCase();\n\n // Enhanced AI agent patterns with confidence scores\n const patterns = [\n // High confidence - explicit AI identifiers\n { pattern: /chatgpt-user/i, name: 'ChatGPT', confidence: 0.95 },\n { pattern: /claude-web/i, name: 'Claude', confidence: 0.95 },\n { pattern: /gpt-crawler/i, name: 'GPT Crawler', confidence: 0.95 },\n { pattern: /perplexitybot/i, name: 'Perplexity', confidence: 0.95 },\n { pattern: /perplexity-user/i, name: 'Perplexity', confidence: 0.95 },\n { pattern: /perplexity-ai/i, name: 'Perplexity', confidence: 0.95 },\n\n // Medium-high confidence - company identifiers\n { pattern: /anthropic/i, name: 'Anthropic', confidence: 0.9 },\n { pattern: /openai/i, name: 'OpenAI', confidence: 0.9 },\n\n // Medium confidence - product names\n { pattern: /copilot/i, name: 'GitHub Copilot', confidence: 0.85 },\n { pattern: /bard/i, name: 'Google Bard', confidence: 0.85 },\n { pattern: /gemini/i, name: 'Google Gemini', confidence: 0.85 },\n { pattern: /perplexity/i, name: 'Perplexity', confidence: 0.85 }, // Fallback\n { pattern: /\\byou\\.com\\b/i, name: 'You.com', confidence: 0.8 },\n { pattern: /\\bphind\\b/i, name: 'Phind', confidence: 0.8 },\n ];\n\n // Check for suspicious headers\n const suspiciousHeaders = ['x-openai-', 'x-anthropic-', 'x-ai-', 'x-llm-', 'x-gpt-'];\n\n let headerBoost = 0;\n for (const [key] of Object.entries(metadata.headers)) {\n if (suspiciousHeaders.some((prefix) => key.toLowerCase().startsWith(prefix))) {\n headerBoost = 0.1;\n break;\n }\n }\n\n // Check patterns - patterns are ordered by confidence (highest first: 0.95, 0.90, 0.85...)\n // so breaking on first match returns the highest-confidence match\n for (const { pattern, name, confidence } of patterns) {\n if (pattern.test(userAgent)) {\n const finalConfidence = Math.min(confidence + headerBoost, 1.0);\n\n const result: DetectionResult = {\n isAgent: true,\n confidence: finalConfidence,\n agent: name,\n verificationMethod: 'pattern',\n riskLevel: finalConfidence > 0.9 ? 'high' : 'medium',\n timestamp: new Date().toISOString(),\n };\n\n if (this.config.onAgentDetected) {\n this.config.onAgentDetected(result);\n }\n\n return result;\n }\n }\n\n // Not detected\n return {\n isAgent: false,\n confidence: 0.85,\n verificationMethod: 'pattern',\n timestamp: new Date().toISOString(),\n };\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n getVerificationMethod(): 'cryptographic' | 'pattern' {\n return this.wasmInstance ? 'cryptographic' : 'pattern';\n }\n}\n\n/**\n * Factory function to create an AgentShield instance for Edge Runtime\n */\nexport function createEdgeAgentShield(config?: AgentShieldConfig) {\n return new EdgeRuntimeAgentShield(config);\n}\n\n/**\n * Singleton instance for simple usage\n */\nlet defaultInstance: EdgeRuntimeAgentShield | null = null;\n\nexport function getDefaultAgentShield(config?: AgentShieldConfig): EdgeRuntimeAgentShield {\n if (!defaultInstance) {\n defaultInstance = new EdgeRuntimeAgentShield(config);\n }\n return defaultInstance;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/edge-runtime-loader.ts"],"names":["exports"],"mappings":"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","file":"edge-runtime-loader.js","sourcesContent":["/**\n * Utility functions for agentshield-nextjs\n */\n\nimport type { NextRequest } from 'next/server';\n\n/**\n * Extract client IP address from a NextRequest.\n * In Next.js 15+, the `ip` property was removed from NextRequest.\n * This function uses headers to determine the client IP.\n *\n * @param request - The NextRequest object\n * @returns The client IP address or undefined if not available\n */\nexport function getClientIp(request: NextRequest): string | undefined {\n // Check x-forwarded-for header (standard for proxies/load balancers)\n const forwardedFor = request.headers.get('x-forwarded-for');\n if (forwardedFor) {\n // Take the first IP in the chain (original client)\n const ip = forwardedFor.split(',')[0]?.trim();\n if (ip) return ip;\n }\n\n // Check x-real-ip header (commonly used by nginx)\n const realIp = request.headers.get('x-real-ip');\n if (realIp) return realIp;\n\n // Check cf-connecting-ip header (Cloudflare)\n const cfIp = request.headers.get('cf-connecting-ip');\n if (cfIp) return cfIp;\n\n // Check x-client-ip header (some proxies use this)\n const clientIp = request.headers.get('x-client-ip');\n if (clientIp) return clientIp;\n\n return undefined;\n}\n\n/**\n * Safely extract the hostname from a URL string.\n * Returns a friendly fallback when parsing fails so UX copy doesn't leak\n * \"undefined\" or similar to end users.\n */\nexport function safeHostname(url: string): string {\n try {\n return new URL(url).hostname;\n } catch {\n return 'this site';\n }\n}\n","/**\n * Edge Runtime Compatible WASM Loader for AgentShield\n *\n * This module provides a pre-built solution for loading WASM in Edge Runtime.\n * It requires the WASM file to be manually placed in the project.\n */\n\nimport type { NextRequest } from 'next/server';\nimport { getClientIp } from './utils';\n\n// User must provide the WASM module via import\n// This is intentionally not imported here to allow user control\nexport interface WasmModule {\n default: WebAssembly.Module;\n}\n\nexport interface DetectionResult {\n isAgent: boolean;\n isAiCrawler?: boolean;\n confidence: number;\n agent?: string;\n verificationMethod: 'cryptographic' | 'pattern';\n riskLevel?: 'low' | 'medium' | 'high' | 'critical';\n timestamp: string;\n}\n\nexport interface AgentShieldConfig {\n wasmModule?: WebAssembly.Module;\n enableWasm?: boolean;\n onAgentDetected?: (result: DetectionResult) => void;\n blockAgents?: boolean;\n allowedAgents?: string[];\n debug?: boolean;\n}\n\ninterface WasmExports {\n detect_agent(metadataPtr: number, metadataLen: number): number;\n get_version(): number;\n __wbindgen_malloc(size: number): number;\n __wbindgen_free(ptr: number, size: number): void;\n __wbindgen_realloc(ptr: number, oldSize: number, newSize: number): number;\n memory: WebAssembly.Memory;\n}\n\nclass EdgeRuntimeAgentShield {\n private wasmInstance: WebAssembly.Instance | null = null;\n private wasmMemory: WebAssembly.Memory | null = null;\n private config: AgentShieldConfig;\n private initialized = false;\n\n constructor(config: AgentShieldConfig = {}) {\n this.config = config;\n }\n\n async init(wasmModule?: WebAssembly.Module): Promise<void> {\n if (this.initialized) return;\n\n const module = wasmModule || this.config.wasmModule;\n\n if (module && this.config.enableWasm !== false) {\n try {\n this.wasmMemory = new WebAssembly.Memory({ initial: 17, maximum: 256 });\n\n const imports = {\n wbg: {\n __wbindgen_throw: (ptr: number, len: number) => {\n throw new Error(this.readString(ptr, len));\n },\n __wbg_log_: (ptr: number, len: number) => {\n if (this.config.debug) {\n console.log(this.readString(ptr, len));\n }\n },\n },\n env: {\n memory: this.wasmMemory,\n },\n };\n\n this.wasmInstance = await WebAssembly.instantiate(module, imports);\n this.initialized = true;\n\n if (this.config.debug) {\n console.log('✅ AgentShield WASM initialized in Edge Runtime');\n }\n } catch (error) {\n console.warn('⚠️ WASM initialization failed, using pattern detection:', error);\n this.initialized = true;\n }\n } else {\n this.initialized = true;\n }\n }\n\n private readString(ptr: number, len: number): string {\n if (!this.wasmInstance || !this.wasmMemory) {\n throw new Error('WASM not initialized');\n }\n const memory = new Uint8Array(this.wasmMemory.buffer);\n const bytes = memory.slice(ptr, ptr + len);\n return new TextDecoder().decode(bytes);\n }\n\n private writeString(str: string): [number, number] {\n if (!this.wasmInstance) {\n throw new Error('WASM not initialized');\n }\n const exports = this.wasmInstance.exports as unknown as WasmExports;\n\n const encoded = new TextEncoder().encode(str);\n const ptr = exports.__wbindgen_malloc(encoded.length);\n\n const memory = new Uint8Array(exports.memory.buffer);\n memory.set(encoded, ptr);\n\n return [ptr, encoded.length];\n }\n\n async detect(request: NextRequest): Promise<DetectionResult> {\n if (!this.initialized) {\n await this.init();\n }\n\n const metadata = {\n userAgent: request.headers.get('user-agent') || '',\n ipAddress: getClientIp(request) || '',\n headers: Object.fromEntries(request.headers.entries()),\n };\n\n // Try WASM detection first\n if (this.wasmInstance && this.config.enableWasm !== false) {\n try {\n const exports = this.wasmInstance.exports as unknown as WasmExports;\n const [ptr, len] = this.writeString(JSON.stringify(metadata));\n\n const resultPtr = exports.detect_agent(ptr, len);\n // Read result with dynamic size\n let resultStr = '';\n let offset = 0;\n const memory = new Uint8Array((exports.memory as WebAssembly.Memory).buffer);\n\n // Read until we find the end of the JSON string\n while (offset < 4096) {\n // Max 4KB result\n const byte = memory[resultPtr + offset];\n if (byte === 0 || byte === undefined) break;\n offset++;\n }\n\n if (offset > 0) {\n resultStr = this.readString(resultPtr, offset);\n }\n\n exports.__wbindgen_free(ptr, len);\n if (offset > 0) {\n exports.__wbindgen_free(resultPtr, offset);\n }\n\n const result = JSON.parse(resultStr);\n\n const detection: DetectionResult = {\n ...result,\n verificationMethod: 'cryptographic',\n timestamp: new Date().toISOString(),\n };\n\n if (this.config.onAgentDetected && detection.isAgent) {\n this.config.onAgentDetected(detection);\n }\n\n return detection;\n } catch (error) {\n if (this.config.debug) {\n console.error('WASM detection failed:', error);\n }\n // Fall through to pattern detection\n }\n }\n\n // Fallback: Pattern-based detection\n return this.patternDetection(metadata);\n }\n\n private patternDetection(metadata: {\n userAgent: string;\n ipAddress: string;\n headers: Record<string, string>;\n }): DetectionResult {\n const userAgent = metadata.userAgent.toLowerCase();\n\n // Enhanced AI agent patterns with confidence scores\n const patterns = [\n // High confidence - explicit AI identifiers\n { pattern: /chatgpt-user/i, name: 'ChatGPT', confidence: 0.95 },\n { pattern: /claude-web/i, name: 'Claude', confidence: 0.95 },\n { pattern: /claude-user/i, name: 'Claude', confidence: 0.95 },\n { pattern: /gpt-crawler/i, name: 'GPT Crawler', confidence: 0.95 },\n { pattern: /perplexitybot/i, name: 'Perplexity', confidence: 0.95 },\n { pattern: /perplexity-user/i, name: 'Perplexity', confidence: 0.95 },\n { pattern: /perplexity-ai/i, name: 'Perplexity', confidence: 0.95 },\n\n // Medium-high confidence - company identifiers\n { pattern: /anthropic/i, name: 'Anthropic', confidence: 0.9 },\n { pattern: /openai/i, name: 'OpenAI', confidence: 0.9 },\n\n // Medium confidence - product names\n { pattern: /copilot/i, name: 'GitHub Copilot', confidence: 0.85 },\n { pattern: /bard/i, name: 'Google Bard', confidence: 0.85 },\n { pattern: /gemini/i, name: 'Google Gemini', confidence: 0.85 },\n { pattern: /perplexity/i, name: 'Perplexity', confidence: 0.85 }, // Fallback\n { pattern: /\\byou\\.com\\b/i, name: 'You.com', confidence: 0.8 },\n { pattern: /\\bphind\\b/i, name: 'Phind', confidence: 0.8 },\n ];\n\n // Check for suspicious headers\n const suspiciousHeaders = ['x-openai-', 'x-anthropic-', 'x-ai-', 'x-llm-', 'x-gpt-'];\n\n let headerBoost = 0;\n for (const [key] of Object.entries(metadata.headers)) {\n if (suspiciousHeaders.some((prefix) => key.toLowerCase().startsWith(prefix))) {\n headerBoost = 0.1;\n break;\n }\n }\n\n // Check patterns - patterns are ordered by confidence (highest first: 0.95, 0.90, 0.85...)\n // so breaking on first match returns the highest-confidence match\n for (const { pattern, name, confidence } of patterns) {\n if (pattern.test(userAgent)) {\n const finalConfidence = Math.min(confidence + headerBoost, 1.0);\n\n const result: DetectionResult = {\n isAgent: true,\n confidence: finalConfidence,\n agent: name,\n verificationMethod: 'pattern',\n riskLevel: finalConfidence > 0.9 ? 'high' : 'medium',\n timestamp: new Date().toISOString(),\n };\n\n if (this.config.onAgentDetected) {\n this.config.onAgentDetected(result);\n }\n\n return result;\n }\n }\n\n // Not detected\n return {\n isAgent: false,\n confidence: 0.85,\n verificationMethod: 'pattern',\n timestamp: new Date().toISOString(),\n };\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n getVerificationMethod(): 'cryptographic' | 'pattern' {\n return this.wasmInstance ? 'cryptographic' : 'pattern';\n }\n}\n\n/**\n * Factory function to create an AgentShield instance for Edge Runtime\n */\nexport function createEdgeAgentShield(config?: AgentShieldConfig) {\n return new EdgeRuntimeAgentShield(config);\n}\n\n/**\n * Singleton instance for simple usage\n */\nlet defaultInstance: EdgeRuntimeAgentShield | null = null;\n\nexport function getDefaultAgentShield(config?: AgentShieldConfig): EdgeRuntimeAgentShield {\n if (!defaultInstance) {\n defaultInstance = new EdgeRuntimeAgentShield(config);\n }\n return defaultInstance;\n}\n"]}
|
|
@@ -129,6 +129,7 @@ var EdgeRuntimeAgentShield = class {
|
|
|
129
129
|
// High confidence - explicit AI identifiers
|
|
130
130
|
{ pattern: /chatgpt-user/i, name: "ChatGPT", confidence: 0.95 },
|
|
131
131
|
{ pattern: /claude-web/i, name: "Claude", confidence: 0.95 },
|
|
132
|
+
{ pattern: /claude-user/i, name: "Claude", confidence: 0.95 },
|
|
132
133
|
{ pattern: /gpt-crawler/i, name: "GPT Crawler", confidence: 0.95 },
|
|
133
134
|
{ pattern: /perplexitybot/i, name: "Perplexity", confidence: 0.95 },
|
|
134
135
|
{ pattern: /perplexity-user/i, name: "Perplexity", confidence: 0.95 },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/edge-runtime-loader.ts"],"names":["exports"],"mappings":"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","file":"edge-runtime-loader.mjs","sourcesContent":["/**\n * Utility functions for agentshield-nextjs\n */\n\nimport type { NextRequest } from 'next/server';\n\n/**\n * Extract client IP address from a NextRequest.\n * In Next.js 15+, the `ip` property was removed from NextRequest.\n * This function uses headers to determine the client IP.\n *\n * @param request - The NextRequest object\n * @returns The client IP address or undefined if not available\n */\nexport function getClientIp(request: NextRequest): string | undefined {\n // Check x-forwarded-for header (standard for proxies/load balancers)\n const forwardedFor = request.headers.get('x-forwarded-for');\n if (forwardedFor) {\n // Take the first IP in the chain (original client)\n const ip = forwardedFor.split(',')[0]?.trim();\n if (ip) return ip;\n }\n\n // Check x-real-ip header (commonly used by nginx)\n const realIp = request.headers.get('x-real-ip');\n if (realIp) return realIp;\n\n // Check cf-connecting-ip header (Cloudflare)\n const cfIp = request.headers.get('cf-connecting-ip');\n if (cfIp) return cfIp;\n\n // Check x-client-ip header (some proxies use this)\n const clientIp = request.headers.get('x-client-ip');\n if (clientIp) return clientIp;\n\n return undefined;\n}\n\n/**\n * Safely extract the hostname from a URL string.\n * Returns a friendly fallback when parsing fails so UX copy doesn't leak\n * \"undefined\" or similar to end users.\n */\nexport function safeHostname(url: string): string {\n try {\n return new URL(url).hostname;\n } catch {\n return 'this site';\n }\n}\n","/**\n * Edge Runtime Compatible WASM Loader for AgentShield\n *\n * This module provides a pre-built solution for loading WASM in Edge Runtime.\n * It requires the WASM file to be manually placed in the project.\n */\n\nimport type { NextRequest } from 'next/server';\nimport { getClientIp } from './utils';\n\n// User must provide the WASM module via import\n// This is intentionally not imported here to allow user control\nexport interface WasmModule {\n default: WebAssembly.Module;\n}\n\nexport interface DetectionResult {\n isAgent: boolean;\n isAiCrawler?: boolean;\n confidence: number;\n agent?: string;\n verificationMethod: 'cryptographic' | 'pattern';\n riskLevel?: 'low' | 'medium' | 'high' | 'critical';\n timestamp: string;\n}\n\nexport interface AgentShieldConfig {\n wasmModule?: WebAssembly.Module;\n enableWasm?: boolean;\n onAgentDetected?: (result: DetectionResult) => void;\n blockAgents?: boolean;\n allowedAgents?: string[];\n debug?: boolean;\n}\n\ninterface WasmExports {\n detect_agent(metadataPtr: number, metadataLen: number): number;\n get_version(): number;\n __wbindgen_malloc(size: number): number;\n __wbindgen_free(ptr: number, size: number): void;\n __wbindgen_realloc(ptr: number, oldSize: number, newSize: number): number;\n memory: WebAssembly.Memory;\n}\n\nclass EdgeRuntimeAgentShield {\n private wasmInstance: WebAssembly.Instance | null = null;\n private wasmMemory: WebAssembly.Memory | null = null;\n private config: AgentShieldConfig;\n private initialized = false;\n\n constructor(config: AgentShieldConfig = {}) {\n this.config = config;\n }\n\n async init(wasmModule?: WebAssembly.Module): Promise<void> {\n if (this.initialized) return;\n\n const module = wasmModule || this.config.wasmModule;\n\n if (module && this.config.enableWasm !== false) {\n try {\n this.wasmMemory = new WebAssembly.Memory({ initial: 17, maximum: 256 });\n\n const imports = {\n wbg: {\n __wbindgen_throw: (ptr: number, len: number) => {\n throw new Error(this.readString(ptr, len));\n },\n __wbg_log_: (ptr: number, len: number) => {\n if (this.config.debug) {\n console.log(this.readString(ptr, len));\n }\n },\n },\n env: {\n memory: this.wasmMemory,\n },\n };\n\n this.wasmInstance = await WebAssembly.instantiate(module, imports);\n this.initialized = true;\n\n if (this.config.debug) {\n console.log('✅ AgentShield WASM initialized in Edge Runtime');\n }\n } catch (error) {\n console.warn('⚠️ WASM initialization failed, using pattern detection:', error);\n this.initialized = true;\n }\n } else {\n this.initialized = true;\n }\n }\n\n private readString(ptr: number, len: number): string {\n if (!this.wasmInstance || !this.wasmMemory) {\n throw new Error('WASM not initialized');\n }\n const memory = new Uint8Array(this.wasmMemory.buffer);\n const bytes = memory.slice(ptr, ptr + len);\n return new TextDecoder().decode(bytes);\n }\n\n private writeString(str: string): [number, number] {\n if (!this.wasmInstance) {\n throw new Error('WASM not initialized');\n }\n const exports = this.wasmInstance.exports as unknown as WasmExports;\n\n const encoded = new TextEncoder().encode(str);\n const ptr = exports.__wbindgen_malloc(encoded.length);\n\n const memory = new Uint8Array(exports.memory.buffer);\n memory.set(encoded, ptr);\n\n return [ptr, encoded.length];\n }\n\n async detect(request: NextRequest): Promise<DetectionResult> {\n if (!this.initialized) {\n await this.init();\n }\n\n const metadata = {\n userAgent: request.headers.get('user-agent') || '',\n ipAddress: getClientIp(request) || '',\n headers: Object.fromEntries(request.headers.entries()),\n };\n\n // Try WASM detection first\n if (this.wasmInstance && this.config.enableWasm !== false) {\n try {\n const exports = this.wasmInstance.exports as unknown as WasmExports;\n const [ptr, len] = this.writeString(JSON.stringify(metadata));\n\n const resultPtr = exports.detect_agent(ptr, len);\n // Read result with dynamic size\n let resultStr = '';\n let offset = 0;\n const memory = new Uint8Array((exports.memory as WebAssembly.Memory).buffer);\n\n // Read until we find the end of the JSON string\n while (offset < 4096) {\n // Max 4KB result\n const byte = memory[resultPtr + offset];\n if (byte === 0 || byte === undefined) break;\n offset++;\n }\n\n if (offset > 0) {\n resultStr = this.readString(resultPtr, offset);\n }\n\n exports.__wbindgen_free(ptr, len);\n if (offset > 0) {\n exports.__wbindgen_free(resultPtr, offset);\n }\n\n const result = JSON.parse(resultStr);\n\n const detection: DetectionResult = {\n ...result,\n verificationMethod: 'cryptographic',\n timestamp: new Date().toISOString(),\n };\n\n if (this.config.onAgentDetected && detection.isAgent) {\n this.config.onAgentDetected(detection);\n }\n\n return detection;\n } catch (error) {\n if (this.config.debug) {\n console.error('WASM detection failed:', error);\n }\n // Fall through to pattern detection\n }\n }\n\n // Fallback: Pattern-based detection\n return this.patternDetection(metadata);\n }\n\n private patternDetection(metadata: {\n userAgent: string;\n ipAddress: string;\n headers: Record<string, string>;\n }): DetectionResult {\n const userAgent = metadata.userAgent.toLowerCase();\n\n // Enhanced AI agent patterns with confidence scores\n const patterns = [\n // High confidence - explicit AI identifiers\n { pattern: /chatgpt-user/i, name: 'ChatGPT', confidence: 0.95 },\n { pattern: /claude-web/i, name: 'Claude', confidence: 0.95 },\n { pattern: /gpt-crawler/i, name: 'GPT Crawler', confidence: 0.95 },\n { pattern: /perplexitybot/i, name: 'Perplexity', confidence: 0.95 },\n { pattern: /perplexity-user/i, name: 'Perplexity', confidence: 0.95 },\n { pattern: /perplexity-ai/i, name: 'Perplexity', confidence: 0.95 },\n\n // Medium-high confidence - company identifiers\n { pattern: /anthropic/i, name: 'Anthropic', confidence: 0.9 },\n { pattern: /openai/i, name: 'OpenAI', confidence: 0.9 },\n\n // Medium confidence - product names\n { pattern: /copilot/i, name: 'GitHub Copilot', confidence: 0.85 },\n { pattern: /bard/i, name: 'Google Bard', confidence: 0.85 },\n { pattern: /gemini/i, name: 'Google Gemini', confidence: 0.85 },\n { pattern: /perplexity/i, name: 'Perplexity', confidence: 0.85 }, // Fallback\n { pattern: /\\byou\\.com\\b/i, name: 'You.com', confidence: 0.8 },\n { pattern: /\\bphind\\b/i, name: 'Phind', confidence: 0.8 },\n ];\n\n // Check for suspicious headers\n const suspiciousHeaders = ['x-openai-', 'x-anthropic-', 'x-ai-', 'x-llm-', 'x-gpt-'];\n\n let headerBoost = 0;\n for (const [key] of Object.entries(metadata.headers)) {\n if (suspiciousHeaders.some((prefix) => key.toLowerCase().startsWith(prefix))) {\n headerBoost = 0.1;\n break;\n }\n }\n\n // Check patterns - patterns are ordered by confidence (highest first: 0.95, 0.90, 0.85...)\n // so breaking on first match returns the highest-confidence match\n for (const { pattern, name, confidence } of patterns) {\n if (pattern.test(userAgent)) {\n const finalConfidence = Math.min(confidence + headerBoost, 1.0);\n\n const result: DetectionResult = {\n isAgent: true,\n confidence: finalConfidence,\n agent: name,\n verificationMethod: 'pattern',\n riskLevel: finalConfidence > 0.9 ? 'high' : 'medium',\n timestamp: new Date().toISOString(),\n };\n\n if (this.config.onAgentDetected) {\n this.config.onAgentDetected(result);\n }\n\n return result;\n }\n }\n\n // Not detected\n return {\n isAgent: false,\n confidence: 0.85,\n verificationMethod: 'pattern',\n timestamp: new Date().toISOString(),\n };\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n getVerificationMethod(): 'cryptographic' | 'pattern' {\n return this.wasmInstance ? 'cryptographic' : 'pattern';\n }\n}\n\n/**\n * Factory function to create an AgentShield instance for Edge Runtime\n */\nexport function createEdgeAgentShield(config?: AgentShieldConfig) {\n return new EdgeRuntimeAgentShield(config);\n}\n\n/**\n * Singleton instance for simple usage\n */\nlet defaultInstance: EdgeRuntimeAgentShield | null = null;\n\nexport function getDefaultAgentShield(config?: AgentShieldConfig): EdgeRuntimeAgentShield {\n if (!defaultInstance) {\n defaultInstance = new EdgeRuntimeAgentShield(config);\n }\n return defaultInstance;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/edge-runtime-loader.ts"],"names":["exports"],"mappings":"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","file":"edge-runtime-loader.mjs","sourcesContent":["/**\n * Utility functions for agentshield-nextjs\n */\n\nimport type { NextRequest } from 'next/server';\n\n/**\n * Extract client IP address from a NextRequest.\n * In Next.js 15+, the `ip` property was removed from NextRequest.\n * This function uses headers to determine the client IP.\n *\n * @param request - The NextRequest object\n * @returns The client IP address or undefined if not available\n */\nexport function getClientIp(request: NextRequest): string | undefined {\n // Check x-forwarded-for header (standard for proxies/load balancers)\n const forwardedFor = request.headers.get('x-forwarded-for');\n if (forwardedFor) {\n // Take the first IP in the chain (original client)\n const ip = forwardedFor.split(',')[0]?.trim();\n if (ip) return ip;\n }\n\n // Check x-real-ip header (commonly used by nginx)\n const realIp = request.headers.get('x-real-ip');\n if (realIp) return realIp;\n\n // Check cf-connecting-ip header (Cloudflare)\n const cfIp = request.headers.get('cf-connecting-ip');\n if (cfIp) return cfIp;\n\n // Check x-client-ip header (some proxies use this)\n const clientIp = request.headers.get('x-client-ip');\n if (clientIp) return clientIp;\n\n return undefined;\n}\n\n/**\n * Safely extract the hostname from a URL string.\n * Returns a friendly fallback when parsing fails so UX copy doesn't leak\n * \"undefined\" or similar to end users.\n */\nexport function safeHostname(url: string): string {\n try {\n return new URL(url).hostname;\n } catch {\n return 'this site';\n }\n}\n","/**\n * Edge Runtime Compatible WASM Loader for AgentShield\n *\n * This module provides a pre-built solution for loading WASM in Edge Runtime.\n * It requires the WASM file to be manually placed in the project.\n */\n\nimport type { NextRequest } from 'next/server';\nimport { getClientIp } from './utils';\n\n// User must provide the WASM module via import\n// This is intentionally not imported here to allow user control\nexport interface WasmModule {\n default: WebAssembly.Module;\n}\n\nexport interface DetectionResult {\n isAgent: boolean;\n isAiCrawler?: boolean;\n confidence: number;\n agent?: string;\n verificationMethod: 'cryptographic' | 'pattern';\n riskLevel?: 'low' | 'medium' | 'high' | 'critical';\n timestamp: string;\n}\n\nexport interface AgentShieldConfig {\n wasmModule?: WebAssembly.Module;\n enableWasm?: boolean;\n onAgentDetected?: (result: DetectionResult) => void;\n blockAgents?: boolean;\n allowedAgents?: string[];\n debug?: boolean;\n}\n\ninterface WasmExports {\n detect_agent(metadataPtr: number, metadataLen: number): number;\n get_version(): number;\n __wbindgen_malloc(size: number): number;\n __wbindgen_free(ptr: number, size: number): void;\n __wbindgen_realloc(ptr: number, oldSize: number, newSize: number): number;\n memory: WebAssembly.Memory;\n}\n\nclass EdgeRuntimeAgentShield {\n private wasmInstance: WebAssembly.Instance | null = null;\n private wasmMemory: WebAssembly.Memory | null = null;\n private config: AgentShieldConfig;\n private initialized = false;\n\n constructor(config: AgentShieldConfig = {}) {\n this.config = config;\n }\n\n async init(wasmModule?: WebAssembly.Module): Promise<void> {\n if (this.initialized) return;\n\n const module = wasmModule || this.config.wasmModule;\n\n if (module && this.config.enableWasm !== false) {\n try {\n this.wasmMemory = new WebAssembly.Memory({ initial: 17, maximum: 256 });\n\n const imports = {\n wbg: {\n __wbindgen_throw: (ptr: number, len: number) => {\n throw new Error(this.readString(ptr, len));\n },\n __wbg_log_: (ptr: number, len: number) => {\n if (this.config.debug) {\n console.log(this.readString(ptr, len));\n }\n },\n },\n env: {\n memory: this.wasmMemory,\n },\n };\n\n this.wasmInstance = await WebAssembly.instantiate(module, imports);\n this.initialized = true;\n\n if (this.config.debug) {\n console.log('✅ AgentShield WASM initialized in Edge Runtime');\n }\n } catch (error) {\n console.warn('⚠️ WASM initialization failed, using pattern detection:', error);\n this.initialized = true;\n }\n } else {\n this.initialized = true;\n }\n }\n\n private readString(ptr: number, len: number): string {\n if (!this.wasmInstance || !this.wasmMemory) {\n throw new Error('WASM not initialized');\n }\n const memory = new Uint8Array(this.wasmMemory.buffer);\n const bytes = memory.slice(ptr, ptr + len);\n return new TextDecoder().decode(bytes);\n }\n\n private writeString(str: string): [number, number] {\n if (!this.wasmInstance) {\n throw new Error('WASM not initialized');\n }\n const exports = this.wasmInstance.exports as unknown as WasmExports;\n\n const encoded = new TextEncoder().encode(str);\n const ptr = exports.__wbindgen_malloc(encoded.length);\n\n const memory = new Uint8Array(exports.memory.buffer);\n memory.set(encoded, ptr);\n\n return [ptr, encoded.length];\n }\n\n async detect(request: NextRequest): Promise<DetectionResult> {\n if (!this.initialized) {\n await this.init();\n }\n\n const metadata = {\n userAgent: request.headers.get('user-agent') || '',\n ipAddress: getClientIp(request) || '',\n headers: Object.fromEntries(request.headers.entries()),\n };\n\n // Try WASM detection first\n if (this.wasmInstance && this.config.enableWasm !== false) {\n try {\n const exports = this.wasmInstance.exports as unknown as WasmExports;\n const [ptr, len] = this.writeString(JSON.stringify(metadata));\n\n const resultPtr = exports.detect_agent(ptr, len);\n // Read result with dynamic size\n let resultStr = '';\n let offset = 0;\n const memory = new Uint8Array((exports.memory as WebAssembly.Memory).buffer);\n\n // Read until we find the end of the JSON string\n while (offset < 4096) {\n // Max 4KB result\n const byte = memory[resultPtr + offset];\n if (byte === 0 || byte === undefined) break;\n offset++;\n }\n\n if (offset > 0) {\n resultStr = this.readString(resultPtr, offset);\n }\n\n exports.__wbindgen_free(ptr, len);\n if (offset > 0) {\n exports.__wbindgen_free(resultPtr, offset);\n }\n\n const result = JSON.parse(resultStr);\n\n const detection: DetectionResult = {\n ...result,\n verificationMethod: 'cryptographic',\n timestamp: new Date().toISOString(),\n };\n\n if (this.config.onAgentDetected && detection.isAgent) {\n this.config.onAgentDetected(detection);\n }\n\n return detection;\n } catch (error) {\n if (this.config.debug) {\n console.error('WASM detection failed:', error);\n }\n // Fall through to pattern detection\n }\n }\n\n // Fallback: Pattern-based detection\n return this.patternDetection(metadata);\n }\n\n private patternDetection(metadata: {\n userAgent: string;\n ipAddress: string;\n headers: Record<string, string>;\n }): DetectionResult {\n const userAgent = metadata.userAgent.toLowerCase();\n\n // Enhanced AI agent patterns with confidence scores\n const patterns = [\n // High confidence - explicit AI identifiers\n { pattern: /chatgpt-user/i, name: 'ChatGPT', confidence: 0.95 },\n { pattern: /claude-web/i, name: 'Claude', confidence: 0.95 },\n { pattern: /claude-user/i, name: 'Claude', confidence: 0.95 },\n { pattern: /gpt-crawler/i, name: 'GPT Crawler', confidence: 0.95 },\n { pattern: /perplexitybot/i, name: 'Perplexity', confidence: 0.95 },\n { pattern: /perplexity-user/i, name: 'Perplexity', confidence: 0.95 },\n { pattern: /perplexity-ai/i, name: 'Perplexity', confidence: 0.95 },\n\n // Medium-high confidence - company identifiers\n { pattern: /anthropic/i, name: 'Anthropic', confidence: 0.9 },\n { pattern: /openai/i, name: 'OpenAI', confidence: 0.9 },\n\n // Medium confidence - product names\n { pattern: /copilot/i, name: 'GitHub Copilot', confidence: 0.85 },\n { pattern: /bard/i, name: 'Google Bard', confidence: 0.85 },\n { pattern: /gemini/i, name: 'Google Gemini', confidence: 0.85 },\n { pattern: /perplexity/i, name: 'Perplexity', confidence: 0.85 }, // Fallback\n { pattern: /\\byou\\.com\\b/i, name: 'You.com', confidence: 0.8 },\n { pattern: /\\bphind\\b/i, name: 'Phind', confidence: 0.8 },\n ];\n\n // Check for suspicious headers\n const suspiciousHeaders = ['x-openai-', 'x-anthropic-', 'x-ai-', 'x-llm-', 'x-gpt-'];\n\n let headerBoost = 0;\n for (const [key] of Object.entries(metadata.headers)) {\n if (suspiciousHeaders.some((prefix) => key.toLowerCase().startsWith(prefix))) {\n headerBoost = 0.1;\n break;\n }\n }\n\n // Check patterns - patterns are ordered by confidence (highest first: 0.95, 0.90, 0.85...)\n // so breaking on first match returns the highest-confidence match\n for (const { pattern, name, confidence } of patterns) {\n if (pattern.test(userAgent)) {\n const finalConfidence = Math.min(confidence + headerBoost, 1.0);\n\n const result: DetectionResult = {\n isAgent: true,\n confidence: finalConfidence,\n agent: name,\n verificationMethod: 'pattern',\n riskLevel: finalConfidence > 0.9 ? 'high' : 'medium',\n timestamp: new Date().toISOString(),\n };\n\n if (this.config.onAgentDetected) {\n this.config.onAgentDetected(result);\n }\n\n return result;\n }\n }\n\n // Not detected\n return {\n isAgent: false,\n confidence: 0.85,\n verificationMethod: 'pattern',\n timestamp: new Date().toISOString(),\n };\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n getVerificationMethod(): 'cryptographic' | 'pattern' {\n return this.wasmInstance ? 'cryptographic' : 'pattern';\n }\n}\n\n/**\n * Factory function to create an AgentShield instance for Edge Runtime\n */\nexport function createEdgeAgentShield(config?: AgentShieldConfig) {\n return new EdgeRuntimeAgentShield(config);\n}\n\n/**\n * Singleton instance for simple usage\n */\nlet defaultInstance: EdgeRuntimeAgentShield | null = null;\n\nexport function getDefaultAgentShield(config?: AgentShieldConfig): EdgeRuntimeAgentShield {\n if (!defaultInstance) {\n defaultInstance = new EdgeRuntimeAgentShield(config);\n }\n return defaultInstance;\n}\n"]}
|
|
@@ -511,6 +511,7 @@ var init_edge_detector_with_wasm = __esm({
|
|
|
511
511
|
var AI_AGENT_PATTERNS = [
|
|
512
512
|
{ pattern: /chatgpt-user/i, type: "chatgpt", name: "ChatGPT" },
|
|
513
513
|
{ pattern: /claude-web/i, type: "claude", name: "Claude" },
|
|
514
|
+
{ pattern: /claude-user/i, type: "claude", name: "Claude" },
|
|
514
515
|
{ pattern: /perplexitybot/i, type: "perplexity", name: "Perplexity" },
|
|
515
516
|
{ pattern: /perplexity-user/i, type: "perplexity", name: "Perplexity" },
|
|
516
517
|
{ pattern: /perplexity/i, type: "perplexity", name: "Perplexity" },
|