vesant-sdk 1.2.0 → 1.3.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.
Files changed (71) hide show
  1. package/dist/{client-BWp5FI3x.d.ts → client-B6fUFAUM.d.mts} +2 -1
  2. package/dist/{client-BIfLMfuC.d.mts → client-DoczGA6L.d.ts} +2 -1
  3. package/dist/client-DzElM7u-.d.mts +238 -0
  4. package/dist/client-DzElM7u-.d.ts +238 -0
  5. package/dist/compliance/index.d.mts +5 -4
  6. package/dist/compliance/index.d.ts +5 -4
  7. package/dist/compliance/index.js +306 -98
  8. package/dist/compliance/index.js.map +1 -1
  9. package/dist/compliance/index.mjs +306 -98
  10. package/dist/compliance/index.mjs.map +1 -1
  11. package/dist/decisions/index.d.mts +100 -0
  12. package/dist/decisions/index.d.ts +100 -0
  13. package/dist/decisions/index.js +607 -0
  14. package/dist/decisions/index.js.map +1 -0
  15. package/dist/decisions/index.mjs +605 -0
  16. package/dist/decisions/index.mjs.map +1 -0
  17. package/dist/geolocation/index.d.mts +4 -3
  18. package/dist/geolocation/index.d.ts +4 -3
  19. package/dist/geolocation/index.js +306 -98
  20. package/dist/geolocation/index.js.map +1 -1
  21. package/dist/geolocation/index.mjs +306 -98
  22. package/dist/geolocation/index.mjs.map +1 -1
  23. package/dist/index.d.mts +14 -6
  24. package/dist/index.d.ts +14 -6
  25. package/dist/index.js +641 -90
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +632 -91
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/kyc/core.d.mts +3 -2
  30. package/dist/kyc/core.d.ts +3 -2
  31. package/dist/kyc/core.js +249 -29
  32. package/dist/kyc/core.js.map +1 -1
  33. package/dist/kyc/core.mjs +249 -29
  34. package/dist/kyc/core.mjs.map +1 -1
  35. package/dist/kyc/index.d.mts +3 -2
  36. package/dist/kyc/index.d.ts +3 -2
  37. package/dist/kyc/index.js +249 -29
  38. package/dist/kyc/index.js.map +1 -1
  39. package/dist/kyc/index.mjs +249 -29
  40. package/dist/kyc/index.mjs.map +1 -1
  41. package/dist/react.d.mts +4 -3
  42. package/dist/react.d.ts +4 -3
  43. package/dist/react.js +1 -1
  44. package/dist/react.js.map +1 -1
  45. package/dist/react.mjs +1 -1
  46. package/dist/react.mjs.map +1 -1
  47. package/dist/risk-profile/index.d.mts +4 -4
  48. package/dist/risk-profile/index.d.ts +4 -4
  49. package/dist/risk-profile/index.js +249 -29
  50. package/dist/risk-profile/index.js.map +1 -1
  51. package/dist/risk-profile/index.mjs +249 -29
  52. package/dist/risk-profile/index.mjs.map +1 -1
  53. package/dist/scores/index.d.mts +96 -0
  54. package/dist/scores/index.d.ts +96 -0
  55. package/dist/scores/index.js +594 -0
  56. package/dist/scores/index.js.map +1 -0
  57. package/dist/scores/index.mjs +591 -0
  58. package/dist/scores/index.mjs.map +1 -0
  59. package/dist/{types-DfHLp_tz.d.ts → types-DLC7Sfy5.d.ts} +1 -1
  60. package/dist/types-DZHongaK.d.mts +61 -0
  61. package/dist/types-DZHongaK.d.ts +61 -0
  62. package/dist/{types-DKCQN4C5.d.mts → types-jaLuzruy.d.mts} +1 -1
  63. package/dist/webhooks/index.d.mts +176 -0
  64. package/dist/webhooks/index.d.ts +176 -0
  65. package/dist/webhooks/index.js +193 -0
  66. package/dist/webhooks/index.js.map +1 -0
  67. package/dist/webhooks/index.mjs +188 -0
  68. package/dist/webhooks/index.mjs.map +1 -0
  69. package/package.json +16 -1
  70. package/dist/types-BpKxSXGF.d.mts +0 -177
  71. package/dist/types-BpKxSXGF.d.ts +0 -177
