diff --git a/.gitignore b/.gitignore index d17bf15..b0088e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ .env tmp *.db -imgs \ No newline at end of file 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) }) } diff --git a/internal/api/routes/upload.go b/internal/api/routes/upload.go index d4950e7..baed591 100644 --- a/internal/api/routes/upload.go +++ b/internal/api/routes/upload.go @@ -4,36 +4,22 @@ import ( "path/filepath" "github.com/gin-gonic/gin" - "github.com/golang-jwt/jwt/v5" - "stereo.cat/backend/internal/auth" "stereo.cat/backend/internal/types" ) func RegisterUploadRoutes(cfg *types.StereoConfig, api *gin.RouterGroup) { - api.POST("/upload", auth.JwtMiddleware(cfg.JWTSecret), func(c *gin.Context) { - claims := c.MustGet("claims").(jwt.MapClaims) - user := claims["user"].(auth.User) - - uid := user.ID - - if uid == "" { - c.JSON(401, gin.H{"error": "unauthorized"}) - return - } - + api.POST("/upload", func(c *gin.Context) { file, err := c.FormFile("file") if err != nil { c.JSON(400, gin.H{"error": "file is required"}) return } - filePath := filepath.Join(cfg.ImagePath, uid, file.Filename) + filePath := filepath.Join(cfg.ImagePath, file.Filename) if err := c.SaveUploadedFile(file, filePath); err != nil { c.JSON(500, gin.H{"error": "failed to save file"}) return } - - c.JSON(200, gin.H{"message": "file uploaded successfully"}) }) api.GET("/:name", func(c *gin.Context) { diff --git a/internal/auth/jwt.go b/internal/auth/jwt.go index 1ea6d0f..9e7aec2 100644 --- a/internal/auth/jwt.go +++ b/internal/auth/jwt.go @@ -11,9 +11,9 @@ import ( ) func GenerateJWT(key string, user User, expiryTimestamp uint64) (string, error) { - claims := Claims{ - User: user, - Exp: expiryTimestamp, + claims := jwt.MapClaims{ + "user": user, + "exp": expiryTimestamp, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) diff --git a/internal/auth/types.go b/internal/auth/types.go index 8627df7..a83b941 100644 --- a/internal/auth/types.go +++ b/internal/auth/types.go @@ -1,10 +1,6 @@ package auth -import ( - "time" - - "github.com/golang-jwt/jwt/v5" -) +import "time" type TokenResponse struct { AccessToken string `json:"access_token"` @@ -32,9 +28,3 @@ type ExchangeCodeRequest struct { Code string `json:"code"` RedirectUri string `json:"redirect_uri"` } - -type Claims struct { - User User `json:"user"` - Exp uint64 `json:"exp"` - jwt.RegisteredClaims -}