@oneaddress/setup 1.1.1 → 1.1.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 +93 -43
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -808,7 +808,7 @@ var L2 = () => {
808
808
  };
809
809
 
810
810
  // src/prompts.ts
811
- var import_node_crypto3 = require("crypto");
811
+ var import_node_crypto4 = require("crypto");
812
812
  var import_node_fs4 = require("fs");
813
813
  var import_node_os2 = require("os");
814
814
  var import_node_path5 = require("path");
@@ -821,13 +821,11 @@ var CRM = "\x1B[38;2;245;238;216m";
821
821
  var FNT = "\x1B[38;2;130;100;45m";
822
822
  var DIM = "\x1B[38;2;70;58;35m";
823
823
  var MID = "\x1B[38;2;155;135;100m";
824
- var GRN = "\x1B[38;2;80;200;120m";
825
824
  var ab = (s) => `${B2}${AMB}${s}${R3}`;
826
825
  var wb = (s) => `${B2}${CRM}${s}${R3}`;
827
826
  var fn = (s) => `${FNT}${s}${R3}`;
828
827
  var dm = (s) => `${DIM}${s}${R3}`;
829
828
  var mi = (s) => `${MID}${s}${R3}`;
830
- var gn = (s) => `${GRN}${s}${R3}`;
831
829
  var _O = [" \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", " \u2588\u2588\u2588\u2588\u2588 "];
832
830
  var _N = ["\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\u2588\u2588\u2588", "\u2588\u2588 \u2588\u2588\u2588", "\u2588\u2588 \u2588\u2588"];
833
831
  var _E = ["\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\u2588\u2588\u2588"];
