Migrated from React to NextJS

This commit is contained in:
2022-10-14 13:58:57 +02:00
parent b2a16e5181
commit b4ff0c8f77
72 changed files with 1557 additions and 1686 deletions

View File

@@ -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
View 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
}

View File

@@ -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,

View File

@@ -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})
}

View File

@@ -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})
}

View File

@@ -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
}

View File

@@ -1,3 +0,0 @@
package jwt
const SecretKey = "secret"

View File

@@ -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
}

View File

@@ -1,11 +0,0 @@
package models
import (
jwt "github.com/dgrijalva/jwt-go"
)
type Claim struct {
ID int64 `json:"id,omitempty"`
jwt.StandardClaims
}

View File

@@ -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
}