feat: migrate auth0mock from Node.js to Go

Refactor the application to a Go-based architecture for improved
performance and maintainability. Replace the Dockerfile to utilize a
multi-stage build process, enhancing image efficiency. Implement
comprehensive session store tests to ensure reliability and create
new OAuth handlers for managing authentication efficiently. Update 
documentation to reflect these structural changes.
This commit is contained in:
2025-12-29 16:30:37 +01:00
parent 96453e1d15
commit 9992fb4ef1
25 changed files with 1976 additions and 1991 deletions
+151
View File
@@ -0,0 +1,151 @@
package auth
import (
"encoding/json"
"testing"
)
func TestNewJWTService(t *testing.T) {
service, err := NewJWTService("https://test.example.com/", "https://audience", "https://admin", "https://email")
if err != nil {
t.Fatalf("failed to create JWT service: %v", err)
}
if service.Issuer() != "https://test.example.com/" {
t.Errorf("expected issuer https://test.example.com/, got %s", service.Issuer())
}
if service.Audience() != "https://audience" {
t.Errorf("expected audience https://audience, got %s", service.Audience())
}
}
func TestSignToken(t *testing.T) {
service, err := NewJWTService("https://test.example.com/", "https://audience", "https://admin", "https://email")
if err != nil {
t.Fatalf("failed to create JWT service: %v", err)
}
claims := map[string]interface{}{
"sub": "test-subject",
"aud": "test-audience",
}
token, err := service.SignToken(claims)
if err != nil {
t.Fatalf("failed to sign token: %v", err)
}
if token == "" {
t.Error("expected non-empty token")
}
// Verify token can be decoded
decoded, err := service.DecodeToken(token)
if err != nil {
t.Fatalf("failed to decode token: %v", err)
}
if decoded["sub"] != "test-subject" {
t.Errorf("expected sub=test-subject, got %v", decoded["sub"])
}
}
func TestSignAccessToken(t *testing.T) {
service, err := NewJWTService("https://test.example.com/", "https://audience", "https://admin", "https://email")
if err != nil {
t.Fatalf("failed to create JWT service: %v", err)
}
customClaims := []map[string]interface{}{
{"https://admin": true},
}
token, err := service.SignAccessToken("auth0|user@example.com", "client-id", "user@example.com", customClaims)
if err != nil {
t.Fatalf("failed to sign access token: %v", err)
}
decoded, err := service.DecodeToken(token)
if err != nil {
t.Fatalf("failed to decode token: %v", err)
}
if decoded["sub"] != "auth0|user@example.com" {
t.Errorf("expected sub=auth0|user@example.com, got %v", decoded["sub"])
}
if decoded["https://email"] != "user@example.com" {
t.Errorf("expected email claim, got %v", decoded["https://email"])
}
}
func TestSignIDToken(t *testing.T) {
service, err := NewJWTService("https://test.example.com/", "https://audience", "https://admin", "https://email")
if err != nil {
t.Fatalf("failed to create JWT service: %v", err)
}
token, err := service.SignIDToken(
"auth0|user@example.com",
"client-id",
"test-nonce",
"user@example.com",
"Test User",
"Test",
"User",
"https://example.com/picture.jpg",
nil,
)
if err != nil {
t.Fatalf("failed to sign ID token: %v", err)
}
decoded, err := service.DecodeToken(token)
if err != nil {
t.Fatalf("failed to decode token: %v", err)
}
if decoded["name"] != "Test User" {
t.Errorf("expected name=Test User, got %v", decoded["name"])
}
if decoded["nonce"] != "test-nonce" {
t.Errorf("expected nonce=test-nonce, got %v", decoded["nonce"])
}
}
func TestGetJWKS(t *testing.T) {
service, err := NewJWTService("https://test.example.com/", "https://audience", "https://admin", "https://email")
if err != nil {
t.Fatalf("failed to create JWT service: %v", err)
}
jwks, err := service.GetJWKS()
if err != nil {
t.Fatalf("failed to get JWKS: %v", err)
}
var result map[string]interface{}
if err := json.Unmarshal(jwks, &result); err != nil {
t.Fatalf("failed to parse JWKS: %v", err)
}
keys, ok := result["keys"].([]interface{})
if !ok {
t.Fatal("expected keys array in JWKS")
}
if len(keys) != 1 {
t.Errorf("expected 1 key, got %d", len(keys))
}
key := keys[0].(map[string]interface{})
if key["kty"] != "RSA" {
t.Errorf("expected kty=RSA, got %v", key["kty"])
}
if key["use"] != "sig" {
t.Errorf("expected use=sig, got %v", key["use"])
}
}