feat: login service and implement database storage

This commit is contained in:
ericprd 2025-02-23 22:34:26 +08:00
parent a95a5ca521
commit 5fcb5c2cd5
24 changed files with 579 additions and 11 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
bin
.env

102
README.md Normal file
View File

@ -0,0 +1,102 @@
# Instructions: Setup Go Version 1.24.0, Manage Dependencies, Build, and Run
## Prerequisites
Before proceeding, make sure you have the following installed on your computer:
- **Go (Golang) version 1.24.0**
- **Make**
## Steps to Install Go 1.24.0
### For Windows:
1. Download the installer from [official Go website](https://golang.org/dl/).
2. Run the downloaded `.msi` file and follow the installation wizard.
3. During installation, you may be prompted to set the `GOPATH` and `GOROOT`. Choose the appropriate settings
based on your preference or keep the default values.
### For macOS:
1. Open Terminal.
2. Download the package using Homebrew (if not installed, visit [Homebrew website](https://brew.sh/) for
installation instructions):
```bash
brew install go@1.24
```
3. Link the installed version to your PATH:
```bash
brew link --overwrite --force go@1.24
```
### For Linux:
1. Open Terminal.
2. Download the appropriate tarball from [official Go website](https://golang.org/dl/).
3. Extract the downloaded archive:
```bash
tar -C /usr/local -xzf go1.24.linux-amd64.tar.gz
```
4. Add Go to your PATH by editing your shell configuration file (e.g., `.bashrc`, `.zshrc`):
```bash
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
```
## Verify Installation
After installation, verify that Go 1.24.0 is installed correctly by running:
```bash
go version
```
You should see an output like `go version go1.24 darwin/amd64` (or similar, depending on your OS).
## Install Make (if not already installed)
### For Windows:
- Download and install [Make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm).
- Add the installation directory to your PATH.
### For macOS:
1. Open Terminal.
2. Install Make using Homebrew:
```bash
brew install make
```
### For Linux:
Make is usually pre-installed on most Linux distributions. If it's not installed, you can install it using your
package manager (e.g., `sudo apt-get install make` for Ubuntu).
## Navigate to Your Go Project Directory
Open Terminal and navigate to the root directory of your Go project.
## Resolve Dependencies with `go mod tidy`
Run the following command to download and resolve all dependencies specified in your `go.mod` file:
```bash
go mod tidy
```
## Build the Binary Using `make build`
Run the following command to build your project. The binary will be placed in the `bin` folder.
```bash
make build
```
## Run the Program Using `make run`
Finally, you can run your program using:
```bash
make run
```
This command will compile and execute your Go application.
---
**Note:** Ensure that your `Makefile` is correctly set up to handle these commands. If not, you may need to create
or adjust it accordingly.
```
Please follow the above instructions to set up Go version 1.24.0, manage dependencies using `go mod tidy`, build a
binary with `make build`, and run your application with `make run`.

View File

@ -1,17 +1,61 @@
package main
import (
"context"
"fmt"
"log"
"github.com/ardeman/project-legalgo-go/database"
repository "github.com/ardeman/project-legalgo-go/internal/accessor"
internalhttp "github.com/ardeman/project-legalgo-go/internal/api/http"
pkgconfig "github.com/ardeman/project-legalgo-go/internal/config"
"github.com/ardeman/project-legalgo-go/internal/services"
"github.com/go-chi/chi/v5"
"github.com/joho/godotenv"
"go.uber.org/fx"
)
func main() {
fx.New(
internalhttp.Module,
fx.Invoke(func(apiRouter chi.Router) {
pkgconfig.Router(apiRouter)
}),
)
func init() {
if err := godotenv.Load(); err != nil {
log.Fatal("cannot load environment file")
}
}
func run(lc fx.Lifecycle, db *database.DB, apiRouter chi.Router) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
fmt.Println("Application has started...")
// Run migration
if err := db.Migrate(); err != nil {
log.Fatal("Migration failed: ", err)
}
pkgconfig.Router(apiRouter)
return nil
},
OnStop: func(ctx context.Context) error {
fmt.Println("Shutting down...")
return nil
},
})
}
func main() {
app := fx.New(
database.Module,
repository.Module,
internalhttp.Module,
services.Module,
fx.Invoke(run),
)
if err := app.Start(context.Background()); err != nil {
log.Fatal("Error starting app:", err)
}
// Wait for the app to stop gracefully
if err := app.Stop(context.Background()); err != nil {
log.Fatal("Error stopping app:", err)
}
}

7
database/module.go Normal file
View File

@ -0,0 +1,7 @@
package database
import "go.uber.org/fx"
var Module = fx.Module("database", fx.Provide(
NewDB,
))

43
database/new_db.go Normal file
View File

@ -0,0 +1,43 @@
package database
import (
"fmt"
"os"
staffmodel "github.com/ardeman/project-legalgo-go/database/staff"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type DB struct {
*gorm.DB
}
func NewDB() (*DB, error) {
var (
host = os.Getenv("DB_HOST")
user = os.Getenv("DB_USER")
password = os.Getenv("DB_PASSWORD")
dbName = os.Getenv("DB_NAME")
dbPort = os.Getenv("DB_PORT")
)
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%v sslmode=disable", host, user, password, dbName, dbPort)
if dsn == "" {
return nil, fmt.Errorf("DATABASE_URL environment is not set")
}
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
return nil, fmt.Errorf("failed to connect to database: %w", err)
}
return &DB{db}, nil
}
func (db *DB) Migrate() error {
// Auto Migrate the User model
return db.AutoMigrate(&staffmodel.Staff{})
}

11
database/staff/model.go Normal file
View File

@ -0,0 +1,11 @@
package staffmodel
import (
"github.com/google/uuid"
)
type Staff struct {
ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"`
Email string `gorm:"unique,not null" json:"email"`
Password string `gorm:"not null" json:"password"`
}

21
go.mod
View File

@ -7,12 +7,32 @@ require (
go.uber.org/fx v1.23.0
)
require (
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.7.2 // indirect
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 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
golang.org/x/crypto v0.34.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/text v0.22.0 // indirect
gorm.io/driver/postgres v1.5.11 // indirect
)
require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/go-chi/chi v1.5.5
github.com/go-chi/chi/v5 v5.2.1 // indirect
github.com/go-chi/cors v1.2.1
github.com/go-playground/validator/v10 v10.25.0
github.com/google/uuid v1.6.0
github.com/redis/go-redis/v9 v9.7.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
go.uber.org/dig v1.18.0 // indirect
@ -20,4 +40,5 @@ require (
go.uber.org/zap v1.26.0 // indirect
golang.org/x/sync v0.11.0
golang.org/x/sys v0.30.0 // indirect
gorm.io/gorm v1.25.12
)

41
go.sum
View File

@ -5,14 +5,40 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/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.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE=
github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8=
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
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/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.7.1 h1:4LhKRCIduqXqtvCUlaq9c8bdHOkICjDMrr1+Zb3osAc=
@ -20,6 +46,7 @@ github.com/redis/go-redis/v9 v9.7.1/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93Ge
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
@ -33,12 +60,26 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
golang.org/x/crypto v0.34.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314=
gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=

View File

@ -0,0 +1,10 @@
package repository
import (
staffrepository "github.com/ardeman/project-legalgo-go/internal/accessor/staff"
"go.uber.org/fx"
)
var Module = fx.Module("repository", fx.Provide(
staffrepository.New,
))

View File

@ -0,0 +1,25 @@
package staffrepository
import (
"errors"
staffmodel "github.com/ardeman/project-legalgo-go/database/staff"
"gorm.io/gorm"
)
func (sr *StaffRepository) GetStaff(email string) (*staffmodel.Staff, error) {
var staff staffmodel.Staff
if email == "" {
return nil, errors.New("email is empty")
}
if err := sr.DB.Where("email = ?", email).First(&staff).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("staff not found")
}
return nil, err
}
return &staff, nil
}

