Skip to content

Commit

Permalink
added script for biometric
Browse files Browse the repository at this point in the history
  • Loading branch information
TheNoumanDev committed Nov 27, 2024
1 parent e2036c2 commit 5fa9fa5
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 0 deletions.
7 changes: 7 additions & 0 deletions starter/modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,13 @@ export const modules = [
{ key: 'bluetooth_description', question: 'Please provide a description for accessing Bluetooth: ', required: (args) => args.platform.includes('ios') },
{ key: 'bluetooth_peripheral_description', question: 'Please provide a description for using Bluetooth peripherals: ', required: (args) => args.platform.includes('ios') }
]
},
{
name: 'biometric',
path: 'scripts/modules/enable_biometric.dart',
parameters: [
{ key: 'face_id_description', question: 'Please provide a description for Face ID usage (iOS): ', required: (args) => args.platform.includes('ios') }
]
}
];

Expand Down
1 change: 1 addition & 0 deletions starter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"useChat": "node dart_runner.js chat",
"useAuth": "node dart_runner.js auth",
"useBluetooth": "node dart_runner.js bluetooth",
"useBiometric": "node dart_runner.js biometric",
"generate_keystore": "node dart_runner.js generateKeystore",
"get_sha_keys": "node dart_runner.js getShaKeys"
},
Expand Down
68 changes: 68 additions & 0 deletions starter/scripts/modules/enable_biometric.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import 'dart:io';

import '../utils.dart';

void main(List<String> arguments) async {
List<String> platforms = getPlatforms(arguments);

final androidPermissions = [
'<uses-permission android:name="android.permission.USE_BIOMETRIC"/>',
];

final iOSPermissions = [
{
'key': 'face_id_description',
'value': 'NSFaceIDUsageDescription',
}
];

try {
// Add the biometric permission to AndroidManifest.xml
if (platforms.contains('android')) {
updateAndroidPermissions(permissions: androidPermissions);

// Update MainActivity to extend FlutterFragmentActivity
final mainActivityUpdates = {
'kotlin': [
{
'pattern':
r'import\s+io\.flutter\.embedding\.android\.FlutterActivity',
'replacement':
'import io.flutter.embedding.android.FlutterFragmentActivity'
},
{
'pattern': r'class\s+MainActivity\s*:\s*FlutterActivity\(\)',
'replacement': 'class MainActivity: FlutterFragmentActivity()'
}
],
'java': [
{
'pattern':
r'import\s+io\.flutter\.embedding\.android\.FlutterActivity;',
'replacement':
'import io.flutter.embedding.android.FlutterFragmentActivity;'
},
{
'pattern':
r'public\s+class\s+MainActivity\s+extends\s+FlutterActivity',
'replacement':
'public class MainActivity extends FlutterFragmentActivity'
}
]
};

updateMainActivity(mainActivityUpdates);
}

// Add Face ID usage description to Info.plist for iOS
if (platforms.contains('ios')) {
updateIOSPermissions(iOSPermissions, arguments);
}

print('Biometric enabled successfully for ${platforms.join(', ')}! 🎉');
exit(0);
} catch (e) {
print('Starter Error: $e');
exit(1);
}
}
78 changes: 78 additions & 0 deletions starter/scripts/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,84 @@ void updateAndroidPermissions(
writeFileContent(androidManifestFilePath, manifestContent);
}

void updateMainActivity(Map<String, List<Map<String, String>>> updates) {
const baseDir = 'android/app/src/main';

String? activityFilePath = findMainActivity(baseDir);
if (activityFilePath == null) {
throw Exception('MainActivity not found in $baseDir');
}

String content = readFileContent(activityFilePath);
bool isKotlin = activityFilePath.endsWith('.kt');

try {
final patterns = isKotlin ? updates['kotlin']! : updates['java']!;
bool requiresUpdate = false;
String updatedContent = content;

// Check if any of the desired states already exist
for (final update in patterns) {
final desiredContent = update['replacement'] ?? '';
if (!content.contains(desiredContent)) {
requiresUpdate = true;
break;
}
}

// Apply updates if needed
if (requiresUpdate) {
for (final update in patterns) {
try {
final newContent = updateContent(updatedContent,
update['pattern'] ?? '', update['replacement'] ?? '');
if (newContent != updatedContent) {
updatedContent = newContent;
}
} catch (_) {
// Continue with next pattern if one fails
continue;
}
}

// Write changes if content was modified
if (updatedContent != content) {
writeFileContent(activityFilePath, updatedContent);
}
}
} catch (e) {
throw Exception('Failed to update MainActivity: $e');
}
}

/// Finds the MainActivity file in the project
String? findMainActivity(String baseDir) {
final commonPaths = ['kotlin', 'java'];

for (final path in commonPaths) {
final dir = Directory('$baseDir/$path');
if (!dir.existsSync()) continue;

try {
final files = dir.listSync(recursive: true);
final activityFile = files.firstWhere(
(file) =>
file.path.endsWith('MainActivity.kt') ||
file.path.endsWith('MainActivity.java'),
orElse: () => File(''),
);

if (activityFile.path.isNotEmpty) {
return activityFile.path;
}
} catch (_) {
continue;
}
}

return null;
}

// Update Info.plist for iOS with permissions and descriptions
void updateIOSPermissions(
List<Map<String, String>> iOSPermissions, List<String> arguments,
Expand Down

0 comments on commit 5fa9fa5

Please sign in to comment.