2023-08-23 16:17:01 +01:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
2023-08-23 17:36:23 +01:00
|
|
|
"fmt"
|
2023-08-23 16:17:01 +01:00
|
|
|
postfixLookup "github.com/1f349/lotus/postfix-lookup"
|
2023-09-11 01:33:08 +01:00
|
|
|
"github.com/1f349/lotus/sendmail"
|
2023-08-23 16:17:01 +01:00
|
|
|
"github.com/julienschmidt/httprouter"
|
2023-08-23 17:57:02 +01:00
|
|
|
"log"
|
2023-08-23 16:17:01 +01:00
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
var defaultPostfixLookup = postfixLookup.NewPostfixLookup().Lookup
|
|
|
|
var timeNow = time.Now
|
|
|
|
|
|
|
|
// MessageSender is the internal handler for `POST /message` requests
|
|
|
|
// the access token is already validated at this point
|
|
|
|
func MessageSender(send Smtp) func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims) {
|
|
|
|
return func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims) {
|
|
|
|
// check body exists
|
|
|
|
if req.Body == nil {
|
|
|
|
apiError(rw, http.StatusBadRequest, "Missing request body")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// parse json body
|
2023-09-11 01:33:08 +01:00
|
|
|
var j sendmail.Json
|
2023-08-23 16:17:01 +01:00
|
|
|
err := json.NewDecoder(req.Body).Decode(&j)
|
|
|
|
if err != nil {
|
|
|
|
apiError(rw, http.StatusBadRequest, "Invalid JSON body")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// prepare the mail for sending
|
|
|
|
mail, err := j.PrepareMail(timeNow())
|
|
|
|
if err != nil {
|
2023-08-23 17:36:23 +01:00
|
|
|
apiError(rw, http.StatusBadRequest, fmt.Sprintf("Invalid mail message: %s", err))
|
2023-08-23 16:17:01 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// this looks up the underlying account for the sender alias
|
2023-08-23 19:14:47 +01:00
|
|
|
lookup, err := defaultPostfixLookup(mail.From.Address)
|
2023-08-23 16:17:01 +01:00
|
|
|
|
|
|
|
// the alias does not exist
|
|
|
|
if errors.Is(err, postfixLookup.ErrInvalidAlias) {
|
|
|
|
apiError(rw, http.StatusBadRequest, "Invalid sender alias")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// the alias lookup failed to run
|
|
|
|
if err != nil {
|
|
|
|
apiError(rw, http.StatusInternalServerError, "Sender alias lookup failed")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// the alias does not match the logged-in user
|
|
|
|
if lookup != b.Subject {
|
|
|
|
apiError(rw, http.StatusBadRequest, "User does not own sender alias")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// try sending the mail
|
2023-08-23 17:57:02 +01:00
|
|
|
if err := send.Send(mail); err != nil {
|
2023-08-23 16:17:01 +01:00
|
|
|
apiError(rw, http.StatusInternalServerError, "Failed to send mail")
|
2023-08-23 17:57:02 +01:00
|
|
|
log.Printf("Failed to send mail: %#v: %s\n", mail, err)
|
2023-08-23 16:17:01 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
rw.WriteHeader(http.StatusAccepted)
|
|
|
|
}
|
|
|
|
}
|