1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-30 00:36:28 +00:00
comunicmobile/lib/ui/routes/account_settings/account_security_settings.dart

217 lines
6.9 KiB
Dart
Raw Normal View History

import 'package:comunic/helpers/account_helper.dart';
2020-04-30 16:19:01 +00:00
import 'package:comunic/helpers/settings_helper.dart';
2020-05-01 07:02:15 +00:00
import 'package:comunic/models/security_settings.dart';
2020-04-30 16:19:01 +00:00
import 'package:comunic/ui/dialogs/input_new_password_dialog.dart';
2020-04-30 11:32:22 +00:00
import 'package:comunic/ui/dialogs/input_user_password_dialog.dart';
2020-05-02 13:32:06 +00:00
import 'package:comunic/ui/widgets/dialogs/auto_sized_dialog_content_widget.dart';
2020-04-29 15:28:47 +00:00
import 'package:comunic/utils/intl_utils.dart';
2020-04-30 16:19:01 +00:00
import 'package:comunic/utils/ui_utils.dart';
2020-04-29 15:28:47 +00:00
import 'package:flutter/material.dart';
2020-04-30 11:32:22 +00:00
import 'package:settings_ui/settings_ui.dart';
2020-04-29 15:28:47 +00:00
/// Account security settings
///
/// @author Pierre HUBERT
class AccountSecuritySettingsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(tr("Security settings")),
),
2020-04-30 11:32:22 +00:00
body: _AccountSecuritySettingsScreenBody(),
2020-04-29 15:28:47 +00:00
);
}
}
2020-04-30 11:32:22 +00:00
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,
),
2020-05-01 07:02:15 +00:00
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,
),
SettingsTile(
title: tr("Disconnect all your devices"),
subtitle: tr(
"Disconnect all your devices from Comunic, including the current one. Use this option if one of the device you use for Comunic was stolen."),
onTap: _disconnectAllDevices,
),
2020-04-30 11:32:22 +00:00
],
)
],
);
}
/// Change current user password
void _changePassword() async {
2020-04-30 16:19:01 +00:00
try {
final currPassword = await showUserPasswordDialog(context);
if (currPassword == null) return;
final newPassword = await showInputNewPassword(context);
if (newPassword == null) return;
await SettingsHelper.changePassword(currPassword, newPassword);
showSimpleSnack(
context, tr("Your password has been successfully changed!"));
} catch (e, stack) {
print("Could not update current user password! $e\n$stack");
showSimpleSnack(context, tr("Could not update password!"));
}
2020-04-30 11:32:22 +00:00
}
2020-05-01 07:02:15 +00:00
/// 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!"));
}
}
/// Disconnect all devices
void _disconnectAllDevices() async {
try {
if (!await showConfirmDialog(
context: context,
message: tr(
"Do you really want to disconnect all your devices from Comunic ?")))
return;
await AccountHelper.disconnectAllDevices();
} catch (e, stack) {
print("Could not disconnect user on all devices! $e\n$stack");
showSimpleSnack(
context, tr("Could not disconnect you from all your devices!"));
}
}
2020-05-01 07:02:15 +00:00
}
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,
),
);
}
2020-04-30 11:32:22 +00:00
}