mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-10-30 17:54:57 +00:00 
			
		
		
		
	Can change password
This commit is contained in:
		| @@ -151,4 +151,14 @@ class SettingsHelper { | |||||||
|       await APIRequest(uri: "settings/check_password", needLogin: true) |       await APIRequest(uri: "settings/check_password", needLogin: true) | ||||||
|           .addString("password", password) |           .addString("password", password) | ||||||
|           .execWithThrow(); |           .execWithThrow(); | ||||||
|  |  | ||||||
|  |   /// Change user password | ||||||
|  |   /// | ||||||
|  |   /// Throws in case of failure | ||||||
|  |   static Future<void> changePassword( | ||||||
|  |           String oldPassword, String newPassword) async => | ||||||
|  |       await APIRequest(uri: "settings/update_password", needLogin: true) | ||||||
|  |           .addString("oldPassword", oldPassword) | ||||||
|  |           .addString("newPassword", newPassword) | ||||||
|  |           .execWithThrow(); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										112
									
								
								lib/ui/dialogs/input_new_password_dialog.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								lib/ui/dialogs/input_new_password_dialog.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | import 'package:comunic/ui/widgets/auto_sized_dialog_content_widget.dart'; | ||||||
|  | import 'package:comunic/utils/input_utils.dart'; | ||||||
|  | import 'package:comunic/utils/intl_utils.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  |  | ||||||
|  | /// Ask the user to enter a new password | ||||||
|  | /// | ||||||
|  | /// @author Pierre HUBERT | ||||||
|  |  | ||||||
|  | /// Ask the user to enter a new password | ||||||
|  | Future<String> showInputNewPassword(BuildContext context) async { | ||||||
|  |   return await showDialog( | ||||||
|  |       context: context, builder: (c) => _InputNewPasswordDialog()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _InputNewPasswordDialog extends StatefulWidget { | ||||||
|  |   @override | ||||||
|  |   __InputNewPasswordDialogState createState() => | ||||||
|  |       __InputNewPasswordDialogState(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class __InputNewPasswordDialogState extends State<_InputNewPasswordDialog> { | ||||||
|  |   final _controller1 = TextEditingController(); | ||||||
|  |   final _controller2 = TextEditingController(); | ||||||
|  |   final _focusScopeNode = FocusScopeNode(); | ||||||
|  |  | ||||||
|  |   String get _password => _controller1.text; | ||||||
|  |  | ||||||
|  |   bool get _input1Valid => validatePassword(_password); | ||||||
|  |  | ||||||
|  |   bool get _input2Valid => _controller1.text == _controller2.text; | ||||||
|  |  | ||||||
|  |   bool get _isValid => _input1Valid && _input2Valid; | ||||||
|  |  | ||||||
|  |   void Function() get _submitAction => | ||||||
|  |       _isValid ? () => Navigator.of(context).pop(_password) : null; | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void dispose() { | ||||||
|  |     _focusScopeNode.dispose(); | ||||||
|  |     super.dispose(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return AlertDialog( | ||||||
|  |       title: Text(tr("New password")), | ||||||
|  |       content: AutoSizeDialogContentWidget(child: _buildContent()), | ||||||
|  |       actions: <Widget>[ | ||||||
|  |         MaterialButton( | ||||||
|  |           onPressed: () => Navigator.of(context).pop(), | ||||||
|  |           child: Text(tr("Cancel").toUpperCase()), | ||||||
|  |         ), | ||||||
|  |         MaterialButton( | ||||||
|  |           onPressed: _submitAction, | ||||||
|  |           child: Text(tr("Confirm").toUpperCase()), | ||||||
|  |         ), | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget _buildContent() { | ||||||
|  |     return FocusScope( | ||||||
|  |       node: _focusScopeNode, | ||||||
|  |       child: Column( | ||||||
|  |         children: <Widget>[ | ||||||
|  |           // Input 1 | ||||||
|  |           _buildPasswordField( | ||||||
|  |             controller: _controller1, | ||||||
|  |             label: tr("Your new password"), | ||||||
|  |             errorText: _controller1.text.isNotEmpty && !_input1Valid | ||||||
|  |                 ? tr("Invalid password!") | ||||||
|  |                 : null, | ||||||
|  |             textInputAction: TextInputAction.next, | ||||||
|  |             onSubmitted: () => _focusScopeNode.nextFocus(), | ||||||
|  |           ), | ||||||
|  |  | ||||||
|  |           // Input 2 | ||||||
|  |           _buildPasswordField( | ||||||
|  |               controller: _controller2, | ||||||
|  |               label: tr("Confirm you new password"), | ||||||
|  |               errorText: _controller2.text.isNotEmpty && !_input2Valid | ||||||
|  |                   ? tr("This password is not the same as the other one!") | ||||||
|  |                   : null, | ||||||
|  |               textInputAction: TextInputAction.done, | ||||||
|  |               onSubmitted: _submitAction), | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget _buildPasswordField({ | ||||||
|  |     @required TextEditingController controller, | ||||||
|  |     @required String label, | ||||||
|  |     @required String errorText, | ||||||
|  |     @required TextInputAction textInputAction, | ||||||
|  |     @required void Function() onSubmitted, | ||||||
|  |   }) { | ||||||
|  |     return TextFormField( | ||||||
|  |       textInputAction: textInputAction, | ||||||
|  |       controller: controller, | ||||||
|  |       onChanged: (s) => setState(() {}), | ||||||
|  |       onFieldSubmitted: (s) => onSubmitted(), | ||||||
|  |       obscureText: true, | ||||||
|  |       decoration: InputDecoration( | ||||||
|  |         alignLabelWithHint: true, | ||||||
|  |         labelText: label, | ||||||
|  |         errorText: errorText, | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -1,5 +1,8 @@ | |||||||
|  | import 'package:comunic/helpers/settings_helper.dart'; | ||||||
|  | import 'package:comunic/ui/dialogs/input_new_password_dialog.dart'; | ||||||
| import 'package:comunic/ui/dialogs/input_user_password_dialog.dart'; | import 'package:comunic/ui/dialogs/input_user_password_dialog.dart'; | ||||||
| import 'package:comunic/utils/intl_utils.dart'; | import 'package:comunic/utils/intl_utils.dart'; | ||||||
|  | import 'package:comunic/utils/ui_utils.dart'; | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
| import 'package:settings_ui/settings_ui.dart'; | import 'package:settings_ui/settings_ui.dart'; | ||||||
|  |  | ||||||
| @@ -46,6 +49,22 @@ class __AccountSecuritySettingsScreenBodyState | |||||||
|  |  | ||||||
|   /// Change current user password |   /// Change current user password | ||||||
|   void _changePassword() async { |   void _changePassword() async { | ||||||
|  |     try { | ||||||
|       final currPassword = await showUserPasswordDialog(context); |       final currPassword = await showUserPasswordDialog(context); | ||||||
|  |  | ||||||
|  |       if (currPassword == null) return; | ||||||
|  |  | ||||||
|  |       final newPassword = await showInputNewPassword(context); | ||||||
|  |  | ||||||
|  |       if (newPassword == null) return; | ||||||
|  |  | ||||||
|  |       await SettingsHelper.changePassword(currPassword, newPassword); | ||||||
|  |  | ||||||
|  |       showSimpleSnack( | ||||||
|  |           context, tr("Your password has been successfully changed!")); | ||||||
|  |     } catch (e, stack) { | ||||||
|  |       print("Could not update current user password! $e\n$stack"); | ||||||
|  |       showSimpleSnack(context, tr("Could not update password!")); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								lib/ui/widgets/auto_sized_dialog_content_widget.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								lib/ui/widgets/auto_sized_dialog_content_widget.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  |  | ||||||
|  | /// Widget that can be used to build dialog content | ||||||
|  | /// | ||||||
|  | /// @author Pierre Hubert | ||||||
|  | class AutoSizeDialogContentWidget extends StatelessWidget { | ||||||
|  |   final Widget child; | ||||||
|  |  | ||||||
|  |   const AutoSizeDialogContentWidget({ | ||||||
|  |     Key key, | ||||||
|  |     @required this.child, | ||||||
|  |   }) : super(key: key); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return ConstrainedBox( | ||||||
|  |         constraints: | ||||||
|  |             BoxConstraints(maxHeight: MediaQuery.of(context).size.height - 50), | ||||||
|  |         child: SingleChildScrollView( | ||||||
|  |           child: child, | ||||||
|  |         )); | ||||||
|  |   } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user