Send a notification on failed TOTP
This commit is contained in:
parent
1571dfa825
commit
3572ac4b82
2 changed files with 40 additions and 1 deletions
|
@ -20,11 +20,13 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"code.vikunja.io/api/pkg/db"
|
"code.vikunja.io/api/pkg/db"
|
||||||
|
"code.vikunja.io/api/pkg/log"
|
||||||
"code.vikunja.io/api/pkg/models"
|
"code.vikunja.io/api/pkg/models"
|
||||||
"code.vikunja.io/api/pkg/modules/auth"
|
"code.vikunja.io/api/pkg/modules/auth"
|
||||||
|
"code.vikunja.io/api/pkg/notifications"
|
||||||
user2 "code.vikunja.io/api/pkg/user"
|
user2 "code.vikunja.io/api/pkg/user"
|
||||||
"code.vikunja.io/web/handler"
|
"code.vikunja.io/web/handler"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt"
|
"github.com/golang-jwt/jwt"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
@ -64,11 +66,23 @@ func Login(c echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if totpEnabled {
|
if totpEnabled {
|
||||||
|
if u.TOTPPasscode == "" {
|
||||||
|
return handler.HandleHTTPError(user2.ErrInvalidTOTPPasscode{}, c)
|
||||||
|
}
|
||||||
|
|
||||||
_, err = user2.ValidateTOTPPasscode(s, &user2.TOTPPasscode{
|
_, err = user2.ValidateTOTPPasscode(s, &user2.TOTPPasscode{
|
||||||
User: user,
|
User: user,
|
||||||
Passcode: u.TOTPPasscode,
|
Passcode: u.TOTPPasscode,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if user2.IsErrInvalidTOTPPasscode(err) {
|
||||||
|
log.Errorf("Invalid TOTP credentials provided for user %d", user.ID)
|
||||||
|
|
||||||
|
err2 := notifications.Notify(user, &user2.InvalidTOTPNotification{User: user})
|
||||||
|
if err2 != nil {
|
||||||
|
log.Errorf("Could not send failed TOTP notification to user %d: %s", user.ID, err2)
|
||||||
|
}
|
||||||
|
}
|
||||||
_ = s.Rollback()
|
_ = s.Rollback()
|
||||||
return handler.HandleHTTPError(err, c)
|
return handler.HandleHTTPError(err, c)
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,3 +110,28 @@ func (n *ResetPasswordNotification) ToDB() interface{} {
|
||||||
func (n *ResetPasswordNotification) Name() string {
|
func (n *ResetPasswordNotification) Name() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InvalidTOTPNotification represents a InvalidTOTPNotification notification
|
||||||
|
type InvalidTOTPNotification struct {
|
||||||
|
User *User
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToMail returns the mail notification for InvalidTOTPNotification
|
||||||
|
func (n *InvalidTOTPNotification) ToMail() *notifications.Mail {
|
||||||
|
return notifications.NewMail().
|
||||||
|
Subject("Someone just tried to login to your Vikunja account, but failed").
|
||||||
|
Greeting("Hi "+n.User.GetName()+",").
|
||||||
|
Line("Someone just tried to log in into your account with correct username and password but a wrong TOTP passcode.").
|
||||||
|
Line("**If this was not you, someone else knows your password. You should set a new one immediately!**").
|
||||||
|
Action("Reset your password", config.ServiceFrontendurl.GetString()+"get-password-reset")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDB returns the InvalidTOTPNotification notification in a format which can be saved in the db
|
||||||
|
func (n *InvalidTOTPNotification) ToDB() interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the name of the notification
|
||||||
|
func (n *InvalidTOTPNotification) Name() string {
|
||||||
|
return "totp.invalid"
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue