Personal finance tracker
0
fork

Configure Feed

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

wip: add auth middleware

+28 -13
+1 -2
backend/go.mod
··· 6 6 github.com/bluesky-social/indigo v0.0.0-20260220055544-bf41e2ee75ab 7 7 github.com/danielgtaylor/huma/v2 v2.35.0 8 8 github.com/go-chi/chi/v5 v5.2.5 9 + github.com/gorilla/sessions v1.4.0 9 10 github.com/spf13/cobra v1.9.1 10 11 github.com/uptrace/bun v1.2.16 11 12 github.com/uptrace/bun/dialect/sqlitedialect v1.2.16 ··· 19 20 github.com/dustin/go-humanize v1.0.1 // indirect 20 21 github.com/earthboundkid/versioninfo/v2 v2.24.1 // indirect 21 22 github.com/fatih/color v1.18.0 // indirect 22 - github.com/go-jet/jet/v2 v2.14.1 // indirect 23 23 github.com/golang-jwt/jwt/v5 v5.2.2 // indirect 24 24 github.com/google/go-querystring v1.1.0 // indirect 25 25 github.com/google/uuid v1.6.0 // indirect 26 26 github.com/gorilla/securecookie v1.1.2 // indirect 27 - github.com/gorilla/sessions v1.4.0 // indirect 28 27 github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect 29 28 github.com/inconshreveable/mousetrap v1.1.0 // indirect 30 29 github.com/jinzhu/inflection v1.0.0 // indirect
+2 -2
backend/go.sum
··· 17 17 github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= 18 18 github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug= 19 19 github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0= 20 - github.com/go-jet/jet/v2 v2.14.1 h1:wsfD9e7CGP9h46+IFNlftfncBcmVnKddikbTtapQM3M= 21 - github.com/go-jet/jet/v2 v2.14.1/go.mod h1:dqTAECV2Mo3S2NFjbm4vJ1aDruZjhaJ1RAAR8rGUkkc= 22 20 github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= 23 21 github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= 24 22 github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= ··· 26 24 github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 27 25 github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= 28 26 github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= 27 + github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= 28 + github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 29 29 github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= 30 30 github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= 31 31 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+6 -4
backend/main.go
··· 29 29 bundebug.FromEnv(), 30 30 )) 31 31 32 - // Router 32 + // chi Router 33 33 r := chi.NewRouter() 34 34 r.Use(middleware.Logger) 35 35 36 36 // OAuth 37 - oauth.New(bundb).Register(r) 37 + oa := oauth.New(bundb).Register(r) 38 38 39 - // API routers 40 39 r.Route("/api", func(r chi.Router) { 40 + // Huma 41 41 humaconfig := huma.DefaultConfig("Subete API", "v1") 42 42 humaconfig.Servers = []*huma.Server{ 43 43 {URL: "/api"}, 44 44 } 45 45 api := humachi.New(r, humaconfig) 46 + api.UseMiddleware(oa.Middleware(api)) 46 47 47 - // Authed 48 + // Subete API routes 48 49 wallet.New(bundb).Register(api) 49 50 }) 50 51 ··· 55 56 } 56 57 hooks.OnStart(func() { 57 58 fmt.Printf("%s server at: http://%s\n", config.Loaded.APP_ENV, config.Loaded.APP_ADDR) 59 + fmt.Printf("OpenAPI docs at: http://%s/api/docs\n", config.Loaded.APP_ADDR) 58 60 server.ListenAndServe() 59 61 }) 60 62 hooks.OnStop(func() {
+19 -5
backend/oauth/oauth.go
··· 10 10 "github.com/bluesky-social/indigo/atproto/atcrypto" 11 11 atoauth "github.com/bluesky-social/indigo/atproto/auth/oauth" 12 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 + "github.com/danielgtaylor/huma/v2" 14 + "github.com/danielgtaylor/huma/v2/adapters/humachi" 13 15 "github.com/go-chi/chi/v5" 14 16 "github.com/gorilla/sessions" 15 17 "github.com/uptrace/bun" ··· 64 66 } 65 67 } 66 68 67 - func (oa *OAuth) Register(r *chi.Mux) { 69 + func (oa *OAuth) Register(r *chi.Mux) *OAuth { 68 70 r.Get("/oauth/client-metadata.json", oa.clientMetadata) 69 71 r.Get("/oauth/jwks.json", oa.jwks) 70 72 r.Get("/oauth/callback", oa.callback) 71 73 r.Post("/oauth/login", oa.login) 72 74 r.Get("/oauth/logout", oa.logout) 73 75 // r.Post("/oauth/signup", oauth.signup) 76 + return oa 77 + } 78 + 79 + func (oa *OAuth) Middleware(api huma.API) func(ctx huma.Context, next func(huma.Context)) { 80 + return func(ctx huma.Context, next func(huma.Context)) { 81 + r, _ := humachi.Unwrap(ctx) 82 + if err := oa.resumeSession(r); err != nil { 83 + huma.WriteErr(api, ctx, http.StatusUnauthorized, "unauthorized", err) 84 + return 85 + } 86 + next(ctx) 87 + } 74 88 } 75 89 76 90 func (oa *OAuth) clientMetadata(w http.ResponseWriter, r *http.Request) { ··· 157 171 } 158 172 159 173 func (oa *OAuth) resumeSession(r *http.Request) error { 160 - session, sessionValue, err := oa.getSessionValue(r) 174 + _, sessionValue, err := oa.getSessionValue(r) 161 175 if err != nil { 162 176 return err 163 - } 164 - if session.IsNew { 165 - return fmt.Errorf("no session available for user") 166 177 } 167 178 168 179 _, err = oa.clientApp.ResumeSession(r.Context(), sessionValue.did, sessionValue.id) ··· 204 215 session, err := oa.cookieStore.Get(r, sessionKey) 205 216 if err != nil { 206 217 return nil, nil, err 218 + } 219 + if session.IsNew { 220 + return nil, nil, fmt.Errorf("no session available for user") 207 221 } 208 222 209 223 did, err := syntax.ParseDID(session.Values[keySessionDID].(string))