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())
 | 
			
		||||
          .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
 | 
			
		||||
  Future<int> _downloadCurrentUserID() async {
 | 
			
		||||
    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/ui/routes/password_reset_route.dart';
 | 
			
		||||
import 'package:comunic/ui/widgets/dialogs/cancel_dialog_button.dart';
 | 
			
		||||
import 'package:comunic/ui/widgets/safe_state.dart';
 | 
			
		||||
import 'package:comunic/utils/input_utils.dart';
 | 
			
		||||
@@ -80,6 +81,8 @@ class _ResetPasswordBodyState extends SafeState<_ResetPasswordBody> {
 | 
			
		||||
      case _SelectedOption.SECURITY_QUESTIONS:
 | 
			
		||||
        return _buildSecurityQuestionsScreen();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    throw Exception("Unreachable statement!");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildEnterEmailAddressScreen() {
 | 
			
		||||
@@ -225,7 +228,8 @@ class _ResetPasswordBodyState extends SafeState<_ResetPasswordBody> {
 | 
			
		||||
    _setLoading(true);
 | 
			
		||||
    try {
 | 
			
		||||
      final token = await AccountHelper.checkAnswers(_emailAddress, _answers);
 | 
			
		||||
      print(token);
 | 
			
		||||
 | 
			
		||||
      _useResetToken(token);
 | 
			
		||||
    } catch (e, s) {
 | 
			
		||||
      print("Could not submit security answers! $e\n$s");
 | 
			
		||||
      showSimpleSnack(
 | 
			
		||||
@@ -233,6 +237,10 @@ class _ResetPasswordBodyState extends SafeState<_ResetPasswordBody> {
 | 
			
		||||
    }
 | 
			
		||||
    _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 {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user