A fork of the Cocoon PDS but being made more distributed.
11

Configure Feed

Select the types of activity you want to include in your feed.

cleanup some error returns

Hailey (Jul 12, 2025, 12:21 PM -0700) b1cfabc8 5863a209

+31 -20
+13
internal/helpers/helpers.go
··· 7 7 "math/rand" 8 8 "net/url" 9 9 10 + "github.com/Azure/go-autorest/autorest/to" 10 11 "github.com/labstack/echo/v4" 11 12 "github.com/lestrrat-go/jwx/v2/jwk" 12 13 ) ··· 29 30 msg += ". " + *suffix 30 31 } 31 32 return genericError(e, 400, msg) 33 + } 34 + 35 + func InvalidTokenError(e echo.Context) error { 36 + return InputError(e, to.StringPtr("InvalidToken")) 37 + } 38 + 39 + func ExpiredTokenError(e echo.Context) error { 40 + // WARN: See https://github.com/bluesky-social/atproto/discussions/3319 41 + return e.JSON(400, map[string]string{ 42 + "error": "ExpiredToken", 43 + "message": "*", 44 + }) 32 45 } 33 46 34 47 func genericError(e echo.Context, code int, msg string) error {
+2 -2
server/handle_server_confirm_email.go
··· 28 28 } 29 29 30 30 if urepo.EmailVerificationCode == nil || urepo.EmailVerificationCodeExpiresAt == nil { 31 - return helpers.InputError(e, to.StringPtr("ExpiredToken")) 31 + return helpers.ExpiredTokenError(e) 32 32 } 33 33 34 34 if *urepo.EmailVerificationCode != req.Token { ··· 36 36 } 37 37 38 38 if time.Now().UTC().After(*urepo.EmailVerificationCodeExpiresAt) { 39 - return helpers.InputError(e, to.StringPtr("ExpiredToken")) 39 + return helpers.ExpiredTokenError(e) 40 40 } 41 41 42 42 now := time.Now().UTC()
+2 -2
server/handle_server_reset_password.go
··· 33 33 } 34 34 35 35 if *urepo.PasswordResetCode != req.Token { 36 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 36 + return helpers.InvalidTokenError(e) 37 37 } 38 38 39 39 if time.Now().UTC().After(*urepo.PasswordResetCodeExpiresAt) { 40 - return helpers.InputError(e, to.StringPtr("ExpiredToken")) 40 + return helpers.ExpiredTokenError(e) 41 41 } 42 42 43 43 hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), 10)
+3 -4
server/handle_server_update_email.go
··· 3 3 import ( 4 4 "time" 5 5 6 - "github.com/Azure/go-autorest/autorest/to" 7 6 "github.com/haileyok/cocoon/internal/helpers" 8 7 "github.com/haileyok/cocoon/models" 9 8 "github.com/labstack/echo/v4" ··· 29 28 } 30 29 31 30 if urepo.EmailUpdateCode == nil || urepo.EmailUpdateCodeExpiresAt == nil { 32 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 31 + return helpers.InvalidTokenError(e) 33 32 } 34 33 35 34 if *urepo.EmailUpdateCode != req.Token { 36 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 35 + return helpers.InvalidTokenError(e) 37 36 } 38 37 39 38 if time.Now().UTC().After(*urepo.EmailUpdateCodeExpiresAt) { 40 - return helpers.InputError(e, to.StringPtr("ExpiredToken")) 39 + return helpers.ExpiredTokenError(e) 41 40 } 42 41 43 42 if err := s.db.Exec("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 {
+11 -12
server/middleware.go
··· 54 54 token, _, err := new(jwt.Parser).ParseUnverified(tokenstr, jwt.MapClaims{}) 55 55 claims, ok := token.Claims.(jwt.MapClaims) 56 56 if !ok { 57 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 57 + return helpers.InvalidTokenError(e) 58 58 } 59 59 60 60 var did string ··· 93 93 }) 94 94 if err != nil { 95 95 s.logger.Error("error parsing jwt", "error", err) 96 - // NOTE: https://github.com/bluesky-social/atproto/discussions/3319 97 - return e.JSON(400, map[string]string{"error": "ExpiredToken", "message": "token has expired"}) 96 + return helpers.ExpiredTokenError(e) 98 97 } 99 98 100 99 if !token.Valid { 101 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 100 + return helpers.InvalidTokenError(e) 102 101 } 103 102 } else { 104 103 kpts := strings.Split(tokenstr, ".") ··· 143 142 scope, _ := claims["scope"].(string) 144 143 145 144 if isRefresh && scope != "com.atproto.refresh" { 146 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 145 + return helpers.InvalidTokenError(e) 147 146 } else if !hasLxm && !isRefresh && scope != "com.atproto.access" { 148 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 147 + return helpers.InvalidTokenError(e) 149 148 } 150 149 151 150 table := "tokens" ··· 160 159 var result Result 161 160 if err := s.db.Raw("SELECT EXISTS(SELECT 1 FROM "+table+" WHERE token = ?) AS found", nil, tokenstr).Scan(&result).Error; err != nil { 162 161 if err == gorm.ErrRecordNotFound { 163 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 162 + return helpers.InvalidTokenError(e) 164 163 } 165 164 166 165 s.logger.Error("error getting token from db", "error", err) ··· 168 167 } 169 168 170 169 if !result.Found { 171 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 170 + return helpers.InvalidTokenError(e) 172 171 } 173 172 } 174 173 ··· 179 178 } 180 179 181 180 if exp < float64(time.Now().UTC().Unix()) { 182 - return helpers.InputError(e, to.StringPtr("ExpiredToken")) 181 + return helpers.ExpiredTokenError(e) 183 182 } 184 183 185 184 if repo == nil { ··· 197 196 e.Set("token", tokenstr) 198 197 199 198 if err := next(e); err != nil { 200 - e.Error(err) 199 + return helpers.InvalidTokenError(e) 201 200 } 202 201 203 202 return nil ··· 241 240 } 242 241 243 242 if oauthToken.Token == "" { 244 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 243 + return helpers.InvalidTokenError(e) 245 244 } 246 245 247 246 if *oauthToken.Parameters.DpopJkt != proof.JKT { ··· 250 249 } 251 250 252 251 if time.Now().After(oauthToken.ExpiresAt) { 253 - return e.JSON(400, map[string]string{"error": "ExpiredToken", "message": "token has expired"}) 252 + return helpers.ExpiredTokenError(e) 254 253 } 255 254 256 255 repo, err := s.getRepoActorByDid(oauthToken.Sub)