Skip to content

Commit 15de259

Browse files
committed
add resproxy changes
1 parent 818588f commit 15de259

File tree

6 files changed

+149
-2
lines changed

6 files changed

+149
-2
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# CHANGELOG
22

3+
## 4.3.0
4+
5+
- Add support for IPinfo Residential Proxy API
6+
37
## 4.2.0
48

59
- Add support for IPinfo Core API

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "node-ipinfo",
3-
"version": "4.2.0",
3+
"version": "4.3.0",
44
"description": "Official Node client library for IPinfo",
55
"main": "dist/src/index.js",
66
"types": "dist/src/index.d.ts",

src/common.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export const HOST: string = "ipinfo.io";
22
export const HOST_LITE: string = "api.ipinfo.io/lite";
33
export const HOST_CORE: string = "api.ipinfo.io/lookup";
44
export const HOST_PLUS: string = "api.ipinfo.io/lookup";
5+
export const HOST_RES_PROXY: string = "ipinfo.io/resproxy";
56

67
// cache version
78
export const CACHE_VSN: string = "1";
@@ -202,6 +203,13 @@ export interface IPinfoPlus {
202203
is_satellite: boolean;
203204
}
204205

206+
export interface IPinfoResProxy {
207+
ip: string;
208+
service: string;
209+
last_seen: string;
210+
percent_days_seen: number;
211+
}
212+
205213
export interface Prefix {
206214
netblock: string;
207215
id: string;

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import IPinfoWrapper from "./ipinfoWrapper";
22
import IPinfoLiteWrapper from "./ipinfoLiteWrapper";
33
import IPinfoCoreWrapper from "./ipinfoCoreWrapper";
44
import IPinfoPlusWrapper from "./ipinfoPlusWrapper";
5+
import IPinfoResProxyWrapper from "./ipinfoResProxyWrapper";
56
import Cache from "./cache/cache";
67
import LruCache from "./cache/lruCache";
78
import ApiLimitError from "./errors/apiLimitError";
@@ -15,6 +16,7 @@ export {
1516
IPinfoLiteWrapper,
1617
IPinfoCoreWrapper,
1718
IPinfoPlusWrapper,
19+
IPinfoResProxyWrapper,
1820
ApiLimitError
1921
};
2022
export {
@@ -27,6 +29,7 @@ export {
2729
IPinfo,
2830
IPinfoCore,
2931
IPinfoPlus,
32+
IPinfoResProxy,
3033
Prefix,
3134
Prefixes6,
3235
AsnResponse,

src/ipinfoResProxyWrapper.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import fetch from "node-fetch"
2+
import type { RequestInit, Response } from "node-fetch"
3+
import Cache from "./cache/cache"
4+
import LruCache from "./cache/lruCache"
5+
import ApiLimitError from "./errors/apiLimitError"
6+
import { isInSubnet } from "subnet-check"
7+
import {
8+
REQUEST_TIMEOUT_DEFAULT,
9+
CACHE_VSN,
10+
HOST_RES_PROXY,
11+
BOGON_NETWORKS,
12+
IPinfoResProxy,
13+
IPBogon
14+
} from "./common"
15+
import VERSION from "./version"
16+
17+
const clientUserAgent = `IPinfoClient/nodejs/${VERSION}`
18+
19+
export default class IPinfoResProxyWrapper {
20+
private token: string;
21+
private baseUrl: string;
22+
private cache: Cache;
23+
private timeout: number;
24+
25+
/**
26+
* Creates IPinfoResProxyWrapper object to communicate with the IPinfo Res Proxy API.
27+
*
28+
* @param token Token string provided by IPinfo for the registered user.
29+
* @param cache An implementation of IPCache interface, or LruCache if not specified.
30+
* @param timeout Request timeout in milliseconds, or 5000ms if not specified. 0 disables the timeout.
31+
* @param baseUrl The base url to use for api requests, or "ipinfo.io" if not specified.
32+
*/
33+
constructor(
34+
token: string,
35+
cache?: Cache,
36+
timeout?: number,
37+
baseUrl?: string,
38+
) {
39+
this.token = token
40+
this.cache = cache || new LruCache()
41+
this.timeout =
42+
timeout === null || timeout === undefined
43+
? REQUEST_TIMEOUT_DEFAULT
44+
: timeout
45+
this.baseUrl = baseUrl || `https://${HOST_RES_PROXY}`
46+
}
47+
48+
public static cacheKey(k: string): string {
49+
return `${k}:${CACHE_VSN}`
50+
}
51+
52+
public async fetchApi(
53+
path: string,
54+
init: RequestInit = {}
55+
): Promise<Response> {
56+
const headers = {
57+
Accept: "application/json",
58+
Authorization: `Bearer ${this.token}`,
59+
"Content-Type": "application/json",
60+
"User-Agent": clientUserAgent
61+
}
62+
63+
const request = Object.assign(
64+
{
65+
timeout: this.timeout,
66+
method: "GET",
67+
compress: false,
68+
},
69+
init,
70+
{ headers: Object.assign(headers, init.headers) },
71+
)
72+
73+
const url = [this.baseUrl, path].join(
74+
!this.baseUrl.endsWith("/") && !path.startsWith("/")
75+
? "/"
76+
: ""
77+
)
78+
79+
return fetch(url, request).then((response: Response) => {
80+
if (response.status === 429) {
81+
throw new ApiLimitError()
82+
}
83+
84+
if (response.status >= 400) {
85+
throw new Error(
86+
`Received an error from the IPinfo API ` +
87+
`(using authorization ${headers["Authorization"]}) ` +
88+
`${response.status} ${response.statusText} ${response.url}`
89+
)
90+
}
91+
92+
return response
93+
})
94+
}
95+
96+
public async lookupIp(
97+
ip: string | undefined = undefined
98+
): Promise<IPinfoResProxy | IPBogon> {
99+
if (ip && this.isBogon(ip)) {
100+
return { ip, bogon: true }
101+
}
102+
103+
if (!ip) {
104+
ip = "me"
105+
}
106+
107+
const data = await this.cache.get(IPinfoResProxyWrapper.cacheKey(ip))
108+
109+
if (data) {
110+
return data
111+
}
112+
113+
return this.fetchApi(ip)
114+
.then(async (response) => {
115+
const ipinfo = (await response.json()) as IPinfoResProxy
116+
this.cache.set(IPinfoResProxyWrapper.cacheKey(ip), ipinfo)
117+
118+
return ipinfo
119+
})
120+
}
121+
122+
private isBogon(ip: string): boolean {
123+
if (ip != "") {
124+
for (let network of BOGON_NETWORKS) {
125+
if (isInSubnet(ip, network)) {
126+
return true
127+
}
128+
}
129+
}
130+
return false
131+
}
132+
}

src/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
const VERSION = "4.2.0";
1+
const VERSION = "4.3.0";
22

33
export default VERSION;

0 commit comments

Comments
 (0)