@prosopo/provider 5.12.2 → 5.13.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.
Files changed (69) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +13 -10
  2. package/.turbo/turbo-build$colon$tsc.log +27 -27
  3. package/.turbo/turbo-build.log +13 -10
  4. package/CHANGELOG.md +69 -0
  5. package/dist/api/captcha/assetSeal.d.ts +15 -0
  6. package/dist/api/captcha/assetSeal.d.ts.map +1 -0
  7. package/dist/api/captcha/assetSeal.js +22 -0
  8. package/dist/api/captcha/assetSeal.js.map +1 -0
  9. package/dist/api/captcha/assetSealFormat.d.ts +23 -0
  10. package/dist/api/captcha/assetSealFormat.d.ts.map +1 -0
  11. package/dist/api/captcha/assetSealFormat.js +87 -0
  12. package/dist/api/captcha/assetSealFormat.js.map +1 -0
  13. package/dist/api/captcha/getImageCaptchaChallenge.d.ts.map +1 -1
  14. package/dist/api/captcha/getImageCaptchaChallenge.js +2 -1
  15. package/dist/api/captcha/getImageCaptchaChallenge.js.map +1 -1
  16. package/dist/api/captcha/sealedAssetsResolver.d.ts +22 -0
  17. package/dist/api/captcha/sealedAssetsResolver.d.ts.map +1 -0
  18. package/dist/api/captcha/sealedAssetsResolver.js +69 -0
  19. package/dist/api/captcha/sealedAssetsResolver.js.map +1 -0
  20. package/dist/api/captcha/signedAssetsResolver.d.ts +2 -1
  21. package/dist/api/captcha/signedAssetsResolver.d.ts.map +1 -1
  22. package/dist/api/captcha/signedAssetsResolver.js +6 -5
  23. package/dist/api/captcha/signedAssetsResolver.js.map +1 -1
  24. package/dist/cjs/api/captcha/assetSeal.cjs +22 -0
  25. package/dist/cjs/api/captcha/assetSealFormat.cjs +95 -0
  26. package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +2 -1
  27. package/dist/cjs/api/captcha/sealedAssetsResolver.cjs +70 -0
  28. package/dist/cjs/api/captcha/signedAssetsResolver.cjs +6 -4
  29. package/dist/cjs/compositeIpAddress.cjs +44 -0
  30. package/dist/cjs/index.cjs +1 -0
  31. package/dist/cjs/tasks/captchaManager.cjs +15 -1
  32. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +12 -2
  33. package/dist/compositeIpAddress.d.ts +1 -0
  34. package/dist/compositeIpAddress.d.ts.map +1 -1
  35. package/dist/compositeIpAddress.js +44 -1
  36. package/dist/compositeIpAddress.js.map +1 -1
  37. package/dist/edge/assetSealHandler.d.ts +9 -0
  38. package/dist/edge/assetSealHandler.d.ts.map +1 -0
  39. package/dist/edge/assetSealHandler.js +74 -0
  40. package/dist/edge/assetSealHandler.js.map +1 -0
  41. package/dist/index.js +2 -2
  42. package/dist/tasks/captchaManager.d.ts +1 -1
  43. package/dist/tasks/captchaManager.d.ts.map +1 -1
  44. package/dist/tasks/captchaManager.js +15 -1
  45. package/dist/tasks/captchaManager.js.map +1 -1
  46. package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
  47. package/dist/tasks/powCaptcha/powTasks.js +13 -3
  48. package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
  49. package/dist/tests/unit/api/captcha/assetSeal.unit.test.d.ts +2 -0
  50. package/dist/tests/unit/api/captcha/assetSeal.unit.test.d.ts.map +1 -0
  51. package/dist/tests/unit/api/captcha/assetSeal.unit.test.js +132 -0
  52. package/dist/tests/unit/api/captcha/assetSeal.unit.test.js.map +1 -0
  53. package/dist/tests/unit/api/captcha/sealedAssetsResolver.unit.test.d.ts +2 -0
  54. package/dist/tests/unit/api/captcha/sealedAssetsResolver.unit.test.d.ts.map +1 -0
  55. package/dist/tests/unit/api/captcha/sealedAssetsResolver.unit.test.js +151 -0
  56. package/dist/tests/unit/api/captcha/sealedAssetsResolver.unit.test.js.map +1 -0
  57. package/dist/tests/unit/compositeIpAddress.unit.test.js +37 -1
  58. package/dist/tests/unit/compositeIpAddress.unit.test.js.map +1 -1
  59. package/dist/tests/unit/edge/assetSealHandler.unit.test.d.ts +2 -0
  60. package/dist/tests/unit/edge/assetSealHandler.unit.test.d.ts.map +1 -0
  61. package/dist/tests/unit/edge/assetSealHandler.unit.test.js +145 -0
  62. package/dist/tests/unit/edge/assetSealHandler.unit.test.js.map +1 -0
  63. package/dist/tests/unit/tasks/captchaManager.unit.test.js +41 -0
  64. package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -1
  65. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +100 -1
  66. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +1 -1
  67. package/edge/entry.ts +62 -0
  68. package/package.json +16 -14
  69. package/scripts/buildEdgeScript.mjs +31 -0
