Add monorepo structure for NexaVPN WireGuard control plane including: - .gitignore for node_modules, build artifacts, and environment files - README with project overview, monorepo layout, and quick start guide - Admin web UI with React, Vite, TypeScript, and nginx reverse proxy - API client with type definitions for users, devices, policies, gateways, and audit logs - Admin pages for dashboard, users, devices, policies, g
78 lines
1.8 KiB
Go
78 lines
1.8 KiB
Go
package auth
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
func NewRefreshToken() (plain string, hashed string, err error) {
|
|
raw := make([]byte, 32)
|
|
if _, err = rand.Read(raw); err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
plain = base64.RawURLEncoding.EncodeToString(raw)
|
|
sum := sha256.Sum256([]byte(plain))
|
|
hashed = base64.RawURLEncoding.EncodeToString(sum[:])
|
|
return plain, hashed, nil
|
|
}
|
|
|
|
func SignAccessToken(secret, issuer string, ttl time.Duration, claims Claims) (string, error) {
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
|
"iss": issuer,
|
|
"sub": claims.UserID.String(),
|
|
"username": claims.Username,
|
|
"role": claims.Role,
|
|
"session_id": claims.Session.String(),
|
|
"exp": time.Now().Add(ttl).Unix(),
|
|
"iat": time.Now().Unix(),
|
|
})
|
|
|
|
return token.SignedString([]byte(secret))
|
|
}
|
|
|
|
func ParseAccessToken(secret string, tokenString string) (Claims, error) {
|
|
claims := Claims{}
|
|
|
|
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (any, error) {
|
|
return []byte(secret), nil
|
|
})
|
|
if err != nil || !token.Valid {
|
|
return claims, err
|
|
}
|
|
|
|
mapClaims, ok := token.Claims.(jwt.MapClaims)
|
|
if !ok {
|
|
return claims, jwt.ErrTokenMalformed
|
|
}
|
|
|
|
subject, ok := mapClaims["sub"].(string)
|
|
if !ok {
|
|
return claims, jwt.ErrTokenMalformed
|
|
}
|
|
sessionValue, ok := mapClaims["session_id"].(string)
|
|
if !ok {
|
|
return claims, jwt.ErrTokenMalformed
|
|
}
|
|
|
|
userID, err := uuid.Parse(subject)
|
|
if err != nil {
|
|
return claims, err
|
|
}
|
|
sessionID, err := uuid.Parse(sessionValue)
|
|
if err != nil {
|
|
return claims, err
|
|
}
|
|
|
|
claims.UserID = userID
|
|
claims.Session = sessionID
|
|
claims.Username, _ = mapClaims["username"].(string)
|
|
claims.Role, _ = mapClaims["role"].(string)
|
|
return claims, nil
|
|
}
|