@prosopo/load-balancer 2.10.49 → 2.11.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/.turbo/turbo-build$colon$cjs.log +9 -8
- package/.turbo/turbo-build$colon$tsc.log +12 -12
- package/.turbo/turbo-build.log +10 -9
- package/CHANGELOG.md +82 -0
- package/README.md +34 -0
- package/dist/balancer.d.ts +3 -14
- package/dist/balancer.d.ts.map +1 -1
- package/dist/balancer.js +61 -11
- package/dist/balancer.js.map +1 -1
- package/dist/cjs/balancer.cjs +61 -10
- package/dist/cjs/index.cjs +3 -0
- package/dist/cjs/providerUrlOverride.cjs +33 -0
- package/dist/cjs/providers.cjs +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/providerUrlOverride.d.ts +2 -0
- package/dist/providerUrlOverride.d.ts.map +1 -0
- package/dist/providerUrlOverride.js +33 -0
- package/dist/providerUrlOverride.js.map +1 -0
- package/dist/providers.d.ts.map +1 -1
- package/dist/providers.js +6 -1
- package/dist/providers.js.map +1 -1
- package/dist/tests/providerUrlOverride.unit.test.d.ts +2 -0
- package/dist/tests/providerUrlOverride.unit.test.d.ts.map +1 -0
- package/dist/tests/providerUrlOverride.unit.test.js +144 -0
- package/dist/tests/providerUrlOverride.unit.test.js.map +1 -0
- package/dist/tests/providers.unit.test.js +2 -0
- package/dist/tests/providers.unit.test.js.map +1 -1
- package/package.json +4 -5
- package/src/balancer.ts +112 -18
- package/src/index.ts +1 -0
- package/src/providerUrlOverride.ts +44 -0
- package/src/providers.ts +13 -0
- package/src/tests/providerUrlOverride.unit.test.ts +182 -0
- package/src/tests/providers.unit.test.ts +6 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/load-balancer@2.
|
|
2
|
+
> @prosopo/load-balancer@2.11.0 build:cjs
|
|
3
3
|
> NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
|
|
4
4
|
|
|
5
5
|
ViteCommonJSConfig: .
|
|
@@ -7,8 +7,8 @@ ViteCommonJSConfig: .
|
|
|
7
7
|
tsConfigPaths: [
|
|
8
8
|
'/home/runner/work/captcha/captcha/packages/common/tsconfig.json',
|
|
9
9
|
'/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
|
|
10
|
-
'/home/runner/work/captcha/captcha/packages/logger/tsconfig.json',
|
|
11
10
|
'/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
|
|
11
|
+
'/home/runner/work/captcha/captcha/packages/logger/tsconfig.json',
|
|
12
12
|
'/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
|
|
13
13
|
'/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json'
|
|
14
14
|
]
|
|
@@ -17,8 +17,8 @@ ViteCommonJSConfig: .
|
|
|
17
17
|
externals: [
|
|
18
18
|
'@prosopo/common',
|
|
19
19
|
'@prosopo/locale',
|
|
20
|
-
'@prosopo/logger',
|
|
21
20
|
'@prosopo/util',
|
|
21
|
+
'@prosopo/logger',
|
|
22
22
|
'@prosopo/types',
|
|
23
23
|
'@prosopo/util-crypto'
|
|
24
24
|
]
|
|
@@ -27,13 +27,14 @@ ViteCommonJSConfig: .
|
|
|
27
27
|
[36mvite v8.1.5 [32mbuilding ssr environment for production...[36m[39m
|
|
28
28
|
Bundle build started
|
|
29
29
|
[2K
|
|
30
|
-
✓
|
|
30
|
+
✓ 7 modules transformed.
|
|
31
31
|
rendering chunks...
|
|
32
32
|
computing gzip size...
|
|
33
33
|
dist/cjs/retry.cjs 1.13 kB │ gzip: 0.56 kB
|
|
34
|
-
dist/cjs/
|
|
34
|
+
dist/cjs/providerUrlOverride.cjs 1.42 kB │ gzip: 0.78 kB
|
|
35
|
+
dist/cjs/index.cjs 1.63 kB │ gzip: 0.41 kB
|
|
35
36
|
dist/cjs/developmentProviderUrl.cjs 1.81 kB │ gzip: 0.88 kB
|
|
36
|
-
dist/cjs/balancer.cjs
|
|
37
|
-
dist/cjs/providers.cjs
|
|
37
|
+
dist/cjs/balancer.cjs 4.36 kB │ gzip: 1.90 kB
|
|
38
|
+
dist/cjs/providers.cjs 6.12 kB │ gzip: 2.10 kB
|
|
38
39
|
|
|
39
|
-
[32m✓ built in
|
|
40
|
+
[32m✓ built in 67ms[39m
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/load-balancer@2.
|
|
2
|
+
> @prosopo/load-balancer@2.11.0 build:tsc
|
|
3
3
|
> tsc --build --verbose
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
9:05:50 AM - Projects in this build:
|
|
6
6
|
* ../../dev/config/tsconfig.json
|
|
7
|
-
* ../locale/tsconfig.json
|
|
8
7
|
* ../util/tsconfig.json
|
|
8
|
+
* ../locale/tsconfig.json
|
|
9
9
|
* ../logger/tsconfig.json
|
|
10
10
|
* ../util-crypto/tsconfig.json
|
|
11
11
|
* ../types/tsconfig.json
|
|
12
12
|
* ../common/tsconfig.json
|
|
13
13
|
* tsconfig.json
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
9:05:50 AM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
9:05:50 AM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
9:05:50 AM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
9:05:50 AM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
9:05:50 AM - 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'
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
9:05:50 AM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
9:05:50 AM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/error.ts' is older than output '../common/tsconfig.tsbuildinfo'
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
9:05:50 AM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
9:05:50 AM - Building project '/home/runner/work/captcha/captcha/packages/load-balancer/tsconfig.json'...
|
|
32
32
|
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/load-balancer@2.
|
|
2
|
+
> @prosopo/load-balancer@2.11.0 build
|
|
3
3
|
> npm run build:cross-env -- --mode ${NODE_ENV:-development}
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @prosopo/load-balancer@2.
|
|
6
|
+
> @prosopo/load-balancer@2.11.0 build:cross-env
|
|
7
7
|
> vite build --config vite.esm.config.ts --mode production
|
|
8
8
|
|
|
9
9
|
ViteEsmConfig: .
|
|
@@ -11,8 +11,8 @@ ViteEsmConfig: .
|
|
|
11
11
|
tsConfigPaths: [
|
|
12
12
|
'/home/runner/work/captcha/captcha/packages/common/tsconfig.json',
|
|
13
13
|
'/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
|
|
14
|
-
'/home/runner/work/captcha/captcha/packages/logger/tsconfig.json',
|
|
15
14
|
'/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
|
|
15
|
+
'/home/runner/work/captcha/captcha/packages/logger/tsconfig.json',
|
|
16
16
|
'/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
|
|
17
17
|
'/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json'
|
|
18
18
|
]
|
|
@@ -21,8 +21,8 @@ ViteEsmConfig: .
|
|
|
21
21
|
externals: [
|
|
22
22
|
'@prosopo/common',
|
|
23
23
|
'@prosopo/locale',
|
|
24
|
-
'@prosopo/logger',
|
|
25
24
|
'@prosopo/util',
|
|
25
|
+
'@prosopo/logger',
|
|
26
26
|
'@prosopo/types',
|
|
27
27
|
'@prosopo/util-crypto'
|
|
28
28
|
]
|
|
@@ -31,14 +31,15 @@ ViteEsmConfig: .
|
|
|
31
31
|
[36mvite v8.1.5 [32mbuilding ssr environment for production...[36m[39m
|
|
32
32
|
Bundle build started
|
|
33
33
|
[2K
|
|
34
|
-
✓
|
|
34
|
+
✓ 7 modules transformed.
|
|
35
35
|
rendering chunks...
|
|
36
36
|
computing gzip size...
|
|
37
37
|
dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
|
|
38
|
-
dist/index.js
|
|
38
|
+
dist/index.js 1.00 kB │ gzip: 0.32 kB
|
|
39
39
|
dist/retry.js 1.09 kB │ gzip: 0.55 kB
|
|
40
|
+
dist/providerUrlOverride.js 1.39 kB │ gzip: 0.77 kB
|
|
40
41
|
dist/developmentProviderUrl.js 1.70 kB │ gzip: 0.87 kB
|
|
41
|
-
dist/balancer.js
|
|
42
|
-
dist/providers.js 5.
|
|
42
|
+
dist/balancer.js 4.11 kB │ gzip: 1.86 kB
|
|
43
|
+
dist/providers.js 5.85 kB │ gzip: 2.07 kB
|
|
43
44
|
|
|
44
|
-
[32m✓ built in
|
|
45
|
+
[32m✓ built in 62ms[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,87 @@
|
|
|
1
1
|
# @prosopo/load-balancer
|
|
2
2
|
|
|
3
|
+
## 2.11.0
|
|
4
|
+
### Minor Changes
|
|
5
|
+
|
|
6
|
+
- f13bea8: Let a deployment supply its own provider list with `PROSOPO_PROVIDER_LIST`.
|
|
7
|
+
|
|
8
|
+
There was no supported way to point the widget at providers you run. The only lever was
|
|
9
|
+
`PROSOPO_PROVIDER_URL_DEVELOPMENT`, which is read solely when the environment is `development`, and the widget takes
|
|
10
|
+
that environment from `NODE_ENV` at build time. So redirecting a bundle meant building it as a development bundle:
|
|
11
|
+
unminified, ~1.9 MB across chunks instead of ~1.4 MB, with rate limiting implications if anyone copied the same setting
|
|
12
|
+
onto their provider. Building with `NODE_ENV=production` silently ignored the variable and sent the widget back to
|
|
13
|
+
Prosopo's fleet, with nothing in the output to say so.
|
|
14
|
+
|
|
15
|
+
`PROSOPO_PROVIDER_LIST` is environment-independent, so `production` stays correct everywhere. It short-circuits both
|
|
16
|
+
halves of discovery — the `/healthz` call that picks a node, and the list `@prosopo/server` matches a token against —
|
|
17
|
+
so a self-hosted deployment makes no request to Prosopo at all.
|
|
18
|
+
|
|
19
|
+
Two forms, because one node and several have different needs:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
PROSOPO_PROVIDER_LIST=https://captcha1.example.com,https://captcha2.example.com
|
|
23
|
+
PROSOPO_PROVIDER_LIST='{"one":{"address":"5Abc...","url":"https://captcha1.example.com","datasetId":"","weight":3}}'
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The JSON form is the exact shape `provider-list.prosopo.io` serves, parsed by the same `convertHostedProvider`, so
|
|
27
|
+
weights and the `ipv4` / `ipv6` sub-lists behave identically. The bare-URL form fills in placeholder `address` and
|
|
28
|
+
`datasetId`, neither of which is load-bearing on this path — the DNS-routed production path already passes a constant
|
|
29
|
+
for `address`, and clients stopped sending `datasetId`.
|
|
30
|
+
|
|
31
|
+
Because it returns a list rather than one URL, a multi-provider override gets weighted selection and real failover:
|
|
32
|
+
`getRandomProviderFromList` can now exclude a node that just errored and pick a different one, which with a single
|
|
33
|
+
development URL degraded to retrying the same node.
|
|
34
|
+
|
|
35
|
+
Details worth knowing:
|
|
36
|
+
|
|
37
|
+
- Trailing slashes are stripped. A token embeds the provider URL it was minted against and the verifier matches by
|
|
38
|
+
exact string, so `https://host/` and `https://host` must not disagree.
|
|
39
|
+
- A malformed value is ignored and normal discovery resumes rather than throwing, so a deployment-time typo cannot
|
|
40
|
+
take every captcha on a page down with it.
|
|
41
|
+
- The env read lives in its own module holding nothing else. Parsing needs `convertHostedProvider` from `balancer.ts`,
|
|
42
|
+
and `balancer.ts` needs the read — putting both in one file would create an import cycle, which this package has
|
|
43
|
+
already lost a release to when a cycle between chunks broke the widget at load.
|
|
44
|
+
- `PROSOPO_PROVIDER_URL_DEVELOPMENT` is untouched and still works for local development.
|
|
45
|
+
|
|
46
|
+
Verified by building a production bundle with the override set: `defaultEnvironment` stays `production`, the bundle is
|
|
47
|
+
minified, and the override is baked in.
|
|
48
|
+
|
|
49
|
+
### Patch Changes
|
|
50
|
+
|
|
51
|
+
- Updated dependencies [4c9b84b]
|
|
52
|
+
- @prosopo/types@5.10.1
|
|
53
|
+
|
|
54
|
+
## 2.10.50
|
|
55
|
+
### Patch Changes
|
|
56
|
+
|
|
57
|
+
- a9141c3: Stop loading zod before the widget can draw itself. Takes another 13KB gzipped off the critical path.
|
|
58
|
+
|
|
59
|
+
zod is 14KB gzipped and it was being downloaded and parsed before the checkbox appeared, because six small things on the startup path happened to use it:
|
|
60
|
+
|
|
61
|
+
- two lists of strings in `@prosopo/logger` (log levels, output format)
|
|
62
|
+
- two lists of strings in `@prosopo/locale` (language codes, translation keys)
|
|
63
|
+
- two lists of two strings in `@prosopo/types` (start mode, challenge placement)
|
|
64
|
+
- one four-field object in `@prosopo/load-balancer` (a provider entry)
|
|
65
|
+
- an `instanceof ZodError` check in `@prosopo/common`
|
|
66
|
+
- `INPUT_LIMITS`, a plain table of numbers, that happened to live in the same file as zod-based string builders
|
|
67
|
+
|
|
68
|
+
None of these need a validation library. They are now plain TypeScript: a list, a type, and where input is untrusted, a one-line guard. `INPUT_LIMITS` moved to its own file so reading it no longer drags the builders along.
|
|
69
|
+
|
|
70
|
+
zod has not gone anywhere — the real request and response schemas in `@prosopo/types` still use it, and still validate exactly as before. It now arrives with the code that needs it, after the widget is on screen, rather than in front of it.
|
|
71
|
+
|
|
72
|
+
Two API changes for anyone importing these directly:
|
|
73
|
+
|
|
74
|
+
- `LanguageSchema`, `TranslationKeysSchema`, `StartModeSchema` and `Placement` are no longer exported as zod schemas. Use `isLanguage()`, `isStartMode()`, `isPlacement()` to check a value, and `LanguageCodes`, `translationKeys`, `StartModes`, `Placements` for the lists.
|
|
75
|
+
- `isZodError()` now recognises a zod error by its name rather than `instanceof`. That is strictly more tolerant: the name still matches when an error crosses a realm boundary or comes from a second copy of zod, which `instanceof` misses — it was already the fallback arm of the same check.
|
|
76
|
+
|
|
77
|
+
Two behaviour notes: a malformed entry in the fetched provider list now throws a plain `Error` naming the entry, where it used to throw an untranslated zod error; and the language codes accepted are unchanged.
|
|
78
|
+
|
|
79
|
+
Covered by the existing suites for every package touched (types, types-database, locale, logger, common, load-balancer, all five procaptcha packages, api, cli, api-express-router, server, and the provider's 1322 unit tests), all passing. The built bundle was also loaded in a real browser: the widget renders from the first eight chunks, zod arrives in the second wave, and the provider's error came back translated into German.
|
|
80
|
+
- Updated dependencies [a9141c3]
|
|
81
|
+
- Updated dependencies [a9141c3]
|
|
82
|
+
- @prosopo/common@3.1.59
|
|
83
|
+
- @prosopo/types@5.10.0
|
|
84
|
+
|
|
3
85
|
## 2.10.49
|
|
4
86
|
### Patch Changes
|
|
5
87
|
|
package/README.md
CHANGED
|
@@ -47,3 +47,37 @@ In this example:
|
|
|
47
47
|
- Total weight = 4
|
|
48
48
|
- Provider 1 receives ~25% of traffic
|
|
49
49
|
- Provider 2 receives ~75% of traffic
|
|
50
|
+
|
|
51
|
+
## Overriding the provider list
|
|
52
|
+
|
|
53
|
+
By default the list is fetched from `provider-list.prosopo.io` for `staging` and `production`, and hardcoded to a local
|
|
54
|
+
provider for `development`. `PROSOPO_PROVIDER_LIST` replaces all of that with providers you name, in every environment.
|
|
55
|
+
|
|
56
|
+
This is what a [self-hosted](https://docs.prosopo.io/en/self-hosting/) deployment uses. It short-circuits both halves of
|
|
57
|
+
discovery — the `/healthz` call the widget makes to pick a node, and the list a verifier matches a token against — so
|
|
58
|
+
nothing reaches Prosopo.
|
|
59
|
+
|
|
60
|
+
Two forms are accepted. One or more comma-separated URLs:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
PROSOPO_PROVIDER_LIST=https://captcha1.example.com,https://captcha2.example.com
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
...or the same JSON shape documented above, when you want to set weights or the `ipv4` / `ipv6` sub-lists:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
PROSOPO_PROVIDER_LIST='{"one":{"address":"5Abc...","url":"https://captcha1.example.com","datasetId":"","weight":3}}'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Notes:
|
|
73
|
+
|
|
74
|
+
- Trailing slashes are stripped. A token embeds the provider URL it was minted against and `@prosopo/server` finds the
|
|
75
|
+
issuer by exact string match, so `https://host/` and `https://host` must not be able to disagree.
|
|
76
|
+
- A malformed value is ignored and normal discovery resumes, rather than throwing. A deployment-time typo should not
|
|
77
|
+
take down every captcha on the page — check your logs if an override seems to have no effect.
|
|
78
|
+
- The bare-URL form ignores `ipMode`. The `ipv4.` / `ipv6.` labels are a property of Prosopo's own DNS and prefixing
|
|
79
|
+
them onto another host would resolve to nothing. Use the JSON form's sub-lists if you run single-stack sub-zones.
|
|
80
|
+
- Frontend builds bake the value in at bundle time; Node reads it at runtime.
|
|
81
|
+
|
|
82
|
+
`PROSOPO_PROVIDER_URL_DEVELOPMENT` still exists and still only applies when the environment is `development`. Prefer
|
|
83
|
+
`PROSOPO_PROVIDER_LIST`, which works in a production build.
|
package/dist/balancer.d.ts
CHANGED
|
@@ -1,27 +1,16 @@
|
|
|
1
1
|
import type { EnvironmentTypes } from "@prosopo/types";
|
|
2
|
-
|
|
3
|
-
declare const HardcodedProviderSchema: z.ZodObject<{
|
|
4
|
-
address: z.ZodString;
|
|
5
|
-
url: z.ZodString;
|
|
6
|
-
datasetId: z.ZodString;
|
|
7
|
-
weight: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodNumber>>, number, number | undefined>;
|
|
8
|
-
}, "strip", z.ZodTypeAny, {
|
|
2
|
+
export interface HardcodedProvider {
|
|
9
3
|
address: string;
|
|
10
4
|
url: string;
|
|
11
5
|
datasetId: string;
|
|
12
6
|
weight: number;
|
|
13
|
-
}
|
|
14
|
-
address: string;
|
|
15
|
-
url: string;
|
|
16
|
-
datasetId: string;
|
|
17
|
-
weight?: number | undefined;
|
|
18
|
-
}>;
|
|
19
|
-
export type HardcodedProvider = z.infer<typeof HardcodedProviderSchema>;
|
|
7
|
+
}
|
|
20
8
|
export type IpMode = "ipv4" | "ipv6";
|
|
21
9
|
type hostedProviders = Record<string, unknown>;
|
|
22
10
|
export declare const convertHostedProvider: (provider: hostedProviders, ipMode?: IpMode) => HardcodedProvider[];
|
|
23
11
|
export declare const stripIpModeLabel: (hostname: string) => string;
|
|
24
12
|
export declare const getProviderHostname: (provider: HardcodedProvider) => string;
|
|
13
|
+
export declare const getProviderListOverride: (raw?: string | undefined, ipMode?: IpMode) => HardcodedProvider[];
|
|
25
14
|
export declare const getLoadBalancerUrl: (environment: EnvironmentTypes) => string;
|
|
26
15
|
export declare const loadBalancer: (environment: EnvironmentTypes, ipMode?: IpMode) => Promise<HardcodedProvider[]>;
|
|
27
16
|
export {};
|
package/dist/balancer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"balancer.d.ts","sourceRoot":"","sources":["../src/balancer.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"balancer.d.ts","sourceRoot":"","sources":["../src/balancer.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIvD,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CACf;AAkCD,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAQrC,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAK/C,eAAO,MAAM,qBAAqB,aACvB,eAAe,WAChB,MAAM,KACb,iBAAiB,EAUnB,CAAC;AAKF,eAAO,MAAM,gBAAgB,aAAc,MAAM,KAAG,MACjB,CAAC;AAEpC,eAAO,MAAM,mBAAmB,aAAc,iBAAiB,KAAG,MACjB,CAAC;AA0ClD,eAAO,MAAM,uBAAuB,SAC9B,MAAM,GAAG,SAAS,WACd,MAAM,KACb,iBAAiB,EAiBnB,CAAC;AAEF,eAAO,MAAM,kBAAkB,gBAAiB,gBAAgB,KAAG,MAUlE,CAAC;AAEF,eAAO,MAAM,YAAY,gBACX,gBAAgB,WACpB,MAAM,KACb,OAAO,CAAC,iBAAiB,EAAE,CAmC7B,CAAC"}
|
package/dist/balancer.js
CHANGED
|
@@ -1,29 +1,79 @@
|
|
|
1
1
|
import { getDevelopmentProviderUrl } from "./developmentProviderUrl.js";
|
|
2
|
+
import { readProviderListOverride } from "./providerUrlOverride.js";
|
|
2
3
|
import { ProsopoEnvError } from "@prosopo/common";
|
|
3
|
-
import { z } from "zod";
|
|
4
4
|
//#region src/balancer.ts
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The provider list is fetched JSON, so entries are checked rather than
|
|
7
|
+
* trusted. Hand-written rather than a zod schema: this module is on the
|
|
8
|
+
* widget's critical path and zod costs 14KB gzipped to validate three strings
|
|
9
|
+
* and a number.
|
|
10
|
+
*/
|
|
11
|
+
var parseHardcodedProvider = (value) => {
|
|
12
|
+
const entry = value;
|
|
13
|
+
if (!isProviderRecord(value) || typeof entry.address !== "string" || typeof entry.url !== "string" || typeof entry.datasetId !== "string" || entry.weight !== void 0 && typeof entry.weight !== "number") throw new Error(`Malformed provider entry in the provider list: ${JSON.stringify(value)}`);
|
|
14
|
+
return {
|
|
15
|
+
address: entry.address,
|
|
16
|
+
url: entry.url,
|
|
17
|
+
datasetId: entry.datasetId,
|
|
18
|
+
weight: Math.max(1, Math.min(100, Math.round(entry.weight ?? 1)))
|
|
19
|
+
};
|
|
20
|
+
};
|
|
13
21
|
var IP_MODE_KEYS = ["ipv4", "ipv6"];
|
|
14
22
|
var isProviderRecord = (value) => typeof value === "object" && value !== null;
|
|
15
23
|
var convertHostedProvider = (provider, ipMode) => {
|
|
16
24
|
const source = ipMode && isProviderRecord(provider[ipMode]) ? provider[ipMode] : provider;
|
|
17
|
-
return Object.entries(source).filter(([key]) => !IP_MODE_KEYS.includes(key)).map(([, value]) =>
|
|
25
|
+
return Object.entries(source).filter(([key]) => !IP_MODE_KEYS.includes(key)).map(([, value]) => parseHardcodedProvider(value)).sort((a, b) => a.url.localeCompare(b.url));
|
|
18
26
|
};
|
|
19
27
|
var stripIpModeLabel = (hostname) => hostname.replace(/^ipv[46]\./, "");
|
|
20
28
|
var getProviderHostname = (provider) => stripIpModeLabel(new URL(provider.url).hostname);
|
|
29
|
+
var SELF_HOSTED_ADDRESS = "self-hosted";
|
|
30
|
+
var SELF_HOSTED_DATASET_ID = "";
|
|
31
|
+
var stripTrailingSlash = (url) => url.replace(/\/$/, "");
|
|
32
|
+
var providersFromUrlList = (raw) => raw.split(",").map((url) => stripTrailingSlash(url.trim())).filter((url) => url.length > 0).map((url) => ({
|
|
33
|
+
address: SELF_HOSTED_ADDRESS,
|
|
34
|
+
url,
|
|
35
|
+
datasetId: SELF_HOSTED_DATASET_ID,
|
|
36
|
+
weight: 1
|
|
37
|
+
}));
|
|
38
|
+
/**
|
|
39
|
+
* Parses `PROSOPO_PROVIDER_LIST` into providers, or returns empty when unset.
|
|
40
|
+
*
|
|
41
|
+
* Two accepted forms:
|
|
42
|
+
*
|
|
43
|
+
* - The same JSON the hosted provider list serves, so weights and the
|
|
44
|
+
* `ipv4` / `ipv6` sub-lists behave identically. See the README.
|
|
45
|
+
* - One or more bare URLs, comma-separated, for a deployment that has
|
|
46
|
+
* nothing to say about weights or addresses.
|
|
47
|
+
*
|
|
48
|
+
* Trailing slashes are stripped throughout: a token embeds the provider URL
|
|
49
|
+
* it was minted against and `@prosopo/server` finds the issuer by exact
|
|
50
|
+
* string match, so `https://host/` and `https://host` must not disagree.
|
|
51
|
+
*
|
|
52
|
+
* A malformed override returns empty rather than throwing, falling back to
|
|
53
|
+
* normal discovery. Throwing would take every captcha on the page down over
|
|
54
|
+
* what is a deployment-time typo.
|
|
55
|
+
*/
|
|
56
|
+
var getProviderListOverride = (raw = readProviderListOverride(), ipMode) => {
|
|
57
|
+
const trimmed = raw?.trim();
|
|
58
|
+
if (!trimmed) return [];
|
|
59
|
+
if (!trimmed.startsWith("{")) return providersFromUrlList(trimmed);
|
|
60
|
+
try {
|
|
61
|
+
return convertHostedProvider(JSON.parse(trimmed), ipMode).map((provider) => ({
|
|
62
|
+
...provider,
|
|
63
|
+
url: stripTrailingSlash(provider.url)
|
|
64
|
+
}));
|
|
65
|
+
} catch {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
};
|
|
21
69
|
var getLoadBalancerUrl = (environment) => {
|
|
22
70
|
if (environment === "production") return "https://provider-list.prosopo.io/";
|
|
23
71
|
if (environment === "staging") return "https://provider-list.prosopo.io/staging.json";
|
|
24
72
|
throw new ProsopoEnvError("CONFIG.UNKNOWN_ENVIRONMENT", { context: { environment } });
|
|
25
73
|
};
|
|
26
74
|
var loadBalancer = async (environment, ipMode) => {
|
|
75
|
+
const override = getProviderListOverride(void 0, ipMode);
|
|
76
|
+
if (override.length > 0) return override;
|
|
27
77
|
if (environment === "development") return [{
|
|
28
78
|
address: "5EjTA28bKSbFPPyMbUjNtArxyqjwq38r1BapVmLZShaqEedV",
|
|
29
79
|
url: getDevelopmentProviderUrl(),
|
|
@@ -36,4 +86,4 @@ var loadBalancer = async (environment, ipMode) => {
|
|
|
36
86
|
}).then((res) => res.json()), ipMode);
|
|
37
87
|
};
|
|
38
88
|
//#endregion
|
|
39
|
-
export { convertHostedProvider, getLoadBalancerUrl, getProviderHostname, loadBalancer, stripIpModeLabel };
|
|
89
|
+
export { convertHostedProvider, getLoadBalancerUrl, getProviderHostname, getProviderListOverride, loadBalancer, stripIpModeLabel };
|
package/dist/balancer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"balancer.js","sourceRoot":"","sources":["../src/balancer.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"balancer.js","sourceRoot":"","sources":["../src/balancer.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/balancer.cjs
CHANGED
|
@@ -1,29 +1,79 @@
|
|
|
1
1
|
const require_developmentProviderUrl = require("./developmentProviderUrl.cjs");
|
|
2
|
+
const require_providerUrlOverride = require("./providerUrlOverride.cjs");
|
|
2
3
|
let _prosopo_common = require("@prosopo/common");
|
|
3
|
-
let zod = require("zod");
|
|
4
4
|
//#region src/balancer.ts
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The provider list is fetched JSON, so entries are checked rather than
|
|
7
|
+
* trusted. Hand-written rather than a zod schema: this module is on the
|
|
8
|
+
* widget's critical path and zod costs 14KB gzipped to validate three strings
|
|
9
|
+
* and a number.
|
|
10
|
+
*/
|
|
11
|
+
var parseHardcodedProvider = (value) => {
|
|
12
|
+
const entry = value;
|
|
13
|
+
if (!isProviderRecord(value) || typeof entry.address !== "string" || typeof entry.url !== "string" || typeof entry.datasetId !== "string" || entry.weight !== void 0 && typeof entry.weight !== "number") throw new Error(`Malformed provider entry in the provider list: ${JSON.stringify(value)}`);
|
|
14
|
+
return {
|
|
15
|
+
address: entry.address,
|
|
16
|
+
url: entry.url,
|
|
17
|
+
datasetId: entry.datasetId,
|
|
18
|
+
weight: Math.max(1, Math.min(100, Math.round(entry.weight ?? 1)))
|
|
19
|
+
};
|
|
20
|
+
};
|
|
13
21
|
var IP_MODE_KEYS = ["ipv4", "ipv6"];
|
|
14
22
|
var isProviderRecord = (value) => typeof value === "object" && value !== null;
|
|
15
23
|
var convertHostedProvider = (provider, ipMode) => {
|
|
16
24
|
const source = ipMode && isProviderRecord(provider[ipMode]) ? provider[ipMode] : provider;
|
|
17
|
-
return Object.entries(source).filter(([key]) => !IP_MODE_KEYS.includes(key)).map(([, value]) =>
|
|
25
|
+
return Object.entries(source).filter(([key]) => !IP_MODE_KEYS.includes(key)).map(([, value]) => parseHardcodedProvider(value)).sort((a, b) => a.url.localeCompare(b.url));
|
|
18
26
|
};
|
|
19
27
|
var stripIpModeLabel = (hostname) => hostname.replace(/^ipv[46]\./, "");
|
|
20
28
|
var getProviderHostname = (provider) => stripIpModeLabel(new URL(provider.url).hostname);
|
|
29
|
+
var SELF_HOSTED_ADDRESS = "self-hosted";
|
|
30
|
+
var SELF_HOSTED_DATASET_ID = "";
|
|
31
|
+
var stripTrailingSlash = (url) => url.replace(/\/$/, "");
|
|
32
|
+
var providersFromUrlList = (raw) => raw.split(",").map((url) => stripTrailingSlash(url.trim())).filter((url) => url.length > 0).map((url) => ({
|
|
33
|
+
address: SELF_HOSTED_ADDRESS,
|
|
34
|
+
url,
|
|
35
|
+
datasetId: SELF_HOSTED_DATASET_ID,
|
|
36
|
+
weight: 1
|
|
37
|
+
}));
|
|
38
|
+
/**
|
|
39
|
+
* Parses `PROSOPO_PROVIDER_LIST` into providers, or returns empty when unset.
|
|
40
|
+
*
|
|
41
|
+
* Two accepted forms:
|
|
42
|
+
*
|
|
43
|
+
* - The same JSON the hosted provider list serves, so weights and the
|
|
44
|
+
* `ipv4` / `ipv6` sub-lists behave identically. See the README.
|
|
45
|
+
* - One or more bare URLs, comma-separated, for a deployment that has
|
|
46
|
+
* nothing to say about weights or addresses.
|
|
47
|
+
*
|
|
48
|
+
* Trailing slashes are stripped throughout: a token embeds the provider URL
|
|
49
|
+
* it was minted against and `@prosopo/server` finds the issuer by exact
|
|
50
|
+
* string match, so `https://host/` and `https://host` must not disagree.
|
|
51
|
+
*
|
|
52
|
+
* A malformed override returns empty rather than throwing, falling back to
|
|
53
|
+
* normal discovery. Throwing would take every captcha on the page down over
|
|
54
|
+
* what is a deployment-time typo.
|
|
55
|
+
*/
|
|
56
|
+
var getProviderListOverride = (raw = require_providerUrlOverride.readProviderListOverride(), ipMode) => {
|
|
57
|
+
const trimmed = raw?.trim();
|
|
58
|
+
if (!trimmed) return [];
|
|
59
|
+
if (!trimmed.startsWith("{")) return providersFromUrlList(trimmed);
|
|
60
|
+
try {
|
|
61
|
+
return convertHostedProvider(JSON.parse(trimmed), ipMode).map((provider) => ({
|
|
62
|
+
...provider,
|
|
63
|
+
url: stripTrailingSlash(provider.url)
|
|
64
|
+
}));
|
|
65
|
+
} catch {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
};
|
|
21
69
|
var getLoadBalancerUrl = (environment) => {
|
|
22
70
|
if (environment === "production") return "https://provider-list.prosopo.io/";
|
|
23
71
|
if (environment === "staging") return "https://provider-list.prosopo.io/staging.json";
|
|
24
72
|
throw new _prosopo_common.ProsopoEnvError("CONFIG.UNKNOWN_ENVIRONMENT", { context: { environment } });
|
|
25
73
|
};
|
|
26
74
|
var loadBalancer = async (environment, ipMode) => {
|
|
75
|
+
const override = getProviderListOverride(void 0, ipMode);
|
|
76
|
+
if (override.length > 0) return override;
|
|
27
77
|
if (environment === "development") return [{
|
|
28
78
|
address: "5EjTA28bKSbFPPyMbUjNtArxyqjwq38r1BapVmLZShaqEedV",
|
|
29
79
|
url: require_developmentProviderUrl.getDevelopmentProviderUrl(),
|
|
@@ -39,5 +89,6 @@ var loadBalancer = async (environment, ipMode) => {
|
|
|
39
89
|
exports.convertHostedProvider = convertHostedProvider;
|
|
40
90
|
exports.getLoadBalancerUrl = getLoadBalancerUrl;
|
|
41
91
|
exports.getProviderHostname = getProviderHostname;
|
|
92
|
+
exports.getProviderListOverride = getProviderListOverride;
|
|
42
93
|
exports.loadBalancer = loadBalancer;
|
|
43
94
|
exports.stripIpModeLabel = stripIpModeLabel;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_developmentProviderUrl = require("./developmentProviderUrl.cjs");
|
|
3
|
+
const require_providerUrlOverride = require("./providerUrlOverride.cjs");
|
|
3
4
|
const require_balancer = require("./balancer.cjs");
|
|
4
5
|
const require_providers = require("./providers.cjs");
|
|
5
6
|
exports.DEFAULT_DEVELOPMENT_PROVIDER_URL = require_developmentProviderUrl.DEFAULT_DEVELOPMENT_PROVIDER_URL;
|
|
@@ -11,9 +12,11 @@ exports.convertHostedProvider = require_balancer.convertHostedProvider;
|
|
|
11
12
|
exports.getDevelopmentProviderUrl = require_developmentProviderUrl.getDevelopmentProviderUrl;
|
|
12
13
|
exports.getLoadBalancerUrl = require_balancer.getLoadBalancerUrl;
|
|
13
14
|
exports.getProviderHostname = require_balancer.getProviderHostname;
|
|
15
|
+
exports.getProviderListOverride = require_balancer.getProviderListOverride;
|
|
14
16
|
exports.getProviders = require_providers.getProviders;
|
|
15
17
|
exports.getRandomActiveProvider = require_providers.getRandomActiveProvider;
|
|
16
18
|
exports.getRandomProviderFromList = require_providers.getRandomProviderFromList;
|
|
17
19
|
exports.loadBalancer = require_balancer.loadBalancer;
|
|
18
20
|
exports.readDevelopmentProviderUrlOverride = require_developmentProviderUrl.readDevelopmentProviderUrlOverride;
|
|
21
|
+
exports.readProviderListOverride = require_providerUrlOverride.readProviderListOverride;
|
|
19
22
|
exports.stripIpModeLabel = require_balancer.stripIpModeLabel;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region src/providerUrlOverride.ts
|
|
2
|
+
/**
|
|
3
|
+
* Supplies the provider list directly instead of fetching Prosopo's.
|
|
4
|
+
*
|
|
5
|
+
* A self-hosted deployment has its own providers and no hosted list to
|
|
6
|
+
* discover them from. Setting this replaces both halves of discovery — the
|
|
7
|
+
* endpoint the widget calls and the list a verifier matches a token against —
|
|
8
|
+
* with whatever it names. See `getProviderListOverride` in `balancer.ts` for
|
|
9
|
+
* the accepted forms.
|
|
10
|
+
*
|
|
11
|
+
* Distinct from `PROSOPO_PROVIDER_URL_DEVELOPMENT`, which only applies when
|
|
12
|
+
* the environment is `development`. That coupling forced self-hosters to ship
|
|
13
|
+
* a development build of the widget purely to redirect it; this override is
|
|
14
|
+
* environment-independent, so `production` stays correct everywhere.
|
|
15
|
+
*
|
|
16
|
+
* Kept in its own module, holding nothing but the read, so that parsing can
|
|
17
|
+
* live next to `convertHostedProvider` in `balancer.ts` without the two
|
|
18
|
+
* modules importing each other. A cycle here would be bundled into the widget
|
|
19
|
+
* and this package has already lost a release to one.
|
|
20
|
+
*
|
|
21
|
+
* Written as a static `process.env.X` access for the same reason as the
|
|
22
|
+
* development override: frontend bundlers substitute that exact expression
|
|
23
|
+
* for a literal, which a computed lookup would not match.
|
|
24
|
+
*/
|
|
25
|
+
var readProviderListOverride = () => {
|
|
26
|
+
try {
|
|
27
|
+
return process.env.PROSOPO_PROVIDER_LIST;
|
|
28
|
+
} catch {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
exports.readProviderListOverride = readProviderListOverride;
|
package/dist/cjs/providers.cjs
CHANGED
|
@@ -47,6 +47,11 @@ var resolveBaseUrl = (env) => {
|
|
|
47
47
|
return endpoints[env] ?? endpoints.development;
|
|
48
48
|
};
|
|
49
49
|
var resolvePinnedUrl = async (env, ipMode) => {
|
|
50
|
+
const override = require_balancer.getProviderListOverride(void 0, ipMode);
|
|
51
|
+
if (override.length > 0) {
|
|
52
|
+
const chosen = pickWeightedProvider(override, Math.random);
|
|
53
|
+
if (chosen) return chosen.url;
|
|
54
|
+
}
|
|
50
55
|
const base = applyIpModeToUrl(resolveBaseUrl(env), ipMode);
|
|
51
56
|
if (env === "development") return base;
|
|
52
57
|
const key = cacheKey(env, ipMode);
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "./_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { DEFAULT_DEVELOPMENT_PROVIDER_URL, getDevelopmentProviderUrl, readDevelopmentProviderUrlOverride } from "./developmentProviderUrl.js";
|
|
3
|
-
import {
|
|
3
|
+
import { readProviderListOverride } from "./providerUrlOverride.js";
|
|
4
|
+
import { convertHostedProvider, getLoadBalancerUrl, getProviderHostname, getProviderListOverride, loadBalancer, stripIpModeLabel } from "./balancer.js";
|
|
4
5
|
import { _resetHealthzRetryPolicy, _resetPinCache, _resetProviderListCache, _setHealthzRetryPolicy, getProviders, getRandomActiveProvider, getRandomProviderFromList } from "./providers.js";
|
|
5
|
-
export { DEFAULT_DEVELOPMENT_PROVIDER_URL, _resetHealthzRetryPolicy, _resetPinCache, _resetProviderListCache, _setHealthzRetryPolicy, convertHostedProvider, getDevelopmentProviderUrl, getLoadBalancerUrl, getProviderHostname, getProviders, getRandomActiveProvider, getRandomProviderFromList, loadBalancer, readDevelopmentProviderUrlOverride, stripIpModeLabel };
|
|
6
|
+
export { DEFAULT_DEVELOPMENT_PROVIDER_URL, _resetHealthzRetryPolicy, _resetPinCache, _resetProviderListCache, _setHealthzRetryPolicy, convertHostedProvider, getDevelopmentProviderUrl, getLoadBalancerUrl, getProviderHostname, getProviderListOverride, getProviders, getRandomActiveProvider, getRandomProviderFromList, loadBalancer, readDevelopmentProviderUrlOverride, readProviderListOverride, stripIpModeLabel };
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerUrlOverride.d.ts","sourceRoot":"","sources":["../src/providerUrlOverride.ts"],"names":[],"mappings":"AAqCA,eAAO,MAAM,wBAAwB,QAAO,MAAM,GAAG,SAMpD,CAAC"}
|