@apifuse/provider-sdk 2.2.0-beta.31 → 2.2.0-beta.33
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/CHANGELOG.md +9 -0
- package/dist/error-resolution.js +0 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/provider.d.ts +1 -1
- package/dist/provider.js +1 -1
- package/dist/runtime/browser.d.ts +1 -0
- package/dist/runtime/browser.js +344 -27
- package/dist/runtime/choice.d.ts +0 -1
- package/dist/runtime/choice.js +1 -78
- package/dist/runtime/resolver-vendors/browser.d.ts +2 -0
- package/dist/runtime/resolver-vendors/browser.js +68 -16
- package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
- package/dist/runtime/resolver-vendors/capsolver.js +526 -0
- package/dist/runtime/resolver-vendors/twocaptcha.js +46 -13
- package/dist/runtime/resolver-vendors/types.d.ts +1 -1
- package/dist/runtime/resolver-vendors/types.js +6 -3
- package/dist/runtime/resolver.d.ts +1 -1
- package/dist/runtime/resolver.js +19 -4
- package/dist/server/serve-implementation.js +1 -2
- package/dist/types.d.ts +9 -1
- package/package.json +1 -1
- package/src/error-resolution.ts +0 -1
- package/src/index.ts +0 -1
- package/src/provider.ts +0 -1
- package/src/runtime/browser.ts +430 -31
- package/src/runtime/choice.ts +1 -91
- package/src/runtime/resolver-vendors/browser.ts +82 -15
- package/src/runtime/resolver-vendors/capsolver.ts +700 -0
- package/src/runtime/resolver-vendors/twocaptcha.ts +43 -8
- package/src/runtime/resolver-vendors/types.ts +6 -3
- package/src/runtime/resolver.ts +21 -6
- package/src/server/serve-implementation.ts +0 -2
- package/src/types.ts +10 -1
|
@@ -338,11 +338,6 @@ export function createTwoCaptchaResolverVendorAdapter(
|
|
|
338
338
|
if (!resolverVendorSupports(TWOCAPTCHA_VENDOR_ID, challenge.kind)) {
|
|
339
339
|
throw new TypeError(`2captcha resolver does not support ${challenge.kind}`);
|
|
340
340
|
}
|
|
341
|
-
if (challenge.kind !== "recaptcha_v2" && challenge.kind !== "aws_waf") {
|
|
342
|
-
throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "not_implemented", {
|
|
343
|
-
phase: "create_task",
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
341
|
if (
|
|
347
342
|
challenge.kind === "aws_waf" &&
|
|
348
343
|
(!challenge.siteKey?.trim() ||
|
|
@@ -354,6 +349,11 @@ export function createTwoCaptchaResolverVendorAdapter(
|
|
|
354
349
|
phase: "create_task",
|
|
355
350
|
});
|
|
356
351
|
}
|
|
352
|
+
if (challenge.kind === "recaptcha_v3" && challenge.minScore === undefined) {
|
|
353
|
+
throw new ResolverVendorUnavailableError(TWOCAPTCHA_VENDOR_ID, "transport_failure", {
|
|
354
|
+
phase: "create_task",
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
357
|
|
|
358
358
|
assertResolverHostAllowed(challenge.pageUrl, options.allowedHosts);
|
|
359
359
|
callerSignal.throwIfAborted();
|
|
@@ -388,14 +388,49 @@ export function createTwoCaptchaResolverVendorAdapter(
|
|
|
388
388
|
...(identity ? { userAgent: identity.userAgent } : {}),
|
|
389
389
|
...(proxy ?? {}),
|
|
390
390
|
}
|
|
391
|
-
|
|
392
|
-
|
|
391
|
+
: challenge.kind === "recaptcha_v2"
|
|
392
|
+
? {
|
|
393
|
+
type: proxy ? "RecaptchaV2Task" : "RecaptchaV2TaskProxyless",
|
|
393
394
|
websiteURL: challenge.pageUrl,
|
|
394
395
|
websiteKey: challenge.siteKey,
|
|
395
396
|
isInvisible: false,
|
|
396
397
|
...(identity ? { userAgent: identity.userAgent } : {}),
|
|
398
|
+
...(proxy ?? {}),
|
|
399
|
+
}
|
|
400
|
+
: challenge.kind === "recaptcha_v3"
|
|
401
|
+
? {
|
|
402
|
+
type: "RecaptchaV3TaskProxyless",
|
|
403
|
+
websiteURL: challenge.pageUrl,
|
|
404
|
+
websiteKey: challenge.siteKey,
|
|
405
|
+
minScore: challenge.minScore,
|
|
406
|
+
pageAction: challenge.action,
|
|
407
|
+
...(identity ? { userAgent: identity.userAgent } : {}),
|
|
408
|
+
}
|
|
409
|
+
: challenge.kind === "hcaptcha"
|
|
410
|
+
? {
|
|
411
|
+
type: proxy ? "HCaptchaTask" : "HCaptchaTaskProxyless",
|
|
412
|
+
websiteURL: challenge.pageUrl,
|
|
413
|
+
websiteKey: challenge.siteKey,
|
|
414
|
+
...(identity ? { userAgent: identity.userAgent } : {}),
|
|
415
|
+
...(proxy ?? {}),
|
|
416
|
+
}
|
|
417
|
+
: challenge.kind === "turnstile"
|
|
418
|
+
? {
|
|
419
|
+
type: proxy ? "TurnstileTask" : "TurnstileTaskProxyless",
|
|
420
|
+
websiteURL: challenge.pageUrl,
|
|
421
|
+
websiteKey: challenge.siteKey,
|
|
422
|
+
...(challenge.action !== undefined ? { action: challenge.action } : {}),
|
|
423
|
+
...(challenge.cdata !== undefined ? { data: challenge.cdata } : {}),
|
|
424
|
+
...(identity ? { userAgent: identity.userAgent } : {}),
|
|
397
425
|
...(proxy ?? {}),
|
|
398
|
-
}
|
|
426
|
+
}
|
|
427
|
+
: // `resolverVendorSupports` above already rejected every kind this
|
|
428
|
+
// adapter does not build a task for, so this branch is unreachable.
|
|
429
|
+
(() => {
|
|
430
|
+
throw new TypeError(
|
|
431
|
+
`2captcha resolver does not support ${challenge.kind}`,
|
|
432
|
+
);
|
|
433
|
+
})();
|
|
399
434
|
const createResult = await postJson(
|
|
400
435
|
fetchImpl,
|
|
401
436
|
endpoint(baseUrl, "createTask"),
|
|
@@ -8,15 +8,18 @@ import type { TraceRecorder } from "../trace.js";
|
|
|
8
8
|
|
|
9
9
|
export const RESOLVER_VENDOR_CAPABILITIES = {
|
|
10
10
|
browser: ["aws_waf", "cloudflare_interstitial"],
|
|
11
|
+
// Every kind listed per vendor is implemented by that vendor's adapter; the
|
|
12
|
+
// per-adapter "agrees with every declared capability" tests iterate this
|
|
13
|
+
// table, so adding a kind here without an implementation fails the suite.
|
|
14
|
+
// 2captcha omits `cloudflare_interstitial`, `akamai_sec_cpt`, and
|
|
15
|
+
// `akamai_sensor`: their API offers no task type for them, so declaring them
|
|
16
|
+
// would route challenges to a vendor that can only refuse.
|
|
11
17
|
"2captcha": [
|
|
12
18
|
"turnstile",
|
|
13
19
|
"recaptcha_v2",
|
|
14
20
|
"recaptcha_v3",
|
|
15
21
|
"hcaptcha",
|
|
16
|
-
"cloudflare_interstitial",
|
|
17
22
|
"aws_waf",
|
|
18
|
-
"akamai_sec_cpt",
|
|
19
|
-
"akamai_sensor",
|
|
20
23
|
],
|
|
21
24
|
capsolver: [
|
|
22
25
|
"turnstile",
|
package/src/runtime/resolver.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
resolverChallengeIssuingIdentity,
|
|
25
25
|
} from "./resolver-vendors/bindings.js";
|
|
26
26
|
import { createBrowserResolverVendorAdapter } from "./resolver-vendors/browser.js";
|
|
27
|
+
import { createCapsolverResolverVendorAdapter } from "./resolver-vendors/capsolver.js";
|
|
27
28
|
import { assertResolverHostAllowed } from "./resolver-vendors/hosts.js";
|
|
28
29
|
import { createTwoCaptchaResolverVendorAdapter } from "./resolver-vendors/twocaptcha.js";
|
|
29
30
|
import {
|
|
@@ -70,7 +71,7 @@ type ResolvedResolverVendor =
|
|
|
70
71
|
| {
|
|
71
72
|
readonly vendor: Exclude<ProviderResolverVendor, "custom">;
|
|
72
73
|
readonly available: true;
|
|
73
|
-
readonly configuration: string;
|
|
74
|
+
readonly configuration: string | undefined;
|
|
74
75
|
}
|
|
75
76
|
| {
|
|
76
77
|
readonly vendor: ProviderResolverVendor;
|
|
@@ -183,19 +184,29 @@ export type ResolverInstrumentationMetadata = {
|
|
|
183
184
|
};
|
|
184
185
|
|
|
185
186
|
export type ResolverAdapterFactory = (
|
|
186
|
-
configuration: string,
|
|
187
|
+
configuration: string | undefined,
|
|
187
188
|
timeoutMs: number,
|
|
188
189
|
allowedHosts: readonly string[],
|
|
189
190
|
) => ResolverVendorAdapter;
|
|
190
191
|
|
|
191
192
|
const resolverAdapterRegistry: Partial<Record<ProviderResolverVendor, ResolverAdapterFactory>> = {
|
|
192
193
|
"2captcha"(configuration, timeoutMs, allowedHosts) {
|
|
194
|
+
if (configuration === undefined) {
|
|
195
|
+
throw new Error("2captcha resolver adapter factory requires an API key");
|
|
196
|
+
}
|
|
193
197
|
return createTwoCaptchaResolverVendorAdapter({
|
|
194
198
|
allowedHosts,
|
|
195
199
|
apiKey: configuration,
|
|
196
200
|
timeoutMs,
|
|
197
201
|
});
|
|
198
202
|
},
|
|
203
|
+
capsolver(configuration, timeoutMs, allowedHosts) {
|
|
204
|
+
return createCapsolverResolverVendorAdapter({
|
|
205
|
+
allowedHosts,
|
|
206
|
+
apiKey: configuration,
|
|
207
|
+
timeoutMs,
|
|
208
|
+
});
|
|
209
|
+
},
|
|
199
210
|
browser(configuration, timeoutMs, allowedHosts) {
|
|
200
211
|
return createBrowserResolverVendorAdapter({
|
|
201
212
|
allowedHosts,
|
|
@@ -246,7 +257,6 @@ export function swapResolverDefaultUserAgentForTests(
|
|
|
246
257
|
// This is the sole allowlist for declared vendors whose registry entry may be absent.
|
|
247
258
|
// Remove a vendor here when its adapter is registered.
|
|
248
259
|
const KNOWN_UNIMPLEMENTED_RESOLVER_VENDORS: ReadonlySet<ProviderResolverVendor> = new Set([
|
|
249
|
-
"capsolver",
|
|
250
260
|
"capmonster",
|
|
251
261
|
"custom",
|
|
252
262
|
]);
|
|
@@ -959,15 +969,20 @@ function resolveVendorAvailability(
|
|
|
959
969
|
reason: "missing_transport",
|
|
960
970
|
};
|
|
961
971
|
}
|
|
972
|
+
if (vendor === "browser") {
|
|
973
|
+
return {
|
|
974
|
+
vendor,
|
|
975
|
+
available: true,
|
|
976
|
+
configuration: normalizedEnvValue(env, APIFUSE__CDP_POOL__URL),
|
|
977
|
+
};
|
|
978
|
+
}
|
|
962
979
|
|
|
963
980
|
const envKey =
|
|
964
981
|
vendor === "2captcha"
|
|
965
982
|
? APIFUSE__RESOLVER__2CAPTCHA__API_KEY
|
|
966
983
|
: vendor === "capsolver"
|
|
967
984
|
? APIFUSE__RESOLVER__CAPSOLVER__API_KEY
|
|
968
|
-
:
|
|
969
|
-
? APIFUSE__RESOLVER__CAPMONSTER__API_KEY
|
|
970
|
-
: APIFUSE__CDP_POOL__URL;
|
|
985
|
+
: APIFUSE__RESOLVER__CAPMONSTER__API_KEY;
|
|
971
986
|
|
|
972
987
|
const configuration = normalizedEnvValue(env, envKey);
|
|
973
988
|
return configuration
|
|
@@ -39,7 +39,6 @@ import { createProviderCache } from "../runtime/cache.js";
|
|
|
39
39
|
import {
|
|
40
40
|
createProviderChoiceContext,
|
|
41
41
|
PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
|
|
42
|
-
PROVIDER_RUNTIME_CHOICE_WORD_ISSUANCE_ENV,
|
|
43
42
|
} from "../runtime/choice.js";
|
|
44
43
|
import { createCredentialContext } from "../runtime/credential.js";
|
|
45
44
|
import { createEnvContext } from "../runtime/env.js";
|
|
@@ -627,7 +626,6 @@ function createProviderContext(
|
|
|
627
626
|
const env = createEnvContext([
|
|
628
627
|
...(provider.secrets?.map((secret) => secret.name) ?? []),
|
|
629
628
|
PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
|
|
630
|
-
PROVIDER_RUNTIME_CHOICE_WORD_ISSUANCE_ENV,
|
|
631
629
|
]);
|
|
632
630
|
const credential = createCredentialContext({
|
|
633
631
|
allowedKeys: provider.credential?.keys,
|
package/src/types.ts
CHANGED
|
@@ -1757,7 +1757,7 @@ export interface BrowserCookie {
|
|
|
1757
1757
|
readonly sameSite?: "Strict" | "Lax" | "None";
|
|
1758
1758
|
}
|
|
1759
1759
|
|
|
1760
|
-
export type BrowserResourceMethod = "GET" | "HEAD";
|
|
1760
|
+
export type BrowserResourceMethod = "GET" | "HEAD" | "POST";
|
|
1761
1761
|
|
|
1762
1762
|
export type BrowserResourceRequest = {
|
|
1763
1763
|
readonly url: string;
|
|
@@ -1769,6 +1769,9 @@ export type BrowserResourceRequest = {
|
|
|
1769
1769
|
export type BrowserResourceBody = Buffer | Uint8Array | ArrayBuffer | string;
|
|
1770
1770
|
|
|
1771
1771
|
export type BrowserResourceDecision =
|
|
1772
|
+
| {
|
|
1773
|
+
readonly action: "continue";
|
|
1774
|
+
}
|
|
1772
1775
|
| {
|
|
1773
1776
|
readonly action: "fulfill";
|
|
1774
1777
|
readonly status?: number;
|
|
@@ -1793,6 +1796,12 @@ export type BrowserResourceRoute = {
|
|
|
1793
1796
|
export type BrowserResourcePolicy = {
|
|
1794
1797
|
readonly defaultAction?: "block";
|
|
1795
1798
|
readonly allowedMethods?: readonly BrowserResourceMethod[];
|
|
1799
|
+
/**
|
|
1800
|
+
* Appends an enforcing CSP header to every renderable document response
|
|
1801
|
+
* while the policy is active. Existing CSP headers are retained, so this
|
|
1802
|
+
* can only further restrict the document.
|
|
1803
|
+
*/
|
|
1804
|
+
readonly documentContentSecurityPolicy?: string;
|
|
1796
1805
|
readonly routes: readonly BrowserResourceRoute[];
|
|
1797
1806
|
};
|
|
1798
1807
|
|