Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ var InsecureTLSConfig = &tls.Config{InsecureSkipVerify: true}
var SMTPServer = ""
var SMTPPort = 587
var SMTPSSLEnabled = false
var SMTPForceAuthLogin = false
var SMTPAccount = ""
var SMTPFrom = ""
var SMTPToken = ""
Expand Down
19 changes: 15 additions & 4 deletions common/email.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ func generateMessageID() (string, error) {
return fmt.Sprintf("<%d.%s@%s>", time.Now().UnixNano(), GetRandomString(12), domain), nil
}

func shouldUseSMTPLoginAuth() bool {
if SMTPForceAuthLogin {
return true
}
return isOutlookServer(SMTPAccount) || slices.Contains(EmailLoginAuthServerList, SMTPServer)
}
Comment thread
Hoshino-Yumetsuki marked this conversation as resolved.

func getSMTPAuth() smtp.Auth {
if shouldUseSMTPLoginAuth() {
return LoginAuth(SMTPAccount, SMTPToken)
}
return smtp.PlainAuth("", SMTPAccount, SMTPToken, SMTPServer)
}

func SendEmail(subject string, receiver string, content string) error {
if SMTPFrom == "" { // for compatibility
SMTPFrom = SMTPAccount
Expand All @@ -38,7 +52,7 @@ func SendEmail(subject string, receiver string, content string) error {
"Message-ID: %s\r\n"+ // 添加 Message-ID 头
"Content-Type: text/html; charset=UTF-8\r\n\r\n%s\r\n",
receiver, SystemName, SMTPFrom, encodedSubject, time.Now().Format(time.RFC1123Z), id, content))
auth := smtp.PlainAuth("", SMTPAccount, SMTPToken, SMTPServer)
auth := getSMTPAuth()
addr := fmt.Sprintf("%s:%d", SMTPServer, SMTPPort)
to := strings.Split(receiver, ";")
var err error
Expand Down Expand Up @@ -80,9 +94,6 @@ func SendEmail(subject string, receiver string, content string) error {
if err != nil {
return err
}
} else if isOutlookServer(SMTPAccount) || slices.Contains(EmailLoginAuthServerList, SMTPServer) {
auth = LoginAuth(SMTPAccount, SMTPToken)
err = smtp.SendMail(addr, auth, SMTPFrom, to, mail)
} else {
err = smtp.SendMail(addr, auth, SMTPFrom, to, mail)
}
Expand Down
5 changes: 4 additions & 1 deletion model/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func InitOptionMap() {
common.OptionMap["SMTPAccount"] = ""
common.OptionMap["SMTPToken"] = ""
common.OptionMap["SMTPSSLEnabled"] = strconv.FormatBool(common.SMTPSSLEnabled)
common.OptionMap["SMTPForceAuthLogin"] = strconv.FormatBool(common.SMTPForceAuthLogin)
common.OptionMap["Notice"] = ""
common.OptionMap["About"] = ""
common.OptionMap["HomePageContent"] = ""
Expand Down Expand Up @@ -233,7 +234,7 @@ func updateOptionMap(key string, value string) (err error) {
common.ImageDownloadPermission = intValue
}
}
if strings.HasSuffix(key, "Enabled") || key == "DefaultCollapseSidebar" || key == "DefaultUseAutoGroup" {
if strings.HasSuffix(key, "Enabled") || key == "DefaultCollapseSidebar" || key == "DefaultUseAutoGroup" || key == "SMTPForceAuthLogin" {
boolValue := value == "true"
switch key {
case "PasswordRegisterEnabled":
Expand Down Expand Up @@ -308,6 +309,8 @@ func updateOptionMap(key string, value string) (err error) {
setting.StopOnSensitiveEnabled = boolValue
case "SMTPSSLEnabled":
common.SMTPSSLEnabled = boolValue
case "SMTPForceAuthLogin":
common.SMTPForceAuthLogin = boolValue
case "WorkerAllowHttpImageRequestEnabled":
system_setting.WorkerAllowHttpImageRequestEnabled = boolValue
case "DefaultUseAutoGroup":
Expand Down
9 changes: 5 additions & 4 deletions web/bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions web/src/components/settings/SystemSetting.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const SystemSetting = () => {
EmailDomainRestrictionEnabled: '',
EmailAliasRestrictionEnabled: '',
SMTPSSLEnabled: '',
SMTPForceAuthLogin: '',
EmailDomainWhitelist: [],
TelegramOAuthEnabled: '',
TelegramBotToken: '',
Expand Down Expand Up @@ -182,6 +183,7 @@ const SystemSetting = () => {
case 'EmailDomainRestrictionEnabled':
case 'EmailAliasRestrictionEnabled':
case 'SMTPSSLEnabled':
case 'SMTPForceAuthLogin':
case 'LinuxDOOAuthEnabled':
case 'discord.enabled':
case 'oidc.enabled':
Expand Down Expand Up @@ -1335,6 +1337,15 @@ const SystemSetting = () => {
>
{t('启用SMTP SSL')}
</Form.Checkbox>
<Form.Checkbox
field='SMTPForceAuthLogin'
noLabel
onChange={(e) =>
handleCheckboxChange('SMTPForceAuthLogin', e)
}
>
{t('强制使用 AUTH LOGIN')}
</Form.Checkbox>
</Col>
</Row>
<Button onClick={submitSMTP}>{t('保存 SMTP 设置')}</Button>
Expand Down
1 change: 1 addition & 0 deletions web/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,7 @@
"启用Gemini思考后缀适配": "Enable Gemini thinking suffix adaptation",
"启用Ping间隔": "Enable Ping interval",
"启用SMTP SSL": "Enable SMTP SSL",
"强制使用 AUTH LOGIN": "Force AUTH LOGIN",
"启用SSRF防护(推荐开启以保护服务器安全)": "Enable SSRF Protection (Recommended for server security)",
"启用供应商": "Enable Provider",
"启用全部": "Enable all",
Expand Down
1 change: 1 addition & 0 deletions web/src/i18n/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,7 @@
"启用Gemini思考后缀适配": "Activer l'adaptation du suffixe de la pensée Gemini",
"启用Ping间隔": "Activer l'intervalle de ping",
"启用SMTP SSL": "Activer SMTP SSL",
"强制使用 AUTH LOGIN": "Forcer AUTH LOGIN",
"启用SSRF防护(推荐开启以保护服务器安全)": "Activer la protection SSRF (recommandé pour la sécurité du serveur)",
"启用供应商": "Activer le fournisseur",
"启用全部": "Activer tout",
Expand Down
1 change: 1 addition & 0 deletions web/src/i18n/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,7 @@
"启用Gemini思考后缀适配": "Gemini思考サフィックスモードを有効にする",
"启用Ping间隔": "Ping間隔を有効にする",
"启用SMTP SSL": "SMTP SSLを有効にする",
"强制使用 AUTH LOGIN": "AUTH LOGINを強制する",
"启用SSRF防护(推荐开启以保护服务器安全)": "SSRF保護を有効にする(サーバーを保護するため、有効化を推奨します)",
"启用供应商": "プロバイダーを有効化",
"启用全部": "すべてを有効にする",
Expand Down
1 change: 1 addition & 0 deletions web/src/i18n/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,7 @@
"启用Gemini思考后缀适配": "Включить адаптацию суффикса мышления Gemini",
"启用Ping间隔": "Включить интервал Ping",
"启用SMTP SSL": "Включить SMTP SSL",
"强制使用 AUTH LOGIN": "Принудительно AUTH LOGIN",
"启用SSRF防护(推荐开启以保护服务器安全)": "Включить защиту SSRF (рекомендуется включить для защиты безопасности сервера)",
"启用供应商": "Включить поставщика",
"启用全部": "Включить все",
Expand Down
1 change: 1 addition & 0 deletions web/src/i18n/locales/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,7 @@
"启用Gemini思考后缀适配": "Bật thích ứng hậu tố tư duy Gemini",
"启用Ping间隔": "Bật khoảng thời gian Ping",
"启用SMTP SSL": "Bật SMTP SSL",
"强制使用 AUTH LOGIN": "Buộc AUTH LOGIN",
"启用SSRF防护(推荐开启以保护服务器安全)": "Bật bảo vệ SSRF (Khuyên dùng để bảo mật máy chủ)",
"启用供应商": "Bật nhà cung cấp",
"启用全部": "Bật tất cả",
Expand Down
1 change: 1 addition & 0 deletions web/src/i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@
"启用Gemini思考后缀适配": "启用Gemini思考后缀适配",
"启用Ping间隔": "启用Ping间隔",
"启用SMTP SSL": "启用SMTP SSL",
"强制使用 AUTH LOGIN": "强制使用 AUTH LOGIN",
"启用SSRF防护(推荐开启以保护服务器安全)": "启用SSRF防护(推荐开启以保护服务器安全)",
"启用全部": "启用全部",
"启用后可接入 io.net GPU 资源": "启用后可接入 io.net GPU 资源",
Expand Down
1 change: 1 addition & 0 deletions web/src/i18n/locales/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,7 @@
"启用Gemini思考后缀适配": "啟用Gemini思考後綴相容",
"启用Ping间隔": "啟用Ping間隔",
"启用SMTP SSL": "啟用SMTP SSL",
"强制使用 AUTH LOGIN": "強制使用 AUTH LOGIN",
"启用SSRF防护(推荐开启以保护服务器安全)": "啟用SSRF防護(推薦開啟以保護伺服器安全)",
"启用全部": "啟用全部",
"启用后可接入 io.net GPU 资源": "啟用後可接入 io.net GPU 資源",
Expand Down