feat(security): #286 fix mail sending
Some checks failed
Build Docker Image / Build-Docker-Image (push) Failing after 39s
Some checks failed
Build Docker Image / Build-Docker-Image (push) Failing after 39s
This commit is contained in:
@@ -59,9 +59,9 @@ var (
|
|||||||
|
|
||||||
func (handler AuthImpl) handleSignInPage() http.HandlerFunc {
|
func (handler AuthImpl) handleSignInPage() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session := middleware.GetSession(r)
|
user := middleware.GetUser(r)
|
||||||
if session != nil {
|
if user != nil {
|
||||||
if !session.User.EmailVerified {
|
if !user.EmailVerified {
|
||||||
utils.DoRedirect(w, r, "/auth/verify")
|
utils.DoRedirect(w, r, "/auth/verify")
|
||||||
} else {
|
} else {
|
||||||
utils.DoRedirect(w, r, "/")
|
utils.DoRedirect(w, r, "/")
|
||||||
@@ -122,10 +122,10 @@ func (handler AuthImpl) handleSignIn() http.HandlerFunc {
|
|||||||
|
|
||||||
func (handler AuthImpl) handleSignUpPage() http.HandlerFunc {
|
func (handler AuthImpl) handleSignUpPage() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session := middleware.GetSession(r)
|
user := middleware.GetUser(r)
|
||||||
|
|
||||||
if session != nil {
|
if user != nil {
|
||||||
if !session.User.EmailVerified {
|
if !user.EmailVerified {
|
||||||
utils.DoRedirect(w, r, "/auth/verify")
|
utils.DoRedirect(w, r, "/auth/verify")
|
||||||
} else {
|
} else {
|
||||||
utils.DoRedirect(w, r, "/")
|
utils.DoRedirect(w, r, "/")
|
||||||
@@ -140,31 +140,30 @@ func (handler AuthImpl) handleSignUpPage() http.HandlerFunc {
|
|||||||
|
|
||||||
func (handler AuthImpl) handleSignUpVerifyPage() http.HandlerFunc {
|
func (handler AuthImpl) handleSignUpVerifyPage() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session := middleware.GetSession(r)
|
user := middleware.GetUser(r)
|
||||||
if session == nil {
|
if user == nil {
|
||||||
utils.DoRedirect(w, r, "/auth/signin")
|
utils.DoRedirect(w, r, "/auth/signin")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if session.User.EmailVerified {
|
if user.EmailVerified {
|
||||||
utils.DoRedirect(w, r, "/")
|
utils.DoRedirect(w, r, "/")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
signIn := auth.VerifyComp()
|
signIn := auth.VerifyComp()
|
||||||
handler.render.RenderLayout(r, w, signIn, session.User)
|
handler.render.RenderLayout(r, w, signIn, user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler AuthImpl) handleVerifyResendComp() http.HandlerFunc {
|
func (handler AuthImpl) handleVerifyResendComp() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session := middleware.GetSession(r)
|
user := middleware.GetUser(r)
|
||||||
if session == nil {
|
if user == nil {
|
||||||
utils.DoRedirect(w, r, "/auth/signin")
|
utils.DoRedirect(w, r, "/auth/signin")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user := session.User
|
|
||||||
go handler.service.SendVerificationMail(user.Id, user.Email)
|
go handler.service.SendVerificationMail(user.Id, user.Email)
|
||||||
|
|
||||||
_, err := w.Write([]byte("<p class=\"mt-8\">Verification email sent</p>"))
|
_, err := w.Write([]byte("<p class=\"mt-8\">Verification email sent</p>"))
|
||||||
@@ -195,11 +194,13 @@ func (handler AuthImpl) handleSignUp() http.HandlerFunc {
|
|||||||
var password = r.FormValue("password")
|
var password = r.FormValue("password")
|
||||||
|
|
||||||
_, err := utils.WaitMinimumTime(securityWaitDuration, func() (interface{}, error) {
|
_, err := utils.WaitMinimumTime(securityWaitDuration, func() (interface{}, error) {
|
||||||
|
log.Info("Signing up %v", email)
|
||||||
user, err := handler.service.SignUp(email, password)
|
user, err := handler.service.SignUp(email, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Info("Sending verification email to %v", user.Email)
|
||||||
go handler.service.SendVerificationMail(user.Id, user.Email)
|
go handler.service.SendVerificationMail(user.Id, user.Email)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
})
|
})
|
||||||
@@ -248,34 +249,34 @@ func (handler AuthImpl) handleSignOut() http.HandlerFunc {
|
|||||||
|
|
||||||
func (handler AuthImpl) handleDeleteAccountPage() http.HandlerFunc {
|
func (handler AuthImpl) handleDeleteAccountPage() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session := middleware.GetSession(r)
|
user := middleware.GetUser(r)
|
||||||
if session == nil {
|
if user == nil {
|
||||||
utils.DoRedirect(w, r, "/auth/signin")
|
utils.DoRedirect(w, r, "/auth/signin")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
comp := auth.DeleteAccountComp()
|
comp := auth.DeleteAccountComp()
|
||||||
handler.render.RenderLayout(r, w, comp, session.User)
|
handler.render.RenderLayout(r, w, comp, user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler AuthImpl) handleDeleteAccountComp() http.HandlerFunc {
|
func (handler AuthImpl) handleDeleteAccountComp() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session := middleware.GetSession(r)
|
user := middleware.GetUser(r)
|
||||||
if session == nil {
|
if user == nil {
|
||||||
utils.DoRedirect(w, r, "/auth/signin")
|
utils.DoRedirect(w, r, "/auth/signin")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
password := r.FormValue("password")
|
password := r.FormValue("password")
|
||||||
|
|
||||||
_, err := handler.service.SignIn(session.User.Email, password)
|
_, err := handler.service.SignIn(user.Email, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.TriggerToast(w, r, "error", "Password not correct")
|
utils.TriggerToast(w, r, "error", "Password not correct")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = handler.service.DeleteAccount(session.User)
|
err = handler.service.DeleteAccount(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.TriggerToast(w, r, "error", "Internal Server Error")
|
utils.TriggerToast(w, r, "error", "Internal Server Error")
|
||||||
return
|
return
|
||||||
@@ -290,23 +291,23 @@ func (handler AuthImpl) handleChangePasswordPage() http.HandlerFunc {
|
|||||||
|
|
||||||
isPasswordReset := r.URL.Query().Has("token")
|
isPasswordReset := r.URL.Query().Has("token")
|
||||||
|
|
||||||
session := middleware.GetSession(r)
|
user := middleware.GetUser(r)
|
||||||
|
|
||||||
if session == nil && !isPasswordReset {
|
if user == nil && !isPasswordReset {
|
||||||
utils.DoRedirect(w, r, "/auth/signin")
|
utils.DoRedirect(w, r, "/auth/signin")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
comp := auth.ChangePasswordComp(isPasswordReset)
|
comp := auth.ChangePasswordComp(isPasswordReset)
|
||||||
handler.render.RenderLayout(r, w, comp, session.User)
|
handler.render.RenderLayout(r, w, comp, user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler AuthImpl) handleChangePasswordComp() http.HandlerFunc {
|
func (handler AuthImpl) handleChangePasswordComp() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
session := middleware.GetSession(r)
|
user := middleware.GetUser(r)
|
||||||
if session == nil {
|
if user == nil {
|
||||||
utils.DoRedirect(w, r, "/auth/signin")
|
utils.DoRedirect(w, r, "/auth/signin")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -314,7 +315,7 @@ func (handler AuthImpl) handleChangePasswordComp() http.HandlerFunc {
|
|||||||
currPass := r.FormValue("current-password")
|
currPass := r.FormValue("current-password")
|
||||||
newPass := r.FormValue("new-password")
|
newPass := r.FormValue("new-password")
|
||||||
|
|
||||||
err := handler.service.ChangePassword(session.User, currPass, newPass)
|
err := handler.service.ChangePassword(user, currPass, newPass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.TriggerToast(w, r, "error", "Password not correct")
|
utils.TriggerToast(w, r, "error", "Password not correct")
|
||||||
return
|
return
|
||||||
@@ -327,14 +328,14 @@ func (handler AuthImpl) handleChangePasswordComp() http.HandlerFunc {
|
|||||||
func (handler AuthImpl) handleResetPasswordPage() http.HandlerFunc {
|
func (handler AuthImpl) handleResetPasswordPage() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
session := middleware.GetSession(r)
|
user := middleware.GetUser(r)
|
||||||
if session == nil {
|
if user == nil {
|
||||||
utils.DoRedirect(w, r, "/auth/signin")
|
utils.DoRedirect(w, r, "/auth/signin")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
comp := auth.ResetPasswordComp()
|
comp := auth.ResetPasswordComp()
|
||||||
handler.render.RenderLayout(r, w, comp, session.User)
|
handler.render.RenderLayout(r, w, comp, user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,16 @@ func Authenticate(service service.Auth) func(http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetUser(r *http.Request) *service.User {
|
||||||
|
|
||||||
|
session := GetSession(r)
|
||||||
|
if session == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return session.User
|
||||||
|
}
|
||||||
|
|
||||||
func GetSession(r *http.Request) *service.Session {
|
func GetSession(r *http.Request) *service.Session {
|
||||||
obj := r.Context().Value(SessionKey)
|
obj := r.Context().Value(SessionKey)
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
|
|||||||
28
less
Normal file
28
less
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
__ _ ___
|
||||||
|
/ /\ | | | |_)
|
||||||
|
/_/--\ |_| |_| \_ v1.52.3, built with Go go1.22.5
|
||||||
|
|
||||||
|
mkdir /home/tiwun/source/me-fit/tmp
|
||||||
|
watching .
|
||||||
|
watching db
|
||||||
|
watching handler
|
||||||
|
watching handler/middleware
|
||||||
|
watching log
|
||||||
|
watching migration
|
||||||
|
watching mocks
|
||||||
|
!exclude node_modules
|
||||||
|
watching service
|
||||||
|
!exclude static
|
||||||
|
watching template
|
||||||
|
watching template/auth
|
||||||
|
watching template/mail
|
||||||
|
watching template/workout
|
||||||
|
!exclude tmp
|
||||||
|
watching types
|
||||||
|
watching utils
|
||||||
|
building...
|
||||||
|
[32m(✓)[0m Complete [[2m updates=12[22m[2m duration=10.258748ms[22m ]
|
||||||
|
cleaning...
|
||||||
|
deleting /home/tiwun/source/me-fit/tmp
|
||||||
|
see you again~
|
||||||
@@ -220,7 +220,7 @@ func (service AuthImpl) SignUp(email string, password string) (*User, error) {
|
|||||||
func (service AuthImpl) SendVerificationMail(userId uuid.UUID, email string) {
|
func (service AuthImpl) SendVerificationMail(userId uuid.UUID, email string) {
|
||||||
|
|
||||||
tokens, err := service.db.GetTokensByUserIdAndType(userId, db.TokenTypeEmailVerify)
|
tokens, err := service.db.GetTokensByUserIdAndType(userId, db.TokenTypeEmailVerify)
|
||||||
if err != nil {
|
if err != db.ErrNotFound {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,7 +304,7 @@ func (service AuthImpl) DeleteAccount(user *User) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
go service.mail.SendMail(user.Email, "Account deleted", "Your account has been deleted")
|
service.mail.SendMail(user.Email, "Account deleted", "Your account has been deleted")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -370,7 +370,7 @@ func (service AuthImpl) SendForgotPasswordMail(email string) error {
|
|||||||
log.Error("Could not render reset password email: %v", err)
|
log.Error("Could not render reset password email: %v", err)
|
||||||
return types.ErrInternal
|
return types.ErrInternal
|
||||||
}
|
}
|
||||||
go service.mail.SendMail(email, "Reset Password", mail.String())
|
service.mail.SendMail(email, "Reset Password", mail.String())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ func NewMailImpl(server *types.Settings) MailImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m MailImpl) SendMail(to string, subject string, message string) {
|
func (m MailImpl) SendMail(to string, subject string, message string) {
|
||||||
|
go m.internalSendMail(to, subject, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MailImpl) internalSendMail(to string, subject string, message string) {
|
||||||
if m.server.Smtp == nil {
|
if m.server.Smtp == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -32,6 +36,7 @@ func (m MailImpl) SendMail(to string, subject string, message string) {
|
|||||||
|
|
||||||
msg := fmt.Sprintf("From: %v <%v>\nTo: %v\nSubject: %v\nMIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n%v", s.FromName, s.FromMail, to, subject, message)
|
msg := fmt.Sprintf("From: %v <%v>\nTo: %v\nSubject: %v\nMIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n%v", s.FromName, s.FromMail, to, subject, message)
|
||||||
|
|
||||||
|
log.Info("Sending mail to %v", to)
|
||||||
err := smtp.SendMail(s.Host+":"+s.Port, auth, s.FromMail, []string{to}, []byte(msg))
|
err := smtp.SendMail(s.Host+":"+s.Port, auth, s.FromMail, []string{to}, []byte(msg))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error sending mail: %v", err)
|
log.Error("Error sending mail: %v", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user