@@ -0,0 +1,193 @@
1
+ 'use strict';
2
+
3
+ // src/core/webhook-utils.ts
4
+ async function verifyWebhookSignature(payload, signature, secret) {
5
+ const hexDigest = await computeHmacSha256(payload, secret);
6
+ const expectedPrefixed = `sha256=${hexDigest}`;
7
+ if (signature.startsWith("sha256=")) {
8
+ return constantTimeEqual(signature, expectedPrefixed);
9
+ }
10
+ return constantTimeEqual(signature, hexDigest);
11
+ }
12
+ async function computeHmacSha256(message, secret) {
13
+ if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.subtle) {
14
+ const encoder = new TextEncoder();
15
+ const key = await globalThis.crypto.subtle.importKey(
16
+ "raw",
17
+ encoder.encode(secret),
18
+ { name: "HMAC", hash: "SHA-256" },
19
+ false,
20
+ ["sign"]
21
+ );
22
+ const sig = await globalThis.crypto.subtle.sign("HMAC", key, encoder.encode(message));
23
+ return Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("");
24
+ }
25
+ try {
26
+ const { createHmac } = await import('crypto');
27
+ return createHmac("sha256", secret).update(message).digest("hex");
28
+ } catch {
29
+ throw new Error(
30
+ "No crypto implementation available. Requires Web Crypto API or Node.js crypto module."
31
+ );
32
+ }
33
+ }
34
+ function constantTimeEqual(a, b) {
35
+ if (a.length !== b.length) {
36
+ return false;
37
+ }
38
+ let result = 0;
39
+ for (let i = 0; i < a.length; i++) {
40
+ result |= a.charCodeAt(i) ^ b.charCodeAt(i);
41
+ }
42
+ return result === 0;
43
+ }
44
+
45
+ // src/webhooks/handler.ts
46
+ var WebhookHandler = class {
47
+ constructor(config) {
48
+ this.handlers = /* @__PURE__ */ new Map();
49
+ this.anyHandlers = [];
50
+ this.secret = config.secret;
51
+ this.tolerance = config.tolerance ?? 3e5;
52
+ }
53
+ /**
54
+ * Register a handler for a specific event type.
55
+ */
56
+ on(eventType, handler) {
57
+ const existing = this.handlers.get(eventType) || [];
58
+ existing.push(handler);
59
+ this.handlers.set(eventType, existing);
60
+ return this;
61
+ }
62
+ /**
63
+ * Register a catch-all handler for all event types.
64
+ */
65
+ onAny(handler) {
66
+ this.anyHandlers.push(handler);
67
+ return this;
68
+ }
69
+ /**
70
+ * Verify signature and parse the webhook body.
71
+ */
72
+ async verifyAndParse(body, signature) {
73
+ const isValid = await verifyWebhookSignature(body, signature, this.secret);
74
+ if (!isValid) {
75
+ throw new Error("Invalid webhook signature");
76
+ }
77
+ return this.parseAndValidate(body);
78
+ }
79
+ /**
80
+ * Verify signature, parse, and dispatch to registered handlers.
81
+ */
82
+ async handle(body, signature) {
83
+ const event = await this.verifyAndParse(body, signature);
84
+ await this.dispatch(event);
85
+ }
86
+ /**
87
+ * Parse an event without signature verification (for testing).
88
+ */
89
+ parseEvent(body) {
90
+ return this.parseAndValidate(body);
91
+ }
92
+ parseAndValidate(body) {
93
+ const event = JSON.parse(body);
94
+ if (!event.type || !event.id || !event.timestamp) {
95
+ throw new Error("Invalid webhook event: missing required fields (type, id, timestamp)");
96
+ }
97
+ if (this.tolerance > 0) {
98
+ const eventTime = new Date(event.timestamp).getTime();
99
+ const now = Date.now();
100
+ if (Math.abs(now - eventTime) > this.tolerance) {
101
+ throw new Error(
102
+ `Webhook event timestamp is outside tolerance window (${this.tolerance}ms)`
103
+ );
104
+ }
105
+ }
106
+ return event;
107
+ }
108
+ async dispatch(event) {
109
+ const typeHandlers = this.handlers.get(event.type) || [];
110
+ const allHandlers = [...typeHandlers, ...this.anyHandlers];
111
+ for (const handler of allHandlers) {
112
+ await handler(event);
113
+ }
114
+ }
115
+ };
116
+
117
+ // src/webhooks/middleware.ts
118
+ function createWebhookMiddleware(options) {
119
+ const handler = buildHandler(options);
120
+ const signatureHeader = options.signatureHeader || "x-webhook-signature";
121
+ return async (req, res, next) => {
122
+ try {
123
+ const body = typeof req.body === "string" ? req.body : req.body.toString("utf-8");
124
+ const signature = req.headers[signatureHeader];
125
+ if (!signature || typeof signature !== "string") {
126
+ res.status(401).json({ error: "Missing webhook signature" });
127
+ return;
128
+ }
129
+ await handler.handle(body, signature);
130
+ res.status(200).json({ received: true });
131
+ } catch (error) {
132
+ const message = error instanceof Error ? error.message : "Webhook processing failed";
133
+ if (message.includes("signature")) {
134
+ res.status(401).json({ error: message });
135
+ } else if (message.includes("tolerance") || message.includes("timestamp")) {
136
+ res.status(400).json({ error: message });
137
+ } else if (next) {
138
+ next(error);
139
+ } else {
140
+ res.status(500).json({ error: message });
141
+ }
142
+ }
143
+ };
144
+ }
145
+ function createNextWebhookHandler(options) {
146
+ const handler = buildHandler(options);
147
+ const signatureHeader = options.signatureHeader || "x-webhook-signature";
148
+ return async (request) => {
149
+ try {
150
+ const body = await request.text();
151
+ const signature = request.headers.get(signatureHeader);
152
+ if (!signature) {
153
+ return new Response(JSON.stringify({ error: "Missing webhook signature" }), {
154
+ status: 401,
155
+ headers: { "Content-Type": "application/json" }
156
+ });
157
+ }
158
+ await handler.handle(body, signature);
159
+ return new Response(JSON.stringify({ received: true }), {
160
+ status: 200,
161
+ headers: { "Content-Type": "application/json" }
162
+ });
163
+ } catch (error) {
164
+ const message = error instanceof Error ? error.message : "Webhook processing failed";
165
+ const status = message.includes("signature") ? 401 : message.includes("tolerance") || message.includes("timestamp") ? 400 : 500;
166
+ return new Response(JSON.stringify({ error: message }), {
167
+ status,
168
+ headers: { "Content-Type": "application/json" }
169
+ });
170
+ }
171
+ };
172
+ }
173
+ function buildHandler(options) {
174
+ const handler = new WebhookHandler(options);
175
+ if (options.handlers) {
176
+ for (const [eventType, eventHandler] of Object.entries(options.handlers)) {
177
+ if (eventHandler) {
178
+ handler.on(eventType, eventHandler);
179
+ }
180
+ }
181
+ }
182
+ if (options.onAny) {
183
+ handler.onAny(options.onAny);
184
+ }
185
+ return handler;
186
+ }
187
+
188
+ exports.WebhookHandler = WebhookHandler;
189
+ exports.createNextWebhookHandler = createNextWebhookHandler;
190
+ exports.createWebhookMiddleware = createWebhookMiddleware;
191
+ exports.verifyWebhookSignature = verifyWebhookSignature;
192
+ //# sourceMappingURL=index.js.map
193
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/webhook-utils.ts","../../src/webhooks/handler.ts","../../src/webhooks/middleware.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Webhook signature verification utilities.\n *\n * Supports both Web Crypto API (browsers, Deno, Cloudflare Workers)\n * and Node.js crypto module with automatic runtime detection.\n * Uses constant-time comparison to prevent timing attacks.\n */\n\n/**\n * Verify an HMAC-SHA256 webhook signature.\n *\n * @param payload - The raw request body string\n * @param signature - The signature from the webhook header\n * @param secret - The webhook signing secret\n * @returns true if the signature is valid\n */\nexport async function verifyWebhookSignature(\n payload: string,\n signature: string,\n secret: string\n): Promise<boolean> {\n const hexDigest = await computeHmacSha256(payload, secret);\n\n // Backend sends \"sha256=<hex>\" format — support both prefixed and raw signatures\n const expectedPrefixed = `sha256=${hexDigest}`;\n\n if (signature.startsWith('sha256=')) {\n return constantTimeEqual(signature, expectedPrefixed);\n }\n\n return constantTimeEqual(signature, hexDigest);\n}\n\n/**\n * Compute HMAC-SHA256 hex digest.\n * Automatically selects Web Crypto API or Node.js crypto.\n */\nasync function computeHmacSha256(message: string, secret: string): Promise<string> {\n // Try Web Crypto API first (browsers, Deno, Cloudflare Workers, Node 18+)\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle) {\n const encoder = new TextEncoder();\n const key = await globalThis.crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n );\n const sig = await globalThis.crypto.subtle.sign('HMAC', key, encoder.encode(message));\n return Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n }\n\n // Fallback to Node.js crypto module\n try {\n const { createHmac } = await import('crypto');\n return createHmac('sha256', secret).update(message).digest('hex');\n } catch {\n throw new Error(\n 'No crypto implementation available. Requires Web Crypto API or Node.js crypto module.'\n );\n }\n}\n\n/**\n * Constant-time string comparison to prevent timing attacks.\n */\nfunction constantTimeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n}\n","/**\n * Webhook event handler with signature verification and typed dispatch.\n */\n\nimport { verifyWebhookSignature } from '../core/webhook-utils';\nimport type {\n WebhookEvent,\n WebhookEventType,\n WebhookEventHandler,\n WebhookAnyHandler,\n WebhookHandlerConfig,\n} from './types';\n\nexport class WebhookHandler {\n private handlers = new Map<WebhookEventType, WebhookEventHandler[]>();\n private anyHandlers: WebhookAnyHandler[] = [];\n private readonly secret: string;\n private readonly tolerance: number;\n\n constructor(config: WebhookHandlerConfig) {\n this.secret = config.secret;\n this.tolerance = config.tolerance ?? 300000; // 5 minutes\n }\n\n /**\n * Register a handler for a specific event type.\n */\n on<T extends WebhookEventType>(\n eventType: T,\n handler: WebhookEventHandler<T>\n ): this {\n const existing = this.handlers.get(eventType) || [];\n existing.push(handler as unknown as WebhookEventHandler);\n this.handlers.set(eventType, existing);\n return this;\n }\n\n /**\n * Register a catch-all handler for all event types.\n */\n onAny(handler: WebhookAnyHandler): this {\n this.anyHandlers.push(handler);\n return this;\n }\n\n /**\n * Verify signature and parse the webhook body.\n */\n async verifyAndParse(body: string, signature: string): Promise<WebhookEvent> {\n const isValid = await verifyWebhookSignature(body, signature, this.secret);\n if (!isValid) {\n throw new Error('Invalid webhook signature');\n }\n\n return this.parseAndValidate(body);\n }\n\n /**\n * Verify signature, parse, and dispatch to registered handlers.\n */\n async handle(body: string, signature: string): Promise<void> {\n const event = await this.verifyAndParse(body, signature);\n await this.dispatch(event);\n }\n\n /**\n * Parse an event without signature verification (for testing).\n */\n parseEvent(body: string): WebhookEvent {\n return this.parseAndValidate(body);\n }\n\n private parseAndValidate(body: string): WebhookEvent {\n const event = JSON.parse(body) as WebhookEvent;\n\n if (!event.type || !event.id || !event.timestamp) {\n throw new Error('Invalid webhook event: missing required fields (type, id, timestamp)');\n }\n\n // Timestamp tolerance check\n if (this.tolerance > 0) {\n const eventTime = new Date(event.timestamp).getTime();\n const now = Date.now();\n if (Math.abs(now - eventTime) > this.tolerance) {\n throw new Error(\n `Webhook event timestamp is outside tolerance window (${this.tolerance}ms)`\n );\n }\n }\n\n return event;\n }\n\n private async dispatch(event: WebhookEvent): Promise<void> {\n const typeHandlers = this.handlers.get(event.type) || [];\n const allHandlers = [...typeHandlers, ...this.anyHandlers];\n\n for (const handler of allHandlers) {\n await (handler as WebhookAnyHandler)(event);\n }\n }\n}\n","/**\n * Framework middleware helpers for webhook handling.\n *\n * Provides pre-built integrations for Express/Connect and Next.js App Router.\n */\n\nimport { WebhookHandler } from './handler';\nimport type { WebhookHandlerConfig, WebhookEventType, WebhookEventHandler, WebhookAnyHandler } from './types';\n\nexport interface WebhookMiddlewareOptions extends WebhookHandlerConfig {\n /** Event handlers to register */\n handlers?: Partial<Record<WebhookEventType, WebhookEventHandler>>;\n /** Catch-all handler */\n onAny?: WebhookAnyHandler;\n}\n\n/**\n * Create an Express/Connect-compatible middleware for webhook handling.\n *\n * Expects the raw body to be available as `req.body` (string).\n * Use `express.raw({ type: 'application/json' })` or similar middleware upstream.\n */\nexport function createWebhookMiddleware(options: WebhookMiddlewareOptions) {\n const handler = buildHandler(options);\n const signatureHeader = options.signatureHeader || 'x-webhook-signature';\n\n return async (\n req: { body: string | Buffer; headers: Record<string, string | string[] | undefined> },\n res: { status(code: number): { json(body: unknown): void }; json?(body: unknown): void },\n next?: (err?: unknown) => void\n ) => {\n try {\n const body = typeof req.body === 'string' ? req.body : req.body.toString('utf-8');\n const signature = req.headers[signatureHeader];\n\n if (!signature || typeof signature !== 'string') {\n res.status(401).json({ error: 'Missing webhook signature' });\n return;\n }\n\n await handler.handle(body, signature);\n res.status(200).json({ received: true });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Webhook processing failed';\n\n if (message.includes('signature')) {\n res.status(401).json({ error: message });\n } else if (message.includes('tolerance') || message.includes('timestamp')) {\n res.status(400).json({ error: message });\n } else if (next) {\n next(error);\n } else {\n res.status(500).json({ error: message });\n }\n }\n };\n}\n\n/**\n * Create a Next.js App Router-compatible webhook handler.\n *\n * Returns an async function `(request: Request) => Promise<Response>`.\n */\nexport function createNextWebhookHandler(\n options: WebhookMiddlewareOptions\n): (request: Request) => Promise<Response> {\n const handler = buildHandler(options);\n const signatureHeader = options.signatureHeader || 'x-webhook-signature';\n\n return async (request: Request): Promise<Response> => {\n try {\n const body = await request.text();\n const signature = request.headers.get(signatureHeader);\n\n if (!signature) {\n return new Response(JSON.stringify({ error: 'Missing webhook signature' }), {\n status: 401,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n await handler.handle(body, signature);\n\n return new Response(JSON.stringify({ received: true }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Webhook processing failed';\n const status = message.includes('signature')\n ? 401\n : message.includes('tolerance') || message.includes('timestamp')\n ? 400\n : 500;\n\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n };\n}\n\nfunction buildHandler(options: WebhookMiddlewareOptions): WebhookHandler {\n const handler = new WebhookHandler(options);\n\n if (options.handlers) {\n for (const [eventType, eventHandler] of Object.entries(options.handlers)) {\n if (eventHandler) {\n handler.on(eventType as WebhookEventType, eventHandler);\n }\n }\n }\n\n if (options.onAny) {\n handler.onAny(options.onAny);\n }\n\n return handler;\n}\n"]}
@@ -0,0 +1,188 @@
1
+ // src/core/webhook-utils.ts
2
+ async function verifyWebhookSignature(payload, signature, secret) {
3
+ const hexDigest = await computeHmacSha256(payload, secret);
4
+ const expectedPrefixed = `sha256=${hexDigest}`;
5
+ if (signature.startsWith("sha256=")) {
6
+ return constantTimeEqual(signature, expectedPrefixed);
7
+ }
8
+ return constantTimeEqual(signature, hexDigest);
9
+ }
10
+ async function computeHmacSha256(message, secret) {
11
+ if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.subtle) {
12
+ const encoder = new TextEncoder();
13
+ const key = await globalThis.crypto.subtle.importKey(
14
+ "raw",
15
+ encoder.encode(secret),
16
+ { name: "HMAC", hash: "SHA-256" },
17
+ false,
18
+ ["sign"]
19
+ );
20
+ const sig = await globalThis.crypto.subtle.sign("HMAC", key, encoder.encode(message));
21
+ return Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("");
22
+ }
23
+ try {
24
+ const { createHmac } = await import('crypto');
25
+ return createHmac("sha256", secret).update(message).digest("hex");
26
+ } catch {
27
+ throw new Error(
28
+ "No crypto implementation available. Requires Web Crypto API or Node.js crypto module."
29
+ );
30
+ }
31
+ }
32
+ function constantTimeEqual(a, b) {
33
+ if (a.length !== b.length) {
34
+ return false;
35
+ }
36
+ let result = 0;
37
+ for (let i = 0; i < a.length; i++) {
38
+ result |= a.charCodeAt(i) ^ b.charCodeAt(i);
39
+ }
40
+ return result === 0;
41
+ }
42
+
43
+ // src/webhooks/handler.ts
44
+ var WebhookHandler = class {
45
+ constructor(config) {
46
+ this.handlers = /* @__PURE__ */ new Map();
47
+ this.anyHandlers = [];
48
+ this.secret = config.secret;
49
+ this.tolerance = config.tolerance ?? 3e5;
50
+ }
51
+ /**
52
+ * Register a handler for a specific event type.
53
+ */
54
+ on(eventType, handler) {
55
+ const existing = this.handlers.get(eventType) || [];
56
+ existing.push(handler);
57
+ this.handlers.set(eventType, existing);
58
+ return this;
59
+ }
60
+ /**
61
+ * Register a catch-all handler for all event types.
62
+ */
63
+ onAny(handler) {
64
+ this.anyHandlers.push(handler);
65
+ return this;
66
+ }
67
+ /**
68
+ * Verify signature and parse the webhook body.
69
+ */
70
+ async verifyAndParse(body, signature) {
71
+ const isValid = await verifyWebhookSignature(body, signature, this.secret);
72
+ if (!isValid) {
73
+ throw new Error("Invalid webhook signature");
74
+ }
75
+ return this.parseAndValidate(body);
76
+ }
77
+ /**
78
+ * Verify signature, parse, and dispatch to registered handlers.
79
+ */
80
+ async handle(body, signature) {
81
+ const event = await this.verifyAndParse(body, signature);
82
+ await this.dispatch(event);
83
+ }
84
+ /**
85
+ * Parse an event without signature verification (for testing).
86
+ */
87
+ parseEvent(body) {
88
+ return this.parseAndValidate(body);
89
+ }
90
+ parseAndValidate(body) {
91
+ const event = JSON.parse(body);
92
+ if (!event.type || !event.id || !event.timestamp) {
93
+ throw new Error("Invalid webhook event: missing required fields (type, id, timestamp)");
94
+ }
95
+ if (this.tolerance > 0) {
96
+ const eventTime = new Date(event.timestamp).getTime();
97
+ const now = Date.now();
98
+ if (Math.abs(now - eventTime) > this.tolerance) {
99
+ throw new Error(
100
+ `Webhook event timestamp is outside tolerance window (${this.tolerance}ms)`
101
+ );
102
+ }
103
+ }
104
+ return event;
105
+ }
106
+ async dispatch(event) {
107
+ const typeHandlers = this.handlers.get(event.type) || [];
108
+ const allHandlers = [...typeHandlers, ...this.anyHandlers];
109
+ for (const handler of allHandlers) {
110
+ await handler(event);
111
+ }
112
+ }
113
+ };
114
+
115
+ // src/webhooks/middleware.ts
116
+ function createWebhookMiddleware(options) {
117
+ const handler = buildHandler(options);
118
+ const signatureHeader = options.signatureHeader || "x-webhook-signature";
119
+ return async (req, res, next) => {
120
+ try {
121
+ const body = typeof req.body === "string" ? req.body : req.body.toString("utf-8");
122
+ const signature = req.headers[signatureHeader];
123
+ if (!signature || typeof signature !== "string") {
124
+ res.status(401).json({ error: "Missing webhook signature" });
125
+ return;
126
+ }
127
+ await handler.handle(body, signature);
128
+ res.status(200).json({ received: true });
129
+ } catch (error) {
130
+ const message = error instanceof Error ? error.message : "Webhook processing failed";
131
+ if (message.includes("signature")) {
132
+ res.status(401).json({ error: message });
133
+ } else if (message.includes("tolerance") || message.includes("timestamp")) {
134
+ res.status(400).json({ error: message });
135
+ } else if (next) {
136
+ next(error);
137
+ } else {
138
+ res.status(500).json({ error: message });
139
+ }
140
+ }
141
+ };
142
+ }
143
+ function createNextWebhookHandler(options) {
144
+ const handler = buildHandler(options);
145
+ const signatureHeader = options.signatureHeader || "x-webhook-signature";
146
+ return async (request) => {
147
+ try {
148
+ const body = await request.text();
149
+ const signature = request.headers.get(signatureHeader);
150
+ if (!signature) {
151
+ return new Response(JSON.stringify({ error: "Missing webhook signature" }), {
152
+ status: 401,
153
+ headers: { "Content-Type": "application/json" }
154
+ });
155
+ }
156
+ await handler.handle(body, signature);
157
+ return new Response(JSON.stringify({ received: true }), {
158
+ status: 200,
159
+ headers: { "Content-Type": "application/json" }
160
+ });
161
+ } catch (error) {
162
+ const message = error instanceof Error ? error.message : "Webhook processing failed";
163
+ const status = message.includes("signature") ? 401 : message.includes("tolerance") || message.includes("timestamp") ? 400 : 500;
164
+ return new Response(JSON.stringify({ error: message }), {
165
+ status,
166
+ headers: { "Content-Type": "application/json" }
167
+ });
168
+ }
169
+ };
170
+ }
171
+ function buildHandler(options) {
172
+ const handler = new WebhookHandler(options);
173
+ if (options.handlers) {
174
+ for (const [eventType, eventHandler] of Object.entries(options.handlers)) {
175
+ if (eventHandler) {
176
+ handler.on(eventType, eventHandler);
177
+ }
178
+ }
179
+ }
180
+ if (options.onAny) {
181
+ handler.onAny(options.onAny);
182
+ }
183
+ return handler;
184
+ }
185
+
186
+ export { WebhookHandler, createNextWebhookHandler, createWebhookMiddleware, verifyWebhookSignature };
187
+ //# sourceMappingURL=index.mjs.map
188
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/webhook-utils.ts","../../src/webhooks/handler.ts","../../src/webhooks/middleware.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Webhook signature verification utilities.\n *\n * Supports both Web Crypto API (browsers, Deno, Cloudflare Workers)\n * and Node.js crypto module with automatic runtime detection.\n * Uses constant-time comparison to prevent timing attacks.\n */\n\n/**\n * Verify an HMAC-SHA256 webhook signature.\n *\n * @param payload - The raw request body string\n * @param signature - The signature from the webhook header\n * @param secret - The webhook signing secret\n * @returns true if the signature is valid\n */\nexport async function verifyWebhookSignature(\n payload: string,\n signature: string,\n secret: string\n): Promise<boolean> {\n const hexDigest = await computeHmacSha256(payload, secret);\n\n // Backend sends \"sha256=<hex>\" format — support both prefixed and raw signatures\n const expectedPrefixed = `sha256=${hexDigest}`;\n\n if (signature.startsWith('sha256=')) {\n return constantTimeEqual(signature, expectedPrefixed);\n }\n\n return constantTimeEqual(signature, hexDigest);\n}\n\n/**\n * Compute HMAC-SHA256 hex digest.\n * Automatically selects Web Crypto API or Node.js crypto.\n */\nasync function computeHmacSha256(message: string, secret: string): Promise<string> {\n // Try Web Crypto API first (browsers, Deno, Cloudflare Workers, Node 18+)\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle) {\n const encoder = new TextEncoder();\n const key = await globalThis.crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n );\n const sig = await globalThis.crypto.subtle.sign('HMAC', key, encoder.encode(message));\n return Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n }\n\n // Fallback to Node.js crypto module\n try {\n const { createHmac } = await import('crypto');\n return createHmac('sha256', secret).update(message).digest('hex');\n } catch {\n throw new Error(\n 'No crypto implementation available. Requires Web Crypto API or Node.js crypto module.'\n );\n }\n}\n\n/**\n * Constant-time string comparison to prevent timing attacks.\n */\nfunction constantTimeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n}\n","/**\n * Webhook event handler with signature verification and typed dispatch.\n */\n\nimport { verifyWebhookSignature } from '../core/webhook-utils';\nimport type {\n WebhookEvent,\n WebhookEventType,\n WebhookEventHandler,\n WebhookAnyHandler,\n WebhookHandlerConfig,\n} from './types';\n\nexport class WebhookHandler {\n private handlers = new Map<WebhookEventType, WebhookEventHandler[]>();\n private anyHandlers: WebhookAnyHandler[] = [];\n private readonly secret: string;\n private readonly tolerance: number;\n\n constructor(config: WebhookHandlerConfig) {\n this.secret = config.secret;\n this.tolerance = config.tolerance ?? 300000; // 5 minutes\n }\n\n /**\n * Register a handler for a specific event type.\n */\n on<T extends WebhookEventType>(\n eventType: T,\n handler: WebhookEventHandler<T>\n ): this {\n const existing = this.handlers.get(eventType) || [];\n existing.push(handler as unknown as WebhookEventHandler);\n this.handlers.set(eventType, existing);\n return this;\n }\n\n /**\n * Register a catch-all handler for all event types.\n */\n onAny(handler: WebhookAnyHandler): this {\n this.anyHandlers.push(handler);\n return this;\n }\n\n /**\n * Verify signature and parse the webhook body.\n */\n async verifyAndParse(body: string, signature: string): Promise<WebhookEvent> {\n const isValid = await verifyWebhookSignature(body, signature, this.secret);\n if (!isValid) {\n throw new Error('Invalid webhook signature');\n }\n\n return this.parseAndValidate(body);\n }\n\n /**\n * Verify signature, parse, and dispatch to registered handlers.\n */\n async handle(body: string, signature: string): Promise<void> {\n const event = await this.verifyAndParse(body, signature);\n await this.dispatch(event);\n }\n\n /**\n * Parse an event without signature verification (for testing).\n */\n parseEvent(body: string): WebhookEvent {\n return this.parseAndValidate(body);\n }\n\n private parseAndValidate(body: string): WebhookEvent {\n const event = JSON.parse(body) as WebhookEvent;\n\n if (!event.type || !event.id || !event.timestamp) {\n throw new Error('Invalid webhook event: missing required fields (type, id, timestamp)');\n }\n\n // Timestamp tolerance check\n if (this.tolerance > 0) {\n const eventTime = new Date(event.timestamp).getTime();\n const now = Date.now();\n if (Math.abs(now - eventTime) > this.tolerance) {\n throw new Error(\n `Webhook event timestamp is outside tolerance window (${this.tolerance}ms)`\n );\n }\n }\n\n return event;\n }\n\n private async dispatch(event: WebhookEvent): Promise<void> {\n const typeHandlers = this.handlers.get(event.type) || [];\n const allHandlers = [...typeHandlers, ...this.anyHandlers];\n\n for (const handler of allHandlers) {\n await (handler as WebhookAnyHandler)(event);\n }\n }\n}\n","/**\n * Framework middleware helpers for webhook handling.\n *\n * Provides pre-built integrations for Express/Connect and Next.js App Router.\n */\n\nimport { WebhookHandler } from './handler';\nimport type { WebhookHandlerConfig, WebhookEventType, WebhookEventHandler, WebhookAnyHandler } from './types';\n\nexport interface WebhookMiddlewareOptions extends WebhookHandlerConfig {\n /** Event handlers to register */\n handlers?: Partial<Record<WebhookEventType, WebhookEventHandler>>;\n /** Catch-all handler */\n onAny?: WebhookAnyHandler;\n}\n\n/**\n * Create an Express/Connect-compatible middleware for webhook handling.\n *\n * Expects the raw body to be available as `req.body` (string).\n * Use `express.raw({ type: 'application/json' })` or similar middleware upstream.\n */\nexport function createWebhookMiddleware(options: WebhookMiddlewareOptions) {\n const handler = buildHandler(options);\n const signatureHeader = options.signatureHeader || 'x-webhook-signature';\n\n return async (\n req: { body: string | Buffer; headers: Record<string, string | string[] | undefined> },\n res: { status(code: number): { json(body: unknown): void }; json?(body: unknown): void },\n next?: (err?: unknown) => void\n ) => {\n try {\n const body = typeof req.body === 'string' ? req.body : req.body.toString('utf-8');\n const signature = req.headers[signatureHeader];\n\n if (!signature || typeof signature !== 'string') {\n res.status(401).json({ error: 'Missing webhook signature' });\n return;\n }\n\n await handler.handle(body, signature);\n res.status(200).json({ received: true });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Webhook processing failed';\n\n if (message.includes('signature')) {\n res.status(401).json({ error: message });\n } else if (message.includes('tolerance') || message.includes('timestamp')) {\n res.status(400).json({ error: message });\n } else if (next) {\n next(error);\n } else {\n res.status(500).json({ error: message });\n }\n }\n };\n}\n\n/**\n * Create a Next.js App Router-compatible webhook handler.\n *\n * Returns an async function `(request: Request) => Promise<Response>`.\n */\nexport function createNextWebhookHandler(\n options: WebhookMiddlewareOptions\n): (request: Request) => Promise<Response> {\n const handler = buildHandler(options);\n const signatureHeader = options.signatureHeader || 'x-webhook-signature';\n\n return async (request: Request): Promise<Response> => {\n try {\n const body = await request.text();\n const signature = request.headers.get(signatureHeader);\n\n if (!signature) {\n return new Response(JSON.stringify({ error: 'Missing webhook signature' }), {\n status: 401,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n await handler.handle(body, signature);\n\n return new Response(JSON.stringify({ received: true }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Webhook processing failed';\n const status = message.includes('signature')\n ? 401\n : message.includes('tolerance') || message.includes('timestamp')\n ? 400\n : 500;\n\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n };\n}\n\nfunction buildHandler(options: WebhookMiddlewareOptions): WebhookHandler {\n const handler = new WebhookHandler(options);\n\n if (options.handlers) {\n for (const [eventType, eventHandler] of Object.entries(options.handlers)) {\n if (eventHandler) {\n handler.on(eventType as WebhookEventType, eventHandler);\n }\n }\n }\n\n if (options.onAny) {\n handler.onAny(options.onAny);\n }\n\n return handler;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vesant-sdk",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "TypeScript SDK for Vesant Compliance Platform - Geolocation, KYC, Risk Profiling, CipherText, and Compliance Orchestration",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -40,6 +40,21 @@
40
40
  "types": "./dist/kyc/core.d.ts",
41
41
  "import": "./dist/kyc/core.mjs",
42
42
  "require": "./dist/kyc/core.js"
43
+ },
44
+ "./decisions": {
45
+ "types": "./dist/decisions/index.d.ts",
46
+ "import": "./dist/decisions/index.mjs",
47
+ "require": "./dist/decisions/index.js"
48
+ },
49
+ "./webhooks": {
50
+ "types": "./dist/webhooks/index.d.ts",
51
+ "import": "./dist/webhooks/index.mjs",
52
+ "require": "./dist/webhooks/index.js"
53
+ },
54
+ "./scores": {
55
+ "types": "./dist/scores/index.d.ts",
56
+ "import": "./dist/scores/index.mjs",
57
+ "require": "./dist/scores/index.js"
43
58
  }
