From eccc4885cc19065da40677ae09587bbe52388d87 Mon Sep 17 00:00:00 2001 From: Hayden Hargreaves Date: Sun, 27 Jul 2025 14:11:26 -0700 Subject: [PATCH] (FIX): This should be the last of the user nil deref updates! I believe this can mark the tasks about fixing the deref issues with auth completed. Will test in production to find out! --- internal/app/handlers/engagement_handler.go | 42 ++++++++++++++------ internal/app/handlers/page_handler.go | 12 ++++++ internal/app/handlers/recipe_handler.go | 2 + internal/app/handlers/user_handler.go | 44 ++++++++++----------- 4 files changed, 65 insertions(+), 35 deletions(-) diff --git a/internal/app/handlers/engagement_handler.go b/internal/app/handlers/engagement_handler.go index 1f80b7b..1c1f00b 100644 --- a/internal/app/handlers/engagement_handler.go +++ b/internal/app/handlers/engagement_handler.go @@ -13,7 +13,15 @@ func EngagementViewRecipe(ctx *gin.Context) { deps := ctx.MustGet("deps").(*domain.InjectedDependencies) recipeId, _ := strconv.Atoi(ctx.Param("id")) - if !domain.IsLoggedIn(ctx) { + // Ensure user is logged in with a valid account + user := deps.UserService.GetAuthenicatedUser(ctx) + if user == nil { + // Log (stale) user out + domain.SetCookie(ctx, "jwt_token", "", -1) + domain.SetCookie(ctx, "search-filters", "", -1) + } + + if !domain.IsLoggedIn(ctx) || user == nil { if _, err := deps.EngagementService.ViewRecipe(recipeId); err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, @@ -26,9 +34,8 @@ func EngagementViewRecipe(ctx *gin.Context) { return } - userId := ctx.MustGet("userId").(int) - - if _, err := deps.EngagementService.UserViewRecipe(userId, recipeId); err != nil { + // We caught nil already, we can assume the user exists + if _, err := deps.EngagementService.UserViewRecipe(user.Id, recipeId); err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": err.Error(), @@ -43,7 +50,15 @@ func EngagementShareRecipe(ctx *gin.Context) { deps := ctx.MustGet("deps").(*domain.InjectedDependencies) recipeId, _ := strconv.Atoi(ctx.Param("id")) - if !domain.IsLoggedIn(ctx) { + // Ensure user is logged in with a valid account + user := deps.UserService.GetAuthenicatedUser(ctx) + if user == nil { + // Log (stale) user out + domain.SetCookie(ctx, "jwt_token", "", -1) + domain.SetCookie(ctx, "search-filters", "", -1) + } + + if !domain.IsLoggedIn(ctx) || user == nil { if _, err := deps.EngagementService.ShareRecipe(recipeId); err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, @@ -55,9 +70,7 @@ func EngagementShareRecipe(ctx *gin.Context) { return } - userId := ctx.MustGet("userId").(int) - - if _, err := deps.EngagementService.UserShareRecipe(userId, recipeId); err != nil { + if _, err := deps.EngagementService.UserShareRecipe(user.Id, recipeId); err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": err.Error(), @@ -70,7 +83,15 @@ func EngagementShareRecipe(ctx *gin.Context) { func EngagementFavoriteRecipe(ctx *gin.Context) { deps := ctx.MustGet("deps").(*domain.InjectedDependencies) - if !domain.IsLoggedIn(ctx) { + // Ensure user is logged in with a valid account + user := deps.UserService.GetAuthenicatedUser(ctx) + if user == nil { + // Log (stale) user out + domain.SetCookie(ctx, "jwt_token", "", -1) + domain.SetCookie(ctx, "search-filters", "", -1) + } + + if !domain.IsLoggedIn(ctx) || user == nil { ctx.Header("HX-Redirect", domain.WEB_LOGIN) ctx.Status(http.StatusOK) return @@ -78,9 +99,8 @@ func EngagementFavoriteRecipe(ctx *gin.Context) { id := ctx.Param("id") recipeId, _ := strconv.Atoi(id) - userId := ctx.MustGet("userId").(int) - if _, err := deps.EngagementService.UserFavoriteRecipe(userId, recipeId); err != nil { + if _, err := deps.EngagementService.UserFavoriteRecipe(user.Id, recipeId); err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": err.Error(), diff --git a/internal/app/handlers/page_handler.go b/internal/app/handlers/page_handler.go index 5d16eb2..a29b705 100755 --- a/internal/app/handlers/page_handler.go +++ b/internal/app/handlers/page_handler.go @@ -136,12 +136,24 @@ func FavoritesPage(ctx *gin.Context) { } func CreatePage(ctx *gin.Context) { + deps := ctx.MustGet("deps").(*domainServer.InjectedDependencies) + // If not logged in, direct to the login page if !domainServer.IsLoggedIn(ctx) { ctx.Redirect(http.StatusSeeOther, domainServer.WEB_LOGIN) return } + // Ensure user is logged in with a valid account + if user := deps.UserService.GetAuthenicatedUser(ctx); user == nil { + // Log (stale) user out + domain.SetCookie(ctx, "jwt_token", "", -1) + domain.SetCookie(ctx, "search-filters", "", -1) + + ctx.Redirect(http.StatusSeeOther, domainServer.WEB_LOGIN) + return + } + title := "Potion - Create" page := pages.CreatePage() diff --git a/internal/app/handlers/recipe_handler.go b/internal/app/handlers/recipe_handler.go index 3a85be0..2d24556 100644 --- a/internal/app/handlers/recipe_handler.go +++ b/internal/app/handlers/recipe_handler.go @@ -84,6 +84,8 @@ func SearchRecipes(ctx *gin.Context) { userId = &id } + // TODO: Not sure if we need to ensure the user is valid here + // We don't care about favorite status, so use false recipes, err := deps.RecipeService.SearchRecipes(filters, userId, false) if err != nil { diff --git a/internal/app/handlers/user_handler.go b/internal/app/handlers/user_handler.go index c5508bf..e19cd18 100644 --- a/internal/app/handlers/user_handler.go +++ b/internal/app/handlers/user_handler.go @@ -11,8 +11,16 @@ import ( func GetUserRecipes(ctx *gin.Context) { deps := ctx.MustGet("deps").(*domain.InjectedDependencies) + // Ensure user is logged in with a valid account + user := deps.UserService.GetAuthenicatedUser(ctx) + if user == nil { + // Log (stale) user out + domain.SetCookie(ctx, "jwt_token", "", -1) + domain.SetCookie(ctx, "search-filters", "", -1) + } + // Ensure logged in - if !domain.IsLoggedIn(ctx) { + if !domain.IsLoggedIn(ctx) || user == nil { ctx.JSON(http.StatusUnauthorized, gin.H{ "status": http.StatusUnauthorized, "message": "User is not authorized to access this endpoint. Please login to continue.", @@ -21,17 +29,7 @@ func GetUserRecipes(ctx *gin.Context) { return } - userId, ok := ctx.MustGet("userId").(int) - if !ok { - ctx.JSON(http.StatusInternalServerError, gin.H{ - "status": http.StatusInternalServerError, - "message": "Unable to access user id from store.", - "recipes": nil, - }) - return - } - - recipes, err := deps.RecipeService.GetUserRecipes(userId) + recipes, err := deps.RecipeService.GetUserRecipes(user.Id) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{ "status": http.StatusBadRequest, @@ -51,8 +49,16 @@ func GetUserRecipes(ctx *gin.Context) { func GetUserFavoriteRecipes(ctx *gin.Context) { deps := ctx.MustGet("deps").(*domain.InjectedDependencies) + // Ensure user is logged in with a valid account + user := deps.UserService.GetAuthenicatedUser(ctx) + if user == nil { + // Log (stale) user out + domain.SetCookie(ctx, "jwt_token", "", -1) + domain.SetCookie(ctx, "search-filters", "", -1) + } + // Ensure logged in - if !domain.IsLoggedIn(ctx) { + if !domain.IsLoggedIn(ctx) || user == nil { ctx.JSON(http.StatusUnauthorized, gin.H{ "status": http.StatusUnauthorized, "message": "User is not authorized to access this endpoint. Please login to continue.", @@ -61,17 +67,7 @@ func GetUserFavoriteRecipes(ctx *gin.Context) { return } - userId, ok := ctx.MustGet("userId").(int) - if !ok { - ctx.JSON(http.StatusInternalServerError, gin.H{ - "status": http.StatusInternalServerError, - "message": "Unable to access user id from store.", - "recipes": nil, - }) - return - } - - recipes, err := deps.RecipeService.GetUserFavoriteRecipes(userId) + recipes, err := deps.RecipeService.GetUserFavoriteRecipes(user.Id) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{ "status": http.StatusBadRequest,