View File

@ -0,0 +1,18 @@
package staffrepository
import (
"github.com/ardeman/project-legalgo-go/database"
staffmodel "github.com/ardeman/project-legalgo-go/database/staff"
)
type StaffRepository struct {
DB *database.DB
}
type StaffInterface interface {
GetStaff(string) (*staffmodel.Staff, error)
}
func New(db *database.DB) StaffInterface {
return &StaffRepository{db}
}

View File

@ -0,0 +1,67 @@
package authhttp
import (
"net/http"
domain "github.com/ardeman/project-legalgo-go/internal/domain/auth"
serviceauth "github.com/ardeman/project-legalgo-go/internal/services/auth"
"github.com/ardeman/project-legalgo-go/internal/utilities/response"
"github.com/ardeman/project-legalgo-go/internal/utilities/utils"
"github.com/go-chi/chi/v5"
"github.com/go-playground/validator/v10"
)
func LoginStaff(
router chi.Router,
authSvc serviceauth.LoginStaffIntf,
validate *validator.Validate,
) {
router.Post("/staff/login", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var request domain.StaffLoginReq
if err := utils.UnmarshalBody(r, &request); err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"failed to unmarshal request",
)
return
}
if err := validate.Struct(request); err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.(validator.ValidationErrors).Error(),
)
return
}
token, err := authSvc.LoginAsStaff(request.Email)
if err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
responsePayload := &domain.StaffLoginResponse{
Token: token,
}
response.RespondJsonSuccess(ctx, w, responsePayload)
})
}

View File

