@prosopo/provider 5.9.0 → 5.10.1

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 (83) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +13 -12
  2. package/.turbo/turbo-build$colon$tsc.log +27 -27
  3. package/.turbo/turbo-build.log +14 -13
  4. package/CHANGELOG.md +82 -0
  5. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.d.ts.map +1 -1
  6. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +5 -1
  7. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js.map +1 -1
  8. package/dist/api/captcha/submitPoWCaptchaSolution.js +51 -11
  9. package/dist/api/captcha/submitPoWCaptchaSolution.js.map +1 -1
  10. package/dist/api/healthzGeo.d.ts +54 -0
  11. package/dist/api/healthzGeo.d.ts.map +1 -0
  12. package/dist/api/healthzGeo.js +205 -0
  13. package/dist/api/healthzGeo.js.map +1 -0
  14. package/dist/api/metrics.d.ts +3 -0
  15. package/dist/api/metrics.d.ts.map +1 -1
  16. package/dist/api/metrics.js +11 -1
  17. package/dist/api/metrics.js.map +1 -1
  18. package/dist/api/public.d.ts.map +1 -1
  19. package/dist/api/public.js +13 -3
  20. package/dist/api/public.js.map +1 -1
  21. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +5 -1
  22. package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +51 -11
  23. package/dist/cjs/api/healthzGeo.cjs +209 -0
  24. package/dist/cjs/api/metrics.cjs +11 -0
  25. package/dist/cjs/api/public.cjs +13 -2
  26. package/dist/cjs/services/ipComparison.cjs +4 -2
  27. package/dist/cjs/tasks/detection/decodePayload.cjs +1126 -983
  28. package/dist/cjs/tasks/detection/decodePayload.js +1 -2
  29. package/dist/cjs/tasks/detection/getBotScore.cjs +28 -1
  30. package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +97 -80
  31. package/dist/cjs/util.cjs +4 -9
  32. package/dist/services/ipComparison.d.ts.map +1 -1
  33. package/dist/services/ipComparison.js +4 -2
  34. package/dist/services/ipComparison.js.map +1 -1
  35. package/dist/tasks/detection/decodePayload.d.ts +2 -2
  36. package/dist/tasks/detection/decodePayload.d.ts.map +1 -1
  37. package/dist/tasks/detection/decodePayload.js +1 -2
  38. package/dist/tasks/detection/decodePayload.js.map +1 -1
  39. package/dist/tasks/detection/getBotScore.d.ts +9 -0
  40. package/dist/tasks/detection/getBotScore.d.ts.map +1 -1
  41. package/dist/tasks/detection/getBotScore.js +30 -4
  42. package/dist/tasks/detection/getBotScore.js.map +1 -1
  43. package/dist/tasks/frictionless/frictionlessTasks.d.ts +8 -3
  44. package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +1 -1
  45. package/dist/tasks/frictionless/frictionlessTasks.js +97 -80
  46. package/dist/tasks/frictionless/frictionlessTasks.js.map +1 -1
  47. package/dist/tests/integration/escalationPeekBeforeConsume.integration.test.js +26 -2
  48. package/dist/tests/integration/escalationPeekBeforeConsume.integration.test.js.map +1 -1
  49. package/dist/tests/integration/trafficFilterHierarchy.integration.test.js +1 -0
  50. package/dist/tests/integration/trafficFilterHierarchy.integration.test.js.map +1 -1
  51. package/dist/tests/integration/webBotAuthAuthenticated.integration.test.js +1 -0
  52. package/dist/tests/integration/webBotAuthAuthenticated.integration.test.js.map +1 -1
  53. package/dist/tests/unit/api/captcha/submitPoWCaptchaSolution.escalation.unit.test.js +49 -38
  54. package/dist/tests/unit/api/captcha/submitPoWCaptchaSolution.escalation.unit.test.js.map +1 -1
  55. package/dist/tests/unit/api/healthzGeo.unit.test.d.ts +2 -0
  56. package/dist/tests/unit/api/healthzGeo.unit.test.d.ts.map +1 -0
  57. package/dist/tests/unit/api/healthzGeo.unit.test.js +272 -0
  58. package/dist/tests/unit/api/healthzGeo.unit.test.js.map +1 -0
  59. package/dist/tests/unit/api/public.unit.test.js +132 -2
  60. package/dist/tests/unit/api/public.unit.test.js.map +1 -1
  61. package/dist/tests/unit/services/ipComparison.unit.test.js +29 -0
  62. package/dist/tests/unit/services/ipComparison.unit.test.js.map +1 -1
  63. package/dist/tests/unit/tasks/detection/getBotScore.unit.test.js +44 -1
  64. package/dist/tests/unit/tasks/detection/getBotScore.unit.test.js.map +1 -1
  65. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.js +39 -0
  66. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.js.map +1 -1
  67. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js +78 -2
  68. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js.map +1 -1
  69. package/dist/tests/unit/testUtils/mockProviderEnv.d.ts.map +1 -1
  70. package/dist/tests/unit/testUtils/mockProviderEnv.js +1 -0
  71. package/dist/tests/unit/testUtils/mockProviderEnv.js.map +1 -1
  72. package/dist/tests/unit/util.deepValidateIpAddress.rules.unit.test.d.ts +2 -0
  73. package/dist/tests/unit/util.deepValidateIpAddress.rules.unit.test.d.ts.map +1 -0
  74. package/dist/tests/unit/util.deepValidateIpAddress.rules.unit.test.js +115 -0
  75. package/dist/tests/unit/util.deepValidateIpAddress.rules.unit.test.js.map +1 -0
  76. package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.js +70 -0
  77. package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.js.map +1 -1
  78. package/dist/tests/unit/util.ipDistance.unit.test.js +1 -0
  79. package/dist/tests/unit/util.ipDistance.unit.test.js.map +1 -1
  80. package/dist/util.d.ts.map +1 -1
  81. package/dist/util.js +4 -9
  82. package/dist/util.js.map +1 -1
  83. package/package.json +14 -14
