@linkforty/core 1.0.0 → 1.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.
Files changed (56) hide show
  1. package/dist/index.d.ts +4 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +13 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/database.d.ts.map +1 -1
  6. package/dist/lib/database.js +154 -0
  7. package/dist/lib/database.js.map +1 -1
  8. package/dist/lib/event-emitter.d.ts +46 -0
  9. package/dist/lib/event-emitter.d.ts.map +1 -0
  10. package/dist/lib/event-emitter.js +29 -0
  11. package/dist/lib/event-emitter.js.map +1 -0
  12. package/dist/lib/fingerprint.d.ts +64 -0
  13. package/dist/lib/fingerprint.d.ts.map +1 -0
  14. package/dist/lib/fingerprint.js +387 -0
  15. package/dist/lib/fingerprint.js.map +1 -0
  16. package/dist/lib/utils.d.ts +1 -0
  17. package/dist/lib/utils.d.ts.map +1 -1
  18. package/dist/lib/utils.js +1 -0
  19. package/dist/lib/utils.js.map +1 -1
  20. package/dist/lib/webhook.d.ts +18 -0
  21. package/dist/lib/webhook.d.ts.map +1 -0
  22. package/dist/lib/webhook.js +150 -0
  23. package/dist/lib/webhook.js.map +1 -0
  24. package/dist/routes/debug.d.ts +7 -0
  25. package/dist/routes/debug.d.ts.map +1 -0
  26. package/dist/routes/debug.js +321 -0
  27. package/dist/routes/debug.js.map +1 -0
  28. package/dist/routes/index.d.ts +5 -0
  29. package/dist/routes/index.d.ts.map +1 -1
  30. package/dist/routes/index.js +11 -1
  31. package/dist/routes/index.js.map +1 -1
  32. package/dist/routes/links.d.ts.map +1 -1
  33. package/dist/routes/links.js +21 -3
  34. package/dist/routes/links.js.map +1 -1
  35. package/dist/routes/preview.d.ts +3 -0
  36. package/dist/routes/preview.d.ts.map +1 -0
  37. package/dist/routes/preview.js +225 -0
  38. package/dist/routes/preview.js.map +1 -0
  39. package/dist/routes/qr.d.ts +6 -0
  40. package/dist/routes/qr.d.ts.map +1 -0
  41. package/dist/routes/qr.js +136 -0
  42. package/dist/routes/qr.js.map +1 -0
  43. package/dist/routes/redirect.d.ts.map +1 -1
  44. package/dist/routes/redirect.js +167 -11
  45. package/dist/routes/redirect.js.map +1 -1
  46. package/dist/routes/sdk.d.ts +7 -0
  47. package/dist/routes/sdk.d.ts.map +1 -0
  48. package/dist/routes/sdk.js +265 -0
  49. package/dist/routes/sdk.js.map +1 -0
  50. package/dist/routes/webhooks.d.ts +3 -0
  51. package/dist/routes/webhooks.d.ts.map +1 -0
  52. package/dist/routes/webhooks.js +212 -0
  53. package/dist/routes/webhooks.js.map +1 -0
  54. package/dist/types/index.d.ts +81 -0
  55. package/dist/types/index.d.ts.map +1 -1
  56. package/package.json +11 -7
