forked from hailey.at/cocoon
An atproto PDS written in Go
at main 2.0 kB view raw
1package server 2 3import ( 4 "time" 5 6 "github.com/haileyok/cocoon/internal/helpers" 7 "github.com/haileyok/cocoon/models" 8 "github.com/labstack/echo/v4" 9) 10 11type ComAtprotoServerUpdateEmailRequest struct { 12 Email string `json:"email" validate:"required"` 13 EmailAuthFactor bool `json:"emailAuthFactor"` 14 Token string `json:"token"` 15} 16 17func (s *Server) handleServerUpdateEmail(e echo.Context) error { 18 ctx := e.Request().Context() 19 logger := s.logger.With("name", "handleServerUpdateEmail") 20 21 urepo := e.Get("repo").(*models.RepoActor) 22 23 var req ComAtprotoServerUpdateEmailRequest 24 if err := e.Bind(&req); err != nil { 25 logger.Error("error binding", "error", err) 26 return helpers.ServerError(e, nil) 27 } 28 29 if err := e.Validate(req); err != nil { 30 return helpers.InputError(e, nil) 31 } 32 33 // To disable email auth factor a token is required. 34 // To enable email auth factor a token is not required. 35 // If updating an email address, a token will be sent anyway 36 if urepo.TwoFactorType != models.TwoFactorTypeNone && req.EmailAuthFactor == false && req.Token == "" { 37 return helpers.InvalidTokenError(e) 38 } 39 40 if req.Token != "" { 41 if urepo.EmailUpdateCode == nil || urepo.EmailUpdateCodeExpiresAt == nil { 42 return helpers.InvalidTokenError(e) 43 } 44 45 if *urepo.EmailUpdateCode != req.Token { 46 return helpers.InvalidTokenError(e) 47 } 48 49 if time.Now().UTC().After(*urepo.EmailUpdateCodeExpiresAt) { 50 return helpers.ExpiredTokenError(e) 51 } 52 } 53 54 twoFactorType := models.TwoFactorTypeNone 55 if req.EmailAuthFactor { 56 twoFactorType = models.TwoFactorTypeEmail 57 } 58 59 query := "UPDATE repos SET email_update_code = NULL, email_update_code_expires_at = NULL, two_factor_type = ?, email = ?" 60 61 if urepo.Email != req.Email { 62 query += ",email_confirmed_at = NULL" 63 } 64 65 query += " WHERE did = ?" 66 67 if err := s.db.Exec(ctx, query, nil, twoFactorType, req.Email, urepo.Repo.Did).Error; err != nil { 68 logger.Error("error updating repo", "error", err) 69 return helpers.ServerError(e, nil) 70 } 71 72 return e.NoContent(200) 73}