1import 'package:atproto_oauth_flutter/atproto_oauth_flutter.dart'; 2 3import 'environment_config.dart'; 4 5/// OAuth Configuration for atProto 6/// 7/// This configuration provides ClientMetadata for the new 8/// atproto_oauth_flutter package. The new package handles proper 9/// decentralized OAuth discovery (works with ANY PDS). 10class OAuthConfig { 11 // OAuth Server Configuration 12 // Cloudflare Worker that hosts client-metadata.json and handles OAuth 13 // callbacks 14 static const String oauthServerUrl = 15 'https://lingering-darkness-50a6.brettmay0212.workers.dev'; 16 17 // Custom URL scheme for deep linking 18 // Must match AndroidManifest.xml intent filters 19 // Using the same format as working Expo implementation 20 static const String customScheme = 21 'dev.workers.brettmay0212.lingering-darkness-50a6'; 22 23 // API Configuration 24 // Environment-aware API URL 25 static String get apiUrl => EnvironmentConfig.current.apiUrl; 26 27 // Derived OAuth URLs 28 static const String clientId = '$oauthServerUrl/client-metadata.json'; 29 30 // IMPORTANT: Private-use URI schemes (RFC 8252) require SINGLE slash, 31 // not double! 32 // Correct: dev.workers.example:/oauth/callback 33 // Incorrect: dev.workers.example://oauth/callback 34 static const String customSchemeCallback = '$customScheme:/oauth/callback'; 35 36 // HTTPS callback (fallback for PDS that don't support custom 37 // URI schemes) 38 static const String httpsCallback = '$oauthServerUrl/oauth/callback'; 39 40 // OAuth Scopes - recommended scope for atProto 41 static const String scope = 'atproto transition:generic'; 42 43 // Client name for display during authorization 44 static const String clientName = 'Coves'; 45 46 /// Create ClientMetadata for the FlutterOAuthClient 47 /// 48 /// This configures the OAuth client with: 49 /// - Discoverable client ID (HTTPS URL to metadata JSON) 50 /// - HTTPS callback (primary - works with all PDS servers) 51 /// - Custom URL scheme (fallback - requires PDS support) 52 /// - DPoP enabled for token security 53 /// - Proper scopes for atProto access 54 static ClientMetadata createClientMetadata() { 55 return const ClientMetadata( 56 clientId: clientId, 57 // Use HTTPS as PRIMARY - prevents browser re-navigation that 58 // invalidates auth codes. Custom scheme as fallback (Worker page 59 // redirects to custom scheme anyway) 60 redirectUris: [httpsCallback, customSchemeCallback], 61 scope: scope, 62 clientName: clientName, 63 dpopBoundAccessTokens: true, // Enable DPoP for security 64 applicationType: 'native', 65 grantTypes: ['authorization_code', 'refresh_token'], 66 tokenEndpointAuthMethod: 'none', // Public client (mobile apps) 67 ); 68 } 69}