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.POST("/user/password", apiv1.UserChangePassword)
|
||||||
a.GET("/users", apiv1.UserList)
|
a.GET("/users", apiv1.UserList)
|
||||||
a.POST("/user/token", apiv1.RenewToken)
|
a.POST("/user/token", apiv1.RenewToken)
|
||||||
|
a.POST("/user/settings/email", apiv1.UpdateUserEmail)
|
||||||
|
|
||||||
listHandler := &handler.WebHandler{
|
listHandler := &handler.WebHandler{
|
||||||
EmptyStruct: func() handler.CObject {
|
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
|
// The new user should not be activated until it confirms his mail address
|
||||||
newUser.IsActive = false
|
newUser.IsActive = false
|
||||||
// Generate a confirm token
|
// Generate a confirm token
|
||||||
newUser.EmailConfirmToken = utils.MakeRandomString(400)
|
newUser.EmailConfirmToken = utils.MakeRandomString(60)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert it
|
// 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
|
// Send the user a mail with a link to confirm the mail
|
||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
"User": newUserOut,
|
"User": newUserOut,
|
||||||
|
"IsNew": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
mail.SendMailWithTemplate(user.Email, newUserOut.Username+" + Vikunja = <3", "confirm-email", data)
|
mail.SendMailWithTemplate(user.Email, newUserOut.Username+" + Vikunja = <3", "confirm-email", data)
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
{{template "mail-header.tmpl" .}}
|
{{template "mail-header.tmpl" .}}
|
||||||
<p>
|
<p>
|
||||||
Hi {{.User.Username}},<br>
|
Hi {{.User.Username}},<br>
|
||||||
<br>
|
{{if .IsNew}}
|
||||||
Welcome to Vikunja!
|
<br>
|
||||||
|
Welcome to Vikunja!
|
||||||
|
{{end}}
|
||||||
<br/>
|
<br/>
|
||||||
To confirm you email address, click the link below:
|
To confirm your email address, click the link below:
|
||||||
</p>
|
</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;">
|
<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
|
Confirm your email address
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
Hi {{.User.Username}},
|
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}}
|
{{.FrontendURL}}?userEmailConfirm={{.User.EmailConfirmToken}}
|
Loading…
Reference in a new issue