From 95a94bfed536c42da8d06c034a92be026c147c2d Mon Sep 17 00:00:00 2001 From: hex Date: Tue, 6 May 2025 19:00:17 +0200 Subject: [PATCH 1/3] fix: add creation date upon user registration --- internal/auth/client/client.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/auth/client/client.go b/internal/auth/client/client.go index 9a415f5..ae172d9 100644 --- a/internal/auth/client/client.go +++ b/internal/auth/client/client.go @@ -8,6 +8,8 @@ import ( "net/http" "net/url" "strings" + "time" + "stereo.cat/backend/internal/auth" ) @@ -30,6 +32,7 @@ func New(redirectUri, clientId, clientSecret string) Client { func (c Client) GetUser(t auth.TokenResponse) (auth.User, error) { user := auth.User { Blacklisted: false, + CreatedAt: time.Now(), } req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/%s", api, "users/@me"), nil) From fbd23fe2cf2e978c915e8fd5ea1bd2d8f9bf239d Mon Sep 17 00:00:00 2001 From: grngxd <36968271+grngxd@users.noreply.github.com> Date: Tue, 6 May 2025 21:34:26 +0100 Subject: [PATCH 2/3] idk but it did something --- internal/auth/client/client.go | 8 +++--- internal/auth/jwt.go | 48 ++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/internal/auth/client/client.go b/internal/auth/client/client.go index ae172d9..3a922bc 100644 --- a/internal/auth/client/client.go +++ b/internal/auth/client/client.go @@ -30,10 +30,10 @@ func New(redirectUri, clientId, clientSecret string) Client { } func (c Client) GetUser(t auth.TokenResponse) (auth.User, error) { - user := auth.User { - Blacklisted: false, - CreatedAt: time.Now(), - } + user := auth.User{ + Blacklisted: false, + CreatedAt: time.Now(), + } req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/%s", api, "users/@me"), nil) diff --git a/internal/auth/jwt.go b/internal/auth/jwt.go index 6a01712..9e7aec2 100644 --- a/internal/auth/jwt.go +++ b/internal/auth/jwt.go @@ -1,6 +1,7 @@ package auth import ( + "encoding/json" "fmt" "net/http" "strings" @@ -20,30 +21,45 @@ func GenerateJWT(key string, user User, expiryTimestamp uint64) (string, error) } func invalidAuth(c *gin.Context) { - c.String(http.StatusUnauthorized, "Unauthorized.") - c.Abort() + c.String(http.StatusUnauthorized, "Unauthorized.") + c.Abort() } func JwtMiddleware(secret string) gin.HandlerFunc { - return func(c *gin.Context) { - jwtSplit := strings.Split(c.GetHeader("Authorization"), " ") + return func(c *gin.Context) { + jwtSplit := strings.Split(c.GetHeader("Authorization"), " ") - if jwtSplit[0] != "Bearer" { - invalidAuth(c) - return - } + if len(jwtSplit) < 2 || jwtSplit[0] != "Bearer" { + invalidAuth(c) + return + } - claims, err := ValidateJWT(jwtSplit[1], secret) + claims, err := ValidateJWT(jwtSplit[1], secret) + if err != nil { + invalidAuth(c) + return + } - if err != nil { - invalidAuth(c) - return - } + if userClaims, ok := claims["user"].(map[string]interface{}); ok { + userJSON, err := json.Marshal(userClaims) // Convert map to JSON + if err != nil { + invalidAuth(c) + return + } - c.Set("claims", claims) + var user User + err = json.Unmarshal(userJSON, &user) + if err != nil { + invalidAuth(c) + return + } - c.Next() - } + claims["user"] = user + } + + c.Set("claims", claims) + c.Next() + } } func ValidateJWT(jwtString, key string) (jwt.MapClaims, error) { From 0521b523c4dcce35d7409abfed6519630e5a1190 Mon Sep 17 00:00:00 2001 From: hex Date: Sat, 10 May 2025 15:31:34 +0200 Subject: [PATCH 3/3] feat: database user creation && readme explanation --- README.md | 5 +++++ internal/api/routes/auth.go | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fb342cc..b58e450 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ # stereo.cat backend written in Go, uses Gin. + +## database shit + +Instead of using Discord oAuth as a database, we instead use it as a login source, only using it to source a username/id, avatar data and a secure login/registration flow. +We store these attributes alongside stereo.cat specific attributes in our own database. There is a trade-off however: this means that avatar & username data is not updated in real-time, only when the oauth flow is executed. diff --git a/internal/api/routes/auth.go b/internal/api/routes/auth.go index a6a634f..53082dc 100644 --- a/internal/api/routes/auth.go +++ b/internal/api/routes/auth.go @@ -31,11 +31,21 @@ func RegisterAuthRoutes(cfg *types.StereoConfig, api *gin.RouterGroup) { panic(err) } - c.String(http.StatusOK, jwt) + res := cfg.Database.FirstOrCreate(&user) + + if res.Error != nil { + panic(res.Error) + } + + // TODO: redirect to dashboard + c.JSON(http.StatusOK, gin.H{ + "jwt": jwt, + "known": res.RowsAffected == 0, + }) }) api.GET("/auth/me", auth.JwtMiddleware(cfg.JWTSecret), func(c *gin.Context) { - claims, _ := c.Get("claims") + claims, _ := c.Get("claims") c.JSON(http.StatusOK, claims) }) }