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.
|
||||||
NaiJi marked this conversation as resolved
Outdated
|
|||||||
|
///
|
||||||
|
/// - 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.
|
||||||
NaiJi marked this conversation as resolved
Outdated
inex
commented
Outdated
Review
Same, wrong docstring formatting Same, wrong docstring formatting
|
|||||||
|
///
|
||||||
|
/// - 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
inex
commented
Review
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. 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.
|
|||||||
|
/// 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
Incorrect docstring formatting. Never use this style of comments.
https://dart.dev/guides/language/effective-dart/documentation#dont-use-block-comments-for-documentation
This also could have been a doctring.