diff --git a/dialer/lib/presentation/features/settings/cryptography/key_management.dart b/dialer/lib/presentation/features/settings/cryptography/key_management.dart index ba35987..f766ebc 100644 --- a/dialer/lib/presentation/features/settings/cryptography/key_management.dart +++ b/dialer/lib/presentation/features/settings/cryptography/key_management.dart @@ -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 { - String? publicKey; + final AsymmetricCryptoService _cryptoService = AsymmetricCryptoService(); + List> _keys = []; bool _isLoading = false; - bool _hasError = false; - String _errorMessage = ''; @override void initState() { super.initState(); - _loadPublicKey(); + _loadKeys(); } - Future _loadPublicKey() async { + Future _loadKeys() async { setState(() { _isLoading = true; - _hasError = false; }); - try { - final cryptoService = context.read(); - final key = await cryptoService.getPublicKeyPem(); - - if (mounted) { - setState(() { - publicKey = key; - _isLoading = false; - }); - } + List> 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 _regenerateKeyPair() async { + Future _generateKey() async { setState(() { _isLoading = true; - _hasError = false; }); - try { - final cryptoService = context.read(); - 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 _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 _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', ), ); }