mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-12-30 05:46:15 -06:00
add email confirm handler
This commit is contained in:
parent
d1c271fc8e
commit
652b41d1ce
6 changed files with 90 additions and 1 deletions
|
|
@ -179,6 +179,9 @@ type Processor interface {
|
|||
|
||||
// UserChangePassword changes the password for the given user, with the given form.
|
||||
UserChangePassword(ctx context.Context, authed *oauth.Auth, form *apimodel.PasswordChangeRequest) gtserror.WithCode
|
||||
// UserConfirmEmail confirms an email address using the given token.
|
||||
// The user belonging to the confirmed email is also returned.
|
||||
UserConfirmEmail(ctx context.Context, token string) (*gtsmodel.User, gtserror.WithCode)
|
||||
|
||||
/*
|
||||
FEDERATION API-FACING PROCESSING FUNCTIONS
|
||||
|
|
|
|||
|
|
@ -23,9 +23,14 @@ import (
|
|||
|
||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||
)
|
||||
|
||||
func (p *processor) UserChangePassword(ctx context.Context, authed *oauth.Auth, form *apimodel.PasswordChangeRequest) gtserror.WithCode {
|
||||
return p.userProcessor.ChangePassword(ctx, authed.User, form.OldPassword, form.NewPassword)
|
||||
}
|
||||
|
||||
func (p *processor) UserConfirmEmail(ctx context.Context, token string) (*gtsmodel.User, gtserror.WithCode) {
|
||||
return p.userProcessor.ConfirmEmail(ctx, token)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,12 +20,14 @@ package user
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/email"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/util"
|
||||
)
|
||||
|
|
@ -76,3 +78,46 @@ func (p *processor) SendConfirmEmail(ctx context.Context, user *gtsmodel.User, u
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *processor) ConfirmEmail(ctx context.Context, token string) (*gtsmodel.User, gtserror.WithCode) {
|
||||
if token == "" {
|
||||
return nil, gtserror.NewErrorNotFound(errors.New("no token provided"))
|
||||
}
|
||||
|
||||
user := >smodel.User{}
|
||||
if err := p.db.GetWhere(ctx, []db.Where{{Key: "confirmation_token", Value: token}}, user); err != nil {
|
||||
if err == db.ErrNoEntries {
|
||||
return nil, gtserror.NewErrorNotFound(err)
|
||||
}
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
if user.Account == nil {
|
||||
a, err := p.db.GetAccountByID(ctx, user.AccountID)
|
||||
if err != nil {
|
||||
return nil, gtserror.NewErrorNotFound(err)
|
||||
}
|
||||
user.Account = a
|
||||
}
|
||||
|
||||
if !user.Account.SuspendedAt.IsZero() {
|
||||
return nil, gtserror.NewErrorForbidden(fmt.Errorf("ConfirmEmail: account %s is suspended", user.AccountID))
|
||||
}
|
||||
|
||||
if user.UnconfirmedEmail == "" || user.UnconfirmedEmail == user.Email {
|
||||
// no pending email confirmations so just return OK
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// mark the user's email address as confirmed + remove the unconfirmed address and the token
|
||||
user.Email = user.UnconfirmedEmail
|
||||
user.UnconfirmedEmail = ""
|
||||
user.ConfirmedAt = time.Now()
|
||||
user.ConfirmationToken = ""
|
||||
|
||||
if err := p.db.UpdateByPrimaryKey(ctx, user); err != nil {
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,10 @@ type Processor interface {
|
|||
// ChangePassword changes the specified user's password from old => new,
|
||||
// or returns an error if the new password is too weak, or the old password is incorrect.
|
||||
ChangePassword(ctx context.Context, user *gtsmodel.User, oldPassword string, newPassword string) gtserror.WithCode
|
||||
// SendConfirmEmail sends a 'confirm-your-email-address' type email to a user.
|
||||
SendConfirmEmail(ctx context.Context, user *gtsmodel.User, username string) error
|
||||
// ConfirmEmail confirms an email address using the given token.
|
||||
ConfirmEmail(ctx context.Context, token string) (*gtsmodel.User, gtserror.WithCode)
|
||||
}
|
||||
|
||||
type processor struct {
|
||||
|
|
|
|||
|
|
@ -18,8 +18,12 @@
|
|||
|
||||
package web
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func (m *Module) ConfirmEmailGETHandler(c *gin.Context) {
|
||||
// if there's no token in the query, just serve the 404 web handler
|
||||
|
|
@ -29,5 +33,25 @@ func (m *Module) ConfirmEmailGETHandler(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx := c.Request.Context()
|
||||
|
||||
user, errWithCode := m.processor.UserConfirmEmail(ctx, token)
|
||||
if errWithCode != nil {
|
||||
logrus.Debugf("error confirming email: %s", errWithCode.Error())
|
||||
// if something goes wrong, just log it and direct to the 404 handler to not give anything away
|
||||
m.NotFoundHandler(c)
|
||||
return
|
||||
}
|
||||
|
||||
instance, err := m.processor.InstanceGet(ctx, m.config.Host)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "confirmed.tmpl", gin.H{
|
||||
"instance": instance,
|
||||
"email": user.Email,
|
||||
"username": user.Account.Username,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
9
web/template/confirmed.tmpl
Normal file
9
web/template/confirmed.tmpl
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{{ template "header.tmpl" .}}
|
||||
<main>
|
||||
<section>
|
||||
<h1>Email Address Confirmed</h1>
|
||||
<p>Thanks {{.username}}! Your email address <b>{{.email}}</b> has been confirmed.<p>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
{{ template "footer.tmpl" .}}
|
||||
Loading…
Add table
Add a link
Reference in a new issue