@@ -129,11 +129,12 @@ describe("submitPoWCaptchaSolution.buildEscalation", () => {
129
129
  expect(env.spies.cacheSessionEscalation).not.toHaveBeenCalled();
130
130
  expect(env.spies.createSession).not.toHaveBeenCalled();
131
131
  });
132
- const CAPTCHA_TYPE_IDX = 5;
133
- const SITE_KEY_IDX = 6;
134
- const SIMD_READINGS_IDX = 19;
135
- const BUNDLE_ID_IDX = 24;
136
- const ORIGIN_SESSION_ID_IDX = 31;
132
+ const createSessionInput = () => {
133
+ const args = env.spies.createSession.mock.calls[0];
134
+ if (!args)
135
+ throw new Error("expected createSession to be called");
136
+ return args[0];
137
+ };
137
138
  it("passes captchaType=image and the origin sessionId when escalating to image", async () => {
138
139
  env.spies.getPowCaptchaRecordByChallenge.mockResolvedValue({
139
140
  sessionId: "origin-id",
@@ -142,12 +143,10 @@ describe("submitPoWCaptchaSolution.buildEscalation", () => {
142
143
  env.spies.getSessionRecordBySessionId.mockResolvedValue(makeOriginSession());
143
144
  await buildEscalation(env.tasks, { verified: true, routingOutput: { captchaType: CaptchaType.image } }, "challenge");
144
145
  expect(env.spies.createSession).toHaveBeenCalledTimes(1);
145
- const args = env.spies.createSession.mock.calls[0];
146
- if (!args)
147
- throw new Error("expected createSession to be called");
148
- expect(args[CAPTCHA_TYPE_IDX]).toBe(CaptchaType.image);
149
- expect(args[ORIGIN_SESSION_ID_IDX]).toBe("origin-id");
150
- expect(args[SITE_KEY_IDX]).toBe("site");
146
+ const input = createSessionInput();
147
+ expect(input.captchaType).toBe(CaptchaType.image);
148
+ expect(input.originSessionId).toBe("origin-id");
149
+ expect(input.siteKey).toBe("site");
151
150
  });
152
151
  it("passes captchaType=puzzle and the origin sessionId when escalating to puzzle", async () => {
153
152
  env.spies.getPowCaptchaRecordByChallenge.mockResolvedValue({
@@ -157,11 +156,9 @@ describe("submitPoWCaptchaSolution.buildEscalation", () => {
157
156
  env.spies.getSessionRecordBySessionId.mockResolvedValue(makeOriginSession());
158
157
  await buildEscalation(env.tasks, { verified: true, routingOutput: { captchaType: CaptchaType.puzzle } }, "challenge");
159
158
  expect(env.spies.createSession).toHaveBeenCalledTimes(1);
160
- const args = env.spies.createSession.mock.calls[0];
161
- if (!args)
162
- throw new Error("expected createSession to be called");
163
- expect(args[CAPTCHA_TYPE_IDX]).toBe(CaptchaType.puzzle);
164
- expect(args[ORIGIN_SESSION_ID_IDX]).toBe("origin-id");
159
+ const input = createSessionInput();
160
+ expect(input.captchaType).toBe(CaptchaType.puzzle);
161
+ expect(input.originSessionId).toBe("origin-id");
165
162
  });
166
163
  it("carries the origin's simdReadings onto the image escalation at creation time (so the DM verify path doesn't have to lean on chain fallback for the common case)", async () => {
167
164
  const originSimd = {
@@ -191,10 +188,7 @@ describe("submitPoWCaptchaSolution.buildEscalation", () => {
191
188
  });
192
189
  env.spies.getSessionRecordBySessionId.mockResolvedValue(origin);
193
190
  await buildEscalation(env.tasks, { verified: true, routingOutput: { captchaType: CaptchaType.image } }, "challenge");
194
- const args = env.spies.createSession.mock.calls[0];
195
- if (!args)
196
- throw new Error("expected createSession to be called");
197
- expect(args[SIMD_READINGS_IDX]).toBe(originSimd);
191
+ expect(createSessionInput().simdReadings).toBe(originSimd);
198
192
  });
199
193
  it("carries the origin's simdReadings onto the puzzle escalation at creation time", async () => {
200
194
  const originSimd = {
@@ -224,10 +218,7 @@ describe("submitPoWCaptchaSolution.buildEscalation", () => {
224
218
  });
225
219
  env.spies.getSessionRecordBySessionId.mockResolvedValue(origin);
226
220
  await buildEscalation(env.tasks, { verified: true, routingOutput: { captchaType: CaptchaType.puzzle } }, "challenge");
227
- const args = env.spies.createSession.mock.calls[0];
228
- if (!args)
229
- throw new Error("expected createSession to be called");
230
- expect(args[SIMD_READINGS_IDX]).toBe(originSimd);
221
+ expect(createSessionInput().simdReadings).toBe(originSimd);
231
222
  });
232
223
  it("carries the origin's bundleId onto the image escalation so the (same-origin) behavioural payload can be decrypted at solve time", async () => {
233
224
  const origin = {
@@ -240,10 +231,7 @@ describe("submitPoWCaptchaSolution.buildEscalation", () => {
240
231
  });
241
232
  env.spies.getSessionRecordBySessionId.mockResolvedValue(origin);
242
233
  await buildEscalation(env.tasks, { verified: true, routingOutput: { captchaType: CaptchaType.image } }, "challenge");
243
- const args = env.spies.createSession.mock.calls[0];
244
- if (!args)
245
- throw new Error("expected createSession to be called");
246
- expect(args[BUNDLE_ID_IDX]).toBe("bundle-42");
234
+ expect(createSessionInput().bundleId).toBe("bundle-42");
247
235
  });
248
236
  it("carries the origin's bundleId onto the puzzle escalation for the same reason", async () => {
249
237
  const origin = {
@@ -256,10 +244,35 @@ describe("submitPoWCaptchaSolution.buildEscalation", () => {
256
244
  });
257
245
  env.spies.getSessionRecordBySessionId.mockResolvedValue(origin);
258
246
  await buildEscalation(env.tasks, { verified: true, routingOutput: { captchaType: CaptchaType.puzzle } }, "challenge");
259
- const args = env.spies.createSession.mock.calls[0];
260
- if (!args)
261
- throw new Error("expected createSession to be called");
262
- expect(args[BUNDLE_ID_IDX]).toBe("bundle-17");
247
+ expect(createSessionInput().bundleId).toBe("bundle-17");
248
+ });
249
+ it("carries the origin's b onto the escalation", async () => {
250
+ const originB = { k1: ["v1", "v2"] };
251
+ env.spies.getPowCaptchaRecordByChallenge.mockResolvedValue({
252
+ sessionId: "origin-id",
253
+ dappAccount: "dapp",
254
+ });
255
+ env.spies.getSessionRecordBySessionId.mockResolvedValue({
256
+ ...makeOriginSession(),
257
+ b: originB,
258
+ });
259
+ await buildEscalation(env.tasks, { verified: true, routingOutput: { captchaType: CaptchaType.image } }, "challenge");
260
+ expect(createSessionInput().b).toBe(originB);
261
+ });
262
+ it("carries the origin's cv and sq onto the escalation", async () => {
263
+ env.spies.getPowCaptchaRecordByChallenge.mockResolvedValue({
264
+ sessionId: "origin-id",
265
+ dappAccount: "dapp",
266
+ });
267
+ env.spies.getSessionRecordBySessionId.mockResolvedValue({
268
+ ...makeOriginSession(),
269
+ cv: 42,
270
+ sq: 7,
271
+ });
272
+ await buildEscalation(env.tasks, { verified: true, routingOutput: { captchaType: CaptchaType.image } }, "challenge");
273
+ const input = createSessionInput();
274
+ expect(input.cv).toBe(42);
275
+ expect(input.sq).toBe(7);
263
276
  });
264
277
  it("does NOT carry behavioural data (BDP) onto the escalation session — BDP lives only in the pow-solve request payload", async () => {
265
278
  const origin = {
@@ -276,12 +289,10 @@ describe("submitPoWCaptchaSolution.buildEscalation", () => {
276
289
  });
277
290
  env.spies.getSessionRecordBySessionId.mockResolvedValue(origin);
278
291
  await buildEscalation(env.tasks, { verified: true, routingOutput: { captchaType: CaptchaType.image } }, "challenge");
279
- const args = env.spies.createSession.mock.calls[0];
280
- if (!args)
281
- throw new Error("expected createSession to be called");
282
- expect(args.some((a) => a ===
283
- origin
284
- .behavioralDataPacked)).toBe(false);
292
+ const input = createSessionInput();
293
+ expect(Object.values(input)).not.toContain(origin
294
+ .behavioralDataPacked);
295
+ expect(input).not.toHaveProperty("behavioralDataPacked");
285
296
  });
286
297
  });
287
298
  //# sourceMappingURL=submitPoWCaptchaSolution.escalation.unit.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"submitPoWCaptchaSolution.escalation.unit.test.js","sourceRoot":"","sources":["../../../../../src/tests/unit/api/captcha/submitPoWCaptchaSolution.escalation.unit.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"submitPoWCaptchaSolution.escalation.unit.test.js","sourceRoot":"","sources":["../../../../../src/tests/unit/api/captcha/submitPoWCaptchaSolution.escalation.unit.test.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,WAAW,EAAgB,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,qDAAqD,CAAC;AAQtF,MAAM,SAAS,GAAG,GAAG,EAAE;IACtB,MAAM,sBAAsB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,aAAa,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC7D,SAAS,EAAE,eAAe;KAC1B,CAAC,CAAC,CAAC;IACJ,MAAM,8BAA8B,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;IAC/C,MAAM,2BAA2B,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;IAE5C,MAAM,KAAK,GAAG;QACb,EAAE,EAAE;YACH,8BAA8B;YAC9B,2BAA2B;SAC3B;QACD,mBAAmB,EAAE;YACpB,aAAa;SACb;QACD,UAAU,EAAE;YACX,sBAAsB;SACtB;QAKD,MAAM,EAAE;YACP,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;SAC1D;KACmD,CAAC;IAEtD,OAAO;QACN,KAAK;QACL,KAAK,EAAE;YACN,sBAAsB;YACtB,aAAa;YACb,8BAA8B;YAC9B,2BAA2B;SAC3B;KACD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,GAAY,EAAE,CACvC,CAAC;IACA,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,cAAc;IACrB,KAAK,EAAE,GAAG;IACV,SAAS,EAAE,GAAG;IACd,eAAe,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE;IACnC,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACpC,WAAW,EAAE,WAAW,CAAC,GAAG;IAC5B,OAAO,EAAE,MAAM;IACf,iBAAiB,EAAE,UAAU;IAC7B,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,KAAK;IACb,iBAAiB,EAAE,UAAU;IAC7B,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,SAAS;IACf,YAAY,EAAE,SAAS;CACvB,CAAuB,CAAC;AAE1B,QAAQ,CAAC,0CAA0C,EAAE,GAAG,EAAE;IACzD,IAAI,GAAiC,CAAC;IAEtC,UAAU,CAAC,GAAG,EAAE;QACf,GAAG,GAAG,SAAS,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,GAAG,GAAG,MAAM,eAAe,CAChC,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,EAC5C,WAAW,CACX,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAChE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAChG,MAAM,GAAG,GAAG,MAAM,eAAe,CAChC,GAAG,CAAC,KAAK,EACT;YACC,QAAQ,EAAE,KAAK;YACf,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE;SACjD,EACD,WAAW,CACX,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,GAAG,GAAG,MAAM,eAAe,CAChC,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,GAAG,EAAE,EAAE,EACnE,WAAW,CACX,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACxF,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CACtD,iBAAiB,EAAE,CACnB,CAAC;QAEF,MAAM,GAAG,GAAG,MAAM,eAAe,CAChC,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EACrE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;YACnB,WAAW,EAAE,WAAW,CAAC,KAAK;YAC9B,SAAS,EAAE,eAAe;SAC1B,CAAC,CAAC;QAIH,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,oBAAoB,CAC5D,WAAW,EACX,eAAe,CACf,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC9E,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CACtD,iBAAiB,EAAE,CACnB,CAAC;QAEF,MAAM,eAAe,CACpB,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,EAAE,EACtE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,oBAAoB,CAC5D,WAAW,EACX,eAAe,CACf,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAK7F,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CACtD,iBAAiB,EAAE,CACnB,CAAC;QACD,GAAG,CAAC,KAA4C,CAAC,UAAU,GAAG,IAAI,CAAC;QAEpE,MAAM,GAAG,GAAG,MAAM,eAAe,CAChC,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EACrE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;YACnB,WAAW,EAAE,WAAW,CAAC,KAAK;YAC9B,SAAS,EAAE,eAAe;SAC1B,CAAC,CAAC;QAGH,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mFAAmF,EAAE,KAAK,IAAI,EAAE;QAClG,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAEjE,MAAM,GAAG,GAAG,MAAM,eAAe,CAChC,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EACrE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAChE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wFAAwF,EAAE,KAAK,IAAI,EAAE;QACvG,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAEnE,MAAM,GAAG,GAAG,MAAM,eAAe,CAChC,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EACrE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAChE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;IAIH,MAAM,kBAAkB,GAAG,GAAuB,EAAE;QACnD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC,CAAC,CAAuB,CAAC;IACtC,CAAC,CAAC;IAEF,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;QAC3F,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CACtD,iBAAiB,EAAE,CACnB,CAAC;QAEF,MAAM,eAAe,CACpB,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EACrE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAGhD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAC7F,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CACtD,iBAAiB,EAAE,CACnB,CAAC;QAEF,MAAM,eAAe,CACpB,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,EAAE,EACtE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iKAAiK,EAAE,KAAK,IAAI,EAAE;QAChL,MAAM,UAAU,GAAG;YAClB,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,CAAC;YACT,iBAAiB,EAAE,KAAK;YACxB,SAAS,EAAE,GAAG;YACd,UAAU,EAAE,EAAE;YACd,GAAG,EAAE;gBACJ;oBACC,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,OAAO;oBACjB,MAAM,EAAE,GAAG;oBACX,QAAQ,EAAE,GAAG;oBACb,KAAK,EAAE,GAAG;oBACV,UAAU,EAAE,CAAC;iBACb;aACD;SACD,CAAC;QACF,MAAM,MAAM,GAAG;YACd,GAAG,iBAAiB,EAAE;YACtB,YAAY,EAAE,UAAU;SACxB,CAAC;QACF,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAEhE,MAAM,eAAe,CACpB,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EACrE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,kBAAkB,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,UAAU,GAAG;YAClB,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,CAAC;YACT,iBAAiB,EAAE,KAAK;YACxB,SAAS,EAAE,GAAG;YACd,UAAU,EAAE,EAAE;YACd,GAAG,EAAE;gBACJ;oBACC,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,OAAO;oBACjB,MAAM,EAAE,GAAG;oBACX,QAAQ,EAAE,GAAG;oBACb,KAAK,EAAE,GAAG;oBACV,UAAU,EAAE,CAAC;iBACb;aACD;SACD,CAAC;QACF,MAAM,MAAM,GAAG;YACd,GAAG,iBAAiB,EAAE;YACtB,YAAY,EAAE,UAAU;SACxB,CAAC;QACF,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAEhE,MAAM,eAAe,CACpB,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,EAAE,EACtE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,kBAAkB,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iIAAiI,EAAE,KAAK,IAAI,EAAE;QAChJ,MAAM,MAAM,GAAG;YACd,GAAG,iBAAiB,EAAE;YACtB,QAAQ,EAAE,WAAW;SACrB,CAAC;QACF,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAEhE,MAAM,eAAe,CACpB,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EACrE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,kBAAkB,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAC7F,MAAM,MAAM,GAAG;YACd,GAAG,iBAAiB,EAAE;YACtB,QAAQ,EAAE,WAAW;SACrB,CAAC;QACF,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAEhE,MAAM,eAAe,CACpB,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,EAAE,EACtE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,kBAAkB,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAI3D,MAAM,OAAO,GAA6B,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CAAC;YACvD,GAAG,iBAAiB,EAAE;YACtB,CAAC,EAAE,OAAO;SACV,CAAC,CAAC;QAEH,MAAM,eAAe,CACpB,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EACrE,WAAW,CACX,CAAC;QAEF,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAEnE,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CAAC;YACvD,GAAG,iBAAiB,EAAE;YACtB,EAAE,EAAE,EAAE;YACN,EAAE,EAAE,CAAC;SACL,CAAC,CAAC;QAEH,MAAM,eAAe,CACpB,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EACrE,WAAW,CACX,CAAC;QAEF,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAOH,EAAE,CAAC,qHAAqH,EAAE,KAAK,IAAI,EAAE;QAGpI,MAAM,MAAM,GAAG;YACd,GAAG,iBAAiB,EAAE;YACtB,oBAAoB,EAAE;gBACrB,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC1B,EAAE,EAAE,EAAE;gBACN,EAAE,EAAE,EAAE;aACN;SACqB,CAAC;QACxB,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,iBAAiB,CAAC;YAC1D,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,MAAM;SACnB,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAEhE,MAAM,eAAe,CACpB,GAAG,CAAC,KAAK,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EACrE,WAAW,CACX,CAAC;QAMF,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CACxC,MAAuD;aACtD,oBAAoB,CACtB,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=healthzGeo.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"healthzGeo.unit.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/unit/api/healthzGeo.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,272 @@
1
+ import { IpInfoService, } from "@prosopo/ipinfo";
2
+ import { afterEach, describe, expect, it, vi } from "vitest";
3
+ import { HealthzGeoRouter, TargetHealthMonitor, getHealthzGeoRouter, readHealthzGeoConfig, resetHealthzGeoRouter, } from "../../../api/healthzGeo.js";
4
+ const OWN_HOST = "node-a.example.com";
5
+ const TARGET_HOST = "node-b.example.com";
6
+ const CLIENT_IP = "8.8.8.8";
7
+ const ipInfo = (options) => ({
8
+ initialize: vi.fn(async () => { }),
9
+ lookup: vi.fn(async () => {
10
+ throw new Error("lookup() must not be called by healthz");
11
+ }),
12
+ country: vi.fn(() => options.country),
13
+ isAvailable: vi.fn(() => options.available ?? true),
14
+ });
15
+ const config = (overrides = {}) => ({
16
+ enabled: true,
17
+ routes: new Map([["US", TARGET_HOST]]),
18
+ probeIntervalMs: 30_000,
19
+ probeTimeoutMs: 2_000,
20
+ ...overrides,
21
+ });
22
+ const monitorWith = (...upHosts) => {
23
+ const monitor = new TargetHealthMonitor({
24
+ hosts: upHosts,
25
+ intervalMs: 30_000,
26
+ timeoutMs: 2_000,
27
+ probe: vi.fn(async () => true),
28
+ });
29
+ return monitor;
30
+ };
31
+ const readyMonitor = async (...upHosts) => {
32
+ const monitor = monitorWith(...upHosts);
33
+ await monitor.pollAll();
34
+ return monitor;
35
+ };
36
+ describe("readHealthzGeoConfig", () => {
37
+ it("is disabled when nothing is set", () => {
38
+ expect(readHealthzGeoConfig({}).enabled).toBe(false);
39
+ });
40
+ it("is disabled when the flag is set to anything but 'true'", () => {
41
+ for (const flag of ["false", "1", "yes", "TRUE", ""]) {
42
+ expect(readHealthzGeoConfig({
43
+ PROSOPO_HEALTHZ_GEO_STEERING: flag,
44
+ PROSOPO_HEALTHZ_GEO_ROUTES: `{"US":"${TARGET_HOST}"}`,
45
+ }).enabled).toBe(false);
46
+ }
47
+ });
48
+ it("is disabled when the flag is on but no routes are configured", () => {
49
+ expect(readHealthzGeoConfig({ PROSOPO_HEALTHZ_GEO_STEERING: "true" }).enabled).toBe(false);
50
+ });
51
+ it("enables steering and upper-cases the country keys", () => {
52
+ const parsed = readHealthzGeoConfig({
53
+ PROSOPO_HEALTHZ_GEO_STEERING: "true",
54
+ PROSOPO_HEALTHZ_GEO_ROUTES: `{"us":"${TARGET_HOST}"}`,
55
+ });
56
+ expect(parsed.enabled).toBe(true);
57
+ expect(parsed.routes.get("US")).toBe(TARGET_HOST);
58
+ });
59
+ it("stays off when the route map is unparseable or malformed", () => {
60
+ for (const routes of [
61
+ "not json",
62
+ "[]",
63
+ '{"USA":"node-b.example.com"}',
64
+ '{"US":""}',
65
+ '{"US":"https://node-b.example.com/healthz"}',
66
+ '{"US":123}',
67
+ ]) {
68
+ const parsed = readHealthzGeoConfig({
69
+ PROSOPO_HEALTHZ_GEO_STEERING: "true",
70
+ PROSOPO_HEALTHZ_GEO_ROUTES: routes,
71
+ });
72
+ expect(parsed.enabled).toBe(false);
73
+ expect(parsed.routes.size).toBe(0);
74
+ }
75
+ });
76
+ it("defaults the probe period and timeout, and rejects nonsense overrides", () => {
77
+ const defaults = readHealthzGeoConfig({});
78
+ expect(defaults.probeIntervalMs).toBe(30_000);
79
+ expect(defaults.probeTimeoutMs).toBe(2_000);
80
+ const overridden = readHealthzGeoConfig({
81
+ PROSOPO_HEALTHZ_GEO_PROBE_INTERVAL_MS: "5000",
82
+ PROSOPO_HEALTHZ_GEO_PROBE_TIMEOUT_MS: "500",
83
+ });
84
+ expect(overridden.probeIntervalMs).toBe(5_000);
85
+ expect(overridden.probeTimeoutMs).toBe(500);
86
+ const nonsense = readHealthzGeoConfig({
87
+ PROSOPO_HEALTHZ_GEO_PROBE_INTERVAL_MS: "0",
88
+ PROSOPO_HEALTHZ_GEO_PROBE_TIMEOUT_MS: "-1",
89
+ });
90
+ expect(nonsense.probeIntervalMs).toBe(30_000);
91
+ expect(nonsense.probeTimeoutMs).toBe(2_000);
92
+ expect(readHealthzGeoConfig({ PROSOPO_HEALTHZ_GEO_PROBE_INTERVAL_MS: "5" })
93
+ .probeIntervalMs).toBe(1_000);
94
+ });
95
+ });
96
+ describe("HealthzGeoRouter.resolveHost", () => {
97
+ it("steers to the host the caller's country maps to", async () => {
98
+ const service = ipInfo({ country: "US" });
99
+ const router = new HealthzGeoRouter(config(), { ipInfoService: service }, await readyMonitor(TARGET_HOST));
100
+ expect(router.resolveHost(CLIENT_IP, OWN_HOST)).toEqual({
101
+ host: TARGET_HOST,
102
+ outcome: "steered",
103
+ });
104
+ expect(service.lookup).not.toHaveBeenCalled();
105
+ });
106
+ it("answers with its own name when the flag is off", async () => {
107
+ const service = ipInfo({ country: "US" });
108
+ const router = new HealthzGeoRouter(config({ enabled: false }), { ipInfoService: service }, await readyMonitor(TARGET_HOST));
109
+ expect(router.resolveHost(CLIENT_IP, OWN_HOST)).toEqual({
110
+ host: OWN_HOST,
111
+ outcome: "not_steered",
112
+ });
113
+ expect(service.isAvailable).not.toHaveBeenCalled();
114
+ expect(service.country).not.toHaveBeenCalled();
115
+ });
116
+ it("answers with its own name when the country has no override", async () => {
117
+ const router = new HealthzGeoRouter(config(), { ipInfoService: ipInfo({ country: "GB" }) }, await readyMonitor(TARGET_HOST));
118
+ expect(router.resolveHost(CLIENT_IP, OWN_HOST)).toEqual({
119
+ host: OWN_HOST,
120
+ outcome: "not_steered",
121
+ });
122
+ });
123
+ it("answers with its own name when the override names this node", async () => {
124
+ const router = new HealthzGeoRouter(config({ routes: new Map([["US", OWN_HOST]]) }), { ipInfoService: ipInfo({ country: "US" }) }, await readyMonitor(OWN_HOST));
125
+ expect(router.resolveHost(CLIENT_IP, OWN_HOST)).toEqual({
126
+ host: OWN_HOST,
127
+ outcome: "not_steered",
128
+ });
129
+ });
130
+ it("reports geo_unavailable when the country is unknown", async () => {
131
+ const router = new HealthzGeoRouter(config(), { ipInfoService: ipInfo({ country: undefined }) }, await readyMonitor(TARGET_HOST));
132
+ expect(router.resolveHost(CLIENT_IP, OWN_HOST)).toEqual({
133
+ host: OWN_HOST,
134
+ outcome: "geo_unavailable",
135
+ });
136
+ });
137
+ it("reports geo_unavailable, without a lookup, while ip info is unavailable", async () => {
138
+ const service = ipInfo({ available: false, country: "US" });
139
+ const router = new HealthzGeoRouter(config(), { ipInfoService: service }, await readyMonitor(TARGET_HOST));
140
+ expect(router.resolveHost(CLIENT_IP, OWN_HOST)).toEqual({
141
+ host: OWN_HOST,
142
+ outcome: "geo_unavailable",
143
+ });
144
+ expect(service.country).not.toHaveBeenCalled();
145
+ expect(service.lookup).not.toHaveBeenCalled();
146
+ });
147
+ it("reports geo_unavailable when the request has no address", async () => {
148
+ const router = new HealthzGeoRouter(config(), { ipInfoService: ipInfo({ country: "US" }) }, await readyMonitor(TARGET_HOST));
149
+ expect(router.resolveHost(undefined, OWN_HOST)).toEqual({
150
+ host: OWN_HOST,
151
+ outcome: "geo_unavailable",
152
+ });
153
+ });
154
+ it("does not steer a loopback caller", async () => {
155
+ const maxmind = {
156
+ initialize: vi.fn(async () => { }),
157
+ isAvailable: vi.fn(() => true),
158
+ countryCode: vi.fn(() => "US"),
159
+ };
160
+ const service = new IpInfoService({}, {
161
+ maxmind: maxmind,
162
+ });
163
+ const router = new HealthzGeoRouter(config(), { ipInfoService: service }, await readyMonitor(TARGET_HOST));
164
+ for (const ip of ["127.0.0.1", "::1", "::ffff:127.0.0.1", "172.18.0.4"]) {
165
+ expect(router.resolveHost(ip, OWN_HOST)).toEqual({
166
+ host: OWN_HOST,
167
+ outcome: "geo_unavailable",
168
+ });
169
+ }
170
+ expect(maxmind.countryCode).not.toHaveBeenCalled();
171
+ });
172
+ it("does not steer to a target that is not confirmed up", async () => {
173
+ const router = new HealthzGeoRouter(config(), { ipInfoService: ipInfo({ country: "US" }) }, monitorWith(TARGET_HOST));
174
+ expect(router.resolveHost(CLIENT_IP, OWN_HOST)).toEqual({
175
+ host: OWN_HOST,
176
+ outcome: "target_down",
177
+ });
178
+ });
179
+ it("stops steering once the target stops answering", async () => {
180
+ let healthy = true;
181
+ const monitor = new TargetHealthMonitor({
182
+ hosts: [TARGET_HOST],
183
+ intervalMs: 30_000,
184
+ timeoutMs: 2_000,
185
+ probe: vi.fn(async () => healthy),
186
+ });
187
+ const router = new HealthzGeoRouter(config(), { ipInfoService: ipInfo({ country: "US" }) }, monitor);
188
+ await monitor.pollAll();
189
+ expect(router.resolveHost(CLIENT_IP, OWN_HOST).outcome).toBe("steered");
190
+ healthy = false;
191
+ await monitor.pollAll();
192
+ expect(router.resolveHost(CLIENT_IP, OWN_HOST).outcome).toBe("target_down");
193
+ });
194
+ });
195
+ describe("TargetHealthMonitor", () => {
196
+ afterEach(() => {
197
+ vi.useRealTimers();
198
+ });
199
+ it("reports every host down before it has probed anything", () => {
200
+ const monitor = monitorWith(TARGET_HOST);
201
+ expect(monitor.isUp(TARGET_HOST)).toBe(false);
202
+ expect(monitor.isUp("never-configured.example.com")).toBe(false);
203
+ });
204
+ it("keeps a host down when its probe rejects", async () => {
205
+ const monitor = new TargetHealthMonitor({
206
+ hosts: [TARGET_HOST],
207
+ intervalMs: 30_000,
208
+ timeoutMs: 2_000,
209
+ probe: vi.fn(async () => {
210
+ throw new Error("connect ECONNREFUSED");
211
+ }),
212
+ });
213
+ await expect(monitor.pollAll()).resolves.toBeUndefined();
214
+ expect(monitor.isUp(TARGET_HOST)).toBe(false);
215
+ });
216
+ it("probes each distinct host once per round", async () => {
217
+ const probe = vi.fn(async () => true);
218
+ const monitor = new TargetHealthMonitor({
219
+ hosts: [TARGET_HOST, TARGET_HOST, "node-c.example.com"],
220
+ intervalMs: 30_000,
221
+ timeoutMs: 1_500,
222
+ probe,
223
+ });
224
+ await monitor.pollAll();
225
+ expect(probe).toHaveBeenCalledTimes(2);
226
+ expect(probe).toHaveBeenCalledWith(TARGET_HOST, 1_500);
227
+ });
228
+ it("polls on its interval and stops when told to", async () => {
229
+ vi.useFakeTimers();
230
+ const probe = vi.fn(async () => true);
231
+ const monitor = new TargetHealthMonitor({
232
+ hosts: [TARGET_HOST],
233
+ intervalMs: 1_000,
234
+ timeoutMs: 500,
235
+ probe,
236
+ });
237
+ monitor.start();
238
+ expect(probe).toHaveBeenCalledTimes(1);
239
+ await vi.advanceTimersByTimeAsync(2_500);
240
+ expect(probe).toHaveBeenCalledTimes(3);
241
+ monitor.stop();
242
+ await vi.advanceTimersByTimeAsync(5_000);
243
+ expect(probe).toHaveBeenCalledTimes(3);
244
+ });
245
+ it("starts no timer when there is nothing to probe", () => {
246
+ vi.useFakeTimers();
247
+ const probe = vi.fn(async () => true);
248
+ const monitor = new TargetHealthMonitor({
249
+ hosts: [],
250
+ intervalMs: 1_000,
251
+ timeoutMs: 500,
252
+ probe,
253
+ });
254
+ monitor.start();
255
+ monitor.stop();
256
+ expect(probe).not.toHaveBeenCalled();
257
+ expect(vi.getTimerCount()).toBe(0);
258
+ });
259
+ });
260
+ describe("getHealthzGeoRouter", () => {
261
+ afterEach(() => {
262
+ resetHealthzGeoRouter();
263
+ });
264
+ it("is off by default and built once per process", () => {
265
+ const router = getHealthzGeoRouter({
266
+ ipInfoService: ipInfo({ country: "US" }),
267
+ });
268
+ expect(router.enabled).toBe(false);
269
+ expect(getHealthzGeoRouter({ ipInfoService: ipInfo({}) })).toBe(router);
270
+ });
271
+ });
272
+ //# sourceMappingURL=healthzGeo.unit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"healthzGeo.unit.test.js","sourceRoot":"","sources":["../../../../src/tests/unit/api/healthzGeo.unit.test.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import { handleErrors } from "@prosopo/api-express-router";
2
2
  import { ProsopoApiError } from "@prosopo/common";
3
- import { PublicApiPaths } from "@prosopo/types";
3
+ import { PublicApiPaths, providerDetailsSchema, } from "@prosopo/types";
4
4
  import { version } from "@prosopo/util";
5
- import { beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { afterEach, beforeEach, describe, expect, it, vi, } from "vitest";
6
+ import { resetHealthzGeoRouter } from "../../../api/healthzGeo.js";
6
7
  import { metricsHandler } from "../../../api/metrics.js";
7
8
  import { publicRouter } from "../../../api/public.js";
8
9
  vi.mock("@prosopo/api-express-router", () => ({
@@ -15,6 +16,15 @@ vi.mock("@prosopo/util", async (importActual) => {
15
16
  version: "1.0.0-test",
16
17
  };
17
18
  });
19
+ const getRouteHandler = (router, path) => {
20
+ const { stack } = router;
21
+ const handler = stack.find((layer) => layer.route?.path === path)?.route
22
+ ?.stack[0]?.handle;
23
+ if (!handler) {
24
+ throw new Error(`no handler registered for ${path}`);
25
+ }
26
+ return handler;
27
+ };
18
28
  describe("publicRouter", () => {
19
29
  let mockEnv;
20
30
  let mockDb;
@@ -266,5 +276,125 @@ describe("publicRouter", () => {
266
276
  ]),
267
277
  }));
268
278
  });
279
+ describe("the details endpoint reports the answering node", () => {
280
+ const envWithConfiguredHost = (host) => ({
281
+ getDb: vi.fn().mockReturnValue(mockDb),
282
+ logger: mockLogger,
283
+ config: { host },
284
+ });
285
+ const callDetails = async (env, hostname) => {
286
+ const handler = getRouteHandler(publicRouter(env), PublicApiPaths.GetProviderDetails);
287
+ const req = { hostname, params: {} };
288
+ await handler(req, mockRes, mockNext);
289
+ return vi.mocked(mockRes.json).mock.calls[0]?.[0];
290
+ };
291
+ it("reports the configured host", async () => {
292
+ const body = await callDetails(envWithConfiguredHost("provider.example.com"), "proxied.example.com");
293
+ expect(body).toEqual(expect.objectContaining({ host: "provider.example.com" }));
294
+ });
295
+ it("falls back to the request hostname when no host is configured", async () => {
296
+ const body = await callDetails(envWithConfiguredHost(""), "req.example.com");
297
+ expect(body).toEqual(expect.objectContaining({ host: "req.example.com" }));
298
+ });
299
+ it("returns a body the shared schema still accepts", async () => {
300
+ const body = await callDetails(envWithConfiguredHost("provider.example.com"), "proxied.example.com");
301
+ expect(providerDetailsSchema.safeParse(body).success).toBe(true);
302
+ });
303
+ });
304
+ });
305
+ describe("publicRouter /healthz", () => {
306
+ const healthzHandler = (router) => {
307
+ const layers = router.stack;
308
+ const handler = layers.find((layer) => layer.route?.path === PublicApiPaths.Healthz)?.route?.stack[0]?.handle;
309
+ if (!handler)
310
+ throw new Error("healthz route is not registered");
311
+ return handler;
312
+ };
313
+ const ipInfoService = {
314
+ initialize: vi.fn(async () => { }),
315
+ lookup: vi.fn(async () => {
316
+ throw new Error("lookup() must not be called by healthz");
317
+ }),
318
+ country: vi.fn(() => "US"),
319
+ isAvailable: vi.fn(() => true),
320
+ };
321
+ const env = (host) => ({
322
+ config: { host },
323
+ logger: { warn: vi.fn(), info: vi.fn(), error: vi.fn(), debug: vi.fn() },
324
+ ipInfoService,
325
+ });
326
+ const responseSpy = () => {
327
+ const set = vi.fn();
328
+ const json = vi.fn();
329
+ return {
330
+ res: {
331
+ status: vi.fn().mockReturnThis(),
332
+ set,
333
+ json,
334
+ },
335
+ set,
336
+ json,
337
+ };
338
+ };
339
+ const request = (ip) => ({ ip, hostname: "lb.example.com" });
340
+ const setEnvVars = (vars) => {
341
+ for (const [key, value] of Object.entries(vars)) {
342
+ if (value === undefined) {
343
+ delete process.env[key];
344
+ }
345
+ else {
346
+ process.env[key] = value;
347
+ }
348
+ }
349
+ };
350
+ beforeEach(() => {
351
+ vi.clearAllMocks();
352
+ resetHealthzGeoRouter();
353
+ vi.stubGlobal("fetch", vi.fn(async () => new Response(null, { status: 503 })));
354
+ });
355
+ afterEach(() => {
356
+ resetHealthzGeoRouter();
357
+ vi.unstubAllGlobals();
358
+ setEnvVars({
359
+ PROSOPO_HEALTHZ_GEO_STEERING: undefined,
360
+ PROSOPO_HEALTHZ_GEO_ROUTES: undefined,
361
+ });
362
+ });
363
+ it("answers with its own name and sets no headers when steering is off", () => {
364
+ setEnvVars({
365
+ PROSOPO_HEALTHZ_GEO_STEERING: undefined,
366
+ PROSOPO_HEALTHZ_GEO_ROUTES: JSON.stringify({
367
+ US: "node-b.example.com",
368
+ }),
369
+ });
370
+ const { res, set, json } = responseSpy();
371
+ healthzHandler(publicRouter(env("node-a.example.com")))(request("203.0.113.9"), res, vi.fn());
372
+ expect(json).toHaveBeenCalledWith({
373
+ ok: true,
374
+ host: "node-a.example.com",
375
+ });
376
+ expect(set).not.toHaveBeenCalled();
377
+ expect(ipInfoService.country).not.toHaveBeenCalled();
378
+ });
379
+ it("falls back to the request hostname when no host is configured", () => {
380
+ const { res, json } = responseSpy();
381
+ healthzHandler(publicRouter(env("")))(request("203.0.113.9"), res, vi.fn());
382
+ expect(json).toHaveBeenCalledWith({ ok: true, host: "lb.example.com" });
383
+ });
384
+ it("marks the response uncacheable once it can vary per caller", () => {
385
+ setEnvVars({
386
+ PROSOPO_HEALTHZ_GEO_STEERING: "true",
387
+ PROSOPO_HEALTHZ_GEO_ROUTES: JSON.stringify({
388
+ US: "node-b.example.com",
389
+ }),
390
+ });
391
+ const { res, set, json } = responseSpy();
392
+ healthzHandler(publicRouter(env("node-a.example.com")))(request("203.0.113.9"), res, vi.fn());
393
+ expect(set).toHaveBeenCalledWith("Cache-Control", "no-store, private");
394
+ expect(json).toHaveBeenCalledWith({
395
+ ok: true,
396
+ host: "node-a.example.com",
397
+ });
398
+ });
269
399
  });
270
400
  //# sourceMappingURL=public.unit.test.js.map