]>
Commit | Line | Data |
---|---|---|
0e468546 TM |
1 | import 'package:flutter/material.dart'; |
2 | import 'package:proxmox_dart_api_client/proxmox_dart_api_client.dart'; | |
3 | import 'package:proxmox_login_manager/proxmox_login_form.dart'; | |
4 | ||
5 | class ProxmoxTfaForm extends StatefulWidget { | |
6 | final ProxmoxApiClient apiClient; | |
7 | ||
8 | const ProxmoxTfaForm({Key key, this.apiClient}) : super(key: key); | |
9 | ||
10 | @override | |
11 | _ProxmoxTfaFormState createState() => _ProxmoxTfaFormState(); | |
12 | } | |
13 | ||
14 | class _ProxmoxTfaFormState extends State<ProxmoxTfaForm> { | |
15 | final TextEditingController _codeController = TextEditingController(); | |
16 | bool _isLoading = false; | |
17 | @override | |
18 | Widget build(BuildContext context) { | |
19 | return Theme( | |
20 | data: ThemeData.dark().copyWith(accentColor: Color(0xFFE47225)), | |
21 | child: Material( | |
22 | color: Theme.of(context).primaryColor, | |
23 | child: Stack( | |
24 | alignment: Alignment.center, | |
25 | children: [ | |
26 | SingleChildScrollView( | |
27 | child: ConstrainedBox( | |
28 | constraints: BoxConstraints.tightFor( | |
29 | height: MediaQuery.of(context).size.height), | |
30 | child: Padding( | |
31 | padding: const EdgeInsets.all(8.0), | |
32 | child: Column( | |
33 | mainAxisAlignment: MainAxisAlignment.start, | |
34 | crossAxisAlignment: CrossAxisAlignment.center, | |
35 | children: <Widget>[ | |
36 | Padding( | |
37 | padding: const EdgeInsets.fromLTRB(0, 100.0, 0, 30.0), | |
38 | child: Icon( | |
39 | Icons.lock, | |
40 | size: 48, | |
41 | ), | |
42 | ), | |
43 | Text( | |
44 | 'Verify', | |
45 | style: TextStyle( | |
46 | fontSize: 36, | |
47 | color: Colors.white, | |
48 | fontWeight: FontWeight.bold), | |
49 | ), | |
50 | Text( | |
51 | 'Check your second factor provider', | |
52 | style: TextStyle( | |
53 | color: Colors.white38, fontWeight: FontWeight.bold), | |
54 | ), | |
55 | Padding( | |
56 | padding: const EdgeInsets.fromLTRB(0, 50.0, 0, 8.0), | |
57 | child: Container( | |
58 | width: 150, | |
59 | child: TextField( | |
60 | controller: _codeController, | |
61 | textAlign: TextAlign.center, | |
62 | decoration: InputDecoration(labelText: 'Code'), | |
63 | autofocus: true, | |
64 | onSubmitted: (value) => _submitTfaCode()), | |
65 | ), | |
66 | ), | |
67 | Expanded( | |
68 | child: Align( | |
69 | alignment: Alignment.bottomCenter, | |
70 | child: Container( | |
71 | width: MediaQuery.of(context).size.width, | |
72 | child: FlatButton( | |
73 | onPressed: () => _submitTfaCode(), | |
74 | color: Color(0xFFE47225), | |
75 | child: Text('Continue'), | |
76 | disabledColor: Colors.grey, | |
77 | ), | |
78 | ), | |
79 | ), | |
80 | ), | |
81 | ], | |
82 | ), | |
83 | ), | |
84 | ), | |
85 | ), | |
86 | if (_isLoading) | |
87 | ProxmoxProgressOverlay( | |
88 | message: 'Verify One-Time password...', | |
89 | ) | |
90 | ], | |
91 | ), | |
92 | ), | |
93 | ); | |
94 | } | |
95 | ||
96 | Future<void> _submitTfaCode() async { | |
97 | setState(() { | |
98 | _isLoading = true; | |
99 | }); | |
100 | try { | |
101 | final client = | |
102 | await widget.apiClient.finishTfaChallenge(_codeController.text); | |
103 | Navigator.of(context).pop(client); | |
104 | } on ProxmoxApiException catch (e) { | |
105 | showDialog( | |
106 | context: context, | |
107 | builder: (context) => ProxmoxApiErrorDialog( | |
108 | exception: e, | |
109 | ), | |
110 | ); | |
111 | } catch (e, trace) { | |
112 | print(e); | |
113 | print(trace); | |
114 | showDialog( | |
115 | context: context, | |
116 | builder: (context) => AlertDialog( | |
117 | title: Text('Connection error'), | |
118 | content: Text('Could not establish connection.'), | |
119 | actions: [ | |
120 | FlatButton( | |
121 | onPressed: () => Navigator.of(context).pop(), | |
122 | child: Text('Close'), | |
123 | ), | |
124 | ], | |
125 | ), | |
126 | ); | |
127 | } | |
128 | setState(() { | |
129 | _isLoading = false; | |
130 | }); | |
131 | } | |
132 | } |