This repository has been archived on 2023-11-13. You can view files and clone it, but cannot push or open issues or pull requests.
imagini/internal/api/auth.go
2021-02-04 15:31:07 -05:00

95 lines
2.2 KiB
Go

package api
import (
"errors"
"fmt"
"net/http"
"github.com/google/uuid"
"github.com/lestrrat-go/jwx/jwt"
"reichard.io/imagini/graph/model"
)
func (api *API) refreshTokens(refreshToken jwt.Token) (string, string, error) {
// Acquire User & Device
did, ok := refreshToken.Get("did")
if !ok {
return "", "", errors.New("Missing DID")
}
uid, ok := refreshToken.Get(jwt.SubjectKey)
if !ok {
return "", "", errors.New("Missing UID")
}
deviceUUID, err := uuid.Parse(fmt.Sprintf("%v", did))
if err != nil {
return "", "", errors.New("Invalid DID")
}
userUUID, err := uuid.Parse(fmt.Sprintf("%v", uid))
if err != nil {
return "", "", errors.New("Invalid UID")
}
// Device & User Skeleton
user := model.User{ID: userUUID.String()}
device := model.Device{ID: deviceUUID.String()}
// Find User
_, err = api.DB.User(&user)
if err != nil {
return "", "", err
}
// Update Access Token
accessTokenCookie, err := api.Auth.CreateJWTAccessToken(user, device)
if err != nil {
return "", "", err
}
return accessTokenCookie, "", err
}
func (api *API) validateTokens(w *http.ResponseWriter, r *http.Request) (jwt.Token, error) {
// Validate Access Token
accessCookie, _ := r.Cookie("AccessToken")
if accessCookie != nil {
accessToken, err := api.Auth.ValidateJWTAccessToken(accessCookie.Value)
if err == nil {
return accessToken, nil
}
}
// Validate Refresh Cookie Exists
refreshCookie, _ := r.Cookie("RefreshToken")
if refreshCookie == nil {
return nil, errors.New("Tokens Invalid")
}
// Validate Refresh Token
refreshToken, err := api.Auth.ValidateJWTRefreshToken(refreshCookie.Value)
if err != nil {
return nil, errors.New("Tokens Invalid")
}
// Refresh Access Token & Generate New Refresh Token
newAccessCookie, newRefreshCookie, err := api.refreshTokens(refreshToken)
if err != nil {
return nil, err
}
// TODO: Actually Refresh Refresh Token
newRefreshCookie = refreshCookie.Value
// Update Access & Refresh Cookies
http.SetCookie(*w, &http.Cookie{
Name: "AccessToken",
Value: newAccessCookie,
})
http.SetCookie(*w, &http.Cookie{
Name: "RefreshToken",
Value: newRefreshCookie,
})
return jwt.ParseBytes([]byte(newAccessCookie))
}