mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-12-26 04:48:51 +00:00
Can change password
This commit is contained in:
parent
44ea647624
commit
11c25ea271
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user