Migrated from React to NextJS
This commit is contained in:
@@ -1,20 +1,28 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"twitch-clone/pkg/auth"
|
||||
"twitch-clone/pkg/database"
|
||||
"twitch-clone/pkg/handler"
|
||||
"twitch-clone/pkg/middleware"
|
||||
"twitch-clone/pkg/models"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/cors"
|
||||
"github.com/gofiber/fiber/v2/middleware/csrf"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func Init() {
|
||||
err := godotenv.Load()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
app := fiber.New(fiber.Config{
|
||||
ErrorHandler: func(ctx *fiber.Ctx, err error) error {
|
||||
code := fiber.StatusInternalServerError
|
||||
@@ -26,6 +34,7 @@ func Init() {
|
||||
},
|
||||
})
|
||||
database.ConnectDb()
|
||||
auth.CreateClient()
|
||||
|
||||
app.Use(cors.New(cors.Config{
|
||||
AllowOrigins: "*",
|
||||
@@ -33,19 +42,12 @@ func Init() {
|
||||
AllowCredentials: true,
|
||||
}))
|
||||
app.Use(logger.New())
|
||||
app.Use(csrf.New(csrf.Config{
|
||||
CookieHTTPOnly: true,
|
||||
CookieSameSite: "strict",
|
||||
}))
|
||||
|
||||
api := app.Group("/api")
|
||||
v1 := api.Group("/v1")
|
||||
|
||||
auth := v1.Group("/auth")
|
||||
auth.Post("login", handler.Login)
|
||||
auth.Post("register", handler.Register)
|
||||
|
||||
test := v1.Group("/test", middleware.CheckToken)
|
||||
test := v1.Group("/test")
|
||||
test.Use(middleware.CheckSession)
|
||||
test.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("This is a protected route!")
|
||||
})
|
||||
@@ -56,7 +58,7 @@ func Init() {
|
||||
return ctx.SendFile("./dist/index.html")
|
||||
})
|
||||
|
||||
err := app.Listen(":5000")
|
||||
err = app.Listen(":5000")
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
18
pkg/auth/kratos.go
Normal file
18
pkg/auth/kratos.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
client "github.com/ory/client-go"
|
||||
)
|
||||
|
||||
var AuthClient *client.APIClient
|
||||
|
||||
func CreateClient() {
|
||||
configuration := client.NewConfiguration()
|
||||
configuration.Servers = []client.ServerConfiguration{
|
||||
{
|
||||
URL: "http://127.0.0.1:4443", // Kratos Admin API
|
||||
},
|
||||
}
|
||||
apiClient := client.NewAPIClient(configuration)
|
||||
AuthClient = apiClient
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"twitch-clone/pkg/models"
|
||||
"os"
|
||||
|
||||
"github.com/bwmarrin/snowflake"
|
||||
"gorm.io/driver/postgres"
|
||||
@@ -24,8 +24,7 @@ func ConnectDb() {
|
||||
if err != nil {
|
||||
log.Fatal("Failed to setup snowflake generator. \n", err)
|
||||
}
|
||||
|
||||
dsn := "host=localhost user=postgres password=postgres dbname=postgres port=5432 sslmode=disable"
|
||||
dsn := fmt.Sprintf("host=localhost user=%s password=%s dbname=%s port=5433 sslmode=disable", os.Getenv("POSTGRES_USER"), os.Getenv("POSTGRES_PASSWORD"), os.Getenv("POSTGRES_DB"))
|
||||
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Info),
|
||||
})
|
||||
@@ -37,8 +36,6 @@ func ConnectDb() {
|
||||
log.Println("connected")
|
||||
db.Logger = logger.Default.LogMode(logger.Info)
|
||||
|
||||
db.AutoMigrate(&models.User{})
|
||||
|
||||
DB = Dbinstance{
|
||||
Db: db,
|
||||
Snowflake: node,
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"twitch-clone/pkg/database"
|
||||
"twitch-clone/pkg/jwt"
|
||||
"twitch-clone/pkg/models"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username" validate:"required,min=4,max=32"`
|
||||
Password string `json:"password" validate:"required,min=8,max=128"`
|
||||
}
|
||||
|
||||
type LoginResponse struct {
|
||||
Token string `json:"access_token"`
|
||||
}
|
||||
|
||||
func Login(ctx *fiber.Ctx) error {
|
||||
db := database.Db()
|
||||
body := LoginRequest{}
|
||||
|
||||
if err := ctx.BodyParser(&body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := models.Validate.Struct(body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user := new(models.User)
|
||||
result := db.Where(&models.User{Login: body.Username, Password: body.Password}).Select("id").First(user)
|
||||
|
||||
if result.Error != nil {
|
||||
return errors.New("invalid combination of username and password")
|
||||
}
|
||||
|
||||
token, err := jwt.GenerateJWT(models.Claim{ID: user.ID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Cookie(&fiber.Cookie{
|
||||
Name: "accessToken",
|
||||
Value: token,
|
||||
HTTPOnly: true,
|
||||
SameSite: "Strict",
|
||||
})
|
||||
|
||||
return ctx.JSON(LoginResponse{Token: token})
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"twitch-clone/pkg/database"
|
||||
"twitch-clone/pkg/jwt"
|
||||
"twitch-clone/pkg/models"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type RegisterRequest struct {
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Username string `json:"username" validate:"required,min=4,max=32"`
|
||||
Password string `json:"password" validate:"required,min=8,max=128"`
|
||||
}
|
||||
|
||||
type RegisterResponse struct {
|
||||
Token string `json:"access_token"`
|
||||
}
|
||||
|
||||
func Register(ctx *fiber.Ctx) error {
|
||||
db := database.Db()
|
||||
body := RegisterRequest{}
|
||||
|
||||
if err := ctx.BodyParser(&body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := models.Validate.Struct(body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user := models.User{ID: database.GetID(), Login: body.Username, Password: body.Password, Email: body.Email}
|
||||
result := db.Create(&user)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
|
||||
token, err := jwt.GenerateJWT(models.Claim{ID: user.ID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Cookie(&fiber.Cookie{
|
||||
Name: "accessToken",
|
||||
Value: token,
|
||||
HTTPOnly: true,
|
||||
SameSite: "Strict",
|
||||
})
|
||||
|
||||
return ctx.JSON(LoginResponse{Token: token})
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package jwt
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"twitch-clone/pkg/models"
|
||||
|
||||
jwt "github.com/golang-jwt/jwt"
|
||||
)
|
||||
|
||||
func GenerateJWT(user models.Claim) (string, error) {
|
||||
payload := jwt.MapClaims{
|
||||
"id": user.ID,
|
||||
"exp": time.Now().Add(time.Hour * 1500).Unix(),
|
||||
}
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, payload)
|
||||
tokenStr, err := token.SignedString([]byte(SecretKey))
|
||||
|
||||
if err != nil {
|
||||
return tokenStr, err
|
||||
}
|
||||
return tokenStr, nil
|
||||
}
|
||||
|
||||
func ProcessJWT(token string) (*models.Claim, bool, int64, error) {
|
||||
claims := &models.Claim{}
|
||||
|
||||
splitToken := strings.Split(token, "Bearer")
|
||||
|
||||
if len(splitToken) != 2 {
|
||||
return claims, false, 0, errors.New("invalid JWT format")
|
||||
}
|
||||
|
||||
token = strings.TrimSpace(splitToken[1])
|
||||
tkn, err := jwt.ParseWithClaims(token, claims, func(tk *jwt.Token) (interface{}, error) {
|
||||
return []byte(SecretKey), nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return claims, false, 0, err
|
||||
}
|
||||
|
||||
if !tkn.Valid {
|
||||
return claims, false, 0, errors.New("invalid JWT token")
|
||||
}
|
||||
|
||||
// TODO: validate whether user exists
|
||||
return claims, true, claims.ID, nil
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
package jwt
|
||||
|
||||
const SecretKey = "secret"
|
||||
@@ -1,18 +1,22 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"twitch-clone/pkg/jwt"
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"twitch-clone/pkg/auth"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
/*CheckToken : Check the validate of the jwt*/
|
||||
func CheckToken(c *fiber.Ctx) error {
|
||||
_, _, _, err := jwt.ProcessJWT(c.Get("Authorization"))
|
||||
func CheckSession(c *fiber.Ctx) error {
|
||||
cookie := c.Cookies("ory_kratos_session")
|
||||
if cookie == "" {
|
||||
return errors.New("no session found in cookie")
|
||||
}
|
||||
_, _, err := auth.AuthClient.V0alpha2Api.ToSession(context.Background()).Cookie(cookie).Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Next()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
type Claim struct {
|
||||
ID int64 `json:"id,omitempty"`
|
||||
|
||||
jwt.StandardClaims
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int64 `json:"id,omitempty" gorm:"primaryKey"`
|
||||
Login string `json:"name,omitempty" gorm:"unique"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password,omitempty"`
|
||||
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
Reference in New Issue
Block a user