Compare commits

..

No commits in common. "c23ee933c11fcd6a748ebf68047404cbd532fcf5" and "4ec50cee8a6d1c65483710a2e559056fe2d3bb9e" have entirely different histories.

15 changed files with 44 additions and 234 deletions

View File

@ -1,5 +1,9 @@
package config package config
import (
"legalgo-BE-go/internal/utilities/utils"
)
var ( var (
APP_PORT int APP_PORT int
GRACEFULL_TIMEOUT int GRACEFULL_TIMEOUT int
@ -9,19 +13,16 @@ var (
DB_USER, DB_USER,
DB_PASSWORD, DB_PASSWORD,
DB_NAME, DB_NAME,
DB_PORT, DB_PORT string
SALT_SECURITY string
) )
func InitEnv() { func InitEnv() {
DB_HOST = GetOrDefault("DB_HOST", "localhost") DB_HOST = utils.GetOrDefault("DB_HOST", "localhost")
DB_USER = GetOrDefault("DB_USER", "") DB_USER = utils.GetOrDefault("DB_USER", "")
DB_PASSWORD = GetOrDefault("DB_PASSWORD", "") DB_PASSWORD = utils.GetOrDefault("DB_PASSWORD", "")
DB_NAME = GetOrDefault("DB_NAME", "") DB_NAME = utils.GetOrDefault("DB_NAME", "")
DB_PORT = GetOrDefault("DB_PORT", "") DB_PORT = utils.GetOrDefault("DB_PORT", "")
SALT_SECURITY = GetOrDefault("SALT_SECURITY", "legalgo") APP_PORT = utils.GetOrDefault("APP_PORT", 3000)
GRACEFULL_TIMEOUT = utils.GetOrDefault("GRACEFULL_TIMEOUT", 10)
APP_PORT = GetOrDefault("APP_PORT", 3000)
GRACEFULL_TIMEOUT = GetOrDefault("GRACEFULL_TIMEOUT", 10)
} }

View File

@ -1,29 +0,0 @@
package userrepository
import (
"errors"
authdomain "legalgo-BE-go/internal/domain/auth"
"gorm.io/gorm"
)
func (ur *UserRepository) GetUserProfile(email string) (*authdomain.UserProfile, error) {
var users []authdomain.UserProfile
if email == "" {
return nil, errors.New("email is empty")
}
if err := ur.DB.Table("users u").
Select("u.email, u.id, s.status as subscribe_status, sp.code as subscribe_plan_code, sp.name as subscribe_plan_name").
Joins("join subscribes s on s.id = u.subscribe_id").
Joins("join subscribe_plans sp on s.subscribe_plan_id = sp.id").
Scan(&users).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("user not found")
}
return nil, err
}
return &users[0], nil
}

View File

