1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-26 14:59:22 +00:00

Can ask user his password

This commit is contained in:
Pierre HUBERT 2020-04-30 13:32:22 +02:00
parent d64d2ece05
commit 29cc8558c3
7 changed files with 136 additions and 2 deletions

View File

@ -80,7 +80,7 @@ class APIHelper {
EventsHelper.emit(InvalidLoginTokensEvent()); EventsHelper.emit(InvalidLoginTokensEvent());
if (response.statusCode != HttpStatus.ok) if (response.statusCode != HttpStatus.ok)
return APIResponse(response.statusCode, null); return APIResponse(response.statusCode, response.data);
return APIResponse(response.statusCode, response.data); return APIResponse(response.statusCode, response.data);
} catch (e, stack) { } catch (e, stack) {

View File

@ -143,4 +143,12 @@ class SettingsHelper {
.addInt("emojiID", emojiID) .addInt("emojiID", emojiID)
.exec()) .exec())
.assertOk(); .assertOk();
/// Check current user password
///
/// Throws in case of failure
static Future<void> checkUserPassword(String password) async =>
await APIRequest(uri: "settings/check_password", needLogin: true)
.addString("password", password)
.execWithThrow();
} }

View File

@ -66,6 +66,9 @@ class APIRequest {
/// Execute the request /// Execute the request
Future<APIResponse> exec() async => APIHelper().exec(this); Future<APIResponse> exec() async => APIHelper().exec(this);
/// Execute the request, throws an exception in case of failure
Future<APIResponse> execWithThrow() async => (await exec()).assertOk();
/// Execute the request with files /// Execute the request with files
Future<APIResponse> execWithFiles() async => APIHelper().execWithFiles(this); Future<APIResponse> execWithFiles() async => APIHelper().execWithFiles(this);
} }

View File

@ -21,7 +21,7 @@ class APIResponse {
APIResponse assertOk() { APIResponse assertOk() {
if(!this.isOK) if(!this.isOK)
throw Exception("Request failed with status $code"); throw Exception("Request failed with status $code -> $content");
return this; return this;
} }

View File

@ -0,0 +1,85 @@
import 'package:comunic/helpers/settings_helper.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/utils/input_utils.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
/// Ask the user to enter his password
///
/// @author Pierre Hubert
enum _Status { NONE, CHECKING, ERROR }
Future<String> showUserPasswordDialog(BuildContext context) async {
return await showDialog(
context: context, builder: (c) => _InputUserPasswordDialog());
}
class _InputUserPasswordDialog extends StatefulWidget {
@override
__InputUserPasswordDialogState createState() =>
__InputUserPasswordDialogState();
}
class __InputUserPasswordDialogState
extends SafeState<_InputUserPasswordDialog> {
final _controller = TextEditingController();
var _status = _Status.NONE;
String get _currPass => _controller.text;
bool get _canSubmit =>
validatePassword(_controller.text) && _status != _Status.CHECKING;
void _setStatus(_Status s) => setState(() => _status = s);
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(tr("Password required")),
content: _buildContent(),
actions: <Widget>[
MaterialButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(tr("Cancel").toUpperCase()),
),
MaterialButton(
onPressed: _canSubmit ? _checkPassword : null,
child: Text(tr("Submit").toUpperCase()),
),
],
);
}
Widget _buildContent() {
if (_status == _Status.CHECKING)
return IntrinsicHeight(
child: buildCenteredProgressBar(),
);
return TextField(
controller: _controller,
obscureText: true,
onChanged: (s) => _setStatus(_Status.NONE),
decoration: InputDecoration(
alignLabelWithHint: true,
labelText: tr("Your current password"),
errorText: _status == _Status.ERROR ? tr("Invalid password!") : null,
),
);
}
void _checkPassword() async {
try {
_setStatus(_Status.CHECKING);
await SettingsHelper.checkUserPassword(_currPass);
Navigator.of(context).pop(_currPass);
} catch (e, stack) {
print("Could not validate user pasword! $e\n$stack");
_setStatus(_Status.ERROR);
}
}
}

View File

@ -1,5 +1,7 @@
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:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:settings_ui/settings_ui.dart';
/// Account security settings /// Account security settings
/// ///
@ -12,6 +14,38 @@ class AccountSecuritySettingsScreen extends StatelessWidget {
appBar: AppBar( appBar: AppBar(
title: Text(tr("Security settings")), title: Text(tr("Security settings")),
), ),
body: _AccountSecuritySettingsScreenBody(),
); );
} }
} }
class _AccountSecuritySettingsScreenBody extends StatefulWidget {
@override
__AccountSecuritySettingsScreenBodyState createState() =>
__AccountSecuritySettingsScreenBodyState();
}
class __AccountSecuritySettingsScreenBodyState
extends State<_AccountSecuritySettingsScreenBody> {
@override
Widget build(BuildContext context) {
return SettingsList(
sections: [
SettingsSection(
title: tr("Password"),
tiles: [
SettingsTile(
title: tr("Change password"),
onTap: _changePassword,
),
],
)
],
);
}
/// Change current user password
void _changePassword() async {
final currPassword = await showUserPasswordDialog(context);
}
}

View File

@ -2,6 +2,10 @@
/// ///
/// @author Pierre HUBERT /// @author Pierre HUBERT
/// Check out whether a password is valid or not
bool validatePassword(String s) => s.length > 3;
/// Check out whether a given email address is valid or not /// Check out whether a given email address is valid or not
/// ///
/// Taken from https://medium.com/@nitishk72/form-validation-in-flutter-d762fbc9212c /// Taken from https://medium.com/@nitishk72/form-validation-in-flutter-d762fbc9212c