authenticate method
Authenticate using browser-based flow Returns AuthConfig on success, throws on error
Implementation
Future<AuthConfig> authenticate() async {
// Generate unique session ID
final sessionId = const Uuid().v4();
// Generate PKCE code verifier and challenge
final codeVerifier = _generateCodeVerifier();
final codeChallenge = _generateCodeChallenge(codeVerifier);
if (verbose) {
print('Session ID: $sessionId');
print('Code verifier generated');
print('Code challenge: $codeChallenge');
}
// Build CLI auth URL
final authUrl = _buildAuthUrl(sessionId, codeChallenge);
// Start local server
final server = LocalAuthServer(sessionId: sessionId);
try {
// Print instructions
print('\nOpening browser for authentication...');
print('If browser does not open, visit:');
print(' $authUrl\n');
// Try to open browser
final opened = await _openBrowser(authUrl);
if (!opened && verbose) {
print('Could not automatically open browser');
}
// Wait for callback
print('Waiting for authorization...');
final result = await server.waitForCallback();
if (!result.isSuccess) {
throw Exception(result.error ?? 'Authentication failed');
}
// If we received tokens directly
if (result.accessToken != null) {
return _buildAuthConfigFromTokens(result);
}
// If we received an auth code, we would exchange it here
// For now, we expect the frontend to send tokens directly
// This simplifies the flow and avoids needing a backend token endpoint
if (result.code != null) {
// In a full implementation, exchange code for tokens
// For now, we expect tokens directly
throw Exception('Received auth code but token exchange not implemented');
}
throw Exception('No valid authentication data received');
} finally {
server.stop();
}
}