@ -0,0 +1,9 @@
package authhttp
import "go.uber.org/fx"
var Module = fx.Module("auth-api",
fx.Invoke(
LoginStaff,
),
)

View File

@ -1,15 +1,21 @@
package internalhttp
import (
authhttp "github.com/ardeman/project-legalgo-go/internal/api/http/auth"
"github.com/go-chi/chi/v5"
"github.com/go-chi/cors"
"github.com/go-playground/validator/v10"
"go.uber.org/fx"
chimware "github.com/go-chi/chi/v5/middleware"
)
var Module = fx.Module("router",
fx.Provide(initRouter),
fx.Provide(
initRouter,
validator.New,
),
authhttp.Module,
)
func initRouter() chi.Router {

View File

@ -0,0 +1,10 @@
package domain
type StaffLoginReq struct {
Email string `json:"email" validate:"required"`
Password string `json:"password" validate:"required"`
}
type StaffLoginResponse struct {
Token string `json:"token"`
}

View File

@ -0,0 +1,19 @@
package serviceauth
import staffrepository "github.com/ardeman/project-legalgo-go/internal/accessor/staff"
type LoginStaffSvc struct {
staffAcs staffrepository.StaffInterface
}
type LoginStaffIntf interface {
LoginAsStaff(string) (string, error)
}
func New(
staffAcs staffrepository.StaffInterface,
) LoginStaffIntf {
return &LoginStaffSvc{
staffAcs: staffAcs,
}
}

View File

@ -0,0 +1,21 @@
package serviceauth
import (
"errors"
"github.com/ardeman/project-legalgo-go/internal/utilities/utils"
)
func (sv *LoginStaffSvc) LoginAsStaff(email string) (string, error) {
staff, err := sv.staffAcs.GetStaff(email)
if err != nil {
return "", errors.New(err.Error())
}
token, err := utils.GenerateToken2(staff.Email)
if err != nil {
return "", errors.New(err.Error())
}
return token, nil
}

View File

@ -0,0 +1,12 @@
package services
import (
serviceauth "github.com/ardeman/project-legalgo-go/internal/services/auth"
"go.uber.org/fx"
)
var Module = fx.Module("services",
fx.Provide(
serviceauth.New,
),
)

View File

@ -0,0 +1,15 @@
package response
import "net/http"
type ErrorCode struct {
Code string
Message string
HttpCode int
}
var (
// 4xx
ErrBadRequest = ErrorCode{Code: "BAD_REQUEST", Message: "BAD_REQUEST", HttpCode: http.StatusBadRequest}
ErrDBRequest = ErrorCode{Code: "BAD_DB_REQUEST", Message: "DB_ERROR", HttpCode: http.StatusBadRequest}
)

View File

@ -0,0 +1,23 @@
package response
import (
"context"
"encoding/json"
"net/http"
)
func ResponseWithErrorCode(ctx context.Context, w http.ResponseWriter,
err error, code string, statusCode int, message string) {
setDefaultHeaders(ctx, w.Header())
w.WriteHeader(statusCode)
b, _ := json.Marshal(ErrorResponse{
Error: ErrorResponseData{
Code: code,
Message: message,
},
})
w.Write(b)
}

View File

@ -0,0 +1,19 @@
package response
import (
"context"
"net/http"
)
type ErrorResponseData struct {
Code string `json:"code"`
Message string `json:"message"`
}
type ErrorResponse struct {
Error ErrorResponseData `json:"error"`
}
func setDefaultHeaders(ctx context.Context, headers http.Header) {
headers.Set("Content-Type", "application/json")
}

View File

@ -0,0 +1,23 @@
package response
import (
"context"
"encoding/json"
"net/http"
)
type Response[T any] struct {
Data T `json:"data"`
}
func RespondJsonSuccess[T any](ctx context.Context, w http.ResponseWriter, data T) {
setDefaultHeaders(ctx, w.Header())
w.WriteHeader(http.StatusOK)
b, _ := json.Marshal(Response[T]{
Data: data,
})
w.Write(b)
}

View File

@ -0,0 +1,21 @@
package utils
import (
"encoding/json"
"io"
"net/http"
)
func UnmarshalBody(r *http.Request, v any) error {
body, err := io.ReadAll(r.Body)
if err != nil {
return err
}
err = json.Unmarshal(body, v)
if err != nil {
return err
}
return nil
}

View File

@ -28,11 +28,11 @@ func GenerateToken(options ...ClaimOption) (string, error) {
return token.SignedString(jwtSecret)
}
func GenerateToken2(username string) (string, error) {
func GenerateToken2(email string) (string, error) {
now := timeutils.Now()
token := jwt.New(jwt.SigningMethodES256)
token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims)
claims["username"] = username
claims["email"] = email
claims["exp"] = now.Add(time.Hour).Unix()
return token.SignedString(jwtSecret)