@agentix-security/nextjs 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +36 -0
- package/dist/index.js +36 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -418,6 +418,17 @@ async function fingerprint2(req) {
|
|
|
418
418
|
const buf = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(data));
|
|
419
419
|
return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
420
420
|
}
|
|
421
|
+
function agentScore(req) {
|
|
422
|
+
let score = 0;
|
|
423
|
+
const ua = (req.headers.get("user-agent") ?? "").toLowerCase();
|
|
424
|
+
if (/bot|crawler|spider|python-requests|curl\/|node-fetch|axios|go-http-client|claude-web|gptbot|chatgpt|google-extended|oai-searchbot|anthropic|llm/i.test(ua)) score += 0.8;
|
|
425
|
+
if (!ua) score += 0.6;
|
|
426
|
+
if (!req.headers.get("sec-fetch-site") && !req.headers.get("sec-ch-ua")) score += 0.5;
|
|
427
|
+
if (!req.headers.get("accept-language")) score += 0.15;
|
|
428
|
+
const accept = req.headers.get("accept") ?? "";
|
|
429
|
+
if (req.method === "GET" && !accept.includes("text/html")) score += 0.2;
|
|
430
|
+
return Math.min(score, 1);
|
|
431
|
+
}
|
|
421
432
|
function bearer(req) {
|
|
422
433
|
const auth = req.headers.get("authorization");
|
|
423
434
|
if (!auth?.startsWith("Bearer ")) return null;
|
|
@@ -522,6 +533,31 @@ function agentixMiddleware(sdk) {
|
|
|
522
533
|
expires_in: exp - iat
|
|
523
534
|
});
|
|
524
535
|
}
|
|
536
|
+
const isHumanPage = !pathname.startsWith("/api/") && !pathname.startsWith("/agent/") && !pathname.startsWith("/_next/") && !pathname.startsWith("/favicon");
|
|
537
|
+
if (isHumanPage && agentScore(req) >= 0.5) {
|
|
538
|
+
const registry = sdk.getIntentRegistry();
|
|
539
|
+
const tools = Object.fromEntries(
|
|
540
|
+
[...registry.entries()].map(([intent, entry]) => [intent, { routes: [...entry.routes] }])
|
|
541
|
+
);
|
|
542
|
+
void shipAudit2(cp, licenseKey, auditRow(sdk, req, pathname, 200, fp, {
|
|
543
|
+
trust_mode: "unmanaged_automation",
|
|
544
|
+
intent_scope: "none",
|
|
545
|
+
token_id: null,
|
|
546
|
+
decision: "allow",
|
|
547
|
+
decision_reason: "agent_redirected_to_lane",
|
|
548
|
+
policy_id: "agent-detection"
|
|
549
|
+
}));
|
|
550
|
+
return server_js.NextResponse.json({
|
|
551
|
+
service: "agentix-intent-sdk",
|
|
552
|
+
version: "0.2.0",
|
|
553
|
+
message: "AI agent detected. Use the agent API instead of the human-facing site.",
|
|
554
|
+
tenant_id: sdk.getResolvedTenantId(),
|
|
555
|
+
deployment_id: sdk.getDeploymentId(),
|
|
556
|
+
discovery: { well_known: `${baseUrl}/.well-known/ai-agent.json`, token_endpoint: `${baseUrl}/agent/v1/declare_intent` },
|
|
557
|
+
intents: [...registry.keys()],
|
|
558
|
+
tools
|
|
559
|
+
}, { headers: { "cache-control": "no-store" } });
|
|
560
|
+
}
|
|
525
561
|
if (req.method === "GET" && pathname === "/robots.txt") {
|
|
526
562
|
let upstream = "";
|
|
527
563
|
try {
|
package/dist/index.js
CHANGED
|
@@ -416,6 +416,17 @@ async function fingerprint2(req) {
|
|
|
416
416
|
const buf = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(data));
|
|
417
417
|
return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
418
418
|
}
|
|
419
|
+
function agentScore(req) {
|
|
420
|
+
let score = 0;
|
|
421
|
+
const ua = (req.headers.get("user-agent") ?? "").toLowerCase();
|
|
422
|
+
if (/bot|crawler|spider|python-requests|curl\/|node-fetch|axios|go-http-client|claude-web|gptbot|chatgpt|google-extended|oai-searchbot|anthropic|llm/i.test(ua)) score += 0.8;
|
|
423
|
+
if (!ua) score += 0.6;
|
|
424
|
+
if (!req.headers.get("sec-fetch-site") && !req.headers.get("sec-ch-ua")) score += 0.5;
|
|
425
|
+
if (!req.headers.get("accept-language")) score += 0.15;
|
|
426
|
+
const accept = req.headers.get("accept") ?? "";
|
|
427
|
+
if (req.method === "GET" && !accept.includes("text/html")) score += 0.2;
|
|
428
|
+
return Math.min(score, 1);
|
|
429
|
+
}
|
|
419
430
|
function bearer(req) {
|
|
420
431
|
const auth = req.headers.get("authorization");
|
|
421
432
|
if (!auth?.startsWith("Bearer ")) return null;
|
|
@@ -520,6 +531,31 @@ function agentixMiddleware(sdk) {
|
|
|
520
531
|
expires_in: exp - iat
|
|
521
532
|
});
|
|
522
533
|
}
|
|
534
|
+
const isHumanPage = !pathname.startsWith("/api/") && !pathname.startsWith("/agent/") && !pathname.startsWith("/_next/") && !pathname.startsWith("/favicon");
|
|
535
|
+
if (isHumanPage && agentScore(req) >= 0.5) {
|
|
536
|
+
const registry = sdk.getIntentRegistry();
|
|
537
|
+
const tools = Object.fromEntries(
|
|
538
|
+
[...registry.entries()].map(([intent, entry]) => [intent, { routes: [...entry.routes] }])
|
|
539
|
+
);
|
|
540
|
+
void shipAudit2(cp, licenseKey, auditRow(sdk, req, pathname, 200, fp, {
|
|
541
|
+
trust_mode: "unmanaged_automation",
|
|
542
|
+
intent_scope: "none",
|
|
543
|
+
token_id: null,
|
|
544
|
+
decision: "allow",
|
|
545
|
+
decision_reason: "agent_redirected_to_lane",
|
|
546
|
+
policy_id: "agent-detection"
|
|
547
|
+
}));
|
|
548
|
+
return NextResponse.json({
|
|
549
|
+
service: "agentix-intent-sdk",
|
|
550
|
+
version: "0.2.0",
|
|
551
|
+
message: "AI agent detected. Use the agent API instead of the human-facing site.",
|
|
552
|
+
tenant_id: sdk.getResolvedTenantId(),
|
|
553
|
+
deployment_id: sdk.getDeploymentId(),
|
|
554
|
+
discovery: { well_known: `${baseUrl}/.well-known/ai-agent.json`, token_endpoint: `${baseUrl}/agent/v1/declare_intent` },
|
|
555
|
+
intents: [...registry.keys()],
|
|
556
|
+
tools
|
|
557
|
+
}, { headers: { "cache-control": "no-store" } });
|
|
558
|
+
}
|
|
523
559
|
if (req.method === "GET" && pathname === "/robots.txt") {
|
|
524
560
|
let upstream = "";
|
|
525
561
|
try {
|