initiateNativeAuth method
YouTube Native Authentication
Implementation
Future<bool> initiateNativeAuth(String platform, [String? username]) async {
if (platform == 'youtube') {
debugPrint('🔗 Initiating native Google Sign-In for YouTube');
try {
// Initialize Google Sign-In
final googleSignIn = _initializeGoogleSignIn();
// Sign in with Google
final GoogleSignInAccount? account = await googleSignIn.signIn();
if (account == null) {
debugPrint('User cancelled Google Sign-In');
return false;
}
debugPrint('✅ Google Sign-In successful: ${account.email}');
// Get authentication data
final GoogleSignInAuthentication auth = await account.authentication;
debugPrint('🔑 Got Google tokens');
// Get stored auth token (onairos-npm uses a single user token).
String? authToken = await getFromSecure('onairos_jwt_token') ??
await getFromSecure('onairos_user_token') ??
await getFromSecure('auth_token');
final storedUsername = await getFromSecure('onairos_username');
final finalUsername = storedUsername ?? username ?? account.email ?? 'youtube_user';
// Fetch YouTube channel information
String channelName = 'Unknown Channel';
String? channelId;
try {
debugPrint('📺 Fetching YouTube channel information...');
final channelResponse = await http.get(
Uri.parse('https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true'),
headers: {
'Authorization': 'Bearer ${auth.accessToken}',
'Accept': 'application/json',
},
);
if (channelResponse.statusCode == 200) {
final channelData = jsonDecode(channelResponse.body);
if (channelData['items'] != null && channelData['items'].isNotEmpty) {
channelName = channelData['items'][0]['snippet']['title'];
channelId = channelData['items'][0]['id'];
debugPrint('✅ YouTube channel found: $channelName');
}
}
} catch (channelError) {
debugPrint('⚠️ Error fetching YouTube channel info: $channelError');
channelName = account.displayName ?? account.email ?? 'Unknown Channel';
}
// IMPORTANT: Do not create tokens ad-hoc here.
// Require that the user has already authenticated (email or Google flow) so we
// have a valid backend token.
if (authToken == null || authToken.trim().length < 20) {
debugPrint('❌ No valid auth token found. User must authenticate before connecting YouTube.');
return false;
}
debugPrint('🔗 Linking YouTube data to user: $finalUsername');
debugPrint('📺 YouTube channel name: $channelName');
// Send tokens to backend for YouTube data processing
final backendResponse = await http.post(
Uri.parse('$_apiBaseUrl/youtube/native-auth'),
headers: {
'Content-Type': 'application/json',
if (authToken != null) 'Authorization': 'Bearer $authToken',
},
body: jsonEncode({
'session': {
'username': finalUsername,
'platform': 'youtube',
'timestamp': DateTime.now().toIso8601String(),
'channelName': channelName,
'channelId': channelId,
},
'googleUser': {
'id': account.id,
'email': account.email,
'displayName': account.displayName,
'photoUrl': account.photoUrl,
},
'accessToken': auth.accessToken,
'idToken': auth.idToken,
'serverAuthCode': auth.serverAuthCode,
'userAccountInfo': {
'username': finalUsername,
'email': account.email,
'authToken': authToken,
'channelName': channelName,
'channelId': channelId,
'userIdentifier': authToken != null ? 'user-${authToken.substring(0, 10)}' : 'youtube-${account.email}',
'googleId': account.id,
},
'tokenExpiry': DateTime.now().add(const Duration(hours: 1)).toIso8601String(),
'requestRefreshToken': true,
}),
);
if (backendResponse.statusCode == 200) {
final responseData = jsonDecode(backendResponse.body);
debugPrint('✅ YouTube connection processed by backend: $responseData');
return true;
} else {
final errorData = backendResponse.body;
debugPrint('❌ Backend processing failed: ${backendResponse.statusCode} $errorData');
return false;
}
} catch (error) {
debugPrint('❌ Google Sign-In error: $error');
return false;
}
}
return false;
}