@@ -0,0 +1,387 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.CONFIDENCE_THRESHOLD = exports.DEFAULT_ATTRIBUTION_WINDOW_HOURS = void 0;
40
+ exports.generateFingerprintHash = generateFingerprintHash;
41
+ exports.calculateConfidenceScore = calculateConfidenceScore;
42
+ exports.matchInstallToClick = matchInstallToClick;
43
+ exports.storeFingerprintForClick = storeFingerprintForClick;
44
+ exports.recordInstallEvent = recordInstallEvent;
45
+ const crypto_1 = __importDefault(require("crypto"));
46
+ const database_js_1 = require("./database.js");
47
+ /**
48
+ * Scoring weights for probabilistic matching
49
+ * Total should equal 100 for percentage-based confidence
50
+ */
51
+ const FINGERPRINT_WEIGHTS = {
52
+ IP_ADDRESS: 40,
53
+ USER_AGENT: 30,
54
+ TIMEZONE: 10,
55
+ LANGUAGE: 10,
56
+ SCREEN_RESOLUTION: 10,
57
+ };
58
+ /**
59
+ * Default attribution window in hours (7 days)
60
+ */
61
+ exports.DEFAULT_ATTRIBUTION_WINDOW_HOURS = 168;
62
+ /**
63
+ * Minimum confidence threshold for attribution (70%)
64
+ */
65
+ exports.CONFIDENCE_THRESHOLD = 70;
66
+ /**
67
+ * Generate a fingerprint hash from device data
68
+ * Uses SHA-256 hash of concatenated device attributes
69
+ */
70
+ function generateFingerprintHash(data) {
71
+ const components = [
72
+ data.ipAddress || '',
73
+ data.userAgent || '',
74
+ data.timezone || '',
75
+ data.language || '',
76
+ data.screenWidth?.toString() || '',
77
+ data.screenHeight?.toString() || '',
78
+ data.platform || '',
79
+ data.platformVersion || '',
80
+ ];
81
+ const concatenated = components.join('|');
82
+ return crypto_1.default.createHash('sha256').update(concatenated).digest('hex');
83
+ }
84
+ /**
85
+ * Normalize IP address for comparison
86
+ * Handles IPv4 and IPv6, removes subnet variations
87
+ */
88
+ function normalizeIP(ip) {
89
+ if (!ip)
90
+ return '';
91
+ // For IPv4, use first 3 octets (e.g., 192.168.1.x)
92
+ if (ip.includes('.')) {
93
+ const parts = ip.split('.');
94
+ return parts.slice(0, 3).join('.');
95
+ }
96
+ // For IPv6, use first 4 groups (e.g., 2001:0db8:85a3:0000:xxxx)
97
+ if (ip.includes(':')) {
98
+ const parts = ip.split(':');
99
+ return parts.slice(0, 4).join(':');
100
+ }
101
+ return ip;
102
+ }
103
+ /**
104
+ * Normalize user agent for comparison
105
+ * Extracts key identifiers and removes version numbers
106
+ */
107
+ function normalizeUserAgent(ua) {
108
+ if (!ua)
109
+ return '';
110
+ // Extract platform (iOS, Android, Windows, Mac, Linux)
111
+ const platformMatch = ua.match(/(iPhone|iPad|Android|Windows|Macintosh|Linux)/i);
112
+ const platform = platformMatch ? platformMatch[1] : '';
113
+ // Extract browser (Chrome, Safari, Firefox, Edge)
114
+ const browserMatch = ua.match(/(Chrome|Safari|Firefox|Edge|Opera)/i);
115
+ const browser = browserMatch ? browserMatch[1] : '';
116
+ return `${platform}|${browser}`.toLowerCase();
117
+ }
118
+ /**
119
+ * Calculate confidence score by comparing two fingerprints
120
+ * Returns a score from 0-100 based on matched components
121
+ */
122
+ function calculateConfidenceScore(fingerprint1, fingerprint2) {
123
+ let score = 0;
124
+ const matchedFactors = [];
125
+ // Compare IP addresses (normalized to /24 subnet for IPv4)
126
+ if (fingerprint1.ipAddress && fingerprint2.ipAddress) {
127
+ const ip1 = normalizeIP(fingerprint1.ipAddress);
128
+ const ip2 = normalizeIP(fingerprint2.ipAddress);
129
+ if (ip1 === ip2) {
130
+ score += FINGERPRINT_WEIGHTS.IP_ADDRESS;
131
+ matchedFactors.push('ip');
132
+ }
133
+ }
134
+ // Compare user agents (normalized to platform + browser)
135
+ if (fingerprint1.userAgent && fingerprint2.userAgent) {
136
+ const ua1 = normalizeUserAgent(fingerprint1.userAgent);
137
+ const ua2 = normalizeUserAgent(fingerprint2.userAgent);
138
+ if (ua1 === ua2) {
139
+ score += FINGERPRINT_WEIGHTS.USER_AGENT;
140
+ matchedFactors.push('user_agent');
141
+ }
142
+ }
143
+ // Compare timezone
144
+ if (fingerprint1.timezone && fingerprint2.timezone) {
145
+ if (fingerprint1.timezone === fingerprint2.timezone) {
146
+ score += FINGERPRINT_WEIGHTS.TIMEZONE;
147
+ matchedFactors.push('timezone');
148
+ }
149
+ }
150
+ // Compare language
151
+ if (fingerprint1.language && fingerprint2.language) {
152
+ // Match first 2 characters (e.g., "en-US" matches "en-GB")
153
+ const lang1 = fingerprint1.language.substring(0, 2).toLowerCase();
154
+ const lang2 = fingerprint2.language.substring(0, 2).toLowerCase();
155
+ if (lang1 === lang2) {
156
+ score += FINGERPRINT_WEIGHTS.LANGUAGE;
157
+ matchedFactors.push('language');
158
+ }
159
+ }
160
+ // Compare screen resolution
161
+ if (fingerprint1.screenWidth &&
162
+ fingerprint1.screenHeight &&
163
+ fingerprint2.screenWidth &&
164
+ fingerprint2.screenHeight) {
165
+ if (fingerprint1.screenWidth === fingerprint2.screenWidth &&
166
+ fingerprint1.screenHeight === fingerprint2.screenHeight) {
167
+ score += FINGERPRINT_WEIGHTS.SCREEN_RESOLUTION;
168
+ matchedFactors.push('screen');
169
+ }
170
+ }
171
+ return { score, matchedFactors };
172
+ }
173
+ /**
174
+ * Match an install event to potential click events via probabilistic fingerprinting
175
+ * Returns the best match above confidence threshold within attribution window
176
+ *
177
+ * Note: Uses link-specific attribution windows - each link can have its own window
178
+ */
179
+ async function matchInstallToClick(installFingerprint, attributionWindowHours = exports.DEFAULT_ATTRIBUTION_WINDOW_HOURS) {
180
+ // Query recent click events within maximum possible attribution window (90 days)
181
+ // We'll validate against each link's specific window during matching
182
+ const maxWindowHours = 2160; // 90 days
183
+ const cutoffTime = new Date(Date.now() - maxWindowHours * 60 * 60 * 1000);
184
+ const clicksResult = await database_js_1.db.query(`SELECT
185
+ ce.id as click_id,
186
+ ce.link_id,
187
+ ce.clicked_at,
188
+ l.attribution_window_hours,
189
+ df.ip_address,
190
+ df.user_agent,
191
+ df.timezone,
192
+ df.language,
193
+ df.screen_width,
194
+ df.screen_height,
195
+ df.platform,
196
+ df.platform_version
197
+ FROM click_events ce
198
+ INNER JOIN device_fingerprints df ON df.click_id = ce.id
199
+ INNER JOIN links l ON ce.link_id = l.id
200
+ WHERE ce.clicked_at >= $1
201
+ ORDER BY ce.clicked_at DESC
202
+ LIMIT 1000`, [cutoffTime]);
203
+ if (clicksResult.rows.length === 0) {
204
+ return null;
205
+ }
206
+ const installTime = new Date();
207
+ // Calculate confidence score for each potential match
208
+ let bestMatch = null;
209
+ let highestScore = 0;
210
+ for (const row of clicksResult.rows) {
211
+ // Check if click is within the link's specific attribution window
212
+ const linkWindowHours = row.attribution_window_hours || exports.DEFAULT_ATTRIBUTION_WINDOW_HOURS;
213
+ const clickTime = new Date(row.clicked_at);
214
+ const timeDiffHours = (installTime.getTime() - clickTime.getTime()) / (1000 * 60 * 60);
215
+ if (timeDiffHours > linkWindowHours) {
216
+ // Click is too old for this link's attribution window, skip it
217
+ continue;
218
+ }
219
+ const clickFingerprint = {
220
+ ipAddress: row.ip_address,
221
+ userAgent: row.user_agent,
222
+ timezone: row.timezone,
223
+ language: row.language,
224
+ screenWidth: row.screen_width,
225
+ screenHeight: row.screen_height,
226
+ platform: row.platform,
227
+ platformVersion: row.platform_version,
228
+ };
229
+ const { score, matchedFactors } = calculateConfidenceScore(installFingerprint, clickFingerprint);
230
+ // Track the best match
231
+ if (score > highestScore && score >= exports.CONFIDENCE_THRESHOLD) {
232
+ highestScore = score;
233
+ bestMatch = {
234
+ clickId: row.click_id,
235
+ linkId: row.link_id,
236
+ confidenceScore: score,
237
+ matchedFactors,
238
+ clickedAt: new Date(row.clicked_at),
239
+ };
240
+ }
241
+ }
242
+ return bestMatch;
243
+ }
244
+ /**
245
+ * Store device fingerprint for a click event
246
+ */
247
+ async function storeFingerprintForClick(clickId, fingerprintData) {
248
+ const fingerprintHash = generateFingerprintHash(fingerprintData);
249
+ await database_js_1.db.query(`INSERT INTO device_fingerprints (
250
+ click_id,
251
+ fingerprint_hash,
252
+ ip_address,
253
+ user_agent,
254
+ timezone,
255
+ language,
256
+ screen_width,
257
+ screen_height,
258
+ platform,
259
+ platform_version
260
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`, [
261
+ clickId,
262
+ fingerprintHash,
263
+ fingerprintData.ipAddress,
264
+ fingerprintData.userAgent,
265
+ fingerprintData.timezone || null,
266
+ fingerprintData.language || null,
267
+ fingerprintData.screenWidth || null,
268
+ fingerprintData.screenHeight || null,
269
+ fingerprintData.platform || null,
270
+ fingerprintData.platformVersion || null,
271
+ ]);
272
+ }
273
+ /**
274
+ * Record an install event and attempt to match it to a click
275
+ */
276
+ async function recordInstallEvent(fingerprintData, deviceId, attributionWindowHours = exports.DEFAULT_ATTRIBUTION_WINDOW_HOURS) {
277
+ const fingerprintHash = generateFingerprintHash(fingerprintData);
278
+ // Attempt to match install to a click
279
+ const match = await matchInstallToClick(fingerprintData, attributionWindowHours);
280
+ // Insert install event
281
+ const installResult = await database_js_1.db.query(`INSERT INTO install_events (
282
+ link_id,
283
+ click_id,
284
+ fingerprint_hash,
285
+ confidence_score,
286
+ installed_at,
287
+ first_open_at,
288
+ attribution_window_hours,
289
+ ip_address,
290
+ user_agent,
291
+ timezone,
292
+ language,
293
+ screen_width,
294
+ screen_height,
295
+ platform,
296
+ platform_version,
297
+ device_id,
298
+ deep_link_data
299
+ ) VALUES ($1, $2, $3, $4, NOW(), NOW(), $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
300
+ RETURNING id, deep_link_data`, [
301
+ match?.linkId || null,
302
+ match?.clickId || null,
303
+ fingerprintHash,
304
+ match?.confidenceScore || null,
305
+ attributionWindowHours,
306
+ fingerprintData.ipAddress,
307
+ fingerprintData.userAgent,
308
+ fingerprintData.timezone || null,
309
+ fingerprintData.language || null,
310
+ fingerprintData.screenWidth || null,
311
+ fingerprintData.screenHeight || null,
312
+ fingerprintData.platform || null,
313
+ fingerprintData.platformVersion || null,
314
+ deviceId || null,
315
+ match ? JSON.stringify({}) : JSON.stringify({}), // Will be populated from link data
316
+ ]);
317
+ const installId = installResult.rows[0].id;
318
+ let deepLinkData = {};
319
+ // If we have a match, retrieve the deep link data from the original link
320
+ if (match) {
321
+ const linkResult = await database_js_1.db.query(`SELECT
322
+ short_code,
323
+ original_url,
324
+ ios_url,
325
+ android_url,
326
+ web_fallback_url,
327
+ utm_parameters,
328
+ targeting_rules
329
+ FROM links
330
+ WHERE id = $1`, [match.linkId]);
331
+ if (linkResult.rows.length > 0) {
332
+ const link = linkResult.rows[0];
333
+ deepLinkData = {
334
+ shortCode: link.short_code,
335
+ originalUrl: link.original_url,
336
+ iosUrl: link.ios_url,
337
+ androidUrl: link.android_url,
338
+ webFallbackUrl: link.web_fallback_url,
339
+ utmParameters: link.utm_parameters,
340
+ targetingRules: link.targeting_rules,
341
+ clickedAt: match.clickedAt,
342
+ confidenceScore: match.confidenceScore,
343
+ matchedFactors: match.matchedFactors,
344
+ };
345
+ // Update the install event with deep link data
346
+ await database_js_1.db.query(`UPDATE install_events
347
+ SET deep_link_data = $1,
348
+ deep_link_retrieved = true
349
+ WHERE id = $2`, [JSON.stringify(deepLinkData), installId]);
350
+ // Trigger webhooks for install_event (only if attributed)
351
+ try {
352
+ // Get the link's user_id for webhook lookup
353
+ const linkUserResult = await database_js_1.db.query('SELECT user_id FROM links WHERE id = $1', [match.linkId]);
354
+ if (linkUserResult.rows.length > 0) {
355
+ const userId = linkUserResult.rows[0].user_id;
356
+ const webhooksResult = await database_js_1.db.query('SELECT * FROM webhooks WHERE user_id = $1 AND is_active = true', [userId]);
357
+ if (webhooksResult.rows.length > 0) {
358
+ const { triggerWebhooks } = await Promise.resolve().then(() => __importStar(require('./webhook.js')));
359
+ const installEventData = {
360
+ id: installId,
361
+ linkId: match.linkId,
362
+ fingerprintHash,
363
+ confidenceScore: match.confidenceScore,
364
+ installedAt: new Date().toISOString(),
365
+ deepLinkData,
366
+ ipAddress: fingerprintData.ipAddress,
367
+ userAgent: fingerprintData.userAgent,
368
+ platform: fingerprintData.platform,
369
+ };
370
+ // Trigger webhooks without delivery logging (basic version)
371
+ // For delivery logging, use @linkforty/cloud premium features
372
+ await triggerWebhooks(webhooksResult.rows, 'install_event', installId, installEventData);
373
+ }
374
+ }
375
+ }
376
+ catch (webhookError) {
377
+ console.error(`Error triggering install webhooks: ${webhookError}`);
378
+ }
379
+ }
380
+ }
381
+ return {
382
+ installId,
383
+ match,
384
+ deepLinkData,
385
+ };
386
+ }
387
+ //# sourceMappingURL=fingerprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/lib/fingerprint.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ export declare function generateShortCode(length?: number): string;
2
2
  export declare function parseUserAgent(userAgent: string): {
3
3
  deviceType: string;
4
4
  platform: string;
5
+ platformVersion: string | undefined;
5
6
  browser: string;
6
7
  };