@@ -1 +1 @@
1
- {"version":3,"file":"getImageCaptchaChallenge.js","sourceRoot":"","sources":["../../../src/api/captcha/getImageCaptchaChallenge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"getImageCaptchaChallenge.js","sourceRoot":"","sources":["../../../src/api/captcha/getImageCaptchaChallenge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { Asset, AssetsResolver } from "@prosopo/types";
2
+ export declare const DEFAULT_ASSET_SEAL_TTL_SECONDS = 300;
3
+ export declare const DEFAULT_ASSET_SEAL_URL_PREFIX = "s";
4
+ export interface SealedAssetsResolverOptions {
5
+ readonly key: Uint8Array;
6
+ readonly keyId: number;
7
+ readonly ttlSeconds?: number;
8
+ readonly urlPrefix?: string;
9
+ readonly now?: () => number;
10
+ }
11
+ export declare class SealedAssetsResolver implements AssetsResolver {
12
+ private readonly key;
13
+ private readonly keyId;
14
+ private readonly ttlSeconds;
15
+ private readonly urlPrefix;
16
+ private readonly now;
17
+ constructor(options: SealedAssetsResolverOptions);
18
+ resolveAsset(assetURI: string): Asset;
19
+ private toUrl;
20
+ }
21
+ export declare function getSealedAssetsResolver(): AssetsResolver | undefined;
22
+ //# sourceMappingURL=sealedAssetsResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sealedAssetsResolver.d.ts","sourceRoot":"","sources":["../../../src/api/captcha/sealedAssetsResolver.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAI5D,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED,qBAAa,oBAAqB,YAAW,cAAc;IAC1D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,OAAO,EAAE,2BAA2B;IAQhD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK;IAyBrC,OAAO,CAAC,KAAK;CAUb;AAYD,wBAAgB,uBAAuB,IAAI,cAAc,GAAG,SAAS,CA2BpE"}
@@ -0,0 +1,69 @@
1
+ import { parseSealKeys } from "./assetSealFormat.js";
2
+ import { sealAssetPath } from "./assetSeal.js";
3
+ var SealedAssetsResolver = class {
4
+ constructor(options) {
5
+ this.key = options.key;
6
+ this.keyId = options.keyId;
7
+ this.ttlSeconds = options.ttlSeconds ?? 300;
8
+ this.urlPrefix = options.urlPrefix ?? "s";
9
+ this.now = options.now ?? (() => Date.now());
10
+ }
11
+ resolveAsset(assetURI) {
12
+ const url = this.toUrl(assetURI);
13
+ if (!url) return {
14
+ URI: assetURI,
15
+ getURL: () => assetURI
16
+ };
17
+ if (url.search !== "") throw new Error(`Cannot seal an asset URL that has a query string: ${assetURI}`);
18
+ const blob = sealAssetPath({
19
+ path: url.pathname,
20
+ key: this.key,
21
+ keyId: this.keyId,
22
+ expiresAtSeconds: Math.floor(this.now() / 1e3) + this.ttlSeconds
23
+ });
24
+ const sealed = `${url.origin}/${this.urlPrefix}/${blob}${extensionOf(url.pathname)}`;
25
+ return {
26
+ URI: assetURI,
27
+ getURL: () => sealed
28
+ };
29
+ }
30
+ toUrl(assetURI) {
31
+ try {
32
+ const url = new URL(assetURI);
33
+ return url.protocol === "http:" || url.protocol === "https:" ? url : void 0;
34
+ } catch {
35
+ return;
36
+ }
37
+ }
38
+ };
39
+ var extensionOf = (pathname) => {
40
+ const lastDot = pathname.lastIndexOf(".");
41
+ if (lastDot <= pathname.lastIndexOf("/") + 1) return "";
42
+ const extension = pathname.slice(lastDot);
43
+ return /^\.[a-zA-Z0-9]{1,8}$/.test(extension) ? extension : "";
44
+ };
45
+ function getSealedAssetsResolver() {
46
+ const spec = process.env.PROSOPO_ASSET_SEAL_KEYS;
47
+ if (!spec) return;
48
+ const keys = parseSealKeys(spec);
49
+ const keyId = activeKeyId(keys);
50
+ const key = keys.get(keyId);
51
+ if (!key) throw new Error(`PROSOPO_ASSET_SEAL_ACTIVE_KEY_ID ${keyId} is not in PROSOPO_ASSET_SEAL_KEYS`);
52
+ return new SealedAssetsResolver({
53
+ key,
54
+ keyId,
55
+ ttlSeconds: Number.parseInt(process.env.PROSOPO_ASSET_SEAL_TTL_SECONDS ?? "", 10) || 300,
56
+ urlPrefix: process.env.PROSOPO_ASSET_SEAL_URL_PREFIX || "s"
57
+ });
58
+ }
59
+ var activeKeyId = (keys) => {
60
+ const configured = process.env.PROSOPO_ASSET_SEAL_ACTIVE_KEY_ID;
61
+ if (configured) {
62
+ const parsed = Number.parseInt(configured, 10);
63
+ if (!Number.isInteger(parsed)) throw new Error("PROSOPO_ASSET_SEAL_ACTIVE_KEY_ID must be an integer");
64
+ return parsed;
65
+ }
66
+ return Math.max(...keys.keys());
67
+ };
68
+ //#endregion
69
+ export { SealedAssetsResolver, getSealedAssetsResolver };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sealedAssetsResolver.js","sourceRoot":"","sources":["../../../src/api/captcha/sealedAssetsResolver.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
+ import { DEFAULT_ASSET_TOKEN_TTL_SECONDS } from "@prosopo/datasets";
1
2
  import type { Asset, AssetsResolver } from "@prosopo/types";
2
- export declare const DEFAULT_ASSET_TOKEN_TTL_SECONDS = 300;
3
+ export { DEFAULT_ASSET_TOKEN_TTL_SECONDS };
3
4
  export interface SignedAssetsResolverOptions {
4
5
  securityKey: string;
5
6
  ttlSeconds?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"signedAssetsResolver.d.ts","sourceRoot":"","sources":["../../../src/api/captcha/signedAssetsResolver.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE5D,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD,MAAM,WAAW,2BAA2B;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACnB;AAED,qBAAa,oBAAqB,YAAW,cAAc;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,OAAO,EAAE,2BAA2B;IAOhD,OAAO,CAAC,IAAI;IAUZ,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK;IA0BrC,OAAO,CAAC,KAAK;CAUb;AAQD,wBAAgB,uBAAuB,CACtC,QAAQ,CAAC,EAAE,MAAM,GACf,cAAc,GAAG,SAAS,CAqB5B"}
1
+ {"version":3,"file":"signedAssetsResolver.d.ts","sourceRoot":"","sources":["../../../src/api/captcha/signedAssetsResolver.ts"],"names":[],"mappings":"AAmCA,OAAO,EACN,+BAA+B,EAG/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,+BAA+B,EAAE,CAAC;AAE3C,MAAM,WAAW,2BAA2B;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACnB;AAED,qBAAa,oBAAqB,YAAW,cAAc;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,OAAO,EAAE,2BAA2B;IAOhD,OAAO,CAAC,IAAI;IAYZ,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK;IA0BrC,OAAO,CAAC,KAAK;CAUb;AAQD,wBAAgB,uBAAuB,CACtC,QAAQ,CAAC,EAAE,MAAM,GACf,cAAc,GAAG,SAAS,CAqB5B"}
@@ -1,14 +1,15 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { DEFAULT_ASSET_TOKEN_TTL_SECONDS, assetTokenBase, encodeAssetToken } from "@prosopo/datasets";
3
+ //#region src/api/captcha/signedAssetsResolver.ts
2
4
  var SignedAssetsResolver = class {
3
5
  constructor(options) {
4
6
  this.securityKey = options.securityKey;
5
- this.ttlSeconds = options.ttlSeconds ?? 300;
7
+ this.ttlSeconds = options.ttlSeconds ?? DEFAULT_ASSET_TOKEN_TTL_SECONDS;
6
8
  this.clientIp = options.clientIp;
7
9
  this.now = options.now ?? (() => Date.now());
8
10
  }
9
11
  sign(path, expires) {
10
- const base = `${this.securityKey}${path}${expires}${this.clientIp ?? ""}`;
11
- return createHash("sha256").update(base).digest("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
12
+ return encodeAssetToken(new Uint8Array(createHash("sha256").update(assetTokenBase(this.securityKey, path, expires, this.clientIp)).digest()));
12
13
  }
13
14
  resolveAsset(assetURI) {
14
15
  const url = this.toUrl(assetURI);
@@ -45,9 +46,9 @@ function getSignedAssetsResolver(clientIp) {
45
46
  if (!securityKey) return;
46
47
  return new SignedAssetsResolver({
47
48
  securityKey,
48
- ttlSeconds: Number.parseInt(process.env.PROSOPO_ASSET_TOKEN_TTL_SECONDS ?? "", 10) || 300,
49
+ ttlSeconds: Number.parseInt(process.env.PROSOPO_ASSET_TOKEN_TTL_SECONDS ?? "", 10) || DEFAULT_ASSET_TOKEN_TTL_SECONDS,
49
50
  ...process.env.PROSOPO_ASSET_TOKEN_BIND_IP === "true" && clientIp ? { clientIp } : {}
50
51
  });
51
52
  }
52
53
  //#endregion
53
- export { SignedAssetsResolver, getSignedAssetsResolver };
54
+ export { DEFAULT_ASSET_TOKEN_TTL_SECONDS, SignedAssetsResolver, getSignedAssetsResolver };
@@ -1 +1 @@
1
- {"version":3,"file":"signedAssetsResolver.js","sourceRoot":"","sources":["../../../src/api/captcha/signedAssetsResolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"signedAssetsResolver.js","sourceRoot":"","sources":["../../../src/api/captcha/signedAssetsResolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ const require_assetSealFormat = require("./assetSealFormat.cjs");
2
+ let node_crypto = require("node:crypto");
3
+ //#region src/api/captcha/assetSeal.ts
4
+ var CIPHER = "aes-256-gcm";
5
+ var GCM_OPTIONS = { authTagLength: 16 };
6
+ var sealAssetPath = (params) => {
7
+ if (!require_assetSealFormat.isSafeAssetPath(params.path)) throw new Error(`Refusing to seal an unusable asset path: ${params.path}`);
8
+ const iv = (0, node_crypto.randomBytes)(12);
9
+ const cipher = (0, node_crypto.createCipheriv)(CIPHER, params.key, iv, GCM_OPTIONS);
10
+ cipher.setAAD(require_assetSealFormat.additionalData(params.keyId));
11
+ const ciphertext = Buffer.concat([cipher.update(require_assetSealFormat.encodePayload({
12
+ expiresAtSeconds: params.expiresAtSeconds,
13
+ path: params.path
14
+ })), cipher.final()]);
15
+ return require_assetSealFormat.encodeEnvelope({
16
+ keyId: params.keyId,
17
+ iv: new Uint8Array(iv),
18
+ sealed: new Uint8Array(Buffer.concat([ciphertext, cipher.getAuthTag()]))
19
+ });
20
+ };
21
+ //#endregion
22
+ exports.sealAssetPath = sealAssetPath;
@@ -0,0 +1,95 @@
1
+ var AAD_BYTES = 2;
2
+ var EXPIRY_BYTES = 4;
3
+ var MAX_KEY_ID = 255;
4
+ var BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;
5
+ var textEncoder = new TextEncoder();
6
+ var textDecoder = new TextDecoder("utf-8", { fatal: true });
7
+ var toBase64Url = (bytes) => {
8
+ let binary = "";
9
+ for (const byte of bytes) binary += String.fromCharCode(byte);
10
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
11
+ };
12
+ var fromBase64Url = (value) => {
13
+ if (!BASE64URL_PATTERN.test(value)) return;
14
+ const normalised = value.replace(/-/g, "+").replace(/_/g, "/");
15
+ const padded = normalised.padEnd(normalised.length + (4 - normalised.length % 4) % 4, "=");
16
+ try {
17
+ const binary = atob(padded);
18
+ const bytes = new Uint8Array(binary.length);
19
+ for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
20
+ return bytes;
21
+ } catch {
22
+ return;
23
+ }
24
+ };
25
+ var additionalData = (keyId) => new Uint8Array([1, keyId]);
26
+ var encodeEnvelope = (envelope) => {
27
+ const bytes = new Uint8Array(AAD_BYTES + envelope.iv.length + envelope.sealed.length);
28
+ bytes.set(additionalData(envelope.keyId), 0);
29
+ bytes.set(envelope.iv, AAD_BYTES);
30
+ bytes.set(envelope.sealed, AAD_BYTES + envelope.iv.length);
31
+ return toBase64Url(bytes);
32
+ };
33
+ var decodeEnvelope = (blob) => {
34
+ const bytes = fromBase64Url(blob);
35
+ if (!bytes || bytes.length <= 14) return;
36
+ if (bytes[0] !== 1) return;
37
+ const keyId = bytes[1];
38
+ if (void 0 === keyId) return;
39
+ return {
40
+ keyId,
41
+ iv: bytes.slice(AAD_BYTES, 14),
42
+ sealed: bytes.slice(14)
43
+ };
44
+ };
45
+ var encodePayload = (payload) => {
46
+ const path = textEncoder.encode(payload.path);
47
+ const bytes = new Uint8Array(EXPIRY_BYTES + path.length);
48
+ new DataView(bytes.buffer).setUint32(0, payload.expiresAtSeconds, false);
49
+ bytes.set(path, EXPIRY_BYTES);
50
+ return bytes;
51
+ };
52
+ var decodePayload = (bytes) => {
53
+ if (bytes.length <= EXPIRY_BYTES) return;
54
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
55
+ try {
56
+ return {
57
+ expiresAtSeconds: view.getUint32(0, false),
58
+ path: textDecoder.decode(bytes.subarray(EXPIRY_BYTES))
59
+ };
60
+ } catch {
61
+ return;
62
+ }
63
+ };
64
+ var isSafeAssetPath = (path, requiredPrefix) => {
65
+ if (!path.startsWith("/") || path.length > 512) return false;
66
+ if (path.includes("..") || path.includes("//")) return false;
67
+ if (/[\u0000-\u001f\u007f]/.test(path)) return false;
68
+ return void 0 === requiredPrefix || path.startsWith(requiredPrefix);
69
+ };
70
+ var parseSealKeys = (spec) => {
71
+ const keys = /* @__PURE__ */ new Map();
72
+ for (const entry of spec.split(",")) {
73
+ const trimmed = entry.trim();
74
+ if ("" === trimmed) continue;
75
+ const separator = trimmed.indexOf(":");
76
+ if (separator <= 0) throw new Error("Malformed seal key entry: expected \"keyId:base64key\"");
77
+ const keyId = Number(trimmed.slice(0, separator));
78
+ if (!Number.isInteger(keyId) || keyId < 0 || keyId > MAX_KEY_ID) throw new Error(`Seal key id must be an integer in [0, ${MAX_KEY_ID}]`);
79
+ const key = fromBase64Url(trimmed.slice(separator + 1).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""));
80
+ if (!key || key.length !== 32) throw new Error(`Seal key ${keyId} must be 32 base64-encoded bytes`);
81
+ keys.set(keyId, key);
82
+ }
83
+ if (0 === keys.size) throw new Error("No seal keys configured");
84
+ return keys;
85
+ };
86
+ //#endregion
87
+ exports.additionalData = additionalData;
88
+ exports.decodeEnvelope = decodeEnvelope;
89
+ exports.decodePayload = decodePayload;
90
+ exports.encodeEnvelope = encodeEnvelope;
91
+ exports.encodePayload = encodePayload;
92
+ exports.fromBase64Url = fromBase64Url;
93
+ exports.isSafeAssetPath = isSafeAssetPath;
94
+ exports.parseSealKeys = parseSealKeys;
95
+ exports.toBase64Url = toBase64Url;
@@ -7,6 +7,7 @@ const require_testSiteKey = require("../testSiteKey.cjs");
7
7
  const require_normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
8
8
  const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
9
9
  const require_trafficFilterRequestTime = require("./trafficFilterRequestTime.cjs");
10
+ const require_sealedAssetsResolver = require("./sealedAssetsResolver.cjs");
10
11
  const require_signedAssetsResolver = require("./signedAssetsResolver.cjs");
11
12
  let _prosopo_common = require("@prosopo/common");
12
13
  let _prosopo_types = require("@prosopo/types");
@@ -112,7 +113,7 @@ var getImageCaptchaChallenge_default = (env, userAccessRulesStorage) => async (r
112
113
  }));
113
114
  });
114
115
  const taskData = await tasks.imgCaptchaManager.getRandomCaptchasAndRequestHash(datasetId, user, ipAddress, captchaConfig, clientRecord.settings.imageThreshold ?? .8, validSessionId, req.ipInfo);
115
- const assetsResolver = require_signedAssetsResolver.getSignedAssetsResolver(ipAddress.toString()) ?? env.assetsResolver;
116
+ const assetsResolver = require_sealedAssetsResolver.getSealedAssetsResolver() ?? require_signedAssetsResolver.getSignedAssetsResolver(ipAddress.toString()) ?? env.assetsResolver;
116
117
  const captchaResponse = {
117
118
  [_prosopo_types.ApiParams.status]: "ok",
118
119
  [_prosopo_types.ApiParams.captchas]: taskData.captchas.map((captcha) => ({
@@ -0,0 +1,70 @@
1
+ const require_assetSealFormat = require("./assetSealFormat.cjs");
2
+ const require_assetSeal = require("./assetSeal.cjs");
3
+ var SealedAssetsResolver = class {
4
+ constructor(options) {
5
+ this.key = options.key;
6
+ this.keyId = options.keyId;
7
+ this.ttlSeconds = options.ttlSeconds ?? 300;
8
+ this.urlPrefix = options.urlPrefix ?? "s";
9
+ this.now = options.now ?? (() => Date.now());
10
+ }
11
+ resolveAsset(assetURI) {
12
+ const url = this.toUrl(assetURI);
13
+ if (!url) return {
14
+ URI: assetURI,
15
+ getURL: () => assetURI
16
+ };
17
+ if (url.search !== "") throw new Error(`Cannot seal an asset URL that has a query string: ${assetURI}`);
18
+ const blob = require_assetSeal.sealAssetPath({
19
+ path: url.pathname,
20
+ key: this.key,
21
+ keyId: this.keyId,
22
+ expiresAtSeconds: Math.floor(this.now() / 1e3) + this.ttlSeconds
23
+ });
24
+ const sealed = `${url.origin}/${this.urlPrefix}/${blob}${extensionOf(url.pathname)}`;
25
+ return {
26
+ URI: assetURI,
27
+ getURL: () => sealed
28
+ };
29
+ }
30
+ toUrl(assetURI) {
31
+ try {
32
+ const url = new URL(assetURI);
33
+ return url.protocol === "http:" || url.protocol === "https:" ? url : void 0;
34
+ } catch {
35
+ return;
36
+ }
37
+ }
38
+ };
39
+ var extensionOf = (pathname) => {
40
+ const lastDot = pathname.lastIndexOf(".");
41
+ if (lastDot <= pathname.lastIndexOf("/") + 1) return "";
42
+ const extension = pathname.slice(lastDot);
43
+ return /^\.[a-zA-Z0-9]{1,8}$/.test(extension) ? extension : "";
44
+ };
45
+ function getSealedAssetsResolver() {
46
+ const spec = process.env.PROSOPO_ASSET_SEAL_KEYS;
47
+ if (!spec) return;
48
+ const keys = require_assetSealFormat.parseSealKeys(spec);
49
+ const keyId = activeKeyId(keys);
50
+ const key = keys.get(keyId);
51
+ if (!key) throw new Error(`PROSOPO_ASSET_SEAL_ACTIVE_KEY_ID ${keyId} is not in PROSOPO_ASSET_SEAL_KEYS`);
52
+ return new SealedAssetsResolver({
53
+ key,
54
+ keyId,
55
+ ttlSeconds: Number.parseInt(process.env.PROSOPO_ASSET_SEAL_TTL_SECONDS ?? "", 10) || 300,
56
+ urlPrefix: process.env.PROSOPO_ASSET_SEAL_URL_PREFIX || "s"
57
+ });
58
+ }
59
+ var activeKeyId = (keys) => {
60
+ const configured = process.env.PROSOPO_ASSET_SEAL_ACTIVE_KEY_ID;
61
+ if (configured) {
62
+ const parsed = Number.parseInt(configured, 10);
63
+ if (!Number.isInteger(parsed)) throw new Error("PROSOPO_ASSET_SEAL_ACTIVE_KEY_ID must be an integer");
64
+ return parsed;
65
+ }
66
+ return Math.max(...keys.keys());
67
+ };
68
+ //#endregion
69
+ exports.SealedAssetsResolver = SealedAssetsResolver;
70
+ exports.getSealedAssetsResolver = getSealedAssetsResolver;
@@ -1,14 +1,15 @@
1
1
  let node_crypto = require("node:crypto");
2
+ let _prosopo_datasets = require("@prosopo/datasets");
3
+ //#region src/api/captcha/signedAssetsResolver.ts
2
4
  var SignedAssetsResolver = class {
3
5
  constructor(options) {
4
6
  this.securityKey = options.securityKey;
5
- this.ttlSeconds = options.ttlSeconds ?? 300;
7
+ this.ttlSeconds = options.ttlSeconds ?? _prosopo_datasets.DEFAULT_ASSET_TOKEN_TTL_SECONDS;
6
8
  this.clientIp = options.clientIp;
7
9
  this.now = options.now ?? (() => Date.now());
8
10
  }
9
11
  sign(path, expires) {
10
- const base = `${this.securityKey}${path}${expires}${this.clientIp ?? ""}`;
11
- return (0, node_crypto.createHash)("sha256").update(base).digest("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
12
+ return (0, _prosopo_datasets.encodeAssetToken)(new Uint8Array((0, node_crypto.createHash)("sha256").update((0, _prosopo_datasets.assetTokenBase)(this.securityKey, path, expires, this.clientIp)).digest()));
12
13
  }
13
14
  resolveAsset(assetURI) {
14
15
  const url = this.toUrl(assetURI);
@@ -45,10 +46,11 @@ function getSignedAssetsResolver(clientIp) {
45
46
  if (!securityKey) return;
46
47
  return new SignedAssetsResolver({
47
48
  securityKey,
48
- ttlSeconds: Number.parseInt(process.env.PROSOPO_ASSET_TOKEN_TTL_SECONDS ?? "", 10) || 300,
49
+ ttlSeconds: Number.parseInt(process.env.PROSOPO_ASSET_TOKEN_TTL_SECONDS ?? "", 10) || _prosopo_datasets.DEFAULT_ASSET_TOKEN_TTL_SECONDS,
49
50
  ...process.env.PROSOPO_ASSET_TOKEN_BIND_IP === "true" && clientIp ? { clientIp } : {}
50
51
  });
51
52
  }
52
53
  //#endregion
54
+ exports.DEFAULT_ASSET_TOKEN_TTL_SECONDS = _prosopo_datasets.DEFAULT_ASSET_TOKEN_TTL_SECONDS;
53
55
  exports.SignedAssetsResolver = SignedAssetsResolver;
54
56
  exports.getSignedAssetsResolver = getSignedAssetsResolver;
@@ -38,9 +38,53 @@ var getIpAddressFromComposite = (compositeIpAddress) => {
38
38
  }
39
39
  };
40
40
  var getBigInt = (number) => BigInt(number || 0n);
41
+ /**
42
+ * Mongo hands these back as Decimal128 rather than the `number | bigint` the
43
+ * type promises, and `BigInt(Decimal128)` throws. Route through the string
44
+ * form, and report a value we cannot read as absent rather than throwing.
45
+ */
46
+ var readPart = (value) => {
47
+ if (value === void 0 || value === null) return void 0;
48
+ try {
49
+ return BigInt(value.toString());
50
+ } catch {
51
+ return;
52
+ }
53
+ };
54
+ /**
55
+ * The value `getCompositeIpAddress` returns when it could not read an
56
+ * address at all. 0.0.0.0 is not a client address, so nothing legitimate is
57
+ * being swallowed by treating it as "we don't know".
58
+ */
59
+ var isUnknownIp = (ip) => ip.type === _prosopo_types.IpAddressType.v4 && readPart(ip.lower) === 0n;
60
+ /**
61
+ * Do two observations of a client come from the same place on the network?
62
+ *
63
+ * v4 is compared exactly. v6 is compared on the /64 prefix alone — the
64
+ * interface identifier in the low 64 bits is designed to rotate (RFC 8981
65
+ * privacy extensions), often several times a day on one unchanged connection,
66
+ * so comparing it would call an ordinary phone a different host.
67
+ *
68
+ * A value we do not actually have counts as the same — one that will not
69
+ * parse, or the all-zero v4 `getCompositeIpAddress` returns when handed an
70
+ * address it could not read. This answer gates extra friction for a real
71
+ * user, and a gap in what we recorded is not evidence against them.
72
+ */
73
+ var isSameIpOrigin = (a, b) => {
74
+ if (isUnknownIp(a) || isUnknownIp(b)) return true;
75
+ if (a.type !== b.type) return false;
76
+ const compare = (left, right) => {
77
+ const leftPart = readPart(left);
78
+ const rightPart = readPart(right);
79
+ if (leftPart === void 0 || rightPart === void 0) return true;
80
+ return leftPart === rightPart;
81
+ };
82
+ return a.type === _prosopo_types.IpAddressType.v6 ? compare(a.upper, b.upper) : compare(a.lower, b.lower);
83
+ };
41
84
  var never = () => {
42
85
  throw new Error("Unhandled type");
43
86
  };
44
87
  //#endregion
45
88
  exports.getCompositeIpAddress = getCompositeIpAddress;
46
89
  exports.getIpAddressFromComposite = getIpAddressFromComposite;
90
+ exports.isSameIpOrigin = isSameIpOrigin;
@@ -50,6 +50,7 @@ exports.getVerdictCache = require_blacklistRequestInspector.getVerdictCache;
50
50
  exports.handshakeTimingMiddleware = require_handshakeTimingMiddleware.handshakeTimingMiddleware;
51
51
  exports.headerCheckMiddleware = require_headerCheckMiddleware.headerCheckMiddleware;
52
52
  exports.ignoreMiddleware = require_ignoreMiddleware.ignoreMiddleware;
53
+ exports.isSameIpOrigin = require_compositeIpAddress.isSameIpOrigin;
53
54
  exports.isTlsAvailable = require_startProviderApi.isTlsAvailable;
54
55
  exports.ja4Middleware = require_ja4Middleware.ja4Middleware;
55
56
  exports.migrateFrictionlessLadder = require_frictionlessLadder.migrateFrictionlessLadder;
@@ -564,8 +564,22 @@ var CaptchaManager = class CaptchaManager {
564
564
  const ipInfo = currentIp ? await env.ipInfoService.lookup(currentIp) : recordIpInfo;
565
565
  return require_checkTrafficFilter.checkTrafficFilter(ipInfo, effective, require_enrichDnsEvent.extraIpInfosFromEnrichedDnsEvent(enrichedDnsEvent), enrichedDnsEvent?.pathValid);
566
566
  }
567
+ /**
568
+ * Does this client's tier entitle it to the bot score, and is there one?
569
+ *
570
+ * `score !== undefined`, not `score`: a session with nothing wrong with it
571
+ * scores 0, and a truthiness test dropped the field for exactly those
572
+ * users — a paying customer reading `score` got a present field for
573
+ * every suspicious visitor and a missing one for their cleanest. It has
574
+ * been invisible because `Math.random() * 0.3` makes an exact 0 all but
575
+ * impossible; taking that noise out (see captcha-private#4433) is what
576
+ * would expose it.
577
+ *
578
+ * Returning `boolean` rather than the old `number | boolean | undefined`,
579
+ * which came from `&&`-chaining the score and the tier.
580
+ */
567
581
  static canClientSeeScore(tier, score) {
568
- return score && tier && tier !== _prosopo_types.Tier.Free;
582
+ return score !== void 0 && tier !== _prosopo_types.Tier.Free;
569
583
  }
570
584
  };
571
585
  //#endregion
@@ -190,14 +190,24 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
190
190
  await Promise.all(writePromises);
191
191
  if (!correct) return { verified: correct };
192
192
  const escalateForMissingCoords = !coords && Boolean(challengeRecord.sessionId);
193
+ const solveIp = require_compositeIpAddress.getCompositeIpAddress(ipAddress);
194
+ const escalateForIpChange = Boolean(challengeRecord.sessionId) && !require_compositeIpAddress.isSameIpOrigin(challengeRecord.ipAddress, solveIp);
195
+ if (escalateForIpChange) this.logger.info(() => ({
196
+ msg: "PoW solve arrived from a different address than the challenge",
197
+ data: {
198
+ challenge,
199
+ issuedType: challengeRecord.ipAddress.type,
200
+ solvedType: solveIp.type
201
+ }
202
+ }));
193
203
  let routingOutput = this.postPowContext ? await this.runPostPowRouting({
194
204
  challengeRecord,
195
205
  challengeSplit,
196
206
  behavioralDataPacked: decryptedBehavioralDataPacked
197
207
  }) : void 0;
198
- if (escalateForMissingCoords && routingOutput?.captchaType !== _prosopo_types.CaptchaType.image && routingOutput?.captchaType !== _prosopo_types.CaptchaType.puzzle) routingOutput = {
208
+ if ((escalateForMissingCoords || escalateForIpChange) && routingOutput?.captchaType !== _prosopo_types.CaptchaType.image && routingOutput?.captchaType !== _prosopo_types.CaptchaType.puzzle) routingOutput = {
199
209
  captchaType: _prosopo_types.CaptchaType.image,
200
- reason: _prosopo_types.FrictionlessReason.MISSING_COORDINATES
210
+ reason: escalateForMissingCoords ? _prosopo_types.FrictionlessReason.MISSING_COORDINATES : _prosopo_types.FrictionlessReason.IP_CHANGED
201
211
  };
202
212
  return {
203
213
  verified: correct,
@@ -2,4 +2,5 @@ import type { IPAddress } from "@prosopo/types";
2
2
  import { type CompositeIpAddress } from "@prosopo/types";
3
3
  export declare const getCompositeIpAddress: (ip: string | IPAddress) => CompositeIpAddress;
4
4
  export declare const getIpAddressFromComposite: (compositeIpAddress: CompositeIpAddress) => IPAddress;
5
+ export declare const isSameIpOrigin: (a: CompositeIpAddress, b: CompositeIpAddress) => boolean;
5
6
  //# sourceMappingURL=compositeIpAddress.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compositeIpAddress.d.ts","sourceRoot":"","sources":["../src/compositeIpAddress.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,kBAAkB,EAAiB,MAAM,gBAAgB,CAAC;AAOxE,eAAO,MAAM,qBAAqB,OAC7B,MAAM,GAAG,SAAS,KACpB,kBAaF,CAAC;AAuBF,eAAO,MAAM,yBAAyB,uBACjB,kBAAkB,KACpC,SAaF,CAAC"}
1
+ {"version":3,"file":"compositeIpAddress.d.ts","sourceRoot":"","sources":["../src/compositeIpAddress.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,kBAAkB,EAAiB,MAAM,gBAAgB,CAAC;AAOxE,eAAO,MAAM,qBAAqB,OAC7B,MAAM,GAAG,SAAS,KACpB,kBAaF,CAAC;AAuBF,eAAO,MAAM,yBAAyB,uBACjB,kBAAkB,KACpC,SAaF,CAAC;AAuCF,eAAO,MAAM,cAAc,MACvB,kBAAkB,KAClB,kBAAkB,KACnB,OAiBF,CAAC"}
@@ -38,8 +38,51 @@ var getIpAddressFromComposite = (compositeIpAddress) => {
38
38
  }
39
39
  };
40
40
  var getBigInt = (number) => BigInt(number || 0n);
41
+ /**
42
+ * Mongo hands these back as Decimal128 rather than the `number | bigint` the
43
+ * type promises, and `BigInt(Decimal128)` throws. Route through the string
44
+ * form, and report a value we cannot read as absent rather than throwing.
45
+ */
46
+ var readPart = (value) => {
47
+ if (value === void 0 || value === null) return void 0;
48
+ try {
49
+ return BigInt(value.toString());
50
+ } catch {
51
+ return;
52
+ }
53
+ };
54
+ /**
55
+ * The value `getCompositeIpAddress` returns when it could not read an
56
+ * address at all. 0.0.0.0 is not a client address, so nothing legitimate is
57
+ * being swallowed by treating it as "we don't know".
58
+ */
59
+ var isUnknownIp = (ip) => ip.type === IpAddressType.v4 && readPart(ip.lower) === 0n;
60
+ /**
61
+ * Do two observations of a client come from the same place on the network?
62
+ *
63
+ * v4 is compared exactly. v6 is compared on the /64 prefix alone — the
64
+ * interface identifier in the low 64 bits is designed to rotate (RFC 8981
65
+ * privacy extensions), often several times a day on one unchanged connection,
66
+ * so comparing it would call an ordinary phone a different host.
67
+ *
68
+ * A value we do not actually have counts as the same — one that will not
69
+ * parse, or the all-zero v4 `getCompositeIpAddress` returns when handed an
70
+ * address it could not read. This answer gates extra friction for a real
71
+ * user, and a gap in what we recorded is not evidence against them.
72
+ */
73
+ var isSameIpOrigin = (a, b) => {
74
+ if (isUnknownIp(a) || isUnknownIp(b)) return true;
75
+ if (a.type !== b.type) return false;
76
+ const compare = (left, right) => {
77
+ const leftPart = readPart(left);
78
+ const rightPart = readPart(right);
79
+ if (leftPart === void 0 || rightPart === void 0) return true;
80
+ return leftPart === rightPart;
81
+ };
82
+ return a.type === IpAddressType.v6 ? compare(a.upper, b.upper) : compare(a.lower, b.lower);
83
+ };
41
84
  var never = () => {
42
85
  throw new Error("Unhandled type");
43
86
  };
44
87
  //#endregion
45
- export { getCompositeIpAddress, getIpAddressFromComposite };
88
+ export { getCompositeIpAddress, getIpAddressFromComposite, isSameIpOrigin };
@@ -1 +1 @@
1
- {"version":3,"file":"compositeIpAddress.js","sourceRoot":"","sources":["../src/compositeIpAddress.ts"],"names":[],"mappings":"AAeA,OAAO,EAA2B,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,QAAQ,GAAG,GAAG,CAAC;AACrB,MAAM,aAAa,GAAG,CAAC,EAAE,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC;AAE5C,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACpC,EAAsB,EACD,EAAE;IACvB,IAAI,SAAoB,CAAC;IAEzB,IAAI,CAAC;QACJ,SAAS,GAAG,QAAQ,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,OAAO;YACN,KAAK,EAAE,EAAE;YACT,IAAI,EAAE,aAAa,CAAC,EAAE;SACtB,CAAC;IACH,CAAC;IAED,OAAO,yBAAyB,CAAC,SAAS,CAAC,CAAC;AAC7C,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CACjC,SAAoB,EACC,EAAE;IACvB,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;IAErC,IAAI,SAAS,YAAY,QAAQ,EAAE,CAAC;QACnC,OAAO;YACN,KAAK,EAAE,SAAS;YAChB,IAAI,EAAE,aAAa,CAAC,EAAE;SACtB,CAAC;IACH,CAAC;IAED,SAA4B,CAAC;IAE7B,OAAO;QACN,KAAK,EAAE,SAAS,GAAG,aAAa;QAChC,KAAK,EAAE,SAAS,IAAI,QAAQ;QAC5B,IAAI,EAAE,aAAa,CAAC,EAAE;KACtB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACxC,kBAAsC,EAC1B,EAAE;IACd,QAAQ,kBAAkB,CAAC,IAAI,EAAE,CAAC;QACjC,KAAK,aAAa,CAAC,EAAE;YACpB,OAAO,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;QACjE,KAAK,aAAa,CAAC,EAAE;YACpB,OAAO,QAAQ,CAAC,UAAU,CACzB,CAAC,SAAS,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC;gBAChD,CAAC,SAAS,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,aAAa,CAAC,CACtD,CAAC;QACH;YACC,KAAK,EAAE,CAAC;YACR,OAAO,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;AACF,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,MAAmC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAEhF,MAAM,KAAK,GAAG,GAAU,EAAE;IACzB,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;AACnC,CAAC,CAAC"}
1
+ {"version":3,"file":"compositeIpAddress.js","sourceRoot":"","sources":["../src/compositeIpAddress.ts"],"names":[],"mappings":"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"}