diff --git a/models/models.go b/models/models.go --- a/models/models.go +++ b/models/models.go @@ -29,6 +29,7 @@ Rev string Root []byte Preferences []byte Deactivated bool + EmailAuthFactor bool } func (r *Repo) SignFor(ctx context.Context, did string, msg []byte) ([]byte, error) { @@ -121,8 +122,8 @@ Data []byte } type ReservedKey struct { - KeyDid string `gorm:"primaryKey"` - Did *string `gorm:"index"` + KeyDid string `gorm:"primaryKey"` + Did *string `gorm:"index"` PrivateKey []byte CreatedAt time.Time `gorm:"index"` } diff --git a/server/handle_server_create_session.go b/server/handle_server_create_session.go --- a/server/handle_server_create_session.go +++ b/server/handle_server_create_session.go @@ -104,7 +104,7 @@ Handle: repo.Handle, Did: repo.Repo.Did, Email: repo.Email, EmailConfirmed: repo.EmailConfirmedAt != nil, - EmailAuthFactor: false, + EmailAuthFactor: repo.EmailAuthFactor, Active: repo.Active(), Status: repo.Status(), }) diff --git a/server/handle_server_get_session.go b/server/handle_server_get_session.go --- a/server/handle_server_get_session.go +++ b/server/handle_server_get_session.go @@ -23,7 +23,7 @@ Handle: repo.Handle, Did: repo.Repo.Did, Email: repo.Email, EmailConfirmed: repo.EmailConfirmedAt != nil, - EmailAuthFactor: false, // TODO: todo todo + EmailAuthFactor: repo.EmailAuthFactor, Active: repo.Active(), Status: repo.Status(), }) diff --git a/server/handle_server_update_email.go b/server/handle_server_update_email.go --- a/server/handle_server_update_email.go +++ b/server/handle_server_update_email.go @@ -11,7 +11,7 @@ type ComAtprotoServerUpdateEmailRequest struct { Email string `json:"email" validate:"required"` EmailAuthFactor bool `json:"emailAuthFactor"` - Token string `json:"token" validate:"required"` + Token string `json:"token"` } func (s *Server) handleServerUpdateEmail(e echo.Context) error { @@ -30,19 +30,36 @@ if err := e.Validate(req); err != nil { return helpers.InputError(e, nil) } - if urepo.EmailUpdateCode == nil || urepo.EmailUpdateCodeExpiresAt == nil { + // To disable email auth factor a token is required. + // To enable email auth factor a token is not required. + // If updating an email address, a token will be sent anyway + if urepo.EmailAuthFactor && req.EmailAuthFactor == false && req.Token == "" { return helpers.InvalidTokenError(e) } - if *urepo.EmailUpdateCode != req.Token { - return helpers.InvalidTokenError(e) + if req.Token != "" { + if urepo.EmailUpdateCode == nil || urepo.EmailUpdateCodeExpiresAt == nil { + return helpers.InvalidTokenError(e) + } + + if *urepo.EmailUpdateCode != req.Token { + return helpers.InvalidTokenError(e) + } + + if time.Now().UTC().After(*urepo.EmailUpdateCodeExpiresAt) { + return helpers.ExpiredTokenError(e) + } } - if time.Now().UTC().After(*urepo.EmailUpdateCodeExpiresAt) { - return helpers.ExpiredTokenError(e) + query := "UPDATE repos SET email_update_code = NULL, email_update_code_expires_at = NULL, email_auth_factor = ?, email = ?" + + if urepo.Email != req.Email { + query += ",email_confirmed_at = NULL" } - if err := s.db.Exec(ctx, "UPDATE repos SET email_update_code = NULL, email_update_code_expires_at = NULL, email_confirmed_at = NULL, email = ? WHERE did = ?", nil, req.Email, urepo.Repo.Did).Error; err != nil { + query += " WHERE did = ?" + + if err := s.db.Exec(ctx, query, nil, req.EmailAuthFactor, req.Email, urepo.Repo.Did).Error; err != nil { logger.Error("error updating repo", "error", err) return helpers.ServerError(e, nil) }