mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-04 04:04:18 +00:00 
			
		
		
		
	Can change password
This commit is contained in:
		@@ -158,6 +158,24 @@ class AccountHelper {
 | 
				
			|||||||
              .execWithThrow())
 | 
					              .execWithThrow())
 | 
				
			||||||
          .getObject()["reset_token"];
 | 
					          .getObject()["reset_token"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Check a password reset token
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// Throws in case failure
 | 
				
			||||||
 | 
					  static Future<void> validatePasswordResetToken(String token) async =>
 | 
				
			||||||
 | 
					      await APIRequest.withoutLogin("account/check_password_reset_token")
 | 
				
			||||||
 | 
					          .addString("token", token)
 | 
				
			||||||
 | 
					          .execWithThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Change account password using password reset token
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// Throws an exception in case of failure
 | 
				
			||||||
 | 
					  static Future<void> changeAccountPassword(
 | 
				
			||||||
 | 
					          String token, String password) async =>
 | 
				
			||||||
 | 
					      await APIRequest.withoutLogin("account/reset_user_passwd")
 | 
				
			||||||
 | 
					          .addString("token", token)
 | 
				
			||||||
 | 
					          .addString("password", password)
 | 
				
			||||||
 | 
					          .execWithThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Get current user ID from the server
 | 
					  /// Get current user ID from the server
 | 
				
			||||||
  Future<int> _downloadCurrentUserID() async {
 | 
					  Future<int> _downloadCurrentUserID() async {
 | 
				
			||||||
    final response = await APIRequest(
 | 
					    final response = await APIRequest(
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										129
									
								
								lib/ui/routes/password_reset_route.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								lib/ui/routes/password_reset_route.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,129 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/helpers/account_helper.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/dialogs/input_new_password_dialog.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/widgets/async_screen_widget.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/widgets/safe_state.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/intl_utils.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/ui_utils.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Reset user password route
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @author Pierre HUBERT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PasswordResetRoute extends StatelessWidget {
 | 
				
			||||||
 | 
					  final String token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const PasswordResetRoute({
 | 
				
			||||||
 | 
					    Key key,
 | 
				
			||||||
 | 
					    @required this.token,
 | 
				
			||||||
 | 
					  })  : assert(token != null),
 | 
				
			||||||
 | 
					        super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return Scaffold(
 | 
				
			||||||
 | 
					      appBar: AppBar(
 | 
				
			||||||
 | 
					        title: Text(tr("Change your password")),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      body: _PasswordResetBody(token: token),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _PasswordResetBody extends StatefulWidget {
 | 
				
			||||||
 | 
					  final String token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const _PasswordResetBody({Key key, @required this.token})
 | 
				
			||||||
 | 
					      : assert(token != null),
 | 
				
			||||||
 | 
					        super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  __PasswordResetBodyState createState() => __PasswordResetBodyState();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum _Status { BEFORE_CHANGE, WHILE_CHANGE, AFTER_CHANGE }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class __PasswordResetBodyState extends SafeState<_PasswordResetBody> {
 | 
				
			||||||
 | 
					  final _key = GlobalKey<AsyncScreenWidgetState>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var _status = _Status.BEFORE_CHANGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void _setStatus(_Status s) => setState(() => _status = s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Future<void> _validateToken() async {
 | 
				
			||||||
 | 
					    _status = _Status.BEFORE_CHANGE;
 | 
				
			||||||
 | 
					    await AccountHelper.validatePasswordResetToken(widget.token);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return AsyncScreenWidget(
 | 
				
			||||||
 | 
					      key: _key,
 | 
				
			||||||
 | 
					      onReload: _validateToken, // The first time, we validate the token
 | 
				
			||||||
 | 
					      onBuild: _buildBody,
 | 
				
			||||||
 | 
					      errorMessage: tr(
 | 
				
			||||||
 | 
					          "Could not validate your password reset token! Maybe it has expired now..."),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Widget _buildBody() {
 | 
				
			||||||
 | 
					    // The user has not requested yet to change his password
 | 
				
			||||||
 | 
					    if (_status == _Status.BEFORE_CHANGE)
 | 
				
			||||||
 | 
					      return Center(
 | 
				
			||||||
 | 
					          child: Column(
 | 
				
			||||||
 | 
					        mainAxisSize: MainAxisSize.min,
 | 
				
			||||||
 | 
					        children: <Widget>[
 | 
				
			||||||
 | 
					          Text(tr("You can choose a new password.")),
 | 
				
			||||||
 | 
					          OutlineButton(
 | 
				
			||||||
 | 
					            onPressed: _changePassword,
 | 
				
			||||||
 | 
					            child: Text(tr("Choose a new password")),
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Password is being changed
 | 
				
			||||||
 | 
					    if (_status == _Status.WHILE_CHANGE) return buildCenteredProgressBar();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Password was successfully changed!
 | 
				
			||||||
 | 
					    if (_status == _Status.AFTER_CHANGE)
 | 
				
			||||||
 | 
					      return Center(
 | 
				
			||||||
 | 
					          child: Column(
 | 
				
			||||||
 | 
					        mainAxisSize: MainAxisSize.min,
 | 
				
			||||||
 | 
					        children: <Widget>[
 | 
				
			||||||
 | 
					          Text(
 | 
				
			||||||
 | 
					            tr("Congratulations! Your password has now been successfully changed!"),
 | 
				
			||||||
 | 
					            textAlign: TextAlign.center,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          OutlineButton(
 | 
				
			||||||
 | 
					            onPressed: _quitScreen,
 | 
				
			||||||
 | 
					            child: Text(tr("Login")),
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    throw Exception("Unreachable statement!");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Ask the user to specify his new password
 | 
				
			||||||
 | 
					  void _changePassword() async {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      // Ask for new password
 | 
				
			||||||
 | 
					      final newPass = await showInputNewPassword(context);
 | 
				
			||||||
 | 
					      if (newPass == null) return;
 | 
				
			||||||
 | 
					      _setStatus(_Status.WHILE_CHANGE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Apply it
 | 
				
			||||||
 | 
					      await AccountHelper.changeAccountPassword(widget.token, newPass);
 | 
				
			||||||
 | 
					      _setStatus(_Status.AFTER_CHANGE);
 | 
				
			||||||
 | 
					    } catch (e, s) {
 | 
				
			||||||
 | 
					      print("Could not change user password! $e\n$s");
 | 
				
			||||||
 | 
					      showSimpleSnack(context, tr("Could not change your password!"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // We start everything again
 | 
				
			||||||
 | 
					      _key.currentState.refresh();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Go back to login screen
 | 
				
			||||||
 | 
					  void _quitScreen() => Navigator.of(context).pop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import 'package:comunic/helpers/account_helper.dart';
 | 
					import 'package:comunic/helpers/account_helper.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/routes/password_reset_route.dart';
 | 
				
			||||||
import 'package:comunic/ui/widgets/dialogs/cancel_dialog_button.dart';
 | 
					import 'package:comunic/ui/widgets/dialogs/cancel_dialog_button.dart';
 | 
				
			||||||
import 'package:comunic/ui/widgets/safe_state.dart';
 | 
					import 'package:comunic/ui/widgets/safe_state.dart';
 | 
				
			||||||
import 'package:comunic/utils/input_utils.dart';
 | 
					import 'package:comunic/utils/input_utils.dart';
 | 
				
			||||||
@@ -80,6 +81,8 @@ class _ResetPasswordBodyState extends SafeState<_ResetPasswordBody> {
 | 
				
			|||||||
      case _SelectedOption.SECURITY_QUESTIONS:
 | 
					      case _SelectedOption.SECURITY_QUESTIONS:
 | 
				
			||||||
        return _buildSecurityQuestionsScreen();
 | 
					        return _buildSecurityQuestionsScreen();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    throw Exception("Unreachable statement!");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Widget _buildEnterEmailAddressScreen() {
 | 
					  Widget _buildEnterEmailAddressScreen() {
 | 
				
			||||||
@@ -225,7 +228,8 @@ class _ResetPasswordBodyState extends SafeState<_ResetPasswordBody> {
 | 
				
			|||||||
    _setLoading(true);
 | 
					    _setLoading(true);
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      final token = await AccountHelper.checkAnswers(_emailAddress, _answers);
 | 
					      final token = await AccountHelper.checkAnswers(_emailAddress, _answers);
 | 
				
			||||||
      print(token);
 | 
					
 | 
				
			||||||
 | 
					      _useResetToken(token);
 | 
				
			||||||
    } catch (e, s) {
 | 
					    } catch (e, s) {
 | 
				
			||||||
      print("Could not submit security answers! $e\n$s");
 | 
					      print("Could not submit security answers! $e\n$s");
 | 
				
			||||||
      showSimpleSnack(
 | 
					      showSimpleSnack(
 | 
				
			||||||
@@ -233,6 +237,10 @@ class _ResetPasswordBodyState extends SafeState<_ResetPasswordBody> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    _setLoading(false);
 | 
					    _setLoading(false);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Call this method whenever the user managed to get a password reset token
 | 
				
			||||||
 | 
					  void _useResetToken(String token) => Navigator.of(context).pushReplacement(
 | 
				
			||||||
 | 
					      MaterialPageRoute(builder: (c) => PasswordResetRoute(token: token)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _Spacer extends StatelessWidget {
 | 
					class _Spacer extends StatelessWidget {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user