7
8
  export declare function getLocationFromIP(ip: string): {
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAIA,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,MAAU,GAAG,MAAM,CAE5D;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM;;;;EAS/C;AAoDD,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;EAwB3C;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACrC,MAAM,CAYR;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,CAYzE"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAIA,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,MAAU,GAAG,MAAM,CAE5D;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM;;;;;EAU/C;AAoDD,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;EAwB3C;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACrC,MAAM,CAYR;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,CAYzE"}
package/dist/lib/utils.js CHANGED
@@ -20,6 +20,7 @@ function parseUserAgent(userAgent) {
20
20
  return {
21
21
  deviceType: result.device.type || 'desktop',
22
22
  platform: result.os.name || 'unknown',
23
+ platformVersion: result.os.version || undefined,
23
24
  browser: result.browser.name || 'unknown',
24
25
  };
25
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { Webhook, WebhookPayload, WebhookDeliveryResult, WebhookEvent } from '../types/index.js';
2
+ /**
3
+ * Generate HMAC SHA-256 signature for webhook payload
4
+ */
5
+ export declare function generateWebhookSignature(payload: string, secret: string): string;
6
+ /**
7
+ * Generate a secure random secret for webhook signing
8
+ */
9
+ export declare function generateWebhookSecret(): string;
10
+ /**
11
+ * Deliver webhook with retry logic and exponential backoff
12
+ */
13
+ export declare function deliverWebhook(webhook: Webhook, payload: WebhookPayload, logDelivery?: (result: WebhookDeliveryResult) => Promise<void>): Promise<WebhookDeliveryResult>;
14
+ /**
15
+ * Trigger webhooks for a specific event (fire and forget)
16
+ */
17
+ export declare function triggerWebhooks(webhooks: Webhook[], event: WebhookEvent, eventId: string, data: any, logDelivery?: (webhookId: string, result: WebhookDeliveryResult) => Promise<void>): Promise<void>;
18
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/lib/webhook.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtG;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AA4ED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,EACvB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,GAC7D,OAAO,CAAC,qBAAqB,CAAC,CAmChC;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,GAAG,EACT,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,GAChF,OAAO,CAAC,IAAI,CAAC,CAuCf"}
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.generateWebhookSignature = generateWebhookSignature;
7
+ exports.generateWebhookSecret = generateWebhookSecret;
8
+ exports.deliverWebhook = deliverWebhook;
9
+ exports.triggerWebhooks = triggerWebhooks;
10
+ const crypto_1 = __importDefault(require("crypto"));
11
+ /**
12
+ * Generate HMAC SHA-256 signature for webhook payload
13
+ */
14
+ function generateWebhookSignature(payload, secret) {
15
+ return crypto_1.default.createHmac('sha256', secret).update(payload).digest('hex');
16
+ }
17
+ /**
18
+ * Generate a secure random secret for webhook signing
19
+ */
20
+ function generateWebhookSecret() {
21
+ return crypto_1.default.randomBytes(32).toString('hex');
22
+ }
23
+ /**
24
+ * Sleep utility for retry delays
25
+ */
26
+ function sleep(ms) {
27
+ return new Promise(resolve => setTimeout(resolve, ms));
28
+ }
29
+ /**
30
+ * Attempt a single webhook delivery
31
+ */
32
+ async function attemptWebhookDelivery(webhook, payload, attemptNumber) {
33
+ const payloadString = JSON.stringify(payload);
34
+ const signature = generateWebhookSignature(payloadString, webhook.secret);
35
+ const headers = {
36
+ 'Content-Type': 'application/json',
37
+ 'X-LinkForty-Signature': `sha256=${signature}`,
38
+ 'X-LinkForty-Event': payload.event,
39
+ 'X-LinkForty-Event-ID': payload.event_id,
40
+ 'User-Agent': 'LinkForty-Webhook/1.0',
41
+ ...webhook.headers,
42
+ };
43
+ const controller = new AbortController();
44
+ const timeoutId = setTimeout(() => controller.abort(), webhook.timeout_ms);
45
+ try {
46
+ const response = await fetch(webhook.url, {
47
+ method: 'POST',
48
+ headers,
49
+ body: payloadString,
50
+ signal: controller.signal,
51
+ });
52
+ clearTimeout(timeoutId);
53
+ const responseBody = await response.text().catch(() => '');
54
+ const result = {
55
+ success: response.ok,
56
+ webhookId: webhook.id,
57
+ eventType: payload.event,
58
+ eventId: payload.event_id,
59
+ responseStatus: response.status,
60
+ responseBody: responseBody.substring(0, 1000), // Limit response body size
61
+ attemptNumber,
62
+ deliveredAt: response.ok ? new Date().toISOString() : undefined,
63
+ };
64
+ if (!response.ok) {
65
+ result.errorMessage = `HTTP ${response.status}: ${response.statusText}`;
66
+ }
67
+ return result;
68
+ }
69
+ catch (error) {
70
+ clearTimeout(timeoutId);
71
+ return {
72
+ success: false,
73
+ webhookId: webhook.id,
74
+ eventType: payload.event,
75
+ eventId: payload.event_id,
76
+ errorMessage: error.name === 'AbortError'
77
+ ? `Timeout after ${webhook.timeout_ms}ms`
78
+ : error.message || 'Unknown error',
79
+ attemptNumber,
80
+ };
81
+ }
82
+ }
83
+ /**
84
+ * Deliver webhook with retry logic and exponential backoff
85
+ */
86
+ async function deliverWebhook(webhook, payload, logDelivery) {
87
+ const maxRetries = webhook.retry_count || 3;
88
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
89
+ const result = await attemptWebhookDelivery(webhook, payload, attempt);
90
+ // Log delivery attempt if logging function provided
91
+ if (logDelivery) {
92
+ await logDelivery(result).catch(err => {
93
+ console.error('Failed to log webhook delivery:', err);
94
+ });
95
+ }
96
+ // If successful, return immediately
97
+ if (result.success) {
98
+ return result;
99
+ }
100
+ // If not the last attempt, wait before retrying with exponential backoff
101
+ if (attempt < maxRetries) {
102
+ // Exponential backoff: 1s, 2s, 4s, 8s, 16s, 30s (capped at 30s)
103
+ const delayMs = Math.min(1000 * Math.pow(2, attempt - 1), 30000);
104
+ await sleep(delayMs);
105
+ }
106
+ }
107
+ // Return the last failed result
108
+ return {
109
+ success: false,
110
+ webhookId: webhook.id,
111
+ eventType: payload.event,
112
+ eventId: payload.event_id,
113
+ errorMessage: `Failed after ${maxRetries} attempts`,
114
+ attemptNumber: maxRetries,
115
+ };
116
+ }
117
+ /**
118
+ * Trigger webhooks for a specific event (fire and forget)
119
+ */
120
+ async function triggerWebhooks(webhooks, event, eventId, data, logDelivery) {
121
+ // Create webhook payload
122
+ const payload = {
123
+ event,
124
+ event_id: eventId,
125
+ timestamp: new Date().toISOString(),
126
+ data,
127
+ };
128
+ // Filter webhooks that should receive this event
129
+ const relevantWebhooks = webhooks.filter(webhook => webhook.is_active && webhook.events.includes(event));
130
+ if (relevantWebhooks.length === 0) {
131
+ return; // No webhooks to trigger
132
+ }
133
+ // Fire and forget - don't await these deliveries
134
+ const deliveryPromises = relevantWebhooks.map(async (webhook) => {
135
+ try {
136
+ const result = await deliverWebhook(webhook, payload, logDelivery ? (result) => logDelivery(webhook.id, result) : undefined);
137
+ if (!result.success) {
138
+ console.error(`Webhook ${webhook.id} delivery failed:`, result.errorMessage);
139
+ }
140
+ }
141
+ catch (error) {
142
+ console.error(`Webhook ${webhook.id} delivery error:`, error);
143
+ }
144
+ });
145
+ // Fire and forget - log errors but don't block
146
+ Promise.all(deliveryPromises).catch(err => {
147
+ console.error('Webhook delivery batch error:', err);
148
+ });
149
+ }
150
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/lib/webhook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { FastifyInstance } from 'fastify';
2
+ /**
3
+ * Debugging routes for testing and validation
4
+ * Premium Cloud-only feature
5
+ */
6
+ export declare function debugRoutes(fastify: FastifyInstance): Promise<void>;
7
+ //# sourceMappingURL=debug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/routes/debug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAqB1D;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,iBAoVzD"}