Vow, uncensorable PDS written in Go

build: bump to go 1.26

+119 -149
+2 -2
Dockerfile
··· 1 1 ### Compile stage 2 - FROM golang:1.25.1-bookworm AS build-env 2 + FROM golang:1.26.1-bookworm AS build-env 3 3 4 4 ADD . /dockerbuild 5 5 WORKDIR /dockerbuild ··· 22 22 23 23 LABEL org.opencontainers.image.source=https://pkg.rbrt.fr/vow 24 24 LABEL org.opencontainers.image.description="Vow ATProto PDS" 25 - LABEL org.opencontainers.image.licenses=MIT 25 + LABEL org.opencontainers.image.licenses=MIT
+1 -3
go.mod
··· 1 1 module pkg.rbrt.fr/vow 2 2 3 - go 1.25 3 + go 1.26.1 4 4 5 5 require ( 6 - github.com/Azure/go-autorest/autorest/to v0.4.1 7 6 github.com/bluesky-social/indigo v0.0.0-20260203235305-a86f3ae1f8ec 8 7 github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 9 8 github.com/domodwyer/mailyak/v3 v3.6.2 ··· 36 35 ) 37 36 38 37 require ( 39 - github.com/Azure/go-autorest v14.2.0+incompatible // indirect 40 38 github.com/RussellLuo/slidingwindow v0.0.0-20200528002341-535bb99d338b // indirect 41 39 github.com/beorn7/perks v1.0.1 // indirect 42 40 github.com/cespare/xxhash/v2 v2.3.0 // indirect
-4
go.sum
··· 1 - github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= 2 - github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= 3 - github.com/Azure/go-autorest/autorest/to v0.4.1 h1:CxNHBqdzTr7rLtdrtb5CMjJcDut+WNGCVv7OmS5+lTc= 4 - github.com/Azure/go-autorest/autorest/to v0.4.1/go.mod h1:EtaofgU4zmtvn1zT2ARsjRFdq9vXx0YWtmElwL+GZ9M= 5 1 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 6 2 github.com/RussellLuo/slidingwindow v0.0.0-20200528002341-535bb99d338b h1:5/++qT1/z812ZqBvqQt6ToRswSuPZ/B33m6xVHRzADU= 7 3 github.com/RussellLuo/slidingwindow v0.0.0-20200528002341-535bb99d338b/go.mod h1:4+EPqMRApwwE/6yo6CxiHoSnBzjRr3jsqer7frxP8y4=
+1 -2
models/models.go
··· 4 4 "context" 5 5 "time" 6 6 7 - "github.com/Azure/go-autorest/autorest/to" 8 7 "github.com/bluesky-social/indigo/atproto/atcrypto" 9 8 ) 10 9 ··· 58 57 func (r *Repo) Status() *string { 59 58 var status *string 60 59 if r.Deactivated { 61 - status = to.StringPtr("deactivated") 60 + status = new("deactivated") 62 61 } 63 62 return status 64 63 }
+1 -2
server/handle_identity_sign_plc_operation.go
··· 7 7 "strings" 8 8 "time" 9 9 10 - "github.com/Azure/go-autorest/autorest/to" 11 10 "github.com/bluesky-social/indigo/atproto/atcrypto" 12 11 "pkg.rbrt.fr/vow/identity" 13 12 "pkg.rbrt.fr/vow/internal/helpers" ··· 45 44 } 46 45 47 46 if repo.PlcOperationCode == nil || repo.PlcOperationCodeExpiresAt == nil { 48 - helpers.InputError(w, to.StringPtr("InvalidToken")) 47 + helpers.InputError(w, new("InvalidToken")) 49 48 return 50 49 } 51 50
+1 -2
server/handle_identity_update_handle.go
··· 7 7 "strings" 8 8 "time" 9 9 10 - "github.com/Azure/go-autorest/autorest/to" 11 10 "github.com/bluesky-social/indigo/api/atproto" 12 11 "github.com/bluesky-social/indigo/atproto/atcrypto" 13 12 "github.com/bluesky-social/indigo/events" ··· 97 96 if err := s.evtman.AddEvent(context.TODO(), &events.XRPCStreamEvent{ 98 97 RepoIdentity: &atproto.SyncSubscribeRepos_Identity{ 99 98 Did: repo.Repo.Did, 100 - Handle: to.StringPtr(req.Handle), 99 + Handle: new(req.Handle), 101 100 Seq: time.Now().UnixMicro(), // TODO: no 102 101 Time: time.Now().Format(util.ISO8601), 103 102 },
+15 -16
server/handle_oauth_authorize.go
··· 7 7 "strings" 8 8 "time" 9 9 10 - "github.com/Azure/go-autorest/autorest/to" 11 10 "pkg.rbrt.fr/vow/internal/helpers" 12 11 "pkg.rbrt.fr/vow/oauth" 13 12 "pkg.rbrt.fr/vow/oauth/constants" ··· 30 29 id, err := oauth.DecodeRequestUri(requestUri) 31 30 if err != nil { 32 31 logger.Error("no request uri found in input", "url", r.URL.String()) 33 - helpers.InputError(w, to.StringPtr("no request uri")) 32 + helpers.InputError(w, new("no request uri")) 34 33 return 35 34 } 36 35 reqId = id ··· 46 45 CodeChallengeMethod: r.URL.Query().Get("code_challenge_method"), 47 46 } 48 47 if v := r.URL.Query().Get("code_challenge"); v != "" { 49 - parRequest.CodeChallenge = to.StringPtr(v) 48 + parRequest.CodeChallenge = new(v) 50 49 } 51 50 if v := r.URL.Query().Get("login_hint"); v != "" { 52 - parRequest.LoginHint = to.StringPtr(v) 51 + parRequest.LoginHint = new(v) 53 52 } 54 53 if v := r.URL.Query().Get("dpop_jkt"); v != "" { 55 - parRequest.DpopJkt = to.StringPtr(v) 54 + parRequest.DpopJkt = new(v) 56 55 } 57 56 if v := r.URL.Query().Get("response_mode"); v != "" { 58 - parRequest.ResponseMode = to.StringPtr(v) 57 + parRequest.ResponseMode = new(v) 59 58 } 60 59 61 60 if err := s.validator.Struct(parRequest); err != nil { ··· 71 70 } 72 71 return 73 72 } 74 - helpers.InputError(w, to.StringPtr("no request uri and invalid parameters")) 73 + helpers.InputError(w, new("no request uri and invalid parameters")) 75 74 return 76 75 } 77 76 ··· 80 79 }) 81 80 if err != nil { 82 81 s.logger.Error("error authenticating client in standard request", "client_id", parRequest.ClientID, "error", err) 83 - helpers.ServerError(w, to.StringPtr(err.Error())) 82 + helpers.ServerError(w, new(err.Error())) 84 83 return 85 84 } 86 85 ··· 121 120 122 121 var req provider.OauthAuthorizationRequest 123 122 if err := s.db.Raw(ctx, "SELECT * FROM oauth_authorization_requests WHERE request_id = ?", nil, reqId).Scan(&req).Error; err != nil { 124 - helpers.ServerError(w, to.StringPtr(err.Error())) 123 + helpers.ServerError(w, new(err.Error())) 125 124 return 126 125 } 127 126 128 127 clientId := r.URL.Query().Get("client_id") 129 128 if clientId != req.ClientId { 130 - helpers.InputError(w, to.StringPtr("client id does not match the client id for the supplied request")) 129 + helpers.InputError(w, new("client id does not match the client id for the supplied request")) 131 130 return 132 131 } 133 132 134 133 client, err := s.oauthProvider.ClientManager.GetClient(r.Context(), req.ClientId) 135 134 if err != nil { 136 - helpers.ServerError(w, to.StringPtr(err.Error())) 135 + helpers.ServerError(w, new(err.Error())) 137 136 return 138 137 } 139 138 ··· 181 180 182 181 reqId, err := oauth.DecodeRequestUri(req.RequestUri) 183 182 if err != nil { 184 - helpers.InputError(w, to.StringPtr(err.Error())) 183 + helpers.InputError(w, new(err.Error())) 185 184 return 186 185 } 187 186 188 187 var authReq provider.OauthAuthorizationRequest 189 188 if err := s.db.Raw(ctx, "SELECT * FROM oauth_authorization_requests WHERE request_id = ?", nil, reqId).Scan(&authReq).Error; err != nil { 190 - helpers.ServerError(w, to.StringPtr(err.Error())) 189 + helpers.ServerError(w, new(err.Error())) 191 190 return 192 191 } 193 192 194 193 client, err := s.oauthProvider.ClientManager.GetClient(r.Context(), authReq.ClientId) 195 194 if err != nil { 196 - helpers.ServerError(w, to.StringPtr(err.Error())) 195 + helpers.ServerError(w, new(err.Error())) 197 196 return 198 197 } 199 198 ··· 204 203 } 205 204 206 205 if time.Now().After(authReq.ExpiresAt) { 207 - helpers.InputError(w, to.StringPtr("the request has expired")) 206 + helpers.InputError(w, new("the request has expired")) 208 207 return 209 208 } 210 209 211 210 if authReq.Sub != nil || authReq.Code != nil { 212 - helpers.InputError(w, to.StringPtr("this request was already authorized")) 211 + helpers.InputError(w, new("this request was already authorized")) 213 212 return 214 213 } 215 214
+8 -9
server/handle_oauth_par.go
··· 5 5 "net/http" 6 6 "time" 7 7 8 - "github.com/Azure/go-autorest/autorest/to" 9 8 "pkg.rbrt.fr/vow/internal/helpers" 10 9 "pkg.rbrt.fr/vow/oauth" 11 10 "pkg.rbrt.fr/vow/oauth/constants" ··· 39 38 CodeChallengeMethod: r.FormValue("code_challenge_method"), 40 39 } 41 40 if v := r.FormValue("code_challenge"); v != "" { 42 - parRequest.CodeChallenge = to.StringPtr(v) 41 + parRequest.CodeChallenge = new(v) 43 42 } 44 43 if v := r.FormValue("login_hint"); v != "" { 45 - parRequest.LoginHint = to.StringPtr(v) 44 + parRequest.LoginHint = new(v) 46 45 } 47 46 if v := r.FormValue("dpop_jkt"); v != "" { 48 - parRequest.DpopJkt = to.StringPtr(v) 47 + parRequest.DpopJkt = new(v) 49 48 } 50 49 if v := r.FormValue("response_mode"); v != "" { 51 - parRequest.ResponseMode = to.StringPtr(v) 50 + parRequest.ResponseMode = new(v) 52 51 } 53 52 if v := r.FormValue("client_assertion_type"); v != "" { 54 - parRequest.ClientAssertionType = to.StringPtr(v) 53 + parRequest.ClientAssertionType = new(v) 55 54 } 56 55 if v := r.FormValue("client_assertion"); v != "" { 57 - parRequest.ClientAssertion = to.StringPtr(v) 56 + parRequest.ClientAssertion = new(v) 58 57 } 59 58 60 59 if err := s.validator.Struct(parRequest); err != nil { ··· 90 89 }) 91 90 if err != nil { 92 91 logger.Error("error authenticating client", "client_id", parRequest.ClientID, "error", err) 93 - helpers.InputError(w, to.StringPtr(err.Error())) 92 + helpers.InputError(w, new(err.Error())) 94 93 return 95 94 } 96 95 97 96 if parRequest.DpopJkt == nil { 98 97 if client.Metadata.DpopBoundAccessTokens { 99 - parRequest.DpopJkt = to.StringPtr(dpopProof.JKT) 98 + parRequest.DpopJkt = new(dpopProof.JKT) 100 99 } 101 100 } else { 102 101 if !client.Metadata.DpopBoundAccessTokens {
+26 -27
server/handle_oauth_token.go
··· 10 10 "slices" 11 11 "time" 12 12 13 - "github.com/Azure/go-autorest/autorest/to" 14 13 "github.com/golang-jwt/jwt/v4" 15 14 "pkg.rbrt.fr/vow/internal/helpers" 16 15 "pkg.rbrt.fr/vow/oauth" ··· 51 50 GrantType: r.FormValue("grant_type"), 52 51 } 53 52 if v := r.FormValue("code"); v != "" { 54 - req.Code = to.StringPtr(v) 53 + req.Code = new(v) 55 54 } 56 55 if v := r.FormValue("code_verifier"); v != "" { 57 - req.CodeVerifier = to.StringPtr(v) 56 + req.CodeVerifier = new(v) 58 57 } 59 58 if v := r.FormValue("redirect_uri"); v != "" { 60 - req.RedirectURI = to.StringPtr(v) 59 + req.RedirectURI = new(v) 61 60 } 62 61 if v := r.FormValue("refresh_token"); v != "" { 63 - req.RefreshToken = to.StringPtr(v) 62 + req.RefreshToken = new(v) 64 63 } 65 64 if v := r.FormValue("client_assertion_type"); v != "" { 66 - req.ClientAssertionType = to.StringPtr(v) 65 + req.ClientAssertionType = new(v) 67 66 } 68 67 if v := r.FormValue("client_assertion"); v != "" { 69 - req.ClientAssertion = to.StringPtr(v) 68 + req.ClientAssertion = new(v) 70 69 } 71 70 req.AuthenticateClientRequestBase = provider.AuthenticateClientRequestBase{ 72 71 ClientID: r.FormValue("client_id"), ··· 97 96 }) 98 97 if err != nil { 99 98 logger.Error("error authenticating client", "client_id", req.ClientID, "error", err) 100 - helpers.InputError(w, to.StringPtr(err.Error())) 99 + helpers.InputError(w, new(err.Error())) 101 100 return 102 101 } 103 102 104 103 // TODO: this should come from an oauth provider config 105 104 if !slices.Contains([]string{"authorization_code", "refresh_token"}, req.GrantType) { 106 - helpers.InputError(w, to.StringPtr(fmt.Sprintf(`"%s" grant type is not supported by the server`, req.GrantType))) 105 + helpers.InputError(w, new(fmt.Sprintf(`"%s" grant type is not supported by the server`, req.GrantType))) 107 106 return 108 107 } 109 108 110 109 if !slices.Contains(client.Metadata.GrantTypes, req.GrantType) { 111 - helpers.InputError(w, to.StringPtr(fmt.Sprintf(`"%s" grant type is not supported by the client`, req.GrantType))) 110 + helpers.InputError(w, new(fmt.Sprintf(`"%s" grant type is not supported by the client`, req.GrantType))) 112 111 return 113 112 } 114 113 115 114 if req.GrantType == "authorization_code" { 116 115 if req.Code == nil { 117 - helpers.InputError(w, to.StringPtr(`"code" is required"`)) 116 + helpers.InputError(w, new(`"code" is required"`)) 118 117 return 119 118 } 120 119 ··· 127 126 } 128 127 129 128 if req.RedirectURI == nil || *req.RedirectURI != authReq.Parameters.RedirectURI { 130 - helpers.InputError(w, to.StringPtr(`"redirect_uri" mismatch`)) 129 + helpers.InputError(w, new(`"redirect_uri" mismatch`)) 131 130 return 132 131 } 133 132 134 133 if authReq.Parameters.CodeChallenge != nil { 135 134 if req.CodeVerifier == nil { 136 - helpers.InputError(w, to.StringPtr(`"code_verifier" is required`)) 135 + helpers.InputError(w, new(`"code_verifier" is required`)) 137 136 return 138 137 } 139 138 140 139 if len(*req.CodeVerifier) < 43 { 141 - helpers.InputError(w, to.StringPtr(`"code_verifier" is too short`)) 140 + helpers.InputError(w, new(`"code_verifier" is too short`)) 142 141 return 143 142 } 144 143 145 144 switch authReq.Parameters.CodeChallengeMethod { 146 145 case "", "plain": 147 146 if authReq.Parameters.CodeChallenge != req.CodeVerifier { 148 - helpers.InputError(w, to.StringPtr("invalid code_verifier")) 147 + helpers.InputError(w, new("invalid code_verifier")) 149 148 return 150 149 } 151 150 case "S256": ··· 161 160 compdChal := h.Sum(nil) 162 161 163 162 if !bytes.Equal(inputChal, compdChal) { 164 - helpers.InputError(w, to.StringPtr("invalid code_verifier")) 163 + helpers.InputError(w, new("invalid code_verifier")) 165 164 return 166 165 } 167 166 default: 168 - helpers.InputError(w, to.StringPtr("unsupported code_challenge_method "+authReq.Parameters.CodeChallengeMethod)) 167 + helpers.InputError(w, new("unsupported code_challenge_method "+authReq.Parameters.CodeChallengeMethod)) 169 168 return 170 169 } 171 170 } else if req.CodeVerifier != nil { 172 - helpers.InputError(w, to.StringPtr("code_challenge parameter wasn't provided")) 171 + helpers.InputError(w, new("code_challenge parameter wasn't provided")) 173 172 return 174 173 } 175 174 176 175 repo, err := s.getRepoActorByDid(ctx, *authReq.Sub) 177 176 if err != nil { 178 - helpers.InputError(w, to.StringPtr("unable to find actor")) 177 + helpers.InputError(w, new("unable to find actor")) 179 178 return 180 179 } 181 180 ··· 242 241 243 242 if req.GrantType == "refresh_token" { 244 243 if req.RefreshToken == nil { 245 - helpers.InputError(w, to.StringPtr(`"refresh_token" is required`)) 244 + helpers.InputError(w, new(`"refresh_token" is required`)) 246 245 return 247 246 } 248 247 ··· 254 253 } 255 254 256 255 if client.Metadata.ClientID != oauthToken.ClientId { 257 - helpers.InputError(w, to.StringPtr(`"client_id" mismatch`)) 256 + helpers.InputError(w, new(`"client_id" mismatch`)) 258 257 return 259 258 } 260 259 261 260 if clientAuth.Method != oauthToken.ClientAuth.Method { 262 - helpers.InputError(w, to.StringPtr(`"client authentication method mismatch`)) 261 + helpers.InputError(w, new(`"client authentication method mismatch`)) 263 262 return 264 263 } 265 264 266 265 if *oauthToken.Parameters.DpopJkt != proof.JKT { 267 - helpers.InputError(w, to.StringPtr("dpop proof does not match expected jkt")) 266 + helpers.InputError(w, new("dpop proof does not match expected jkt")) 268 267 return 269 268 } 270 269 271 270 ageRes := oauth.GetSessionAgeFromToken(oauthToken) 272 271 273 272 if ageRes.SessionExpired { 274 - helpers.InputError(w, to.StringPtr("Session expired")) 273 + helpers.InputError(w, new("Session expired")) 275 274 return 276 275 } 277 276 278 277 if ageRes.RefreshExpired { 279 - helpers.InputError(w, to.StringPtr("Refresh token expired")) 278 + helpers.InputError(w, new("Refresh token expired")) 280 279 return 281 280 } 282 281 283 282 if client.Metadata.DpopBoundAccessTokens && oauthToken.Parameters.DpopJkt == nil { 284 283 // why? ref impl 285 - helpers.InputError(w, to.StringPtr("dpop jkt is required for dpop bound access tokens")) 284 + helpers.InputError(w, new("dpop jkt is required for dpop bound access tokens")) 286 285 return 287 286 } 288 287 ··· 336 335 return 337 336 } 338 337 339 - helpers.InputError(w, to.StringPtr(fmt.Sprintf(`grant type "%s" is not supported`, req.GrantType))) 338 + helpers.InputError(w, new(fmt.Sprintf(`grant type "%s" is not supported`, req.GrantType))) 340 339 }
+1 -2
server/handle_proxy_get_feed.go
··· 4 4 "context" 5 5 "net/http" 6 6 7 - "github.com/Azure/go-autorest/autorest/to" 8 7 "github.com/bluesky-social/indigo/api/atproto" 9 8 "github.com/bluesky-social/indigo/api/bsky" 10 9 "github.com/bluesky-social/indigo/atproto/syntax" ··· 15 14 func (s *Server) handleProxyBskyFeedGetFeed(w http.ResponseWriter, r *http.Request) { 16 15 feedUri, err := syntax.ParseATURI(r.URL.Query().Get("feed")) 17 16 if err != nil { 18 - helpers.InputError(w, to.StringPtr("invalid feed uri")) 17 + helpers.InputError(w, new("invalid feed uri")) 19 18 return 20 19 } 21 20
+1 -2
server/handle_repo_describe_repo.go
··· 4 4 "net/http" 5 5 "strings" 6 6 7 - "github.com/Azure/go-autorest/autorest/to" 8 7 "gorm.io/gorm" 9 8 "pkg.rbrt.fr/vow/identity" 10 9 "pkg.rbrt.fr/vow/internal/helpers" ··· 27 26 repo, err := s.getRepoActorByDid(ctx, did) 28 27 if err != nil { 29 28 if err == gorm.ErrRecordNotFound { 30 - helpers.InputError(w, to.StringPtr("RepoNotFound")) 29 + helpers.InputError(w, new("RepoNotFound")) 31 30 return 32 31 } 33 32
+2 -3
server/handle_repo_list_records.go
··· 4 4 "net/http" 5 5 "strconv" 6 6 7 - "github.com/Azure/go-autorest/autorest/to" 8 7 "github.com/bluesky-social/indigo/atproto/atdata" 9 8 "github.com/bluesky-social/indigo/atproto/syntax" 10 9 "pkg.rbrt.fr/vow/internal/helpers" ··· 87 86 if _, err := syntax.ParseDID(did); err != nil { 88 87 actor, err := s.getActorByHandle(ctx, req.Repo) 89 88 if err != nil { 90 - helpers.InputError(w, to.StringPtr("RepoNotFound")) 89 + helpers.InputError(w, new("RepoNotFound")) 91 90 return 92 91 } 93 92 did = actor.Did ··· 124 123 125 124 var newcursor *string 126 125 if len(records) == limit { 127 - newcursor = to.StringPtr(records[len(records)-1].CreatedAt) 126 + newcursor = new(records[len(records)-1].CreatedAt) 128 127 } 129 128 130 129 s.writeJSON(w, 200, ComAtprotoRepoListRecordsResponse{
+1 -2
server/handle_server_confirm_email.go
··· 5 5 "net/http" 6 6 "time" 7 7 8 - "github.com/Azure/go-autorest/autorest/to" 9 8 "pkg.rbrt.fr/vow/internal/helpers" 10 9 "pkg.rbrt.fr/vow/models" 11 10 ) ··· 39 38 } 40 39 41 40 if *urepo.EmailVerificationCode != req.Token { 42 - helpers.InputError(w, to.StringPtr("InvalidToken")) 41 + helpers.InputError(w, new("InvalidToken")) 43 42 return 44 43 } 45 44
+15 -16
server/handle_server_create_account.go
··· 9 9 "strings" 10 10 "time" 11 11 12 - "github.com/Azure/go-autorest/autorest/to" 13 12 "github.com/bluesky-social/indigo/api/atproto" 14 13 "github.com/bluesky-social/indigo/atproto/atcrypto" 15 14 atp "github.com/bluesky-social/indigo/atproto/repo" ··· 59 58 var verr ValidationError 60 59 if errors.As(err, &verr) { 61 60 if verr.Field == "Email" { 62 - helpers.InputError(w, to.StringPtr("InvalidEmail")) 61 + helpers.InputError(w, new("InvalidEmail")) 63 62 return 64 63 } 65 64 66 65 if verr.Field == "Handle" { 67 - helpers.InputError(w, to.StringPtr("InvalidHandle")) 66 + helpers.InputError(w, new("InvalidHandle")) 68 67 return 69 68 } 70 69 71 70 if verr.Field == "Password" { 72 - helpers.InputError(w, to.StringPtr("InvalidPassword")) 71 + helpers.InputError(w, new("InvalidPassword")) 73 72 return 74 73 } 75 74 76 75 if verr.Field == "InviteCode" { 77 - helpers.InputError(w, to.StringPtr("InvalidInviteCode")) 76 + helpers.InputError(w, new("InvalidInviteCode")) 78 77 return 79 78 } 80 79 } ··· 86 85 87 86 token := strings.TrimSpace(strings.Replace(r.Header.Get("authorization"), "Bearer ", "", 1)) 88 87 if token == "" { 89 - helpers.UnauthorizedError(w, to.StringPtr("must authenticate to use an existing did")) 88 + helpers.UnauthorizedError(w, new("must authenticate to use an existing did")) 90 89 return 91 90 } 92 91 authDid, err := s.validateServiceAuth(r.Context(), token, "com.atproto.server.createAccount") 93 92 94 93 if err != nil { 95 94 logger.Warn("error validating authorization token", "endpoint", "com.atproto.server.createAccount", "error", err) 96 - helpers.UnauthorizedError(w, to.StringPtr("invalid authorization token")) 95 + helpers.UnauthorizedError(w, new("invalid authorization token")) 97 96 return 98 97 } 99 98 100 99 if authDid != signupDid { 101 - helpers.ForbiddenError(w, to.StringPtr("auth did did not match signup did")) 100 + helpers.ForbiddenError(w, new("auth did did not match signup did")) 102 101 return 103 102 } 104 103 } ··· 111 110 return 112 111 } 113 112 if err == nil && actor.Did != signupDid { 114 - helpers.InputError(w, to.StringPtr("HandleNotAvailable")) 113 + helpers.InputError(w, new("HandleNotAvailable")) 115 114 return 116 115 } 117 116 118 117 if did, err := s.passport.ResolveHandle(r.Context(), request.Handle); err == nil && did != signupDid { 119 - helpers.InputError(w, to.StringPtr("HandleNotAvailable")) 118 + helpers.InputError(w, new("HandleNotAvailable")) 120 119 return 121 120 } 122 121 123 122 var ic models.InviteCode 124 123 if s.config.RequireInvite { 125 124 if strings.TrimSpace(request.InviteCode) == "" { 126 - helpers.InputError(w, to.StringPtr("InvalidInviteCode")) 125 + helpers.InputError(w, new("InvalidInviteCode")) 127 126 return 128 127 } 129 128 130 129 if err := s.db.Raw(ctx, "SELECT * FROM invite_codes WHERE code = ?", nil, request.InviteCode).Scan(&ic).Error; err != nil { 131 130 if err == gorm.ErrRecordNotFound { 132 - helpers.InputError(w, to.StringPtr("InvalidInviteCode")) 131 + helpers.InputError(w, new("InvalidInviteCode")) 133 132 return 134 133 } 135 134 logger.Error("error getting invite code from db", "error", err) ··· 138 137 } 139 138 140 139 if ic.RemainingUseCount < 1 { 141 - helpers.InputError(w, to.StringPtr("InvalidInviteCode")) 140 + helpers.InputError(w, new("InvalidInviteCode")) 142 141 return 143 142 } 144 143 } ··· 151 150 return 152 151 } 153 152 if err == nil && existingRepo.Did != signupDid { 154 - helpers.InputError(w, to.StringPtr("EmailNotAvailable")) 153 + helpers.InputError(w, new("EmailNotAvailable")) 155 154 return 156 155 } 157 156 ··· 215 214 Did: signupDid, 216 215 CreatedAt: time.Now(), 217 216 Email: request.Email, 218 - EmailVerificationCode: to.StringPtr(fmt.Sprintf("%s-%s", helpers.RandomVarchar(6), helpers.RandomVarchar(6))), 217 + EmailVerificationCode: new(fmt.Sprintf("%s-%s", helpers.RandomVarchar(6), helpers.RandomVarchar(6))), 219 218 Password: string(hashed), 220 219 SigningKey: k.Bytes(), 221 220 } ··· 272 271 if err := s.evtman.AddEvent(context.TODO(), &events.XRPCStreamEvent{ 273 272 RepoIdentity: &atproto.SyncSubscribeRepos_Identity{ 274 273 Did: urepo.Did, 275 - Handle: to.StringPtr(request.Handle), 274 + Handle: new(request.Handle), 276 275 Seq: time.Now().UnixMicro(), // TODO: no 277 276 Time: time.Now().Format(util.ISO8601), 278 277 },
+2 -3
server/handle_server_create_invite_codes.go
··· 4 4 "encoding/json" 5 5 "net/http" 6 6 7 - "github.com/Azure/go-autorest/autorest/to" 8 7 "github.com/google/uuid" 9 8 "pkg.rbrt.fr/vow/internal/helpers" 10 9 "pkg.rbrt.fr/vow/models" ··· 41 40 } 42 41 43 42 if req.CodeCount == nil { 44 - req.CodeCount = to.IntPtr(1) 43 + req.CodeCount = new(1) 45 44 } 46 45 47 46 if req.ForAccounts == nil { 48 - req.ForAccounts = to.StringSlicePtr([]string{"admin"}) 47 + req.ForAccounts = new([]string{"admin"}) 49 48 } 50 49 51 50 codes := make([]ComAtprotoServerCreateInviteCodesItem, 0, len(*req.ForAccounts))
+8 -9
server/handle_server_create_session.go
··· 9 9 "strings" 10 10 "time" 11 11 12 - "github.com/Azure/go-autorest/autorest/to" 13 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 + "golang.org/x/crypto/bcrypt" 14 + "gorm.io/gorm" 14 15 "pkg.rbrt.fr/vow/internal/helpers" 15 16 "pkg.rbrt.fr/vow/models" 16 - "golang.org/x/crypto/bcrypt" 17 - "gorm.io/gorm" 18 17 ) 19 18 20 19 type ComAtprotoServerCreateSessionRequest struct { ··· 50 49 var verr ValidationError 51 50 if errors.As(err, &verr) { 52 51 if verr.Field == "Identifier" { 53 - helpers.InputError(w, to.StringPtr("InvalidRequest")) 52 + helpers.InputError(w, new("InvalidRequest")) 54 53 return 55 54 } 56 55 57 56 if verr.Field == "Password" { 58 - helpers.InputError(w, to.StringPtr("InvalidRequest")) 57 + helpers.InputError(w, new("InvalidRequest")) 59 58 return 60 59 } 61 60 } ··· 84 83 85 84 if err != nil { 86 85 if err == gorm.ErrRecordNotFound { 87 - helpers.InputError(w, to.StringPtr("InvalidRequest")) 86 + helpers.InputError(w, new("InvalidRequest")) 88 87 return 89 88 } 90 89 ··· 97 96 if err != bcrypt.ErrMismatchedHashAndPassword { 98 97 logger.Error("error comparing hash and password", "error", err) 99 98 } 100 - helpers.InputError(w, to.StringPtr("InvalidRequest")) 99 + helpers.InputError(w, new("InvalidRequest")) 101 100 return 102 101 } 103 102 ··· 110 109 return 111 110 } 112 111 113 - helpers.InputError(w, to.StringPtr("AuthFactorTokenRequired")) 112 + helpers.InputError(w, new("AuthFactorTokenRequired")) 114 113 return 115 114 } 116 115 ··· 124 123 return 125 124 } 126 125 127 - helpers.InputError(w, to.StringPtr("AuthFactorTokenRequired")) 126 + helpers.InputError(w, new("AuthFactorTokenRequired")) 128 127 return 129 128 } 130 129
+1 -2
server/handle_server_deactivate_account.go
··· 5 5 "net/http" 6 6 "time" 7 7 8 - "github.com/Azure/go-autorest/autorest/to" 9 8 "github.com/bluesky-social/indigo/api/atproto" 10 9 "github.com/bluesky-social/indigo/events" 11 10 "github.com/bluesky-social/indigo/util" ··· 34 33 RepoAccount: &atproto.SyncSubscribeRepos_Account{ 35 34 Active: false, 36 35 Did: urepo.Repo.Did, 37 - Status: to.StringPtr("deactivated"), 36 + Status: new("deactivated"), 38 37 Seq: time.Now().UnixMicro(), // TODO: bad puppy 39 38 Time: time.Now().Format(util.ISO8601), 40 39 },
+1 -2
server/handle_server_delete_account.go
··· 6 6 "net/http" 7 7 "time" 8 8 9 - "github.com/Azure/go-autorest/autorest/to" 10 9 "github.com/bluesky-social/indigo/api/atproto" 11 10 "github.com/bluesky-social/indigo/events" 12 11 "github.com/bluesky-social/indigo/util" ··· 159 158 RepoAccount: &atproto.SyncSubscribeRepos_Account{ 160 159 Active: false, 161 160 Did: req.Did, 162 - Status: to.StringPtr("deleted"), 161 + Status: new("deleted"), 163 162 Seq: time.Now().UnixMicro(), 164 163 Time: time.Now().Format(util.ISO8601), 165 164 },
+3 -4
server/handle_server_get_service_auth.go
··· 10 10 "strings" 11 11 "time" 12 12 13 - "github.com/Azure/go-autorest/autorest/to" 14 13 "github.com/google/uuid" 14 + secp256k1secec "gitlab.com/yawning/secp256k1-voi/secec" 15 15 "pkg.rbrt.fr/vow/internal/helpers" 16 16 "pkg.rbrt.fr/vow/models" 17 - secp256k1secec "gitlab.com/yawning/secp256k1-voi/secec" 18 17 ) 19 18 20 19 type ServerGetServiceAuthRequest struct { ··· 49 48 } 50 49 51 50 if req.Lxm == "com.atproto.server.getServiceAuth" { 52 - helpers.InputError(w, to.StringPtr("may not generate auth tokens recursively")) 51 + helpers.InputError(w, new("may not generate auth tokens recursively")) 53 52 return 54 53 } 55 54 ··· 60 59 maxExp = now + 60 61 60 } 62 61 if exp > maxExp { 63 - helpers.InputError(w, to.StringPtr("expiration too big. smoller please")) 62 + helpers.InputError(w, new("expiration too big. smoller please")) 64 63 return 65 64 } 66 65
+1 -2
server/handle_server_request_email_confirmation.go
··· 5 5 "net/http" 6 6 "time" 7 7 8 - "github.com/Azure/go-autorest/autorest/to" 9 8 "pkg.rbrt.fr/vow/internal/helpers" 10 9 "pkg.rbrt.fr/vow/models" 11 10 ) ··· 17 16 urepo, _ := getContextValue[*models.RepoActor](r, contextKeyRepo) 18 17 19 18 if urepo.EmailConfirmedAt != nil { 20 - helpers.InputError(w, to.StringPtr("InvalidRequest")) 19 + helpers.InputError(w, new("InvalidRequest")) 21 20 return 22 21 } 23 22
+2 -3
server/handle_server_reset_password.go
··· 5 5 "net/http" 6 6 "time" 7 7 8 - "github.com/Azure/go-autorest/autorest/to" 8 + "golang.org/x/crypto/bcrypt" 9 9 "pkg.rbrt.fr/vow/internal/helpers" 10 10 "pkg.rbrt.fr/vow/models" 11 - "golang.org/x/crypto/bcrypt" 12 11 ) 13 12 14 13 type ComAtprotoServerResetPasswordRequest struct { ··· 35 34 } 36 35 37 36 if urepo.PasswordResetCode == nil || urepo.PasswordResetCodeExpiresAt == nil { 38 - helpers.InputError(w, to.StringPtr("InvalidToken")) 37 + helpers.InputError(w, new("InvalidToken")) 39 38 return 40 39 } 41 40
+3 -4
server/handle_server_resolve_handle.go
··· 2 2 3 3 import ( 4 4 "context" 5 - "pkg.rbrt.fr/vow/identity" 6 5 "net/http" 6 + "pkg.rbrt.fr/vow/identity" 7 7 8 - "github.com/Azure/go-autorest/autorest/to" 9 8 "github.com/bluesky-social/indigo/atproto/syntax" 10 9 "pkg.rbrt.fr/vow/internal/helpers" 11 10 ) ··· 20 19 handle := r.URL.Query().Get("handle") 21 20 22 21 if handle == "" { 23 - helpers.InputError(w, to.StringPtr("Handle must be supplied in request.")) 22 + helpers.InputError(w, new("Handle must be supplied in request.")) 24 23 return 25 24 } 26 25 27 26 parsed, err := syntax.ParseHandle(handle) 28 27 if err != nil { 29 - helpers.InputError(w, to.StringPtr("Invalid handle.")) 28 + helpers.InputError(w, new("Invalid handle.")) 30 29 return 31 30 } 32 31
+2 -3
server/handle_sync_get_blob.go
··· 6 6 "io" 7 7 "net/http" 8 8 9 - "github.com/Azure/go-autorest/autorest/to" 9 + "github.com/ipfs/go-cid" 10 10 "pkg.rbrt.fr/vow/internal/helpers" 11 11 "pkg.rbrt.fr/vow/models" 12 - "github.com/ipfs/go-cid" 13 12 ) 14 13 15 14 func (s *Server) handleSyncGetBlob(w http.ResponseWriter, r *http.Request) { ··· 44 43 status := urepo.Status() 45 44 if status != nil { 46 45 if *status == "deactivated" { 47 - helpers.InputError(w, to.StringPtr("RepoDeactivated")) 46 + helpers.InputError(w, new("RepoDeactivated")) 48 47 return 49 48 } 50 49 }
+2 -3
server/handle_sync_list_blobs.go
··· 4 4 "net/http" 5 5 "strconv" 6 6 7 - "github.com/Azure/go-autorest/autorest/to" 7 + "github.com/ipfs/go-cid" 8 8 "pkg.rbrt.fr/vow/internal/helpers" 9 9 "pkg.rbrt.fr/vow/models" 10 - "github.com/ipfs/go-cid" 11 10 ) 12 11 13 12 type ComAtprotoSyncListBlobsResponse struct { ··· 54 53 status := urepo.Status() 55 54 if status != nil { 56 55 if *status == "deactivated" { 57 - helpers.InputError(w, to.StringPtr("RepoDeactivated")) 56 + helpers.InputError(w, new("RepoDeactivated")) 58 57 return 59 58 } 60 59 }
+2 -3
server/handle_well_known.go
··· 5 5 "net/http" 6 6 "strings" 7 7 8 - "github.com/Azure/go-autorest/autorest/to" 9 8 "gorm.io/gorm" 10 9 "pkg.rbrt.fr/vow/internal/helpers" 11 10 ) ··· 72 71 73 72 host := r.Host 74 73 if host == "" { 75 - helpers.InputError(w, to.StringPtr("Invalid handle.")) 74 + helpers.InputError(w, new("Invalid handle.")) 76 75 return 77 76 } 78 77 ··· 123 122 Issuer: "https://" + s.config.Hostname, 124 123 RequestParameterSupported: true, 125 124 RequestUriParameterSupported: true, 126 - RequireRequestUriRegistration: to.BoolPtr(true), 125 + RequireRequestUriRegistration: new(true), 127 126 ScopesSupported: VowSupportedScopes, 128 127 SubjectTypesSupported: []string{"public"}, 129 128 ResponseTypesSupported: []string{"code"},
+6 -7
server/middleware.go
··· 10 10 "strings" 11 11 "time" 12 12 13 - "github.com/Azure/go-autorest/autorest/to" 14 13 "github.com/golang-jwt/jwt/v4" 14 + "gitlab.com/yawning/secp256k1-voi" 15 + secp256k1secec "gitlab.com/yawning/secp256k1-voi/secec" 16 + "gorm.io/gorm" 15 17 "pkg.rbrt.fr/vow/internal/helpers" 16 18 "pkg.rbrt.fr/vow/models" 17 19 "pkg.rbrt.fr/vow/oauth/dpop" 18 20 "pkg.rbrt.fr/vow/oauth/provider" 19 - "gitlab.com/yawning/secp256k1-voi" 20 - secp256k1secec "gitlab.com/yawning/secp256k1-voi/secec" 21 - "gorm.io/gorm" 22 21 ) 23 22 24 23 // context keys for values set by middleware ··· 48 47 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 49 48 username, password, ok := r.BasicAuth() 50 49 if !ok || username != "admin" || password != s.config.AdminPassword { 51 - helpers.InputError(w, to.StringPtr("Unauthorized")) 50 + helpers.InputError(w, new("Unauthorized")) 52 51 return 53 52 } 54 53 next.ServeHTTP(w, r) ··· 293 292 w.Header().Add("access-control-expose-headers", "DPoP-Nonce") 294 293 } 295 294 296 - proof, err := s.oauthProvider.DpopManager.CheckProof(r.Method, "https://"+s.config.Hostname+r.URL.String(), r.Header, to.StringPtr(accessToken)) 295 + proof, err := s.oauthProvider.DpopManager.CheckProof(r.Method, "https://"+s.config.Hostname+r.URL.String(), r.Header, new(accessToken)) 297 296 if err != nil { 298 297 if errors.Is(err, dpop.ErrUseDpopNonce) { 299 298 w.Header().Set("WWW-Authenticate", `DPoP error="use_dpop_nonce"`) ··· 322 321 323 322 if *oauthToken.Parameters.DpopJkt != proof.JKT { 324 323 logger.Error("jkt mismatch", "token", oauthToken.Parameters.DpopJkt, "proof", proof.JKT) 325 - helpers.InputError(w, to.StringPtr("dpop jkt mismatch")) 324 + helpers.InputError(w, new("dpop jkt mismatch")) 326 325 return 327 326 } 328 327
+11 -12
server/repo.go
··· 9 9 "sync" 10 10 "time" 11 11 12 - "github.com/Azure/go-autorest/autorest/to" 13 12 "github.com/bluesky-social/indigo/api/atproto" 14 13 "github.com/bluesky-social/indigo/atproto/atcrypto" 15 14 "github.com/bluesky-social/indigo/atproto/atdata" ··· 264 263 } 265 264 } else if op.Rkey == nil { 266 265 // creates that don't supply an rkey will have one generated for them 267 - op.Rkey = to.StringPtr(rm.clock.Next().String()) 266 + op.Rkey = new(rm.clock.Next().String()) 268 267 writes[i].Rkey = op.Rkey 269 268 } 270 269 ··· 320 319 }) 321 320 322 321 results = append(results, ApplyWriteResult{ 323 - Type: to.StringPtr(OpTypeCreate.String()), 324 - Uri: to.StringPtr("at://" + urepo.Did + "/" + op.Collection + "/" + *op.Rkey), 325 - Cid: to.StringPtr(nc.String()), 326 - ValidationStatus: to.StringPtr("valid"), // TODO: obviously this might not be true atm lol 322 + Type: new(OpTypeCreate.String()), 323 + Uri: new("at://" + urepo.Did + "/" + op.Collection + "/" + *op.Rkey), 324 + Cid: new(nc.String()), 325 + ValidationStatus: new("valid"), // TODO: obviously this might not be true atm lol 327 326 }) 328 327 case OpTypeDelete: 329 328 // try to find the old record in the database ··· 349 348 ops = append(ops, atpOp) 350 349 351 350 results = append(results, ApplyWriteResult{ 352 - Type: to.StringPtr(OpTypeDelete.String()), 351 + Type: new(OpTypeDelete.String()), 353 352 }) 354 353 case OpTypeUpdate: 355 354 // HACK: same hack as above for type fixes ··· 389 388 }) 390 389 391 390 results = append(results, ApplyWriteResult{ 392 - Type: to.StringPtr(OpTypeUpdate.String()), 393 - Uri: to.StringPtr("at://" + urepo.Did + "/" + op.Collection + "/" + *op.Rkey), 394 - Cid: to.StringPtr(nc.String()), 395 - ValidationStatus: to.StringPtr("valid"), // TODO: obviously this might not be true atm lol 391 + Type: new(OpTypeUpdate.String()), 392 + Uri: new("at://" + urepo.Did + "/" + op.Collection + "/" + *op.Rkey), 393 + Cid: new(nc.String()), 394 + ValidationStatus: new("valid"), // TODO: obviously this might not be true atm lol 396 395 }) 397 396 } 398 397 } ··· 541 540 } 542 541 543 542 for i := range results { 544 - results[i].Type = to.StringPtr(*results[i].Type + "Result") 543 + results[i].Type = new(*results[i].Type + "Result") 545 544 results[i].Commit = &RepoCommit{ 546 545 Cid: newroot.String(), 547 546 Rev: rev,