Update JWT
This commit is contained in:
parent
54aeb3568a
commit
1db200435e
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Ignore environment config
|
||||
.env
|
||||
16
Dockerfile
Normal file
16
Dockerfile
Normal file
@ -0,0 +1,16 @@
|
||||
# Dockerfile
|
||||
FROM golang:1.24.4
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY go.mod ./
|
||||
COPY go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN go build -o main ./cmd/main.go
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["./main"]
|
||||
@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"BE-MiniERP/middlewares"
|
||||
"BE-MiniERP/modules/auth"
|
||||
"BE-MiniERP/modules/inventory"
|
||||
"BE-MiniERP/modules/sales"
|
||||
@ -10,6 +11,10 @@ import (
|
||||
|
||||
func SetupRoutes(app *fiber.App) {
|
||||
auth.RegisterRoutes(app.Group("/auth"))
|
||||
|
||||
app.Use("/inventory", middlewares.JWTProtected())
|
||||
app.Use("/sales", middlewares.JWTProtected())
|
||||
|
||||
inventory.RegisterRoutes(app.Group("/inventory"))
|
||||
sales.RegisterRoutes(app.Group("/sales"))
|
||||
}
|
||||
|
||||
@ -4,12 +4,15 @@ import (
|
||||
"log"
|
||||
|
||||
"BE-MiniERP/api"
|
||||
"BE-MiniERP/config"
|
||||
"BE-MiniERP/database" // pastikan ini sesuai dengan module di go.mod
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Inisialisasi konfigurasi
|
||||
config.InitConfig()
|
||||
// Koneksi database
|
||||
database.Connect()
|
||||
|
||||
|
||||
@ -1,15 +1,45 @@
|
||||
package config
|
||||
|
||||
import "os"
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
DBUrl string
|
||||
JWTSecret string
|
||||
DBHost string
|
||||
DBPort string
|
||||
DBUser string
|
||||
DBPassword string
|
||||
DBName string
|
||||
DBSSLMode string
|
||||
}
|
||||
|
||||
func GetConfig() Config {
|
||||
return Config{
|
||||
DBUrl: os.Getenv("DB_URL"),
|
||||
JWTSecret: os.Getenv("JWT_SECRET"),
|
||||
var appConfig = &Config{}
|
||||
|
||||
func InitConfig() {
|
||||
// Load .env file
|
||||
err := godotenv.Load()
|
||||
if err != nil {
|
||||
log.Println("Warning: .env file not found, using system environment variables.")
|
||||
}
|
||||
|
||||
// Load config from env
|
||||
appConfig.JWTSecret = os.Getenv("JWT_SECRET")
|
||||
appConfig.DBHost = os.Getenv("DB_HOST")
|
||||
appConfig.DBPort = os.Getenv("DB_PORT")
|
||||
appConfig.DBUser = os.Getenv("DB_USER")
|
||||
appConfig.DBPassword = os.Getenv("DB_PASSWORD")
|
||||
appConfig.DBName = os.Getenv("DB_NAME")
|
||||
appConfig.DBSSLMode = os.Getenv("DB_SSLMODE")
|
||||
|
||||
if appConfig.JWTSecret == "" || appConfig.DBHost == "" {
|
||||
log.Fatal("Required environment variables are missing")
|
||||
}
|
||||
}
|
||||
|
||||
func GetConfig() *Config {
|
||||
return appConfig
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ CREATE TABLE users (
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE master_product_category (
|
||||
CREATE TABLE product_categories (
|
||||
id SERIAL PRIMARY KEY,
|
||||
code VARCHAR(50),
|
||||
name VARCHAR(100),
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"BE-MiniERP/config"
|
||||
auth_models "BE-MiniERP/modules/auth/models"
|
||||
inventory_models "BE-MiniERP/modules/inventory/models"
|
||||
sales_models "BE-MiniERP/modules/sales/models"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"gorm.io/driver/postgres"
|
||||
@ -13,18 +15,22 @@ import (
|
||||
var DB *gorm.DB
|
||||
|
||||
func Connect() {
|
||||
dsn := "host=10.5.50.9 user=probindo password=Pr08ind0 dbname=erp port=5432 sslmode=disable"
|
||||
cfg := config.GetConfig()
|
||||
|
||||
dsn := fmt.Sprintf(
|
||||
"host=%s user=%s password=%s dbname=%s port=%s sslmode=%s",
|
||||
cfg.DBHost, cfg.DBUser, cfg.DBPassword, cfg.DBName, cfg.DBPort, cfg.DBSSLMode,
|
||||
)
|
||||
|
||||
var err error
|
||||
DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
log.Fatal("Failed to connect to DB:", err)
|
||||
}
|
||||
|
||||
// Auto migrate models
|
||||
err = DB.AutoMigrate(
|
||||
// Auth
|
||||
&auth_models.User{},
|
||||
|
||||
// Inventory
|
||||
&inventory_models.Product{},
|
||||
&inventory_models.ProductCategory{},
|
||||
&inventory_models.Collection{},
|
||||
@ -34,8 +40,6 @@ func Connect() {
|
||||
&inventory_models.ProductionOrder{},
|
||||
&inventory_models.Warehouse{},
|
||||
&inventory_models.StockMovement{},
|
||||
|
||||
// Sales
|
||||
&sales_models.Customer{},
|
||||
&sales_models.SalesOrder{},
|
||||
&sales_models.SalesOrderItem{},
|
||||
|
||||
10
docker-compose.yml
Normal file
10
docker-compose.yml
Normal file
@ -0,0 +1,10 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
container_name: be-minierp-container
|
||||
ports:
|
||||
- "8080:3000"
|
||||
environment:
|
||||
- DATABASE_URL=host=10.5.50.9 user=probindo password=Pr08ind0 dbname=erp port=5432 sslmode=disable
|
||||
1
go.mod
1
go.mod
@ -14,6 +14,7 @@ require (
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
|
||||
2
go.sum
2
go.sum
@ -19,6 +19,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
|
||||
@ -12,7 +12,9 @@ func JWTProtected() fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
authHeader := c.Get("Authorization")
|
||||
if authHeader == "" {
|
||||
return c.SendStatus(fiber.StatusUnauthorized)
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
||||
"message": "Missing Authorization header",
|
||||
})
|
||||
}
|
||||
|
||||
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
|
||||
@ -21,10 +23,19 @@ func JWTProtected() fiber.Handler {
|
||||
})
|
||||
|
||||
if err != nil || !token.Valid {
|
||||
return c.SendStatus(fiber.StatusUnauthorized)
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
||||
"message": "Invalid or expired token",
|
||||
})
|
||||
}
|
||||
|
||||
c.Locals("user", token.Claims)
|
||||
claims, ok := token.Claims.(jwt.MapClaims)
|
||||
if !ok {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
||||
"message": "Invalid token claims",
|
||||
})
|
||||
}
|
||||
|
||||
c.Locals("user", claims)
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,27 +1,21 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"BE-MiniERP/config"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
var jwtKey = []byte("supersecret") // sebaiknya dari env
|
||||
|
||||
type Claims struct {
|
||||
UserID uint `json:"user_id"`
|
||||
Role string `json:"role"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func GenerateJWT(userID uint, role string) (string, error) {
|
||||
claims := &Claims{
|
||||
UserID: userID,
|
||||
Role: role,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
|
||||
},
|
||||
claims := jwt.MapClaims{
|
||||
"user_id": userID,
|
||||
"role": role,
|
||||
"exp": time.Now().Add(time.Hour * 1).Unix(), // expired dalam 1 jam
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
return token.SignedString(jwtKey)
|
||||
|
||||
// INI PALING PENTING ⬇️
|
||||
return token.SignedString([]byte(config.GetConfig().JWTSecret))
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user