@oneaddress/setup 1.3.2 → 1.3.3

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 (2) hide show
  1. package/dist/index.js +102 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -856,7 +856,7 @@ var _R = ["\u2588\u2588\u2588\u2588\u2588\u2588 ", "\u2588\u2588 \u2588\u2588"
856
856
  var _S = [" \u2588\u2588\u2588\u2588\u2588\u2588", "\u2588\u2588 ", "\u2588\u2588 ", " \u2588\u2588\u2588\u2588\u2588 ", " \u2588\u2588", " \u2588\u2588", "\u2588\u2588\u2588\u2588\u2588\u2588 "];
857
857
  var ONE_ROWS = Array.from({ length: 7 }, (_3, i) => [_O[i], _N[i], _E[i]].join(" "));
858
858
  var ADDR_ROWS = Array.from({ length: 7 }, (_3, i) => [_A[i], _D2[i], _D2[i], _R[i], _E[i], _S[i], _S[i]].join(" "));
859
- var WIZARD_VERSION = true ? "1.3.2" : "?";
859
+ var WIZARD_VERSION = true ? "1.3.3" : "?";
860
860
  function printCompactHeader() {
861
861
  const INNER = 42;
862
862
  const TOP = fn("\u250C") + dm("\u2500".repeat(INNER)) + fn("\u2510");
@@ -1426,6 +1426,19 @@ app.post('/webhook', async (req: Request, res: Response) => {
1426
1426
  return res.status(200).json({ ok: true });
1427
1427
  }
1428
1428
 
1429
+ // \u2500\u2500 address.test / address.test-dispatch: OneAddress connection-verification
1430
+ // A fabricated test record wrapped to your key. Reaching this line proves
1431
+ // PARTNER_PRIVATE_KEY_PEM decrypted it: a wrong key would have failed the D5
1432
+ // decrypt above and returned 422, never here. Answer { verification: true },
1433
+ // which is what the receiver-verification and go-live checks look for. Return
1434
+ // anything else (including the forward-compat skip below) and the check reads
1435
+ // as "answered but could not decrypt", which is not what happened.
1436
+ if (event === 'address.test' || event === 'address.test-dispatch') {
1437
+ const index = typeof body.index === 'number' ? body.index : undefined;
1438
+ console.log(\`[webhook] \${event} verification probe decrypted OK\`);
1439
+ return res.status(200).json({ verification: true, index });
1440
+ }
1441
+
1429
1442
  // Unknown event \u2014 acknowledge (forward compatibility)
1430
1443
  console.log(\`[webhook] Unknown event "\${event}" \u2014 acknowledged\`);
1431
1444
  return res.status(200).json({ ok: true, skipped: true });
@@ -1960,6 +1973,15 @@ async def webhook(request: Request) -> Response:
1960
1973
  except Exception as e:
1961
1974
  print(f"[webhook] Callback POST failed: {e}")
1962
1975
 
1976
+ elif event in ("address.test", "address.test-dispatch"):
1977
+ # OneAddress connection-verification probe. Reaching here means the D5
1978
+ # decrypt above succeeded (a wrong key returned 422), which is exactly
1979
+ # what the check proves, so answer verification=true. Anything else reads
1980
+ # as "answered but could not decrypt", which is not what happened.
1981
+ print(f"[webhook] {event} verification probe decrypted OK")
1982
+ return Response(content=json.dumps({"verification": True, "index": body.get("index")}),
1983
+ media_type="application/json")
1984
+
1963
1985
  else:
1964
1986
  print(f"[webhook] Unknown event '{event}' \u2014 acknowledged")
1965
1987
 
@@ -2517,6 +2539,14 @@ public class OneAddressWebhookController {
2517
2539
  } else if ("address.verify".equals(event)) {
2518
2540
  handleAddressVerify(body, address, accountNumber, verifiedName, knownNames);
2519
2541
  if (dispatchId != null && !dispatchId.isBlank()) store.markProcessed(dispatchId, "verify");
2542
+ } else if ("address.test".equals(event) || "address.test-dispatch".equals(event)) {
2543
+ // OneAddress connection-verification probe. Reaching here means the
2544
+ // D5 decrypt above succeeded (a wrong key returned 422), which is
2545
+ // what the check proves, so answer verification=true.
2546
+ if (dispatchId != null && !dispatchId.isBlank()) store.markProcessed(dispatchId, "verification:ok");
2547
+ Object idx = body.get("index");
2548
+ log.info("[OneAddress] {} verification probe decrypted OK", event);
2549
+ return ResponseEntity.ok("{\\"verification\\":true,\\"index\\":" + (idx == null ? "null" : idx.toString()) + "}");
2520
2550
  } else {
2521
2551
  log.info("[OneAddress] skipping unknown event: {}", event);
2522
2552
  if (dispatchId != null && !dispatchId.isBlank()) store.markProcessed(dispatchId, "ignored:unknown-event");
@@ -3285,7 +3315,11 @@ app.MapPost("/webhooks/oneaddress", async (HttpRequest request) =>
3285
3315
 
3286
3316
  var eventType = body.TryGetProperty("event", out var evtEl) ? evtEl.GetString() : null;
3287
3317
 
3288
- if (eventType != "address.updated" && eventType != "address.verify")
3318
+ // address.test / address.test-dispatch (the connection-verification probe)
3319
+ // must pass this guard so it reaches the decrypt below; a wrong key then
3320
+ // returns 422 and only a real decrypt reaches the verification answer.
3321
+ if (eventType != "address.updated" && eventType != "address.verify"
3322
+ && eventType != "address.test" && eventType != "address.test-dispatch")
3289
3323
  {
3290
3324
  app.Logger.LogInformation("[OneAddress] skipping unknown event: {EventType}", eventType);
3291
3325
  return Results.Json(new { ok = true, skipped = true });
@@ -3366,6 +3400,17 @@ app.MapPost("/webhooks/oneaddress", async (HttpRequest request) =>
3366
3400
  app.Logger.LogWarning("[OneAddress] dispatch {DispatchId} received before but never completed \u2014 reprocessing", dispatchId);
3367
3401
  }
3368
3402
 
3403
+ if (eventType == "address.test" || eventType == "address.test-dispatch")
3404
+ {
3405
+ // OneAddress connection-verification probe. Reaching here means the D5
3406
+ // decrypt above succeeded (a wrong key returned 422), which is what the
3407
+ // check proves, so answer verification=true.
3408
+ int? index = body.TryGetProperty("index", out var idxEl) && idxEl.ValueKind == JsonValueKind.Number
3409
+ ? idxEl.GetInt32() : (int?)null;
3410
+ app.Logger.LogInformation("[OneAddress] {EventType} verification probe decrypted OK", eventType);
3411
+ return Results.Json(new { verification = true, index });
3412
+ }
3413
+
3369
3414
  if (eventType == "address.updated")
3370
3415
  {
3371
3416
  // Work FIRST, respond after. Acknowledging before the write commits
@@ -4203,6 +4248,21 @@ func main() {
4203
4248
  _ = store.MarkProcessed(dispatch, "verify:"+result)
4204
4249
  }
4205
4250
 
4251
+ case "address.test", "address.test-dispatch":
4252
+ // OneAddress connection-verification probe. Reaching this case means the
4253
+ // decrypt above succeeded (a wrong key returned 422), which is what the
4254
+ // check proves, so answer verification=true rather than the ok:true below.
4255
+ log.Printf("[webhook] %s verification probe decrypted OK", event)
4256
+ if dispatch != "" {
4257
+ _ = store.MarkProcessed(dispatch, "verification:ok")
4258
+ }
4259
+ var idx any = nil
4260
+ if v, ok := parsed["index"]; ok {
4261
+ idx = v
4262
+ }
4263
+ jsonResp(w, 200, map[string]any{"verification": true, "index": idx})
4264
+ return
4265
+
4206
4266
  default:
4207
4267
  log.Printf("[webhook] Unknown event %q \u2014 acknowledged", event)
4208
4268
  if dispatch != "" {
@@ -4869,7 +4929,11 @@ Route::post('/webhook', function (Request $request): Response {
4869
4929
 
4870
4930
  $eventType = $body['event'] ?? '';
4871
4931
 
4872
- if ($eventType !== 'address.updated' && $eventType !== 'address.verify') {
4932
+ // address.test / address.test-dispatch (the connection-verification probe)
4933
+ // must pass this guard so it reaches the decrypt below; a wrong key then
4934
+ // returns 422 and only a real decrypt reaches the verification answer.
4935
+ if ($eventType !== 'address.updated' && $eventType !== 'address.verify'
4936
+ && $eventType !== 'address.test' && $eventType !== 'address.test-dispatch') {
4873
4937
  return response()->json(['ok' => true, 'skipped' => true]);
4874
4938
  }
4875
4939
 
@@ -5038,6 +5102,14 @@ Route::post('/webhook', function (Request $request): Response {
5038
5102
  }
5039
5103
  }
5040
5104
 
5105
+ if ($eventType === 'address.test' || $eventType === 'address.test-dispatch') {
5106
+ // OneAddress connection-verification probe. Reaching here means the D5
5107
+ // decrypt above succeeded (a wrong key returned 422), which is what the
5108
+ // check proves, so answer verification=true.
5109
+ \\Log::info('[OneAddress] verification probe decrypted OK', ['event' => $eventType]);
5110
+ return response()->json(['verification' => true, 'index' => $body['index'] ?? null]);
5111
+ }
5112
+
5041
5113
  if ($eventType === 'address.updated') {
5042
5114
  // Work FIRST, respond after. Acknowledging before the write commits
5043
5115
  // marks the dispatch delivered on a failure that is never retried.
@@ -5224,7 +5296,7 @@ async function scaffold(platform, outputDir, partnerId, webhookSecret, webhookUr
5224
5296
 
5225
5297
  // src/register.ts
5226
5298
  var import_node_crypto = require("crypto");
5227
- var PKG_VERSION = true ? "1.3.2" : "dev";
5299
+ var PKG_VERSION = true ? "1.3.3" : "dev";
5228
5300
  var REGISTER_URL = "https://partners.oneaddress.io/api/partner/installs";
5229
5301
  function hmacSha256(secret, message) {
5230
5302
  return (0, import_node_crypto.createHmac)("sha256", secret).update(message).digest("hex");
@@ -6284,21 +6356,36 @@ Continuing will overwrite it.`
6284
6356
  s4.start("Starting Cloudflare Tunnel");
6285
6357
  onCleanup(stopTunnel);
6286
6358
  try {
6287
- const tunnel = await startTunnel(3001);
6359
+ let tunnel = await startTunnel(3001);
6288
6360
  webhookUrl = `${tunnel.url}/webhook`;
6289
6361
  tunnelBase = tunnel.url;
6290
6362
  s4.stop(`Tunnel active: ${tunnel.url}`);
6291
6363
  M2.warn(
6292
- "IMPORTANT: This tunnel URL is temporary \u2014 it expires when this process stops.\nBefore going to production, deploy to a permanent server and update the webhook URL in the portal."
6364
+ "IMPORTANT: This tunnel URL is temporary. It lives only while this wizard\nkeeps running, and every run gets a new address. Before going to production,\ndeploy to a permanent server and update the webhook URL in the portal."
6293
6365
  );
6294
6366
  const s4b = Y2();
6295
6367
  s4b.start("Waiting for the tunnel to start routing");
6296
- const ready = await waitForTunnelReady(tunnel.url);
6297
- webhookReady = ready;
6298
- s4b.stop(ready ? "Tunnel is routing" : "Tunnel is slow to come online");
6299
- if (!ready) {
6368
+ webhookReady = await waitForTunnelReady(tunnel.url);
6369
+ if (!webhookReady) {
6370
+ s4b.stop("First tunnel is slow to route, trying a fresh one");
6371
+ stopTunnel();
6372
+ tunnel = await startTunnel(3001);
6373
+ webhookUrl = `${tunnel.url}/webhook`;
6374
+ tunnelBase = tunnel.url;
6375
+ const s4c = Y2();
6376
+ s4c.start(`Waiting for the new tunnel to route: ${tunnel.url}`);
6377
+ webhookReady = await waitForTunnelReady(tunnel.url, { budgetMs: 45e3 });
6378
+ s4c.stop(webhookReady ? "Tunnel is routing" : "Tunnel still not routing");
6379
+ } else {
6380
+ s4b.stop("Tunnel is routing");
6381
+ }
6382
+ if (!webhookReady) {
6300
6383
  M2.warn(
6301
- "The tunnel edge has not answered yet. This is a Cloudflare warmup delay,\nnot your server, which is running on :3001. The wizard will wait once more\nbefore the conformance checks so a cold tunnel does not read as a failure."
6384
+ `The tunnel edge is still not routing after a retry. This is almost always
6385
+ one of two things, and neither is your server (it is running on :3001):
6386
+ 1. Open ${tunnel.url}/health in a browser. If it never loads, your network
6387
+ is blocking cloudflared and no wait will fix it, so try a different network.
6388
+ 2. The tunnel only lives while this wizard runs, so keep this window open.`
6302
6389
  );
6303
6390
  }
6304
6391
  } catch (err) {
@@ -6341,7 +6428,10 @@ Continuing will overwrite it.`
6341
6428
  }
6342
6429
  if (!webhookReady) {
6343
6430
  M2.warn(
6344
- "Skipping the conformance checks: the Cloudflare tunnel edge has not come online.\nThis is a tunnel warmup delay, not your server, which is running on :3001.\nRe-run the wizard, or run `npm test` once the tunnel URL responds in a browser."
6431
+ `Skipping the conformance checks: the tunnel edge is not routing.
6432
+ Your server is fine, it is running on :3001. This is either your network
6433
+ blocking cloudflared (open ${tunnelBase}/health in a browser to check) or the
6434
+ tunnel needing this wizard to stay open. Re-run once that URL loads in a browser.`
6345
6435
  );
6346
6436
  } else {
6347
6437
  M2.info("");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneaddress/setup",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "Interactive setup wizard for OneAddress partner webhook integrations",
5
5
  "main": "dist/index.js",
6
6
  "bin": {