Add changing email for users
This commit is contained in:
parent
e1ab2095fa
commit
1dca8e96a7
6 changed files with 164 additions and 7 deletions
72
pkg/routes/api/v1/user_update_email.go
Normal file
72
pkg/routes/api/v1/user_update_email.go
Normal file
|
@ -0,0 +1,72 @@
|
|||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"code.vikunja.io/web/handler"
|
||||
"fmt"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// UpdateUserEmail is the handler to let a user update their email address.
|
||||
// @Summary Update email address
|
||||
// @Description Lets the current user change their email address.
|
||||
// @tags user
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param userEmailUpdate body user.EmailUpdate true "The new email address and current password."
|
||||
// @Security JWTKeyAuth
|
||||
// @Success 200 {object} models.Message
|
||||
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Something's invalid."
|
||||
// @Failure 404 {object} code.vikunja.io/web.HTTPError "User does not exist."
|
||||
// @Failure 500 {object} models.Message "Internal server error."
|
||||
// @Router /user/settings/email [post]
|
||||
func UpdateUserEmail(c echo.Context) (err error) {
|
||||
|
||||
var emailUpdate = &user.EmailUpdate{}
|
||||
if err := c.Bind(emailUpdate); err != nil {
|
||||
log.Debugf("Invalid model error. Internal error was: %s", err.Error())
|
||||
if he, is := err.(*echo.HTTPError); is {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid model provided. Error was: %s", he.Message))
|
||||
}
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid model provided."))
|
||||
}
|
||||
|
||||
emailUpdate.User, err = user.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
emailUpdate.User, err = user.CheckUserCredentials(&user.Login{
|
||||
Username: emailUpdate.User.Username,
|
||||
Password: emailUpdate.Password,
|
||||
})
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
err = user.UpdateEmail(emailUpdate)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, models.Message{Message: "We sent you email with a link to confirm your email address."})
|
||||
}
|
|
@ -206,6 +206,7 @@ func registerAPIRoutes(a *echo.Group) {
|
|||
a.POST("/user/password", apiv1.UserChangePassword)
|
||||
a.GET("/users", apiv1.UserList)
|
||||
a.POST("/user/token", apiv1.RenewToken)
|
||||
a.POST("/user/settings/email", apiv1.UpdateUserEmail)
|
||||
|
||||
listHandler := &handler.WebHandler{
|
||||
EmptyStruct: func() handler.CObject {
|
||||
|
|
79
pkg/user/update_email.go
Normal file
79
pkg/user/update_email.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/mail"
|
||||
"code.vikunja.io/api/pkg/utils"
|
||||
)
|
||||
|
||||
// EmailUpdate is the data structure to update a user's email address
|
||||
type EmailUpdate struct {
|
||||
User *User `json:"-"`
|
||||
// The new email address. Needs to be a valid email address.
|
||||
NewEmail string `json:"new_email" valid:"email,length(0|250),required"`
|
||||
// The password of the user for confirmation.
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// UpdateEmail lets a user update their email address
|
||||
func UpdateEmail(update *EmailUpdate) (err error) {
|
||||
|
||||
// Check the email is not already used
|
||||
user := &User{}
|
||||
has, err := x.Where("email = ?", update.NewEmail).Get(user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if has {
|
||||
return ErrUserEmailExists{UserID: user.ID, Email: update.NewEmail}
|
||||
}
|
||||
|
||||
// Set the user as unconfirmed and the new email address
|
||||
update.User, err = GetUserWithEmail(&User{ID: update.User.ID})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
update.User.IsActive = false
|
||||
update.User.Email = update.NewEmail
|
||||
update.User.EmailConfirmToken = utils.MakeRandomString(64)
|
||||
_, err = x.
|
||||
Where("id = ?", update.User.ID).
|
||||
Cols("email", "is_active", "email_confirm_token").
|
||||
Update(update.User)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Send the confirmation mail
|
||||
if !config.MailerEnabled.GetBool() {
|
||||
return
|
||||
}
|
||||
|
||||
// Send the user a mail with a link to confirm the mail
|
||||
data := map[string]interface{}{
|
||||
"User": update.User,
|
||||
"IsNew": false,
|
||||
}
|
||||
|
||||
mail.SendMailWithTemplate(update.User.Email, update.User.Username+", please confirm your email address at Vikunja", "confirm-email", data)
|
||||
|
||||
return
|
||||
}
|
|
@ -252,7 +252,7 @@ func CreateUser(user *User) (newUser *User, err error) {
|
|||
// The new user should not be activated until it confirms his mail address
|
||||
newUser.IsActive = false
|
||||
// Generate a confirm token
|
||||
newUser.EmailConfirmToken = utils.MakeRandomString(400)
|
||||
newUser.EmailConfirmToken = utils.MakeRandomString(60)
|
||||
}
|
||||
|
||||
// Insert it
|
||||
|
@ -277,7 +277,8 @@ func CreateUser(user *User) (newUser *User, err error) {
|
|||
|
||||
// Send the user a mail with a link to confirm the mail
|
||||
data := map[string]interface{}{
|
||||
"User": newUserOut,
|
||||
"User": newUserOut,
|
||||
"IsNew": true,
|
||||
}
|
||||
|
||||
mail.SendMailWithTemplate(user.Email, newUserOut.Username+" + Vikunja = <3", "confirm-email", data)
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
{{template "mail-header.tmpl" .}}
|
||||
<p>
|
||||
Hi {{.User.Username}},<br>
|
||||
<br>
|
||||
Welcome to Vikunja!
|
||||
{{if .IsNew}}
|
||||
<br>
|
||||
Welcome to Vikunja!
|
||||
{{end}}
|
||||
<br/>
|
||||
To confirm you email address, click the link below:
|
||||
To confirm your email address, click the link below:
|
||||
</p>
|
||||
<a href="{{.FrontendURL}}?userEmailConfirm={{.User.EmailConfirmToken}}" title="Confirm your email address" style="background: rgb(20, 131, 175); -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; border: 1px solid rgb(16, 106, 140); border-bottom-width: 3px; color: rgb(255, 255, 255); font-weight: 700; font-size: 13px; margin: 10px auto; padding: 5px 10px; text-decoration: none; text-align: center; text-rendering: optimizelegibility; text-transform: uppercase; display: block; width: 200px;">
|
||||
Confirm your email address
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
Hi {{.User.Username}},
|
||||
|
||||
Welcome to Vikunja!
|
||||
{{if .IsNew}}
|
||||
Welcome to Vikunja!
|
||||
|
||||
To confirm you email address, click the link below:
|
||||
{{end}}
|
||||
To confirm your email address, copy the link below and paste it in your browser:
|
||||
|
||||
{{.FrontendURL}}?userEmailConfirm={{.User.EmailConfirmToken}}
|
Loading…
Reference in a new issue