From 6a57b7514d05101876b3f49196d9831e5ed81e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zo=C3=AB=20Maas?= Date: Thu, 14 Nov 2024 10:27:17 +0100 Subject: [PATCH 1/4] chore: Removed fs from the plugin and added dsn-query library --- .../__tests__/localAgent.test.ts | 1 + .../__tests__/restAgent.test.ts | 1 + packages/anomaly-detection/agent.yml | 7 +- packages/anomaly-detection/package.json | 1 + .../src/agent/AnomalyDetection.ts | 39 +++++----- pnpm-lock.yaml | 73 ++++++++++++++++++- 6 files changed, 99 insertions(+), 23 deletions(-) diff --git a/packages/anomaly-detection/__tests__/localAgent.test.ts b/packages/anomaly-detection/__tests__/localAgent.test.ts index a765a727c..d4940eb9c 100644 --- a/packages/anomaly-detection/__tests__/localAgent.test.ts +++ b/packages/anomaly-detection/__tests__/localAgent.test.ts @@ -10,6 +10,7 @@ let agent: any const setup = async (): Promise => { const config = await getConfig('packages/anomaly-detection/agent.yml') + config.agent.$args[0].plugins[0].$args[0].geoIpDB.$args[0].path = process.env.GEO_IP_DB_PATH const { localAgent, db } = await createObjects(config, { localAgent: '/agent', db: '/dbConnection' }) agent = localAgent dbConnection = db diff --git a/packages/anomaly-detection/__tests__/restAgent.test.ts b/packages/anomaly-detection/__tests__/restAgent.test.ts index fe6a9be02..4e9cf284c 100644 --- a/packages/anomaly-detection/__tests__/restAgent.test.ts +++ b/packages/anomaly-detection/__tests__/restAgent.test.ts @@ -33,6 +33,7 @@ const getAgent = (options?: IAgentOptions) => const setup = async (): Promise => { const config = await getConfig('packages/anomaly-detection/agent.yml') + config.agent.$args[0].plugins[0].$args[0].geoIpDB.$args[0].path = process.env.GEO_IP_DB_PATH const { agent, db } = await createObjects(config, { agent: '/agent', db: '/dbConnection' }) serverAgent = agent dbConnection = db diff --git a/packages/anomaly-detection/agent.yml b/packages/anomaly-detection/agent.yml index d6e19f761..c174a3c5d 100644 --- a/packages/anomaly-detection/agent.yml +++ b/packages/anomaly-detection/agent.yml @@ -82,5 +82,8 @@ agent: plugins: - $require: ./packages/anomaly-detection/dist#AnomalyDetection $args: - - geoIpDBPath: - $env: GEO_IP_DB_PATH + - geoIpDB: + $require: 'fs?t=function#readFileSync' + $args: + - path: + $env: GEO_IP_DB_PATH diff --git a/packages/anomaly-detection/package.json b/packages/anomaly-detection/package.json index dcb8d069e..05c478893 100644 --- a/packages/anomaly-detection/package.json +++ b/packages/anomaly-detection/package.json @@ -17,6 +17,7 @@ "dependencies": { "cross-fetch": "^3.1.8", "debug": "^4.3.5", + "dns-query": "^0.11.2", "mmdb-lib": "^2.1.1", "typeorm": "^0.3.20" }, diff --git a/packages/anomaly-detection/src/agent/AnomalyDetection.ts b/packages/anomaly-detection/src/agent/AnomalyDetection.ts index 072a11144..df78b3737 100644 --- a/packages/anomaly-detection/src/agent/AnomalyDetection.ts +++ b/packages/anomaly-detection/src/agent/AnomalyDetection.ts @@ -1,9 +1,8 @@ import {IAgentPlugin} from "@veramo/core"; import {IAnomalyDetection, LookupLocationArgs, LookupLocationResult, schema} from "../index"; -import * as fs from 'fs'; -import * as dns from 'dns' import * as mmdb from 'mmdb-lib' import {CountryResponse} from 'mmdb-lib' +import {lookupTxt} from "dns-query"; export const anomalyDetectionMethods: Array = [ 'lookupLocation' @@ -19,12 +18,12 @@ export class AnomalyDetection implements IAgentPlugin { lookupLocation: this.lookupLocation.bind(this) } - constructor(args: { geoIpDBPath: string }) { - const { geoIpDBPath } = { ...args } - if (geoIpDBPath === undefined || geoIpDBPath === null) { - throw new Error('The geoIpDBPath argument is required') + constructor(args: { geoIpDB: Buffer }) { + const { geoIpDB } = { ...args } + if (geoIpDB === undefined || geoIpDB === null) { + throw new Error('The geoIpDB argument is required') } - this.db = fs.readFileSync(geoIpDBPath) + this.db = geoIpDB } private async lookupLocation(args: LookupLocationArgs): Promise { @@ -35,8 +34,8 @@ export class AnomalyDetection implements IAgentPlugin { let result: CountryResponse | null if (!new RegExp(ipv4Reg).test(ipOrHostname) && !new RegExp(ipv6Reg).test(ipOrHostname)) { - const ip = await this.dnsLookupPromise({ hostname: ipOrHostname }) - result = reader.get(ip) + const txtResult = await lookupTxt(ipOrHostname, { endpoints: ['8.8.8.8', '8.8.4.4'] }) + result = reader.get(txtResult.endpoint) } else { result = reader.get(ipOrHostname) } @@ -50,15 +49,15 @@ export class AnomalyDetection implements IAgentPlugin { return null } - private async dnsLookupPromise(args: { hostname: string }): Promise { - const { hostname } = { ...args } - return new Promise((resolve, reject) => { - dns.lookup(hostname, (error, ip) => { - if (error) { - reject(error) - } - resolve(ip) - }) - }) - } + // private async dnsLookupPromise(args: { hostname: string }): Promise { + // const { hostname } = { ...args } + // return new Promise((resolve, reject) => { + // dns.lookup(hostname, (error, ip) => { + // if (error) { + // reject(error) + // } + // resolve(ip) + // }) + // }) + // } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad7246f21..dc17815f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -213,6 +213,9 @@ importers: debug: specifier: ^4.3.5 version: 4.3.6 + dns-query: + specifier: ^0.11.2 + version: 0.11.2 mmdb-lib: specifier: ^2.1.1 version: 2.1.1 @@ -5376,6 +5379,20 @@ packages: '@keyv/test-suite@1.9.5': resolution: {integrity: sha512-TYMfykWn9mi9+XQl7Dc2I4i6rsHp9ZZyci9n0iMUCJ/wi7htJGl6Nw5eMXtqqJxjCJW1T82v22YayJPHrVraCw==} + '@leichtgewicht/base64-codec@1.0.0': + resolution: {integrity: sha512-0cgP4lRBzh3F4tlpTfs7F+PJyBN8j5yUC9KrQFWp/bREswgzZVHE8T1rNyRDWgvALwwpPtnJDQfqWUmxI33Epg==} + + '@leichtgewicht/dns-packet@6.0.3': + resolution: {integrity: sha512-qmVHhFBFiBvPsk/wJ/EdoWHb+tGkzY4haybmDPukhF6w0+8wpEbrHTIRE9LzeUu2P0bAbmrK8WOXt5V5QN6jQg==} + engines: {node: '>=6'} + + '@leichtgewicht/dns-socket@5.0.0': + resolution: {integrity: sha512-Sbrn/OG0HTTPGSkwIDCHy8/tUI6UglIzFsMNjzZn/Na1/i5owSm6rVi9CfKNNjRcUlYEzICELYW6EoZdjwVY2A==} + engines: {node: '>=6'} + + '@leichtgewicht/ip-codec@2.0.5': + resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} + '@lerna/create@8.1.8': resolution: {integrity: sha512-wi72R01tgjBjzG2kjRyTHl4yCTKDfDMIXRyKz9E/FBa9SkFvUOAE4bdyY9MhEsRZmSWL7+CYE8Flv/HScRpBbA==} engines: {node: '>=18.0.0'} @@ -6026,7 +6043,6 @@ packages: '@sphereon/kmp-mdl-mdoc@0.2.0-SNAPSHOT.22': resolution: {integrity: sha512-uAZZExVy+ug9JLircejWa5eLtAZ7bnBP6xb7DO2+86LRsHNLh2k2jMWJYxp+iWtGHTsh6RYsZl14ScQLvjiQ/A==} - bundledDependencies: [] '@sphereon/lto-did-ts@0.1.8-unstable.0': resolution: {integrity: sha512-3jzwwuYX/VYuze+T9/yg4PcsJ5iNNwAfTp4WfS4aSfPFBErDAfKXqn6kOb0wFYGkhejr3Jz+rljPC2iKZiHiGA==} @@ -7527,6 +7543,9 @@ packages: resolution: {integrity: sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==} engines: {node: '>=12.17'} + bytes.js@0.0.2: + resolution: {integrity: sha512-KrLm4hv5Qs9w6b0U7h1bCdqxrsf+e9QMsfHeyQFzAz94x/5Aqa+FTEUSNBtt5d2VuV3Hfiea3c4ti74RZDDYkg==} + bytes@3.0.0: resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} engines: {node: '>= 0.8'} @@ -8302,6 +8321,10 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} + dns-query@0.11.2: + resolution: {integrity: sha512-zF8qxQpqCB467o4A63DLpQClo77H642JEKMx0Ra9GFww7Rx0234Fo8NoG0LBoSBZxamWkXfLxhzDG19bTBHvXQ==} + hasBin: true + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -8598,6 +8621,7 @@ packages: eslint@8.57.0: resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@9.6.1: @@ -13283,6 +13307,18 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + utf8-bytes@0.0.1: + resolution: {integrity: sha512-GifWmJAx2qAXT+lZLhbkWhBsy7pr6xWHiPWlVToDiELdWgZwt4Ogjf9tlgvKuALzTFR/d+EPQQI9ogJV3957Jg==} + + utf8-codec@1.0.0: + resolution: {integrity: sha512-S/QSLezp3qvG4ld5PUfXiH7mCFxLKjSVZRFkB3DOjgwHuJPFDkInAXc/anf7BAbHt/D38ozDzL+QMZ6/7gsI6w==} + + utf8-length@0.0.1: + resolution: {integrity: sha512-j/XH2ftofBiobnyApxlN/J6j/ixwT89WEjDcjT66d2i0+GIn9RZfzt8lpEXXE4jUe4NsjBSUq70kS2euQ4nnMw==} + + utf8-string-bytes@1.0.3: + resolution: {integrity: sha512-i/I1Omf6lADjVBlwJpQifZOePV15snHny9w04+lc71+3t8PyWuLC/7clyoOSHOBNGXFe2PAGxmTiZ+Z4HWsPyw==} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -16068,6 +16104,23 @@ snapshots: - bluebird - supports-color + '@leichtgewicht/base64-codec@1.0.0': {} + + '@leichtgewicht/dns-packet@6.0.3': + dependencies: + '@leichtgewicht/ip-codec': 2.0.5 + bytes.js: 0.0.2 + utf8-bytes: 0.0.1 + utf8-codec: 1.0.0 + utf8-length: 0.0.1 + utf8-string-bytes: 1.0.3 + + '@leichtgewicht/dns-socket@5.0.0': + dependencies: + '@leichtgewicht/dns-packet': 6.0.3 + + '@leichtgewicht/ip-codec@2.0.5': {} + '@lerna/create@8.1.8(encoding@0.1.13)(typescript@5.6.3)': dependencies: '@npmcli/arborist': 7.5.4 @@ -19937,6 +19990,8 @@ snapshots: byte-size@8.1.1: {} + bytes.js@0.0.2: {} + bytes@3.0.0: {} bytes@3.1.2: {} @@ -20835,6 +20890,14 @@ snapshots: dependencies: path-type: 4.0.0 + dns-query@0.11.2: + dependencies: + '@leichtgewicht/base64-codec': 1.0.0 + '@leichtgewicht/dns-packet': 6.0.3 + '@leichtgewicht/dns-socket': 5.0.0 + '@leichtgewicht/ip-codec': 2.0.5 + utf8-codec: 1.0.0 + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -27150,6 +27213,14 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 + utf8-bytes@0.0.1: {} + + utf8-codec@1.0.0: {} + + utf8-length@0.0.1: {} + + utf8-string-bytes@1.0.3: {} + util-deprecate@1.0.2: {} util@0.12.5: From a710fbd34cccf928e573ed18d4d50bc234cae4a1 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Fri, 15 Nov 2024 09:45:59 +0100 Subject: [PATCH 2/4] chore: fixed dnsLookupPromise callback sig --- .../shared/anomalyDetectionAgentLogic.ts | 30 +++++++++++-------- .../src/agent/AnomalyDetection.ts | 23 +++++++------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/packages/anomaly-detection/__tests__/shared/anomalyDetectionAgentLogic.ts b/packages/anomaly-detection/__tests__/shared/anomalyDetectionAgentLogic.ts index 8ae9e5823..c50c3f664 100644 --- a/packages/anomaly-detection/__tests__/shared/anomalyDetectionAgentLogic.ts +++ b/packages/anomaly-detection/__tests__/shared/anomalyDetectionAgentLogic.ts @@ -16,29 +16,35 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro afterAll(testContext.tearDown) it('should lookup the location of an IPv4 address', async () => { - await expect(agent.lookupLocation({ - ipOrHostname: '77.247.248.1' - })).resolves.toEqual({ + await expect( + agent.lookupLocation({ + ipOrHostname: '77.247.248.1', + }), + ).resolves.toEqual({ continent: 'EU', - country: 'AL' + country: 'AL', }) }) it('should lookup the location of an IPv6 address', async () => { - await expect(agent.lookupLocation({ - ipOrHostname: '2001:4860:7:27f::f5' - })).resolves.toEqual({ + await expect( + agent.lookupLocation({ + ipOrHostname: '2001:4860:7:27f::f5', + }), + ).resolves.toEqual({ continent: 'NA', - country: 'US' + country: 'US', }) }) it('should lookup the location of a hostname', async () => { - await expect(agent.lookupLocation({ - ipOrHostname: 'sphereon.com' - })).resolves.toEqual({ + await expect( + agent.lookupLocation({ + ipOrHostname: 'localhost', + }), + ).resolves.toEqual({ continent: 'EU', - country: 'DE' + country: 'DE', }) }) }) diff --git a/packages/anomaly-detection/src/agent/AnomalyDetection.ts b/packages/anomaly-detection/src/agent/AnomalyDetection.ts index cd828ea81..c84d49ba0 100644 --- a/packages/anomaly-detection/src/agent/AnomalyDetection.ts +++ b/packages/anomaly-detection/src/agent/AnomalyDetection.ts @@ -1,12 +1,10 @@ -import {IAgentPlugin} from "@veramo/core"; -import {IAnomalyDetection, LookupLocationArgs, LookupLocationResult, schema} from "../index"; +import { IAgentPlugin } from '@veramo/core' +import { IAnomalyDetection, LookupLocationArgs, LookupLocationResult, schema } from '../index' import * as dns from 'dns' import * as mmdb from 'mmdb-lib' -import {CountryResponse} from 'mmdb-lib' +import { CountryResponse } from 'mmdb-lib' -export const anomalyDetectionMethods: Array = [ -'lookupLocation' -] +export const anomalyDetectionMethods: Array = ['lookupLocation'] /** * {@inheritDoc IAnomalyDetection} @@ -15,7 +13,7 @@ export class AnomalyDetection implements IAgentPlugin { readonly schema = schema.IAnomalyDetection private readonly db: Buffer readonly methods: IAnomalyDetection = { - lookupLocation: this.lookupLocation.bind(this) + lookupLocation: this.lookupLocation.bind(this), } constructor(args: { geoIpDB: Buffer }) { @@ -29,8 +27,9 @@ export class AnomalyDetection implements IAgentPlugin { private async lookupLocation(args: LookupLocationArgs): Promise { const { ipOrHostname } = { ...args } const reader = new mmdb.Reader(this.db) - const ipv4Reg = "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])" - const ipv6Reg = "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))" + const ipv4Reg = '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + const ipv6Reg = + '(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))' let result: CountryResponse | null if (!new RegExp(ipv4Reg).test(ipOrHostname) && !new RegExp(ipv6Reg).test(ipOrHostname)) { @@ -43,7 +42,7 @@ export class AnomalyDetection implements IAgentPlugin { if (result !== undefined && result !== null) { return Promise.resolve({ continent: result?.continent?.code, - country: result?.country?.iso_code + country: result?.country?.iso_code, }) } return null @@ -52,11 +51,11 @@ export class AnomalyDetection implements IAgentPlugin { private async dnsLookupPromise(args: { hostname: string }): Promise { const { hostname } = { ...args } return new Promise((resolve, reject) => { - dns.lookup(hostname, (error, ip) => { + dns.lookup(hostname, (error: NodeJS.ErrnoException | null, address: string, family: number) => { if (error) { reject(error) } - resolve(ip) + resolve(address) }) }) } From c8957e5782a0dbdc1227fda38572f4cba112d11e Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Fri, 15 Nov 2024 17:04:24 +0100 Subject: [PATCH 3/4] chore: added dnsLookupCallback for RN --- .../src/agent/AnomalyDetection.ts | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/packages/anomaly-detection/src/agent/AnomalyDetection.ts b/packages/anomaly-detection/src/agent/AnomalyDetection.ts index c84d49ba0..0bce6c458 100644 --- a/packages/anomaly-detection/src/agent/AnomalyDetection.ts +++ b/packages/anomaly-detection/src/agent/AnomalyDetection.ts @@ -1,8 +1,8 @@ import { IAgentPlugin } from '@veramo/core' import { IAnomalyDetection, LookupLocationArgs, LookupLocationResult, schema } from '../index' -import * as dns from 'dns' -import * as mmdb from 'mmdb-lib' -import { CountryResponse } from 'mmdb-lib' +import { CountryResponse, Reader } from 'mmdb-lib' + +type DnsLookupFn = (hostname: string) => Promise export const anomalyDetectionMethods: Array = ['lookupLocation'] @@ -12,28 +12,30 @@ export const anomalyDetectionMethods: Array = ['lookupLocation'] export class AnomalyDetection implements IAgentPlugin { readonly schema = schema.IAnomalyDetection private readonly db: Buffer + private readonly dnsLookup?: DnsLookupFn readonly methods: IAnomalyDetection = { lookupLocation: this.lookupLocation.bind(this), } - constructor(args: { geoIpDB: Buffer }) { - const { geoIpDB } = { ...args } + constructor(args: { geoIpDB: Buffer; dnsLookupCallback?: DnsLookupFn }) { + const { geoIpDB, dnsLookupCallback } = { ...args } if (geoIpDB === undefined || geoIpDB === null) { throw new Error('The geoIpDB argument is required') } this.db = geoIpDB + this.dnsLookup = dnsLookupCallback } private async lookupLocation(args: LookupLocationArgs): Promise { const { ipOrHostname } = { ...args } - const reader = new mmdb.Reader(this.db) + const reader = new Reader(this.db) const ipv4Reg = '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' const ipv6Reg = '(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))' let result: CountryResponse | null if (!new RegExp(ipv4Reg).test(ipOrHostname) && !new RegExp(ipv6Reg).test(ipOrHostname)) { - const ip = await this.dnsLookupPromise({ hostname: ipOrHostname }) + const ip = await this.resolveDns(ipOrHostname) result = reader.get(ip) } else { result = reader.get(ipOrHostname) @@ -48,12 +50,26 @@ export class AnomalyDetection implements IAgentPlugin { return null } - private async dnsLookupPromise(args: { hostname: string }): Promise { - const { hostname } = { ...args } + private async resolveDns(hostname: string): Promise { + if (this.dnsLookup) { + return this.dnsLookup(hostname) + } + + // Fallback to Node.js dns + let dns + try { + dns = await Function('return import("dns")')() + } catch { + throw new Error( + 'DNS resolution not available on this platform, use the dnsLookupCallback in the AnomalyDetection constructor to implement DNS resolution for your platform.', + ) + } + return new Promise((resolve, reject) => { dns.lookup(hostname, (error: NodeJS.ErrnoException | null, address: string, family: number) => { if (error) { reject(error) + return } resolve(address) }) From 08fad965ffc9b445a751b74226268b8168b99cb9 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Fri, 15 Nov 2024 17:38:40 +0100 Subject: [PATCH 4/4] chore: reverted test & dns = eval('require("dns")') --- .../__tests__/shared/anomalyDetectionAgentLogic.ts | 2 +- packages/anomaly-detection/src/agent/AnomalyDetection.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/anomaly-detection/__tests__/shared/anomalyDetectionAgentLogic.ts b/packages/anomaly-detection/__tests__/shared/anomalyDetectionAgentLogic.ts index c50c3f664..1c0bf625e 100644 --- a/packages/anomaly-detection/__tests__/shared/anomalyDetectionAgentLogic.ts +++ b/packages/anomaly-detection/__tests__/shared/anomalyDetectionAgentLogic.ts @@ -40,7 +40,7 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro it('should lookup the location of a hostname', async () => { await expect( agent.lookupLocation({ - ipOrHostname: 'localhost', + ipOrHostname: 'sphereon.com', }), ).resolves.toEqual({ continent: 'EU', diff --git a/packages/anomaly-detection/src/agent/AnomalyDetection.ts b/packages/anomaly-detection/src/agent/AnomalyDetection.ts index 0bce6c458..5b853cc82 100644 --- a/packages/anomaly-detection/src/agent/AnomalyDetection.ts +++ b/packages/anomaly-detection/src/agent/AnomalyDetection.ts @@ -58,10 +58,11 @@ export class AnomalyDetection implements IAgentPlugin { // Fallback to Node.js dns let dns try { - dns = await Function('return import("dns")')() - } catch { + dns = eval('require("dns")') + } catch (e) { + console.error(e) throw new Error( - 'DNS resolution not available on this platform, use the dnsLookupCallback in the AnomalyDetection constructor to implement DNS resolution for your platform.', + `DNS resolution not available on this platform, use the dnsLookupCallback in the AnomalyDetection constructor to implement DNS resolution for your platform.\r\n${e.message}`, ) }