]> git.proxmox.com Git - flutter/proxmox_login_manager.git/blobdiff - lib/proxmox_tfa_form.dart
tree wide: various small lint auto-fixes
[flutter/proxmox_login_manager.git] / lib / proxmox_tfa_form.dart
index dfdb921089eab7733d37d39444c263e8ffb75598..f761462aadfc6adfeefc08011439808f87c78c02 100644 (file)
@@ -14,11 +14,21 @@ class ProxmoxTfaForm extends StatefulWidget {
 class _ProxmoxTfaFormState extends State<ProxmoxTfaForm> {
   final TextEditingController _codeController = TextEditingController();
   bool _isLoading = false;
+  List<String> _tfa_kinds = [];
+  String _selected_tfa_kind = "";
+
+  @override
+  void initState() {
+    super.initState();
+    _tfa_kinds = widget.apiClient!.credentials.tfa!.kinds().toList();
+    _selected_tfa_kind = _tfa_kinds[0];
+  }
+
   @override
   Widget build(BuildContext context) {
     return Theme(
       data: ThemeData.dark().copyWith(
-          colorScheme: ColorScheme.dark().copyWith(
+          colorScheme: const ColorScheme.dark().copyWith(
               secondary: ProxmoxColors.orange,
               onSecondary: ProxmoxColors.supportGrey)),
       child: Scaffold(
@@ -28,7 +38,7 @@ class _ProxmoxTfaFormState extends State<ProxmoxTfaForm> {
           elevation: 0.0,
           backgroundColor: Colors.transparent,
           leading: IconButton(
-            icon: Icon(Icons.close),
+            icon: const Icon(Icons.close),
             onPressed: () => Navigator.of(context).pop(),
           ),
         ),
@@ -39,68 +49,99 @@ class _ProxmoxTfaFormState extends State<ProxmoxTfaForm> {
               child: ConstrainedBox(
                 constraints: BoxConstraints.tightFor(
                     height: MediaQuery.of(context).size.height),
-                child: Padding(
-                  padding: const EdgeInsets.all(8.0),
-                  child: Column(
-                    mainAxisAlignment: MainAxisAlignment.start,
-                    crossAxisAlignment: CrossAxisAlignment.center,
-                    children: <Widget>[
-                      Padding(
-                        padding: const EdgeInsets.fromLTRB(0, 100.0, 0, 30.0),
-                        child: Icon(
-                          Icons.lock,
-                          size: 48,
+                child: SafeArea(
+                  child: Padding(
+                    padding: const EdgeInsets.all(8.0),
+                    child: Column(
+                      mainAxisAlignment: MainAxisAlignment.start,
+                      crossAxisAlignment: CrossAxisAlignment.center,
+                      children: <Widget>[
+                        const Padding(
+                          padding: EdgeInsets.fromLTRB(0, 100.0, 0, 30.0),
+                          child: Icon(
+                            Icons.lock,
+                            size: 48,
+                          ),
                         ),
-                      ),
-                      Text(
-                        'Verify',
-                        style: TextStyle(
-                            fontSize: 36,
-                            color: Colors.white,
-                            fontWeight: FontWeight.bold),
-                      ),
-                      Text(
-                        'Check your second factor provider',
-                        style: TextStyle(
-                            color: Colors.white38, fontWeight: FontWeight.bold),
-                      ),
-                      Padding(
-                        padding: const EdgeInsets.fromLTRB(0, 50.0, 0, 8.0),
-                        child: Container(
-                          width: 150,
-                          child: TextField(
-                              controller: _codeController,
-                              textAlign: TextAlign.center,
-                              decoration: InputDecoration(labelText: 'Code'),
-                              autofocus: true,
-                              onSubmitted: (value) => _submitTfaCode()),
+                        const Text(
+                          'Verify',
+                          style: TextStyle(
+                              fontSize: 36,
+                              color: Colors.white,
+                              fontWeight: FontWeight.bold),
                         ),
-                      ),
-                      Expanded(
-                        child: Align(
-                          alignment: Alignment.bottomCenter,
+                        const Text(
+                          'Check your second factor provider',
+                          style: TextStyle(
+                              color: Colors.white38,
+                              fontWeight: FontWeight.bold),
+                        ),
+                        Padding(
+                          padding: const EdgeInsets.fromLTRB(0, 50.0, 0, 8.0),
                           child: Container(
-                            width: MediaQuery.of(context).size.width,
-                            child: TextButton(
-                              style: TextButton.styleFrom(
-                                foregroundColor: Colors.white,
-                                backgroundColor: Color(0xFFE47225),
-                                disabledBackgroundColor: Colors.grey,
+                            width: 175,
+                            child: Column(
+                              children: <Widget>[
+                                DropdownButtonFormField(
+                                  decoration: const InputDecoration(
+                                      labelText: 'Method',
+                                      icon: Icon(Icons.input)),
+                                  items: _tfa_kinds
+                                      .map((e) => DropdownMenuItem(
+                                            value: e,
+                                            child: ListTile(title: Text(e)),
+                                          ))
+                                      .toList(),
+                                  onChanged: (String? value) {
+                                    setState(() {
+                                      _selected_tfa_kind = value!;
+                                    });
+                                  },
+                                  selectedItemBuilder: (context) =>
+                                      _tfa_kinds.map((e) => Text(e)).toList(),
+                                  value: _selected_tfa_kind,
+                                ),
+                                TextField(
+                                    controller: _codeController,
+                                    textAlign: TextAlign.center,
+                                    decoration: const InputDecoration(
+                                        labelText: 'Code',
+                                        icon: Icon(Icons.pin)),
+                                    keyboardType: _selected_tfa_kind == 'totp'
+                                        ? TextInputType.number
+                                        : TextInputType.visiblePassword,
+                                    autofocus: true,
+                                    onSubmitted: (value) => _submitTfaCode()),
+                              ],
+                            ),
+                          ),
+                        ),
+                        Expanded(
+                          child: Align(
+                            alignment: Alignment.bottomCenter,
+                            child: Container(
+                              width: MediaQuery.of(context).size.width,
+                              child: TextButton(
+                                style: TextButton.styleFrom(
+                                  foregroundColor: Colors.white,
+                                  backgroundColor: const Color(0xFFE47225),
+                                  disabledBackgroundColor: Colors.grey,
+                                ),
+                                onPressed: () => _submitTfaCode(),
+                                child: const Text('Continue'),
                               ),
-                              onPressed: () => _submitTfaCode(),
-                              child: Text('Continue'),
                             ),
                           ),
                         ),
-                      ),
-                    ],
+                      ],
+                    ),
                   ),
                 ),
               ),
             ),
             if (_isLoading)
-              ProxmoxProgressOverlay(
-                message: 'Verify One-Time password...',
+              const ProxmoxProgressOverlay(
+                message: 'Verifying second-factor...',
               )
           ],
         ),
@@ -113,8 +154,8 @@ class _ProxmoxTfaFormState extends State<ProxmoxTfaForm> {
       _isLoading = true;
     });
     try {
-      final client =
-          await widget.apiClient!.finishTfaChallenge(_codeController.text);
+      final client = await widget.apiClient!
+          .finishTfaChallenge(_selected_tfa_kind, _codeController.text);
       Navigator.of(context).pop(client);
     } on ProxmoxApiException catch (e) {
       showDialog(