SmtpCredentials-Irlwliwa.js 12 KB

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