Fix username validation and exception handling #89
|
@ -320,12 +320,13 @@
|
||||||
"delete_ssh_key": "Delete SSH key for {}"
|
"delete_ssh_key": "Delete SSH key for {}"
|
||||||
},
|
},
|
||||||
"validations": {
|
"validations": {
|
||||||
"required": "Required",
|
"required": "Required.",
|
||||||
"invalid_format": "Invalid format",
|
"invalid_format": "Invalid format.",
|
||||||
"root_name": "User name cannot be 'root'",
|
"root_name": "User name cannot be 'root'.",
|
||||||
"key_format": "Invalid key format",
|
"key_format": "Invalid key format.",
|
||||||
"length": "Length is [] should be {}",
|
"length_not_equal": "Length is []. Should be {}.",
|
||||||
"user_already_exist": "Already exists",
|
"length_longer": "Length is []. Should be shorter than or equal to {}.",
|
||||||
"key_already_exists": "This key already exists"
|
"user_already_exist": "This user already exists.",
|
||||||
|
"key_already_exists": "This key already exists."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,9 +323,10 @@
|
||||||
"validations": {
|
"validations": {
|
||||||
"required": "Обязательное поле.",
|
"required": "Обязательное поле.",
|
||||||
"invalid_format": "Неверный формат.",
|
"invalid_format": "Неверный формат.",
|
||||||
"root_name": "Имя пользователя не может быть'root'.",
|
"root_name": "Имя пользователя не может быть 'root'.",
|
||||||
"key_format": "Неверный формат.",
|
"key_format": "Неверный формат.",
|
||||||
"length": "Длина строки [] должна быть {}.",
|
"length_not_equal": "Длина строки []. Должно быть равно {}.",
|
||||||
|
"length_longer": "Длина строки []. Должно быть меньше либо равно {}.",
|
||||||
"user_already_exist": "Имя уже используется.",
|
"user_already_exist": "Имя уже используется.",
|
||||||
"key_already_exists": "Этот ключ уже добавлен."
|
"key_already_exists": "Этот ключ уже добавлен."
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ class ApiResponse<D> {
|
||||||
final String? errorMessage;
|
final String? errorMessage;
|
||||||
final D data;
|
final D data;
|
||||||
|
|
||||||
get isSuccess => statusCode >= 200 && statusCode < 300;
|
bool get isSuccess => statusCode >= 200 && statusCode < 300;
|
||||||
|
|
||||||
ApiResponse({
|
ApiResponse({
|
||||||
required this.statusCode,
|
required this.statusCode,
|
||||||
|
@ -65,27 +65,47 @@ class ServerApi extends ApiMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ApiResponse<User>> createUser(User user) async {
|
Future<ApiResponse<User>> createUser(User user) async {
|
||||||
Response response;
|
|
||||||
|
|
||||||
var client = await getClient();
|
var client = await getClient();
|
||||||
// POST request with JSON body containing username and password
|
|
||||||
|
|
||||||
response = await client.post(
|
var makeErrorApiReponse = (int status) {
|
||||||
'/users',
|
|
||||||
data: {
|
|
||||||
'username': user.login,
|
|
||||||
'password': user.password,
|
|
||||||
},
|
|
||||||
options: Options(
|
|
||||||
contentType: 'application/json',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
close(client);
|
|
||||||
|
|
||||||
if (response.statusCode == HttpStatus.created) {
|
|
||||||
return ApiResponse(
|
return ApiResponse(
|
||||||
statusCode: response.statusCode ?? HttpStatus.internalServerError,
|
statusCode: status,
|
||||||
|
data: User(
|
||||||
|
login: user.login,
|
||||||
|
password: user.password,
|
||||||
|
isFoundOnServer: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
late Response<dynamic> response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = await client.post(
|
||||||
|
'/users',
|
||||||
|
data: {
|
||||||
|
'username': user.login,
|
||||||
|
'password': user.password,
|
||||||
|
},
|
||||||
|
options: Options(
|
||||||
|
contentType: 'application/json',
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return (status != null) &&
|
||||||
|
(status < HttpStatus.internalServerError);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return makeErrorApiReponse(HttpStatus.internalServerError);
|
||||||
|
} finally {
|
||||||
|
close(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((response.statusCode != null) &&
|
||||||
|
(response.statusCode == HttpStatus.created)) {
|
||||||
|
return ApiResponse(
|
||||||
|
statusCode: response.statusCode!,
|
||||||
data: User(
|
data: User(
|
||||||
login: user.login,
|
login: user.login,
|
||||||
password: user.password,
|
password: user.password,
|
||||||
|
@ -93,18 +113,11 @@ class ServerApi extends ApiMap {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return ApiResponse(
|
print(response.statusCode.toString() +
|
||||||
statusCode: response.statusCode ?? HttpStatus.internalServerError,
|
": " +
|
||||||
data: User(
|
(response.statusMessage ?? ""));
|
||||||
login: user.login,
|
return makeErrorApiReponse(
|
||||||
password: user.password,
|
response.statusCode ?? HttpStatus.internalServerError);
|
||||||
isFoundOnServer: false,
|
|
||||||
note: response.data['message'] ?? null,
|
|
||||||
),
|
|
||||||
errorMessage: response.data?.containsKey('error') ?? false
|
|
||||||
? response.data['error']
|
|
||||||
: null,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
|
||||||
|
|
||||||
|
class FieldCubitFactory {
|
||||||
|
FieldCubitFactory(this.context);
|
||||||
|
|
||||||
|
/// A common user login field.
|
||||||
|
///
|
||||||
|
/// - Available characters are lowercase a-z, digits and underscore _
|
||||||
|
/// - Must start with either a-z or underscore
|
||||||
|
/// - Must be no longer than 'userMaxLength' characters
|
||||||
|
/// - Must not be empty
|
||||||
|
/// - Must not be a reserved root login
|
||||||
|
/// - Must be unique
|
||||||
|
FieldCubit<String> createUserLoginField() {
|
||||||
|
final userAllowedRegExp = RegExp(r"^[a-z_][a-z0-9_]+$");
|
||||||
|
const userMaxLength = 31;
|
||||||
|
return FieldCubit(
|
||||||
|
initalValue: '',
|
||||||
|
validations: [
|
||||||
|
ValidationModel<String>(
|
||||||
|
(s) => s.toLowerCase() == 'root', 'validations.root_name'.tr()),
|
||||||
|
ValidationModel(
|
||||||
|
(login) => context.read<UsersCubit>().state.isLoginRegistered(login),
|
||||||
|
'validations.user_already_exist'.tr(),
|
||||||
|
),
|
||||||
|
RequiredStringValidation('validations.required'.tr()),
|
||||||
|
LengthStringLongerValidation(userMaxLength),
|
||||||
|
ValidationModel<String>((s) => !userAllowedRegExp.hasMatch(s),
|
||||||
|
'validations.invalid_format'.tr()),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A common user password field.
|
||||||
|
///
|
||||||
|
/// - Must fail on the regural expression of invalid matches: [\n\r\s]+
|
||||||
|
/// - Must not be empty
|
||||||
|
FieldCubit<String> createUserPasswordField() {
|
||||||
|
var passwordForbiddenRegExp = RegExp(r"[\n\r\s]+");
|
||||||
|
return FieldCubit(
|
||||||
|
initalValue: '',
|
||||||
|
validations: [
|
||||||
|
RequiredStringValidation('validations.required'.tr()),
|
||||||
|
ValidationModel<String>(
|
||||||
|
(password) => passwordForbiddenRegExp.hasMatch(password),
|
||||||
|
'validations.invalid_format'.tr()),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final BuildContext context;
|
||||||
|
}
|
|
@ -12,9 +12,6 @@ class BackblazeFormCubit extends FormCubit {
|
||||||
initalValue: '',
|
initalValue: '',
|
||||||
validations: [
|
validations: [
|
||||||
RequiredStringValidation('validations.required'.tr()),
|
RequiredStringValidation('validations.required'.tr()),
|
||||||
//ValidationModel<String>(
|
|
||||||
//(s) => regExp.hasMatch(s), 'invalid key format'),
|
|
||||||
//LegnthStringValidationWithLenghShowing(64, 'length is [] shoud be 64')
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -22,9 +19,6 @@ class BackblazeFormCubit extends FormCubit {
|
||||||
initalValue: '',
|
initalValue: '',
|
||||||
validations: [
|
validations: [
|
||||||
RequiredStringValidation('required'),
|
RequiredStringValidation('required'),
|
||||||
//ValidationModel<String>(
|
|
||||||
//(s) => regExp.hasMatch(s), 'invalid key format'),
|
|
||||||
//LegnthStringValidationWithLenghShowing(64, 'length is [] shoud be 64')
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,7 @@ import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/cloudflare.dart';
|
import 'package:selfprivacy/logic/api_maps/cloudflare.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart';
|
||||||
import '../validations/validations.dart';
|
|
||||||
|
|
||||||
class CloudFlareFormCubit extends FormCubit {
|
class CloudFlareFormCubit extends FormCubit {
|
||||||
CloudFlareFormCubit(this.initializingCubit) {
|
CloudFlareFormCubit(this.initializingCubit) {
|
||||||
|
@ -16,12 +15,7 @@ class CloudFlareFormCubit extends FormCubit {
|
||||||
RequiredStringValidation('validations.required'.tr()),
|
RequiredStringValidation('validations.required'.tr()),
|
||||||
ValidationModel<String>(
|
ValidationModel<String>(
|
||||||
(s) => regExp.hasMatch(s), 'validations.key_format'.tr()),
|
(s) => regExp.hasMatch(s), 'validations.key_format'.tr()),
|
||||||
LengthStringValidationWithLengthShowing(
|
LengthStringNotEqualValidation(40)
|
||||||
40,
|
|
||||||
'validations.length'.tr(
|
|
||||||
args: ["40"],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,7 @@ import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/hetzner.dart';
|
import 'package:selfprivacy/logic/api_maps/hetzner.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart';
|
||||||
import '../validations/validations.dart';
|
|
||||||
|
|
||||||
class HetznerFormCubit extends FormCubit {
|
class HetznerFormCubit extends FormCubit {
|
||||||
HetznerFormCubit(this.initializingCubit) {
|
HetznerFormCubit(this.initializingCubit) {
|
||||||
|
@ -16,8 +15,7 @@ class HetznerFormCubit extends FormCubit {
|
||||||
RequiredStringValidation('validations.required'.tr()),
|
RequiredStringValidation('validations.required'.tr()),
|
||||||
ValidationModel<String>(
|
ValidationModel<String>(
|
||||||
(s) => regExp.hasMatch(s), 'validations.key_format'.tr()),
|
(s) => regExp.hasMatch(s), 'validations.key_format'.tr()),
|
||||||
LengthStringValidationWithLengthShowing(
|
LengthStringNotEqualValidation(64)
|
||||||
64, 'validations.length'.tr(args: ["64"]))
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -2,33 +2,14 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
||||||
import 'package:selfprivacy/logic/models/user.dart';
|
import 'package:selfprivacy/logic/models/user.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
|
|
||||||
class RootUserFormCubit extends FormCubit {
|
class RootUserFormCubit extends FormCubit {
|
||||||
RootUserFormCubit(this.initializingCubit) {
|
RootUserFormCubit(
|
||||||
var userRegExp = RegExp(r"\W");
|
this.initializingCubit, final FieldCubitFactory fieldFactory) {
|
||||||
var passwordRegExp = RegExp(r"[\n\r\s]+");
|
userName = fieldFactory.createUserLoginField();
|
||||||
|
password = fieldFactory.createUserPasswordField();
|
||||||
userName = FieldCubit(
|
|
||||||
initalValue: '',
|
|
||||||
validations: [
|
|
||||||
ValidationModel<String>(
|
|
||||||
(s) => s.toLowerCase() == 'root', 'validations.root_name'.tr()),
|
|
||||||
RequiredStringValidation('validations.required'.tr()),
|
|
||||||
ValidationModel<String>(
|
|
||||||
(s) => userRegExp.hasMatch(s), 'validations.invalid_format'.tr()),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
password = FieldCubit(
|
|
||||||
initalValue: '',
|
|
||||||
validations: [
|
|
||||||
RequiredStringValidation('validations.required'.tr()),
|
|
||||||
ValidationModel<String>((s) => passwordRegExp.hasMatch(s),
|
|
||||||
'validations.invalid_format'.tr()),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
isVisible = FieldCubit(initalValue: false);
|
isVisible = FieldCubit(initalValue: false);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/job.dart';
|
import 'package:selfprivacy/logic/models/job.dart';
|
||||||
import 'package:selfprivacy/logic/models/user.dart';
|
import 'package:selfprivacy/logic/models/user.dart';
|
||||||
|
@ -10,38 +10,16 @@ import 'package:selfprivacy/utils/password_generator.dart';
|
||||||
class UserFormCubit extends FormCubit {
|
class UserFormCubit extends FormCubit {
|
||||||
UserFormCubit({
|
UserFormCubit({
|
||||||
required this.jobsCubit,
|
required this.jobsCubit,
|
||||||
required List<User> users,
|
required FieldCubitFactory fieldFactory,
|
||||||
User? user,
|
User? user,
|
||||||
}) {
|
}) {
|
||||||
var isEdit = user != null;
|
var isEdit = user != null;
|
||||||
|
|
||||||
var userRegExp = RegExp(r"\W");
|
login = fieldFactory.createUserLoginField();
|
||||||
var passwordRegExp = RegExp(r"[\n\r\s]+");
|
login.setValue(isEdit ? user!.login : '');
|
||||||
|
password = fieldFactory.createUserPasswordField();
|
||||||
login = FieldCubit(
|
password.setValue(
|
||||||
initalValue: isEdit ? user!.login : '',
|
isEdit ? (user?.password ?? '') : StringGenerators.userPassword());
|
||||||
validations: [
|
|
||||||
ValidationModel<String>(
|
|
||||||
(s) => s.toLowerCase() == 'root', 'validations.root_name'.tr()),
|
|
||||||
ValidationModel(
|
|
||||||
(login) => users.any((user) => user.login == login),
|
|
||||||
'validations.user_already_exist'.tr(),
|
|
||||||
),
|
|
||||||
RequiredStringValidation('validations.required'.tr()),
|
|
||||||
ValidationModel<String>(
|
|
||||||
(s) => userRegExp.hasMatch(s), 'validations.invalid_format'.tr()),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
password = FieldCubit(
|
|
||||||
initalValue:
|
|
||||||
isEdit ? (user?.password ?? '') : StringGenerators.userPassword(),
|
|
||||||
validations: [
|
|
||||||
RequiredStringValidation('validations.required'.tr()),
|
|
||||||
ValidationModel<String>((s) => passwordRegExp.hasMatch(s),
|
|
||||||
'validations.invalid_format'.tr()),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
super.addFields([login, password]);
|
super.addFields([login, password]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,28 @@
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
class LengthStringValidationWithLengthShowing extends ValidationModel<String> {
|
abstract class LengthStringValidation extends ValidationModel<String> {
|
||||||
LengthStringValidationWithLengthShowing(int length, String errorText)
|
LengthStringValidation(bool Function(String) predicate, String errorMessage)
|
||||||
: super((n) => n.length != length, errorText);
|
: super(predicate, errorMessage);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String? check(String val) {
|
String? check(String value) {
|
||||||
var length = val.length;
|
var length = value.length;
|
||||||
var errorMassage = this.errorMassage.replaceAll("[]", length.toString());
|
var errorMessage = this.errorMassage.replaceAll("[]", length.toString());
|
||||||
return test(val) ? errorMassage : null;
|
return test(value) ? errorMessage : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LengthStringNotEqualValidation extends LengthStringValidation {
|
||||||
NaiJi marked this conversation as resolved
|
|||||||
|
/// String must be equal to [length]
|
||||||
|
LengthStringNotEqualValidation(int length)
|
||||||
|
: super((n) => n.length != length,
|
||||||
|
'validations.length_not_equal'.tr(args: [length.toString()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
class LengthStringLongerValidation extends LengthStringValidation {
|
||||||
|
/// String must be shorter than or equal to [length]
|
||||||
|
LengthStringLongerValidation(int length)
|
||||||
|
: super((n) => n.length > length,
|
||||||
|
'validations.length_longer'.tr(args: [length.toString()]));
|
||||||
|
}
|
||||||
|
|
|
@ -160,7 +160,12 @@ class UsersCubit extends AppConfigDependendCubit<UsersState> {
|
||||||
if (user.login == 'root' || user.login == state.primaryUser.login) {
|
if (user.login == 'root' || user.login == state.primaryUser.login) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// If API returned error, do nothing
|
||||||
final result = await api.createUser(user);
|
final result = await api.createUser(user);
|
||||||
|
if (!result.isSuccess) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var loadedUsers = List<User>.from(state.users);
|
var loadedUsers = List<User>.from(state.users);
|
||||||
loadedUsers.add(result.data);
|
loadedUsers.add(result.data);
|
||||||
await box.clear();
|
await box.clear();
|
||||||
|
|
|
@ -22,5 +22,11 @@ class UsersState extends AppConfigDependendState {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isLoginRegistered(String login) {
|
||||||
|
return users.any((user) => user.login == login) ||
|
||||||
|
login == rootUser.login ||
|
||||||
|
login == primaryUser.login;
|
||||||
|
}
|
||||||
|
|
||||||
bool get isEmpty => users.isEmpty;
|
bool get isEmpty => users.isEmpty;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ void main() async {
|
||||||
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/* Wakelock support for Linux
|
/// Wakelock support for Linux
|
||||||
* desktop is not yet implemented */
|
/// desktop is not yet implemented
|
||||||
await Wakelock.enable();
|
await Wakelock.enable();
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:selfprivacy/config/brand_theme.dart';
|
import 'package:selfprivacy/config/brand_theme.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/initializing/backblaze_form_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/forms/initializing/backblaze_form_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/initializing/cloudflare_form_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/forms/initializing/cloudflare_form_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/initializing/domain_cloudflare.dart';
|
import 'package:selfprivacy/logic/cubit/forms/initializing/domain_cloudflare.dart';
|
||||||
|
@ -352,7 +353,8 @@ class InitializingPage extends StatelessWidget {
|
||||||
|
|
||||||
Widget _stepUser(AppConfigCubit initializingCubit) {
|
Widget _stepUser(AppConfigCubit initializingCubit) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => RootUserFormCubit(initializingCubit),
|
create: (context) =>
|
||||||
|
RootUserFormCubit(initializingCubit, FieldCubitFactory(context)),
|
||||||
child: Builder(builder: (context) {
|
child: Builder(builder: (context) {
|
||||||
var formCubitState = context.watch<RootUserFormCubit>().state;
|
var formCubitState = context.watch<RootUserFormCubit>().state;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ class _NewUser extends StatelessWidget {
|
||||||
}
|
}
|
||||||
return UserFormCubit(
|
return UserFormCubit(
|
||||||
jobsCubit: jobCubit,
|
jobsCubit: jobCubit,
|
||||||
users: users,
|
fieldFactory: FieldCubitFactory(context),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Builder(builder: (context) {
|
child: Builder(builder: (context) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:selfprivacy/config/brand_colors.dart';
|
||||||
import 'package:selfprivacy/config/brand_theme.dart';
|
import 'package:selfprivacy/config/brand_theme.dart';
|
||||||
import 'package:selfprivacy/config/text_themes.dart';
|
import 'package:selfprivacy/config/text_themes.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/user/user_form_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/forms/user/user_form_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
|
||||||
|
|
Loading…
Reference in New Issue
This is a documentation comment. Consider making it docstring (three slashes) or removing it entirely, if the class name is enough.
IDE will use docstrings in intellisense. It won't use usual comments.