···
4
+
"Coves/internal/api/handlers/oauth"
5
+
"Coves/internal/atproto/identity"
···
12
-
"Coves/internal/api/handlers/oauth"
13
-
"Coves/internal/atproto/identity"
oauthCore "Coves/internal/core/oauth"
"github.com/lestrrat-go/jwx/v2/jwk"
···
// TestOAuthClientMetadata tests the /oauth/client-metadata.json endpoint
func TestOAuthClientMetadata(t *testing.T) {
24
-
expectedClientID string
25
-
expectedJWKSURI string
26
-
expectedRedirect string
24
+
expectedClientID string
25
+
expectedJWKSURI string
26
+
expectedRedirect string
29
-
name: "localhost development",
30
-
appviewURL: "http://localhost:8081",
31
-
expectedClientID: "http://localhost?redirect_uri=http://localhost:8081/oauth/callback&scope=atproto%20transition:generic",
32
-
expectedJWKSURI: "", // No JWKS URI for localhost
33
-
expectedRedirect: "http://localhost:8081/oauth/callback",
29
+
name: "localhost development",
30
+
appviewURL: "http://localhost:8081",
31
+
expectedClientID: "http://localhost?redirect_uri=http://localhost:8081/oauth/callback&scope=atproto%20transition:generic",
32
+
expectedJWKSURI: "", // No JWKS URI for localhost
33
+
expectedRedirect: "http://localhost:8081/oauth/callback",
36
-
name: "production HTTPS",
37
-
appviewURL: "https://coves.social",
38
-
expectedClientID: "https://coves.social/oauth/client-metadata.json",
39
-
expectedJWKSURI: "https://coves.social/oauth/jwks.json",
40
-
expectedRedirect: "https://coves.social/oauth/callback",
36
+
name: "production HTTPS",
37
+
appviewURL: "https://coves.social",
38
+
expectedClientID: "https://coves.social/oauth/client-metadata.json",
39
+
expectedJWKSURI: "https://coves.social/oauth/jwks.json",
40
+
expectedRedirect: "https://coves.social/oauth/callback",
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
47
-
os.Setenv("APPVIEW_PUBLIC_URL", tt.appviewURL)
48
-
defer os.Unsetenv("APPVIEW_PUBLIC_URL")
47
+
if err := os.Setenv("APPVIEW_PUBLIC_URL", tt.appviewURL); err != nil {
48
+
t.Fatalf("Failed to set APPVIEW_PUBLIC_URL: %v", err)
51
+
if err := os.Unsetenv("APPVIEW_PUBLIC_URL"); err != nil {
52
+
t.Logf("Failed to unset APPVIEW_PUBLIC_URL: %v", err)
req := httptest.NewRequest("GET", "/oauth/client-metadata.json", nil)
···
t.Run(tt.name, func(t *testing.T) {
126
-
os.Setenv("OAUTH_PRIVATE_JWK", tt.envValue)
127
-
defer os.Unsetenv("OAUTH_PRIVATE_JWK")
132
+
if err := os.Setenv("OAUTH_PRIVATE_JWK", tt.envValue); err != nil {
133
+
t.Fatalf("Failed to set OAUTH_PRIVATE_JWK: %v", err)
136
+
if err := os.Unsetenv("OAUTH_PRIVATE_JWK"); err != nil {
137
+
t.Logf("Failed to unset OAUTH_PRIVATE_JWK: %v", err)
···
203
+
if err := db.Close(); err != nil {
204
+
t.Logf("Failed to close database: %v", err)
sessionStore := oauthCore.NewPostgresSessionStore(db)
···
t.Run(tt.name, func(t *testing.T) {
234
-
os.Setenv("OAUTH_PRIVATE_JWK", tt.envJWK)
235
-
defer os.Unsetenv("OAUTH_PRIVATE_JWK")
250
+
if err := os.Setenv("OAUTH_PRIVATE_JWK", tt.envJWK); err != nil {
251
+
t.Fatalf("Failed to set OAUTH_PRIVATE_JWK: %v", err)
254
+
if err := os.Unsetenv("OAUTH_PRIVATE_JWK"); err != nil {
255
+
t.Logf("Failed to unset OAUTH_PRIVATE_JWK: %v", err)
237
-
os.Unsetenv("OAUTH_PRIVATE_JWK")
259
+
if err := os.Unsetenv("OAUTH_PRIVATE_JWK"); err != nil {
260
+
t.Logf("Failed to unset OAUTH_PRIVATE_JWK: %v", err)
// Create mock identity resolver for validation tests
···
handler := oauth.NewLoginHandler(mockResolver, sessionStore)
247
-
bodyBytes, _ := json.Marshal(tt.requestBody)
271
+
bodyBytes, marshalErr := json.Marshal(tt.requestBody)
272
+
if marshalErr != nil {
273
+
t.Fatalf("Failed to marshal request body: %v", marshalErr)
req := httptest.NewRequest("POST", "/oauth/login", bytes.NewReader(bodyBytes))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
···
300
+
if err := db.Close(); err != nil {
301
+
t.Logf("Failed to close database: %v", err)
sessionStore := oauthCore.NewPostgresSessionStore(db)
···
testJWK := `{"alg":"ES256","crv":"P-256","d":"9tCMceYSgyZfO5KYOCm3rWEhXLqq2l4LjP7-PJtJKyk","kid":"oauth-client-key","kty":"EC","use":"sig","x":"EOYWEgZ2d-smTO6jh0f-9B7YSFYdlrvlryjuXTCrOjE","y":"_FR2jBcWNxoJl5cd1eq9sYtAs33No9AVtd42UyyWYi4"}`
queryParams map[string]string
···
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
321
-
os.Setenv("OAUTH_PRIVATE_JWK", testJWK)
322
-
defer os.Unsetenv("OAUTH_PRIVATE_JWK")
352
+
if err := os.Setenv("OAUTH_PRIVATE_JWK", testJWK); err != nil {
353
+
t.Fatalf("Failed to set OAUTH_PRIVATE_JWK: %v", err)
356
+
if err := os.Unsetenv("OAUTH_PRIVATE_JWK"); err != nil {
357
+
t.Logf("Failed to unset OAUTH_PRIVATE_JWK: %v", err)
handler := oauth.NewCallbackHandler(sessionStore)
···
// Verify public key doesn't have private component
403
-
pubKeyJSON, _ := json.Marshal(pubKey)
440
+
pubKeyJSON, marshalErr := json.Marshal(pubKey)
441
+
if marshalErr != nil {
442
+
t.Fatalf("failed to marshal public key: %v", marshalErr)
var pubKeyMap map[string]interface{}
405
-
json.Unmarshal(pubKeyJSON, &pubKeyMap)
445
+
if unmarshalErr := json.Unmarshal(pubKeyJSON, &pubKeyMap); unmarshalErr != nil {
446
+
t.Fatalf("failed to unmarshal public key: %v", unmarshalErr)
if _, hasPrivate := pubKeyMap["d"]; hasPrivate {
t.Error("SECURITY: public key should not contain private 'd' component!")