@ -12,7 +12,6 @@ type UserRepository struct {
type UserIntf interface { type UserIntf interface {
GetUserByEmail(string) (*authdomain.User, error) GetUserByEmail(string) (*authdomain.User, error)
GetUserByID(string) (*authdomain.UserProfile, error) GetUserByID(string) (*authdomain.UserProfile, error)
GetUserProfile(string) (*authdomain.UserProfile, error)
CreateUser(*authdomain.User) (*authdomain.User, error) CreateUser(*authdomain.User) (*authdomain.User, error)
} }

View File

@ -4,9 +4,7 @@ import (
"errors" "errors"
authsvc "legalgo-BE-go/internal/services/auth" authsvc "legalgo-BE-go/internal/services/auth"
"legalgo-BE-go/internal/utilities/response" "legalgo-BE-go/internal/utilities/response"
"legalgo-BE-go/internal/utilities/utils"
"net/http" "net/http"
"strings"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
) )
@ -15,15 +13,14 @@ func GetStaffProfile(
router chi.Router, router chi.Router,
authSvc authsvc.AuthIntf, authSvc authsvc.AuthIntf,
) { ) {
router.Get("/staff/profile", func(w http.ResponseWriter, r *http.Request) { router.Get("/staff/{id}/profile", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
authHeader := r.Header.Get("Authorization") id := chi.URLParam(r, "id")
if id == "" {
if authHeader == "" {
response.ResponseWithErrorCode( response.ResponseWithErrorCode(
ctx, ctx,
w, w,
errors.New("provided auth is empty"), errors.New("provided id is empty"),
response.ErrBadRequest.Code, response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode, response.ErrBadRequest.HttpCode,
"required params is not provided", "required params is not provided",
@ -31,45 +28,7 @@ func GetStaffProfile(
return return
} }
if !strings.HasPrefix(authHeader, "Bearer") { staffProfile, err := authSvc.GetStaffProfile(id)
response.ResponseWithErrorCode(
ctx,
w,
errors.New("invalid authorization token"),
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"invalid required token",
)
return
}
token := strings.Split(authHeader, " ")
if len(token) < 2 {
response.ResponseWithErrorCode(
ctx,
w,
errors.New("invalid authorization"),
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"invalid required token",
)
return
}
destructedToken, err := utils.DestructToken(token[1])
if err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
staffProfile, err := authSvc.GetStaffProfile(destructedToken.Email)
if err != nil { if err != nil {
response.ResponseWithErrorCode( response.ResponseWithErrorCode(
ctx, ctx,
@ -90,15 +49,14 @@ func GetUserProfile(
router chi.Router, router chi.Router,
authSvc authsvc.AuthIntf, authSvc authsvc.AuthIntf,
) { ) {
router.Get("/user/profile", func(w http.ResponseWriter, r *http.Request) { router.Get("/user/{id}/profile", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
authHeader := r.Header.Get("Authorization") id := chi.URLParam(r, "id")
if id == "" {
if authHeader == "" {
response.ResponseWithErrorCode( response.ResponseWithErrorCode(
ctx, ctx,
w, w,
errors.New("provided auth is empty"), errors.New("provided id is empty"),
response.ErrBadRequest.Code, response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode, response.ErrBadRequest.HttpCode,
"required params is not provided", "required params is not provided",
@ -106,45 +64,7 @@ func GetUserProfile(
return return
} }
if !strings.HasPrefix(authHeader, "Bearer") { userProfile, err := authSvc.GetUserProfile(id)
response.ResponseWithErrorCode(
ctx,
w,
errors.New("invalid authorization token"),
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"invalid required token",
)
return
}
token := strings.Split(authHeader, " ")
if len(token) < 2 {
response.ResponseWithErrorCode(
ctx,
w,
errors.New("invalid authorization"),
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"invalid required token",
)
return
}
destructedToken, err := utils.DestructToken(token[1])
if err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
userProfile, err := authSvc.GetUserProfile(destructedToken.Email)
if err != nil { if err != nil {
response.ResponseWithErrorCode( response.ResponseWithErrorCode(
ctx, ctx,

View File

@ -1,6 +0,0 @@
package authdomain
type AuthToken struct {
Email string
SessionID string
}

View File

@ -4,7 +4,7 @@ type JWTClaim string
const ( const (
TYPE JWTClaim = "type" TYPE JWTClaim = "type"
EMAIL JWTClaim = "email" USERNAME JWTClaim = "username"
EXPIRED_AT JWTClaim = "exp" EXPIRED_AT JWTClaim = "exp"
SESSION_ID JWTClaim = "sid" SESSION_ID JWTClaim = "sid"
ISSUED_AT JWTClaim = "iat" ISSUED_AT JWTClaim = "iat"

View File

@ -2,8 +2,8 @@ package authsvc
import authdomain "legalgo-BE-go/internal/domain/auth" import authdomain "legalgo-BE-go/internal/domain/auth"
func (as *AuthSvc) GetStaffProfile(email string) (*authdomain.StaffProfile, error) { func (as *AuthSvc) GetStaffProfile(id string) (*authdomain.StaffProfile, error) {
staff, err := as.staffRepo.GetStaffByEmail(email) staff, err := as.staffRepo.GetStaffByID(id)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -2,8 +2,8 @@ package authsvc
import authdomain "legalgo-BE-go/internal/domain/auth" import authdomain "legalgo-BE-go/internal/domain/auth"
func (as *AuthSvc) GetUserProfile(email string) (*authdomain.UserProfile, error) { func (as *AuthSvc) GetUserProfile(id string) (*authdomain.UserProfile, error) {
user, err := as.userRepo.GetUserProfile(email) user, err := as.userRepo.GetUserByID(id)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -5,8 +5,6 @@ import (
authdomain "legalgo-BE-go/internal/domain/auth" authdomain "legalgo-BE-go/internal/domain/auth"
"legalgo-BE-go/internal/utilities/utils" "legalgo-BE-go/internal/utilities/utils"
"github.com/google/uuid"
) )
func (sv *AuthSvc) LoginAsStaff(spec authdomain.LoginReq) (string, error) { func (sv *AuthSvc) LoginAsStaff(spec authdomain.LoginReq) (string, error) {
@ -20,12 +18,7 @@ func (sv *AuthSvc) LoginAsStaff(spec authdomain.LoginReq) (string, error) {
return "", errors.New("wrong password") return "", errors.New("wrong password")
} }
authToken := authdomain.AuthToken{ token, err := utils.GenerateToken(staff.Email)
Email: staff.Email,
SessionID: uuid.NewString(),
}
token, err := utils.GenerateToken(authToken)
if err != nil { if err != nil {
return "", errors.New(err.Error()) return "", errors.New(err.Error())
} }

View File

@ -5,8 +5,6 @@ import (
authdomain "legalgo-BE-go/internal/domain/auth" authdomain "legalgo-BE-go/internal/domain/auth"
"legalgo-BE-go/internal/utilities/utils" "legalgo-BE-go/internal/utilities/utils"
"github.com/google/uuid"
) )
func (a *AuthSvc) LoginAsUser(spec authdomain.LoginReq) (string, error) { func (a *AuthSvc) LoginAsUser(spec authdomain.LoginReq) (string, error) {
@ -20,12 +18,7 @@ func (a *AuthSvc) LoginAsUser(spec authdomain.LoginReq) (string, error) {
return "", errors.New("wrong password") return "", errors.New("wrong password")
} }
authToken := authdomain.AuthToken{ token, err := utils.GenerateToken(user.Email)
Email: user.Email,
SessionID: uuid.NewString(),
}
token, err := utils.GenerateToken(authToken)
if err != nil { if err != nil {
return "", errors.New(err.Error()) return "", errors.New(err.Error())
} }

View File

@ -19,24 +19,19 @@ func (a *AuthSvc) RegisterStaff(spec authdomain.RegisterStaffReq) (string, error
return "", err return "", err
} }
staff := authdomain.Staff{ user := authdomain.Staff{
ID: uuid.NewString(), ID: uuid.NewString(),
Email: spec.Email, Email: spec.Email,
Password: hashedPwd, Password: hashedPwd,
Username: spec.Username, Username: spec.Username,
} }
_, err = a.staffRepo.Create(&staff) _, err = a.staffRepo.Create(&user)
if err != nil { if err != nil {
return "", errors.New(err.Error()) return "", errors.New(err.Error())
} }
authToken := authdomain.AuthToken{ token, err := utils.GenerateToken(spec.Email)
Email: staff.Email,
SessionID: uuid.NewString(),
}
token, err := utils.GenerateToken(authToken)
if err != nil { if err != nil {
return "", errors.New(err.Error()) return "", errors.New(err.Error())
} }

View File

@ -48,12 +48,7 @@ func (a *AuthSvc) RegisterUser(spec authdomain.RegisterUserReq) (string, error)
return "", errors.New(err.Error()) return "", errors.New(err.Error())
} }
authToken := authdomain.AuthToken{ token, err := utils.GenerateToken(spec.Email)
Email: user.Email,
SessionID: uuid.NewString(),
}
token, err := utils.GenerateToken(authToken)
if err != nil { if err != nil {
return "", errors.New(err.Error()) return "", errors.New(err.Error())
} }

View File

@ -1,4 +1,4 @@
package config package utils
import ( import (
"os" "os"

View File

@ -1,18 +1,15 @@
package utils package utils
import ( import (
"errors"
"fmt"
"time" "time"
"legalgo-BE-go/config"
authdomain "legalgo-BE-go/internal/domain/auth"
jwtclaimenum "legalgo-BE-go/internal/enums/jwt"
timeutils "legalgo-BE-go/internal/utilities/time_utils" timeutils "legalgo-BE-go/internal/utilities/time_utils"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
) )
var jwtSecret = []byte("secret jwt key") // TODO: change later from env
type ClaimOption func(options jwt.MapClaims) type ClaimOption func(options jwt.MapClaims)
// func GenerateToken(options ...ClaimOption) (string, error) { // func GenerateToken(options ...ClaimOption) (string, error) {
@ -31,60 +28,12 @@ type ClaimOption func(options jwt.MapClaims)
// return token.SignedString(jwtSecret) // return token.SignedString(jwtSecret)
// } // }
func GenerateToken(data authdomain.AuthToken) (string, error) { func GenerateToken(email string) (string, error) {
now := timeutils.Now() now := timeutils.Now()
token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims)
claims["email"] = email
claims["exp"] = now.Add(time.Hour).Unix()
claims := jwt.MapClaims{ return token.SignedString(jwtSecret)
"email": data.Email,
"session_id": data.SessionID,
"exp": now.Add(1 * time.Hour).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(config.SALT_SECURITY))
}
func parseToken(s string) (*jwt.Token, error) {
return jwt.Parse(s, func(t *jwt.Token) (any, error) {
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
errMsg := fmt.Sprintf("unexpected signing method: %v", t.Header["alg"])
return nil, errors.New(errMsg)
}
return []byte(config.SALT_SECURITY), nil
})
}
func DestructToken(s string) (authdomain.AuthToken, error) {
var data authdomain.AuthToken
token, err := parseToken(s)
if err != nil {
return data, err
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
return data, errors.New("failed to parse token")
}
if !token.Valid {
return data, errors.New("invalid token")
}
email, ok := claims[string(jwtclaimenum.EMAIL)].(string)
if !ok {
return data, errors.New("invalid email")
}
sessionId, ok := claims[string(jwtclaimenum.SESSION_ID)].(string)
data = authdomain.AuthToken{
Email: email,
SessionID: sessionId,
}
return data, nil
} }

View File

@ -120,7 +120,7 @@ paths:
message: message:
type: string type: string
/staff/profile: /staff/{id}/profile:
get: get:
summary: "get staff profile" summary: "get staff profile"
tags: tags:
@ -164,7 +164,7 @@ paths:
message: message:
type: string type: string
/user/profile: /user/{id}/profile:
get: get:
summary: "get staff profile" summary: "get staff profile"
tags: tags: