Jade/login.go
2024-05-05 21:10:09 +02:00

129 lines
3.6 KiB
Go

package main
import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/gofiber/fiber/v2"
)
const EDGEDB_AUTH_BASE_URL = "http://127.0.0.1:10700/db/main/ext/auth"
func generatePKCE() (string, string) {
verifier := make([]byte, 32)
_, err := rand.Read(verifier)
if err != nil {
panic(err)
}
challenge := sha256.Sum256(verifier)
return base64.RawURLEncoding.EncodeToString(verifier), base64.RawURLEncoding.EncodeToString(challenge[:])
}
func handleUiSignIn(c *fiber.Ctx) error {
verifier, challenge := generatePKCE()
fmt.Println("handleUiSignIn verifier: " + verifier)
fmt.Println("handleUiSignIn challenge: " + challenge)
redirectURL := fmt.Sprintf("%s/ui/signin?challenge=%s", EDGEDB_AUTH_BASE_URL, challenge)
c.Cookie(&fiber.Cookie{
Name: "jade-edgedb-pkce-verifier",
Value: verifier,
HTTPOnly: true,
Path: "/",
Secure: true,
SameSite: "Strict",
})
return c.Redirect(redirectURL, fiber.StatusMovedPermanently)
}
func handleUiSignUp(c *fiber.Ctx) error {
verifier, challenge := generatePKCE()
fmt.Println("handleUiSignUp verifier: " + verifier)
fmt.Println("handleUiSignUp challenge: " + challenge)
redirectURL := fmt.Sprintf("%s/ui/signup?challenge=%s", EDGEDB_AUTH_BASE_URL, challenge)
c.Cookie(&fiber.Cookie{
Name: "jade-edgedb-pkce-verifier",
Value: verifier,
HTTPOnly: true,
Path: "/",
Secure: true,
SameSite: "Strict",
})
return c.Redirect(redirectURL, fiber.StatusMovedPermanently)
}
func handleCallbackSignup(c *fiber.Ctx) error {
code := c.Query("code")
fmt.Println("Callback signup code: " + code)
verifier := c.Cookies("jade-edgedb-pkce-verifier")
if verifier == "" {
return c.Status(fiber.StatusBadRequest).SendString("Could not find 'verifier' in the cookie store. Is this the same user agent/browser that started the authorization flow?")
}
return c.SendString("OK")
}
func handleCallback(c *fiber.Ctx) error {
code := c.Query("code")
if code == "" {
error := c.Query("error")
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("OAuth callback is missing 'code'. OAuth provider responded with error: %s", error))
}
verifier := c.Cookies("jade-edgedb-pkce-verifier")
if verifier == "" {
return c.Status(fiber.StatusBadRequest).SendString("Could not find 'verifier' in the cookie store. Is this the same user agent/browser that started the authorization flow?")
}
fmt.Println("handleCallback code: " + code)
fmt.Println("handleCallback verifier: " + verifier)
codeExchangeURL := fmt.Sprintf("%s/token?code=%s&verifier=%s", EDGEDB_AUTH_BASE_URL, code, verifier)
resp, err := http.Get(codeExchangeURL)
if err != nil {
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error from the auth server: %s", err.Error()))
}
defer resp.Body.Close()
if resp.StatusCode != fiber.StatusOK {
body, _ := io.ReadAll(resp.Body)
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error from the auth server: %s", string(body)))
}
var tokenResponse struct {
AuthToken string `json:"auth_token"`
}
err = json.NewDecoder(resp.Body).Decode(&tokenResponse)
if err != nil {
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error decoding auth server response: %s", err.Error()))
}
c.Cookie(&fiber.Cookie{
Name: "edgedb-auth-token",
Value: tokenResponse.AuthToken,
HTTPOnly: true,
Path: "/",
Secure: true,
SameSite: "Strict",
})
fmt.Println("Login successful")
fmt.Println("edgedb-auth-token: " + tokenResponse.AuthToken)
return c.SendStatus(fiber.StatusNoContent)
}