@oneaddress/setup 1.2.1 → 1.3.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.
- package/dist/index.js +85 -52
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -856,8 +856,31 @@ 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.
|
|
859
|
+
var WIZARD_VERSION = true ? "1.3.1" : "?";
|
|
860
|
+
function printCompactHeader() {
|
|
861
|
+
const INNER = 42;
|
|
862
|
+
const TOP = fn("\u250C") + dm("\u2500".repeat(INNER)) + fn("\u2510");
|
|
863
|
+
const BOT = fn("\u2514") + dm("\u2500".repeat(INNER)) + fn("\u2518");
|
|
864
|
+
const S3 = dm("\u2502");
|
|
865
|
+
const blank = ` ${S3}${" ".repeat(INNER)}${S3}`;
|
|
866
|
+
const row = (content, visibleLen) => ` ${S3} ${content}${" ".repeat(Math.max(0, INNER - 2 - visibleLen))}${S3}`;
|
|
867
|
+
const ver = `v${WIZARD_VERSION} \xB7 partners.oneaddress.io`;
|
|
868
|
+
console.log("");
|
|
869
|
+
console.log(" " + TOP);
|
|
870
|
+
console.log(blank);
|
|
871
|
+
console.log(row(wb("One ") + ab("Address"), "One Address".length));
|
|
872
|
+
console.log(row(mi("Partner Setup Wizard"), "Partner Setup Wizard".length));
|
|
873
|
+
console.log(row(fn(ver), ver.length));
|
|
874
|
+
console.log(blank);
|
|
875
|
+
console.log(" " + BOT);
|
|
876
|
+
console.log("");
|
|
877
|
+
}
|
|
860
878
|
function printHeader() {
|
|
879
|
+
const cols = typeof process !== "undefined" && process.stdout && process.stdout.columns ? process.stdout.columns : 80;
|
|
880
|
+
if (cols < 88) {
|
|
881
|
+
printCompactHeader();
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
861
884
|
const BAR_LEN = 85;
|
|
862
885
|
const TOP_BAR = fn("\u250C") + dm("\u2500".repeat(BAR_LEN)) + fn("\u2510");
|
|
863
886
|
const BOT_BAR = fn("\u2514") + dm("\u2500".repeat(BAR_LEN)) + fn("\u2518");
|
|
@@ -5201,7 +5224,7 @@ async function scaffold(platform, outputDir, partnerId, webhookSecret, webhookUr
|
|
|
5201
5224
|
|
|
5202
5225
|
// src/register.ts
|
|
5203
5226
|
var import_node_crypto = require("crypto");
|
|
5204
|
-
var PKG_VERSION = true ? "1.
|
|
5227
|
+
var PKG_VERSION = true ? "1.3.1" : "dev";
|
|
5205
5228
|
var REGISTER_URL = "https://partners.oneaddress.io/api/partner/installs";
|
|
5206
5229
|
function hmacSha256(secret, message) {
|
|
5207
5230
|
return (0, import_node_crypto.createHmac)("sha256", secret).update(message).digest("hex");
|
|
@@ -5686,7 +5709,13 @@ async function startTunnel(port) {
|
|
|
5686
5709
|
// src/register-url.ts
|
|
5687
5710
|
var import_node_crypto4 = require("crypto");
|
|
5688
5711
|
var PORTAL_API = "https://partners.oneaddress.io/api/partner/webhook-url";
|
|
5689
|
-
|
|
5712
|
+
function describeReadFailure(status) {
|
|
5713
|
+
if (status === 401) return "the portal rejected the signature (HTTP 401), which means your Webhook signing secret does not match the one on your profile. Copy it again from partners.oneaddress.io \u2192 Webhook \u2192 Webhook signing secret.";
|
|
5714
|
+
if (status === 404) return "the portal has no active partner for this account (HTTP 404), which usually means it is not approved yet.";
|
|
5715
|
+
if (status === 400) return "the portal rejected the request (HTTP 400).";
|
|
5716
|
+
return `the portal returned HTTP ${status}.`;
|
|
5717
|
+
}
|
|
5718
|
+
async function getExistingWebhookUrl(partnerId, webhookSecret, onError) {
|
|
5690
5719
|
try {
|
|
5691
5720
|
const ts = String(Math.floor(Date.now() / 1e3));
|
|
5692
5721
|
const sig = (0, import_node_crypto4.createHmac)("sha256", webhookSecret).update(`${ts}.`).digest("hex");
|
|
@@ -5699,14 +5728,18 @@ async function getExistingWebhookUrl(partnerId, webhookSecret) {
|
|
|
5699
5728
|
},
|
|
5700
5729
|
signal: AbortSignal.timeout(8e3)
|
|
5701
5730
|
});
|
|
5702
|
-
if (!res.ok)
|
|
5731
|
+
if (!res.ok) {
|
|
5732
|
+
onError?.(describeReadFailure(res.status));
|
|
5733
|
+
return void 0;
|
|
5734
|
+
}
|
|
5703
5735
|
const data = await res.json();
|
|
5704
5736
|
return data.webhook_url ?? null;
|
|
5705
|
-
} catch {
|
|
5737
|
+
} catch (err) {
|
|
5738
|
+
onError?.(`could not reach the portal (${err instanceof Error ? err.message : "network error"})`);
|
|
5706
5739
|
return void 0;
|
|
5707
5740
|
}
|
|
5708
5741
|
}
|
|
5709
|
-
async function getVerifiesAccountReference(partnerId, webhookSecret) {
|
|
5742
|
+
async function getVerifiesAccountReference(partnerId, webhookSecret, onError) {
|
|
5710
5743
|
try {
|
|
5711
5744
|
const ts = String(Math.floor(Date.now() / 1e3));
|
|
5712
5745
|
const sig = (0, import_node_crypto4.createHmac)("sha256", webhookSecret).update(`${ts}.`).digest("hex");
|
|
@@ -5719,13 +5752,17 @@ async function getVerifiesAccountReference(partnerId, webhookSecret) {
|
|
|
5719
5752
|
},
|
|
5720
5753
|
signal: AbortSignal.timeout(8e3)
|
|
5721
5754
|
});
|
|
5722
|
-
if (!res.ok)
|
|
5755
|
+
if (!res.ok) {
|
|
5756
|
+
onError?.(describeReadFailure(res.status));
|
|
5757
|
+
return void 0;
|
|
5758
|
+
}
|
|
5723
5759
|
const data = await res.json();
|
|
5724
5760
|
const v2 = data.verifies_account_reference;
|
|
5725
5761
|
if (v2 === true || v2 === false) return v2;
|
|
5726
5762
|
if (v2 === null) return null;
|
|
5727
5763
|
return void 0;
|
|
5728
|
-
} catch {
|
|
5764
|
+
} catch (err) {
|
|
5765
|
+
onError?.(`could not reach the portal (${err instanceof Error ? err.message : "network error"})`);
|
|
5729
5766
|
return void 0;
|
|
5730
5767
|
}
|
|
5731
5768
|
}
|
|
@@ -5759,20 +5796,26 @@ async function registerWebhookUrl(partnerId, webhookSecret, webhookUrl) {
|
|
|
5759
5796
|
}
|
|
5760
5797
|
}
|
|
5761
5798
|
|
|
5762
|
-
// src/
|
|
5799
|
+
// src/cli-gate.ts
|
|
5763
5800
|
var MAX_ATTEMPTS = 3;
|
|
5764
5801
|
var AUTH_URL = "https://partners.oneaddress.io/api/cli/auth";
|
|
5765
|
-
async function
|
|
5802
|
+
async function checkToken(token) {
|
|
5766
5803
|
try {
|
|
5767
5804
|
const res = await fetch(AUTH_URL, {
|
|
5768
5805
|
method: "POST",
|
|
5769
5806
|
headers: { "Content-Type": "application/json" },
|
|
5770
|
-
body: JSON.stringify({
|
|
5807
|
+
body: JSON.stringify({ token: token.trim() }),
|
|
5771
5808
|
signal: AbortSignal.timeout(8e3)
|
|
5772
5809
|
});
|
|
5773
|
-
if (res.status === 200)
|
|
5774
|
-
|
|
5775
|
-
|
|
5810
|
+
if (res.status === 200) {
|
|
5811
|
+
const data = await res.json().catch(() => ({}));
|
|
5812
|
+
if (data.ok && typeof data.partnerId === "string" && data.partnerId) {
|
|
5813
|
+
return { ok: true, partnerId: data.partnerId };
|
|
5814
|
+
}
|
|
5815
|
+
return { ok: false, reason: "Portal did not return a partner for this token, is it a CLI token from Profile \u2192 CLI Access?" };
|
|
5816
|
+
}
|
|
5817
|
+
if (res.status === 401) return { ok: false, reason: "Token not accepted" };
|
|
5818
|
+
if (res.status === 429) return { ok: false, reason: "Rate-limited, wait 60 s and retry", retryable: true };
|
|
5776
5819
|
const body = await res.json().catch(() => ({}));
|
|
5777
5820
|
return {
|
|
5778
5821
|
ok: false,
|
|
@@ -5787,35 +5830,26 @@ async function checkCredentials(user, pass) {
|
|
|
5787
5830
|
};
|
|
5788
5831
|
}
|
|
5789
5832
|
}
|
|
5790
|
-
async function
|
|
5833
|
+
async function cliGate() {
|
|
5791
5834
|
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
5792
|
-
const
|
|
5793
|
-
message: attempt === 1 ? "OneAddress CLI
|
|
5794
|
-
|
|
5795
|
-
validate: (v2) => v2.trim() ? void 0 : "Username is required"
|
|
5796
|
-
});
|
|
5797
|
-
if (pD(user)) {
|
|
5798
|
-
xe("Cancelled.");
|
|
5799
|
-
process.exit(0);
|
|
5800
|
-
}
|
|
5801
|
-
const pass = await ge({
|
|
5802
|
-
message: "OneAddress CLI Password",
|
|
5803
|
-
validate: (v2) => v2.trim() ? void 0 : "Password is required"
|
|
5835
|
+
const token = await ge({
|
|
5836
|
+
message: attempt === 1 ? "OneAddress CLI token (Profile \u2192 CLI Access in the portal)" : `OneAddress CLI token (attempt ${attempt}/${MAX_ATTEMPTS})`,
|
|
5837
|
+
validate: (v2) => v2.trim() ? void 0 : "CLI token is required"
|
|
5804
5838
|
});
|
|
5805
|
-
if (pD(
|
|
5839
|
+
if (pD(token)) {
|
|
5806
5840
|
xe("Cancelled.");
|
|
5807
5841
|
process.exit(0);
|
|
5808
5842
|
}
|
|
5809
|
-
const result = await
|
|
5810
|
-
if (result.ok) return;
|
|
5843
|
+
const result = await checkToken(token);
|
|
5844
|
+
if (result.ok) return { partnerId: result.partnerId };
|
|
5811
5845
|
if (result.retryable) {
|
|
5812
|
-
M2.warn(` ${result.reason}
|
|
5846
|
+
M2.warn(` ${result.reason}, retry the same token.`);
|
|
5813
5847
|
attempt--;
|
|
5814
5848
|
continue;
|
|
5815
5849
|
}
|
|
5816
5850
|
if (attempt < MAX_ATTEMPTS) {
|
|
5817
5851
|
const remaining = MAX_ATTEMPTS - attempt;
|
|
5818
|
-
M2.error(` ${result.reason}
|
|
5852
|
+
M2.error(` ${result.reason}, ${remaining} attempt${remaining === 1 ? "" : "s"} remaining.`);
|
|
5819
5853
|
} else {
|
|
5820
5854
|
M2.error(` ${result.reason}.`);
|
|
5821
5855
|
}
|
|
@@ -5989,26 +6023,20 @@ function stripControlChars(line) {
|
|
|
5989
6023
|
async function main() {
|
|
5990
6024
|
printHeader();
|
|
5991
6025
|
Ie("OneAddress Partner Setup");
|
|
5992
|
-
await
|
|
6026
|
+
const { partnerId: pid } = await cliGate();
|
|
6027
|
+
if (!UUID_RE.test(pid)) {
|
|
6028
|
+
xe("The portal returned an unexpected partner id. Please retry, or contact support.");
|
|
6029
|
+
process.exit(1);
|
|
6030
|
+
}
|
|
5993
6031
|
M2.info("We will:");
|
|
5994
|
-
M2.info(" 1. Collect your credentials from the Partner Portal");
|
|
6032
|
+
M2.info(" 1. Collect your remaining credentials from the Partner Portal");
|
|
5995
6033
|
M2.info(" 2. Scaffold a working webhook server for your platform");
|
|
5996
6034
|
M2.info(" 3. Get it live with a passing conformance check \u2014 in under 5 minutes");
|
|
5997
|
-
M2.info("\nOpen partners.oneaddress.io \u2192 My Profile to find
|
|
5998
|
-
const partnerId = await he({
|
|
5999
|
-
message: "Your Partner ID (UUID format)",
|
|
6000
|
-
placeholder: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
6001
|
-
validate: (v2) => {
|
|
6002
|
-
if (!v2.trim()) return "Partner ID is required";
|
|
6003
|
-
if (!UUID_RE.test(v2.trim()))
|
|
6004
|
-
return "Must be a valid UUID \u2014 find it at partners.oneaddress.io \u2192 My Profile";
|
|
6005
|
-
}
|
|
6006
|
-
});
|
|
6007
|
-
assertNotCancelled(partnerId);
|
|
6035
|
+
M2.info("\nOpen partners.oneaddress.io \u2192 My Profile to find the two values below.\n");
|
|
6008
6036
|
const webhookSecret = await ge({
|
|
6009
|
-
message: "Your Webhook
|
|
6037
|
+
message: "Your Webhook signing secret (min 20 chars)",
|
|
6010
6038
|
validate: (v2) => {
|
|
6011
|
-
if (!v2.trim()) return "Webhook
|
|
6039
|
+
if (!v2.trim()) return "Webhook signing secret is required";
|
|
6012
6040
|
if (v2.length < 20) return "That looks too short \u2014 paste the full secret from My Profile";
|
|
6013
6041
|
}
|
|
6014
6042
|
});
|
|
@@ -6024,7 +6052,6 @@ async function main() {
|
|
|
6024
6052
|
}
|
|
6025
6053
|
});
|
|
6026
6054
|
assertNotCancelled(privateKeyRaw);
|
|
6027
|
-
const pid = partnerId.trim();
|
|
6028
6055
|
const secret = webhookSecret.trim();
|
|
6029
6056
|
const normalised = normalisePrivateKey(privateKeyRaw.trim());
|
|
6030
6057
|
if (normalised.error) {
|
|
@@ -6069,11 +6096,14 @@ async function main() {
|
|
|
6069
6096
|
}
|
|
6070
6097
|
}
|
|
6071
6098
|
}
|
|
6072
|
-
|
|
6099
|
+
let accountRefReason = "";
|
|
6100
|
+
const accountRefDeclaration = await getVerifiesAccountReference(pid, secret, (r2) => {
|
|
6101
|
+
accountRefReason = r2;
|
|
6102
|
+
});
|
|
6073
6103
|
const verifiesAccountReference = accountRefDeclaration === true;
|
|
6074
6104
|
if (accountRefDeclaration === void 0) {
|
|
6075
6105
|
M2.warn(
|
|
6076
|
-
"Could not read your account-reference declaration from the portal.\
|
|
6106
|
+
"Could not read your account-reference declaration from the portal.\n" + (accountRefReason ? "Reason: " + accountRefReason + "\n" : "") + "Conformance check-14 has been left out of the generated `npm test`, so a\npassing run does NOT mean your receiver matches account references correctly.\nSet it at partners.oneaddress.io \u2192 My Profile, then re-run this wizard."
|
|
6077
6107
|
);
|
|
6078
6108
|
}
|
|
6079
6109
|
const s1 = Y2();
|
|
@@ -6147,7 +6177,10 @@ async function main() {
|
|
|
6147
6177
|
if (start.output) M2.warn(start.output.slice(0, 600));
|
|
6148
6178
|
}
|
|
6149
6179
|
let webhookUrl = "";
|
|
6150
|
-
|
|
6180
|
+
let existingUrlReason = "";
|
|
6181
|
+
const existingUrlResult = await getExistingWebhookUrl(pid, secret, (r2) => {
|
|
6182
|
+
existingUrlReason = r2;
|
|
6183
|
+
});
|
|
6151
6184
|
if (typeof existingUrlResult === "string") {
|
|
6152
6185
|
M2.warn(
|
|
6153
6186
|
`A webhook URL is already registered for this partner:
|
|
@@ -6166,7 +6199,7 @@ Continuing will overwrite it.`
|
|
|
6166
6199
|
}
|
|
6167
6200
|
} else if (existingUrlResult === void 0) {
|
|
6168
6201
|
M2.warn(
|
|
6169
|
-
"Could not check whether a webhook URL is already registered (portal API unreachable).
|
|
6202
|
+
"Could not check whether a webhook URL is already registered" + (existingUrlReason ? ": " + existingUrlReason : " (portal API unreachable).") + "\nAny URL you register now will overwrite an existing one without warning."
|
|
6170
6203
|
);
|
|
6171
6204
|
const continueAnyway = await ye({
|
|
6172
6205
|
message: "Continue anyway?",
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oneaddress/setup",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Interactive setup wizard for OneAddress partner webhook integrations",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"oneaddress-setup": "dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"LICENSE",
|
|
10
|
+
"LICENSE",
|
|
11
|
+
"dist",
|
|
11
12
|
"README.md"
|
|
12
13
|
],
|
|
13
14
|
"scripts": {
|