mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-26 06:49:22 +00:00
Show security questions
This commit is contained in:
parent
91e7dd4019
commit
e78d526bbb
@ -134,6 +134,16 @@ class AccountHelper {
|
|||||||
.execWithThrow())
|
.execWithThrow())
|
||||||
.getObject()["defined"];
|
.getObject()["defined"];
|
||||||
|
|
||||||
|
/// Get the security questions of the user
|
||||||
|
///
|
||||||
|
/// Throws in case of failure
|
||||||
|
static Future<List<String>> getSecurityQuestions(String email) async =>
|
||||||
|
((await APIRequest.withoutLogin("account/get_security_questions")
|
||||||
|
.addString("email", email)
|
||||||
|
.execWithThrow())
|
||||||
|
.getObject()["questions"])
|
||||||
|
.cast<String>();
|
||||||
|
|
||||||
/// Get current user ID from the server
|
/// Get current user ID from the server
|
||||||
Future<int> _downloadCurrentUserID() async {
|
Future<int> _downloadCurrentUserID() async {
|
||||||
final response = await APIRequest(
|
final response = await APIRequest(
|
||||||
|
@ -6,6 +6,7 @@ import 'package:comunic/utils/intl_utils.dart';
|
|||||||
import 'package:comunic/utils/ui_utils.dart';
|
import 'package:comunic/utils/ui_utils.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
|
||||||
/// Reset password route
|
/// Reset password route
|
||||||
///
|
///
|
||||||
@ -21,14 +22,14 @@ class ResetPasswordRoute extends StatelessWidget {
|
|||||||
body: Center(
|
body: Center(
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(maxWidth: 300),
|
constraints: BoxConstraints(maxWidth: 300),
|
||||||
child: _ResetPasswordBody(),
|
child: SingleChildScrollView(child: _ResetPasswordBody()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum _SelectedOption { NONE }
|
enum _SelectedOption { NONE, SECURITY_QUESTIONS }
|
||||||
|
|
||||||
class _ResetPasswordBody extends StatefulWidget {
|
class _ResetPasswordBody extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
@ -54,6 +55,10 @@ class _ResetPasswordBodyState extends SafeState<_ResetPasswordBody> {
|
|||||||
|
|
||||||
void _setLoading(bool loading) => setState(() => _loading = loading);
|
void _setLoading(bool loading) => setState(() => _loading = loading);
|
||||||
|
|
||||||
|
/// Step 3b - Answer security questions
|
||||||
|
List<String> _questions;
|
||||||
|
var _questionsControllers = List<TextEditingController>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (_loading) return buildCenteredProgressBar();
|
if (_loading) return buildCenteredProgressBar();
|
||||||
@ -63,6 +68,9 @@ class _ResetPasswordBodyState extends SafeState<_ResetPasswordBody> {
|
|||||||
switch (_selectedOption) {
|
switch (_selectedOption) {
|
||||||
case _SelectedOption.NONE:
|
case _SelectedOption.NONE:
|
||||||
return _buildOptionsScreen();
|
return _buildOptionsScreen();
|
||||||
|
|
||||||
|
case _SelectedOption.SECURITY_QUESTIONS:
|
||||||
|
return _buildSecurityQuestionsScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,13 +134,20 @@ class _ResetPasswordBodyState extends SafeState<_ResetPasswordBody> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(tr("Here are your options to reset your account:")),
|
Text(tr("Here are your options to reset your account:")),
|
||||||
Container(height: 15),
|
_Spacer(),
|
||||||
OutlineButton.icon(
|
OutlineButton.icon(
|
||||||
onPressed: _openSendEmailDialog,
|
onPressed: _openSendEmailDialog,
|
||||||
icon: Icon(Icons.email),
|
icon: Icon(Icons.email),
|
||||||
label: Text(tr("Send us an email to ask for help")),
|
label: Text(tr("Send us an email to ask for help")),
|
||||||
),
|
),
|
||||||
Container(height: 15),
|
_Spacer(visible: _hasSecurityQuestions),
|
||||||
|
_hasSecurityQuestions
|
||||||
|
? OutlineButton.icon(
|
||||||
|
onPressed: _loadSecurityQuestions,
|
||||||
|
icon: Icon(Icons.help_outline),
|
||||||
|
label: Text(tr("Answer your security questions")),
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -146,4 +161,60 @@ class _ResetPasswordBodyState extends SafeState<_ResetPasswordBody> {
|
|||||||
actions: <Widget>[CancelDialogButton()],
|
actions: <Widget>[CancelDialogButton()],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Load security questions
|
||||||
|
void _loadSecurityQuestions() async {
|
||||||
|
_setLoading(true);
|
||||||
|
try {
|
||||||
|
_questions = await AccountHelper.getSecurityQuestions(_emailAddress);
|
||||||
|
|
||||||
|
_questionsControllers =
|
||||||
|
List.generate(_questions.length, (i) => TextEditingController());
|
||||||
|
_selectedOption = _SelectedOption.SECURITY_QUESTIONS;
|
||||||
|
} catch (e, s) {
|
||||||
|
print("Could not load security questions! $e\n$s");
|
||||||
|
showSimpleSnack(context, tr("Could not load your security questions!"));
|
||||||
|
}
|
||||||
|
_setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Show a screen to prompt security questions of the user
|
||||||
|
Widget _buildSecurityQuestionsScreen() {
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: <Widget>[]
|
||||||
|
..add(Text(tr("Please answer now your security questions:")))
|
||||||
|
..add(_Spacer())
|
||||||
|
..addAll(List.generate(_questions.length, _buildSecurityQuestionField))
|
||||||
|
..add(_Spacer())
|
||||||
|
..add(OutlineButton(
|
||||||
|
onPressed: null,
|
||||||
|
child: Text(tr("Submit")),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSecurityQuestionField(int id) => TextField(
|
||||||
|
controller: _questionsControllers[id],
|
||||||
|
decoration: InputDecoration(
|
||||||
|
alignLabelWithHint: true,
|
||||||
|
labelText: _questions[id],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _Spacer extends StatelessWidget {
|
||||||
|
final bool visible;
|
||||||
|
|
||||||
|
const _Spacer({Key key, this.visible = true})
|
||||||
|
: assert(visible != null),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
height: visible ? 35 : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user