diff --git a/lib/helpers/api_helper.dart b/lib/helpers/api_helper.dart index f5d61f7..0e5c983 100644 --- a/lib/helpers/api_helper.dart +++ b/lib/helpers/api_helper.dart @@ -21,10 +21,15 @@ class APIHelper { //Add API tokens request.addString("client", config().clientName); - //Add user tokens (if required) + //Add user token (if required) if (request.needLogin) { final token = (await PreferencesHelper.getInstance()).getLoginToken(); - assert(token != null); + + if (token == null) { + EventsHelper.emit(InvalidLoginTokensEvent()); + throw new Exception("No login token available!"); + } + request.addString("token", token); } diff --git a/lib/helpers/server_config_helper.dart b/lib/helpers/server_config_helper.dart index 4b1118f..47c028b 100644 --- a/lib/helpers/server_config_helper.dart +++ b/lib/helpers/server_config_helper.dart @@ -21,59 +21,66 @@ class ServerConfigurationHelper { final passwordPolicy = response["password_policy"]; final dataConservationPolicy = response["data_conservation_policy"]; final conversationsPolicy = response["conversations_policy"]; + final accountInformationPolicy = response["account_info_policy"]; _config = ServerConfig( - minSupportedMobileVersion: - Version.parse(response["min_supported_mobile_version"]), - termsURL: response["terms_url"], - playStoreURL: response["play_store_url"], - androidDirectDownloadURL: response["android_direct_download_url"], - notificationsPolicy: NotificationsPolicy( - hasFirebase: pushNotificationsPolicy["has_firebase"], - hasIndependent: pushNotificationsPolicy["has_independent"], - ), - passwordPolicy: PasswordPolicy( - allowMailInPassword: passwordPolicy["allow_email_in_password"], - allowNameInPassword: passwordPolicy["allow_name_in_password"], - minPasswordLength: passwordPolicy["min_password_length"], - minNumberUpperCaseLetters: - passwordPolicy["min_number_upper_case_letters"], - minNumberLowerCaseLetters: - passwordPolicy["min_number_lower_case_letters"], - minNumberDigits: passwordPolicy["min_number_digits"], - minNumberSpecialCharacters: - passwordPolicy["min_number_special_characters"], - minCategoriesPresence: passwordPolicy["min_categories_presence"], - ), - dataConservationPolicy: ServerDataConservationPolicy( - minInactiveAccountLifetime: - dataConservationPolicy["min_inactive_account_lifetime"], - minNotificationLifetime: - dataConservationPolicy["min_notification_lifetime"], - minCommentsLifetime: dataConservationPolicy["min_comments_lifetime"], - minPostsLifetime: dataConservationPolicy["min_posts_lifetime"], - minConversationMessagesLifetime: - dataConservationPolicy["min_conversation_messages_lifetime"], - minLikesLifetime: dataConservationPolicy["min_likes_lifetime"], - ), - conversationsPolicy: ConversationsPolicy( - maxConversationNameLen: - conversationsPolicy["max_conversation_name_len"], - minMessageLen: conversationsPolicy["min_message_len"], - maxMessageLen: conversationsPolicy["max_message_len"], - allowedFilesType: - conversationsPolicy["allowed_files_type"].cast(), - filesMaxSize: conversationsPolicy["files_max_size"], - writingEventInterval: conversationsPolicy["writing_event_interval"], - writingEventLifetime: conversationsPolicy["writing_event_lifetime"], - maxMessageImageWidth: conversationsPolicy["max_message_image_width"], - maxMessageImageHeight: - conversationsPolicy["max_message_image_height"], - maxThumbnailWidth: conversationsPolicy["max_thumbnail_width"], - maxThumbnailHeight: conversationsPolicy["max_thumbnail_height"], - maxLogoWidth: conversationsPolicy["max_logo_width"], - maxLogoHeight: conversationsPolicy["max_logo_height"], - )); + minSupportedMobileVersion: + Version.parse(response["min_supported_mobile_version"]), + termsURL: response["terms_url"], + playStoreURL: response["play_store_url"], + androidDirectDownloadURL: response["android_direct_download_url"], + notificationsPolicy: NotificationsPolicy( + hasFirebase: pushNotificationsPolicy["has_firebase"], + hasIndependent: pushNotificationsPolicy["has_independent"], + ), + passwordPolicy: PasswordPolicy( + allowMailInPassword: passwordPolicy["allow_email_in_password"], + allowNameInPassword: passwordPolicy["allow_name_in_password"], + minPasswordLength: passwordPolicy["min_password_length"], + minNumberUpperCaseLetters: + passwordPolicy["min_number_upper_case_letters"], + minNumberLowerCaseLetters: + passwordPolicy["min_number_lower_case_letters"], + minNumberDigits: passwordPolicy["min_number_digits"], + minNumberSpecialCharacters: + passwordPolicy["min_number_special_characters"], + minCategoriesPresence: passwordPolicy["min_categories_presence"], + ), + dataConservationPolicy: ServerDataConservationPolicy( + minInactiveAccountLifetime: + dataConservationPolicy["min_inactive_account_lifetime"], + minNotificationLifetime: + dataConservationPolicy["min_notification_lifetime"], + minCommentsLifetime: dataConservationPolicy["min_comments_lifetime"], + minPostsLifetime: dataConservationPolicy["min_posts_lifetime"], + minConversationMessagesLifetime: + dataConservationPolicy["min_conversation_messages_lifetime"], + minLikesLifetime: dataConservationPolicy["min_likes_lifetime"], + ), + conversationsPolicy: ConversationsPolicy( + maxConversationNameLen: + conversationsPolicy["max_conversation_name_len"], + minMessageLen: conversationsPolicy["min_message_len"], + maxMessageLen: conversationsPolicy["max_message_len"], + allowedFilesType: + conversationsPolicy["allowed_files_type"].cast(), + filesMaxSize: conversationsPolicy["files_max_size"], + writingEventInterval: conversationsPolicy["writing_event_interval"], + writingEventLifetime: conversationsPolicy["writing_event_lifetime"], + maxMessageImageWidth: conversationsPolicy["max_message_image_width"], + maxMessageImageHeight: conversationsPolicy["max_message_image_height"], + maxThumbnailWidth: conversationsPolicy["max_thumbnail_width"], + maxThumbnailHeight: conversationsPolicy["max_thumbnail_height"], + maxLogoWidth: conversationsPolicy["max_logo_width"], + maxLogoHeight: conversationsPolicy["max_logo_height"], + ), + accountInformationPolicy: AccountInformationPolicy( + minFirstNameLength: accountInformationPolicy["min_first_name_length"], + maxFirstNameLength: accountInformationPolicy["max_first_name_length"], + minLastNameLength: accountInformationPolicy["min_last_name_length"], + maxLastNameLength: accountInformationPolicy["max_last_name_length"], + ), + ); } /// Get current server configuration, throwing if it is not loaded yet diff --git a/lib/models/server_config.dart b/lib/models/server_config.dart index 1300796..f826733 100644 --- a/lib/models/server_config.dart +++ b/lib/models/server_config.dart @@ -112,6 +112,23 @@ class ConversationsPolicy { assert(maxLogoHeight != null); } +class AccountInformationPolicy { + final int minFirstNameLength; + final int maxFirstNameLength; + final int minLastNameLength; + final int maxLastNameLength; + + const AccountInformationPolicy({ + @required this.minFirstNameLength, + @required this.maxFirstNameLength, + @required this.minLastNameLength, + @required this.maxLastNameLength, + }) : assert(minFirstNameLength != null), + assert(maxFirstNameLength != null), + assert(minLastNameLength != null), + assert(maxLastNameLength != null); +} + class ServerConfig { final Version minSupportedMobileVersion; final String termsURL; @@ -121,6 +138,7 @@ class ServerConfig { final PasswordPolicy passwordPolicy; final ServerDataConservationPolicy dataConservationPolicy; final ConversationsPolicy conversationsPolicy; + final AccountInformationPolicy accountInformationPolicy; const ServerConfig({ @required this.minSupportedMobileVersion, @@ -131,6 +149,7 @@ class ServerConfig { @required this.passwordPolicy, @required this.dataConservationPolicy, @required this.conversationsPolicy, + @required this.accountInformationPolicy, }) : assert(minSupportedMobileVersion != null), assert(termsURL != null), assert(playStoreURL != null), @@ -138,5 +157,6 @@ class ServerConfig { assert(notificationsPolicy != null), assert(passwordPolicy != null), assert(dataConservationPolicy != null), - assert(conversationsPolicy != null); + assert(conversationsPolicy != null), + assert(accountInformationPolicy != null); } diff --git a/lib/ui/routes/create_account_route.dart b/lib/ui/routes/create_account_route.dart index f69a17b..683b896 100644 --- a/lib/ui/routes/create_account_route.dart +++ b/lib/ui/routes/create_account_route.dart @@ -44,9 +44,13 @@ class __CreateAccountRouteBodyState extends State<_CreateAccountRouteBody> { bool _showErrors = false; - bool get _isFirstNameValid => _firstNameController.text.length > 3; + bool get _isFirstNameValid => + _firstNameController.text.length >= + srvConfig.accountInformationPolicy.minFirstNameLength; - bool get _isLastNameValid => _lastNameController.text.length > 3; + bool get _isLastNameValid => + _lastNameController.text.length >= + srvConfig.accountInformationPolicy.minLastNameLength; bool get _isEmailValid => validateEmail(_emailController.text); @@ -97,6 +101,8 @@ class __CreateAccountRouteBodyState extends State<_CreateAccountRouteBody> { label: tr("First name"), onEdited: _updateUI, icon: Icon(Icons.perm_identity), + maxLength: + srvConfig.accountInformationPolicy.maxFirstNameLength, error: _showErrors && !_isFirstNameValid ? tr("Invalid first name!") : null, @@ -108,6 +114,7 @@ class __CreateAccountRouteBodyState extends State<_CreateAccountRouteBody> { label: tr("Last name"), onEdited: _updateUI, icon: Icon(Icons.perm_identity), + maxLength: srvConfig.accountInformationPolicy.maxLastNameLength, error: _showErrors && !_isLastNameValid ? tr("Invalid last name!") : null, @@ -268,6 +275,7 @@ class _InputEntry extends StatelessWidget { final String error; final Widget icon; final TextInputType keyboard; + final int maxLength; const _InputEntry({ Key key, @@ -278,6 +286,7 @@ class _InputEntry extends StatelessWidget { this.error, this.icon, this.keyboard, + this.maxLength, }) : assert(controller != null), assert(label != null), assert(onEdited != null), @@ -291,6 +300,7 @@ class _InputEntry extends StatelessWidget { onChanged: (s) => onEdited(), keyboardType: keyboard, obscureText: isPassword, + maxLength: maxLength, decoration: InputDecoration( alignLabelWithHint: true, errorText: error, diff --git a/lib/ui/routes/settings/general_account_settings.dart b/lib/ui/routes/settings/general_account_settings.dart index 6f23fd3..f86a507 100644 --- a/lib/ui/routes/settings/general_account_settings.dart +++ b/lib/ui/routes/settings/general_account_settings.dart @@ -1,5 +1,6 @@ import 'package:comunic/enums/user_page_visibility.dart'; import 'package:comunic/helpers/serialization/user_list_serialization_helper.dart'; +import 'package:comunic/helpers/server_config_helper.dart'; import 'package:comunic/helpers/settings_helper.dart'; import 'package:comunic/models/general_settings.dart'; import 'package:comunic/ui/dialogs/multi_choices_dialog.dart'; @@ -86,7 +87,9 @@ class _GeneralAccountSettingsScreenState _settings.firstName = s; _updateSettings(); }, - checkInput: (s) => s.length >= 3, + maxLength: srvConfig.accountInformationPolicy.maxFirstNameLength, + checkInput: (s) => + s.length >= srvConfig.accountInformationPolicy.minFirstNameLength, ), // Last name @@ -97,7 +100,9 @@ class _GeneralAccountSettingsScreenState _settings.lastName = s; _updateSettings(); }, - checkInput: (s) => s.length >= 3, + maxLength: srvConfig.accountInformationPolicy.maxLastNameLength, + checkInput: (s) => + s.length >= srvConfig.accountInformationPolicy.minLastNameLength, ), // Emails settings