Auto-indexing service and GraphQL API for AT Protocol Records
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: pass oauth scopes through without filtering in client metadata

The filter_atproto_scopes function was incorrectly dropping valid scopes
that weren't in a hardcoded list of two. Scopes are validated at config
save time, so filtering here was both redundant and broken.

+13 -27
+5
CHANGELOG.md
··· 5 5 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), 6 6 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 7 8 + ## v0.15.1 9 + 10 + ### Fixed 11 + - Pass OAuth scopes through without filtering in client metadata (fe4c3a7) 12 + 8 13 ## v0.15.0 9 14 10 15 ### Added
+1 -21
server/src/handlers/oauth/client_metadata.gleam
··· 1 1 /// Client metadata endpoint for ATProtocol OAuth 2 2 /// GET /oauth-client-metadata.json 3 3 import gleam/json 4 - import gleam/list 5 4 import gleam/option.{type Option, None, Some} 6 - import gleam/string 7 5 import wisp 8 6 9 7 /// Client metadata response ··· 25 23 ) 26 24 } 27 25 28 - /// Filter scopes to only ATProto-compatible scopes 29 - fn filter_atproto_scopes(scope: String) -> String { 30 - let scopes = string.split(scope, " ") 31 - 32 - let filtered = 33 - list.filter(scopes, fn(s) { 34 - case s { 35 - "atproto" -> True 36 - "transition:generic" -> True 37 - _ -> False 38 - } 39 - }) 40 - 41 - string.join(filtered, " ") 42 - } 43 - 44 26 /// Generate client metadata 45 27 pub fn generate_metadata( 46 28 client_id: String, ··· 50 32 jwks: Option(json.Json), 51 33 jwks_uri: Option(String), 52 34 ) -> ClientMetadataResponse { 53 - let filtered_scope = filter_atproto_scopes(scope) 54 - 55 35 ClientMetadataResponse( 56 36 client_id: client_id, 57 37 client_name: client_name, 58 38 redirect_uris: redirect_uris, 59 39 grant_types: ["authorization_code", "refresh_token"], 60 40 response_types: ["code"], 61 - scope: filtered_scope, 41 + scope: scope, 62 42 token_endpoint_auth_method: "private_key_jwt", 63 43 token_endpoint_auth_signing_alg: "ES256", 64 44 subject_type: "public",
+7 -6
server/test/oauth/client_metadata_test.gleam
··· 8 8 "https://example.com/oauth-client-metadata.json", 9 9 "Test Client", 10 10 ["https://example.com/callback"], 11 - "atproto openid profile", 11 + "atproto transition:generic", 12 12 None, 13 13 None, 14 14 ) ··· 16 16 metadata.client_id 17 17 |> should.equal("https://example.com/oauth-client-metadata.json") 18 18 metadata.client_name |> should.equal("Test Client") 19 - metadata.scope |> should.equal("atproto") 19 + metadata.scope |> should.equal("atproto transition:generic") 20 20 metadata.dpop_bound_access_tokens |> should.be_true 21 21 } 22 22 23 - pub fn filter_atproto_scopes_test() { 23 + pub fn scopes_passed_through_test() { 24 24 let metadata = 25 25 client_metadata.generate_metadata( 26 26 "https://example.com", 27 27 "Test", 28 28 [], 29 - "atproto transition:generic openid profile email", 29 + "atproto transition:generic transition:chat.bsky", 30 30 None, 31 31 None, 32 32 ) 33 33 34 - // Should only keep atproto and transition:generic 35 - metadata.scope |> should.equal("atproto transition:generic") 34 + // Scopes should be passed through as-is (validated at config save time) 35 + metadata.scope 36 + |> should.equal("atproto transition:generic transition:chat.bsky") 36 37 }