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 accessToken, err := api.Auth.CreateJWTAccessToken(user, device) if err != nil { return "", "", err } return accessToken, "", err } func (api *API) validateTokens(w *http.ResponseWriter, r *http.Request) (jwt.Token, error) { accessTokenHeader := r.Header.Get("X-Imagini-AccessToken") if accessTokenHeader != "" { accessToken, err := api.Auth.ValidateJWTAccessToken(accessTokenHeader) if err == nil { return accessToken, nil } } refreshTokenHeader := r.Header.Get("X-Imagini-RefreshToken") if refreshTokenHeader == "" { return nil, errors.New("Tokens Invalid") } // 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) refreshToken, err := api.Auth.ValidateJWTRefreshToken(refreshTokenHeader) if err != nil { return nil, errors.New("Tokens Invalid") } // Refresh Access Token & Generate New Refresh Token newAccessToken, newRefreshToken, err := api.refreshTokens(refreshToken) if err != nil { return nil, err } // TODO: Actually Refresh Refresh Token // newRefreshToken = refreshCookie.Value newRefreshToken = refreshTokenHeader // Set appropriate cookies (TODO: Only for web!) // Update Access & Refresh Cookies // http.SetCookie(*w, &http.Cookie{ // Name: "AccessToken", // Value: newAccessToken, // }) // http.SetCookie(*w, &http.Cookie{ // Name: "RefreshToken", // Value: newRefreshToken, // }) (*w).Header().Set("X-Imagini-AccessToken", newAccessToken) (*w).Header().Set("X-Imagini-RefreshToken", newRefreshToken) return jwt.ParseBytes([]byte(newAccessToken)) }