diff --git a/internal/processing/user/emailconfirm.go b/internal/processing/user/emailconfirm.go index e4ebb0b33..f3b7ab089 100644 --- a/internal/processing/user/emailconfirm.go +++ b/internal/processing/user/emailconfirm.go @@ -32,6 +32,10 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/util" ) +var ( + oneWeek = 168 * time.Hour +) + func (p *processor) SendConfirmEmail(ctx context.Context, user *gtsmodel.User, username string) error { if user.UnconfirmedEmail == "" || user.UnconfirmedEmail == user.Email { // user has already confirmed this email address, so there's nothing to do @@ -109,6 +113,10 @@ func (p *processor) ConfirmEmail(ctx context.Context, token string) (*gtsmodel.U return user, nil } + if user.ConfirmationSentAt.Before(time.Now().Add(-oneWeek)) { + return nil, gtserror.NewErrorForbidden(errors.New("confirmation token more than a week old, please request a new one")) + } + // mark the user's email address as confirmed + remove the unconfirmed address and the token user.Email = user.UnconfirmedEmail user.UnconfirmedEmail = "" diff --git a/internal/processing/user/emailconfirm_test.go b/internal/processing/user/emailconfirm_test.go index cb9b6f86a..f269f4db4 100644 --- a/internal/processing/user/emailconfirm_test.go +++ b/internal/processing/user/emailconfirm_test.go @@ -88,6 +88,27 @@ func (suite *EmailConfirmTestSuite) TestConfirmEmail() { suite.WithinDuration(updatedUser.UpdatedAt, time.Now(), 1*time.Minute) } +func (suite *EmailConfirmTestSuite) TestConfirmEmailOldToken() { + ctx := context.Background() + + user := suite.testUsers["local_account_1"] + + // set a bunch of stuff on the user as though zork hasn't been confirmed yet, but has had an email sent 8 days ago + user.UnconfirmedEmail = "some.email@example.org" + user.Email = "" + user.ConfirmedAt = time.Time{} + user.ConfirmationSentAt = time.Now().Add(-192 * time.Hour) + user.ConfirmationToken = "1d1aa44b-afa4-49c8-ac4b-eceb61715cc6" + + err := suite.db.UpdateByPrimaryKey(ctx, user) + suite.NoError(err) + + // confirm with the token set above + updatedUser, errWithCode := suite.user.ConfirmEmail(ctx, "1d1aa44b-afa4-49c8-ac4b-eceb61715cc6") + suite.Nil(updatedUser) + suite.EqualError(errWithCode, "confirmation token more than a week old, please request a new one") +} + func TestEmailConfirmTestSuite(t *testing.T) { suite.Run(t, &EmailConfirmTestSuite{}) }