@prosopo/ipinfo 0.2.14
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/.turbo/turbo-build$colon$tsc.log +27 -0
- package/.turbo/turbo-build.log +38 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/CHANGELOG.md +119 -0
- package/dist/IpInfoService.d.ts +12 -0
- package/dist/IpInfoService.d.ts.map +1 -0
- package/dist/IpInfoService.js +96 -0
- package/dist/IpInfoService.js.map +1 -0
- package/dist/backends/ipapi.d.ts +14 -0
- package/dist/backends/ipapi.d.ts.map +1 -0
- package/dist/backends/ipapi.js +100 -0
- package/dist/backends/ipapi.js.map +1 -0
- package/dist/backends/maxmind.d.ts +17 -0
- package/dist/backends/maxmind.d.ts.map +1 -0
- package/dist/backends/maxmind.js +150 -0
- package/dist/backends/maxmind.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
- package/vite.cjs.config.ts +22 -0
- package/vite.esm.config.ts +20 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
> @prosopo/ipinfo@0.2.10 build:tsc
|
|
3
|
+
> tsc --build --verbose
|
|
4
|
+
|
|
5
|
+
17:33:58 - Projects in this build:
|
|
6
|
+
* ../../dev/config/tsconfig.json
|
|
7
|
+
* ../locale/tsconfig.json
|
|
8
|
+
* ../util/tsconfig.json
|
|
9
|
+
* ../util-crypto/tsconfig.json
|
|
10
|
+
* ../types/tsconfig.json
|
|
11
|
+
* ../common/tsconfig.json
|
|
12
|
+
* tsconfig.json
|
|
13
|
+
|
|
14
|
+
17:33:58 - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/vite/vite.backend.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
|
|
15
|
+
|
|
16
|
+
17:33:58 - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/locales/tr/translation.json' is older than output '../locale/tsconfig.tsbuildinfo'
|
|
17
|
+
|
|
18
|
+
17:33:58 - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
|
|
19
|
+
|
|
20
|
+
17:33:58 - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
|
|
21
|
+
|
|
22
|
+
17:33:58 - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/database.ts' is older than output '../types/tsconfig.tsbuildinfo'
|
|
23
|
+
|
|
24
|
+
17:33:58 - Project '../common/tsconfig.json' is up to date because newest input '../common/src/error.ts' is older than output '../common/tsconfig.tsbuildinfo'
|
|
25
|
+
|
|
26
|
+
17:33:58 - Project 'tsconfig.json' is up to date because newest input 'src/IpInfoService.ts' is older than output 'tsconfig.tsbuildinfo'
|
|
27
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @prosopo/ipinfo@0.2.11 build
|
|
4
|
+
> npm run build:cross-env -- --mode ${NODE_ENV:-development}
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
> @prosopo/ipinfo@0.2.11 build:cross-env
|
|
8
|
+
> vite build --config vite.esm.config.ts --mode production
|
|
9
|
+
|
|
10
|
+
ViteEsmConfig: .
|
|
11
|
+
{
|
|
12
|
+
tsConfigPaths: [
|
|
13
|
+
[32m'/home/chris/dev/prosopo/captcha-private2/captcha/packages/logger/tsconfig.json'[39m,
|
|
14
|
+
[32m'/home/chris/dev/prosopo/captcha-private2/captcha/packages/types/tsconfig.json'[39m,
|
|
15
|
+
[32m'/home/chris/dev/prosopo/captcha-private2/captcha/packages/locale/tsconfig.json'[39m,
|
|
16
|
+
[32m'/home/chris/dev/prosopo/captcha-private2/captcha/packages/util/tsconfig.json'[39m,
|
|
17
|
+
[32m'/home/chris/dev/prosopo/captcha-private2/captcha/packages/util-crypto/tsconfig.json'[39m
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
{
|
|
21
|
+
externals: [
|
|
22
|
+
[32m'@prosopo/logger'[39m,
|
|
23
|
+
[32m'@prosopo/types'[39m,
|
|
24
|
+
[32m'@prosopo/locale'[39m,
|
|
25
|
+
[32m'@prosopo/util'[39m,
|
|
26
|
+
[32m'@prosopo/util-crypto'[39m
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
[36mvite v6.4.1 [32mbuilding SSR bundle for production...[36m[39m
|
|
30
|
+
Bundle build started
|
|
31
|
+
[2K[1Gtransforming (1) [2msrc/index.ts[22mBuild end
|
|
32
|
+
[2K[1G[32m✓[39m 4 modules transformed.
|
|
33
|
+
[2K[1Grendering chunks (1)...[2K[1Grendering chunks (2)...[2K[1Grendering chunks (3)...[2K[1Grendering chunks (4)...[2K[1G[2K[1G[2mdist/[22m[36mindex.js [39m[1m[2m0.08 kB[22m[1m[22m
|
|
34
|
+
[2mdist/[22m[36mIpInfoService.js [39m[1m[2m2.67 kB[22m[1m[22m
|
|
35
|
+
[2mdist/[22m[36mbackends/ipapi.js [39m[1m[2m3.14 kB[22m[1m[22m
|
|
36
|
+
[2mdist/[22m[36mbackends/maxmind.js [39m[1m[2m4.44 kB[22m[1m[22m
|
|
37
|
+
[32m✓ built in 142ms[39m
|
|
38
|
+
⠙[1G[0K⠙[1G[0K
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# @prosopo/ipinfo
|
|
2
|
+
|
|
3
|
+
## 0.2.14
|
|
4
|
+
### Patch Changes
|
|
5
|
+
|
|
6
|
+
- Updated dependencies [a1d60db]
|
|
7
|
+
- Updated dependencies [2392aaf]
|
|
8
|
+
- Updated dependencies [97cf7bd]
|
|
9
|
+
- Updated dependencies [6ca1125]
|
|
10
|
+
- Updated dependencies [32a591b]
|
|
11
|
+
- @prosopo/types@4.3.0
|
|
12
|
+
- @prosopo/logger@1.0.2
|
|
13
|
+
|
|
14
|
+
## 0.2.13
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [6c26669]
|
|
18
|
+
- Updated dependencies [f7f9ec5]
|
|
19
|
+
- @prosopo/types@4.2.1
|
|
20
|
+
|
|
21
|
+
## 0.2.12
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- 0fd81af: Extract the logger into its own `@prosopo/logger` package, out of `@prosopo/common`. Consumers now import logger symbols from `@prosopo/logger`; `@prosopo/common` no longer re-exports them. Unused `@prosopo/common` dependencies pruned where the only usage was the logger.
|
|
25
|
+
- Updated dependencies [0fd81af]
|
|
26
|
+
- @prosopo/logger@1.0.1
|
|
27
|
+
|
|
28
|
+
## 0.2.11
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- Updated dependencies [20cae63]
|
|
32
|
+
- Updated dependencies [4d9923e]
|
|
33
|
+
- @prosopo/types@4.2.0
|
|
34
|
+
|
|
35
|
+
## 0.2.10
|
|
36
|
+
### Patch Changes
|
|
37
|
+
|
|
38
|
+
- Updated dependencies [d351362]
|
|
39
|
+
- @prosopo/types@4.1.4
|
|
40
|
+
|
|
41
|
+
## 0.2.9
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- Updated dependencies [e2711ae]
|
|
45
|
+
- Updated dependencies [5786629]
|
|
46
|
+
- @prosopo/types@4.1.3
|
|
47
|
+
- @prosopo/common@3.1.36
|
|
48
|
+
|
|
49
|
+
## 0.2.8
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- @prosopo/types@4.1.2
|
|
53
|
+
|
|
54
|
+
## 0.2.7
|
|
55
|
+
### Patch Changes
|
|
56
|
+
|
|
57
|
+
- Updated dependencies [91958da]
|
|
58
|
+
- @prosopo/types@4.1.1
|
|
59
|
+
- @prosopo/common@3.1.35
|
|
60
|
+
|
|
61
|
+
## 0.2.6
|
|
62
|
+
### Patch Changes
|
|
63
|
+
|
|
64
|
+
- Updated dependencies [6a741ce]
|
|
65
|
+
- @prosopo/types@4.1.0
|
|
66
|
+
|
|
67
|
+
## 0.2.5
|
|
68
|
+
### Patch Changes
|
|
69
|
+
|
|
70
|
+
- Updated dependencies [3c0be68]
|
|
71
|
+
- Updated dependencies [f9ea09d]
|
|
72
|
+
- Updated dependencies [d865319]
|
|
73
|
+
- Updated dependencies [753304b]
|
|
74
|
+
- Updated dependencies [8bb7286]
|
|
75
|
+
- Updated dependencies [f9ea09d]
|
|
76
|
+
- Updated dependencies [4aae4e6]
|
|
77
|
+
- Updated dependencies [4993813]
|
|
78
|
+
- @prosopo/types@4.0.0
|
|
79
|
+
- @prosopo/common@3.1.34
|
|
80
|
+
|
|
81
|
+
## 0.2.4
|
|
82
|
+
### Patch Changes
|
|
83
|
+
|
|
84
|
+
- Updated dependencies [819ed95]
|
|
85
|
+
- @prosopo/types@3.16.1
|
|
86
|
+
|
|
87
|
+
## 0.2.3
|
|
88
|
+
### Patch Changes
|
|
89
|
+
|
|
90
|
+
- Updated dependencies [f6a4402]
|
|
91
|
+
- Updated dependencies [99dfb44]
|
|
92
|
+
- @prosopo/types@3.16.0
|
|
93
|
+
|
|
94
|
+
## 0.2.2
|
|
95
|
+
### Patch Changes
|
|
96
|
+
|
|
97
|
+
- Updated dependencies [3e54c0a]
|
|
98
|
+
- @prosopo/types@3.15.0
|
|
99
|
+
|
|
100
|
+
## 0.2.1
|
|
101
|
+
### Patch Changes
|
|
102
|
+
|
|
103
|
+
- Updated dependencies [946a8ba]
|
|
104
|
+
- Updated dependencies [5614814]
|
|
105
|
+
- @prosopo/types@3.14.1
|
|
106
|
+
- @prosopo/common@3.1.33
|
|
107
|
+
|
|
108
|
+
## 0.2.0
|
|
109
|
+
### Minor Changes
|
|
110
|
+
|
|
111
|
+
- 42650db: Add better spam rules and move ipinfo service to local instead of external
|
|
112
|
+
|
|
113
|
+
### Patch Changes
|
|
114
|
+
|
|
115
|
+
- fc514dd: ability to block different types of traffic
|
|
116
|
+
- Updated dependencies [fc514dd]
|
|
117
|
+
- Updated dependencies [42650db]
|
|
118
|
+
- @prosopo/types@3.14.0
|
|
119
|
+
- @prosopo/common@3.1.32
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IPInfoResponse } from "@prosopo/types";
|
|
2
|
+
import type { IIpInfoService, IpInfoServiceConfig } from "./types.js";
|
|
3
|
+
export declare class IpInfoService implements IIpInfoService {
|
|
4
|
+
private maxmindBackend;
|
|
5
|
+
private ipapiBackend;
|
|
6
|
+
private config;
|
|
7
|
+
constructor(config: IpInfoServiceConfig);
|
|
8
|
+
initialize(): Promise<void>;
|
|
9
|
+
isAvailable(): boolean;
|
|
10
|
+
lookup(ip: string): Promise<IPInfoResponse>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=IpInfoService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IpInfoService.d.ts","sourceRoot":"","sources":["../src/IpInfoService.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAuCtE,qBAAa,aAAc,YAAW,cAAc;IACnD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,EAAE,mBAAmB;IAoBjC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAcjC,WAAW,IAAI,OAAO;IAOhB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CA4CjD"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { IpapiBackend } from "./backends/ipapi.js";
|
|
2
|
+
import { MaxMindBackend } from "./backends/maxmind.js";
|
|
3
|
+
function isNonRoutable(ip) {
|
|
4
|
+
const normalized = ip.replace(/^::ffff:/i, "");
|
|
5
|
+
if (normalized.startsWith("127.") ||
|
|
6
|
+
normalized.startsWith("10.") ||
|
|
7
|
+
normalized.startsWith("192.168.") ||
|
|
8
|
+
normalized.startsWith("169.254.") ||
|
|
9
|
+
normalized === "0.0.0.0") {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
if (normalized.startsWith("172.")) {
|
|
13
|
+
const second = Number.parseInt(normalized.split(".")[1] ?? "", 10);
|
|
14
|
+
if (second >= 16 && second <= 31)
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (normalized === "::1" || normalized === "::")
|
|
18
|
+
return true;
|
|
19
|
+
if (/^f[cd]/i.test(normalized))
|
|
20
|
+
return true;
|
|
21
|
+
if (/^fe[89ab]/i.test(normalized))
|
|
22
|
+
return true;
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
export class IpInfoService {
|
|
26
|
+
constructor(config) {
|
|
27
|
+
this.maxmindBackend = null;
|
|
28
|
+
this.ipapiBackend = null;
|
|
29
|
+
this.config = config;
|
|
30
|
+
if (config.maxmindCityDbPath || config.maxmindAsnDbPath) {
|
|
31
|
+
this.maxmindBackend = new MaxMindBackend({
|
|
32
|
+
cityDbPath: config.maxmindCityDbPath,
|
|
33
|
+
asnDbPath: config.maxmindAsnDbPath,
|
|
34
|
+
logger: config.logger,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (config.ipapiUrl) {
|
|
38
|
+
this.ipapiBackend = new IpapiBackend({
|
|
39
|
+
baseUrl: config.ipapiUrl,
|
|
40
|
+
apiKey: config.ipapiKey,
|
|
41
|
+
logger: config.logger,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async initialize() {
|
|
46
|
+
if (this.maxmindBackend) {
|
|
47
|
+
await this.maxmindBackend.initialize();
|
|
48
|
+
}
|
|
49
|
+
this.config.logger?.info(() => ({
|
|
50
|
+
msg: "IpInfoService initialized",
|
|
51
|
+
data: {
|
|
52
|
+
maxmindAvailable: this.maxmindBackend?.isAvailable() ?? false,
|
|
53
|
+
ipapiAvailable: this.ipapiBackend?.isAvailable() ?? false,
|
|
54
|
+
},
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
isAvailable() {
|
|
58
|
+
return ((this.maxmindBackend?.isAvailable() ?? false) ||
|
|
59
|
+
(this.ipapiBackend?.isAvailable() ?? false));
|
|
60
|
+
}
|
|
61
|
+
async lookup(ip) {
|
|
62
|
+
if (isNonRoutable(ip)) {
|
|
63
|
+
return {
|
|
64
|
+
isValid: false,
|
|
65
|
+
error: "Non-routable IP address",
|
|
66
|
+
ip,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (this.ipapiBackend?.isAvailable()) {
|
|
70
|
+
const result = await this.ipapiBackend.lookup(ip);
|
|
71
|
+
if (result.isValid) {
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
this.config.logger?.debug(() => ({
|
|
75
|
+
msg: "ipapi.is lookup failed, falling back to MaxMind",
|
|
76
|
+
data: {
|
|
77
|
+
ip,
|
|
78
|
+
error: "error" in result ? result.error : "unknown",
|
|
79
|
+
},
|
|
80
|
+
}));
|
|
81
|
+
if (this.maxmindBackend?.isAvailable()) {
|
|
82
|
+
return this.maxmindBackend.lookup(ip);
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
if (this.maxmindBackend?.isAvailable()) {
|
|
87
|
+
return this.maxmindBackend.lookup(ip);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
isValid: false,
|
|
91
|
+
error: "No IP info backend available",
|
|
92
|
+
ip,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=IpInfoService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IpInfoService.js","sourceRoot":"","sources":["../src/IpInfoService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Logger } from "@prosopo/logger";
|
|
2
|
+
import type { IPInfoResponse } from "@prosopo/types";
|
|
3
|
+
export interface IpapiBackendConfig {
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
logger?: Logger;
|
|
7
|
+
}
|
|
8
|
+
export declare class IpapiBackend {
|
|
9
|
+
private config;
|
|
10
|
+
constructor(config: IpapiBackendConfig);
|
|
11
|
+
isAvailable(): boolean;
|
|
12
|
+
lookup(ip: string): Promise<IPInfoResponse>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=ipapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipapi.d.ts","sourceRoot":"","sources":["../../src/backends/ipapi.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAEX,cAAc,EAEd,MAAM,gBAAgB,CAAC;AAIxB,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,YAAY;IACxB,OAAO,CAAC,MAAM,CAAqB;gBAEvB,MAAM,EAAE,kBAAkB;IAItC,WAAW,IAAI,OAAO;IAIhB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CA2GjD"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const TIMEOUT_MS = 700;
|
|
2
|
+
export class IpapiBackend {
|
|
3
|
+
constructor(config) {
|
|
4
|
+
this.config = config;
|
|
5
|
+
}
|
|
6
|
+
isAvailable() {
|
|
7
|
+
return Boolean(this.config.baseUrl);
|
|
8
|
+
}
|
|
9
|
+
async lookup(ip) {
|
|
10
|
+
try {
|
|
11
|
+
if (!ip || typeof ip !== "string") {
|
|
12
|
+
return {
|
|
13
|
+
isValid: false,
|
|
14
|
+
error: "Invalid IP address provided",
|
|
15
|
+
ip: ip || "undefined",
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const body = { q: ip };
|
|
19
|
+
if (this.config.apiKey) {
|
|
20
|
+
body.key = this.config.apiKey;
|
|
21
|
+
}
|
|
22
|
+
const controller = new AbortController();
|
|
23
|
+
const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
24
|
+
try {
|
|
25
|
+
const response = await fetch(this.config.baseUrl, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: {
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
Accept: "application/json",
|
|
30
|
+
},
|
|
31
|
+
body: JSON.stringify(body),
|
|
32
|
+
signal: controller.signal,
|
|
33
|
+
});
|
|
34
|
+
clearTimeout(timeoutId);
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
return {
|
|
37
|
+
isValid: false,
|
|
38
|
+
error: `API request failed with status ${response.status}: ${response.statusText}`,
|
|
39
|
+
ip,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const data = (await response.json());
|
|
43
|
+
if (data.is_bogon) {
|
|
44
|
+
return {
|
|
45
|
+
isValid: false,
|
|
46
|
+
error: "IP address is bogon (non-routable)",
|
|
47
|
+
ip,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const result = {
|
|
51
|
+
ip: data.ip,
|
|
52
|
+
isValid: true,
|
|
53
|
+
isVPN: data.is_vpn,
|
|
54
|
+
isTor: data.is_tor,
|
|
55
|
+
isProxy: data.is_proxy,
|
|
56
|
+
isDatacenter: data.is_datacenter,
|
|
57
|
+
isAbuser: data.is_abuser,
|
|
58
|
+
isMobile: data.is_mobile,
|
|
59
|
+
isSatellite: data.is_satellite,
|
|
60
|
+
isCrawler: data.is_crawler,
|
|
61
|
+
providerName: data.company?.name || data.datacenter?.datacenter,
|
|
62
|
+
providerType: data.company?.type || data.asn?.type,
|
|
63
|
+
asnNumber: data.asn?.asn,
|
|
64
|
+
asnOrganization: data.asn?.org,
|
|
65
|
+
country: data.location?.country,
|
|
66
|
+
countryCode: data.location?.country_code,
|
|
67
|
+
region: data.location?.state,
|
|
68
|
+
city: data.location?.city,
|
|
69
|
+
latitude: data.location?.latitude,
|
|
70
|
+
longitude: data.location?.longitude,
|
|
71
|
+
timezone: data.location?.timezone,
|
|
72
|
+
vpnService: data.vpn?.service,
|
|
73
|
+
vpnType: data.vpn?.type,
|
|
74
|
+
abuserScore: Number.parseFloat(data.asn?.abuser_score.split(" ")[0] || "0"),
|
|
75
|
+
companyAbuserScore: Number.parseFloat(data.company?.abuser_score.split(" ")[0] || "0"),
|
|
76
|
+
};
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
catch (fetchError) {
|
|
80
|
+
clearTimeout(timeoutId);
|
|
81
|
+
if (fetchError instanceof Error && fetchError.name === "AbortError") {
|
|
82
|
+
return {
|
|
83
|
+
isValid: false,
|
|
84
|
+
error: `Request timed out after ${TIMEOUT_MS}ms`,
|
|
85
|
+
ip,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
throw fetchError;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
return {
|
|
93
|
+
isValid: false,
|
|
94
|
+
error: `Network or parsing error: ${error instanceof Error ? error.message : String(error)}`,
|
|
95
|
+
ip,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=ipapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipapi.js","sourceRoot":"","sources":["../../src/backends/ipapi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Logger } from "@prosopo/logger";
|
|
2
|
+
import type { IPInfoResponse } from "@prosopo/types";
|
|
3
|
+
export interface MaxMindBackendConfig {
|
|
4
|
+
cityDbPath?: string;
|
|
5
|
+
asnDbPath?: string;
|
|
6
|
+
logger?: Logger;
|
|
7
|
+
}
|
|
8
|
+
export declare class MaxMindBackend {
|
|
9
|
+
private cityReader;
|
|
10
|
+
private asnReader;
|
|
11
|
+
private config;
|
|
12
|
+
constructor(config: MaxMindBackendConfig);
|
|
13
|
+
initialize(): Promise<void>;
|
|
14
|
+
isAvailable(): boolean;
|
|
15
|
+
lookup(ip: string): Promise<IPInfoResponse>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=maxmind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maxmind.d.ts","sourceRoot":"","sources":["../../src/backends/maxmind.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,gBAAgB,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,cAAc;IAC1B,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,MAAM,CAAuB;gBAEzB,MAAM,EAAE,oBAAoB;IAIlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoCjC,WAAW,IAAI,OAAO;IAIhB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CA8FjD"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export class MaxMindBackend {
|
|
2
|
+
constructor(config) {
|
|
3
|
+
this.cityReader = null;
|
|
4
|
+
this.asnReader = null;
|
|
5
|
+
this.config = config;
|
|
6
|
+
}
|
|
7
|
+
async initialize() {
|
|
8
|
+
const { Reader } = await import("@maxmind/geoip2-node");
|
|
9
|
+
if (this.config.cityDbPath) {
|
|
10
|
+
try {
|
|
11
|
+
this.cityReader = await Reader.open(this.config.cityDbPath);
|
|
12
|
+
this.config.logger?.info(() => ({
|
|
13
|
+
msg: "MaxMind City reader initialized",
|
|
14
|
+
data: { dbPath: this.config.cityDbPath },
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
this.config.logger?.warn(() => ({
|
|
19
|
+
msg: "Failed to initialize MaxMind City reader",
|
|
20
|
+
err: error,
|
|
21
|
+
data: { dbPath: this.config.cityDbPath },
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (this.config.asnDbPath) {
|
|
26
|
+
try {
|
|
27
|
+
this.asnReader = await Reader.open(this.config.asnDbPath);
|
|
28
|
+
this.config.logger?.info(() => ({
|
|
29
|
+
msg: "MaxMind ASN reader initialized",
|
|
30
|
+
data: { dbPath: this.config.asnDbPath },
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
this.config.logger?.warn(() => ({
|
|
35
|
+
msg: "Failed to initialize MaxMind ASN reader",
|
|
36
|
+
err: error,
|
|
37
|
+
data: { dbPath: this.config.asnDbPath },
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
isAvailable() {
|
|
43
|
+
return this.cityReader !== null || this.asnReader !== null;
|
|
44
|
+
}
|
|
45
|
+
async lookup(ip) {
|
|
46
|
+
if (!this.isAvailable()) {
|
|
47
|
+
return {
|
|
48
|
+
isValid: false,
|
|
49
|
+
error: "MaxMind readers not initialized",
|
|
50
|
+
ip,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
let cityData;
|
|
55
|
+
let asnData;
|
|
56
|
+
if (this.cityReader) {
|
|
57
|
+
try {
|
|
58
|
+
cityData = this.cityReader.city(ip);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
this.config.logger?.debug(() => ({
|
|
62
|
+
msg: "MaxMind City lookup failed",
|
|
63
|
+
data: { ip },
|
|
64
|
+
err: error,
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (this.asnReader) {
|
|
69
|
+
try {
|
|
70
|
+
asnData = this.asnReader.asn(ip);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
this.config.logger?.debug(() => ({
|
|
74
|
+
msg: "MaxMind ASN lookup failed",
|
|
75
|
+
data: { ip },
|
|
76
|
+
err: error,
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!cityData && !asnData) {
|
|
81
|
+
return {
|
|
82
|
+
isValid: false,
|
|
83
|
+
error: "No MaxMind data available for IP",
|
|
84
|
+
ip,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const result = {
|
|
88
|
+
ip,
|
|
89
|
+
isValid: true,
|
|
90
|
+
isVPN: cityData?.traits?.isAnonymousVpn ?? false,
|
|
91
|
+
isTor: cityData?.traits?.isTorExitNode ?? false,
|
|
92
|
+
isProxy: (cityData?.traits?.isPublicProxy ?? false) ||
|
|
93
|
+
(cityData?.traits?.isResidentialProxy ?? false),
|
|
94
|
+
isDatacenter: cityData?.traits?.isHostingProvider ?? false,
|
|
95
|
+
isAbuser: false,
|
|
96
|
+
isMobile: false,
|
|
97
|
+
isSatellite: cityData?.traits?.isSatelliteProvider ?? false,
|
|
98
|
+
isCrawler: false,
|
|
99
|
+
country: cityData?.country?.names?.en,
|
|
100
|
+
countryCode: cityData?.country?.isoCode,
|
|
101
|
+
region: cityData?.subdivisions?.[0]?.names?.en,
|
|
102
|
+
city: cityData?.city?.names?.en,
|
|
103
|
+
latitude: cityData?.location?.latitude,
|
|
104
|
+
longitude: cityData?.location?.longitude,
|
|
105
|
+
timezone: cityData?.location?.timeZone,
|
|
106
|
+
asnNumber: cityData?.traits?.autonomousSystemNumber ??
|
|
107
|
+
asnData?.autonomousSystemNumber,
|
|
108
|
+
asnOrganization: cityData?.traits?.autonomousSystemOrganization ??
|
|
109
|
+
asnData?.autonomousSystemOrganization,
|
|
110
|
+
providerName: cityData?.traits?.autonomousSystemOrganization ??
|
|
111
|
+
asnData?.autonomousSystemOrganization,
|
|
112
|
+
providerType: mapUserType(cityData?.traits?.userType),
|
|
113
|
+
};
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
return {
|
|
118
|
+
isValid: false,
|
|
119
|
+
error: `MaxMind lookup error: ${error instanceof Error ? error.message : String(error)}`,
|
|
120
|
+
ip,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function mapUserType(userType) {
|
|
126
|
+
switch (userType) {
|
|
127
|
+
case "hosting":
|
|
128
|
+
case "content_delivery_network":
|
|
129
|
+
return "hosting";
|
|
130
|
+
case "college":
|
|
131
|
+
case "school":
|
|
132
|
+
case "library":
|
|
133
|
+
return "education";
|
|
134
|
+
case "government":
|
|
135
|
+
case "military":
|
|
136
|
+
return "government";
|
|
137
|
+
case "business":
|
|
138
|
+
return "business";
|
|
139
|
+
case "residential":
|
|
140
|
+
case "cellular":
|
|
141
|
+
case "dialup":
|
|
142
|
+
case "cafe":
|
|
143
|
+
case "traveler":
|
|
144
|
+
case "router":
|
|
145
|
+
return "isp";
|
|
146
|
+
default:
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=maxmind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maxmind.js","sourceRoot":"","sources":["../../src/backends/maxmind.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Logger } from "@prosopo/logger";
|
|
2
|
+
import type { IPInfoResponse } from "@prosopo/types";
|
|
3
|
+
export interface IIpInfoService {
|
|
4
|
+
initialize(): Promise<void>;
|
|
5
|
+
lookup(ip: string): Promise<IPInfoResponse>;
|
|
6
|
+
isAvailable(): boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface IpInfoServiceConfig {
|
|
9
|
+
maxmindCityDbPath?: string;
|
|
10
|
+
maxmindAsnDbPath?: string;
|
|
11
|
+
ipapiUrl?: string;
|
|
12
|
+
ipapiKey?: string;
|
|
13
|
+
logger?: Logger;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,WAAW,cAAc;IAC9B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5C,WAAW,IAAI,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prosopo/ipinfo",
|
|
3
|
+
"version": "0.2.14",
|
|
4
|
+
"description": "IP information service with MaxMind and ipapi.is backends",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": "^24",
|
|
10
|
+
"npm": "^11"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js",
|
|
16
|
+
"require": "./dist/cjs/index.cjs"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"clean": "del-cli --verbose dist tsconfig.tsbuildinfo",
|
|
21
|
+
"build": "npm run build:cross-env -- --mode ${NODE_ENV:-development}",
|
|
22
|
+
"build:cross-env": "vite build --config vite.esm.config.ts",
|
|
23
|
+
"build:tsc": "tsc --build --verbose",
|
|
24
|
+
"build:cjs": "NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV",
|
|
25
|
+
"typecheck": "tsc --project tsconfig.types.json"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@maxmind/geoip2-node": "5.0.0",
|
|
29
|
+
"@prosopo/logger": "1.0.2",
|
|
30
|
+
"@prosopo/types": "4.3.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@prosopo/config": "3.3.1",
|
|
34
|
+
"@types/node": "22.10.2",
|
|
35
|
+
"@vitest/coverage-v8": "3.2.4",
|
|
36
|
+
"del-cli": "6.0.0",
|
|
37
|
+
"tslib": "2.7.0",
|
|
38
|
+
"typescript": "5.6.2",
|
|
39
|
+
"vite": "6.4.1",
|
|
40
|
+
"vitest": "3.2.4"
|
|
41
|
+
},
|
|
42
|
+
"license": "Apache-2.0",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/prosopo/captcha.git",
|
|
46
|
+
"directory": "packages/ipinfo"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
import { ViteCommonJSConfig } from "@prosopo/config";
|
|
16
|
+
|
|
17
|
+
export default function () {
|
|
18
|
+
return ViteCommonJSConfig(
|
|
19
|
+
path.basename("."),
|
|
20
|
+
path.resolve("./tsconfig.json"),
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import { ViteEsmConfig } from "@prosopo/config";
|
|
17
|
+
|
|
18
|
+
export default function () {
|
|
19
|
+
return ViteEsmConfig(path.basename("."), path.resolve("./tsconfig.json"));
|
|
20
|
+
}
|