@linxin666/dsh-ssh 0.3.4 → 0.3.6

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/lib/client.js CHANGED
@@ -272,6 +272,7 @@ window.__ModuleLoader__.load({
272
272
  onReady: void 0,
273
273
  onOutput: void 0,
274
274
  onExit: void 0,
275
+ onAuthPrompt: void 0,
275
276
  send: (data) => {
276
277
  if (socket.readyState === WebSocket.OPEN) socket.send(JSON.stringify({
277
278
  type: "input",
@@ -285,6 +286,12 @@ window.__ModuleLoader__.load({
285
286
  rows
286
287
  }));
287
288
  },
289
+ sendAuthResponse: (responses) => {
290
+ if (socket.readyState === WebSocket.OPEN) socket.send(JSON.stringify({
291
+ type: "auth_response",
292
+ responses
293
+ }));
294
+ },
288
295
  close: () => {
289
296
  try {
290
297
  socket.close();
@@ -301,6 +308,7 @@ window.__ModuleLoader__.load({
301
308
  if (frame.type === "ready") connection.onReady?.();
302
309
  else if (frame.type === "output") connection.onOutput?.(frame.data);
303
310
  else if (frame.type === "exit") connection.onExit?.(frame.code, frame.error);
311
+ else if (frame.type === "auth_prompt") connection.onAuthPrompt?.(frame.name, frame.instructions, frame.prompts);
304
312
  };
305
313
  socket.onclose = () => {
306
314
  connection.onExit?.(null, "connection closed");
@@ -396,6 +404,11 @@ window.__ModuleLoader__.load({
396
404
  "terminal.ready": "终端已连接({alias})",
397
405
  "terminal.exited": "终端已退出({alias})",
398
406
  "terminal.error": "终端错误:{error}",
407
+ "terminal.auth.title": "二次身份验证 (2FA / 交互式认证)",
408
+ "terminal.auth.submit": "提交验证码",
409
+ "terminal.auth.cancel": "取消",
410
+ "terminal.auth.placeholder": "请输入验证码或口令",
411
+ "terminal.auth.hint": "服务器请求进行交互式二次验证(输入仅本次生效,不落盘):",
399
412
  "transfer.selectHost": "选择主机",
400
413
  "transfer.remotePath": "远程路径",
401
414
  "transfer.remotePathHint": "如 /tmp/ 或 /home/user/app.tar.gz",
@@ -537,6 +550,11 @@ window.__ModuleLoader__.load({
537
550
  "terminal.ready": "Terminal connected ({alias})",
538
551
  "terminal.exited": "Terminal exited ({alias})",
539
552
  "terminal.error": "Terminal error: {error}",
553
+ "terminal.auth.title": "Two-Factor Authentication (2FA)",
554
+ "terminal.auth.submit": "Submit Code",
555
+ "terminal.auth.cancel": "Cancel",
556
+ "terminal.auth.placeholder": "Enter code or passphrase",
557
+ "terminal.auth.hint": "The server requested interactive 2FA (session only, never saved):",
540
558
  "transfer.selectHost": "Select host",
541
559
  "transfer.remotePath": "Remote path",
542
560
  "transfer.remotePathHint": "e.g. /tmp/ or /home/user/app.tar.gz",
@@ -14786,6 +14804,8 @@ window.__ModuleLoader__.load({
14786
14804
  const [hosts, setHosts] = (0, react.useState)([]);
14787
14805
  const [alias, setAlias] = (0, react.useState)(presetAlias ?? "");
14788
14806
  const [status, setStatus] = (0, react.useState)({ kind: "idle" });
14807
+ const [authPrompt, setAuthPrompt] = (0, react.useState)(void 0);
14808
+ const [authInputs, setAuthInputs] = (0, react.useState)([]);
14789
14809
  const containerRef = (0, react.useRef)(null);
14790
14810
  const termRef = (0, react.useRef)(null);
14791
14811
  const fitRef = (0, react.useRef)(null);
@@ -14826,12 +14846,15 @@ window.__ModuleLoader__.load({
14826
14846
  if (presetAlias !== void 0) setAlias(presetAlias);
14827
14847
  }, [presetAlias, requestId]);
14828
14848
  const teardown = () => {
14849
+ setAuthPrompt(void 0);
14850
+ setAuthInputs([]);
14829
14851
  const connection = connRef.current;
14830
14852
  connRef.current = null;
14831
14853
  if (connection !== null) {
14832
14854
  connection.onReady = void 0;
14833
14855
  connection.onOutput = void 0;
14834
14856
  connection.onExit = void 0;
14857
+ connection.onAuthPrompt = void 0;
14835
14858
  connection.close();
14836
14859
  }
14837
14860
  dataSubRef.current?.dispose();
@@ -14902,7 +14925,17 @@ window.__ModuleLoader__.load({
14902
14925
  dataSubRef.current = term.onData((data) => {
14903
14926
  connection.send(data);
14904
14927
  });
14928
+ connection.onAuthPrompt = (name, instructions, prompts) => {
14929
+ setAuthPrompt({
14930
+ name,
14931
+ instructions,
14932
+ prompts
14933
+ });
14934
+ setAuthInputs(prompts.map(() => ""));
14935
+ };
14905
14936
  connection.onReady = () => {
14937
+ setAuthPrompt(void 0);
14938
+ setAuthInputs([]);
14906
14939
  setStatus({
14907
14940
  kind: "connected",
14908
14941
  alias: target
@@ -14914,6 +14947,8 @@ window.__ModuleLoader__.load({
14914
14947
  connection.onExit = (_code, error) => {
14915
14948
  if (settled) return;
14916
14949
  settled = true;
14950
+ setAuthPrompt(void 0);
14951
+ setAuthInputs([]);
14917
14952
  dataSubRef.current?.dispose();
14918
14953
  dataSubRef.current = null;
14919
14954
  term.options.disableStdin = true;
@@ -14929,6 +14964,12 @@ window.__ModuleLoader__.load({
14929
14964
  teardown();
14930
14965
  setStatus({ kind: "idle" });
14931
14966
  };
14967
+ const submitAuth = (e) => {
14968
+ e?.preventDefault();
14969
+ if (connRef.current === null || authPrompt === void 0) return;
14970
+ connRef.current.sendAuthResponse(authInputs);
14971
+ setAuthPrompt(void 0);
14972
+ };
14932
14973
  const active = status.kind === "connecting" || status.kind === "connected";
14933
14974
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
14934
14975
  className: panel_module_css_default.termBody,
@@ -14993,14 +15034,73 @@ window.__ModuleLoader__.load({
14993
15034
  }),
14994
15035
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
14995
15036
  className: panel_module_css_default.termWrap,
14996
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
14997
- ref: containerRef,
14998
- className: panel_module_css_default.termContainer,
14999
- "data-dsh-part": "terminal"
15000
- }), status.kind === "idle" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
15001
- className: panel_module_css_default.termPlaceholder,
15002
- children: hosts.length === 0 ? tt("hosts.empty") : tt("terminal.placeholder")
15003
- })]
15037
+ children: [
15038
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
15039
+ ref: containerRef,
15040
+ className: panel_module_css_default.termContainer,
15041
+ "data-dsh-part": "terminal"
15042
+ }),
15043
+ status.kind === "idle" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
15044
+ className: panel_module_css_default.termPlaceholder,
15045
+ children: hosts.length === 0 ? tt("hosts.empty") : tt("terminal.placeholder")
15046
+ }),
15047
+ authPrompt !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
15048
+ className: panel_module_css_default.modalBackdrop,
15049
+ style: {
15050
+ position: "absolute",
15051
+ zIndex: 10
15052
+ },
15053
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
15054
+ className: panel_module_css_default.modalCard,
15055
+ style: { maxWidth: 420 },
15056
+ onSubmit: submitAuth,
15057
+ children: [
15058
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
15059
+ className: panel_module_css_default.modalHeader,
15060
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
15061
+ className: panel_module_css_default.modalTitle,
15062
+ children: authPrompt.name || tt("terminal.auth.title")
15063
+ })
15064
+ }),
15065
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
15066
+ className: panel_module_css_default.hint,
15067
+ children: authPrompt.instructions || tt("terminal.auth.hint")
15068
+ }),
15069
+ authPrompt.prompts.map((p, idx) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
15070
+ className: panel_module_css_default.field,
15071
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
15072
+ className: panel_module_css_default.fieldLabel,
15073
+ children: p.prompt.trim() || tt("terminal.auth.title")
15074
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
15075
+ autoFocus: idx === 0,
15076
+ className: panel_module_css_default.input,
15077
+ type: p.echo ? "text" : "password",
15078
+ placeholder: tt("terminal.auth.placeholder"),
15079
+ value: authInputs[idx] ?? "",
15080
+ onChange: (event) => {
15081
+ const next = [...authInputs];
15082
+ next[idx] = event.target.value;
15083
+ setAuthInputs(next);
15084
+ }
15085
+ })]
15086
+ }, idx)),
15087
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
15088
+ className: panel_module_css_default.modalFooter,
15089
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15090
+ type: "button",
15091
+ className: panel_module_css_default.ghostButton,
15092
+ onClick: disconnect,
15093
+ children: tt("terminal.auth.cancel")
15094
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15095
+ type: "submit",
15096
+ className: panel_module_css_default.primaryButton,
15097
+ children: tt("terminal.auth.submit")
15098
+ })]
15099
+ })
15100
+ ]
15101
+ })
15102
+ })
15103
+ ]
15004
15104
  })
15005
15105
  ]
15006
15106
  });
@@ -15982,7 +16082,7 @@ window.__ModuleLoader__.load({
15982
16082
  /** The building package's version, when the bundle carries it. */
15983
16083
  function bakedVersion() {
15984
16084
  try {
15985
- return "0.3.4";
16085
+ return "0.3.6";
15986
16086
  } catch {
15987
16087
  return;
15988
16088
  }