mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-28 17:23:09 -06:00
Define Mailer interface and provide SmtpMailer implementation
This commit is contained in:
parent
503f43abe0
commit
4d1f248a9b
|
|
@ -22,6 +22,16 @@ import (
|
|||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verification is used in
|
||||
// - https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-account-3pid-email-requesttoken
|
||||
// - https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-register-email-requesttoken
|
||||
Verification ThreepidSessionType = iota
|
||||
// Password is used in
|
||||
// - https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-account-password-email-requesttoken
|
||||
Password
|
||||
)
|
||||
|
||||
// UserInternalAPI is the internal API for information about users and devices.
|
||||
type UserInternalAPI interface {
|
||||
InputAccountData(ctx context.Context, req *InputAccountDataRequest, res *InputAccountDataResponse) error
|
||||
|
|
@ -365,3 +375,5 @@ type IsSessionValidatedResponse struct {
|
|||
Validated bool
|
||||
ValidatedAt int
|
||||
}
|
||||
|
||||
type ThreepidSessionType int
|
||||
|
|
|
|||
102
userapi/mail/mail.go
Normal file
102
userapi/mail/mail.go
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
package mail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/smtp"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/dendrite/internal"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/userapi/api"
|
||||
)
|
||||
|
||||
const (
|
||||
messageIdByteLength = 48
|
||||
)
|
||||
|
||||
type Mailer interface {
|
||||
// Send is used in
|
||||
// - https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-account-3pid-email-requesttoken
|
||||
// - https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-register-email-requesttoken
|
||||
// - https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-account-password-email-requesttoken
|
||||
Send(*Mail, api.ThreepidSessionType) error
|
||||
}
|
||||
type SmtpMailer struct {
|
||||
conf config.EmailConf
|
||||
templates map[api.ThreepidSessionType]*template.Template
|
||||
}
|
||||
|
||||
type Mail struct {
|
||||
To string
|
||||
Link string
|
||||
Token string
|
||||
Extra []string
|
||||
}
|
||||
|
||||
type Substitutions struct {
|
||||
*Mail
|
||||
Date string
|
||||
MessageId string
|
||||
}
|
||||
|
||||
func (m *SmtpMailer) Send(mail *Mail, t api.ThreepidSessionType) error {
|
||||
return m.send(mail, m.templates[t])
|
||||
}
|
||||
|
||||
func (m *SmtpMailer) send(mail *Mail, t *template.Template) error {
|
||||
messageId, err := internal.GenerateBlob(messageIdByteLength)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s := Substitutions{
|
||||
Mail: mail,
|
||||
Date: time.Now().Format(time.RFC1123Z),
|
||||
MessageId: messageId,
|
||||
}
|
||||
b := bytes.Buffer{}
|
||||
err = t.Execute(&b, s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return smtp.SendMail(
|
||||
m.conf.Smtp.Host,
|
||||
smtp.PlainAuth(
|
||||
"",
|
||||
m.conf.Smtp.User,
|
||||
m.conf.Smtp.Password,
|
||||
m.conf.Smtp.Host,
|
||||
),
|
||||
m.conf.From,
|
||||
[]string{
|
||||
mail.To,
|
||||
},
|
||||
b.Bytes(),
|
||||
)
|
||||
}
|
||||
|
||||
func NewMailer(c *config.UserAPI) (Mailer, error) {
|
||||
templateRaw, err := ioutil.ReadFile(fmt.Sprintf("%s/verification.eml", c.Email.TemplatesPath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
verificationT, err := template.New("verification").Parse(string(templateRaw))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
templateRaw, err = ioutil.ReadFile(fmt.Sprintf("%s/password.eml", c.Email.TemplatesPath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
passwordT, err := template.New("password").Parse(string(templateRaw))
|
||||
return &SmtpMailer{
|
||||
conf: c.Email,
|
||||
templates: map[api.ThreepidSessionType]*template.Template{
|
||||
api.Password: passwordT,
|
||||
api.Verification: verificationT,
|
||||
},
|
||||
}, err
|
||||
|
||||
}
|
||||
38
userapi/mail/mail_test.go
Normal file
38
userapi/mail/mail_test.go
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package mail
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matryer/is"
|
||||
)
|
||||
|
||||
func TestSendVerification(t *testing.T) {
|
||||
is := is.New(t)
|
||||
dut := mustNewMailer(is)
|
||||
err := dut.Send(
|
||||
&Mail{
|
||||
To: "kevil11378@186site.com",
|
||||
Link: "my",
|
||||
Token: "foo",
|
||||
Extra: []string{
|
||||
"bar",
|
||||
},
|
||||
}, api.Verification)
|
||||
is.NoErr(err)
|
||||
}
|
||||
|
||||
func mustNewMailer(is *is.I) Mailer {
|
||||
mailer, err := NewMailer(&config.UserAPI{
|
||||
Email: config.EmailConf{
|
||||
TemplatesPath: "../../res/default",
|
||||
From: "test@matrix.com",
|
||||
Smtp: config.Smtp{
|
||||
Host: "localhost:25",
|
||||
},
|
||||
},
|
||||
})
|
||||
is.NoErr(err)
|
||||
return mailer
|
||||
}
|
||||
Loading…
Reference in a new issue