@tencentcloudadp/cli 0.1.1 → 0.1.2
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/cli.js +28 -13
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/skills/adp/SKILL.md +1 -1
- package/skills/adp/references/auth.md +1 -1
package/dist/cli.js
CHANGED
|
@@ -1688,6 +1688,7 @@ function createLocalCredentialForm() {
|
|
|
1688
1688
|
}
|
|
1689
1689
|
async function openForm(input) {
|
|
1690
1690
|
const token = randomBytes(32).toString("base64url");
|
|
1691
|
+
const csrf = randomBytes(32).toString("base64url");
|
|
1691
1692
|
const expectedPath = `/login/${token}`;
|
|
1692
1693
|
let host = "";
|
|
1693
1694
|
let state = "open";
|
|
@@ -1699,7 +1700,7 @@ async function openForm(input) {
|
|
|
1699
1700
|
const server = createServer((req, res) => {
|
|
1700
1701
|
void handle(req, res).catch(() => {
|
|
1701
1702
|
if (!res.headersSent) {
|
|
1702
|
-
send(res, 500, page({ error: "Internal error" }));
|
|
1703
|
+
send(res, 500, page({ error: "Internal error", csrf }));
|
|
1703
1704
|
}
|
|
1704
1705
|
});
|
|
1705
1706
|
});
|
|
@@ -1718,19 +1719,15 @@ async function openForm(input) {
|
|
|
1718
1719
|
return;
|
|
1719
1720
|
}
|
|
1720
1721
|
if (req.method === "GET") {
|
|
1721
|
-
send(res, 200, page({ site: input.defaultSite }));
|
|
1722
|
+
send(res, 200, page({ site: input.defaultSite, csrf }));
|
|
1722
1723
|
return;
|
|
1723
1724
|
}
|
|
1724
1725
|
if (req.method !== "POST") {
|
|
1725
1726
|
send(res, 405, "Method not allowed", "text/plain");
|
|
1726
1727
|
return;
|
|
1727
1728
|
}
|
|
1728
|
-
if (!isSameOrigin(req, host)) {
|
|
1729
|
-
send(res, 403, "Cross-origin request rejected", "text/plain");
|
|
1730
|
-
return;
|
|
1731
|
-
}
|
|
1732
1729
|
if (state === "verifying") {
|
|
1733
|
-
send(res, 409, page({ error: "A submission is already being verified. Wait a moment and reload." }));
|
|
1730
|
+
send(res, 409, page({ error: "A submission is already being verified. Wait a moment and reload.", csrf }));
|
|
1734
1731
|
return;
|
|
1735
1732
|
}
|
|
1736
1733
|
const body = await readBody(req);
|
|
@@ -1738,9 +1735,17 @@ async function openForm(input) {
|
|
|
1738
1735
|
send(res, 413, "Request body too large", "text/plain");
|
|
1739
1736
|
return;
|
|
1740
1737
|
}
|
|
1741
|
-
const
|
|
1738
|
+
const params = new URLSearchParams(body);
|
|
1739
|
+
if (!isSameOrigin(req, host) && !sameSecret(params.get("csrf") ?? "", csrf)) {
|
|
1740
|
+
send(res, 403, page({
|
|
1741
|
+
error: "\u6D4F\u89C8\u5668\u628A\u8FD9\u6B21\u63D0\u4EA4\u5F53\u6210\u4E86\u8DE8\u7AD9\u8BF7\u6C42\u3002\u8BF7\u5728\u672C\u9875\u91CD\u65B0\u586B\u5199\u5E76\u70B9\u300C\u9A8C\u8BC1\u5E76\u4FDD\u5B58\u300D\u3002",
|
|
1742
|
+
csrf
|
|
1743
|
+
}));
|
|
1744
|
+
return;
|
|
1745
|
+
}
|
|
1746
|
+
const parsed = parseSubmission(params);
|
|
1742
1747
|
if ("error" in parsed) {
|
|
1743
|
-
send(res, 400, page({ error: parsed.error, site: parsed.site, secretId: parsed.secretId }));
|
|
1748
|
+
send(res, 400, page({ error: parsed.error, site: parsed.site, secretId: parsed.secretId, csrf }));
|
|
1744
1749
|
return;
|
|
1745
1750
|
}
|
|
1746
1751
|
state = "verifying";
|
|
@@ -1749,7 +1754,7 @@ async function openForm(input) {
|
|
|
1749
1754
|
} catch (error) {
|
|
1750
1755
|
state = "open";
|
|
1751
1756
|
const message = error instanceof Error ? error.message : "Verification failed";
|
|
1752
|
-
send(res, 400, page({ error: message, site: parsed.credential.site, secretId: parsed.credential.secretId }));
|
|
1757
|
+
send(res, 400, page({ error: message, site: parsed.credential.site, secretId: parsed.credential.secretId, csrf }));
|
|
1753
1758
|
return;
|
|
1754
1759
|
}
|
|
1755
1760
|
state = "done";
|
|
@@ -1850,6 +1855,11 @@ body{font:14px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;max-wi
|
|
|
1850
1855
|
label{display:block;margin:14px 0 4px;font-weight:600}input,select{width:100%;padding:8px;box-sizing:border-box;border:1px solid #c9cdd4;border-radius:6px;font:inherit}
|
|
1851
1856
|
button{margin-top:20px;padding:9px 18px;border:0;border-radius:6px;background:#0052d9;color:#fff;font:inherit;cursor:pointer}
|
|
1852
1857
|
.err{background:#fff1f0;border:1px solid #ffccc7;padding:8px 12px;border-radius:6px}.hint{color:#646a73;font-size:13px}
|
|
1858
|
+
.site-hint,.endpoint-field{display:none}
|
|
1859
|
+
form:has(#site option[value="cloud"]:checked) .hint-cloud,
|
|
1860
|
+
form:has(#site option[value="independent"]:checked) .hint-independent,
|
|
1861
|
+
form:has(#site option[value="custom"]:checked) .hint-custom,
|
|
1862
|
+
form:has(#site option[value="custom"]:checked) .endpoint-field{display:block}
|
|
1853
1863
|
</style></head><body>${body}</body></html>`;
|
|
1854
1864
|
}
|
|
1855
1865
|
function form(input) {
|
|
@@ -1859,15 +1869,20 @@ function form(input) {
|
|
|
1859
1869
|
<p class="hint">\u51ED\u636E\u53EA\u4FDD\u5B58\u5728\u672C\u673A\uFF08~/.adp/profiles\uFF0C\u6743\u9650 0600\uFF09\uFF0C\u4E0D\u4F1A\u53D1\u9001\u5230\u5BF9\u8BDD\u3002\u8BF7\u4E0D\u8981\u628A\u5BC6\u94A5\u7C98\u8D34\u5230\u804A\u5929\u91CC\u3002</p>
|
|
1860
1870
|
${input.error ? `<p class="err">${escapeHtml(input.error)}</p>` : ""}
|
|
1861
1871
|
<form method="post" autocomplete="off">
|
|
1872
|
+
<input type="hidden" name="csrf" value="${escapeHtml(input.csrf ?? "")}">
|
|
1862
1873
|
<label for="site">\u7AD9\u70B9</label>
|
|
1863
1874
|
<select id="site" name="site">${option("cloud", "\u516C\u6709\u4E91\uFF08adp.tencentcloudapi.com\uFF09")}${option("independent", "\u72EC\u7ACB\u7AD9\uFF08capi.adp.tencent.com\uFF09")}${option("custom", "\u81EA\u5B9A\u4E49\u5730\u5740")}</select>
|
|
1864
|
-
<
|
|
1875
|
+
<div class="endpoint-field">
|
|
1876
|
+
<label for="endpoint">\u81EA\u5B9A\u4E49\u5730\u5740</label>
|
|
1865
1877
|
<input id="endpoint" name="endpoint" placeholder="capi.internal.example.com">
|
|
1878
|
+
</div>
|
|
1866
1879
|
<label for="secretId">SecretId</label>
|
|
1867
|
-
<input id="secretId" name="secretId" required value="${escapeHtml(input.secretId ?? "")}"
|
|
1880
|
+
<input id="secretId" name="secretId" required value="${escapeHtml(input.secretId ?? "")}">
|
|
1868
1881
|
<label for="secretKey">SecretKey</label>
|
|
1869
1882
|
<input id="secretKey" name="secretKey" type="password" required>
|
|
1870
|
-
<p class="hint">\u516C\u6709\u4E91\u5BC6\u94A5\u5728 <a href="https://console.cloud.tencent.com/cam/capi" target="_blank" rel="noreferrer">CAM \u63A7\u5236\u53F0</a> \u521B\u5EFA\u3002</p>
|
|
1883
|
+
<p class="hint site-hint hint-cloud">\u516C\u6709\u4E91\u5BC6\u94A5\u5728 <a href="https://console.cloud.tencent.com/cam/capi" target="_blank" rel="noreferrer">CAM \u63A7\u5236\u53F0</a> \u521B\u5EFA\uFF0CSecretId \u4EE5 AKID \u5F00\u5934\u3002</p>
|
|
1884
|
+
<p class="hint site-hint hint-independent">\u72EC\u7ACB\u7AD9\u5BC6\u94A5\u5728 <a href="https://adp.tencent.com/adp#/key-manage" target="_blank" rel="noreferrer">\u4F01\u4E1A\u7BA1\u7406 \u2192 \u5BC6\u94A5\u7BA1\u7406 \u2192 \u65B0\u5EFAAPI\u5BC6\u94A5</a>\uFF0C\u4E0D\u8981\u6C42 AKID \u524D\u7F00\u3002</p>
|
|
1885
|
+
<p class="hint site-hint hint-custom">\u4F7F\u7528\u76EE\u6807\u73AF\u5883\u7B7E\u53D1\u7684 SecretId / SecretKey\u3002</p>
|
|
1871
1886
|
<button type="submit">\u9A8C\u8BC1\u5E76\u4FDD\u5B58</button>
|
|
1872
1887
|
</form>`;
|
|
1873
1888
|
}
|