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