frontend: install command uses the node id from the mint form (node-26#4)
The mint panel's copy command hard-coded --node-id node-XXX. Now the label just entered (the operator types the node id there — placeholder relabeled "Node ID, e.g. node-003") is captured on mint and interpolated into the command: spaces → dashes, non [A-Za-z0-9_-] stripped (install.sh's rule), falling back to node-XXX only if that yields nothing. The "edit node-XXX" hint now only shows in the fallback case. Not typechecked (no node/npm here); one useState<string|null>, one derived string, a JSX conditional. `next build` in deploy.yml gates it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
de03f5bcaf
commit
93fa3a6054
@@ -41,19 +41,26 @@ function EnrollmentTokensPanel() {
|
|||||||
const [justMinted, setJustMinted] = useState<string | null>(null);
|
const [justMinted, setJustMinted] = useState<string | null>(null);
|
||||||
const [cmdCopied, setCmdCopied] = useState(false);
|
const [cmdCopied, setCmdCopied] = useState(false);
|
||||||
const [tokenCopied, setTokenCopied] = useState(false);
|
const [tokenCopied, setTokenCopied] = useState(false);
|
||||||
|
// The label the operator typed for the token that was just minted — used as
|
||||||
|
// the node id in the install command below. Captured on mint because `label`
|
||||||
|
// itself is cleared afterward.
|
||||||
|
const [mintedLabel, setMintedLabel] = useState<string | null>(null);
|
||||||
|
|
||||||
// The paste-ready one-shot install command for a fresh Pi. node id and the
|
// The paste-ready one-shot install command for a fresh Pi. The node id comes
|
||||||
// MQTT broker host aren't known here — left as placeholders the operator
|
// from the label just entered (spaces → dashes; install.sh requires
|
||||||
// edits. C2 URL comes from this deployment's own config; the broker is the
|
// [A-Za-z0-9_-]); if that yields nothing it falls back to a node-XXX
|
||||||
// documented mqtt.<domain> sibling of the api host (install.sh header).
|
// placeholder. The MQTT broker host is the documented mqtt.<domain> sibling
|
||||||
|
// of the api host (install.sh header) — a DNS assumption the operator checks.
|
||||||
const c2Url = (process.env.NEXT_PUBLIC_C2_URL ?? "https://api.example.net").replace(/\/$/, "");
|
const c2Url = (process.env.NEXT_PUBLIC_C2_URL ?? "https://api.example.net").replace(/\/$/, "");
|
||||||
const mqttBroker = (() => {
|
const mqttBroker = (() => {
|
||||||
try { return `mqtt.${new URL(c2Url).hostname.replace(/^api\./, "")}`; }
|
try { return `mqtt.${new URL(c2Url).hostname.replace(/^api\./, "")}`; }
|
||||||
catch { return "mqtt.example.net"; }
|
catch { return "mqtt.example.net"; }
|
||||||
})();
|
})();
|
||||||
|
const nodeIdForCmd =
|
||||||
|
(mintedLabel ?? "").trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-9_-]/g, "") || "node-XXX";
|
||||||
const installCmd = justMinted
|
const installCmd = justMinted
|
||||||
? `curl -fsSL https://git.vpn.cusano.net/logan/node-26/raw/tag/v1/install.sh \\
|
? `curl -fsSL https://git.vpn.cusano.net/logan/node-26/raw/tag/v1/install.sh \\
|
||||||
| sudo bash -s -- --token ${justMinted} --node-id node-XXX \\
|
| sudo bash -s -- --token ${justMinted} --node-id ${nodeIdForCmd} \\
|
||||||
--c2-url ${c2Url} --mqtt-broker ${mqttBroker}`
|
--c2-url ${c2Url} --mqtt-broker ${mqttBroker}`
|
||||||
: "";
|
: "";
|
||||||
|
|
||||||
@@ -74,6 +81,7 @@ function EnrollmentTokensPanel() {
|
|||||||
try {
|
try {
|
||||||
const result = await c2api.mintEnrollmentToken(label.trim());
|
const result = await c2api.mintEnrollmentToken(label.trim());
|
||||||
setJustMinted(result.token);
|
setJustMinted(result.token);
|
||||||
|
setMintedLabel(label.trim());
|
||||||
setLabel("");
|
setLabel("");
|
||||||
load();
|
load();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -119,7 +127,10 @@ function EnrollmentTokensPanel() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="text-xs text-indigo-200 font-mono mt-3 mb-1">
|
<p className="text-xs text-indigo-200 font-mono mt-3 mb-1">
|
||||||
…or run this on a fresh Pi (edit <span className="text-indigo-100">node-XXX</span> and the broker host):
|
…or run this on a fresh Pi{" "}
|
||||||
|
{nodeIdForCmd === "node-XXX"
|
||||||
|
? <>(edit <span className="text-indigo-100">node-XXX</span> and check the broker host)</>
|
||||||
|
: <>(check the broker host)</>}:
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-start gap-2">
|
<div className="flex items-start gap-2">
|
||||||
<pre className="flex-1 text-xs text-indigo-100 font-mono whitespace-pre-wrap break-all bg-gray-900 rounded px-2 py-1.5">{installCmd}</pre>
|
<pre className="flex-1 text-xs text-indigo-100 font-mono whitespace-pre-wrap break-all bg-gray-900 rounded px-2 py-1.5">{installCmd}</pre>
|
||||||
@@ -136,7 +147,7 @@ function EnrollmentTokensPanel() {
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setJustMinted(null)}
|
onClick={() => { setJustMinted(null); setMintedLabel(null); }}
|
||||||
className="text-xs text-indigo-300 hover:text-indigo-200 mt-3 transition-colors"
|
className="text-xs text-indigo-300 hover:text-indigo-200 mt-3 transition-colors"
|
||||||
>
|
>
|
||||||
Dismiss
|
Dismiss
|
||||||
@@ -151,7 +162,7 @@ function EnrollmentTokensPanel() {
|
|||||||
<input
|
<input
|
||||||
value={label}
|
value={label}
|
||||||
onChange={(e) => setLabel(e.target.value)}
|
onChange={(e) => setLabel(e.target.value)}
|
||||||
placeholder="Label, e.g. 'node-003 field kit'"
|
placeholder="Node ID, e.g. node-003"
|
||||||
className="flex-1 min-w-[12rem] bg-gray-800 border border-gray-700 rounded-lg px-3 py-1.5 text-white text-sm focus:outline-none focus:border-indigo-500"
|
className="flex-1 min-w-[12rem] bg-gray-800 border border-gray-700 rounded-lg px-3 py-1.5 text-white text-sm focus:outline-none focus:border-indigo-500"
|
||||||
/>
|
/>
|
||||||
<Button type="submit" size="sm" disabled={minting || !label.trim()}>
|
<Button type="submit" size="sm" disabled={minting || !label.trim()}>
|
||||||
|
|||||||
Reference in New Issue
Block a user