Updated key management to match current version
All checks were successful
/ mirror (push) Successful in 4s
/ build-stealth (push) Successful in 9m11s
/ build (push) Successful in 9m13s

This commit is contained in:
AlexisDanlos 2025-03-31 00:50:35 +02:00
parent 664dd4bb38
commit cef7a27e88

View File

@ -1,145 +1,144 @@
import 'package:flutter/material.dart';
import '../../../../domain/services/cryptography/asymmetric_crypto_service.dart';
import 'package:provider/provider.dart';
import 'package:dialer/services/cryptography/asymmetric_crypto_service.dart';
/// Cryptographic key management page
class ManageKeysPage extends StatefulWidget {
const ManageKeysPage({Key? key}) : super(key: key);
@override
_ManageKeysPageState createState() => _ManageKeysPageState();
}
class _ManageKeysPageState extends State<ManageKeysPage> {
String? publicKey;
final AsymmetricCryptoService _cryptoService = AsymmetricCryptoService();
List<Map<String, dynamic>> _keys = [];
bool _isLoading = false;
bool _hasError = false;
String _errorMessage = '';
@override
void initState() {
super.initState();
_loadPublicKey();
_loadKeys();
}
Future<void> _loadPublicKey() async {
Future<void> _loadKeys() async {
setState(() {
_isLoading = true;
_hasError = false;
});
try {
final cryptoService = context.read<AsymmetricCryptoService>();
final key = await cryptoService.getPublicKeyPem();
if (mounted) {
setState(() {
publicKey = key;
_isLoading = false;
});
}
List<Map<String, dynamic>> keys = await _cryptoService.getAllKeys();
setState(() {
_keys = keys;
});
} catch (e) {
if (mounted) {
setState(() {
_hasError = true;
_errorMessage = 'Failed to load public key: $e';
_isLoading = false;
});
}
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Error loading keys: $e')));
} finally {
setState(() {
_isLoading = false;
});
}
}
Future<void> _regenerateKeyPair() async {
Future<void> _generateKey() async {
setState(() {
_isLoading = true;
_hasError = false;
});
try {
final cryptoService = context.read<AsymmetricCryptoService>();
await cryptoService.generateAndStoreKeyPair();
await _loadPublicKey();
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('New key pair generated!')),
);
}
await _cryptoService.generateKeyPair();
await _loadKeys();
ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(content: Text('Key generated successfully')));
} catch (e) {
if (mounted) {
setState(() {
_hasError = true;
_errorMessage = 'Failed to generate key pair: $e';
_isLoading = false;
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error generating key pair: $e')),
);
}
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Error generating key: $e')));
} finally {
setState(() {
_isLoading = false;
});
}
}
Future<void> _deleteKey(String alias) async {
setState(() {
_isLoading = true;
});
try {
await _cryptoService.deleteKeyPair(alias);
await _loadKeys();
ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(content: Text('Key deleted successfully')));
} catch (e) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Error deleting key: $e')));
} finally {
setState(() {
_isLoading = false;
});
}
}
Future<void> _viewPublicKey(String alias) async {
try {
final publicKey = await _cryptoService.getPublicKey(alias);
showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text('Public Key'),
content: SingleChildScrollView(child: Text(publicKey)),
actions: [
TextButton(
child: const Text('Close'),
onPressed: () {
Navigator.pop(context);
},
)
],
),
);
} catch (e) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Error retrieving public key: $e')));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: const Text('Key Management'),
title: const Text('Manage Keys'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: _isLoading
? const Center(child: CircularProgressIndicator())
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Your Public Key',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey[900],
borderRadius: BorderRadius.circular(8),
),
child: _hasError
? Text(
_errorMessage,
style: const TextStyle(
color: Colors.red,
fontFamily: 'monospace',
fontSize: 12,
),
)
: Text(
publicKey ?? 'No key available',
style: const TextStyle(
color: Colors.white70,
fontFamily: 'monospace',
fontSize: 12,
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: _keys.isEmpty
? const Center(child: Text('No keys found'))
: ListView.builder(
itemCount: _keys.length,
itemBuilder: (context, index) {
final keyData = _keys[index];
return ListTile(
title: Text(keyData['label'] ?? 'No label'),
subtitle: Text(keyData['alias'] ?? ''),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(Icons.visibility),
tooltip: 'View Public Key',
onPressed: () => _viewPublicKey(keyData['alias']),
),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: _regenerateKeyPair,
child: const Text('Generate New Key Pair'),
),
if (_hasError) ...[
const SizedBox(height: 16),
const Text(
'Note: Encryption features may be limited due to error.',
style: TextStyle(color: Colors.yellow),
),
],
],
),
IconButton(
icon: const Icon(Icons.delete),
tooltip: 'Delete Key',
onPressed: () => _deleteKey(keyData['alias']),
),
],
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: _generateKey,
child: const Icon(Icons.add),
tooltip: 'Generate New Key',
),
);
}