mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-12-26 04:48:51 +00:00
Can change security settings
This commit is contained in:
parent
289bf30a40
commit
20ea964337
@ -5,6 +5,7 @@ import 'package:comunic/models/account_image_settings.dart';
|
||||
import 'package:comunic/models/api_request.dart';
|
||||
import 'package:comunic/models/general_settings.dart';
|
||||
import 'package:comunic/models/new_emoji.dart';
|
||||
import 'package:comunic/models/security_settings.dart';
|
||||
|
||||
/// Settings helper
|
||||
///
|
||||
@ -161,4 +162,36 @@ class SettingsHelper {
|
||||
.addString("oldPassword", oldPassword)
|
||||
.addString("newPassword", newPassword)
|
||||
.execWithThrow();
|
||||
|
||||
/// Retrieve security settings of the user
|
||||
///
|
||||
/// This method throws in case of failure
|
||||
static Future<SecuritySettings> getSecuritySettings(String password) async {
|
||||
final response =
|
||||
(await APIRequest(uri: "settings/get_security", needLogin: true)
|
||||
.addString("password", password)
|
||||
.execWithThrow())
|
||||
.getObject();
|
||||
|
||||
return SecuritySettings(
|
||||
securityQuestion1: response["security_question_1"],
|
||||
securityAnswer1: response["security_answer_1"],
|
||||
securityQuestion2: response["security_question_2"],
|
||||
securityAnswer2: response["security_answer_2"],
|
||||
);
|
||||
}
|
||||
|
||||
/// Apply new security settings to the user
|
||||
///
|
||||
/// Throws in case of failure
|
||||
static Future<void> setSecuritySettings(
|
||||
String password, SecuritySettings newSettings) async {
|
||||
await APIRequest(uri: "settings/set_security", needLogin: true)
|
||||
.addString("password", password)
|
||||
.addString("security_question_1", newSettings.securityQuestion1)
|
||||
.addString("security_answer_1", newSettings.securityAnswer1)
|
||||
.addString("security_question_2", newSettings.securityQuestion2)
|
||||
.addString("security_answer_2", newSettings.securityAnswer2)
|
||||
.execWithThrow();
|
||||
}
|
||||
}
|
||||
|
22
lib/models/security_settings.dart
Normal file
22
lib/models/security_settings.dart
Normal file
@ -0,0 +1,22 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Security settings of the user
|
||||
///
|
||||
/// @author Pierre HUBERT
|
||||
|
||||
class SecuritySettings {
|
||||
final String securityQuestion1;
|
||||
final String securityAnswer1;
|
||||
final String securityQuestion2;
|
||||
final String securityAnswer2;
|
||||
|
||||
const SecuritySettings({
|
||||
@required this.securityQuestion1,
|
||||
@required this.securityAnswer1,
|
||||
@required this.securityQuestion2,
|
||||
@required this.securityAnswer2,
|
||||
}) : assert(securityQuestion1 != null),
|
||||
assert(securityAnswer1 != null),
|
||||
assert(securityQuestion2 != null),
|
||||
assert(securityAnswer2 != null);
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
import 'package:comunic/helpers/settings_helper.dart';
|
||||
import 'package:comunic/models/security_settings.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/widgets/auto_sized_dialog_content_widget.dart';
|
||||
import 'package:comunic/utils/intl_utils.dart';
|
||||
import 'package:comunic/utils/ui_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -41,6 +43,12 @@ class __AccountSecuritySettingsScreenBodyState
|
||||
title: tr("Change password"),
|
||||
onTap: _changePassword,
|
||||
),
|
||||
SettingsTile(
|
||||
title: tr("Change your security questions"),
|
||||
subtitle: tr(
|
||||
"Your security questions can be used to recover an access to your account when you loose your password..."),
|
||||
onTap: _changeSecurityQuestions,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
@ -67,4 +75,118 @@ class __AccountSecuritySettingsScreenBodyState
|
||||
showSimpleSnack(context, tr("Could not update password!"));
|
||||
}
|
||||
}
|
||||
|
||||
/// Change security questions
|
||||
void _changeSecurityQuestions() async {
|
||||
try {
|
||||
final password = await showUserPasswordDialog(context);
|
||||
|
||||
if (password == null) return;
|
||||
|
||||
final settings = await SettingsHelper.getSecuritySettings(password);
|
||||
|
||||
final newSettings = await showDialog<SecuritySettings>(
|
||||
context: context,
|
||||
builder: (c) => _SecurityQuestionsDialog(settings: settings));
|
||||
|
||||
if (newSettings == null) return;
|
||||
|
||||
await SettingsHelper.setSecuritySettings(password, newSettings);
|
||||
|
||||
showSimpleSnack(context,
|
||||
tr("You security questions have been successfully updated!"));
|
||||
} catch (e, stack) {
|
||||
print("Could not update security questions!$e\n$stack");
|
||||
showSimpleSnack(context, tr("Could not update security questions!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _SecurityQuestionsDialog extends StatefulWidget {
|
||||
final SecuritySettings settings;
|
||||
|
||||
const _SecurityQuestionsDialog({Key key, @required this.settings})
|
||||
: assert(settings != null),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
__SecurityQuestionsDialogState createState() =>
|
||||
__SecurityQuestionsDialogState();
|
||||
}
|
||||
|
||||
class __SecurityQuestionsDialogState extends State<_SecurityQuestionsDialog> {
|
||||
TextEditingController _controllerQuestion1;
|
||||
TextEditingController _controllerAnswer1;
|
||||
TextEditingController _controllerQuestion2;
|
||||
TextEditingController _controllerAnswer2;
|
||||
|
||||
SecuritySettings get _newSettings => SecuritySettings(
|
||||
securityQuestion1: _controllerQuestion1.text,
|
||||
securityAnswer1: _controllerAnswer1.text,
|
||||
securityQuestion2: _controllerQuestion2.text,
|
||||
securityAnswer2: _controllerAnswer2.text,
|
||||
);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_controllerQuestion1 =
|
||||
TextEditingController(text: widget.settings.securityQuestion1);
|
||||
_controllerAnswer1 =
|
||||
TextEditingController(text: widget.settings.securityAnswer1);
|
||||
_controllerQuestion2 =
|
||||
TextEditingController(text: widget.settings.securityQuestion2);
|
||||
_controllerAnswer2 =
|
||||
TextEditingController(text: widget.settings.securityAnswer2);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(tr("Update security questions")),
|
||||
content: AutoSizeDialogContentWidget(child: _buildContent()),
|
||||
actions: <Widget>[
|
||||
MaterialButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: Text(tr("Cancel").toUpperCase()),
|
||||
),
|
||||
MaterialButton(
|
||||
onPressed: () => Navigator.of(context).pop(_newSettings),
|
||||
child: Text(tr("Update").toUpperCase()),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildContent() {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Text(tr(
|
||||
"Note: Your two questions and answers MUST be completed in order to be able to recover your account using your security questions!")),
|
||||
_buildTextField(
|
||||
controller: _controllerQuestion1, label: tr("Question 1")),
|
||||
_buildTextField(controller: _controllerAnswer1, label: tr("Answer 1")),
|
||||
_buildTextField(
|
||||
controller: _controllerQuestion2, label: tr("Question 2")),
|
||||
_buildTextField(controller: _controllerAnswer2, label: tr("Answer 2")),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTextField({
|
||||
@required TextEditingController controller,
|
||||
@required String label,
|
||||
}) {
|
||||
return TextField(
|
||||
controller: controller,
|
||||
onChanged: (s) => setState(() {}),
|
||||
decoration: InputDecoration(
|
||||
alignLabelWithHint: true,
|
||||
labelText: label,
|
||||
errorText: controller.text.isNotEmpty && controller.text.length < 5
|
||||
? tr("Unsafe value!")
|
||||
: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user