@agentvisa/widget 0.2.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AgentVisa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # @agentvisa/widget
2
+
3
+ Lightweight JavaScript/TypeScript widget for **AgentVisa** verification.
4
+
5
+ Drop-in verification for websites that need to confirm a real human has approved an AI agent's action.
6
+
7
+ ## Features
8
+
9
+ - Works with both **Basic** and **Pro** tiers
10
+ - Unified response shape for all plans
11
+ - Zero runtime dependencies
12
+ - < 5KB gzipped
13
+ - TypeScript support
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @agentvisa/widget
19
+ ```
20
+
21
+ Or via CDN:
22
+
23
+ ```html
24
+ <script src="https://cdn.agentvisa.ai/widget.js"></script>
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ### Basic Usage (Recommended)
30
+
31
+ ```ts
32
+ import { AgentVisa } from "@agentvisa/widget";
33
+
34
+ const result = await AgentVisa.verify({
35
+ widgetId: "widget_abc123",
36
+ plan: "basic"
37
+ });
38
+
39
+ console.log(result.valid); // true | false
40
+ console.log(result.reason); // "ok" | "expired" | "invalid" ...
41
+ console.log(result.plan); // "basic" | "pro"
42
+ ```
43
+
44
+ ### Instance Usage
45
+
46
+ ```ts
47
+ const visa = new AgentVisa({
48
+ widgetId: "widget_abc123",
49
+ plan: "pro"
50
+ });
51
+
52
+ const result = await visa.verify();
53
+ ```
54
+
55
+ ### Browser (UMD)
56
+
57
+ ```html
58
+ <script src="https://cdn.agentvisa.ai/widget.js"></script>
59
+ <script>
60
+ const result = await AgentVisa.verify({
61
+ widgetId: "widget_abc123",
62
+ plan: "basic"
63
+ });
64
+ </script>
65
+ ```
66
+
67
+ ## Response Shape
68
+
69
+ The widget always returns the unified response:
70
+
71
+ ```json
72
+ {
73
+ "valid": true,
74
+ "reason": "ok",
75
+ "plan": "basic",
76
+ "widget_id": "widget_abc123",
77
+ "human_name": null,
78
+ "email": null,
79
+ "phone": null,
80
+ "verified_at": null,
81
+ "expires_at": null
82
+ }
83
+ ```
84
+
85
+ ## Configuration
86
+
87
+ | Option | Type | Default | Description |
88
+ |--------------|--------------------|--------------------------|---------------------------------|
89
+ | `widgetId` | `string` | **required** | Your AgentVisa widget ID |
90
+ | `plan` | `"basic" \| "pro"` | `"basic"` | Verification tier |
91
+ | `apiBaseUrl` | `string` | `"https://api.agentvisa.ai"` | Backend API base URL |
92
+
93
+ ## Development
94
+
95
+ ```bash
96
+ npm install
97
+ npm run build
98
+ ```
99
+
100
+ Build output is in `dist/`:
101
+
102
+ - `widget.js` — UMD bundle (browser)
103
+ - `widget.esm.js` — ESM bundle
104
+ - `index.d.ts` — TypeScript definitions
105
+
106
+ ## Examples
107
+
108
+ See the `examples/` folder:
109
+
110
+ - `basic.html` — Basic tier demo
111
+ - `pro.html` — Pro tier demo with richer data
112
+
113
+ ## Contributing
114
+
115
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
116
+
117
+ ## Security
118
+
119
+ See [SECURITY.md](SECURITY.md).
120
+
121
+ ## License
122
+
123
+ MIT © [AgentVisa](https://agentvisa.ai)
package/dist/core.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Shared server-side verification logic.
3
+ * Used by Express and Next.js middleware — no framework deps here.
4
+ */
5
+ export declare const DEFAULT_API_BASE = "https://api.agentvisa.ai";
6
+ export interface AgentVisaConfig {
7
+ /** Your widget ID from the AgentVisa dashboard */
8
+ widgetId: string;
9
+ /** Your widget API key — keep server-side only, never expose to the browser */
10
+ apiKey: string;
11
+ /** Override API base URL (e.g. for staging) */
12
+ apiBaseUrl?: string;
13
+ /**
14
+ * What to do when verification fails or token is missing.
15
+ * "block" (default) — return 401 and stop the request.
16
+ * "passthrough" — attach result to request and continue; let your
17
+ * handler decide. Useful for soft-gating or analytics.
18
+ */
19
+ onUnverified?: "block" | "passthrough";
20
+ }
21
+ export interface VerifyResult {
22
+ valid: boolean;
23
+ reason: string;
24
+ plan?: string;
25
+ widget_id?: string;
26
+ human_name?: string | null;
27
+ verified_at?: string | null;
28
+ expires_at?: string | null;
29
+ five_factor?: string;
30
+ age_over_18?: string;
31
+ age_over_21?: string;
32
+ multiple_agents_authorized?: string;
33
+ verifications_today?: number;
34
+ }
35
+ /**
36
+ * Call /v1/verify with a TemporaryToken.
37
+ * Returns the full API response or a synthetic error result on network failure.
38
+ */
39
+ export declare function callVerify(temporaryToken: string, config: Required<AgentVisaConfig>): Promise<VerifyResult>;
40
+ export declare function resolveConfig(config: AgentVisaConfig): Required<AgentVisaConfig>;
41
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,gBAAgB,6BAA6B,CAAC;AAE3D,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;CACxC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,GAChC,OAAO,CAAC,YAAY,CAAC,CAcvB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAC,CAMhF"}
package/dist/core.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Shared server-side verification logic.
3
+ * Used by Express and Next.js middleware — no framework deps here.
4
+ */
5
+ export const DEFAULT_API_BASE = "https://api.agentvisa.ai";
6
+ /**
7
+ * Call /v1/verify with a TemporaryToken.
8
+ * Returns the full API response or a synthetic error result on network failure.
9
+ */
10
+ export async function callVerify(temporaryToken, config) {
11
+ try {
12
+ const url = `${config.apiBaseUrl}/v1/verify?token=${encodeURIComponent(temporaryToken)}&widget_id=${encodeURIComponent(config.widgetId)}`;
13
+ const response = await fetch(url, {
14
+ method: "POST",
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ "X-Widget-Api-Key": config.apiKey,
18
+ },
19
+ });
20
+ return await response.json();
21
+ }
22
+ catch {
23
+ return { valid: false, reason: "network_error" };
24
+ }
25
+ }
26
+ export function resolveConfig(config) {
27
+ return {
28
+ apiBaseUrl: DEFAULT_API_BASE,
29
+ onUnverified: "block",
30
+ ...config,
31
+ };
32
+ }
33
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,0BAA0B,CAAC;AAkC3D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,cAAsB,EACtB,MAAiC;IAEjC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,UAAU,oBAAoB,kBAAkB,CAAC,cAAc,CAAC,cAAc,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1I,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,kBAAkB,EAAE,MAAM,CAAC,MAAM;aAClC;SACF,CAAC,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAkB,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IACnD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAuB;IACnD,OAAO;QACL,UAAU,EAAE,gBAAgB;QAC5B,YAAY,EAAE,OAAO;QACrB,GAAG,MAAM;KACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * AgentVisa Express middleware
3
+ *
4
+ * Usage:
5
+ * import { agentVisa } from "@agentvisa/widget/express";
6
+ *
7
+ * app.use(agentVisa({
8
+ * widgetId: process.env.AV_WIDGET_ID!,
9
+ * apiKey: process.env.AV_API_KEY!,
10
+ * }));
11
+ *
12
+ * Or protect specific routes only:
13
+ * app.get("/premium", agentVisa({ widgetId, apiKey }), handler);
14
+ *
15
+ * On success, req.agentVisa is populated:
16
+ * req.agentVisa.verified — boolean
17
+ * req.agentVisa.result — full VerifyResult (if verified)
18
+ * req.agentVisa.reason — failure reason (if not verified + passthrough mode)
19
+ */
20
+ import { AgentVisaConfig, VerifyResult } from "../core.js";
21
+ export type { AgentVisaConfig, VerifyResult };
22
+ interface Req {
23
+ headers: Record<string, string | string[] | undefined>;
24
+ agentVisa?: {
25
+ verified: boolean;
26
+ result?: VerifyResult;
27
+ reason?: string;
28
+ };
29
+ }
30
+ interface Res {
31
+ status(code: number): Res;
32
+ json(body: unknown): void;
33
+ setHeader(name: string, value: string): void;
34
+ }
35
+ type NextFn = (err?: unknown) => void;
36
+ export declare function agentVisa(config: AgentVisaConfig): (req: Req, res: Res, next: NextFn) => Promise<void>;
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,eAAe,EAAE,YAAY,EAA6B,MAAM,YAAY,CAAC;AAEtF,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAI9C,UAAU,GAAG;IACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACvD,SAAS,CAAC,EAAE;QACV,QAAQ,EAAE,OAAO,CAAC;QAClB,MAAM,CAAC,EAAE,YAAY,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,UAAU,GAAG;IACX,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC;IAC1B,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9C;AAED,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAEtC,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,IAI7C,KAAK,GAAG,EACR,KAAK,GAAG,EACR,MAAM,MAAM,KACX,OAAO,CAAC,IAAI,CAAC,CA2CjB"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * AgentVisa Express middleware
3
+ *
4
+ * Usage:
5
+ * import { agentVisa } from "@agentvisa/widget/express";
6
+ *
7
+ * app.use(agentVisa({
8
+ * widgetId: process.env.AV_WIDGET_ID!,
9
+ * apiKey: process.env.AV_API_KEY!,
10
+ * }));
11
+ *
12
+ * Or protect specific routes only:
13
+ * app.get("/premium", agentVisa({ widgetId, apiKey }), handler);
14
+ *
15
+ * On success, req.agentVisa is populated:
16
+ * req.agentVisa.verified — boolean
17
+ * req.agentVisa.result — full VerifyResult (if verified)
18
+ * req.agentVisa.reason — failure reason (if not verified + passthrough mode)
19
+ */
20
+ import { callVerify, resolveConfig } from "../core.js";
21
+ export function agentVisa(config) {
22
+ const resolved = resolveConfig(config);
23
+ return async function agentVisaMiddleware(req, res, next) {
24
+ const rawToken = req.headers["x-agentvisa-token"];
25
+ const token = Array.isArray(rawToken) ? rawToken[0] : rawToken;
26
+ // ── No token present ────────────────────────────────────────────────────
27
+ if (!token) {
28
+ if (resolved.onUnverified === "passthrough") {
29
+ req.agentVisa = { verified: false, reason: "no_token" };
30
+ return next();
31
+ }
32
+ res.setHeader("X-AgentVisa-Required", resolved.widgetId);
33
+ res.status(401).json({
34
+ error: "agentvisa_required",
35
+ message: "This endpoint requires an AgentVisa verification token. " +
36
+ "Call POST /v1/token/assert with your api/token and this widget_id " +
37
+ "to get a TemporaryToken, then retry with X-AgentVisa-Token: <token>.",
38
+ widget_id: resolved.widgetId,
39
+ });
40
+ return;
41
+ }
42
+ // ── Token present — verify it ───────────────────────────────────────────
43
+ const result = await callVerify(token, resolved);
44
+ if (!result.valid) {
45
+ if (resolved.onUnverified === "passthrough") {
46
+ req.agentVisa = { verified: false, reason: result.reason, result };
47
+ return next();
48
+ }
49
+ res.setHeader("X-AgentVisa-Required", resolved.widgetId);
50
+ res.status(401).json({
51
+ error: "agentvisa_verification_failed",
52
+ reason: result.reason,
53
+ widget_id: resolved.widgetId,
54
+ });
55
+ return;
56
+ }
57
+ // ── Verified ────────────────────────────────────────────────────────────
58
+ req.agentVisa = { verified: true, result };
59
+ return next();
60
+ };
61
+ }
62
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAiC,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAuBtF,MAAM,UAAU,SAAS,CAAC,MAAuB;IAC/C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAEvC,OAAO,KAAK,UAAU,mBAAmB,CACvC,GAAQ,EACR,GAAQ,EACR,IAAY;QAEZ,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QAE/D,2EAA2E;QAC3E,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,QAAQ,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;gBAC5C,GAAG,CAAC,SAAS,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;gBACxD,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;YACD,GAAG,CAAC,SAAS,CAAC,sBAAsB,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACzD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,oBAAoB;gBAC3B,OAAO,EACL,0DAA0D;oBAC1D,oEAAoE;oBACpE,sEAAsE;gBACxE,SAAS,EAAE,QAAQ,CAAC,QAAQ;aAC7B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,2EAA2E;QAC3E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAEjD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,QAAQ,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;gBAC5C,GAAG,CAAC,SAAS,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBACnE,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;YACD,GAAG,CAAC,SAAS,CAAC,sBAAsB,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACzD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,+BAA+B;gBACtC,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,SAAS,EAAE,QAAQ,CAAC,QAAQ;aAC7B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,2EAA2E;QAC3E,GAAG,CAAC,SAAS,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC3C,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,33 @@
1
+ type Plan = "basic" | "pro";
2
+ interface WidgetOptions {
3
+ widgetId: string;
4
+ plan?: Plan;
5
+ apiBaseUrl?: string;
6
+ }
7
+ interface VerificationResult {
8
+ valid: boolean;
9
+ reason: string;
10
+ plan: Plan;
11
+ widget_id: string;
12
+ human_name: string | null;
13
+ email: string | null;
14
+ phone: string | null;
15
+ verified_at: string | null;
16
+ expires_at: string | null;
17
+ }
18
+
19
+ declare class AgentVisa {
20
+ private options;
21
+ constructor(options: WidgetOptions);
22
+ /**
23
+ * Verify the current token for this widget.
24
+ * Returns the unified VerificationResult.
25
+ */
26
+ verify(): Promise<VerificationResult>;
27
+ /**
28
+ * Quick static helper for one-off verification (commonly used pattern).
29
+ */
30
+ static verify(options: WidgetOptions): Promise<VerificationResult>;
31
+ }
32
+
33
+ export { AgentVisa };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * AgentVisa Next.js middleware
3
+ *
4
+ * Usage — middleware.ts (project root):
5
+ *
6
+ * import { withAgentVisa } from "@agentvisa/widget/next";
7
+ *
8
+ * export default withAgentVisa({
9
+ * widgetId: process.env.AV_WIDGET_ID!,
10
+ * apiKey: process.env.AV_API_KEY!,
11
+ * });
12
+ *
13
+ * export const config = {
14
+ * matcher: ["/api/:path*"], // paths to protect
15
+ * };
16
+ *
17
+ * Or wrap your own middleware:
18
+ *
19
+ * export default withAgentVisa({ widgetId, apiKey }, async (req) => {
20
+ * // only runs if agent is verified
21
+ * return NextResponse.next();
22
+ * });
23
+ *
24
+ * Uses only standard Web APIs (Request/Response) — works on Node.js
25
+ * runtime and Edge runtime.
26
+ *
27
+ * On success, the forwarded request carries two headers your handlers can read:
28
+ * X-AgentVisa-Verified: true
29
+ * X-AgentVisa-Reason: ok
30
+ */
31
+ import { AgentVisaConfig, VerifyResult } from "../core.js";
32
+ export type { AgentVisaConfig, VerifyResult };
33
+ type NextHandler = (request: Request) => Response | Promise<Response>;
34
+ /**
35
+ * Wrap a Next.js middleware handler (or use standalone).
36
+ *
37
+ * @param config Widget ID + API key + options
38
+ * @param handler Optional inner handler — called only when agent is verified.
39
+ * If omitted, passes through with Response headers set.
40
+ */
41
+ export declare function withAgentVisa(config: AgentVisaConfig, handler?: NextHandler): NextHandler;
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,eAAe,EAAE,YAAY,EAA6B,MAAM,YAAY,CAAC;AAEtF,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAE9C,KAAK,WAAW,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEtE;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,WAAW,GACpB,WAAW,CA8Bb"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * AgentVisa Next.js middleware
3
+ *
4
+ * Usage — middleware.ts (project root):
5
+ *
6
+ * import { withAgentVisa } from "@agentvisa/widget/next";
7
+ *
8
+ * export default withAgentVisa({
9
+ * widgetId: process.env.AV_WIDGET_ID!,
10
+ * apiKey: process.env.AV_API_KEY!,
11
+ * });
12
+ *
13
+ * export const config = {
14
+ * matcher: ["/api/:path*"], // paths to protect
15
+ * };
16
+ *
17
+ * Or wrap your own middleware:
18
+ *
19
+ * export default withAgentVisa({ widgetId, apiKey }, async (req) => {
20
+ * // only runs if agent is verified
21
+ * return NextResponse.next();
22
+ * });
23
+ *
24
+ * Uses only standard Web APIs (Request/Response) — works on Node.js
25
+ * runtime and Edge runtime.
26
+ *
27
+ * On success, the forwarded request carries two headers your handlers can read:
28
+ * X-AgentVisa-Verified: true
29
+ * X-AgentVisa-Reason: ok
30
+ */
31
+ import { callVerify, resolveConfig } from "../core.js";
32
+ /**
33
+ * Wrap a Next.js middleware handler (or use standalone).
34
+ *
35
+ * @param config Widget ID + API key + options
36
+ * @param handler Optional inner handler — called only when agent is verified.
37
+ * If omitted, passes through with Response headers set.
38
+ */
39
+ export function withAgentVisa(config, handler) {
40
+ const resolved = resolveConfig(config);
41
+ return async function agentVisaMiddleware(request) {
42
+ const token = request.headers.get("x-agentvisa-token") ?? undefined;
43
+ // ── No token ──────────────────────────────────────────────────────────
44
+ if (!token) {
45
+ if (resolved.onUnverified === "passthrough") {
46
+ const req = addVerificationHeaders(request, false, "no_token");
47
+ return handler ? handler(req) : passthroughResponse(req);
48
+ }
49
+ return blockedResponse(resolved.widgetId, "no_token");
50
+ }
51
+ // ── Verify ────────────────────────────────────────────────────────────
52
+ const result = await callVerify(token, resolved);
53
+ if (!result.valid) {
54
+ if (resolved.onUnverified === "passthrough") {
55
+ const req = addVerificationHeaders(request, false, result.reason);
56
+ return handler ? handler(req) : passthroughResponse(req);
57
+ }
58
+ return blockedResponse(resolved.widgetId, result.reason);
59
+ }
60
+ // ── Verified ──────────────────────────────────────────────────────────
61
+ const req = addVerificationHeaders(request, true, "ok");
62
+ return handler ? handler(req) : passthroughResponse(req);
63
+ };
64
+ }
65
+ // ── Helpers ─────────────────────────────────────────────────────────────────
66
+ function blockedResponse(widgetId, reason) {
67
+ return new Response(JSON.stringify({
68
+ error: "agentvisa_required",
69
+ reason,
70
+ widget_id: widgetId,
71
+ message: "This endpoint requires an AgentVisa verification token. " +
72
+ "Call POST /v1/token/assert with your api/token and this widget_id " +
73
+ "to get a TemporaryToken, then retry with X-AgentVisa-Token: <token>.",
74
+ }), {
75
+ status: 401,
76
+ headers: {
77
+ "Content-Type": "application/json",
78
+ "X-AgentVisa-Required": widgetId,
79
+ },
80
+ });
81
+ }
82
+ function addVerificationHeaders(request, verified, reason) {
83
+ // Clone the request and add verification headers so downstream handlers
84
+ // can read them via request.headers.get("x-agentvisa-verified")
85
+ const headers = new Headers(request.headers);
86
+ headers.set("x-agentvisa-verified", String(verified));
87
+ headers.set("x-agentvisa-reason", reason);
88
+ return new Request(request.url, {
89
+ method: request.method,
90
+ headers,
91
+ body: request.body,
92
+ // @ts-ignore — duplex needed for streaming bodies in some runtimes
93
+ duplex: "half",
94
+ });
95
+ }
96
+ function passthroughResponse(request) {
97
+ // Signal to Next.js to continue to the route handler.
98
+ // Uses the NextResponse.next() equivalent via headers.
99
+ return new Response(null, {
100
+ status: 200,
101
+ headers: {
102
+ "x-middleware-next": "1",
103
+ "x-agentvisa-verified": request.headers.get("x-agentvisa-verified") ?? "false",
104
+ "x-agentvisa-reason": request.headers.get("x-agentvisa-reason") ?? "unknown",
105
+ },
106
+ });
107
+ }
108
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ const DEFAULT_API_BASE = "https://api.agentvisa.ai";
2
+ async function verifyToken(options) {
3
+ const { widgetId, plan = "basic", apiBaseUrl = DEFAULT_API_BASE, } = options;
4
+ const url = new URL("/v1/verify", apiBaseUrl);
5
+ url.searchParams.set("widget_id", widgetId);
6
+ url.searchParams.set("plan", plan);
7
+ // Note: token is currently empty — this is the skeleton.
8
+ // In real usage the AI agent will pass the tmp_ token here.
9
+ const response = await fetch(url.toString(), {
10
+ method: "POST",
11
+ headers: {
12
+ "Content-Type": "application/json",
13
+ },
14
+ body: JSON.stringify({
15
+ token: "",
16
+ widget_id: widgetId,
17
+ plan,
18
+ }),
19
+ });
20
+ if (!response.ok) {
21
+ return {
22
+ valid: false,
23
+ reason: "network_error",
24
+ plan,
25
+ widget_id: widgetId,
26
+ human_name: null,
27
+ email: null,
28
+ phone: null,
29
+ verified_at: null,
30
+ expires_at: null,
31
+ };
32
+ }
33
+ return response.json();
34
+ }
35
+
36
+ class AgentVisa {
37
+ constructor(options) {
38
+ this.options = {
39
+ plan: "basic",
40
+ apiBaseUrl: "https://api.agentvisa.ai",
41
+ ...options,
42
+ };
43
+ }
44
+ /**
45
+ * Verify the current token for this widget.
46
+ * Returns the unified VerificationResult.
47
+ */
48
+ async verify() {
49
+ return verifyToken(this.options);
50
+ }
51
+ /**
52
+ * Quick static helper for one-off verification (commonly used pattern).
53
+ */
54
+ static async verify(options) {
55
+ return verifyToken({
56
+ plan: "basic",
57
+ apiBaseUrl: "https://api.agentvisa.ai",
58
+ ...options,
59
+ });
60
+ }
61
+ }
62
+ // Allow usage as a global script if desired (lightweight CDN use)
63
+ if (typeof window !== "undefined") {
64
+ window.AgentVisa = AgentVisa;
65
+ }
66
+
67
+ export { AgentVisa };
package/dist/widget.js ADDED
@@ -0,0 +1,75 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.AgentVisa = {}));
5
+ })(this, (function (exports) { 'use strict';
6
+
7
+ const DEFAULT_API_BASE = "https://api.agentvisa.ai";
8
+ async function verifyToken(options) {
9
+ const { widgetId, plan = "basic", apiBaseUrl = DEFAULT_API_BASE, } = options;
10
+ const url = new URL("/v1/verify", apiBaseUrl);
11
+ url.searchParams.set("widget_id", widgetId);
12
+ url.searchParams.set("plan", plan);
13
+ // Note: token is currently empty — this is the skeleton.
14
+ // In real usage the AI agent will pass the tmp_ token here.
15
+ const response = await fetch(url.toString(), {
16
+ method: "POST",
17
+ headers: {
18
+ "Content-Type": "application/json",
19
+ },
20
+ body: JSON.stringify({
21
+ token: "",
22
+ widget_id: widgetId,
23
+ plan,
24
+ }),
25
+ });
26
+ if (!response.ok) {
27
+ return {
28
+ valid: false,
29
+ reason: "network_error",
30
+ plan,
31
+ widget_id: widgetId,
32
+ human_name: null,
33
+ email: null,
34
+ phone: null,
35
+ verified_at: null,
36
+ expires_at: null,
37
+ };
38
+ }
39
+ return response.json();
40
+ }
41
+
42
+ class AgentVisa {
43
+ constructor(options) {
44
+ this.options = {
45
+ plan: "basic",
46
+ apiBaseUrl: "https://api.agentvisa.ai",
47
+ ...options,
48
+ };
49
+ }
50
+ /**
51
+ * Verify the current token for this widget.
52
+ * Returns the unified VerificationResult.
53
+ */
54
+ async verify() {
55
+ return verifyToken(this.options);
56
+ }
57
+ /**
58
+ * Quick static helper for one-off verification (commonly used pattern).
59
+ */
60
+ static async verify(options) {
61
+ return verifyToken({
62
+ plan: "basic",
63
+ apiBaseUrl: "https://api.agentvisa.ai",
64
+ ...options,
65
+ });
66
+ }
67
+ }
68
+ // Allow usage as a global script if desired (lightweight CDN use)
69
+ if (typeof window !== "undefined") {
70
+ window.AgentVisa = AgentVisa;
71
+ }
72
+
73
+ exports.AgentVisa = AgentVisa;
74
+
75
+ }));
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@agentvisa/widget",
3
+ "version": "0.2.0",
4
+ "description": "AgentVisa widget + server middleware for Express and Next.js",
5
+ "keywords": [
6
+ "agentvisa",
7
+ "verification",
8
+ "ai-agents",
9
+ "widget",
10
+ "middleware",
11
+ "express",
12
+ "nextjs",
13
+ "5-factor"
14
+ ],
15
+ "author": "AgentVisa",
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/agentvisa/widget.git"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/agentvisa/widget/issues"
23
+ },
24
+ "homepage": "https://agentvisa.ai",
25
+ "type": "module",
26
+ "main": "dist/widget.js",
27
+ "module": "dist/widget.esm.js",
28
+ "types": "dist/index.d.ts",
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "exports": {
33
+ ".": {
34
+ "import": "./dist/widget.esm.js",
35
+ "require": "./dist/widget.js",
36
+ "types": "./dist/index.d.ts"
37
+ },
38
+ "./express": {
39
+ "import": "./dist/express/index.js",
40
+ "require": "./dist/express/index.js",
41
+ "types": "./dist/express/index.d.ts"
42
+ },
43
+ "./next": {
44
+ "import": "./dist/next/index.js",
45
+ "require": "./dist/next/index.js",
46
+ "types": "./dist/next/index.d.ts"
47
+ }
48
+ },
49
+ "scripts": {
50
+ "build": "rollup -c && tsc -p tsconfig.middleware.json",
51
+ "clean": "rm -rf dist",
52
+ "dev": "npm run build",
53
+ "prepublishOnly": "npm run clean && npm run build"
54
+ },
55
+ "devDependencies": {
56
+ "@rollup/plugin-typescript": "^11.1.0",
57
+ "@types/express": "^4.17.21",
58
+ "@types/node": "^22.0.0",
59
+ "rollup": "^4.17.0",
60
+ "rollup-plugin-dts": "^6.0.0",
61
+ "tslib": "^2.8.1",
62
+ "typescript": "^5.4.0"
63
+ },
64
+ "peerDependencies": {
65
+ "express": ">=4.0.0"
66
+ },
67
+ "peerDependenciesMeta": {
68
+ "express": {
69
+ "optional": true
70
+ }
71
+ }
72
+ }