@kya-os/agentshield-nextjs 0.1.14 → 0.1.16
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/create-middleware.d.mts +16 -0
- package/dist/create-middleware.d.ts +16 -0
- package/dist/create-middleware.js +279 -0
- package/dist/create-middleware.js.map +1 -0
- package/dist/create-middleware.mjs +271 -0
- package/dist/create-middleware.mjs.map +1 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +166 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +159 -5
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.d.mts +17 -2
- package/dist/middleware.d.ts +17 -2
- package/dist/nodejs-wasm-loader.d.mts +25 -0
- package/dist/nodejs-wasm-loader.d.ts +25 -0
- package/dist/nodejs-wasm-loader.js +78 -0
- package/dist/nodejs-wasm-loader.js.map +1 -0
- package/dist/nodejs-wasm-loader.mjs +68 -0
- package/dist/nodejs-wasm-loader.mjs.map +1 -0
- package/dist/{middleware-OvcbG6s2.d.mts → types-Hsgc8Gry.d.mts} +1 -14
- package/dist/{middleware-OvcbG6s2.d.ts → types-Hsgc8Gry.d.ts} +1 -14
- package/dist/wasm-setup.d.mts +7 -4
- package/dist/wasm-setup.d.ts +7 -4
- package/dist/wasm-setup.js +126 -21
- package/dist/wasm-setup.js.map +1 -1
- package/dist/wasm-setup.mjs +121 -21
- package/dist/wasm-setup.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
import { N as NextJSMiddlewareConfig } from './types-Hsgc8Gry.mjs';
|
|
3
|
+
import '@kya-os/agentshield';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Enhanced middleware creator that handles WASM initialization internally
|
|
7
|
+
* This avoids top-level await issues in Next.js middleware
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create an AgentShield middleware with automatic WASM initialization
|
|
12
|
+
* This version handles initialization internally to avoid top-level await
|
|
13
|
+
*/
|
|
14
|
+
declare function createAgentShieldMiddleware(config: NextJSMiddlewareConfig): (request: NextRequest) => Promise<NextResponse>;
|
|
15
|
+
|
|
16
|
+
export { createAgentShieldMiddleware, createAgentShieldMiddleware as createMiddleware };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
import { N as NextJSMiddlewareConfig } from './types-Hsgc8Gry.js';
|
|
3
|
+
import '@kya-os/agentshield';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Enhanced middleware creator that handles WASM initialization internally
|
|
7
|
+
* This avoids top-level await issues in Next.js middleware
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create an AgentShield middleware with automatic WASM initialization
|
|
12
|
+
* This version handles initialization internally to avoid top-level await
|
|
13
|
+
*/
|
|
14
|
+
declare function createAgentShieldMiddleware(config: NextJSMiddlewareConfig): (request: NextRequest) => Promise<NextResponse>;
|
|
15
|
+
|
|
16
|
+
export { createAgentShieldMiddleware, createAgentShieldMiddleware as createMiddleware };
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
var agentshield = require('@kya-os/agentshield');
|
|
6
|
+
var server = require('next/server');
|
|
7
|
+
|
|
8
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
11
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
12
|
+
|
|
13
|
+
var __defProp = Object.defineProperty;
|
|
14
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
15
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
16
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
17
|
+
}) : x)(function(x) {
|
|
18
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
19
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
20
|
+
});
|
|
21
|
+
var __esm = (fn, res) => function __init() {
|
|
22
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
23
|
+
};
|
|
24
|
+
var __export = (target, all) => {
|
|
25
|
+
for (var name in all)
|
|
26
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/nodejs-wasm-loader.ts
|
|
30
|
+
var nodejs_wasm_loader_exports = {};
|
|
31
|
+
__export(nodejs_wasm_loader_exports, {
|
|
32
|
+
getWasmModule: () => getWasmModule,
|
|
33
|
+
isNodejsRuntime: () => isNodejsRuntime,
|
|
34
|
+
isWasmInitialized: () => isWasmInitialized,
|
|
35
|
+
loadWasmNodejs: () => loadWasmNodejs
|
|
36
|
+
});
|
|
37
|
+
async function loadWasmNodejs() {
|
|
38
|
+
if (wasmInitialized) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const possiblePaths = [
|
|
43
|
+
// In node_modules (most likely)
|
|
44
|
+
path__default.default.join(process.cwd(), "node_modules", "@kya-os", "agentshield", "dist", "wasm", "agentshield_wasm_bg.wasm"),
|
|
45
|
+
// In project root (if user copied it)
|
|
46
|
+
path__default.default.join(process.cwd(), "agentshield_wasm_bg.wasm"),
|
|
47
|
+
// Relative to current file
|
|
48
|
+
path__default.default.join(__dirname, "..", "..", "..", "agentshield", "dist", "wasm", "agentshield_wasm_bg.wasm")
|
|
49
|
+
];
|
|
50
|
+
let wasmBuffer = null;
|
|
51
|
+
let loadedPath = null;
|
|
52
|
+
for (const wasmPath of possiblePaths) {
|
|
53
|
+
try {
|
|
54
|
+
if (fs__default.default.existsSync(wasmPath)) {
|
|
55
|
+
wasmBuffer = fs__default.default.readFileSync(wasmPath);
|
|
56
|
+
loadedPath = wasmPath;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
} catch (e) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (!wasmBuffer) {
|
|
64
|
+
console.warn("AgentShield: WASM file not found in any expected location");
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const bytes = new Uint8Array(wasmBuffer);
|
|
68
|
+
wasmModule = await WebAssembly.compile(bytes);
|
|
69
|
+
agentshield.setWasmModule(wasmModule);
|
|
70
|
+
wasmInitialized = true;
|
|
71
|
+
console.log(`\u2705 AgentShield: WASM loaded successfully from ${loadedPath} (Node.js runtime)`);
|
|
72
|
+
console.log("\u{1F510} Cryptographic verification enabled (95-100% confidence)");
|
|
73
|
+
return true;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.warn("\u26A0\uFE0F AgentShield: Failed to load WASM in Node.js runtime:", error);
|
|
76
|
+
console.log("\u{1F4CA} Falling back to pattern detection (85% confidence)");
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function isNodejsRuntime() {
|
|
81
|
+
return typeof process !== "undefined" && typeof process.versions !== "undefined" && typeof process.versions.node !== "undefined" && typeof __require !== "undefined";
|
|
82
|
+
}
|
|
83
|
+
function getWasmModule() {
|
|
84
|
+
return wasmModule;
|
|
85
|
+
}
|
|
86
|
+
function isWasmInitialized() {
|
|
87
|
+
return wasmInitialized;
|
|
88
|
+
}
|
|
89
|
+
var wasmInitialized, wasmModule;
|
|
90
|
+
var init_nodejs_wasm_loader = __esm({
|
|
91
|
+
"src/nodejs-wasm-loader.ts"() {
|
|
92
|
+
wasmInitialized = false;
|
|
93
|
+
wasmModule = null;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// src/wasm-setup.ts
|
|
98
|
+
var wasmInitialized2 = false;
|
|
99
|
+
var initPromise = null;
|
|
100
|
+
var initAttempted = false;
|
|
101
|
+
async function setupWasm() {
|
|
102
|
+
if (wasmInitialized2) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (initPromise) {
|
|
106
|
+
return initPromise;
|
|
107
|
+
}
|
|
108
|
+
initPromise = doSetupWasm();
|
|
109
|
+
return initPromise;
|
|
110
|
+
}
|
|
111
|
+
async function doSetupWasm() {
|
|
112
|
+
if (initAttempted) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
initAttempted = true;
|
|
116
|
+
try {
|
|
117
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV === "test") {
|
|
118
|
+
wasmInitialized2 = true;
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const isNodejs = typeof process !== "undefined" && typeof __require !== "undefined" && process.env.NEXT_RUNTIME === "nodejs";
|
|
122
|
+
if (isNodejs) {
|
|
123
|
+
try {
|
|
124
|
+
const { loadWasmNodejs: loadWasmNodejs2 } = await Promise.resolve().then(() => (init_nodejs_wasm_loader(), nodejs_wasm_loader_exports));
|
|
125
|
+
const loaded = await loadWasmNodejs2();
|
|
126
|
+
wasmInitialized2 = true;
|
|
127
|
+
if (loaded) {
|
|
128
|
+
console.log("\u{1F680} AgentShield: Running with full WASM support (Node.js runtime)");
|
|
129
|
+
} else {
|
|
130
|
+
console.log("\u{1F4CA} AgentShield: Using pattern detection (WASM not found)");
|
|
131
|
+
}
|
|
132
|
+
return;
|
|
133
|
+
} catch (error) {
|
|
134
|
+
console.warn("\u26A0\uFE0F AgentShield: Node.js WASM loader failed:", error);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
wasmInitialized2 = true;
|
|
138
|
+
if (process.env.NEXT_RUNTIME === "edge") {
|
|
139
|
+
console.log("\u26A1 AgentShield: Edge Runtime detected - using pattern detection (85% confidence)");
|
|
140
|
+
console.log('\u{1F4A1} Tip: Add `export const runtime = "nodejs"` to your middleware for full WASM support');
|
|
141
|
+
}
|
|
142
|
+
} catch (error) {
|
|
143
|
+
wasmInitialized2 = true;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function createAgentShieldMiddleware(config = {}) {
|
|
147
|
+
const detector = new agentshield.AgentDetector(config);
|
|
148
|
+
if (config.events) {
|
|
149
|
+
Object.entries(config.events).forEach(([event, handler]) => {
|
|
150
|
+
detector.on(event, handler);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
const {
|
|
154
|
+
onAgentDetected = "log",
|
|
155
|
+
onDetection,
|
|
156
|
+
skipPaths = [],
|
|
157
|
+
blockedResponse = {
|
|
158
|
+
status: 403,
|
|
159
|
+
message: "Access denied: Automated agent detected",
|
|
160
|
+
headers: { "Content-Type": "application/json" }
|
|
161
|
+
},
|
|
162
|
+
redirectUrl = "/blocked",
|
|
163
|
+
rewriteUrl = "/blocked"
|
|
164
|
+
} = config;
|
|
165
|
+
return async (request) => {
|
|
166
|
+
try {
|
|
167
|
+
const shouldSkip = skipPaths.some((pattern) => {
|
|
168
|
+
if (typeof pattern === "string") {
|
|
169
|
+
return request.nextUrl.pathname.startsWith(pattern);
|
|
170
|
+
}
|
|
171
|
+
return pattern.test(request.nextUrl.pathname);
|
|
172
|
+
});
|
|
173
|
+
if (shouldSkip) {
|
|
174
|
+
request.agentShield = { skipped: true };
|
|
175
|
+
return server.NextResponse.next();
|
|
176
|
+
}
|
|
177
|
+
const context = {
|
|
178
|
+
userAgent: request.headers.get("user-agent") ?? void 0,
|
|
179
|
+
ipAddress: request.ip ?? request.headers.get("x-forwarded-for") ?? void 0,
|
|
180
|
+
headers: Object.fromEntries(request.headers.entries()),
|
|
181
|
+
url: request.url,
|
|
182
|
+
method: request.method,
|
|
183
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
184
|
+
};
|
|
185
|
+
const result = await detector.analyze(context);
|
|
186
|
+
if (result.isAgent && result.confidence >= (config.confidenceThreshold ?? 0.7)) {
|
|
187
|
+
if (onDetection) {
|
|
188
|
+
const customResponse = await onDetection(request, result);
|
|
189
|
+
if (customResponse) {
|
|
190
|
+
return customResponse;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
switch (onAgentDetected) {
|
|
194
|
+
case "block": {
|
|
195
|
+
const response2 = server.NextResponse.json(
|
|
196
|
+
{
|
|
197
|
+
error: blockedResponse.message,
|
|
198
|
+
detected: true,
|
|
199
|
+
confidence: result.confidence,
|
|
200
|
+
timestamp: result.timestamp
|
|
201
|
+
},
|
|
202
|
+
{ status: blockedResponse.status }
|
|
203
|
+
);
|
|
204
|
+
if (blockedResponse.headers) {
|
|
205
|
+
Object.entries(blockedResponse.headers).forEach(
|
|
206
|
+
([key, value]) => {
|
|
207
|
+
response2.headers.set(key, value);
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
detector.emit("agent.blocked", result, context);
|
|
212
|
+
return response2;
|
|
213
|
+
}
|
|
214
|
+
case "redirect":
|
|
215
|
+
return server.NextResponse.redirect(new URL(redirectUrl, request.url));
|
|
216
|
+
case "rewrite":
|
|
217
|
+
return server.NextResponse.rewrite(new URL(rewriteUrl, request.url));
|
|
218
|
+
case "log":
|
|
219
|
+
console.warn("AgentShield: Agent detected", {
|
|
220
|
+
ipAddress: context.ipAddress,
|
|
221
|
+
userAgent: context.userAgent,
|
|
222
|
+
confidence: result.confidence,
|
|
223
|
+
reasons: result.reasons,
|
|
224
|
+
pathname: request.nextUrl.pathname
|
|
225
|
+
});
|
|
226
|
+
break;
|
|
227
|
+
case "allow":
|
|
228
|
+
default:
|
|
229
|
+
if (result.isAgent && result.confidence >= (config.confidenceThreshold ?? 0.7)) {
|
|
230
|
+
detector.emit("agent.allowed", result, context);
|
|
231
|
+
}
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
request.agentShield = {
|
|
236
|
+
result,
|
|
237
|
+
skipped: false
|
|
238
|
+
};
|
|
239
|
+
const response = server.NextResponse.next();
|
|
240
|
+
response.headers.set("x-agentshield-detected", result.isAgent.toString());
|
|
241
|
+
response.headers.set(
|
|
242
|
+
"x-agentshield-confidence",
|
|
243
|
+
result.confidence.toString()
|
|
244
|
+
);
|
|
245
|
+
return response;
|
|
246
|
+
} catch (error) {
|
|
247
|
+
console.error("AgentShield middleware error:", error);
|
|
248
|
+
return server.NextResponse.next();
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// src/create-middleware.ts
|
|
254
|
+
var middlewareInstance = null;
|
|
255
|
+
var isInitializing = false;
|
|
256
|
+
var initPromise2 = null;
|
|
257
|
+
function createAgentShieldMiddleware2(config) {
|
|
258
|
+
return async function agentShieldMiddleware(request) {
|
|
259
|
+
if (!middlewareInstance) {
|
|
260
|
+
if (!isInitializing) {
|
|
261
|
+
isInitializing = true;
|
|
262
|
+
initPromise2 = (async () => {
|
|
263
|
+
await setupWasm();
|
|
264
|
+
middlewareInstance = createAgentShieldMiddleware(config);
|
|
265
|
+
return middlewareInstance;
|
|
266
|
+
})();
|
|
267
|
+
}
|
|
268
|
+
if (initPromise2) {
|
|
269
|
+
middlewareInstance = await initPromise2;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return middlewareInstance ? middlewareInstance(request) : server.NextResponse.next();
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
exports.createAgentShieldMiddleware = createAgentShieldMiddleware2;
|
|
277
|
+
exports.createMiddleware = createAgentShieldMiddleware2;
|
|
278
|
+
//# sourceMappingURL=create-middleware.js.map
|
|
279
|
+
//# sourceMappingURL=create-middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/nodejs-wasm-loader.ts","../src/wasm-setup.ts","../src/middleware.ts","../src/create-middleware.ts"],"names":["path","fs","setWasmModule","wasmInitialized","loadWasmNodejs","AgentDetector","NextResponse","response","initPromise","createAgentShieldMiddleware"],"mappings":"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","file":"create-middleware.js","sourcesContent":["/**\n * Node.js Runtime WASM Loader for AgentShield\n * \n * This loader uses fs.readFileSync to load WASM in Node.js runtime.\n * It provides full cryptographic verification capabilities.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { setWasmModule } from '@kya-os/agentshield';\n\nlet wasmInitialized = false;\nlet wasmModule: WebAssembly.Module | null = null;\n\n/**\n * Load WASM module using Node.js fs module\n * This only works in Node.js runtime, not Edge Runtime\n */\nexport async function loadWasmNodejs(): Promise<boolean> {\n if (wasmInitialized) {\n return true;\n }\n\n try {\n // Try multiple possible WASM locations\n const possiblePaths = [\n // In node_modules (most likely)\n path.join(process.cwd(), 'node_modules', '@kya-os', 'agentshield', 'dist', 'wasm', 'agentshield_wasm_bg.wasm'),\n // In project root (if user copied it)\n path.join(process.cwd(), 'agentshield_wasm_bg.wasm'),\n // Relative to current file\n path.join(__dirname, '..', '..', '..', 'agentshield', 'dist', 'wasm', 'agentshield_wasm_bg.wasm'),\n ];\n\n let wasmBuffer: Buffer | null = null;\n let loadedPath: string | null = null;\n\n for (const wasmPath of possiblePaths) {\n try {\n if (fs.existsSync(wasmPath)) {\n wasmBuffer = fs.readFileSync(wasmPath);\n loadedPath = wasmPath;\n break;\n }\n } catch (e) {\n // Try next path\n continue;\n }\n }\n\n if (!wasmBuffer) {\n console.warn('AgentShield: WASM file not found in any expected location');\n return false;\n }\n\n // Convert Buffer to Uint8Array for WebAssembly\n // This is the proper way to handle Buffer -> ArrayBuffer conversion\n const bytes = new Uint8Array(wasmBuffer);\n wasmModule = await WebAssembly.compile(bytes);\n \n // Set the module in AgentShield\n setWasmModule(wasmModule);\n \n wasmInitialized = true;\n console.log(`✅ AgentShield: WASM loaded successfully from ${loadedPath} (Node.js runtime)`);\n console.log('🔐 Cryptographic verification enabled (95-100% confidence)');\n \n return true;\n } catch (error) {\n console.warn('⚠️ AgentShield: Failed to load WASM in Node.js runtime:', error);\n console.log('📊 Falling back to pattern detection (85% confidence)');\n return false;\n }\n}\n\n/**\n * Check if we're in Node.js runtime\n */\nexport function isNodejsRuntime(): boolean {\n return typeof process !== 'undefined' && \n typeof process.versions !== 'undefined' && \n typeof process.versions.node !== 'undefined' &&\n typeof require !== 'undefined';\n}\n\n/**\n * Get the loaded WASM module\n */\nexport function getWasmModule(): WebAssembly.Module | null {\n return wasmModule;\n}\n\n/**\n * Check if WASM is initialized\n */\nexport function isWasmInitialized(): boolean {\n return wasmInitialized;\n}","/**\n * WASM Setup for AgentShield in Next.js Edge Runtime\n * \n * This module handles WASM initialization for cryptographic signature verification.\n * Designed to work without top-level await to avoid Next.js middleware issues.\n * \n * Usage in middleware.ts:\n * ```typescript\n * import { setupWasm } from '@kya-os/agentshield-nextjs/wasm-setup';\n * import { createAgentShieldMiddleware } from '@kya-os/agentshield-nextjs';\n * \n * export async function middleware(request: NextRequest) {\n * // Initialize WASM inside the middleware function\n * await setupWasm();\n * \n * const agentShieldMiddleware = createAgentShieldMiddleware({...});\n * return agentShieldMiddleware(request);\n * }\n * ```\n */\n\nlet wasmInitialized = false;\nlet initPromise: Promise<void> | null = null;\nlet initAttempted = false;\n\n/**\n * Initialize WASM module for AgentShield\n * \n * This function:\n * - Loads WASM in production/Edge Runtime for cryptographic verification\n * - Skips WASM in test environments (Jest) automatically\n * - Is safe to call multiple times (idempotent)\n * - Handles errors gracefully with fallback to pattern detection\n * \n * @returns Promise that resolves when initialization is complete\n */\nexport async function setupWasm(): Promise<void> {\n // Already initialized, return immediately\n if (wasmInitialized) {\n return;\n }\n\n // Initialization in progress, return the existing promise\n if (initPromise) {\n return initPromise;\n }\n\n // Start initialization\n initPromise = doSetupWasm();\n return initPromise;\n}\n\nasync function doSetupWasm(): Promise<void> {\n // Prevent multiple initialization attempts\n if (initAttempted) {\n return;\n }\n initAttempted = true;\n\n try {\n // Skip WASM in test environments\n if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {\n wasmInitialized = true;\n return;\n }\n\n // Check if we're in Node.js runtime (middleware with runtime: 'nodejs')\n const isNodejs = typeof process !== 'undefined' && \n typeof require !== 'undefined' &&\n process.env.NEXT_RUNTIME === 'nodejs';\n\n if (isNodejs) {\n // We're in Node.js runtime - use fs to load WASM!\n try {\n const { loadWasmNodejs } = await import('./nodejs-wasm-loader');\n const loaded = await loadWasmNodejs();\n wasmInitialized = true;\n \n if (loaded) {\n console.log('🚀 AgentShield: Running with full WASM support (Node.js runtime)');\n } else {\n console.log('📊 AgentShield: Using pattern detection (WASM not found)');\n }\n return;\n } catch (error) {\n console.warn('⚠️ AgentShield: Node.js WASM loader failed:', error);\n }\n }\n\n // Edge Runtime or build time - skip WASM loading\n // Pattern detection will be used (85% confidence)\n wasmInitialized = true;\n \n if (process.env.NEXT_RUNTIME === 'edge') {\n console.log('⚡ AgentShield: Edge Runtime detected - using pattern detection (85% confidence)');\n console.log('💡 Tip: Add `export const runtime = \"nodejs\"` to your middleware for full WASM support');\n }\n } catch (error) {\n // Mark as initialized to prevent retries\n wasmInitialized = true;\n }\n}\n\n/**\n * Check if WASM has been initialized\n * \n * @returns true if WASM setup has been attempted (success or failure)\n */\nexport function isWasmInitialized(): boolean {\n return wasmInitialized;\n}\n\n/**\n * Reset WASM initialization state (mainly for testing)\n * \n * @internal\n */\nexport function resetWasmState(): void {\n wasmInitialized = false;\n initPromise = null;\n}","/**\n * Next.js middleware for AgentShield\n */\n\nimport { NextRequest, NextResponse } from 'next/server';\nimport { AgentDetector } from '@kya-os/agentshield';\nimport type { NextJSMiddlewareConfig } from './types';\n\n/**\n * Create AgentShield middleware for Next.js\n */\nexport function createAgentShieldMiddleware(\n config: Partial<NextJSMiddlewareConfig> = {}\n) {\n const detector = new AgentDetector(config);\n \n // Wire up event handlers if provided\n if (config.events) {\n Object.entries(config.events).forEach(([event, handler]) => {\n detector.on(event as any, handler as any);\n });\n }\n\n const {\n onAgentDetected = 'log',\n onDetection,\n skipPaths = [],\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 } = config;\n\n return async (request: NextRequest): Promise<NextResponse> => {\n try {\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 // Mark as skipped in request\n (request as any).agentShield = { skipped: true };\n return NextResponse.next();\n }\n\n // Prepare request context\n const context = {\n userAgent: request.headers.get('user-agent') ?? undefined,\n ipAddress: request.ip ?? request.headers.get('x-forwarded-for') ?? undefined,\n headers: Object.fromEntries(request.headers.entries()),\n url: request.url,\n method: request.method,\n timestamp: new Date(),\n };\n\n // Analyze request\n const result = await detector.analyze(context);\n\n // Handle detection result\n if (\n result.isAgent &&\n result.confidence >= (config.confidenceThreshold ?? 0.7)\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(\n ([key, value]) => {\n response.headers.set(key, value);\n }\n );\n }\n \n // Emit blocked event\n detector.emit('agent.blocked', result, context);\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 console.warn('AgentShield: Agent detected', {\n ipAddress: context.ipAddress,\n userAgent: context.userAgent,\n confidence: result.confidence,\n reasons: result.reasons,\n pathname: request.nextUrl.pathname,\n });\n break;\n\n case 'allow':\n default:\n // Emit allowed event for high-confidence agents\n if (result.isAgent && result.confidence >= (config.confidenceThreshold ?? 0.7)) {\n detector.emit('agent.allowed', result, context);\n }\n // Continue processing\n break;\n }\n }\n\n // Add detection result to request for API routes\n (request as any).agentShield = {\n result,\n skipped: false,\n };\n\n // Add detection result to response headers for debugging\n const response = NextResponse.next();\n response.headers.set('x-agentshield-detected', result.isAgent.toString());\n response.headers.set(\n 'x-agentshield-confidence',\n result.confidence.toString()\n );\n\n return response;\n } catch (error) {\n console.error('AgentShield middleware error:', error);\n return NextResponse.next(); // Continue on error\n }\n };\n}\n\n/**\n * Convenience function for basic setup\n */\nexport function agentShield(config: Partial<NextJSMiddlewareConfig> = {}) {\n return createAgentShieldMiddleware(config);\n}\n","/**\n * Enhanced middleware creator that handles WASM initialization internally\n * This avoids top-level await issues in Next.js middleware\n */\n\nimport { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport { setupWasm } from './wasm-setup';\nimport { createAgentShieldMiddleware as createBaseMiddleware } from './middleware';\nimport type { NextJSMiddlewareConfig } from './types';\n\nlet middlewareInstance: any = null;\nlet isInitializing = false;\nlet initPromise: Promise<any> | null = null;\n\n/**\n * Create an AgentShield middleware with automatic WASM initialization\n * This version handles initialization internally to avoid top-level await\n */\nexport function createAgentShieldMiddleware(config: NextJSMiddlewareConfig) {\n return async function agentShieldMiddleware(\n request: NextRequest\n ): Promise<NextResponse> {\n // Initialize WASM and middleware on first request\n if (!middlewareInstance) {\n if (!isInitializing) {\n isInitializing = true;\n initPromise = (async () => {\n // Initialize WASM (will gracefully fallback if not available)\n await setupWasm();\n\n // Create the actual middleware instance\n middlewareInstance = createBaseMiddleware(config);\n return middlewareInstance;\n })();\n }\n\n // Wait for initialization to complete\n if (initPromise) {\n middlewareInstance = await initPromise;\n }\n }\n\n // Run the middleware\n return middlewareInstance\n ? middlewareInstance(request)\n : NextResponse.next();\n };\n}\n\n/**\n * Export the original function as well for backward compatibility\n */\nexport { createAgentShieldMiddleware as createMiddleware };\n"]}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { setWasmModule, AgentDetector } from '@kya-os/agentshield';
|
|
4
|
+
import { NextResponse } from 'next/server';
|
|
5
|
+
|
|
6
|
+
var __defProp = Object.defineProperty;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
9
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
10
|
+
}) : x)(function(x) {
|
|
11
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
12
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
|
+
});
|
|
14
|
+
var __esm = (fn, res) => function __init() {
|
|
15
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
16
|
+
};
|
|
17
|
+
var __export = (target, all) => {
|
|
18
|
+
for (var name in all)
|
|
19
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// src/nodejs-wasm-loader.ts
|
|
23
|
+
var nodejs_wasm_loader_exports = {};
|
|
24
|
+
__export(nodejs_wasm_loader_exports, {
|
|
25
|
+
getWasmModule: () => getWasmModule,
|
|
26
|
+
isNodejsRuntime: () => isNodejsRuntime,
|
|
27
|
+
isWasmInitialized: () => isWasmInitialized,
|
|
28
|
+
loadWasmNodejs: () => loadWasmNodejs
|
|
29
|
+
});
|
|
30
|
+
async function loadWasmNodejs() {
|
|
31
|
+
if (wasmInitialized) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const possiblePaths = [
|
|
36
|
+
// In node_modules (most likely)
|
|
37
|
+
path.join(process.cwd(), "node_modules", "@kya-os", "agentshield", "dist", "wasm", "agentshield_wasm_bg.wasm"),
|
|
38
|
+
// In project root (if user copied it)
|
|
39
|
+
path.join(process.cwd(), "agentshield_wasm_bg.wasm"),
|
|
40
|
+
// Relative to current file
|
|
41
|
+
path.join(__dirname, "..", "..", "..", "agentshield", "dist", "wasm", "agentshield_wasm_bg.wasm")
|
|
42
|
+
];
|
|
43
|
+
let wasmBuffer = null;
|
|
44
|
+
let loadedPath = null;
|
|
45
|
+
for (const wasmPath of possiblePaths) {
|
|
46
|
+
try {
|
|
47
|
+
if (fs.existsSync(wasmPath)) {
|
|
48
|
+
wasmBuffer = fs.readFileSync(wasmPath);
|
|
49
|
+
loadedPath = wasmPath;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
} catch (e) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (!wasmBuffer) {
|
|
57
|
+
console.warn("AgentShield: WASM file not found in any expected location");
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const bytes = new Uint8Array(wasmBuffer);
|
|
61
|
+
wasmModule = await WebAssembly.compile(bytes);
|
|
62
|
+
setWasmModule(wasmModule);
|
|
63
|
+
wasmInitialized = true;
|
|
64
|
+
console.log(`\u2705 AgentShield: WASM loaded successfully from ${loadedPath} (Node.js runtime)`);
|
|
65
|
+
console.log("\u{1F510} Cryptographic verification enabled (95-100% confidence)");
|
|
66
|
+
return true;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.warn("\u26A0\uFE0F AgentShield: Failed to load WASM in Node.js runtime:", error);
|
|
69
|
+
console.log("\u{1F4CA} Falling back to pattern detection (85% confidence)");
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function isNodejsRuntime() {
|
|
74
|
+
return typeof process !== "undefined" && typeof process.versions !== "undefined" && typeof process.versions.node !== "undefined" && typeof __require !== "undefined";
|
|
75
|
+
}
|
|
76
|
+
function getWasmModule() {
|
|
77
|
+
return wasmModule;
|
|
78
|
+
}
|
|
79
|
+
function isWasmInitialized() {
|
|
80
|
+
return wasmInitialized;
|
|
81
|
+
}
|
|
82
|
+
var wasmInitialized, wasmModule;
|
|
83
|
+
var init_nodejs_wasm_loader = __esm({
|
|
84
|
+
"src/nodejs-wasm-loader.ts"() {
|
|
85
|
+
wasmInitialized = false;
|
|
86
|
+
wasmModule = null;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// src/wasm-setup.ts
|
|
91
|
+
var wasmInitialized2 = false;
|
|
92
|
+
var initPromise = null;
|
|
93
|
+
var initAttempted = false;
|
|
94
|
+
async function setupWasm() {
|
|
95
|
+
if (wasmInitialized2) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (initPromise) {
|
|
99
|
+
return initPromise;
|
|
100
|
+
}
|
|
101
|
+
initPromise = doSetupWasm();
|
|
102
|
+
return initPromise;
|
|
103
|
+
}
|
|
104
|
+
async function doSetupWasm() {
|
|
105
|
+
if (initAttempted) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
initAttempted = true;
|
|
109
|
+
try {
|
|
110
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV === "test") {
|
|
111
|
+
wasmInitialized2 = true;
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const isNodejs = typeof process !== "undefined" && typeof __require !== "undefined" && process.env.NEXT_RUNTIME === "nodejs";
|
|
115
|
+
if (isNodejs) {
|
|
116
|
+
try {
|
|
117
|
+
const { loadWasmNodejs: loadWasmNodejs2 } = await Promise.resolve().then(() => (init_nodejs_wasm_loader(), nodejs_wasm_loader_exports));
|
|
118
|
+
const loaded = await loadWasmNodejs2();
|
|
119
|
+
wasmInitialized2 = true;
|
|
120
|
+
if (loaded) {
|
|
121
|
+
console.log("\u{1F680} AgentShield: Running with full WASM support (Node.js runtime)");
|
|
122
|
+
} else {
|
|
123
|
+
console.log("\u{1F4CA} AgentShield: Using pattern detection (WASM not found)");
|
|
124
|
+
}
|
|
125
|
+
return;
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.warn("\u26A0\uFE0F AgentShield: Node.js WASM loader failed:", error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
wasmInitialized2 = true;
|
|
131
|
+
if (process.env.NEXT_RUNTIME === "edge") {
|
|
132
|
+
console.log("\u26A1 AgentShield: Edge Runtime detected - using pattern detection (85% confidence)");
|
|
133
|
+
console.log('\u{1F4A1} Tip: Add `export const runtime = "nodejs"` to your middleware for full WASM support');
|
|
134
|
+
}
|
|
135
|
+
} catch (error) {
|
|
136
|
+
wasmInitialized2 = true;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function createAgentShieldMiddleware(config = {}) {
|
|
140
|
+
const detector = new AgentDetector(config);
|
|
141
|
+
if (config.events) {
|
|
142
|
+
Object.entries(config.events).forEach(([event, handler]) => {
|
|
143
|
+
detector.on(event, handler);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
const {
|
|
147
|
+
onAgentDetected = "log",
|
|
148
|
+
onDetection,
|
|
149
|
+
skipPaths = [],
|
|
150
|
+
blockedResponse = {
|
|
151
|
+
status: 403,
|
|
152
|
+
message: "Access denied: Automated agent detected",
|
|
153
|
+
headers: { "Content-Type": "application/json" }
|
|
154
|
+
},
|
|
155
|
+
redirectUrl = "/blocked",
|
|
156
|
+
rewriteUrl = "/blocked"
|
|
157
|
+
} = config;
|
|
158
|
+
return async (request) => {
|
|
159
|
+
try {
|
|
160
|
+
const shouldSkip = skipPaths.some((pattern) => {
|
|
161
|
+
if (typeof pattern === "string") {
|
|
162
|
+
return request.nextUrl.pathname.startsWith(pattern);
|
|
163
|
+
}
|
|
164
|
+
return pattern.test(request.nextUrl.pathname);
|
|
165
|
+
});
|
|
166
|
+
if (shouldSkip) {
|
|
167
|
+
request.agentShield = { skipped: true };
|
|
168
|
+
return NextResponse.next();
|
|
169
|
+
}
|
|
170
|
+
const context = {
|
|
171
|
+
userAgent: request.headers.get("user-agent") ?? void 0,
|
|
172
|
+
ipAddress: request.ip ?? request.headers.get("x-forwarded-for") ?? void 0,
|
|
173
|
+
headers: Object.fromEntries(request.headers.entries()),
|
|
174
|
+
url: request.url,
|
|
175
|
+
method: request.method,
|
|
176
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
177
|
+
};
|
|
178
|
+
const result = await detector.analyze(context);
|
|
179
|
+
if (result.isAgent && result.confidence >= (config.confidenceThreshold ?? 0.7)) {
|
|
180
|
+
if (onDetection) {
|
|
181
|
+
const customResponse = await onDetection(request, result);
|
|
182
|
+
if (customResponse) {
|
|
183
|
+
return customResponse;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
switch (onAgentDetected) {
|
|
187
|
+
case "block": {
|
|
188
|
+
const response2 = NextResponse.json(
|
|
189
|
+
{
|
|
190
|
+
error: blockedResponse.message,
|
|
191
|
+
detected: true,
|
|
192
|
+
confidence: result.confidence,
|
|
193
|
+
timestamp: result.timestamp
|
|
194
|
+
},
|
|
195
|
+
{ status: blockedResponse.status }
|
|
196
|
+
);
|
|
197
|
+
if (blockedResponse.headers) {
|
|
198
|
+
Object.entries(blockedResponse.headers).forEach(
|
|
199
|
+
([key, value]) => {
|
|
200
|
+
response2.headers.set(key, value);
|
|
201
|
+
}
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
detector.emit("agent.blocked", result, context);
|
|
205
|
+
return response2;
|
|
206
|
+
}
|
|
207
|
+
case "redirect":
|
|
208
|
+
return NextResponse.redirect(new URL(redirectUrl, request.url));
|
|
209
|
+
case "rewrite":
|
|
210
|
+
return NextResponse.rewrite(new URL(rewriteUrl, request.url));
|
|
211
|
+
case "log":
|
|
212
|
+
console.warn("AgentShield: Agent detected", {
|
|
213
|
+
ipAddress: context.ipAddress,
|
|
214
|
+
userAgent: context.userAgent,
|
|
215
|
+
confidence: result.confidence,
|
|
216
|
+
reasons: result.reasons,
|
|
217
|
+
pathname: request.nextUrl.pathname
|
|
218
|
+
});
|
|
219
|
+
break;
|
|
220
|
+
case "allow":
|
|
221
|
+
default:
|
|
222
|
+
if (result.isAgent && result.confidence >= (config.confidenceThreshold ?? 0.7)) {
|
|
223
|
+
detector.emit("agent.allowed", result, context);
|
|
224
|
+
}
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
request.agentShield = {
|
|
229
|
+
result,
|
|
230
|
+
skipped: false
|
|
231
|
+
};
|
|
232
|
+
const response = NextResponse.next();
|
|
233
|
+
response.headers.set("x-agentshield-detected", result.isAgent.toString());
|
|
234
|
+
response.headers.set(
|
|
235
|
+
"x-agentshield-confidence",
|
|
236
|
+
result.confidence.toString()
|
|
237
|
+
);
|
|
238
|
+
return response;
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.error("AgentShield middleware error:", error);
|
|
241
|
+
return NextResponse.next();
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/create-middleware.ts
|
|
247
|
+
var middlewareInstance = null;
|
|
248
|
+
var isInitializing = false;
|
|
249
|
+
var initPromise2 = null;
|
|
250
|
+
function createAgentShieldMiddleware2(config) {
|
|
251
|
+
return async function agentShieldMiddleware(request) {
|
|
252
|
+
if (!middlewareInstance) {
|
|
253
|
+
if (!isInitializing) {
|
|
254
|
+
isInitializing = true;
|
|
255
|
+
initPromise2 = (async () => {
|
|
256
|
+
await setupWasm();
|
|
257
|
+
middlewareInstance = createAgentShieldMiddleware(config);
|
|
258
|
+
return middlewareInstance;
|
|
259
|
+
})();
|
|
260
|
+
}
|
|
261
|
+
if (initPromise2) {
|
|
262
|
+
middlewareInstance = await initPromise2;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return middlewareInstance ? middlewareInstance(request) : NextResponse.next();
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export { createAgentShieldMiddleware2 as createAgentShieldMiddleware, createAgentShieldMiddleware2 as createMiddleware };
|
|
270
|
+
//# sourceMappingURL=create-middleware.mjs.map
|
|
271
|
+
//# sourceMappingURL=create-middleware.mjs.map
|