Skip to content

Commit

Permalink
feat: SMTP Compatibility Enhancement and SSL Protocol Support (#174)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sh1n3zZ committed Jun 22, 2024
1 parent 9d4ff72 commit 6f3cdad
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 9 deletions.
2 changes: 2 additions & 0 deletions app/src/admin/api/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type GeneralState = {

export type MailState = {
host: string;
protocol: boolean;
port: number;
username: string;
password: string;
Expand Down Expand Up @@ -137,6 +138,7 @@ export const initialSystemState: SystemProps = {
auth_footer: false,
},
mail: {
protocol: false,
host: "",
port: 465,
username: "",
Expand Down
1 change: 1 addition & 0 deletions app/src/resources/i18n/cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@
"debugMode": "调试模式",
"debugModeTip": "调试模式,开启后日志将输出详细的请求参数等的日志,用于排查问题",
"mailHost": "发件域名",
"mailProtocol": "发件协议",
"mailPort": "SMTP 端口",
"mailUser": "用户名",
"mailPass": "密码",
Expand Down
1 change: 1 addition & 0 deletions app/src/resources/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@
"backend": "Backend Domain",
"backendTip": "Backend domain name (docker installation default path is/api), used to receive callbacks and storage, etc., default is empty\nExample: {{backend}}",
"mailHost": "Mail Host",
"mailProtocol": "Mail Protocol",
"mailPort": "SMTP Port",
"mailUser": "Username",
"mailPass": "Password",
Expand Down
1 change: 1 addition & 0 deletions app/src/resources/i18n/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@
"backend": "バックエンドドメイン",
"backendTip": "バックエンドドメイン名( dockerインストールのデフォルトパスは/api )、コールバックやストレージなどを受信するために使用、デフォルトは空です\n例:{{ backend}}",
"mailHost": "送信ドメイン名",
"mailProtocol": "送信プロトコル",
"mailPort": "SMTPポート",
"mailUser": "ユーザー名",
"mailPass": "パスワード",
Expand Down
1 change: 1 addition & 0 deletions app/src/resources/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@
"backend": "Домен бэкэнда",
"backendTip": "Имя домена бэкенда (путь установки докера по умолчанию -/api), используется для получения обратных вызовов и хранения и т. д., значение по умолчанию пусто\nПример: {{backend}}",
"mailHost": "Почтовый хост",
"mailProtocol": "Протокол отправки",
"mailPort": "Порт SMTP",
"mailUser": "Имя пользователя",
"mailPass": "Пароль",
Expand Down
39 changes: 35 additions & 4 deletions app/src/routes/admin/System.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ import Paragraph, {
ParagraphSpace,
} from "@/components/Paragraph.tsx";
import { Button } from "@/components/ui/button.tsx";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select.tsx";
import { Label } from "@/components/ui/label.tsx";
import { Input } from "@/components/ui/input.tsx";
import { useMemo, useReducer, useState } from "react";
Expand Down Expand Up @@ -283,8 +290,8 @@ function Mail({ data, dispatch, onChange }: CompProps<MailState>) {
data.username.length > 0 &&
data.password.length > 0 &&
data.from.length > 0 &&
/\w+@\w+\.\w+/.test(data.from) &&
!data.username.includes("@")
data.username.includes("@") &&
!/\w+@/.test(data.from)
);
}, [data]);

Expand Down Expand Up @@ -332,6 +339,30 @@ function Mail({ data, dispatch, onChange }: CompProps<MailState>) {
placeholder={`smtp.qcloudmail.com`}
/>
</ParagraphItem>
<ParagraphItem>
<Label>
<Require /> {t("admin.system.mailProtocol")}
</Label>
<Select
value={data.protocol ? "true" : "false"}
onValueChange={(value: string) => {
dispatch({
type: "update:mail.protocol",
value: value === "true",
});
}}
>
<SelectTrigger className={`select`}>
<SelectValue
placeholder={data.protocol ? t("admin.system.mailProtocolTLS") : t("admin.system.mailProtocolSSL")}
/>
</SelectTrigger>
<SelectContent>
<SelectItem value="true">TLS</SelectItem>
<SelectItem value="false">SSL</SelectItem>
</SelectContent>
</Select>
</ParagraphItem>
<ParagraphItem>
<Label>
<Require /> {t("admin.system.mailPort")}
Expand Down Expand Up @@ -360,7 +391,7 @@ function Mail({ data, dispatch, onChange }: CompProps<MailState>) {
}
className={cn(
"transition-all duration-300",
data.username.includes("@") && `border-red-700`,
!data.username.includes("@") && `border-red-700`,
)}
placeholder={t("admin.system.mailUser")}
/>
Expand Down Expand Up @@ -396,7 +427,7 @@ function Mail({ data, dispatch, onChange }: CompProps<MailState>) {
className={cn(
"transition-all duration-300",
data.from.length > 0 &&
!/\w+@\w+\.\w+/.test(data.from) &&
!/\w+@/.test(data.from) &&
`border-red-700`,
)}
/>
Expand Down
5 changes: 4 additions & 1 deletion channel/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import (
"chat/globals"
"chat/utils"
"fmt"
"github.com/spf13/viper"
"strings"

"github.com/spf13/viper"
)

type ApiInfo struct {
Expand Down Expand Up @@ -54,6 +55,7 @@ type whiteList struct {

type mailState struct {
Host string `json:"host" mapstructure:"host"`
Protocol bool `json:"protocol" mapstructure:"protocol"`
Port int `json:"port" mapstructure:"port"`
Username string `json:"username" mapstructure:"username"`
Password string `json:"password" mapstructure:"password"`
Expand Down Expand Up @@ -162,6 +164,7 @@ func (c *SystemConfig) GetBackend() string {
func (c *SystemConfig) GetMail() *utils.SmtpPoster {
return utils.NewSmtpPoster(
c.Mail.Host,
c.Mail.Protocol,
c.Mail.Port,
c.Mail.Username,
c.Mail.Password,
Expand Down
17 changes: 13 additions & 4 deletions utils/smtp.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@ package utils
import (
"bytes"
"fmt"
"gopkg.in/mail.v2"
"strings"
"text/template"

"gopkg.in/mail.v2"
)

type SmtpPoster struct {
Host string
Protocol bool
Port int
Username string
Password string
From string
}

func NewSmtpPoster(host string, port int, username string, password string, from string) *SmtpPoster {
func NewSmtpPoster(host string, protocol bool, port int, username string, password string, from string) *SmtpPoster {
return &SmtpPoster{
Host: host,
Protocol: protocol,
Port: port,
Username: username,
Password: password,
Expand All @@ -35,14 +38,20 @@ func (s *SmtpPoster) SendMail(to string, subject string, body string) error {
return fmt.Errorf("smtp not configured properly")
}

dialer := mail.NewDialer(s.Host, s.Port, s.From, s.Password)
dialer := mail.NewDialer(s.Host, s.Port, s.Username, s.Password)
message := mail.NewMessage()

message.SetHeader("From", fmt.Sprintf("%s <%s>", s.Username, s.From))
message.SetHeader("From", s.From)
message.SetHeader("To", to)
message.SetHeader("Subject", subject)
message.SetBody("text/html", body)

if s.Protocol {
dialer.StartTLSPolicy = mail.MandatoryStartTLS
} else {
dialer.StartTLSPolicy = mail.NoStartTLS
}

// outlook STARTTLS policy adapter
if strings.Contains(s.Host, "outlook") {
dialer.StartTLSPolicy = mail.MandatoryStartTLS
Expand Down

0 comments on commit 6f3cdad

Please sign in to comment.