SmtpCredentials-ufx_CaIB.js 14 KB

1
  1. import{a as e,n as t}from"./react-dom-stZKkA6x.js";import{f as n,o as ee,r}from"./theme-JEAJA3Ef.js";import{i,kt as a,n as o,st as s,t as c}from"./jsx-runtime-dm82oUI8.js";import{a as te,o as l}from"./grid-oQFtU3R0.js";import{t as ne}from"./table-DZMCIB4H.js";import{n as re,t as ie}from"./SectionCard-DDGEHf10.js";import{t as ae}from"./input-number-5vwSxUlw.js";import{t as u}from"./descriptions-vs1os_w7.js";import{t as d}from"./form-lkDIWt8f.js";import{t as f}from"./input-0_Xo22Fl.js";import{t as p}from"./popconfirm-eKz0FSVA.js";import{t as m}from"./switch-CsMGEdLR.js";import{t as h}from"./CopyOutlined-CqLRh6yQ.js";import{n as oe,t as se}from"./EditOutlined-BiwqHVQr.js";import{t as g}from"./PlusOutlined-YlpF_uyR.js";import{t as _}from"./ReloadOutlined-B6H5UA27.js";import{b as v,f as ce,h as le,n as ue,p as de}from"./index-avDTLp8M.js";import{t as y}from"./EmptyState-rI31ioMm.js";import{t as b}from"./StatusPill-BM21x0ED.js";import{n as fe,t as x}from"./navigation-state-ixI_efPF.js";var S=e(t(),1),C=c();function w(){let{message:e}=n.useApp(),{locale:t,t:c}=ee(),{config:h}=ue(),w=ce(),ve=de(),[E,D]=le(),[O]=d.useForm(),[k]=d.useForm(),[A,ye]=(0,S.useState)(null),[j,be]=(0,S.useState)([]),[M,xe]=(0,S.useState)([]),[N,P]=(0,S.useState)(!0),[F,I]=(0,S.useState)(``),[L,Se]=(0,S.useState)(``),[Ce,we]=(0,S.useState)(``),[R,z]=(0,S.useState)(``),[Te,B]=(0,S.useState)(!1),[V,H]=(0,S.useState)(null),[Ee,U]=(0,S.useState)(!1),[W,G]=(0,S.useState)(null),K=E.get(`tab`),q=K===`relays`||K===`connection`?K:`credentials`,J=_e(E.get(`credentialId`)),Y=_e(E.get(`relayId`)),X=(0,S.useMemo)(()=>{if(J){let e=j.find(e=>e.id===J);return e?{type:`credential`,value:e}:null}if(Y){let e=M.find(e=>e.id===Y);return e?{type:`relay`,value:e}:null}return null},[j,M,J,Y]),Z=(0,S.useCallback)(async()=>{P(!0),I(``),Se(``),we(``);let[e,t,n]=await Promise.allSettled([r.smtpCredential(),r.smtpCredentials(),r.smtpRelays()]);e.status===`fulfilled`?ye(e.value.credential||null):we(T(e.reason,c)),t.status===`fulfilled`?be(t.value.credentials||[]):I(T(t.reason,c)),n.status===`fulfilled`?xe(n.value.relays||[]):Se(T(n.reason,c)),P(!1)},[c]);(0,S.useEffect)(()=>{Z()},[Z]);function De(e){let t=new URLSearchParams(E);t.set(`tab`,e),t.delete(`credentialId`),t.delete(`relayId`),D(t,J||Y?{replace:!0,state:null}:void 0)}function Oe(e){if(!e.id)return;let t=new URLSearchParams(E);t.set(`tab`,`credentials`),t.set(`credentialId`,String(e.id)),t.delete(`relayId`),D(t,{state:x(`${w.pathname}${w.search}`,1)})}function ke(e){let t=new URLSearchParams(E);t.set(`tab`,`relays`),t.set(`relayId`,String(e.id)),t.delete(`credentialId`),D(t,{state:x(`${w.pathname}${w.search}`,1)})}function Q(){let e=fe(w.state);if(e){ve(-e.depth);return}let t=new URLSearchParams(E);t.delete(`credentialId`),t.delete(`relayId`),D(t,{replace:!0,state:null})}async function Ae(t){!t||t===`—`||(await navigator.clipboard.writeText(t),e.success(c(`common.copied`)))}function je(){H(null),O.resetFields(),O.setFieldsValue({username:j.length===0&&(A?.username||h?.submission?.username)||``,password:``}),B(!0)}function Me(e){H(e),O.resetFields(),O.setFieldsValue({username:e.username,password:``}),B(!0)}async function Ne(){let t=await O.validateFields(),n=V?.id?`credential:save:${V.id}`:`credential:create`;z(n);try{await r.saveSmtpLoginCredential(t,V?.id),e.success(c(V?`actions.smtpUpdated`:`actions.smtpCreated`)),B(!1),H(null),O.resetFields(),await Z()}catch(t){e.error(t instanceof Error?t.message:c(`common.error`))}finally{z(``)}}async function Pe(t){if(t.id){z(`credential:delete:${t.id}`);try{await r.deleteSmtpCredential(t.id),e.success(c(`actions.smtpDeleted`)),J===t.id&&Q(),await Z()}catch(t){e.error(t instanceof Error?t.message:c(`common.error`))}finally{z(``)}}}function $(){G(null),k.resetFields(),k.setFieldsValue({name:``,host:``,port:587,secure:!1,username:``,password:``,helo:``,isDefault:M.length===0}),U(!0)}function Fe(e){G(e),k.resetFields(),k.setFieldsValue({name:e.name,host:e.host,port:e.port,secure:e.secure,username:e.username,password:``,helo:e.helo,isDefault:e.isDefault}),U(!0)}async function Ie(){let t={...await k.validateFields()};W&&!t.password&&delete t.password;let n=W?`relay:save:${W.id}`:`relay:create`;z(n);try{await r.saveSmtpRelay(t,W?.id),e.success(c(W?`actions.smtpRelayUpdated`:`actions.smtpRelayCreated`)),U(!1),G(null),k.resetFields(),await Z()}catch(t){e.error(t instanceof Error?t.message:c(`common.error`))}finally{z(``)}}async function Le(t){z(`relay:delete:${t.id}`);try{await r.deleteSmtpRelay(t.id),e.success(c(`actions.smtpRelayDeleted`)),Y===t.id&&Q(),await Z()}catch(t){e.error(t instanceof Error?t.message:c(`common.error`))}finally{z(``)}}let Re=[{title:c(`smtp.username`),dataIndex:`username`,render:e=>(0,C.jsx)(o.Text,{code:!0,children:e})},{title:c(`smtp.password`),dataIndex:`passwordSet`,width:140,render:e=>(0,C.jsx)(b,{tone:e?`success`:`warning`,children:c(e?`smtp.passwordSet`:`smtp.passwordEmpty`)})},{title:c(`tokens.createdAt`),dataIndex:`createdAt`,width:190,render:e=>ge(e,t)},{title:c(`common.actions`),width:140,render:(e,t)=>(0,C.jsxs)(i,{onClick:e=>e.stopPropagation(),children:[(0,C.jsx)(a,{"aria-label":`${c(`common.edit`)} ${t.username}`,icon:(0,C.jsx)(se,{}),onClick:()=>Me(t),disabled:!t.id}),(0,C.jsx)(p,{title:c(`smtp.deleteConfirm`),onConfirm:()=>void Pe(t),disabled:!t.id,children:(0,C.jsx)(a,{"aria-label":`${c(`common.delete`)} ${t.username}`,danger:!0,icon:(0,C.jsx)(oe,{}),loading:R===`credential:delete:${t.id}`,disabled:!t.id})})]})}],ze=[{title:c(`smtpRelay.name`),dataIndex:`name`,render:(e,t)=>(0,C.jsxs)(i,{wrap:!0,children:[(0,C.jsx)(o.Text,{strong:!0,children:e}),t.isDefault?(0,C.jsx)(b,{tone:`success`,children:c(`smtpRelay.default`)}):null]})},{title:c(`smtpRelay.server`),render:(e,t)=>(0,C.jsxs)(o.Text,{code:!0,children:[t.host,`:`,t.port]})},{title:c(`smtpRelay.username`),dataIndex:`username`,render:e=>e||`—`},{title:c(`smtpRelay.password`),dataIndex:`passwordSet`,width:140,render:e=>(0,C.jsx)(b,{tone:e?`success`:`warning`,children:c(e?`smtpRelay.passwordSet`:`smtpRelay.passwordEmpty`)})},{title:c(`common.actions`),width:140,render:(e,t)=>(0,C.jsxs)(i,{onClick:e=>e.stopPropagation(),children:[(0,C.jsx)(a,{"aria-label":`${c(`common.edit`)} ${t.name}`,icon:(0,C.jsx)(se,{}),onClick:()=>Fe(t)}),(0,C.jsx)(p,{title:c(`smtpRelay.deleteConfirm`),onConfirm:()=>void Le(t),children:(0,C.jsx)(a,{"aria-label":`${c(`common.delete`)} ${t.name}`,danger:!0,icon:(0,C.jsx)(oe,{}),loading:R===`relay:delete:${t.id}`})})]})}],Be=q===`credentials`?(0,C.jsx)(a,{type:`primary`,icon:(0,C.jsx)(g,{}),onClick:je,style:{minHeight:44},children:c(`smtp.create`)}):q===`relays`?(0,C.jsx)(a,{type:`primary`,icon:(0,C.jsx)(g,{}),onClick:$,style:{minHeight:44},children:c(`smtpRelay.create`)}):null;return(0,C.jsxs)(i,{direction:`vertical`,size:20,className:`full-width`,children:[(0,C.jsx)(re,{title:c(`nav.smtp`),subtitle:c(`smtp.connectionTitle`),extra:Be}),(0,C.jsx)(ie,{children:(0,C.jsx)(te,{activeKey:q,onChange:De,items:[{key:`credentials`,label:c(`smtp.loginCredentialsTitle`),children:N&&!j.length?(0,C.jsx)(s,{active:!0,paragraph:{rows:5}}):F?(0,C.jsx)(l,{type:`error`,showIcon:!0,message:F,action:(0,C.jsx)(a,{icon:(0,C.jsx)(_,{}),onClick:()=>void Z(),children:c(`common.refresh`)})}):j.length?(0,C.jsx)(ne,{rowKey:e=>e.id||e.username,columns:Re,dataSource:j,scroll:{x:760},onRow:e=>({onClick:()=>Oe(e),style:{cursor:e.id?`pointer`:`default`},tabIndex:e.id?0:-1,onKeyDown:t=>{t.target===t.currentTarget&&(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),Oe(e))}})}):(0,C.jsx)(y,{description:c(`smtp.passwordUnavailable`),action:(0,C.jsx)(a,{icon:(0,C.jsx)(g,{}),onClick:je,children:c(`smtp.create`)})})},{key:`relays`,label:c(`smtpRelay.title`),children:N&&!M.length?(0,C.jsx)(s,{active:!0,paragraph:{rows:5}}):L?(0,C.jsx)(l,{type:`error`,showIcon:!0,message:L,action:(0,C.jsx)(a,{icon:(0,C.jsx)(_,{}),onClick:()=>void Z(),children:c(`common.refresh`)})}):M.length?(0,C.jsx)(ne,{rowKey:`id`,columns:ze,dataSource:M,scroll:{x:860},onRow:e=>({onClick:()=>ke(e),style:{cursor:`pointer`},tabIndex:0,onKeyDown:t=>{t.target===t.currentTarget&&(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),ke(e))}})}):(0,C.jsx)(y,{description:c(`common.notConfigured`),action:(0,C.jsx)(a,{icon:(0,C.jsx)(g,{}),onClick:$,children:c(`smtpRelay.create`)})})},{key:`connection`,label:c(`smtp.connectionTitle`),children:N&&!A?(0,C.jsx)(s,{active:!0}):Ce?(0,C.jsx)(l,{type:`error`,showIcon:!0,message:Ce,action:(0,C.jsx)(a,{icon:(0,C.jsx)(_,{}),onClick:()=>void Z(),children:c(`common.refresh`)})}):(0,C.jsxs)(u,{bordered:!0,column:1,size:`small`,children:[(0,C.jsx)(u.Item,{label:`SMTP Host`,children:he(h?.submission?.host||`—`,Ae,c(`common.copy`))}),(0,C.jsx)(u.Item,{label:`SMTP Port`,children:(0,C.jsx)(i,{wrap:!0,children:(h?.submission?.ports||[]).map(e=>(0,C.jsxs)(b,{tone:`info`,children:[e.port,` · `,e.protocol]},e.port))})}),(0,C.jsx)(u.Item,{label:`TLS / SSL`,children:h?.submission?.tls?`TLS`:`STARTTLS`}),(0,C.jsx)(u.Item,{label:c(`smtp.username`),children:he(A?.username||h?.submission?.username||`—`,Ae,c(`common.copy`))}),(0,C.jsx)(u.Item,{label:c(`smtp.password`),children:(0,C.jsx)(o.Text,{type:`secondary`,children:c(`smtp.resetToCopy`)})})]})}]})}),(0,C.jsxs)(v,{title:c(V?`smtp.editTitle`:`smtp.createTitle`),width:560,open:Te,onClose:()=>B(!1),destroyOnHidden:!0,footer:(0,C.jsx)(pe,{t:c,loading:R===`credential:create`||R.startsWith(`credential:save:`),onCancel:()=>B(!1),onSave:()=>void Ne()}),children:[(0,C.jsx)(l,{type:`info`,showIcon:!0,message:t.startsWith(`en`)?`Saved SMTP passwords are never returned. Leave the password blank when editing to keep it unchanged.`:`已保存的 SMTP 密码不会返回。编辑时留空即可保留原密码。`,style:{marginBottom:20}}),(0,C.jsxs)(d,{form:O,layout:`vertical`,children:[(0,C.jsx)(d.Item,{name:`username`,label:c(`smtp.username`),rules:[{required:!0,message:c(`smtp.usernameRequired`)}],children:(0,C.jsx)(f,{autoComplete:`off`})}),(0,C.jsx)(d.Item,{name:`password`,label:c(`smtp.password`),rules:[{required:!V,message:c(`smtp.passwordRequired`)}],children:(0,C.jsx)(f.Password,{autoComplete:`new-password`})}),(0,C.jsx)(a,{icon:(0,C.jsx)(_,{}),onClick:()=>O.setFieldValue(`password`,me()),children:c(`smtp.regenerate`)})]})]}),(0,C.jsxs)(v,{title:c(W?`smtpRelay.editTitle`:`smtpRelay.createTitle`),width:600,open:Ee,onClose:()=>U(!1),destroyOnHidden:!0,footer:(0,C.jsx)(pe,{t:c,loading:R===`relay:create`||R.startsWith(`relay:save:`),onCancel:()=>U(!1),onSave:()=>void Ie()}),children:[(0,C.jsx)(l,{type:`info`,showIcon:!0,message:t.startsWith(`en`)?`Saved relay passwords are write-only. Leave the password blank when editing to keep it unchanged.`:`已保存的中继密码为只写字段。编辑时留空即可保留原密码。`,style:{marginBottom:20}}),(0,C.jsxs)(d,{form:k,layout:`vertical`,children:[(0,C.jsx)(d.Item,{name:`name`,label:c(`smtpRelay.name`),rules:[{required:!0,message:c(`smtpRelay.nameRequired`)}],children:(0,C.jsx)(f,{autoComplete:`off`,placeholder:`Amazon SES`})}),(0,C.jsx)(d.Item,{name:`host`,label:`SMTP Host`,rules:[{required:!0,message:c(`smtpRelay.hostRequired`)}],children:(0,C.jsx)(f,{autoComplete:`off`,placeholder:`email-smtp.us-east-1.amazonaws.com`})}),(0,C.jsx)(d.Item,{name:`port`,label:`SMTP Port`,rules:[{required:!0,message:c(`smtpRelay.portRequired`)}],children:(0,C.jsx)(ae,{min:1,max:65535,className:`full-width`})}),(0,C.jsx)(d.Item,{name:`secure`,label:`SSL/TLS`,valuePropName:`checked`,children:(0,C.jsx)(m,{})}),(0,C.jsx)(d.Item,{name:`username`,label:c(`smtpRelay.username`),children:(0,C.jsx)(f,{autoComplete:`off`})}),(0,C.jsx)(d.Item,{name:`password`,label:c(`smtpRelay.password`),children:(0,C.jsx)(f.Password,{autoComplete:`new-password`})}),(0,C.jsx)(a,{icon:(0,C.jsx)(_,{}),onClick:()=>k.setFieldValue(`password`,me()),children:c(`smtpRelay.generatePassword`)}),(0,C.jsx)(d.Item,{name:`helo`,label:`HELO`,extra:c(`smtpRelay.heloExtra`),style:{marginTop:20},children:(0,C.jsx)(f,{autoComplete:`off`,placeholder:h?.mailHostname||`mail.example.com`})}),(0,C.jsx)(d.Item,{name:`isDefault`,label:c(`smtpRelay.default`),valuePropName:`checked`,children:(0,C.jsx)(m,{})})]})]}),(0,C.jsx)(v,{title:X?.type===`credential`?X.value.username:X?.type===`relay`?X.value.name:c(`nav.smtp`),width:480,open:!!(J||Y),onClose:Q,children:N&&!X?(0,C.jsx)(s,{active:!0,paragraph:{rows:5}}):X?.type===`credential`?(0,C.jsxs)(u,{bordered:!0,column:1,size:`small`,children:[(0,C.jsx)(u.Item,{label:c(`smtp.username`),children:(0,C.jsx)(o.Text,{code:!0,children:X.value.username})}),(0,C.jsx)(u.Item,{label:c(`smtp.password`),children:(0,C.jsx)(b,{tone:X.value.passwordSet?`success`:`warning`,children:X.value.passwordSet?c(`smtp.passwordSet`):c(`smtp.passwordEmpty`)})}),(0,C.jsx)(u.Item,{label:c(`tokens.createdAt`),children:ge(X.value.createdAt,t)})]}):X?.type===`relay`?(0,C.jsxs)(u,{bordered:!0,column:1,size:`small`,children:[(0,C.jsx)(u.Item,{label:c(`smtpRelay.server`),children:(0,C.jsxs)(o.Text,{code:!0,children:[X.value.host,`:`,X.value.port]})}),(0,C.jsx)(u.Item,{label:`TLS`,children:X.value.secure?`SSL/TLS`:`STARTTLS / Plain`}),(0,C.jsx)(u.Item,{label:c(`smtpRelay.username`),children:X.value.username||`—`}),(0,C.jsx)(u.Item,{label:c(`smtpRelay.password`),children:(0,C.jsx)(b,{tone:X.value.passwordSet?`success`:`warning`,children:X.value.passwordSet?c(`smtpRelay.passwordSet`):c(`smtpRelay.passwordEmpty`)})}),(0,C.jsx)(u.Item,{label:`HELO`,children:X.value.helo||`—`})]}):J&&F?(0,C.jsx)(l,{type:`error`,showIcon:!0,message:F,action:(0,C.jsx)(a,{icon:(0,C.jsx)(_,{}),onClick:()=>void Z(),children:c(`common.refresh`)})}):Y&&L?(0,C.jsx)(l,{type:`error`,showIcon:!0,message:L,action:(0,C.jsx)(a,{icon:(0,C.jsx)(_,{}),onClick:()=>void Z(),children:c(`common.refresh`)})}):J||Y?(0,C.jsx)(y,{description:c(`common.notFound`)}):null})]})}function pe({t:e,loading:t,onCancel:n,onSave:ee}){return(0,C.jsxs)(i,{style:{display:`flex`,justifyContent:`flex-end`},children:[(0,C.jsx)(a,{onClick:n,children:e(`common.cancel`)}),(0,C.jsx)(a,{type:`primary`,loading:t,onClick:ee,children:e(`common.save`)})]})}function me(){let e=new Uint8Array(24);return crypto.getRandomValues(e),btoa(String.fromCharCode(...e)).replace(/[+/=]/g,``).slice(0,28)}function he(e,t,n){return(0,C.jsxs)(i,{children:[(0,C.jsx)(o.Text,{code:!0,className:`inline-code-value`,children:e}),(0,C.jsx)(a,{"aria-label":`${n} ${e}`,icon:(0,C.jsx)(h,{}),onClick:()=>void t(e)})]})}function ge(e,t){if(!e)return`—`;let n=new Date(e);return Number.isNaN(n.getTime())?`—`:new Intl.DateTimeFormat(t,{year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}).format(n)}function _e(e){let t=Number(e);return Number.isInteger(t)&&t>0?t:null}function T(e,t){return e instanceof Error?e.message:t(`common.error`)}export{w as default};