mirror of
https://github.com/hansjone/netxops.git
synced 2026-10-09 17:10:46 +08:00
Do not hard-inject remote.credentials on shipped dsh.
0.1.1-rc.2 remotes never mounts credentials; soft-inject unlocks the token field when available, otherwise point users at set-netx-token. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
69a4820369
commit
99ded2fe2d
6 changed files with 143 additions and 28 deletions
|
|
@ -251,7 +251,7 @@ function NetxopsCard(props) {
|
|||
}),
|
||||
/* @__PURE__ */ jsx_runtime.jsx("p", {
|
||||
className: "dsh-nx-hint",
|
||||
children: t("apiTokenHint")
|
||||
children: state.apiTokenRemoteReady ? t("apiTokenHint") : t("apiTokenUnavailable")
|
||||
})
|
||||
]
|
||||
}),
|
||||
|
|
@ -533,7 +533,12 @@ class NetxopsCardController {
|
|||
ctx;
|
||||
form;
|
||||
store;
|
||||
credential = { ref: "", configured: false, writable: true };
|
||||
credential = {
|
||||
ref: "",
|
||||
configured: false,
|
||||
writable: false,
|
||||
remoteReady: false
|
||||
};
|
||||
constructor(scope, ctx) {
|
||||
this.scope = scope;
|
||||
this.ctx = ctx;
|
||||
|
|
@ -544,6 +549,18 @@ class NetxopsCardController {
|
|||
});
|
||||
this.readCredential();
|
||||
}
|
||||
setCredentialsAvailable(ready) {
|
||||
if (this.credential.remoteReady === ready)
|
||||
return;
|
||||
this.credential = {
|
||||
...this.credential,
|
||||
remoteReady: ready,
|
||||
writable: ready
|
||||
};
|
||||
this.store.set(this.projection());
|
||||
if (ready)
|
||||
this.readCredential();
|
||||
}
|
||||
projection() {
|
||||
return {
|
||||
...this.form.shell(),
|
||||
|
|
@ -552,25 +569,43 @@ class NetxopsCardController {
|
|||
pythonCommand: this.form.field("pythonCommand"),
|
||||
apiToken: this.form.field(API_TOKEN_FIELD),
|
||||
apiTokenConfigured: this.credential.configured,
|
||||
apiTokenWritable: this.credential.writable
|
||||
apiTokenWritable: this.credential.remoteReady && this.credential.writable,
|
||||
apiTokenRemoteReady: this.credential.remoteReady
|
||||
};
|
||||
}
|
||||
credentials() {
|
||||
return this.ctx.get("remote.credentials");
|
||||
}
|
||||
async readCredential() {
|
||||
const ref = refOf(this.scope.getSnapshot());
|
||||
const api = this.credentials();
|
||||
if (api === undefined) {
|
||||
if (ref !== this.credential.ref || this.credential.remoteReady) {
|
||||
this.credential = {
|
||||
ref,
|
||||
configured: false,
|
||||
writable: false,
|
||||
remoteReady: false
|
||||
};
|
||||
this.store.set(this.projection());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ref !== this.credential.ref) {
|
||||
this.credential = { ref, configured: false, writable: true };
|
||||
this.credential = { ref, configured: false, writable: true, remoteReady: true };
|
||||
this.store.set(this.projection());
|
||||
}
|
||||
const response = await this.ctx.remote.credentials.describe([ref]);
|
||||
const response = await api.describe([ref]);
|
||||
if (!response.ok || ref !== refOf(this.scope.getSnapshot()))
|
||||
return;
|
||||
const view = response.value[ref];
|
||||
const view = response.value?.[ref];
|
||||
const next = {
|
||||
ref,
|
||||
configured: view?.configured ?? false,
|
||||
writable: view?.writable ?? true
|
||||
writable: view?.writable ?? true,
|
||||
remoteReady: true
|
||||
};
|
||||
if (next.configured === this.credential.configured && next.writable === this.credential.writable)
|
||||
if (next.configured === this.credential.configured && next.writable === this.credential.writable && next.remoteReady === this.credential.remoteReady)
|
||||
return;
|
||||
this.credential = next;
|
||||
this.store.set(this.projection());
|
||||
|
|
@ -584,7 +619,10 @@ class NetxopsCardController {
|
|||
return { hooks: { netxopsCard: this.store }, ...this.form.actions() };
|
||||
}
|
||||
async writeToken(value) {
|
||||
await this.ctx.remote.credentials.set(refOf(this.scope.getSnapshot()), value);
|
||||
const api = this.credentials();
|
||||
if (api === undefined)
|
||||
return false;
|
||||
await api.set(refOf(this.scope.getSnapshot()), value);
|
||||
await this.readCredential();
|
||||
return this.credential.configured;
|
||||
}
|
||||
|
|
@ -606,6 +644,7 @@ var en = {
|
|||
pythonCommandHint: "Executable that can run `python -m netx_mcp`.",
|
||||
apiToken: "API token",
|
||||
apiTokenHint: "Stored as credential NETX_API_TOKEN (never written into settings). Leave blank to keep the current token.",
|
||||
apiTokenUnavailable: "This DSH build does not expose remote.credentials. Set the token with scripts/set-netx-token.ps1 (or .sh), then restart is not required if credentials are watched.",
|
||||
apiTokenSet: "Configured",
|
||||
apiTokenUnset: "Not set",
|
||||
overridden: "Overridden",
|
||||
|
|
@ -631,6 +670,7 @@ var zh = {
|
|||
pythonCommandHint: "能执行 `python -m netx_mcp` 的解释器。",
|
||||
apiToken: "API Token",
|
||||
apiTokenHint: "写入凭据 NETX_API_TOKEN(不会进 settings)。留空表示保留已有 token。",
|
||||
apiTokenUnavailable: "当前 DSH 未提供 remote.credentials。请用 scripts/set-netx-token.ps1(或 .sh)写入 token;若 harness 在监视凭据文件则无需重启。",
|
||||
apiTokenSet: "已配置",
|
||||
apiTokenUnset: "未设置",
|
||||
overridden: "已覆盖",
|
||||
|
|
@ -652,15 +692,23 @@ var inject = [
|
|||
"slots",
|
||||
"locale",
|
||||
"remote",
|
||||
"remote.credentials",
|
||||
"settingsScope"
|
||||
];
|
||||
function apply(ctx) {
|
||||
ctx.effect(() => ctx.locale.register(LOCALE_NS, { zh, en }), "netxops: locales");
|
||||
const card = new NetxopsCardController(ctx.settingsScope.bind({ namespace: NETXOPS_NS }), ctx);
|
||||
ctx.effect(() => ctx.remote.$on("credentials/reference-updated", (ref) => {
|
||||
card.refreshCredential(ref);
|
||||
}), "netxops: credential invalidations");
|
||||
ctx.inject(["remote.credentials"], (credCtx) => {
|
||||
card.setCredentialsAvailable(true);
|
||||
credCtx.effect(() => {
|
||||
const off = credCtx.remote.$on("credentials/reference-updated", (ref) => {
|
||||
card.refreshCredential(String(ref));
|
||||
});
|
||||
return () => {
|
||||
off();
|
||||
card.setCredentialsAvailable(false);
|
||||
};
|
||||
}, "netxops: credential invalidations");
|
||||
});
|
||||
ctx.slots.inject("settings.plugin.item", () => ctx.slots.register({
|
||||
name: "settings.plugin.item",
|
||||
key: NETXOPS_NS,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue