Files
yakpanel-core/YakPanel-server/frontend/dist/assets/RemoteInstallPage-C4gVyakl.js
2026-04-07 09:46:22 +05:30

3 lines
7.4 KiB
JavaScript

import{r as a,j as e,aw as A}from"./index-CRR9sQ49.js";import{A as b}from"./AdminAlert-DW1IRWce.js";import{A as M}from"./AdminButton-Bd2cLTu3.js";function Y(){const[t,T]=a.useState(null),[d,I]=a.useState(""),[j,L]=a.useState(""),[m,F]=a.useState("22"),[f,O]=a.useState("root"),[n,y]=a.useState("key"),[N,q]=a.useState(""),[g,U]=a.useState(""),[v,S]=a.useState(""),[w,k]=a.useState(""),[h,E]=a.useState([]),[P,u]=a.useState(!1),[H,C]=a.useState(null),[R,_]=a.useState(""),o=a.useRef(null);a.useEffect(()=>{fetch("/api/v1/public-install/config").then(s=>s.ok?s.json():Promise.reject(new Error(`HTTP ${s.status}`))).then(s=>{T(s),k(s.default_install_url||"")}).catch(()=>I("Could not load installer configuration"))},[]),a.useEffect(()=>{o.current&&(o.current.scrollTop=o.current.scrollHeight)},[h]);const p=a.useCallback(s=>{E(c=>[...c.slice(-2e3),s])},[]);async function $(s){if(s.preventDefault(),_(""),E([]),C(null),!(t!=null&&t.enabled))return;const c=w.trim()||t.default_install_url,K=n==="key"?{type:"key",private_key:N,passphrase:g||null}:{type:"password",password:v},B={host:j.trim(),port:parseInt(m,10)||22,username:f.trim(),auth:K,install_url:c===t.default_install_url?null:c};u(!0);try{const l=await fetch("/api/v1/public-install/jobs",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(B)});if(!l.ok){const i=await l.json().catch(()=>({}));throw new Error(i.detail||`HTTP ${l.status}`)}const{job_id:W}=await l.json(),J=window.location.protocol==="https:"?"wss:":"ws:",x=new WebSocket(`${J}//${window.location.host}/api/v1/public-install/ws/${W}`);x.onmessage=i=>{try{const r=JSON.parse(i.data);r.type==="line"&&typeof r.text=="string"&&p(r.text),r.type==="done"&&C(typeof r.exit_code=="number"?r.exit_code:-1)}catch{p(String(i.data))}},x.onerror=()=>p("[websocket error]"),x.onclose=()=>u(!1)}catch(l){_(l instanceof Error?l.message:"Request failed"),u(!1)}finally{n==="password"&&S("")}}return!t&&!d?e.jsx("div",{className:"min-vh-100 d-flex align-items-center justify-content-center bg-body-secondary",children:e.jsx("p",{className:"text-secondary mb-0",children:"Loading…"})}):d?e.jsx("div",{className:"min-vh-100 d-flex align-items-center justify-content-center bg-body-secondary p-3",children:e.jsx(b,{children:d})}):t&&!t.enabled?e.jsx("div",{className:"min-vh-100 d-flex align-items-center justify-content-center bg-body-secondary p-3",children:e.jsx("div",{className:"card shadow-sm w-100",style:{maxWidth:520},children:e.jsxs("div",{className:"card-body p-4",children:[e.jsx("h1",{className:"h4 mb-3",children:"Remote SSH installer disabled"}),e.jsxs("p",{className:"small text-secondary mb-3",children:["Enable it on the API server with environment variable"," ",e.jsx("code",{children:"ENABLE_REMOTE_INSTALLER=true"})," and restart the backend. Prefer SSH keys; exposing this endpoint increases risk."]}),e.jsx("p",{className:"small text-secondary mb-3",children:"One-liner on the target server (as root):"}),e.jsxs("pre",{className:"bg-dark text-success small p-3 rounded mb-3 mb-0 overflow-auto",children:["curl -fsSL ",t.default_install_url," | bash"]}),e.jsx(A,{to:"/login",className:"btn btn-link btn-sm px-0 mt-3",children:"Panel login"})]})})}):e.jsx("div",{className:"min-vh-100 bg-body-secondary py-4 px-3",children:e.jsxs("div",{className:"container",style:{maxWidth:900},children:[e.jsxs(b,{variant:"warning",className:"mb-3",children:[e.jsx("strong",{children:"Security warning:"})," SSH credentials are sent to this panel API and used only for this session (not stored). Prefer ",e.jsx("strong",{children:"SSH private keys"}),". Root password SSH is often disabled on Ubuntu. Non-root users need ",e.jsx("strong",{children:"passwordless sudo"})," (",e.jsx("code",{children:"sudo -n"}),") to run the installer. Allow SSH from this server to the target on port ",m,"."]}),e.jsx("div",{className:"card shadow-sm",children:e.jsxs("div",{className:"card-body p-4",children:[e.jsx("h1",{className:"h4 mb-2",children:"Remote install (SSH)"}),e.jsxs("p",{className:"small text-secondary mb-4 mb-0",children:["Runs the published ",e.jsx("code",{children:"install.sh"})," on the target via SSH (same as shell one-liner)."]}),e.jsx("hr",{}),e.jsxs("form",{onSubmit:$,className:"mt-3",children:[R?e.jsx(b,{className:"mb-3",children:R}):null,e.jsxs("div",{className:"row g-3 mb-3",children:[e.jsxs("div",{className:"col-md-8",children:[e.jsx("label",{className:"form-label",children:"Host"}),e.jsx("input",{type:"text",value:j,onChange:s=>L(s.target.value),className:"form-control",placeholder:"203.0.113.50",required:!0})]}),e.jsxs("div",{className:"col-md-4",children:[e.jsx("label",{className:"form-label",children:"SSH port"}),e.jsx("input",{type:"number",value:m,onChange:s=>F(s.target.value),className:"form-control",min:1,max:65535})]})]}),e.jsxs("div",{className:"mb-3",children:[e.jsx("label",{className:"form-label",children:"SSH username"}),e.jsx("input",{type:"text",value:f,onChange:s=>O(s.target.value),className:"form-control",required:!0})]}),e.jsxs("div",{className:"mb-3",children:[e.jsx("span",{className:"form-label d-block",children:"Authentication"}),e.jsxs("div",{className:"d-flex gap-4",children:[e.jsxs("div",{className:"form-check",children:[e.jsx("input",{className:"form-check-input",type:"radio",name:"auth",id:"auth-key",checked:n==="key",onChange:()=>y("key")}),e.jsx("label",{className:"form-check-label",htmlFor:"auth-key",children:"Private key"})]}),e.jsxs("div",{className:"form-check",children:[e.jsx("input",{className:"form-check-input",type:"radio",name:"auth",id:"auth-pw",checked:n==="password",onChange:()=>y("password")}),e.jsx("label",{className:"form-check-label",htmlFor:"auth-pw",children:"Password"})]})]})]}),n==="key"?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"mb-3",children:[e.jsx("label",{className:"form-label",children:"Private key (PEM)"}),e.jsx("textarea",{value:N,onChange:s=>q(s.target.value),rows:6,className:"form-control font-monospace small",placeholder:"-----BEGIN OPENSSH PRIVATE KEY-----",required:!0})]}),e.jsxs("div",{className:"mb-3",children:[e.jsx("label",{className:"form-label",children:"Key passphrase (optional)"}),e.jsx("input",{type:"password",value:g,onChange:s=>U(s.target.value),className:"form-control"})]})]}):e.jsxs("div",{className:"mb-3",children:[e.jsx("label",{className:"form-label",children:"SSH password"}),e.jsx("input",{type:"password",value:v,onChange:s=>S(s.target.value),className:"form-control",required:!0})]}),e.jsxs("div",{className:"mb-3",children:[e.jsx("label",{className:"form-label",children:"Install script URL (https only)"}),e.jsx("input",{type:"url",value:w,onChange:s=>k(s.target.value),className:"form-control small"})]}),e.jsx(M,{type:"submit",variant:"primary",className:"w-100",disabled:P||!(t!=null&&t.enabled)||!t,children:P?e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"spinner-border spinner-border-sm me-2",role:"status"}),"Running…"]}):"Start remote install"})]})]})}),h.length>0?e.jsx("div",{className:"card bg-dark text-light mt-3",children:e.jsxs("div",{className:"card-body p-3",children:[e.jsx("pre",{ref:o,className:"small font-monospace mb-0 overflow-auto text-wrap",style:{maxHeight:"24rem"},children:h.join(`
`)}),H!==null?e.jsxs("p",{className:"small border-secondary border-top pt-2 mt-2 mb-0",children:["Exit code: ",e.jsx("strong",{children:H})]}):null]})}):null,e.jsx("p",{className:"text-center small text-secondary mt-3 mb-0",children:e.jsx(A,{to:"/login",children:"Panel login"})})]})})}export{Y as RemoteInstallPage};