@linkforty/core 1.44.4 → 1.45.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import { DatabaseOptions } from './lib/database.js';
3
3
  import { type RedirectRouteOptions } from './routes/redirect.js';
4
4
  import { type SdkRouteOptions } from './routes/sdk.js';
5
5
  import type { LinkFortyConfig } from './lib/config.js';
6
+ import { type AsnLookup } from './lib/scanner-detection.js';
6
7
  /**
7
8
  * Configuration options for creating a LinkForty server instance.
8
9
  */
@@ -21,12 +22,21 @@ export interface ServerOptions {
21
22
  redirect?: RedirectRouteOptions;
22
23
  /** Options for the SDK routes: install match scoping. */
23
24
  sdk?: SdkRouteOptions;
24
- /** Click classification options. */
25
+ /**
26
+ * Click classification options. All optional: with none of them the email
27
+ * security scanner rule (lib/scanner-detection.ts) is off and everything else
28
+ * works as usual.
29
+ */
25
30
  botDetection?: {
26
31
  /**
27
- * Path to a MaxMind GeoLite2-ASN (or GeoIP2-ISP) `.mmdb` file. Turns on the
28
- * email security scanner rule (lib/scanner-detection.ts); without it the
29
- * rule is off. A file that can't be opened is logged and the rule stays off.
32
+ * Your own IP-to-ASN source: an in-house table, any database format, or API
33
+ * results kept in memory (it is synchronous). Takes precedence over
34
+ * `asnDatabasePath`. If it throws, the click counts as not a scanner.
35
+ */
36
+ asnLookup?: AsnLookup;
37
+ /**
38
+ * Path to an ASN database in MMDB format, such as DB-IP's IP to ASN Lite. A
39
+ * file that can't be opened is logged and the rule stays off.
30
40
  */
31
41
  asnDatabasePath?: string;
32
42
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAGnD,OAAO,EAAsB,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAkB,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGjF,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAMlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGvD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,KAAK,CAAC,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;KAC3B,CAAC;IACF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oJAAoJ;IACpJ,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,yDAAyD;IACzD,GAAG,CAAC,EAAE,eAAe,CAAC;IACtB,oCAAoC;IACpC,YAAY,CAAC,EAAE;QACb;;;;WAIG;QACH,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF;;;OAGG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,aAAkB,kTA+C7D;AAGD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAGnD,OAAO,EAAsB,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAkB,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGjF,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAMlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAE7G;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,KAAK,CAAC,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;KAC3B,CAAC;IACF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oJAAoJ;IACpJ,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,yDAAyD;IACzD,GAAG,CAAC,EAAE,eAAe,CAAC;IACtB;;;;OAIG;IACH,YAAY,CAAC,EAAE;QACb;;;;WAIG;QACH,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB;;;WAGG;QACH,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF;;;OAGG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,aAAkB,kTAsD7D;AAGD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { templateRoutes } from './routes/templates.js';
11
11
  import { qrRoutes } from './routes/qr.js';
12
12
  import { wellKnownRoutes } from './routes/well-known.js';
13
13
  import { healthRoutes } from './routes/health.js';
14
- import { loadScannerDetection } from './lib/scanner-detection.js';
14
+ import { configureScannerDetection, loadScannerDetection } from './lib/scanner-detection.js';
15
15
  /**
16
16
  * Create and configure a LinkForty Fastify server instance.
17
17
  *
@@ -38,13 +38,21 @@ export async function createServer(options = {}) {
38
38
  }
39
39
  // Database
40
40
  await initializeDatabase(options.database);
41
- // Email security scanner detection (optional: needs an ASN database)
42
- const scannerDetection = loadScannerDetection(options.botDetection?.asnDatabasePath, {
43
- asns: options.config?.botDetection?.emailScannerAsns,
44
- log: (message) => fastify.log.warn(message),
45
- });
46
- if (scannerDetection)
41
+ // Email security scanner detection (optional). With no source configured this
42
+ // leaves any lookup the host already set with configureScannerDetection() alone.
43
+ const scannerAsns = options.config?.botDetection?.emailScannerAsns;
44
+ if (options.botDetection?.asnLookup) {
45
+ configureScannerDetection({ lookup: options.botDetection.asnLookup, asns: scannerAsns });
47
46
  fastify.log.info('Email scanner detection is on');
47
+ }
48
+ else if (options.botDetection?.asnDatabasePath) {
49
+ const on = loadScannerDetection(options.botDetection.asnDatabasePath, {
50
+ asns: scannerAsns,
51
+ log: (message) => fastify.log.warn(message),
52
+ });
53
+ if (on)
54
+ fastify.log.info('Email scanner detection is on');
55
+ }
48
56
  // Routes
49
57
  await fastify.register(healthRoutes);
50
58
  await fastify.register(wellKnownRoutes);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -23,10 +23,11 @@ export declare function configureScannerDetection(options: {
23
23
  /** Whether the email scanner rule is active. */
24
24
  export declare function isScannerDetectionEnabled(): boolean;
25
25
  /**
26
- * Open a MaxMind ASN database (`.mmdb`) and return a lookup over it. Reads the
26
+ * Open an ASN database (`.mmdb` with `autonomous_system_number` records, as
27
+ * DB-IP and MaxMind publish) and return a lookup over it. Reads the
27
28
  * file once; lookups are in memory.
28
29
  *
29
- * @throws when the file can't be read or isn't a MaxMind database.
30
+ * @throws when the file can't be read or isn't an MMDB database.
30
31
  */
31
32
  export declare function openAsnDatabase(path: string): AsnLookup;
32
33
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"scanner-detection.d.ts","sourceRoot":"","sources":["../../src/lib/scanner-detection.ts"],"names":[],"mappings":"AAsBA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAMjD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,MAAM,EAMvC,CAAC;AAEF,gEAAgE;AAChE,MAAM,MAAM,SAAS,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAStD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAG/G;AAED,gDAAgD;AAChD,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAUvD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,GAC1E,OAAO,CAeT;AAQD,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAK7F"}
1
+ {"version":3,"file":"scanner-detection.d.ts","sourceRoot":"","sources":["../../src/lib/scanner-detection.ts"],"names":[],"mappings":"AAsBA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAOjD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,MAAM,EAMvC,CAAC;AAEF,gEAAgE;AAChE,MAAM,MAAM,SAAS,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAUtD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAI/G;AAED,gDAAgD;AAChD,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAUvD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,GAC1E,OAAO,CAeT;AAQD,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAgB7F"}
@@ -13,9 +13,9 @@
13
13
  * of the cloud networks below *and* the user agent is a desktop browser. Mobile
14
14
  * browsers and app HTTP clients from those networks are left alone.
15
15
  *
16
- * The ASN comes from a MaxMind GeoLite2-ASN (or GeoIP2-ISP) database, which an
17
- * instance has to supply: the license doesn't allow redistributing it. Without
18
- * one the rule is simply off and classification works as before.
16
+ * The ASN comes from an MMDB-format ASN database that the instance supplies,
17
+ * such as DB-IP's IP to ASN Lite (CC BY 4.0, attribution required). Without one
18
+ * the rule is simply off and classification works as before.
19
19
  */
20
20
  import { readFileSync } from 'fs';
21
21
  import { Reader } from 'maxmind';
@@ -25,6 +25,7 @@ import { Reader } from 'maxmind';
25
25
  */
26
26
  export const DEFAULT_SCANNER_ASNS = [
27
27
  8075, // Microsoft (Azure; Defender for Office 365 Safe Links)
28
+ 8070, // Microsoft
28
29
  16509, // Amazon (AWS)
29
30
  14618, // Amazon (AWS us-east-1)
30
31
  15169, // Google
@@ -43,6 +44,7 @@ export const RELAY_ASNS = [
43
44
  54113, // Fastly
44
45
  ];
45
46
  let state = null;
47
+ let lookupFailureLogged = false;
46
48
  /**
47
49
  * Turn the email scanner rule on (or off, with `lookup: null`).
48
50
  *
@@ -51,16 +53,18 @@ let state = null;
51
53
  export function configureScannerDetection(options) {
52
54
  const asns = new Set(options.asns ?? DEFAULT_SCANNER_ASNS);
53
55
  state = options.lookup && asns.size > 0 ? { lookup: options.lookup, asns } : null;
56
+ lookupFailureLogged = false;
54
57
  }
55
58
  /** Whether the email scanner rule is active. */
56
59
  export function isScannerDetectionEnabled() {
57
60
  return state !== null;
58
61
  }
59
62
  /**
60
- * Open a MaxMind ASN database (`.mmdb`) and return a lookup over it. Reads the
63
+ * Open an ASN database (`.mmdb` with `autonomous_system_number` records, as
64
+ * DB-IP and MaxMind publish) and return a lookup over it. Reads the
61
65
  * file once; lookups are in memory.
62
66
  *
63
- * @throws when the file can't be read or isn't a MaxMind database.
67
+ * @throws when the file can't be read or isn't an MMDB database.
64
68
  */
65
69
  export function openAsnDatabase(path) {
66
70
  const reader = new Reader(readFileSync(path));
@@ -108,7 +112,19 @@ export function isEmailScanner(userAgent, ip) {
108
112
  return false;
109
113
  if (!DESKTOP_BROWSER_UA.test(userAgent))
110
114
  return false;
111
- const asn = state.lookup(ip);
112
- return asn !== null && state.asns.has(asn);
115
+ try {
116
+ const asn = state.lookup(ip);
117
+ return asn !== null && state.asns.has(asn);
118
+ }
119
+ catch (error) {
120
+ // A failing lookup must never cost the click its record: the caller writes
121
+ // the row after classifying, so count it as not a scanner and carry on.
122
+ if (!lookupFailureLogged) {
123
+ lookupFailureLogged = true;
124
+ const reason = error instanceof Error ? error.message : String(error);
125
+ console.warn(`Email scanner detection: the ASN lookup failed; treating these clicks as not scanners (${reason})`);
126
+ }
127
+ return false;
128
+ }
113
129
  }
114
130
  //# sourceMappingURL=scanner-detection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scanner-detection.js","sourceRoot":"","sources":["../../src/lib/scanner-detection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scanner-detection.js","sourceRoot":"","sources":["../../src/lib/scanner-detection.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linkforty/core",
3
- "version": "1.44.4",
3
+ "version": "1.45.1",
4
4
  "type": "module",
5
5
  "description": "Open-source deeplink management engine with device detection and analytics",
6
6
  "main": "dist/index.js",