44
59
  },
45
60
  "files": [
@@ -1,177 +0,0 @@
1
- /**
2
- * Configuration types for Vesant SDK clients
3
- */
4
- interface Logger {
5
- debug(message: string, meta?: Record<string, unknown>): void;
6
- info(message: string, meta?: Record<string, unknown>): void;
7
- warn(message: string, meta?: Record<string, unknown>): void;
8
- error(message: string, meta?: Record<string, unknown>): void;
9
- }
10
- interface RequestOptions {
11
- signal?: AbortSignal;
12
- }
13
- interface RequestInterceptor {
14
- /** Called before each request. Can modify headers or options. */
15
- onRequest?: (url: string, options: RequestInit) => RequestInit | Promise<RequestInit>;
16
- /** Called after a successful response. Can inspect or transform data. */
17
- onResponse?: (url: string, data: unknown) => unknown | Promise<unknown>;
18
- /** Called when a request fails. Can handle or re-throw. */
19
- onError?: (url: string, error: Error) => void | Promise<void>;
20
- }
21
- interface BaseClientConfig {
22
- /** Base URL for the service */
23
- baseURL: string;
24
- /** Tenant ID for multi-tenancy */
25
- tenantId: string;
26
- /** Optional API key for authentication */
27
- apiKey?: string;
28
- /** Custom headers to include in all requests */
29
- headers?: Record<string, string>;
30
- /** Request timeout in milliseconds (default: 10000) */
31
- timeout?: number;
32
- /** Number of retry attempts (default: 3) */
33
- retries?: number;
34
- /** Enable debug logging (default: false) */
35
- debug?: boolean;
36
- /** Request/response interceptors */
37
- interceptors?: RequestInterceptor[];
38
- /** Custom logger instance */
39
- logger?: Logger;
40
- }
41
- interface CGSConfig {
42
- /** Base URL for the Vesant API */
43
- baseURL: string;
44
- /** Tenant ID for multi-tenancy */
45
- tenantId: string;
46
- /** Optional API key for authentication */
47
- apiKey?: string;
48
- /** Custom headers to include in all requests */
49
- headers?: Record<string, string>;
50
- /** Request timeout in milliseconds (default: 10000) */
51
- timeout?: number;
52
- /** Number of retry attempts for failed requests (default: 3) */
53
- retries?: number;
54
- /** Enable debug logging (default: false) */
55
- debug?: boolean;
56
- /** Automatically create customer profiles on geolocation verification (default: true) */
57
- autoCreateProfiles?: boolean;
58
- /** Sync mode: 'async' uses events, 'sync' uses direct API calls (default: 'sync') */
59
- syncMode?: 'async' | 'sync';
60
- /** Request/response interceptors */
61
- interceptors?: RequestInterceptor[];
62
- /** Custom logger instance */
63
- logger?: Logger;
64
- }
65
- type RequiredCGSConfig = Required<CGSConfig>;
66
- type RequiredBaseClientConfig = Required<BaseClientConfig>;
67
-
68
- /**
69
- * Base HTTP client for all CGS SDK clients
70
- *
71
- * Provides common functionality:
72
- * - Request/response handling
73
- * - Error handling
74
- * - Retry logic with exponential backoff
75
- * - Timeout management
76
- * - Debug logging
77
- */
78
-
79
- declare abstract class BaseClient {
80
- protected config: RequiredBaseClientConfig;
81
- protected logger: Logger;
82
- private interceptors;
83
- constructor(config: BaseClientConfig);
84
- /**
85
- * Make an HTTP request with timeout and error handling
86
- */
87
- protected request<T>(endpoint: string, options?: RequestInit, serviceURL?: string, requestOptions?: RequestOptions): Promise<T>;
88
- /**
89
- * Make an HTTP request with retry logic
90
- */
91
- protected requestWithRetry<T>(endpoint: string, options?: RequestInit, serviceURL?: string, retries?: number, requestOptions?: RequestOptions): Promise<T>;
92
- /**
93
- * Handle error responses from API
94
- */
95
- protected handleErrorResponse(status: number, data: Record<string, unknown>): never;
96
- /**
97
- * Build query string from parameters
98
- */
99
- protected buildQueryString(params: Record<string, unknown>): string;
100
- /**
101
- * Update client configuration
102
- */
103
- updateConfig(config: Partial<BaseClientConfig>): void;
104
- /**
105
- * Get current configuration (readonly)
106
- */
107
- getConfig(): Readonly<BaseClientConfig>;
108
- /**
109
- * Health check endpoint
110
- */
111
- healthCheck(): Promise<{
112
- status: string;
113
- timestamp: string;
114
- }>;
115
- }
116
-
117
- /**
118
- * Shared types used across all CGS SDK modules
119
- */
120
- interface APIResponse<T> {
121
- data?: T;
122
- error?: string;
123
- message?: string;
124
- }
125
- interface PaginationParams {
126
- page?: number;
127
- page_size?: number;
128
- }
129
- interface PaginatedResponse<T> {
130
- data: T[];
131
- total: number;
132
- page: number;
133
- page_size: number;
134
- total_pages: number;
135
- }
136
- interface SuccessResponse<T = unknown> {
137
- success: true;
138
- data: T;
139
- message?: string;
140
- }
141
- interface ErrorResponse {
142
- success: false;
143
- error: string;
144
- code?: string;
145
- details?: Record<string, unknown>;
146
- }
147
- type Result<T> = SuccessResponse<T> | ErrorResponse;
148
- /**
149
- * Standard timestamp format: ISO 8601
150
- */
151
- type Timestamp = string;
152
- /**
153
- * UUID format
154
- */
155
- type UUID = string;
156
- /**
157
- * Risk levels used across the platform
158
- */
159
- type RiskLevel = 'low' | 'medium' | 'high' | 'critical';
160
- /**
161
- * Customer status types
162
- */
163
- type CustomerStatus = 'active' | 'dormant' | 'deactive' | 'suspended';
164
- /**
165
- * Entity types for customer profiles
166
- */
167
- type EntityType = 'individual' | 'corporate' | 'joint_account' | 'minor_with_guardian';
168
- /**
169
- * Location compliance status
170
- */
171
- type LocationCompliance = 'compliant' | 'non-compliant' | 'unknown';
172
- /**
173
- * Verification event types
174
- */
175
- type VerificationEventType = 'registration' | 'login' | 'transaction' | 'withdrawal' | 'deposit' | 'api_access' | 'profile_update';
176
-
177
- export { type APIResponse as A, BaseClient as B, type CustomerStatus as C, type EntityType as E, type LocationCompliance as L, type PaginationParams as P, type RequestOptions as R, type SuccessResponse as S, type Timestamp as T, type UUID as U, type VerificationEventType as V, type PaginatedResponse as a, type Logger as b, type RequestInterceptor as c, type BaseClientConfig as d, type CGSConfig as e, type RequiredCGSConfig as f, type RequiredBaseClientConfig as g, type ErrorResponse as h, type Result as i, type RiskLevel as j };