@@ -853,7 +851,7 @@ function printHeader() {
853
851
  console.log(` ${SIDE}${" ".repeat(BAR_LEN)}${SIDE}`);
854
852
  const wizard = mi("Partner Setup Wizard");
855
853
  const version = fn("v2 \xB7 partners.oneaddress.io");
856
- const tagLine = ` ${wizard} ${version} ${gn("\xB7io")}`;
854
+ const tagLine = ` ${wizard} ${version}`;
857
855
  const padLen = BAR_LEN - 4 - stripAnsi(tagLine).length;
858
856
  console.log(` ${SIDE} ${tagLine}${" ".repeat(Math.max(0, padLen))} ${SIDE}`);
859
857
  console.log(` ${SIDE}${" ".repeat(BAR_LEN)}${SIDE}`);
@@ -2934,25 +2932,72 @@ async function registerInstall(installId, partnerId, webhookSecret, platform, we
2934
2932
  }
2935
2933
 
2936
2934
  // src/conformance.ts
2937
- var import_node_child_process = require("child_process");
2938
- function runConformance(webhookUrl, partnerId, webhookSecret) {
2939
- (0, import_node_child_process.spawnSync)(
2940
- "npx",
2941
- [
2942
- "@oneaddress/conformance",
2943
- "test",
2944
- webhookUrl,
2945
- "--partner-id",
2946
- partnerId,
2947
- "--secret",
2948
- webhookSecret
2949
- ],
2950
- { stdio: "inherit" }
2951
- );
2935
+ var import_node_crypto2 = require("crypto");
2936
+ async function runConformance(webhookUrl, _partnerId, webhookSecret) {
2937
+ function sign(ts, body) {
2938
+ return (0, import_node_crypto2.createHmac)("sha256", webhookSecret).update(`${ts}.${body}`).digest("hex");
2939
+ }
2940
+ const validBody = JSON.stringify({ event: "conformance.ping", test: true });
2941
+ const now = String(Math.floor(Date.now() / 1e3));
2942
+ const staleTs = String(Math.floor(Date.now() / 1e3) - 400);
2943
+ const tests = [
2944
+ {
2945
+ name: "Replay attack rejected (stale timestamp)",
2946
+ ts: staleTs,
2947
+ sig: sign(staleTs, validBody),
2948
+ expectOk: false
2949
+ },
2950
+ {
2951
+ name: "Bad signature rejected",
2952
+ ts: now,
2953
+ sig: "deadbeef".repeat(8),
2954
+ expectOk: false
2955
+ },
2956
+ {
2957
+ name: "Valid signed request accepted",
2958
+ ts: now,
2959
+ sig: sign(now, validBody),
2960
+ expectOk: true
2961
+ }
2962
+ ];
2963
+ let passed = 0;
2964
+ let failed = 0;
2965
+ for (const t of tests) {
2966
+ try {
2967
+ const res = await fetch(webhookUrl, {
2968
+ method: "POST",
2969
+ headers: {
2970
+ "Content-Type": "application/json",
2971
+ "X-OneAddress-Timestamp": t.ts,
2972
+ "X-OneAddress-Signature": t.sig,
2973
+ "X-OneAddress-Dispatch": "0"
2974
+ },
2975
+ body: validBody,
2976
+ signal: AbortSignal.timeout(8e3)
2977
+ });
2978
+ const gotOk = res.ok;
2979
+ const pass = t.expectOk ? gotOk : !gotOk;
2980
+ if (pass) {
2981
+ v2.success(` \u2713 ${t.name} (${res.status})`);
2982
+ passed++;
2983
+ } else {
2984
+ v2.warn(` \u2717 ${t.name} (${res.status} \u2014 expected ${t.expectOk ? "2xx" : "4xx"})`);
2985
+ failed++;
2986
+ }
2987
+ } catch (err) {
2988
+ v2.warn(` \u2717 ${t.name} (network error: ${err instanceof Error ? err.message : String(err)})`);
2989
+ failed++;
2990
+ }
2991
+ }
2992
+ if (failed === 0) {
2993
+ v2.success(`Conformance passed ${passed}/${tests.length} \u2014 your endpoint is correctly secured.`);
2994
+ } else {
2995
+ v2.warn(`Conformance: ${passed}/${tests.length} passed. Check your WEBHOOK_SECRET and timestamp enforcement.`);
2996
+ }
2952
2997
  }
2953
2998
 
2954
2999
  // src/install.ts
2955
- var import_node_child_process2 = require("child_process");
3000
+ var import_node_child_process = require("child_process");
2956
3001
  var import_node_fs2 = require("fs");
2957
3002
  var import_node_path2 = require("path");
2958
3003
  var COMMANDS = {
@@ -2979,7 +3024,7 @@ function installDependencies(platform, outputDir) {
2979
3024
  }
2980
3025
  const cwd = spec.cwd ? (0, import_node_path2.join)(outputDir, spec.cwd) : outputDir;
2981
3026
  const manualCommand = `cd ${outputDir} && ${spec.cmd} ${spec.args.join(" ")}`;
2982
- const result = (0, import_node_child_process2.spawnSync)(spec.cmd, spec.args, {
3027
+ const result = (0, import_node_child_process.spawnSync)(spec.cmd, spec.args, {
2983
3028
  cwd,
2984
3029
  stdio: "pipe",
2985
3030
  encoding: "utf8",
@@ -2996,7 +3041,7 @@ function installDependencies(platform, outputDir) {
2996
3041
  }
2997
3042
 
2998
3043
  // src/autostart.ts
2999
- var import_node_child_process3 = require("child_process");
3044
+ var import_node_child_process2 = require("child_process");
3000
3045
  var import_node_path3 = require("path");
3001
3046
  var import_node_fs3 = require("fs");
3002
3047
  var COMMANDS2 = {
@@ -3012,7 +3057,14 @@ var serverOutput = "";
3012
3057
  function stopServer() {
3013
3058
  if (serverProcess) {
3014
3059
  try {
3015
- serverProcess.kill("SIGTERM");
3060
+ if (process.platform === "win32" && serverProcess.pid) {
3061
+ (0, import_node_child_process2.spawn)("taskkill", ["/F", "/T", "/PID", String(serverProcess.pid)], {
3062
+ stdio: "ignore",
3063
+ detached: true
3064
+ });
3065
+ } else {
3066
+ serverProcess.kill("SIGTERM");
3067
+ }
3016
3068
  } catch {
3017
3069
  }
3018
3070
  serverProcess = null;
@@ -3062,7 +3114,7 @@ async function startServer(platform, outputDir, port = 3001) {
3062
3114
  }
3063
3115
  serverOutput = "";
3064
3116
  const manualCommand = `cd ${outputDir} && ${spec.cmd} ${spec.args.join(" ")}`;
3065
- serverProcess = (0, import_node_child_process3.spawn)(spec.cmd, spec.args, {
3117
+ serverProcess = (0, import_node_child_process2.spawn)(spec.cmd, spec.args, {
3066
3118
  cwd: outputDir,
3067
3119
  stdio: ["ignore", "pipe", "pipe"],
3068
3120
  detached: false,
@@ -3084,7 +3136,7 @@ async function startServer(platform, outputDir, port = 3001) {
3084
3136
  }
3085
3137
 
3086
3138
  // src/tunnel.ts
3087
- var import_node_child_process4 = require("child_process");
3139
+ var import_node_child_process3 = require("child_process");
3088
3140
  var import_promises2 = require("fs/promises");
3089
3141
  var import_node_path4 = require("path");
3090
3142
  var import_node_os = __toESM(require("os"));
@@ -3120,7 +3172,7 @@ async function downloadCloudflared() {
3120
3172
  }
3121
3173
  async function resolveBinary() {
3122
3174
  try {
3123
- (0, import_node_child_process4.execSync)("cloudflared --version", { stdio: "pipe" });
3175
+ (0, import_node_child_process3.execSync)("cloudflared --version", { stdio: "pipe" });
3124
3176
  return "cloudflared";
3125
3177
  } catch {
3126
3178
  }
@@ -3129,7 +3181,7 @@ async function resolveBinary() {
3129
3181
  async function startTunnel(port) {
3130
3182
  const binary = await resolveBinary();
3131
3183
  return new Promise((resolve2, reject) => {
3132
- tunnelProcess = (0, import_node_child_process4.spawn)(binary, ["tunnel", "--url", `http://localhost:${port}`], {
3184
+ tunnelProcess = (0, import_node_child_process3.spawn)(binary, ["tunnel", "--url", `http://localhost:${port}`], {
3133
3185
  stdio: ["ignore", "pipe", "pipe"]
3134
3186
  });
3135
3187
  let resolved = false;
@@ -3168,13 +3220,13 @@ async function startTunnel(port) {
3168
3220
  }
3169
3221
 
3170
3222
  // src/register-url.ts
3171
- var import_node_crypto2 = require("crypto");
3223
+ var import_node_crypto3 = require("crypto");
3172
3224
  var PORTAL_API = "https://partners.oneaddress.io/api/partner/webhook-url";
3173
3225
  async function registerWebhookUrl(partnerId, webhookSecret, webhookUrl) {
3174
3226
  try {
3175
3227
  const body = JSON.stringify({ webhook_url: webhookUrl });
3176
3228
  const ts = String(Math.floor(Date.now() / 1e3));
3177
- const sig = (0, import_node_crypto2.createHmac)("sha256", webhookSecret).update(`${ts}.${body}`).digest("hex");
3229
+ const sig = (0, import_node_crypto3.createHmac)("sha256", webhookSecret).update(`${ts}.${body}`).digest("hex");
3178
3230
  const res = await fetch(PORTAL_API, {
3179
3231
  method: "PATCH",
3180
3232
  headers: {
@@ -3197,7 +3249,7 @@ var R4 = "\x1B[0m";
3197
3249
  var AMB2 = "\x1B[38;2;224;162;72m";
3198
3250
  var MID2 = "\x1B[38;2;155;135;100m";
3199
3251
  var DIM2 = "\x1B[38;2;70;58;35m";
3200
- var GRN2 = "\x1B[38;2;80;200;120m";
3252
+ var GRN = "\x1B[38;2;80;200;120m";
3201
3253
  var CRM2 = "\x1B[1m\x1B[38;2;245;238;216m";
3202
3254
  var cleanupFns = [];
3203
3255
  function onCleanup(fn2) {
@@ -3274,7 +3326,7 @@ function normalisePrivateKey(raw) {
3274
3326
  }
3275
3327
  function validatePkcs8Pem(pem) {
3276
3328
  try {
3277
- (0, import_node_crypto3.createPrivateKey)({ key: pem, format: "pem", type: "pkcs8" });
3329
+ (0, import_node_crypto4.createPrivateKey)({ key: pem, format: "pem", type: "pkcs8" });
3278
3330
  return void 0;
3279
3331
  } catch (err) {
3280
3332
  return `Key validation failed: ${err instanceof Error ? err.message : String(err)}`;
@@ -3378,7 +3430,7 @@ async function main() {
3378
3430
  process.exit(1);
3379
3431
  }
3380
3432
  const s2 = L2();
3381
- s2.start("Installing dependencies\u2026");
3433
+ s2.start("Installing dependencies (this can take 30\u201360 s)\u2026");
3382
3434
  const install = installDependencies(platform, outDir);
3383
3435
  if (install.ok) {
3384
3436
  s2.stop("Dependencies installed");
@@ -3454,7 +3506,7 @@ async function main() {
3454
3506
  );
3455
3507
  }
3456
3508
  registerInstall(
3457
- `OA-${(0, import_node_crypto3.randomUUID)()}`,
3509
+ `OA-${(0, import_node_crypto4.randomUUID)()}`,
3458
3510
  pid,
3459
3511
  secret,
3460
3512
  platform,
@@ -3462,15 +3514,13 @@ async function main() {
3462
3514
  ).catch(() => {
3463
3515
  });
3464
3516
  }
3465
- if (webhookUrl && serverRunning) {
3466
- v2.info("\nRunning conformance checks \u2014 this may take up to 60 seconds\u2026\n");
3467
- runConformance(webhookUrl, pid, secret);
3468
- } else if (webhookUrl) {
3469
- v2.info("\nStart your server, then run the conformance check:");
3470
- v2.info(` npx @oneaddress/conformance test ${webhookUrl}`);
3471
- } else {
3472
- v2.info("\nOnce your endpoint is live, run the conformance check:");
3473
- v2.info(" npx @oneaddress/conformance test <your-https-url>/webhook");
3517
+ if (webhookUrl) {
3518
+ v2.info("");
3519
+ const s6 = L2();
3520
+ s6.start("Running conformance checks\u2026");
3521
+ await new Promise((r2) => setTimeout(r2, 200));
3522
+ s6.stop("Conformance checks:");
3523
+ await runConformance(webhookUrl, pid, secret);
3474
3524
  }
3475
3525
  const summary = [
3476
3526
  `Partner ID: ${pid}`,
@@ -3490,7 +3540,7 @@ async function main() {
3490
3540
  if (serverRunning) {
3491
3541
  console.log("");
3492
3542
  console.log(` ${DIM2}\u250C${"\u2500".repeat(56)}\u2510${R4}`);
3493
- console.log(` ${DIM2}\u2502${R4} ${GRN2}\u25C8${R4} ${CRM2}Server live${R4} ${MID2}on http://localhost:3001/webhook${R4} ${DIM2}\u2502${R4}`);
3543
+ console.log(` ${DIM2}\u2502${R4} ${GRN}\u25C8${R4} ${CRM2}Server live${R4} ${MID2}on http://localhost:3001/webhook${R4} ${DIM2}\u2502${R4}`);
3494
3544
  console.log(` ${DIM2}\u2502${R4} ${AMB2}\u25C8${R4} ${MID2}Edit ${CRM2}src/store.ts${R4} ${MID2}to wire your database${R4} ${DIM2}\u2502${R4}`);
3495
3545
  console.log(` ${DIM2}\u2502${R4} ${MID2}Press Ctrl+C to stop the server and exit.${R4} ${DIM2} \u2502${R4}`);
3496
3546
  console.log(` ${DIM2}\u2514${"\u2500".repeat(56)}\u2518${R4}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneaddress/setup",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "Interactive setup wizard for OneAddress partner webhook integrations",
5
5
  "main": "dist/index.js",
6
6
  "bin": {