feat: add caching control with redis
This commit is contained in:
parent
674a1e1c50
commit
ef95e3bfbe
|
@ -1,10 +1,12 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
"github.com/pahmiudahgede/senggoldong/domain"
|
"github.com/pahmiudahgede/senggoldong/domain"
|
||||||
"gorm.io/driver/postgres"
|
"gorm.io/driver/postgres"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
@ -21,6 +23,12 @@ var (
|
||||||
APIKey string
|
APIKey string
|
||||||
ServerHost string
|
ServerHost string
|
||||||
ServerPort string
|
ServerPort string
|
||||||
|
|
||||||
|
RedisClient *redis.Client
|
||||||
|
RedisHost string
|
||||||
|
RedisPort string
|
||||||
|
RedisPassword string
|
||||||
|
RedisDB int
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitConfig() {
|
func InitConfig() {
|
||||||
|
@ -32,6 +40,10 @@ func InitConfig() {
|
||||||
DBUser = os.Getenv("DB_USER")
|
DBUser = os.Getenv("DB_USER")
|
||||||
DBPassword = os.Getenv("DB_PASSWORD")
|
DBPassword = os.Getenv("DB_PASSWORD")
|
||||||
APIKey = os.Getenv("API_KEY")
|
APIKey = os.Getenv("API_KEY")
|
||||||
|
RedisHost = os.Getenv("REDIS_HOST")
|
||||||
|
RedisPort = os.Getenv("REDIS_PORT")
|
||||||
|
RedisPassword = os.Getenv("REDIS_PASSWORD")
|
||||||
|
RedisDB = 0
|
||||||
|
|
||||||
if ServerHost == "" || ServerPort == "" || DBHost == "" || DBPort == "" || DBName == "" || DBUser == "" || DBPassword == "" || APIKey == "" {
|
if ServerHost == "" || ServerPort == "" || DBHost == "" || DBPort == "" || DBName == "" || DBUser == "" || DBPassword == "" || APIKey == "" {
|
||||||
log.Fatal("Error: environment variables yang dibutuhkan tidak ada")
|
log.Fatal("Error: environment variables yang dibutuhkan tidak ada")
|
||||||
|
@ -77,3 +89,20 @@ func InitDatabase() {
|
||||||
|
|
||||||
fmt.Println("Koneksi ke database berhasil dan migrasi dilakukan")
|
fmt.Println("Koneksi ke database berhasil dan migrasi dilakukan")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InitRedis() {
|
||||||
|
InitConfig()
|
||||||
|
|
||||||
|
RedisClient = redis.NewClient(&redis.Options{
|
||||||
|
Addr: fmt.Sprintf("%s:%s", RedisHost, RedisPort),
|
||||||
|
Password: RedisPassword,
|
||||||
|
DB: RedisDB,
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := RedisClient.Ping(context.Background()).Result()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Gagal terhubung ke Redis:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Koneksi ke Redis berhasil")
|
||||||
|
}
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -4,10 +4,13 @@ go 1.23.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.23.0 // indirect
|
github.com/go-playground/validator/v10 v10.23.0 // indirect
|
||||||
|
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||||
github.com/gofiber/fiber/v2 v2.52.5 // indirect
|
github.com/gofiber/fiber/v2 v2.52.5 // indirect
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||||
github.com/google/uuid v1.5.0 // indirect
|
github.com/google/uuid v1.5.0 // indirect
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -1,6 +1,10 @@
|
||||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
|
@ -9,6 +13,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
|
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
|
||||||
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
|
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||||
|
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||||
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
|
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
|
||||||
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||||
|
|
|
@ -42,6 +42,7 @@ func AppRouter(app *fiber.App) {
|
||||||
// # authentication #
|
// # authentication #
|
||||||
api.Post("/register", controllers.Register)
|
api.Post("/register", controllers.Register)
|
||||||
api.Post("/login", controllers.Login)
|
api.Post("/login", controllers.Login)
|
||||||
|
api.Post("/logout", controllers.Logout)
|
||||||
|
|
||||||
// # userinfo #
|
// # userinfo #
|
||||||
api.Get("/user", middleware.AuthMiddleware, controllers.GetUserInfo)
|
api.Get("/user", middleware.AuthMiddleware, controllers.GetUserInfo)
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/config"
|
||||||
"github.com/pahmiudahgede/senggoldong/dto"
|
"github.com/pahmiudahgede/senggoldong/dto"
|
||||||
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
||||||
"github.com/pahmiudahgede/senggoldong/internal/services"
|
"github.com/pahmiudahgede/senggoldong/internal/services"
|
||||||
|
@ -86,6 +91,16 @@ func Login(c *fiber.Ctx) error {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
err = config.RedisClient.Set(ctx, "auth_token:"+token, credentials.Identifier, time.Hour*24).Err()
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusInternalServerError,
|
||||||
|
"Failed to store session",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
user, err := repositories.GetUserByEmailUsernameOrPhone(credentials.Identifier, "")
|
user, err := repositories.GetUserByEmailUsernameOrPhone(credentials.Identifier, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
||||||
|
@ -248,3 +263,32 @@ func UpdatePassword(c *fiber.Ctx) error {
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Logout(c *fiber.Ctx) error {
|
||||||
|
tokenString := c.Get("Authorization")
|
||||||
|
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
|
||||||
|
|
||||||
|
if tokenString == "" {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusUnauthorized,
|
||||||
|
"Token is required",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
err := config.RedisClient.Del(ctx, "auth_token:"+tokenString).Err()
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusInternalServerError,
|
||||||
|
"Failed to delete session",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusOK,
|
||||||
|
"Logout successful",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/config"
|
||||||
"github.com/pahmiudahgede/senggoldong/dto"
|
"github.com/pahmiudahgede/senggoldong/dto"
|
||||||
"github.com/pahmiudahgede/senggoldong/internal/services"
|
"github.com/pahmiudahgede/senggoldong/internal/services"
|
||||||
"github.com/pahmiudahgede/senggoldong/utils"
|
"github.com/pahmiudahgede/senggoldong/utils"
|
||||||
|
@ -27,8 +31,16 @@ func CreatePin(c *fiber.Ctx) error {
|
||||||
|
|
||||||
userID := c.Locals("userID").(string)
|
userID := c.Locals("userID").(string)
|
||||||
|
|
||||||
existingPin, err := services.GetPinByUserID(userID)
|
redisPin, err := config.RedisClient.Get(c.Context(), "pin:"+userID).Result()
|
||||||
if err == nil && existingPin.ID != "" {
|
if err != nil && err != redis.Nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusInternalServerError,
|
||||||
|
"Failed to check PIN from Redis",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
if redisPin != "" {
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
fiber.StatusBadRequest,
|
fiber.StatusBadRequest,
|
||||||
"PIN sudah ada, tidak perlu dibuat lagi",
|
"PIN sudah ada, tidak perlu dibuat lagi",
|
||||||
|
@ -45,10 +57,18 @@ func CreatePin(c *fiber.Ctx) error {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = config.RedisClient.Set(c.Context(), "pin:"+userID, pin.Pin, time.Minute*30).Err()
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusInternalServerError,
|
||||||
|
"Failed to save PIN to Redis",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
formattedCreatedAt := utils.FormatDateToIndonesianFormat(pin.CreatedAt)
|
formattedCreatedAt := utils.FormatDateToIndonesianFormat(pin.CreatedAt)
|
||||||
|
|
||||||
pinResponse := dto.PinResponse{
|
pinResponse := dto.PinResponse{
|
||||||
|
|
||||||
CreatedAt: formattedCreatedAt,
|
CreatedAt: formattedCreatedAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,9 +82,11 @@ func CreatePin(c *fiber.Ctx) error {
|
||||||
func GetPinStatus(c *fiber.Ctx) error {
|
func GetPinStatus(c *fiber.Ctx) error {
|
||||||
userID := c.Locals("userID").(string)
|
userID := c.Locals("userID").(string)
|
||||||
|
|
||||||
|
_, err := config.RedisClient.Get(c.Context(), "pin:"+userID).Result()
|
||||||
|
if err == redis.Nil {
|
||||||
|
|
||||||
pin, err := services.GetPinByUserID(userID)
|
pin, err := services.GetPinByUserID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
||||||
fiber.StatusNotFound,
|
fiber.StatusNotFound,
|
||||||
"Anda belum membuat PIN",
|
"Anda belum membuat PIN",
|
||||||
|
@ -83,6 +105,22 @@ func GetPinStatus(c *fiber.Ctx) error {
|
||||||
"updatedAt": formattedUpdatedAt,
|
"updatedAt": formattedUpdatedAt,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
|
} else if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusInternalServerError,
|
||||||
|
"Failed to fetch PIN from Redis",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusOK,
|
||||||
|
"PIN sudah dibuat",
|
||||||
|
map[string]interface{}{
|
||||||
|
"createdAt": "PIN ditemukan di Redis",
|
||||||
|
"updatedAt": "PIN ditemukan di Redis",
|
||||||
|
},
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPin(c *fiber.Ctx) error {
|
func GetPin(c *fiber.Ctx) error {
|
||||||
|
@ -96,6 +134,10 @@ func GetPin(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
userID := c.Locals("userID").(string)
|
userID := c.Locals("userID").(string)
|
||||||
|
|
||||||
|
redisPin, err := config.RedisClient.Get(c.Context(), "pin:"+userID).Result()
|
||||||
|
if err == redis.Nil {
|
||||||
|
|
||||||
pin, err := services.GetPinByUserID(userID)
|
pin, err := services.GetPinByUserID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
||||||
|
@ -106,9 +148,31 @@ func GetPin(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
isPinValid := services.CheckPin(pin.Pin, input.Pin)
|
isPinValid := services.CheckPin(pin.Pin, input.Pin)
|
||||||
|
|
||||||
if isPinValid {
|
if isPinValid {
|
||||||
|
|
||||||
|
config.RedisClient.Set(c.Context(), "pin:"+userID, pin.Pin, time.Minute*30)
|
||||||
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusOK,
|
||||||
|
"PIN benar",
|
||||||
|
true,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusUnauthorized,
|
||||||
|
"PIN salah",
|
||||||
|
false,
|
||||||
|
))
|
||||||
|
} else if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusInternalServerError,
|
||||||
|
"Failed to fetch PIN from Redis",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
isPinValid := services.CheckPin(redisPin, input.Pin)
|
||||||
|
if isPinValid {
|
||||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
fiber.StatusOK,
|
fiber.StatusOK,
|
||||||
"PIN benar",
|
"PIN benar",
|
||||||
|
@ -145,7 +209,6 @@ func UpdatePin(c *fiber.Ctx) error {
|
||||||
|
|
||||||
updatedPin, err := services.UpdatePin(userID, input.OldPin, input.NewPin)
|
updatedPin, err := services.UpdatePin(userID, input.OldPin, input.NewPin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
if err.Error() == "PIN lama salah" {
|
if err.Error() == "PIN lama salah" {
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
||||||
fiber.StatusUnauthorized,
|
fiber.StatusUnauthorized,
|
||||||
|
@ -161,6 +224,9 @@ func UpdatePin(c *fiber.Ctx) error {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.RedisClient.Del(c.Context(), "pin:"+userID)
|
||||||
|
config.RedisClient.Set(c.Context(), "pin:"+userID, updatedPin.Pin, time.Minute*30)
|
||||||
|
|
||||||
formattedUpdatedAt := utils.FormatDateToIndonesianFormat(updatedPin.UpdatedAt)
|
formattedUpdatedAt := utils.FormatDateToIndonesianFormat(updatedPin.UpdatedAt)
|
||||||
|
|
||||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/config"
|
||||||
"github.com/pahmiudahgede/senggoldong/utils"
|
"github.com/pahmiudahgede/senggoldong/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,6 +26,16 @@ func RoleRequired(roles ...string) fiber.Handler {
|
||||||
|
|
||||||
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
|
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
cachedToken, err := config.RedisClient.Get(ctx, "auth_token:"+tokenString).Result()
|
||||||
|
if err != nil || cachedToken == "" {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
||||||
|
fiber.StatusUnauthorized,
|
||||||
|
"Invalid or expired token",
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||||
return nil, errors.New("unexpected signing method")
|
return nil, errors.New("unexpected signing method")
|
||||||
|
@ -91,6 +104,14 @@ func AuthMiddleware(c *fiber.Ctx) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
cachedToken, err := config.RedisClient.Get(ctx, "auth_token:"+tokenString).Result()
|
||||||
|
if err != nil || cachedToken == "" {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
||||||
|
"message": "Invalid or expired token",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||||
return []byte(os.Getenv("API_KEY")), nil
|
return []byte(os.Getenv("API_KEY")), nil
|
||||||
})
|
})
|
||||||
|
@ -109,8 +130,9 @@ func AuthMiddleware(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
userID := claims["sub"].(string)
|
userID := claims["sub"].(string)
|
||||||
|
|
||||||
c.Locals("userID", userID)
|
c.Locals("userID", userID)
|
||||||
|
|
||||||
|
config.RedisClient.Expire(ctx, "auth_token:"+tokenString, time.Hour*24).Err()
|
||||||
|
|
||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
|
@ -1,7 +1,11 @@
|
||||||
package repositories
|
package repositories
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pahmiudahgede/senggoldong/config"
|
"github.com/pahmiudahgede/senggoldong/config"
|
||||||
"github.com/pahmiudahgede/senggoldong/domain"
|
"github.com/pahmiudahgede/senggoldong/domain"
|
||||||
|
@ -12,15 +16,34 @@ func CreateAddress(address *domain.Address) error {
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return result.Error
|
return result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheKey := fmt.Sprintf("address:user:%s", address.UserID)
|
||||||
|
config.RedisClient.Del(context.Background(), cacheKey)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAddressesByUserID(userID string) ([]domain.Address, error) {
|
func GetAddressesByUserID(userID string) ([]domain.Address, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
cacheKey := fmt.Sprintf("address:user:%s", userID)
|
||||||
|
|
||||||
|
cachedAddresses, err := config.RedisClient.Get(ctx, cacheKey).Result()
|
||||||
|
if err == nil {
|
||||||
var addresses []domain.Address
|
var addresses []domain.Address
|
||||||
err := config.DB.Where("user_id = ?", userID).Find(&addresses).Error
|
if json.Unmarshal([]byte(cachedAddresses), &addresses) == nil {
|
||||||
|
return addresses, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var addresses []domain.Address
|
||||||
|
err = config.DB.Where("user_id = ?", userID).Find(&addresses).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addressesJSON, _ := json.Marshal(addresses)
|
||||||
|
config.RedisClient.Set(ctx, cacheKey, addressesJSON, time.Hour).Err()
|
||||||
|
|
||||||
return addresses, nil
|
return addresses, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,13 +59,25 @@ func UpdateAddress(address domain.Address) (domain.Address, error) {
|
||||||
if err := config.DB.Save(&address).Error; err != nil {
|
if err := config.DB.Save(&address).Error; err != nil {
|
||||||
return address, err
|
return address, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheKey := fmt.Sprintf("address:user:%s", address.UserID)
|
||||||
|
config.RedisClient.Del(context.Background(), cacheKey)
|
||||||
|
|
||||||
return address, nil
|
return address, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteAddress(addressID string) error {
|
func DeleteAddress(addressID string) error {
|
||||||
var address domain.Address
|
var address domain.Address
|
||||||
if err := config.DB.Where("id = ?", addressID).Delete(&address).Error; err != nil {
|
if err := config.DB.Where("id = ?", addressID).First(&address).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := config.DB.Delete(&address).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheKey := fmt.Sprintf("address:user:%s", address.UserID)
|
||||||
|
config.RedisClient.Del(context.Background(), cacheKey)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,31 @@
|
||||||
package repositories
|
package repositories
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pahmiudahgede/senggoldong/config"
|
"github.com/pahmiudahgede/senggoldong/config"
|
||||||
"github.com/pahmiudahgede/senggoldong/domain"
|
"github.com/pahmiudahgede/senggoldong/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
func IsEmailExist(email, roleId string) bool {
|
func IsEmailExist(email, roleId string) bool {
|
||||||
|
ctx := context.Background()
|
||||||
|
cacheKey := fmt.Sprintf("email:%s", email)
|
||||||
|
cachedRole, err := config.RedisClient.Get(ctx, cacheKey).Result()
|
||||||
|
if err == nil && cachedRole == roleId {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
var user domain.User
|
var user domain.User
|
||||||
if err := config.DB.Where("email = ?", email).First(&user).Error; err == nil {
|
if err := config.DB.Where("email = ?", email).First(&user).Error; err == nil {
|
||||||
if user.RoleID == roleId {
|
if user.RoleID == roleId {
|
||||||
|
if err := config.RedisClient.Set(ctx, cacheKey, roleId, 24*time.Hour).Err(); err != nil {
|
||||||
|
log.Printf("Redis Set error: %v", err)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +33,19 @@ func IsEmailExist(email, roleId string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsUsernameExist(username, roleId string) bool {
|
func IsUsernameExist(username, roleId string) bool {
|
||||||
|
ctx := context.Background()
|
||||||
|
cacheKey := fmt.Sprintf("username:%s", username)
|
||||||
|
cachedRole, err := config.RedisClient.Get(ctx, cacheKey).Result()
|
||||||
|
if err == nil && cachedRole == roleId {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
var user domain.User
|
var user domain.User
|
||||||
if err := config.DB.Where("username = ?", username).First(&user).Error; err == nil {
|
if err := config.DB.Where("username = ?", username).First(&user).Error; err == nil {
|
||||||
if user.RoleID == roleId {
|
if user.RoleID == roleId {
|
||||||
|
if err := config.RedisClient.Set(ctx, cacheKey, roleId, 24*time.Hour).Err(); err != nil {
|
||||||
|
log.Printf("Redis Set error: %v", err)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,9 +53,19 @@ func IsUsernameExist(username, roleId string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsPhoneExist(phone, roleId string) bool {
|
func IsPhoneExist(phone, roleId string) bool {
|
||||||
|
ctx := context.Background()
|
||||||
|
cacheKey := fmt.Sprintf("phone:%s", phone)
|
||||||
|
cachedRole, err := config.RedisClient.Get(ctx, cacheKey).Result()
|
||||||
|
if err == nil && cachedRole == roleId {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
var user domain.User
|
var user domain.User
|
||||||
if err := config.DB.Where("phone = ?", phone).First(&user).Error; err == nil {
|
if err := config.DB.Where("phone = ?", phone).First(&user).Error; err == nil {
|
||||||
if user.RoleID == roleId {
|
if user.RoleID == roleId {
|
||||||
|
if err := config.RedisClient.Set(ctx, cacheKey, roleId, 24*time.Hour).Err(); err != nil {
|
||||||
|
log.Printf("Redis Set error: %v", err)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,8 +90,20 @@ func CreateUser(username, name, email, phone, password, roleId string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUserByEmailUsernameOrPhone(identifier, roleId string) (domain.User, error) {
|
func GetUserByEmailUsernameOrPhone(identifier, roleId string) (domain.User, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
cacheKey := fmt.Sprintf("user:%s", identifier)
|
||||||
var user domain.User
|
var user domain.User
|
||||||
err := config.DB.Where("email = ? OR username = ? OR phone = ?", identifier, identifier, identifier).First(&user).Error
|
|
||||||
|
cachedUser, err := config.RedisClient.Get(ctx, cacheKey).Result()
|
||||||
|
if err == nil {
|
||||||
|
if err := json.Unmarshal([]byte(cachedUser), &user); err == nil {
|
||||||
|
if roleId == "" || user.RoleID == roleId {
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = config.DB.Where("email = ? OR username = ? OR phone = ?", identifier, identifier, identifier).First(&user).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return user, errors.New("user not found")
|
return user, errors.New("user not found")
|
||||||
}
|
}
|
||||||
|
@ -66,28 +112,45 @@ func GetUserByEmailUsernameOrPhone(identifier, roleId string) (domain.User, erro
|
||||||
return user, errors.New("identifier found but role does not match")
|
return user, errors.New("identifier found but role does not match")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
userJSON, _ := json.Marshal(user)
|
||||||
|
if err := config.RedisClient.Set(ctx, cacheKey, userJSON, 1*time.Hour).Err(); err != nil {
|
||||||
|
log.Printf("Redis Set error: %v", err)
|
||||||
|
}
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUserByID(userID string) (domain.User, error) {
|
func GetUserByID(userID string) (domain.User, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
cacheKey := fmt.Sprintf("user:%s", userID)
|
||||||
var user domain.User
|
var user domain.User
|
||||||
if err := config.DB.
|
|
||||||
Preload("Role").
|
cachedUser, err := config.RedisClient.Get(ctx, cacheKey).Result()
|
||||||
Where("id = ?", userID).
|
if err == nil {
|
||||||
First(&user).Error; err != nil {
|
if err := json.Unmarshal([]byte(cachedUser), &user); err == nil {
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := config.DB.Preload("Role").Where("id = ?", userID).First(&user).Error; err != nil {
|
||||||
return user, errors.New("user not found")
|
return user, errors.New("user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("User ID: %s, Role: %v\n", user.ID, user.Role)
|
userJSON, _ := json.Marshal(user)
|
||||||
|
if err := config.RedisClient.Set(ctx, cacheKey, userJSON, 1*time.Hour).Err(); err != nil {
|
||||||
|
log.Printf("Redis Set error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateUser(user *domain.User) error {
|
func UpdateUser(user *domain.User) error {
|
||||||
|
|
||||||
if err := config.DB.Save(user).Error; err != nil {
|
if err := config.DB.Save(user).Error; err != nil {
|
||||||
return errors.New("failed to update user")
|
return errors.New("failed to update user")
|
||||||
}
|
}
|
||||||
|
cacheKey := fmt.Sprintf("user:%s", user.ID)
|
||||||
|
if err := config.RedisClient.Del(context.Background(), cacheKey).Err(); err != nil {
|
||||||
|
log.Printf("Redis Del error: %v", err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,5 +167,10 @@ func UpdateUserPassword(userID, newPassword string) error {
|
||||||
return errors.New("failed to update password")
|
return errors.New("failed to update password")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheKey := fmt.Sprintf("user:%s", userID)
|
||||||
|
if err := config.RedisClient.Del(context.Background(), cacheKey).Err(); err != nil {
|
||||||
|
log.Printf("Redis Del error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package repositories
|
package repositories
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pahmiudahgede/senggoldong/config"
|
"github.com/pahmiudahgede/senggoldong/config"
|
||||||
"github.com/pahmiudahgede/senggoldong/domain"
|
"github.com/pahmiudahgede/senggoldong/domain"
|
||||||
|
@ -17,12 +20,30 @@ func CreatePin(pin *domain.UserPin) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPinByUserID(userID string) (domain.UserPin, error) {
|
func GetPinByUserID(userID string) (domain.UserPin, error) {
|
||||||
var pin domain.UserPin
|
|
||||||
err := config.DB.Where("user_id = ?", userID).First(&pin).Error
|
ctx := context.Background()
|
||||||
if err != nil {
|
redisClient := config.RedisClient
|
||||||
return pin, errors.New("PIN tidak ditemukan")
|
|
||||||
|
redisKey := fmt.Sprintf("user_pin:%s", userID)
|
||||||
|
|
||||||
|
pin, err := redisClient.Get(ctx, redisKey).Result()
|
||||||
|
if err == nil {
|
||||||
|
|
||||||
|
return domain.UserPin{
|
||||||
|
UserID: userID,
|
||||||
|
Pin: pin,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
return pin, nil
|
|
||||||
|
var dbPin domain.UserPin
|
||||||
|
err = config.DB.Where("user_id = ?", userID).First(&dbPin).Error
|
||||||
|
if err != nil {
|
||||||
|
return dbPin, errors.New("PIN tidak ditemukan")
|
||||||
|
}
|
||||||
|
|
||||||
|
redisClient.Set(ctx, redisKey, dbPin.Pin, 5*time.Minute)
|
||||||
|
|
||||||
|
return dbPin, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdatePin(userID string, newPin string) (domain.UserPin, error) {
|
func UpdatePin(userID string, newPin string) (domain.UserPin, error) {
|
||||||
|
@ -44,5 +65,8 @@ func UpdatePin(userID string, newPin string) (domain.UserPin, error) {
|
||||||
return pin, err
|
return pin, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
redisClient := config.RedisClient
|
||||||
|
redisClient.Del(context.Background(), fmt.Sprintf("user_pin:%s", userID))
|
||||||
|
|
||||||
return pin, nil
|
return pin, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/pahmiudahgede/senggoldong/config"
|
||||||
"github.com/pahmiudahgede/senggoldong/domain"
|
"github.com/pahmiudahgede/senggoldong/domain"
|
||||||
"github.com/pahmiudahgede/senggoldong/dto"
|
"github.com/pahmiudahgede/senggoldong/dto"
|
||||||
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
||||||
|
@ -25,15 +30,32 @@ func CreateAddress(userID string, input dto.AddressInput) (domain.Address, error
|
||||||
return domain.Address{}, err
|
return domain.Address{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheKey := fmt.Sprintf("address:user:%s", userID)
|
||||||
|
config.RedisClient.Del(context.Background(), cacheKey)
|
||||||
|
|
||||||
return address, nil
|
return address, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAllAddressesByUserID(userID string) ([]domain.Address, error) {
|
func GetAllAddressesByUserID(userID string) ([]domain.Address, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
cacheKey := fmt.Sprintf("address:user:%s", userID)
|
||||||
|
|
||||||
|
cachedAddresses, err := config.RedisClient.Get(ctx, cacheKey).Result()
|
||||||
|
if err == nil {
|
||||||
|
var addresses []domain.Address
|
||||||
|
if json.Unmarshal([]byte(cachedAddresses), &addresses) == nil {
|
||||||
|
return addresses, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addresses, err := repositories.GetAddressesByUserID(userID)
|
addresses, err := repositories.GetAddressesByUserID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addressesJSON, _ := json.Marshal(addresses)
|
||||||
|
config.RedisClient.Set(ctx, cacheKey, addressesJSON, time.Hour).Err()
|
||||||
|
|
||||||
return addresses, nil
|
return addresses, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +68,6 @@ func GetAddressByID(addressID string) (domain.Address, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateAddress(addressID string, input dto.AddressInput) (domain.Address, error) {
|
func UpdateAddress(addressID string, input dto.AddressInput) (domain.Address, error) {
|
||||||
|
|
||||||
address, err := repositories.GetAddressByID(addressID)
|
address, err := repositories.GetAddressByID(addressID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address, errors.New("address not found")
|
return address, errors.New("address not found")
|
||||||
|
@ -65,13 +86,25 @@ func UpdateAddress(addressID string, input dto.AddressInput) (domain.Address, er
|
||||||
return updatedAddress, errors.New("failed to update address")
|
return updatedAddress, errors.New("failed to update address")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheKey := fmt.Sprintf("address:user:%s", address.UserID)
|
||||||
|
config.RedisClient.Del(context.Background(), cacheKey)
|
||||||
|
|
||||||
return updatedAddress, nil
|
return updatedAddress, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteAddress(addressID string) error {
|
func DeleteAddress(addressID string) error {
|
||||||
err := repositories.DeleteAddress(addressID)
|
address, err := repositories.GetAddressByID(addressID)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("address not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = repositories.DeleteAddress(addressID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("failed to delete address")
|
return errors.New("failed to delete address")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheKey := fmt.Sprintf("address:user:%s", address.UserID)
|
||||||
|
config.RedisClient.Del(context.Background(), cacheKey)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterUser(username, name, email, phone, password, confirmPassword, roleId string) error {
|
func RegisterUser(username, name, email, phone, password, confirmPassword, roleId string) error {
|
||||||
|
|
||||||
if password != confirmPassword {
|
if password != confirmPassword {
|
||||||
return errors.New("password dan confirm password tidak cocok")
|
return errors.New("password dan confirm password tidak cocok")
|
||||||
}
|
}
|
||||||
|
@ -48,7 +47,6 @@ func LoginUser(identifier, password string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const roleId = ""
|
const roleId = ""
|
||||||
|
|
||||||
user, err := repositories.GetUserByEmailUsernameOrPhone(identifier, roleId)
|
user, err := repositories.GetUserByEmailUsernameOrPhone(identifier, roleId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("invalid email/username/phone or password")
|
return "", errors.New("invalid email/username/phone or password")
|
||||||
|
@ -71,7 +69,6 @@ func generateJWT(userID, role string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
|
||||||
t, err := token.SignedString([]byte(os.Getenv("API_KEY")))
|
t, err := token.SignedString([]byte(os.Getenv("API_KEY")))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
|
@ -89,7 +86,6 @@ func GetUserByID(userID string) (domain.User, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateUser(userID, email, username, name, phone string) error {
|
func UpdateUser(userID, email, username, name, phone string) error {
|
||||||
|
|
||||||
user, err := repositories.GetUserByID(userID)
|
user, err := repositories.GetUserByID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("user not found")
|
return errors.New("user not found")
|
||||||
|
@ -129,7 +125,6 @@ func UpdateUser(userID, email, username, name, phone string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdatePassword(userID, oldPassword, newPassword string) error {
|
func UpdatePassword(userID, oldPassword, newPassword string) error {
|
||||||
|
|
||||||
user, err := repositories.GetUserByID(userID)
|
user, err := repositories.GetUserByID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("user not found")
|
return errors.New("user not found")
|
||||||
|
|
|
@ -9,14 +9,6 @@ import (
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetPinByUserID(userID string) (domain.UserPin, error) {
|
|
||||||
pin, err := repositories.GetPinByUserID(userID)
|
|
||||||
if err != nil {
|
|
||||||
return pin, errors.New("PIN tidak ditemukan")
|
|
||||||
}
|
|
||||||
return pin, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreatePin(userID string, input dto.PinInput) (domain.UserPin, error) {
|
func CreatePin(userID string, input dto.PinInput) (domain.UserPin, error) {
|
||||||
|
|
||||||
hashedPin, err := bcrypt.GenerateFromPassword([]byte(input.Pin), bcrypt.DefaultCost)
|
hashedPin, err := bcrypt.GenerateFromPassword([]byte(input.Pin), bcrypt.DefaultCost)
|
||||||
|
@ -37,7 +29,17 @@ func CreatePin(userID string, input dto.PinInput) (domain.UserPin, error) {
|
||||||
return pin, nil
|
return pin, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetPinByUserID(userID string) (domain.UserPin, error) {
|
||||||
|
|
||||||
|
pin, err := repositories.GetPinByUserID(userID)
|
||||||
|
if err != nil {
|
||||||
|
return pin, errors.New("PIN tidak ditemukan")
|
||||||
|
}
|
||||||
|
return pin, nil
|
||||||
|
}
|
||||||
|
|
||||||
func UpdatePin(userID string, oldPin string, newPin string) (domain.UserPin, error) {
|
func UpdatePin(userID string, oldPin string, newPin string) (domain.UserPin, error) {
|
||||||
|
|
||||||
pin, err := repositories.GetPinByUserID(userID)
|
pin, err := repositories.GetPinByUserID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pin, errors.New("PIN tidak ditemukan")
|
return pin, errors.New("PIN tidak ditemukan")
|
||||||
|
|
|
@ -18,6 +18,7 @@ func init() {
|
||||||
|
|
||||||
config.InitConfig()
|
config.InitConfig()
|
||||||
config.InitDatabase()
|
config.InitDatabase()
|
||||||
|
config.InitRedis()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue