1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-22 21:09:21 +00:00

Check email address

This commit is contained in:
Pierre HUBERT 2020-05-03 14:22:06 +02:00
parent e1795bac03
commit 6e274cae11
4 changed files with 151 additions and 0 deletions

View File

@ -116,6 +116,24 @@ class AccountHelper {
} }
} }
/// Check out whether a given email address exists or not
///
/// Throws in case of failure
static Future<bool> existsMailAccount(String email) async =>
(await APIRequest.withoutLogin("account/exists_email")
.addString("email", email)
.execWithThrow())
.getObject()["exists"];
/// Check out whether security questions have been set for an account or not
///
/// Throws in case of failure
static Future<bool> hasSecurityQuestions(String email) async =>
(await APIRequest.withoutLogin("account/has_security_questions")
.addString("email", email)
.execWithThrow())
.getObject()["defined"];
/// 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(

View File

@ -42,6 +42,12 @@ class APIRequest {
if (args == null) this.args = Map(); if (args == null) this.args = Map();
} }
APIRequest.withoutLogin(this.uri, {this.args})
: needLogin = false,
assert(uri != null) {
if (args == null) this.args = Map();
}
APIRequest addString(String name, String value) { APIRequest addString(String name, String value) {
args[name] = value; args[name] = value;
return this; return this;

View File

@ -1,6 +1,7 @@
import 'package:comunic/helpers/account_helper.dart'; import 'package:comunic/helpers/account_helper.dart';
import 'package:comunic/models/authentication_details.dart'; import 'package:comunic/models/authentication_details.dart';
import 'package:comunic/ui/routes/create_account_route.dart'; import 'package:comunic/ui/routes/create_account_route.dart';
import 'package:comunic/ui/routes/reset_password_route.dart';
import 'package:comunic/ui/widgets/init_widget.dart'; import 'package:comunic/ui/widgets/init_widget.dart';
import 'package:comunic/utils/input_utils.dart'; import 'package:comunic/utils/input_utils.dart';
import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/intl_utils.dart';
@ -65,6 +66,11 @@ class _LoginRouteState extends State<LoginRoute> {
.push(MaterialPageRoute(builder: (c) => CreateAccountRoute())); .push(MaterialPageRoute(builder: (c) => CreateAccountRoute()));
} }
void _openResetPasswordPage() {
Navigator.of(context)
.push(MaterialPageRoute(builder: (c) => ResetPasswordRoute()));
}
/// Build error card /// Build error card
Widget _buildErrorCard() { Widget _buildErrorCard() {
if (_authResult == null) return null; if (_authResult == null) return null;
@ -134,6 +140,16 @@ class _LoginRouteState extends State<LoginRoute> {
), ),
onTap: () => _openCreateAccountPage(), onTap: () => _openCreateAccountPage(),
), ),
Container(height: 10),
InkWell(
child: Text(
tr("Password forgotten"),
style: TextStyle(color: Colors.blue),
),
onTap: _openResetPasswordPage,
),
], ],
), ),
), ),

View File

@ -0,0 +1,111 @@
import 'package:comunic/helpers/account_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/cupertino.dart';
import 'package:flutter/material.dart';
/// Reset password route
///
/// @author Pierre Hubert
class ResetPasswordRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(tr("Password forgotten")),
),
body: Center(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 300),
child: _ResetPasswordBody(),
),
),
);
}
}
class _ResetPasswordBody extends StatefulWidget {
@override
_ResetPasswordBodyState createState() => _ResetPasswordBodyState();
}
class _ResetPasswordBodyState extends SafeState<_ResetPasswordBody> {
var _loading = false;
/// Step 1 - check email address
String _emailAddress;
final _emailController = TextEditingController();
String get _inputEmail => _emailController.text;
bool get _isEmailValid =>
_inputEmail.isNotEmpty && validateEmail(_inputEmail);
/// Step 2 - Offer options
bool _hasSecurityQuestions;
void _setLoading(bool loading) => setState(() => _loading = loading);
@override
Widget build(BuildContext context) {
if (_loading) return buildCenteredProgressBar();
if (_emailAddress == null) return _buildEnterEmailAddressScreen();
}
Widget _buildEnterEmailAddressScreen() {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: _emailController,
onChanged: (s) => setState(() {}),
onSubmitted: _isEmailValid ? (s) => _checkEmail() : null,
textInputAction: TextInputAction.done,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
icon: Icon(Icons.email),
alignLabelWithHint: true,
labelText: tr("Email address..."),
suffixIcon: IconButton(
icon: Icon(Icons.check),
onPressed: _isEmailValid ? _checkEmail : null,
),
errorText: _inputEmail.isEmpty || _isEmailValid
? null
: tr("Invalid email address!"),
),
),
],
);
}
/// Check given email address
void _checkEmail() async {
try {
_setLoading(true);
// Check if email address exists or not
if (!await AccountHelper.existsMailAccount(_inputEmail)) {
_setLoading(false);
showSimpleSnack(context, tr("Specified email address was not found!"));
return;
}
_hasSecurityQuestions =
await AccountHelper.hasSecurityQuestions(_inputEmail);
// We retain email address only if everything went well
_emailAddress = _inputEmail;
_setLoading(false);
} catch (e, s) {
print("Could not check given email! $e\n$s");
showSimpleSnack(
context, tr("An error occurred while checking your options !"));
_setLoading(false);
}
}
}