fix: require >1 provider for unlink account endpoints (fixes #29)

This commit is contained in:
Sam 2023-03-18 23:04:50 +01:00
parent d223cd89e8
commit 004403895a
No known key found for this signature in database
GPG key ID: B4EF20DDE721CAA1
5 changed files with 24 additions and 0 deletions

View file

@ -40,6 +40,16 @@ type User struct {
DeleteReason *string DeleteReason *string
} }
func (u User) NumProviders() (numProviders int) {
if u.Discord != nil {
numProviders++
}
if u.Fediverse != nil {
numProviders++
}
return numProviders
}
// usernames must match this regex // usernames must match this regex
var usernameRegex = regexp.MustCompile(`^[\w-.]{2,40}$`) var usernameRegex = regexp.MustCompile(`^[\w-.]{2,40}$`)

View file

@ -222,6 +222,11 @@ func (s *Server) discordUnlink(w http.ResponseWriter, r *http.Request) error {
return server.APIError{Code: server.ErrNotLinked} return server.APIError{Code: server.ErrNotLinked}
} }
// cannot unlink last auth provider
if u.NumProviders() <= 1 {
return server.APIError{Code: server.ErrLastProvider}
}
err = u.UnlinkDiscord(ctx, s.DB) err = u.UnlinkDiscord(ctx, s.DB)
if err != nil { if err != nil {
return errors.Wrap(err, "updating user in db") return errors.Wrap(err, "updating user in db")

View file

@ -249,6 +249,11 @@ func (s *Server) mastodonUnlink(w http.ResponseWriter, r *http.Request) error {
return server.APIError{Code: server.ErrNotLinked} return server.APIError{Code: server.ErrNotLinked}
} }
// cannot unlink last auth provider
if u.NumProviders() <= 1 {
return server.APIError{Code: server.ErrLastProvider}
}
err = u.UnlinkFedi(ctx, s.DB) err = u.UnlinkFedi(ctx, s.DB)
if err != nil { if err != nil {
return errors.Wrap(err, "updating user in db") return errors.Wrap(err, "updating user in db")

View file

@ -96,6 +96,7 @@ const (
ErrUnsupportedInstance = 1013 // unsupported fediverse software ErrUnsupportedInstance = 1013 // unsupported fediverse software
ErrAlreadyLinked = 1014 // user already has linked account of the same type ErrAlreadyLinked = 1014 // user already has linked account of the same type
ErrNotLinked = 1015 // user already doesn't have a linked account ErrNotLinked = 1015 // user already doesn't have a linked account
ErrLastProvider = 1016 // unlinking provider would leave account with no authentication method
// User-related error codes // User-related error codes
ErrUserNotFound = 2001 ErrUserNotFound = 2001
@ -134,6 +135,7 @@ var errCodeMessages = map[int]string{
ErrUnsupportedInstance: "Unsupported instance software", ErrUnsupportedInstance: "Unsupported instance software",
ErrAlreadyLinked: "Your account is already linked to an account of this type", ErrAlreadyLinked: "Your account is already linked to an account of this type",
ErrNotLinked: "Your account is already not linked to an account of this type", ErrNotLinked: "Your account is already not linked to an account of this type",
ErrLastProvider: "This is your account's only authentication provider",
ErrUserNotFound: "User not found", ErrUserNotFound: "User not found",
@ -169,6 +171,7 @@ var errCodeStatuses = map[int]int{
ErrUnsupportedInstance: http.StatusBadRequest, ErrUnsupportedInstance: http.StatusBadRequest,
ErrAlreadyLinked: http.StatusBadRequest, ErrAlreadyLinked: http.StatusBadRequest,
ErrNotLinked: http.StatusBadRequest, ErrNotLinked: http.StatusBadRequest,
ErrLastProvider: http.StatusBadRequest,
ErrUserNotFound: http.StatusNotFound, ErrUserNotFound: http.StatusNotFound,

View file

@ -109,6 +109,7 @@ export enum ErrorCode {
UnsupportedInstance = 1013, UnsupportedInstance = 1013,
AlreadyLinked = 1014, AlreadyLinked = 1014,
NotLinked = 1015, NotLinked = 1015,
LastProvider = 1016,
UserNotFound = 2001, UserNotFound = 2001,