vpndetection 5.1.0 → 5.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.
- package/README.md +36 -3
- package/dist/client.d.ts +13 -1
- package/dist/client.js +18 -72
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +28 -0
- package/dist/errors.js +51 -1
- package/dist/errors.js.map +1 -1
- package/dist/generated/types.gen.d.ts +80 -4
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/oauth.d.ts +118 -0
- package/dist/oauth.js +240 -0
- package/dist/oauth.js.map +1 -0
- package/dist/transport.d.ts +18 -0
- package/dist/transport.js +82 -0
- package/dist/transport.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ Usage counts against the anniversary of your subscription, not the calendar mont
|
|
|
62
62
|
|
|
63
63
|
### Batch lookup
|
|
64
64
|
|
|
65
|
-
Look up many addresses
|
|
65
|
+
Look up as many addresses as you like in one call. Bogons and cached answers are handled locally, and the rest go to the batch endpoint in chunks of up to 1000, in parallel:
|
|
66
66
|
|
|
67
67
|
```js
|
|
68
68
|
const results = await client.lookupBatch(['45.83.91.1', '8.8.8.8', '1.1.1.1']);
|
|
@@ -78,10 +78,10 @@ for (const [ip, result] of results) {
|
|
|
78
78
|
|
|
79
79
|
Results are keyed by address, in the order you first listed each one, so duplicates in your list collapse into a single entry and one address failing never loses the rest: it carries its error as its value, with the status the API would have given that address on its own.
|
|
80
80
|
|
|
81
|
-
How many chunks are in flight at once,
|
|
81
|
+
How many chunks are in flight at once, how many times a failed chunk is retried, and how long each request may take are configurable per call:
|
|
82
82
|
|
|
83
83
|
```js
|
|
84
|
-
const results = await client.lookupBatch(manyIps, { concurrency: 4, retries: 4 });
|
|
84
|
+
const results = await client.lookupBatch(manyIps, { concurrency: 4, retries: 4, timeoutMs: 10_000 });
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
### Caching
|
|
@@ -150,6 +150,18 @@ try {
|
|
|
150
150
|
|
|
151
151
|
Note that `rate_limited` and `quota_exceeded` both arrive as HTTP 429 and are not the same thing. A rate limit is when the API faces extreme traffic bursts and so retrying later works; but a spent quota needs your allowance raised or the window to roll over. The library retries rate limits for you, but not if your quota is exceeded.
|
|
152
152
|
|
|
153
|
+
### Timeouts
|
|
154
|
+
|
|
155
|
+
A request that hasn't finished after 30 seconds is abandoned and surfaces as a retryable `network` error. The limit applies to each attempt, so a call that gets retried can take longer in total. Set it for the client, or for a single lookup:
|
|
156
|
+
|
|
157
|
+
```js
|
|
158
|
+
const client = new VPNDetection({ timeoutMs: 10_000 });
|
|
159
|
+
|
|
160
|
+
const result = await client.lookup('45.83.91.1', { timeoutMs: 2000 });
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
A database transfer is exempt, because a large one takes minutes.
|
|
164
|
+
|
|
153
165
|
### Database downloads
|
|
154
166
|
|
|
155
167
|
If your key carries the `db.download` scope, the licensed databases are available through `client.database`. `download` fetches one to a path, streaming it straight to disk so that nothing bigger than a chunk is ever held in memory:
|
|
@@ -178,6 +190,27 @@ import { DATABASE_FORMATS } from 'vpndetection';
|
|
|
178
190
|
DATABASE_FORMATS.includes(fromTheCommandLine); // ['csvgz', 'mmdb']
|
|
179
191
|
```
|
|
180
192
|
|
|
193
|
+
### Sign in with OAuth (device flow)
|
|
194
|
+
|
|
195
|
+
A program running on the person's own machine can let them sign in with a browser and pick one of their API keys, instead of asking them to paste it:
|
|
196
|
+
|
|
197
|
+
```js
|
|
198
|
+
const client = new VPNDetection();
|
|
199
|
+
|
|
200
|
+
const device = await client.oauth.deviceAuthorization('your-client-id', {
|
|
201
|
+
scope: 'account.read apikeys.read apikeys.reveal',
|
|
202
|
+
});
|
|
203
|
+
console.log(`Open ${device.verification_uri} and enter ${device.user_code}`);
|
|
204
|
+
|
|
205
|
+
const token = await client.oauth.pollDeviceToken('your-client-id', device);
|
|
206
|
+
if (token.apikey === undefined) {
|
|
207
|
+
throw new Error("no API key came back: none was picked, or it can't be shown again");
|
|
208
|
+
}
|
|
209
|
+
const keyed = new VPNDetection({ apiKey: token.apikey });
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
A denied sign-in rejects with `OauthAccessDeniedError` and a code that ran out with `OauthExpiredTokenError`. Client IDs are issued on request from support@vpndetection.io, and `client.oauth.revoke('your-client-id', token.refresh_token)` signs the machine out again.
|
|
213
|
+
|
|
181
214
|
### Absent is not false
|
|
182
215
|
|
|
183
216
|
Only `ip` and `isVpn` come back on every plan. A field your plan does not include is `undefined`, which means "not in your plan" rather than "checked, and no".
|
package/dist/client.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { Writable } from 'node:stream';
|
|
|
2
2
|
import type { Client } from './generated/client/index.js';
|
|
3
3
|
import type { Entitlement, Database, DatabaseFormat, DatabaseMetadata, DbChecksums, Download } from './generated/types.gen.js';
|
|
4
4
|
import { VPNDetectionError } from './errors.js';
|
|
5
|
+
import { OauthApi } from './oauth.js';
|
|
5
6
|
import { type Result } from './types.js';
|
|
6
7
|
/**
|
|
7
8
|
* Where `download` puts the bytes: a path to write, or a stream you opened
|
|
@@ -18,6 +19,11 @@ export interface CacheOptions {
|
|
|
18
19
|
export interface DownloadsOptions {
|
|
19
20
|
/** How many attempts to return, newest first. The API clamps this to 200. */
|
|
20
21
|
limit?: number;
|
|
22
|
+
/**
|
|
23
|
+
* How long one attempt may take before it is abandoned, in milliseconds, for
|
|
24
|
+
* THIS call only. Defaults to the client's `timeoutMs`.
|
|
25
|
+
*/
|
|
26
|
+
timeoutMs?: number;
|
|
21
27
|
}
|
|
22
28
|
export interface Options {
|
|
23
29
|
/**
|
|
@@ -68,6 +74,11 @@ export declare class VPNDetection {
|
|
|
68
74
|
private readonly timeoutMs;
|
|
69
75
|
/** The licensed dataset downloads, for keys that carry the `db.download` scope. */
|
|
70
76
|
readonly database: DatabaseApi;
|
|
77
|
+
/**
|
|
78
|
+
* Sign a person in with the OAuth device flow, so a program on their own
|
|
79
|
+
* machine can be handed one of their API keys. Needs no API key.
|
|
80
|
+
*/
|
|
81
|
+
readonly oauth: OauthApi;
|
|
71
82
|
constructor(options?: Options);
|
|
72
83
|
/**
|
|
73
84
|
* Whether an address is private, loopback, link-local, documentation,
|
|
@@ -129,7 +140,8 @@ export declare class VPNDetection {
|
|
|
129
140
|
* error as its value, so one bad entry cannot lose the rest of the answers:
|
|
130
141
|
* the API reports a per-entry failure with the status the single lookup
|
|
131
142
|
* would have answered, and a chunk that fails as a whole marks every
|
|
132
|
-
* address in it.
|
|
143
|
+
* address in it. A per-call `concurrency` below 1 is refused as
|
|
144
|
+
* `bad_request` before anything is sent.
|
|
133
145
|
*/
|
|
134
146
|
lookupBatch(ips: Iterable<string>, options?: BatchOptions): Promise<Map<string, Result | VPNDetectionError>>;
|
|
135
147
|
private lookupChunk;
|
package/dist/client.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { LRUCache } from 'lru-cache';
|
|
2
2
|
import pLimit from 'p-limit';
|
|
3
|
-
import pRetry from 'p-retry';
|
|
4
3
|
import { createClient, createConfig } from './generated/client/index.js';
|
|
5
4
|
import { myEntitlement, databaseChecksum, databaseMetadata, downloadDatabase as downloadRedirect, listDatabases, listDownloads, lookupBatch, lookupIp, lookupMyIp, } from './generated/sdk.gen.js';
|
|
6
5
|
import { bogonResult, isBogon } from './bogon.js';
|
|
7
6
|
import { errorFromEntry, errorFromResponse, VPNDetectionError } from './errors.js';
|
|
7
|
+
import { OauthApi } from './oauth.js';
|
|
8
|
+
import { asError, deadline, unwrap, withRetry } from './transport.js';
|
|
8
9
|
import { DATABASE_FORMATS, toResult } from './types.js';
|
|
9
10
|
export const DEFAULT_BASE_URL = 'https://api.vpndetection.io';
|
|
10
11
|
// Matches the other SDKs, whose HTTP clients default to 30s. Node's global
|
|
@@ -28,6 +29,11 @@ export class VPNDetection {
|
|
|
28
29
|
timeoutMs;
|
|
29
30
|
/** The licensed dataset downloads, for keys that carry the `db.download` scope. */
|
|
30
31
|
database;
|
|
32
|
+
/**
|
|
33
|
+
* Sign a person in with the OAuth device flow, so a program on their own
|
|
34
|
+
* machine can be handed one of their API keys. Needs no API key.
|
|
35
|
+
*/
|
|
36
|
+
oauth;
|
|
31
37
|
constructor(options = {}) {
|
|
32
38
|
// Resolved once, because the download path calls object storage
|
|
33
39
|
// directly rather than through the generated client and has to reach
|
|
@@ -46,6 +52,7 @@ export class VPNDetection {
|
|
|
46
52
|
this.retries = options.retries ?? 2;
|
|
47
53
|
this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
48
54
|
this.database = new DatabaseApi(this.client, this.retries, this.timeoutMs, fetchImpl);
|
|
55
|
+
this.oauth = new OauthApi(this.client, this.retries, this.timeoutMs);
|
|
49
56
|
}
|
|
50
57
|
/**
|
|
51
58
|
* Whether an address is private, loopback, link-local, documentation,
|
|
@@ -143,9 +150,15 @@ export class VPNDetection {
|
|
|
143
150
|
* error as its value, so one bad entry cannot lose the rest of the answers:
|
|
144
151
|
* the API reports a per-entry failure with the status the single lookup
|
|
145
152
|
* would have answered, and a chunk that fails as a whole marks every
|
|
146
|
-
* address in it.
|
|
153
|
+
* address in it. A per-call `concurrency` below 1 is refused as
|
|
154
|
+
* `bad_request` before anything is sent.
|
|
147
155
|
*/
|
|
148
156
|
async lookupBatch(ips, options = {}) {
|
|
157
|
+
const concurrency = options.concurrency;
|
|
158
|
+
if (concurrency !== undefined && !(concurrency >= 1 && (Number.isInteger(concurrency)
|
|
159
|
+
|| concurrency === Infinity))) {
|
|
160
|
+
throw new VPNDetectionError('bad_request', `concurrency must be a whole number of at least 1, got ${concurrency}`);
|
|
161
|
+
}
|
|
149
162
|
const unique = [...new Set(ips)];
|
|
150
163
|
const out = new Map();
|
|
151
164
|
const pending = [];
|
|
@@ -163,9 +176,7 @@ export class VPNDetection {
|
|
|
163
176
|
}
|
|
164
177
|
// A per-call concurrency gets its own limiter; without one the call
|
|
165
178
|
// would share the instance's budget and silently ignore the override.
|
|
166
|
-
const limit =
|
|
167
|
-
? this.limit
|
|
168
|
-
: pLimit(options.concurrency);
|
|
179
|
+
const limit = concurrency === undefined ? this.limit : pLimit(concurrency);
|
|
169
180
|
const chunks = [];
|
|
170
181
|
for (let i = 0; i < pending.length; i += BATCH_MAX) {
|
|
171
182
|
chunks.push(pending.slice(i, i + BATCH_MAX));
|
|
@@ -271,8 +282,9 @@ export class DatabaseApi {
|
|
|
271
282
|
* and its absence answers nothing.
|
|
272
283
|
*/
|
|
273
284
|
async downloads(options = {}) {
|
|
285
|
+
const timeoutMs = options.timeoutMs ?? this.timeoutMs;
|
|
274
286
|
return withRetry(this.retries, async () => {
|
|
275
|
-
const res = await deadline(
|
|
287
|
+
const res = await deadline(timeoutMs, (signal) => listDownloads({
|
|
276
288
|
client: this.client,
|
|
277
289
|
...(options.limit === undefined ? {} : { query: { limit: options.limit } }),
|
|
278
290
|
signal: signal,
|
|
@@ -423,70 +435,4 @@ function assertFormat(format) {
|
|
|
423
435
|
}
|
|
424
436
|
throw new VPNDetectionError('bad_request', `invalid format ${JSON.stringify(format)}; must be one of ${DATABASE_FORMATS.join(', ')}`);
|
|
425
437
|
}
|
|
426
|
-
function unwrap(res) {
|
|
427
|
-
if (res.response === undefined) {
|
|
428
|
-
throw new VPNDetectionError('network', 'no response from the API');
|
|
429
|
-
}
|
|
430
|
-
if (!res.response.ok) {
|
|
431
|
-
throw errorFromResponse(res.response.status, res.response.headers, res.error ?? res.data);
|
|
432
|
-
}
|
|
433
|
-
return res.data;
|
|
434
|
-
}
|
|
435
|
-
// p-retry owns the backoff schedule; the extra sleep here is what honors a
|
|
436
|
-
// server-supplied Retry-After, which p-retry has no way to know about. A 429
|
|
437
|
-
// carrying that header is the only 429 worth retrying, which is why the wait
|
|
438
|
-
// and the retry decision both key off the same field.
|
|
439
|
-
/**
|
|
440
|
-
* Bound one attempt, and report an expiry as our own error rather than the
|
|
441
|
-
* runtime's `TimeoutError`, whose message says nothing about which call gave up.
|
|
442
|
-
*
|
|
443
|
-
* The signal is built per call, so a retried request gets a fresh budget - the
|
|
444
|
-
* same per-attempt semantics the Go and Python clients have.
|
|
445
|
-
*/
|
|
446
|
-
async function deadline(timeoutMs, fn) {
|
|
447
|
-
const controller = new AbortController();
|
|
448
|
-
let timer;
|
|
449
|
-
// Raced, not left to the signal alone: aborting releases the socket, but only
|
|
450
|
-
// a transport that HONORS the signal then settles, and a substituted `fetch`
|
|
451
|
-
// need not. Clearing the timer stops the losing side rejecting into nothing.
|
|
452
|
-
const expiry = new Promise((_, reject) => {
|
|
453
|
-
timer = setTimeout(() => {
|
|
454
|
-
controller.abort();
|
|
455
|
-
reject(new VPNDetectionError('network', `request timed out after ${timeoutMs}ms`));
|
|
456
|
-
}, timeoutMs);
|
|
457
|
-
});
|
|
458
|
-
try {
|
|
459
|
-
return await Promise.race([fn(controller.signal), expiry]);
|
|
460
|
-
}
|
|
461
|
-
finally {
|
|
462
|
-
clearTimeout(timer);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
async function withRetry(retries, fn) {
|
|
466
|
-
try {
|
|
467
|
-
return await pRetry(fn, {
|
|
468
|
-
retries: retries,
|
|
469
|
-
shouldRetry: ({ error }) => !(error instanceof VPNDetectionError) || error.retryable,
|
|
470
|
-
onFailedAttempt: async ({ error }) => {
|
|
471
|
-
const seconds = error instanceof VPNDetectionError ? error.retryAfterSeconds : undefined;
|
|
472
|
-
if (seconds !== undefined && seconds > 0) {
|
|
473
|
-
await new Promise((r) => setTimeout(r, seconds * 1000));
|
|
474
|
-
}
|
|
475
|
-
},
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
catch (err) {
|
|
479
|
-
throw asError(err);
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
function asError(err) {
|
|
483
|
-
if (err instanceof VPNDetectionError) {
|
|
484
|
-
return err;
|
|
485
|
-
}
|
|
486
|
-
const cause = err?.cause;
|
|
487
|
-
if (cause instanceof VPNDetectionError) {
|
|
488
|
-
return cause;
|
|
489
|
-
}
|
|
490
|
-
return new VPNDetectionError('network', err instanceof Error ? err.message : String(err));
|
|
491
|
-
}
|
|
492
438
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -16,6 +16,34 @@ export declare class VPNDetectionError extends Error {
|
|
|
16
16
|
/** Whether retrying this exact request could succeed. */
|
|
17
17
|
get retryable(): boolean;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* The authorization server refusing an OAuth request: a 4xx whose body names an
|
|
21
|
+
* OAuth error code. Never retryable as it stands.
|
|
22
|
+
*
|
|
23
|
+
* `kind` follows the status like any other failure's. A 401 here means the
|
|
24
|
+
* client ID is not registered, never the API key, which OAuth requests do not
|
|
25
|
+
* carry. The two codes a sign-in ends on have their own subclasses.
|
|
26
|
+
*/
|
|
27
|
+
export declare class OauthError extends VPNDetectionError {
|
|
28
|
+
/** The server's code, such as `authorization_pending` or `invalid_grant`, kept as sent. */
|
|
29
|
+
readonly errorCode: string;
|
|
30
|
+
/** The server's explanation, when it sent one. */
|
|
31
|
+
readonly errorDescription?: string;
|
|
32
|
+
constructor(errorCode: string, errorDescription?: string, status?: number);
|
|
33
|
+
get retryable(): boolean;
|
|
34
|
+
}
|
|
35
|
+
/** The person refused the sign-in. Its device code is spent, so a new attempt starts over. */
|
|
36
|
+
export declare class OauthAccessDeniedError extends OauthError {
|
|
37
|
+
constructor(errorDescription?: string, status?: number);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The device code is no longer valid: it expired, or was already used or
|
|
41
|
+
* refused. A poll that outlives the code raises this itself, with no `status`.
|
|
42
|
+
*/
|
|
43
|
+
export declare class OauthExpiredTokenError extends OauthError {
|
|
44
|
+
constructor(errorDescription?: string, status?: number);
|
|
45
|
+
}
|
|
46
|
+
export declare function oauthErrorFrom(errorCode: string, errorDescription: string | undefined, status: number): OauthError;
|
|
19
47
|
export declare function errorFromResponse(status: number, headers: {
|
|
20
48
|
get(name: string): string | null;
|
|
21
49
|
}, body: unknown): VPNDetectionError;
|
package/dist/errors.js
CHANGED
|
@@ -14,6 +14,56 @@ export class VPNDetectionError extends Error {
|
|
|
14
14
|
return this.kind === 'rate_limited' || this.kind === 'server_error' || this.kind === 'network';
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* The authorization server refusing an OAuth request: a 4xx whose body names an
|
|
19
|
+
* OAuth error code. Never retryable as it stands.
|
|
20
|
+
*
|
|
21
|
+
* `kind` follows the status like any other failure's. A 401 here means the
|
|
22
|
+
* client ID is not registered, never the API key, which OAuth requests do not
|
|
23
|
+
* carry. The two codes a sign-in ends on have their own subclasses.
|
|
24
|
+
*/
|
|
25
|
+
export class OauthError extends VPNDetectionError {
|
|
26
|
+
/** The server's code, such as `authorization_pending` or `invalid_grant`, kept as sent. */
|
|
27
|
+
errorCode;
|
|
28
|
+
/** The server's explanation, when it sent one. */
|
|
29
|
+
errorDescription;
|
|
30
|
+
constructor(errorCode, errorDescription, status) {
|
|
31
|
+
super(status === undefined ? 'bad_request' : errorFromResponse(status, NO_HEADERS, undefined).kind, errorDescription === undefined ? errorCode : `${errorCode}: ${errorDescription}`, status);
|
|
32
|
+
this.name = 'OauthError';
|
|
33
|
+
this.errorCode = errorCode;
|
|
34
|
+
this.errorDescription = errorDescription;
|
|
35
|
+
}
|
|
36
|
+
get retryable() {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** The person refused the sign-in. Its device code is spent, so a new attempt starts over. */
|
|
41
|
+
export class OauthAccessDeniedError extends OauthError {
|
|
42
|
+
constructor(errorDescription, status) {
|
|
43
|
+
super('access_denied', errorDescription, status);
|
|
44
|
+
this.name = 'OauthAccessDeniedError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The device code is no longer valid: it expired, or was already used or
|
|
49
|
+
* refused. A poll that outlives the code raises this itself, with no `status`.
|
|
50
|
+
*/
|
|
51
|
+
export class OauthExpiredTokenError extends OauthError {
|
|
52
|
+
constructor(errorDescription, status) {
|
|
53
|
+
super('expired_token', errorDescription, status);
|
|
54
|
+
this.name = 'OauthExpiredTokenError';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function oauthErrorFrom(errorCode, errorDescription, status) {
|
|
58
|
+
if (errorCode === 'access_denied') {
|
|
59
|
+
return new OauthAccessDeniedError(errorDescription, status);
|
|
60
|
+
}
|
|
61
|
+
if (errorCode === 'expired_token') {
|
|
62
|
+
return new OauthExpiredTokenError(errorDescription, status);
|
|
63
|
+
}
|
|
64
|
+
return new OauthError(errorCode, errorDescription, status);
|
|
65
|
+
}
|
|
66
|
+
const NO_HEADERS = { get: () => null };
|
|
17
67
|
export function errorFromResponse(status, headers, body) {
|
|
18
68
|
const message = messageOf(body) ?? `request failed with status ${status}`;
|
|
19
69
|
const retryAfter = parseRetryAfter(headers.get('retry-after'));
|
|
@@ -47,7 +97,7 @@ export function errorFromResponse(status, headers, body) {
|
|
|
47
97
|
* is a spent allowance, which is the only kind the API puts in an entry.
|
|
48
98
|
*/
|
|
49
99
|
export function errorFromEntry(entry) {
|
|
50
|
-
return errorFromResponse(entry.status,
|
|
100
|
+
return errorFromResponse(entry.status, NO_HEADERS, { error: entry.error });
|
|
51
101
|
}
|
|
52
102
|
// The two APIs behind this host answer with different envelopes: the lookup
|
|
53
103
|
// endpoint uses `error`, the database endpoints use `rc`. Both are read here so
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC/B,IAAI,CAAY;IAChB,MAAM,CAAU;IAChB,iBAAiB,CAAU;IAEpC,YAAY,IAAe,EAAE,OAAe,EAAE,MAAe,EAAE,iBAA0B;QACrF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;IAC/C,CAAC;IAED,yDAAyD;IACzD,IAAI,SAAS;QACT,OAAO,IAAI,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;IACnG,CAAC;CACJ;AAED,MAAM,UAAU,iBAAiB,CAC7B,MAAc,EAAE,OAA6C,EAAE,IAAa;IAE5E,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,8BAA8B,MAAM,EAAE,CAAC;IAC1E,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IAE/D,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,uEAAuE;QACvE,0CAA0C;QAC1C,OAAO,UAAU,KAAK,SAAS;YAC3B,CAAC,CAAC,IAAI,iBAAiB,CAAC,gBAAgB,EAAE,OAAO,EAAE,MAAM,CAAC;YAC1D,CAAC,CAAC,IAAI,iBAAiB,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,OAAO,IAAI,iBAAiB,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,OAAO,IAAI,iBAAiB,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,OAAO,IAAI,iBAAiB,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IACD,uEAAuE;IACvE,wEAAwE;IACxE,2EAA2E;IAC3E,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;QACf,OAAO,IAAI,iBAAiB,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,IAAI,iBAAiB,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAClE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAwC;IACnE,OAAO,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC/B,IAAI,CAAY;IAChB,MAAM,CAAU;IAChB,iBAAiB,CAAU;IAEpC,YAAY,IAAe,EAAE,OAAe,EAAE,MAAe,EAAE,iBAA0B;QACrF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;IAC/C,CAAC;IAED,yDAAyD;IACzD,IAAI,SAAS;QACT,OAAO,IAAI,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;IACnG,CAAC;CACJ;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,UAAW,SAAQ,iBAAiB;IAC7C,2FAA2F;IAClF,SAAS,CAAS;IAC3B,kDAAkD;IACzC,gBAAgB,CAAU;IAEnC,YAAY,SAAiB,EAAE,gBAAyB,EAAE,MAAe;QACrE,KAAK,CACD,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,IAAI,EAC5F,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,KAAK,gBAAgB,EAAE,EAChF,MAAM,CACT,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC7C,CAAC;IAED,IAAa,SAAS;QAClB,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ;AAED,8FAA8F;AAC9F,MAAM,OAAO,sBAAuB,SAAQ,UAAU;IAClD,YAAY,gBAAyB,EAAE,MAAe;QAClD,KAAK,CAAC,eAAe,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;QACjD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACzC,CAAC;CACJ;AAED;;;GAGG;AACH,MAAM,OAAO,sBAAuB,SAAQ,UAAU;IAClD,YAAY,gBAAyB,EAAE,MAAe;QAClD,KAAK,CAAC,eAAe,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;QACjD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACzC,CAAC;CACJ;AAED,MAAM,UAAU,cAAc,CAC1B,SAAiB,EAAE,gBAAoC,EAAE,MAAc;IAEvE,IAAI,SAAS,KAAK,eAAe,EAAE,CAAC;QAChC,OAAO,IAAI,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,SAAS,KAAK,eAAe,EAAE,CAAC;QAChC,OAAO,IAAI,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,SAAS,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;AAEvC,MAAM,UAAU,iBAAiB,CAC7B,MAAc,EAAE,OAA6C,EAAE,IAAa;IAE5E,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,8BAA8B,MAAM,EAAE,CAAC;IAC1E,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IAE/D,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,uEAAuE;QACvE,0CAA0C;QAC1C,OAAO,UAAU,KAAK,SAAS;YAC3B,CAAC,CAAC,IAAI,iBAAiB,CAAC,gBAAgB,EAAE,OAAO,EAAE,MAAM,CAAC;YAC1D,CAAC,CAAC,IAAI,iBAAiB,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,OAAO,IAAI,iBAAiB,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,OAAO,IAAI,iBAAiB,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,OAAO,IAAI,iBAAiB,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IACD,uEAAuE;IACvE,wEAAwE;IACxE,2EAA2E;IAC3E,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;QACf,OAAO,IAAI,iBAAiB,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,IAAI,iBAAiB,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAClE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAwC;IACnE,OAAO,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED,4EAA4E;AAC5E,gFAAgF;AAChF,iDAAiD;AACjD,SAAS,SAAS,CAAC,IAAa;IAC5B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC5C,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,MAAM,CAAC,GAAG,IAA+B,CAAC;IAC1C,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,CAAC,CAAC,KAAK,CAAC;IACnB,CAAC;IACD,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,CAAC,CAAC,EAAE,CAAC;IAChB,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,eAAe,CAAC,KAAoB;IACzC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACxC,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QAC3C,OAAO,OAAO,CAAC;IACnB,CAAC;IACD,wCAAwC;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -567,9 +567,14 @@ export type OauthMetadata = {
|
|
|
567
567
|
grant_types_supported?: Array<string>;
|
|
568
568
|
code_challenge_methods_supported?: Array<string>;
|
|
569
569
|
/**
|
|
570
|
-
*
|
|
570
|
+
* Always `none`. Every client is public and has no secret.
|
|
571
571
|
*/
|
|
572
|
-
|
|
572
|
+
token_endpoint_auth_methods_supported?: Array<string>;
|
|
573
|
+
/**
|
|
574
|
+
* RFC 9207. A redirect back from the authorization endpoint carries `iss`.
|
|
575
|
+
*/
|
|
576
|
+
authorization_response_iss_parameter_supported?: boolean;
|
|
577
|
+
service_documentation?: string;
|
|
573
578
|
};
|
|
574
579
|
export type DeviceAuthorizationRequest = {
|
|
575
580
|
client_id: string;
|
|
@@ -596,6 +601,9 @@ export type DeviceAuthorization = {
|
|
|
596
601
|
* The same page with the code already filled in.
|
|
597
602
|
*/
|
|
598
603
|
verification_uri_complete?: string;
|
|
604
|
+
/**
|
|
605
|
+
* Seconds until both codes expire.
|
|
606
|
+
*/
|
|
599
607
|
expires_in: number;
|
|
600
608
|
/**
|
|
601
609
|
* Seconds between polls.
|
|
@@ -603,26 +611,77 @@ export type DeviceAuthorization = {
|
|
|
603
611
|
interval: number;
|
|
604
612
|
};
|
|
605
613
|
export type TokenRequest = {
|
|
614
|
+
/**
|
|
615
|
+
* `urn:ietf:params:oauth:grant-type:device_code`, `authorization_code` or `refresh_token`.
|
|
616
|
+
*/
|
|
606
617
|
grant_type: string;
|
|
607
618
|
client_id: string;
|
|
619
|
+
/**
|
|
620
|
+
* Required by the device code grant.
|
|
621
|
+
*/
|
|
608
622
|
device_code?: string;
|
|
623
|
+
/**
|
|
624
|
+
* Required by the authorization code grant.
|
|
625
|
+
*/
|
|
609
626
|
code?: string;
|
|
627
|
+
/**
|
|
628
|
+
* Required by the authorization code grant.
|
|
629
|
+
*/
|
|
610
630
|
code_verifier?: string;
|
|
631
|
+
/**
|
|
632
|
+
* Authorization code grant: the `redirect_uri` the code was issued against, exactly.
|
|
633
|
+
*/
|
|
611
634
|
redirect_uri?: string;
|
|
635
|
+
/**
|
|
636
|
+
* Required by the refresh token grant.
|
|
637
|
+
*/
|
|
612
638
|
refresh_token?: string;
|
|
613
639
|
};
|
|
614
640
|
export type TokenResponse = {
|
|
615
641
|
access_token: string;
|
|
642
|
+
/**
|
|
643
|
+
* Always `Bearer`.
|
|
644
|
+
*/
|
|
616
645
|
token_type: string;
|
|
646
|
+
/**
|
|
647
|
+
* Seconds until the access token expires.
|
|
648
|
+
*/
|
|
617
649
|
expires_in: number;
|
|
650
|
+
/**
|
|
651
|
+
* Always returned. A refresh consumes the token it presents, so keep this one.
|
|
652
|
+
*/
|
|
618
653
|
refresh_token?: string;
|
|
619
654
|
/**
|
|
620
655
|
* What was actually granted, which may be narrower than what was asked for.
|
|
621
656
|
*/
|
|
622
657
|
scope?: string;
|
|
658
|
+
/**
|
|
659
|
+
* Not part of OAuth. The ID of the API key the person picked when they
|
|
660
|
+
* approved, returned by every grant while this authorization may still
|
|
661
|
+
* read that key back. Absent when no key was picked, or when the
|
|
662
|
+
* person's role no longer allows reading keys back.
|
|
663
|
+
*
|
|
664
|
+
*/
|
|
665
|
+
'mslm:apikey_id'?: string;
|
|
666
|
+
/**
|
|
667
|
+
* Not part of OAuth. The API key itself, so a device ends up holding an
|
|
668
|
+
* ordinary key. Returned by the device code and authorization code
|
|
669
|
+
* grants only, never by a refresh, and only alongside
|
|
670
|
+
* `mslm:apikey_id`. Absent when that key's secret cannot be read back,
|
|
671
|
+
* which is the case for a key created before keys could be shown again
|
|
672
|
+
* in the console; a rotated key can be.
|
|
673
|
+
*
|
|
674
|
+
*/
|
|
675
|
+
'mslm:apikey'?: string;
|
|
623
676
|
};
|
|
624
677
|
export type RevokeRequest = {
|
|
678
|
+
/**
|
|
679
|
+
* An access token or a refresh token.
|
|
680
|
+
*/
|
|
625
681
|
token: string;
|
|
682
|
+
/**
|
|
683
|
+
* Accepted and not checked.
|
|
684
|
+
*/
|
|
626
685
|
client_id?: string;
|
|
627
686
|
};
|
|
628
687
|
export type OauthError = {
|
|
@@ -907,6 +966,9 @@ export type ListDownloadsData = {
|
|
|
907
966
|
body?: never;
|
|
908
967
|
path?: never;
|
|
909
968
|
query?: {
|
|
969
|
+
/**
|
|
970
|
+
* How many attempts to return. Clamped to 1 through 200.
|
|
971
|
+
*/
|
|
910
972
|
limit?: number;
|
|
911
973
|
};
|
|
912
974
|
url: '/api/v1/database/downloads';
|
|
@@ -1222,11 +1284,16 @@ export type OauthDeviceAuthorizationData = {
|
|
|
1222
1284
|
};
|
|
1223
1285
|
export type OauthDeviceAuthorizationErrors = {
|
|
1224
1286
|
/**
|
|
1225
|
-
* `invalid_request`, `
|
|
1226
|
-
* `slow_down` when this address has started too
|
|
1287
|
+
* `invalid_request`, `unauthorized_client` when the client may not use
|
|
1288
|
+
* the device flow, or `slow_down` when this address has started too
|
|
1289
|
+
* many authorizations.
|
|
1227
1290
|
*
|
|
1228
1291
|
*/
|
|
1229
1292
|
400: OauthError;
|
|
1293
|
+
/**
|
|
1294
|
+
* `invalid_client`: the `client_id` is not registered.
|
|
1295
|
+
*/
|
|
1296
|
+
401: OauthError;
|
|
1230
1297
|
};
|
|
1231
1298
|
export type OauthDeviceAuthorizationError = OauthDeviceAuthorizationErrors[keyof OauthDeviceAuthorizationErrors];
|
|
1232
1299
|
export type OauthDeviceAuthorizationResponses = {
|
|
@@ -1276,9 +1343,18 @@ export type OauthTokenErrors = {
|
|
|
1276
1343
|
/**
|
|
1277
1344
|
* An RFC 6749 error. `authorization_pending` and `slow_down` are
|
|
1278
1345
|
* normal answers while polling a device authorization, not failures.
|
|
1346
|
+
* `access_denied` means the person refused, and `expired_token` that
|
|
1347
|
+
* the device code is no longer valid: it expired, or it was already
|
|
1348
|
+
* exchanged or refused. `invalid_grant` means the code, device code or
|
|
1349
|
+
* refresh token is not valid for this `client_id`. `slow_down` also
|
|
1350
|
+
* answers any grant when this address sends too many requests.
|
|
1279
1351
|
*
|
|
1280
1352
|
*/
|
|
1281
1353
|
400: OauthError;
|
|
1354
|
+
/**
|
|
1355
|
+
* `invalid_client`: the `client_id` is not registered.
|
|
1356
|
+
*/
|
|
1357
|
+
401: OauthError;
|
|
1282
1358
|
};
|
|
1283
1359
|
export type OauthTokenError = OauthTokenErrors[keyof OauthTokenErrors];
|
|
1284
1360
|
export type OauthTokenResponses = {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { VPNDetection, DatabaseApi, DEFAULT_BASE_URL } from './client.js';
|
|
2
2
|
export type { Options, CacheOptions, LookupOptions, BatchOptions, DownloadsOptions, DownloadDestination, } from './client.js';
|
|
3
|
+
export { OauthApi } from './oauth.js';
|
|
4
|
+
export type { OauthOptions, DeviceAuthorizationOptions, PollDeviceTokenOptions, OauthMetadata, DeviceAuthorization, TokenResponse, } from './oauth.js';
|
|
3
5
|
export { isBogon } from './bogon.js';
|
|
4
|
-
export { VPNDetectionError } from './errors.js';
|
|
6
|
+
export { VPNDetectionError, OauthError, OauthAccessDeniedError, OauthExpiredTokenError, } from './errors.js';
|
|
5
7
|
export type { ErrorKind } from './errors.js';
|
|
6
8
|
export type { Result, VpnDetail, ClassDetail, ProxyDetail, LookupResponse, } from './types.js';
|
|
7
9
|
export { DATABASE_FORMATS, STANDINGS, LICENSE_TYPES } from './types.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { VPNDetection, DatabaseApi, DEFAULT_BASE_URL } from './client.js';
|
|
2
|
+
export { OauthApi } from './oauth.js';
|
|
2
3
|
export { isBogon } from './bogon.js';
|
|
3
|
-
export { VPNDetectionError } from './errors.js';
|
|
4
|
+
export { VPNDetectionError, OauthError, OauthAccessDeniedError, OauthExpiredTokenError, } from './errors.js';
|
|
4
5
|
export { DATABASE_FORMATS, STANDINGS, LICENSE_TYPES } from './types.js';
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK1E,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK1E,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKtC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EACH,iBAAiB,EAAE,UAAU,EAAE,sBAAsB,EAAE,sBAAsB,GAChF,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/oauth.d.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { Client } from './generated/client/index.js';
|
|
2
|
+
/** Per-call overrides for one OAuth request. Anything omitted falls back to the client's setting. */
|
|
3
|
+
export interface OauthOptions {
|
|
4
|
+
/** How long one attempt may take before it is abandoned, in milliseconds. */
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
}
|
|
7
|
+
/** What a device sign-in asks for. A member left out is left out of the request, never sent empty. */
|
|
8
|
+
export interface DeviceAuthorizationOptions extends OauthOptions {
|
|
9
|
+
/** Space-delimited scopes, sent as given. The server narrows them to what the client may ask for. */
|
|
10
|
+
scope?: string;
|
|
11
|
+
/** The API the tokens are meant for. */
|
|
12
|
+
resource?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface PollDeviceTokenOptions {
|
|
15
|
+
/** How long EACH request of the poll may take, in milliseconds. Never bounds the poll as a whole. */
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
/** Aborting it stops the wait and any request in flight, and the poll rejects with its reason. */
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
}
|
|
20
|
+
/** The authorization server's discovery document. No call here needs it: each builds on the base URL. */
|
|
21
|
+
export interface OauthMetadata {
|
|
22
|
+
issuer: string;
|
|
23
|
+
authorization_endpoint: string;
|
|
24
|
+
token_endpoint: string;
|
|
25
|
+
device_authorization_endpoint?: string;
|
|
26
|
+
revocation_endpoint?: string;
|
|
27
|
+
scopes_supported?: string[];
|
|
28
|
+
response_types_supported?: string[];
|
|
29
|
+
grant_types_supported?: string[];
|
|
30
|
+
code_challenge_methods_supported?: string[];
|
|
31
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
32
|
+
authorization_response_iss_parameter_supported?: boolean;
|
|
33
|
+
service_documentation?: string;
|
|
34
|
+
}
|
|
35
|
+
/** A started device sign-in. `expires_in` and `interval` are seconds. */
|
|
36
|
+
export interface DeviceAuthorization {
|
|
37
|
+
device_code: string;
|
|
38
|
+
/** What the person types in at `verification_uri`. */
|
|
39
|
+
user_code: string;
|
|
40
|
+
verification_uri: string;
|
|
41
|
+
/** `verification_uri` with the code already in it, for a program that can open a browser. */
|
|
42
|
+
verification_uri_complete?: string;
|
|
43
|
+
expires_in: number;
|
|
44
|
+
interval: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* What a completed sign-in or a refresh hands back.
|
|
48
|
+
*
|
|
49
|
+
* `apikey_id` is set when the person picked one of their API keys and may still
|
|
50
|
+
* read it back. `apikey`, the key itself, also needs a sign-in rather than a
|
|
51
|
+
* refresh and a key whose secret can be shown again, so `apikey_id` without
|
|
52
|
+
* `apikey` is normal. An empty `scope` is present.
|
|
53
|
+
*/
|
|
54
|
+
export interface TokenResponse {
|
|
55
|
+
access_token: string;
|
|
56
|
+
token_type: string;
|
|
57
|
+
expires_in: number;
|
|
58
|
+
/** Spent by the refresh that presents it, so keep the one each refresh returns. */
|
|
59
|
+
refresh_token?: string;
|
|
60
|
+
scope?: string;
|
|
61
|
+
apikey_id?: string;
|
|
62
|
+
apikey?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Signs a person in on their own machine with the OAuth device flow, so a
|
|
66
|
+
* program can be handed one of their API keys instead of asking them to paste
|
|
67
|
+
* it. Reached through `client.oauth`.
|
|
68
|
+
*
|
|
69
|
+
* Every call takes a client ID, issued on request from support@vpndetection.io.
|
|
70
|
+
* None of these requests carries the client's API key, and none needs one.
|
|
71
|
+
*/
|
|
72
|
+
export declare class OauthApi {
|
|
73
|
+
private readonly client;
|
|
74
|
+
private readonly retries;
|
|
75
|
+
private readonly timeoutMs;
|
|
76
|
+
private clock;
|
|
77
|
+
constructor(client: Client, retries: number, timeoutMs: number);
|
|
78
|
+
metadata(options?: OauthOptions): Promise<OauthMetadata>;
|
|
79
|
+
/**
|
|
80
|
+
* Start a device sign-in: show the person `user_code` and `verification_uri`,
|
|
81
|
+
* then hand the answer to `pollDeviceToken`. It consumes nothing, so it is
|
|
82
|
+
* retried like a lookup; a refusal such as `slow_down` is an `OauthError`.
|
|
83
|
+
*/
|
|
84
|
+
deviceAuthorization(clientId: string, options?: DeviceAuthorizationOptions): Promise<DeviceAuthorization>;
|
|
85
|
+
/**
|
|
86
|
+
* Ask once whether the person has approved a device sign-in. Until they do,
|
|
87
|
+
* it rejects with an `OauthError` coded `authorization_pending`;
|
|
88
|
+
* `pollDeviceToken` is the loop around it.
|
|
89
|
+
*
|
|
90
|
+
* Never retried: an approved code is spent by the answer carrying the tokens,
|
|
91
|
+
* so a retry after a lost response could only lose them.
|
|
92
|
+
*/
|
|
93
|
+
exchangeDeviceCode(clientId: string, deviceCode: string, options?: OauthOptions): Promise<TokenResponse>;
|
|
94
|
+
/**
|
|
95
|
+
* Trade a refresh token for a new pair. The old one is spent whatever happens
|
|
96
|
+
* next, so this is never retried. A refresh names the key the person picked
|
|
97
|
+
* (`apikey_id`) but never reveals it again (`apikey`).
|
|
98
|
+
*/
|
|
99
|
+
exchangeRefreshToken(clientId: string, refreshToken: string, options?: OauthOptions): Promise<TokenResponse>;
|
|
100
|
+
/**
|
|
101
|
+
* End a token. A refresh token ends the whole sign-in and every token it
|
|
102
|
+
* issued, which is how a program signs the machine out; an access token ends
|
|
103
|
+
* only itself. The server answers the same for any token, known or not.
|
|
104
|
+
*/
|
|
105
|
+
revoke(clientId: string, token: string, options?: OauthOptions): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Wait for the person to approve a device sign-in, and return its tokens.
|
|
108
|
+
*
|
|
109
|
+
* Waits `device.interval` seconds (5 when that is below 1) before EVERY
|
|
110
|
+
* request, the first included, and 5 more for the rest of the call each time
|
|
111
|
+
* the server answers `slow_down`. Ends at the first answer that is neither:
|
|
112
|
+
* a denial rejects with `OauthAccessDeniedError`, a code that ran out with
|
|
113
|
+
* `OauthExpiredTokenError` - as does outliving `device.expires_in`, counted
|
|
114
|
+
* from this call, with no `status` - and any other failure as it came.
|
|
115
|
+
*/
|
|
116
|
+
pollDeviceToken(clientId: string, device: DeviceAuthorization, options?: PollDeviceTokenOptions): Promise<TokenResponse>;
|
|
117
|
+
private exchange;
|
|
118
|
+
}
|
package/dist/oauth.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { oauthDeviceAuthorization, oauthMetadata, oauthRevoke, oauthToken, } from './generated/sdk.gen.js';
|
|
2
|
+
import { errorFromResponse, OauthError, oauthErrorFrom, OauthExpiredTokenError, VPNDetectionError, } from './errors.js';
|
|
3
|
+
import { asError, deadline, withRetry } from './transport.js';
|
|
4
|
+
/**
|
|
5
|
+
* Signs a person in on their own machine with the OAuth device flow, so a
|
|
6
|
+
* program can be handed one of their API keys instead of asking them to paste
|
|
7
|
+
* it. Reached through `client.oauth`.
|
|
8
|
+
*
|
|
9
|
+
* Every call takes a client ID, issued on request from support@vpndetection.io.
|
|
10
|
+
* None of these requests carries the client's API key, and none needs one.
|
|
11
|
+
*/
|
|
12
|
+
export class OauthApi {
|
|
13
|
+
client;
|
|
14
|
+
retries;
|
|
15
|
+
timeoutMs;
|
|
16
|
+
// The poll's wait and its deadline, which tests replace together.
|
|
17
|
+
clock = { now: () => performance.now(), sleep: sleep };
|
|
18
|
+
constructor(client, retries, timeoutMs) {
|
|
19
|
+
this.client = client;
|
|
20
|
+
this.retries = retries;
|
|
21
|
+
this.timeoutMs = timeoutMs;
|
|
22
|
+
}
|
|
23
|
+
async metadata(options = {}) {
|
|
24
|
+
return withRetry(this.retries, async () => {
|
|
25
|
+
const res = await deadline(options.timeoutMs ?? this.timeoutMs, (signal) => oauthMetadata({
|
|
26
|
+
client: this.client, signal: signal,
|
|
27
|
+
}));
|
|
28
|
+
return decode(res, METADATA);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Start a device sign-in: show the person `user_code` and `verification_uri`,
|
|
33
|
+
* then hand the answer to `pollDeviceToken`. It consumes nothing, so it is
|
|
34
|
+
* retried like a lookup; a refusal such as `slow_down` is an `OauthError`.
|
|
35
|
+
*/
|
|
36
|
+
async deviceAuthorization(clientId, options = {}) {
|
|
37
|
+
const body = {
|
|
38
|
+
client_id: clientId,
|
|
39
|
+
scope: options.scope || undefined,
|
|
40
|
+
resource: options.resource || undefined,
|
|
41
|
+
};
|
|
42
|
+
const timeoutMs = options.timeoutMs ?? this.timeoutMs;
|
|
43
|
+
return withRetry(this.retries, async () => {
|
|
44
|
+
const res = await deadline(timeoutMs, (signal) => oauthDeviceAuthorization({
|
|
45
|
+
client: this.client, body: body, signal: signal,
|
|
46
|
+
}));
|
|
47
|
+
return decode(res, DEVICE_AUTHORIZATION);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Ask once whether the person has approved a device sign-in. Until they do,
|
|
52
|
+
* it rejects with an `OauthError` coded `authorization_pending`;
|
|
53
|
+
* `pollDeviceToken` is the loop around it.
|
|
54
|
+
*
|
|
55
|
+
* Never retried: an approved code is spent by the answer carrying the tokens,
|
|
56
|
+
* so a retry after a lost response could only lose them.
|
|
57
|
+
*/
|
|
58
|
+
async exchangeDeviceCode(clientId, deviceCode, options = {}) {
|
|
59
|
+
return this.exchange({
|
|
60
|
+
grant_type: DEVICE_CODE_GRANT, device_code: deviceCode, client_id: clientId,
|
|
61
|
+
}, options.timeoutMs);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Trade a refresh token for a new pair. The old one is spent whatever happens
|
|
65
|
+
* next, so this is never retried. A refresh names the key the person picked
|
|
66
|
+
* (`apikey_id`) but never reveals it again (`apikey`).
|
|
67
|
+
*/
|
|
68
|
+
async exchangeRefreshToken(clientId, refreshToken, options = {}) {
|
|
69
|
+
return this.exchange({
|
|
70
|
+
grant_type: 'refresh_token', refresh_token: refreshToken, client_id: clientId,
|
|
71
|
+
}, options.timeoutMs);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* End a token. A refresh token ends the whole sign-in and every token it
|
|
75
|
+
* issued, which is how a program signs the machine out; an access token ends
|
|
76
|
+
* only itself. The server answers the same for any token, known or not.
|
|
77
|
+
*/
|
|
78
|
+
async revoke(clientId, token, options = {}) {
|
|
79
|
+
await withRetry(this.retries, async () => {
|
|
80
|
+
const res = await deadline(options.timeoutMs ?? this.timeoutMs, (signal) => oauthRevoke({
|
|
81
|
+
client: this.client,
|
|
82
|
+
body: { token: token, client_id: clientId },
|
|
83
|
+
// The answer says nothing, so it is read as text and dropped rather than parsed.
|
|
84
|
+
parseAs: 'text',
|
|
85
|
+
signal: signal,
|
|
86
|
+
}));
|
|
87
|
+
throwIfFailed(res);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Wait for the person to approve a device sign-in, and return its tokens.
|
|
92
|
+
*
|
|
93
|
+
* Waits `device.interval` seconds (5 when that is below 1) before EVERY
|
|
94
|
+
* request, the first included, and 5 more for the rest of the call each time
|
|
95
|
+
* the server answers `slow_down`. Ends at the first answer that is neither:
|
|
96
|
+
* a denial rejects with `OauthAccessDeniedError`, a code that ran out with
|
|
97
|
+
* `OauthExpiredTokenError` - as does outliving `device.expires_in`, counted
|
|
98
|
+
* from this call, with no `status` - and any other failure as it came.
|
|
99
|
+
*/
|
|
100
|
+
async pollDeviceToken(clientId, device, options = {}) {
|
|
101
|
+
let interval = device.interval >= 1 ? device.interval : 5;
|
|
102
|
+
const expires = this.clock.now() + device.expires_in * 1000;
|
|
103
|
+
for (;;) {
|
|
104
|
+
await this.clock.sleep(interval * 1000, options.signal);
|
|
105
|
+
if (this.clock.now() >= expires) {
|
|
106
|
+
throw new OauthExpiredTokenError();
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
return await this.exchange({
|
|
110
|
+
grant_type: DEVICE_CODE_GRANT, device_code: device.device_code, client_id: clientId,
|
|
111
|
+
}, options.timeoutMs, options.signal);
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
if (!(err instanceof OauthError)) {
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
// RFC 8628: slow_down widens the interval for every later request, not just the next.
|
|
118
|
+
if (err.errorCode === 'slow_down') {
|
|
119
|
+
interval += 5;
|
|
120
|
+
}
|
|
121
|
+
else if (err.errorCode !== 'authorization_pending') {
|
|
122
|
+
throw err;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async exchange(form, timeoutMs, cancel) {
|
|
128
|
+
const res = await deadline(timeoutMs ?? this.timeoutMs, (signal) => oauthToken({
|
|
129
|
+
client: this.client, body: form, signal: signal,
|
|
130
|
+
}), cancel);
|
|
131
|
+
return decode(res, TOKEN_RESPONSE);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const DEVICE_CODE_GRANT = 'urn:ietf:params:oauth:grant-type:device_code';
|
|
135
|
+
const METADATA = {
|
|
136
|
+
issuer: { type: 'string', required: true },
|
|
137
|
+
authorization_endpoint: { type: 'string', required: true },
|
|
138
|
+
token_endpoint: { type: 'string', required: true },
|
|
139
|
+
device_authorization_endpoint: { type: 'string' },
|
|
140
|
+
revocation_endpoint: { type: 'string' },
|
|
141
|
+
scopes_supported: { type: 'string[]' },
|
|
142
|
+
response_types_supported: { type: 'string[]' },
|
|
143
|
+
grant_types_supported: { type: 'string[]' },
|
|
144
|
+
code_challenge_methods_supported: { type: 'string[]' },
|
|
145
|
+
token_endpoint_auth_methods_supported: { type: 'string[]' },
|
|
146
|
+
authorization_response_iss_parameter_supported: { type: 'boolean' },
|
|
147
|
+
service_documentation: { type: 'string' },
|
|
148
|
+
};
|
|
149
|
+
const DEVICE_AUTHORIZATION = {
|
|
150
|
+
device_code: { type: 'string', required: true },
|
|
151
|
+
user_code: { type: 'string', required: true },
|
|
152
|
+
verification_uri: { type: 'string', required: true },
|
|
153
|
+
verification_uri_complete: { type: 'string' },
|
|
154
|
+
expires_in: { type: 'number', required: true },
|
|
155
|
+
interval: { type: 'number', required: true },
|
|
156
|
+
};
|
|
157
|
+
const TOKEN_RESPONSE = {
|
|
158
|
+
access_token: { type: 'string', required: true },
|
|
159
|
+
token_type: { type: 'string', required: true },
|
|
160
|
+
expires_in: { type: 'number', required: true },
|
|
161
|
+
refresh_token: { type: 'string' },
|
|
162
|
+
scope: { type: 'string' },
|
|
163
|
+
apikey_id: { type: 'string', wire: 'mslm:apikey_id' },
|
|
164
|
+
apikey: { type: 'string', wire: 'mslm:apikey' },
|
|
165
|
+
};
|
|
166
|
+
// Only the declared members are copied, on PRESENCE, so an absent one stays
|
|
167
|
+
// absent and an empty `scope` stays present. Anything else the server sends is
|
|
168
|
+
// dropped rather than surfaced untyped.
|
|
169
|
+
function decode(res, members) {
|
|
170
|
+
const status = throwIfFailed(res).status;
|
|
171
|
+
if (res.error !== undefined) {
|
|
172
|
+
// A 2xx the generated client could not parse, which reports it here.
|
|
173
|
+
throw asError(res.error);
|
|
174
|
+
}
|
|
175
|
+
const body = res.data;
|
|
176
|
+
if (!isObject(body)) {
|
|
177
|
+
throw new VPNDetectionError('server_error', 'the answer was not a JSON object', status);
|
|
178
|
+
}
|
|
179
|
+
const out = {};
|
|
180
|
+
for (const [name, member] of Object.entries(members)) {
|
|
181
|
+
const wire = member.wire ?? name;
|
|
182
|
+
const value = body[wire];
|
|
183
|
+
if (value === undefined || value === null) {
|
|
184
|
+
if (member.required) {
|
|
185
|
+
throw new VPNDetectionError('server_error', `the answer carried no ${wire}`, status);
|
|
186
|
+
}
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (!hasType(value, member.type)) {
|
|
190
|
+
throw new VPNDetectionError('server_error', `the answer's ${wire} is not a ${member.type}`, status);
|
|
191
|
+
}
|
|
192
|
+
out[name] = value;
|
|
193
|
+
}
|
|
194
|
+
return out;
|
|
195
|
+
}
|
|
196
|
+
// Only a 4xx whose body is a JSON object with a STRING `error` is an OAuth
|
|
197
|
+
// refusal. Every 5xx, whatever it says, is the server failing, and is retried
|
|
198
|
+
// wherever the operation retries.
|
|
199
|
+
function throwIfFailed(res) {
|
|
200
|
+
if (res.response === undefined) {
|
|
201
|
+
throw new VPNDetectionError('network', 'no response from the API');
|
|
202
|
+
}
|
|
203
|
+
const { status, ok, headers } = res.response;
|
|
204
|
+
if (ok) {
|
|
205
|
+
return res.response;
|
|
206
|
+
}
|
|
207
|
+
const body = res.error;
|
|
208
|
+
if (status >= 400 && status < 500 && isObject(body) && typeof body.error === 'string') {
|
|
209
|
+
const description = typeof body.error_description === 'string' ? body.error_description : undefined;
|
|
210
|
+
throw oauthErrorFrom(body.error, description, status);
|
|
211
|
+
}
|
|
212
|
+
throw errorFromResponse(status, headers, body);
|
|
213
|
+
}
|
|
214
|
+
function isObject(value) {
|
|
215
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
216
|
+
}
|
|
217
|
+
function hasType(value, type) {
|
|
218
|
+
if (type === 'string[]') {
|
|
219
|
+
return Array.isArray(value) && value.every((item) => typeof item === 'string');
|
|
220
|
+
}
|
|
221
|
+
return typeof value === type;
|
|
222
|
+
}
|
|
223
|
+
function sleep(ms, signal) {
|
|
224
|
+
return new Promise((resolve, reject) => {
|
|
225
|
+
if (signal?.aborted) {
|
|
226
|
+
reject(signal.reason);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const onAbort = () => {
|
|
230
|
+
clearTimeout(timer);
|
|
231
|
+
reject(signal?.reason);
|
|
232
|
+
};
|
|
233
|
+
const timer = setTimeout(() => {
|
|
234
|
+
signal?.removeEventListener('abort', onAbort);
|
|
235
|
+
resolve();
|
|
236
|
+
}, ms);
|
|
237
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { VPNDetectionError } from './errors.js';
|
|
2
|
+
export interface Res {
|
|
3
|
+
data?: unknown;
|
|
4
|
+
error?: unknown;
|
|
5
|
+
response?: Response;
|
|
6
|
+
}
|
|
7
|
+
export declare function unwrap<T>(res: Res): T;
|
|
8
|
+
/**
|
|
9
|
+
* Bound one attempt, and report an expiry as our own error rather than the
|
|
10
|
+
* runtime's `TimeoutError`, whose message says nothing about which call gave up.
|
|
11
|
+
*
|
|
12
|
+
* The signal is built per call, so a retried request gets a fresh budget - the
|
|
13
|
+
* same per-attempt semantics the Go and Python clients have. Aborting `cancel`
|
|
14
|
+
* ends the attempt at once, rejecting with its reason.
|
|
15
|
+
*/
|
|
16
|
+
export declare function deadline<T>(timeoutMs: number, fn: (signal: AbortSignal) => Promise<T>, cancel?: AbortSignal): Promise<T>;
|
|
17
|
+
export declare function withRetry<T>(retries: number, fn: () => Promise<T>): Promise<T>;
|
|
18
|
+
export declare function asError(err: unknown): VPNDetectionError;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import pRetry from 'p-retry';
|
|
2
|
+
import { errorFromResponse, VPNDetectionError } from './errors.js';
|
|
3
|
+
export function unwrap(res) {
|
|
4
|
+
if (res.response === undefined) {
|
|
5
|
+
throw new VPNDetectionError('network', 'no response from the API');
|
|
6
|
+
}
|
|
7
|
+
if (!res.response.ok) {
|
|
8
|
+
throw errorFromResponse(res.response.status, res.response.headers, res.error ?? res.data);
|
|
9
|
+
}
|
|
10
|
+
return res.data;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Bound one attempt, and report an expiry as our own error rather than the
|
|
14
|
+
* runtime's `TimeoutError`, whose message says nothing about which call gave up.
|
|
15
|
+
*
|
|
16
|
+
* The signal is built per call, so a retried request gets a fresh budget - the
|
|
17
|
+
* same per-attempt semantics the Go and Python clients have. Aborting `cancel`
|
|
18
|
+
* ends the attempt at once, rejecting with its reason.
|
|
19
|
+
*/
|
|
20
|
+
export async function deadline(timeoutMs, fn, cancel) {
|
|
21
|
+
cancel?.throwIfAborted();
|
|
22
|
+
const controller = new AbortController();
|
|
23
|
+
let timer;
|
|
24
|
+
let stop;
|
|
25
|
+
// Raced, not left to the signal alone: aborting releases the socket, but only
|
|
26
|
+
// a transport that HONORS the signal then settles, and a substituted `fetch`
|
|
27
|
+
// need not. Clearing the timer stops the losing side rejecting into nothing.
|
|
28
|
+
const expiry = new Promise((_, reject) => {
|
|
29
|
+
timer = setTimeout(() => {
|
|
30
|
+
controller.abort();
|
|
31
|
+
reject(new VPNDetectionError('network', `request timed out after ${timeoutMs}ms`));
|
|
32
|
+
}, timeoutMs);
|
|
33
|
+
if (cancel !== undefined) {
|
|
34
|
+
stop = () => {
|
|
35
|
+
controller.abort(cancel.reason);
|
|
36
|
+
reject(cancel.reason);
|
|
37
|
+
};
|
|
38
|
+
cancel.addEventListener('abort', stop, { once: true });
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
try {
|
|
42
|
+
return await Promise.race([fn(controller.signal), expiry]);
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
clearTimeout(timer);
|
|
46
|
+
if (stop !== undefined) {
|
|
47
|
+
cancel?.removeEventListener('abort', stop);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// p-retry owns the backoff schedule; the extra sleep here is what honors a
|
|
52
|
+
// server-supplied Retry-After, which p-retry has no way to know about. A 429
|
|
53
|
+
// carrying that header is the only 429 worth retrying, which is why the wait
|
|
54
|
+
// and the retry decision both key off the same field.
|
|
55
|
+
export async function withRetry(retries, fn) {
|
|
56
|
+
try {
|
|
57
|
+
return await pRetry(fn, {
|
|
58
|
+
retries: retries,
|
|
59
|
+
shouldRetry: ({ error }) => !(error instanceof VPNDetectionError) || error.retryable,
|
|
60
|
+
onFailedAttempt: async ({ error }) => {
|
|
61
|
+
const seconds = error instanceof VPNDetectionError ? error.retryAfterSeconds : undefined;
|
|
62
|
+
if (seconds !== undefined && seconds > 0) {
|
|
63
|
+
await new Promise((r) => setTimeout(r, seconds * 1000));
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
throw asError(err);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export function asError(err) {
|
|
73
|
+
if (err instanceof VPNDetectionError) {
|
|
74
|
+
return err;
|
|
75
|
+
}
|
|
76
|
+
const cause = err?.cause;
|
|
77
|
+
if (cause instanceof VPNDetectionError) {
|
|
78
|
+
return cause;
|
|
79
|
+
}
|
|
80
|
+
return new VPNDetectionError('network', err instanceof Error ? err.message : String(err));
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|