/* * This file is part of laurelin_api * Copyright (C) 2023 Jonni Liljamo * * Licensed under GPL-3.0-only. * See LICENSE for licensing information. */ package auth import ( "api/db" "errors" "os" "time" "github.com/golang-jwt/jwt/v4" ) var JWTSecret = []byte(os.Getenv("LAURELINAPI_JWT_SECRET")) type JWTClaims struct { Username string `json:"username"` Email string `json:"email"` jwt.RegisteredClaims } func NewJWTToken(username string, email string) (token string, err error) { claims := JWTClaims{ Username: username, Email: email, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(1 * time.Hour)), }, } jwtClaims := jwt.NewWithClaims(jwt.SigningMethodHS512, claims) token, err = jwtClaims.SignedString(JWTSecret) return } func ValidateJWTToken(userToken string) (claims *JWTClaims, err error) { token, err := jwt.ParseWithClaims( userToken, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(JWTSecret), nil }, ) if err != nil { return } if !token.Valid { err = errors.New("token not valid") return } claims, ok := token.Claims.(*JWTClaims) if !ok { err = errors.New("could not parse JWT claims") return } if claims.ExpiresAt.Unix() < time.Now().Local().Unix() { err = errors.New("token is expired") return } // Auth should match a registered user // NOTE: Technically auth should always match a registered user, but just in-case. // TOFIX: Or, now that I think about it, I should run some tests to see if this // truly is just dumb to check. _, uerr := db.GetUserByEmail(claims.Email) if uerr != nil { err = errors.New("user does not exist") return } return }