2023-09-12 02:13:37 +08:00
|
|
|
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package email
|
|
|
|
|
|
|
|
import (
|
2025-06-18 20:46:53 +08:00
|
|
|
"context"
|
2023-09-12 02:13:37 +08:00
|
|
|
"crypto/tls"
|
2025-06-18 20:46:53 +08:00
|
|
|
"fmt"
|
|
|
|
"net"
|
2025-01-20 02:36:01 +08:00
|
|
|
"strings"
|
2023-09-12 02:13:37 +08:00
|
|
|
|
2025-01-20 02:36:01 +08:00
|
|
|
"github.com/casdoor/casdoor/conf"
|
2025-06-18 20:46:53 +08:00
|
|
|
"github.com/wneessen/go-mail"
|
|
|
|
"golang.org/x/net/proxy"
|
2023-09-12 02:13:37 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type SmtpEmailProvider struct {
|
2025-06-18 20:46:53 +08:00
|
|
|
Client *mail.Client
|
2023-09-12 02:13:37 +08:00
|
|
|
}
|
|
|
|
|
2025-06-18 20:46:53 +08:00
|
|
|
func NewSmtpEmailProvider(userName string, password string, host string, port int, typ string, disableSsl bool) (*SmtpEmailProvider, error) {
|
2025-06-21 13:15:23 +08:00
|
|
|
client, err := mail.NewClient(host, mail.WithSMTPAuth(mail.SMTPAuthAutoDiscover), mail.WithUsername(userName), mail.WithPassword(password), mail.WithPort(port))
|
2025-06-18 20:46:53 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if client == nil {
|
|
|
|
return nil, fmt.Errorf("client is nil")
|
|
|
|
}
|
|
|
|
|
2023-09-12 02:13:37 +08:00
|
|
|
if typ == "SUBMAIL" {
|
2025-06-18 20:46:53 +08:00
|
|
|
err = client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-09-12 02:13:37 +08:00
|
|
|
}
|
|
|
|
|
2025-06-18 20:46:53 +08:00
|
|
|
client.SetSSL(!disableSsl)
|
2023-09-12 02:13:37 +08:00
|
|
|
|
2025-01-20 02:36:01 +08:00
|
|
|
if strings.HasSuffix(host, ".amazonaws.com") {
|
|
|
|
socks5Proxy := conf.GetConfigString("socks5Proxy")
|
|
|
|
if socks5Proxy != "" {
|
2025-06-18 20:46:53 +08:00
|
|
|
dialSocksProxy, err := proxy.SOCKS5("tcp", socks5Proxy, nil, proxy.Direct)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
dialContext := func(ctx context.Context, network, addr string) (net.Conn, error) {
|
|
|
|
return dialSocksProxy.Dial(network, addr)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = mail.WithDialContextFunc(dialContext)(client)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2025-01-20 02:36:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-06-18 20:46:53 +08:00
|
|
|
return &SmtpEmailProvider{Client: client}, nil
|
2023-09-12 02:13:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SmtpEmailProvider) Send(fromAddress string, fromName string, toAddress string, subject string, content string) error {
|
2025-06-18 20:46:53 +08:00
|
|
|
message := mail.NewMsg()
|
2023-09-12 02:13:37 +08:00
|
|
|
|
2025-06-21 11:30:07 +08:00
|
|
|
err := message.FromFormat(fromName, fromAddress)
|
2025-06-18 20:46:53 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2025-06-21 11:30:07 +08:00
|
|
|
|
2025-06-18 20:46:53 +08:00
|
|
|
err = message.To(toAddress)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2025-06-21 11:30:07 +08:00
|
|
|
|
2025-06-18 20:46:53 +08:00
|
|
|
message.Subject(subject)
|
|
|
|
message.SetBodyString(mail.TypeTextHTML, content)
|
2023-09-12 02:13:37 +08:00
|
|
|
|
2025-06-18 20:46:53 +08:00
|
|
|
return s.Client.DialAndSend(message)
|
2023-09-12 02:13:37 +08:00
|
|
|
}
|