Implement user password reset
parent
a0b365f496
commit
900e07f364
|
@ -483,7 +483,8 @@
|
||||||
"rebootServer": "Перезагрузить сервер",
|
"rebootServer": "Перезагрузить сервер",
|
||||||
"create_ssh_key": "Создать SSH ключ для {}",
|
"create_ssh_key": "Создать SSH ключ для {}",
|
||||||
"delete_ssh_key": "Удалить SSH ключ для {}",
|
"delete_ssh_key": "Удалить SSH ключ для {}",
|
||||||
"server_jobs": "Задачи на сервере"
|
"server_jobs": "Задачи на сервере",
|
||||||
|
"resetUserPassword": "Сбросить пароль пользователя"
|
||||||
},
|
},
|
||||||
"validations": {
|
"validations": {
|
||||||
"required": "Обязательное поле.",
|
"required": "Обязательное поле.",
|
||||||
|
|
|
@ -121,6 +121,9 @@ class JobsCubit extends Cubit<JobsState> {
|
||||||
if (job is DeleteSSHKeyJob) {
|
if (job is DeleteSSHKeyJob) {
|
||||||
await usersCubit.deleteSshKey(job.user, job.publicKey);
|
await usersCubit.deleteSshKey(job.user, job.publicKey);
|
||||||
}
|
}
|
||||||
|
if (job is ResetUserPasswordJob) {
|
||||||
|
await usersCubit.changeUserPassword(job.user, job.user.password!);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await api.pullConfigurationUpdate();
|
await api.pullConfigurationUpdate();
|
||||||
|
|
|
@ -11,28 +11,50 @@ class UserFormCubit extends FormCubit {
|
||||||
UserFormCubit({
|
UserFormCubit({
|
||||||
required this.jobsCubit,
|
required this.jobsCubit,
|
||||||
required final FieldCubitFactory fieldFactory,
|
required final FieldCubitFactory fieldFactory,
|
||||||
final User? user,
|
final this.initialUser,
|
||||||
}) {
|
}) {
|
||||||
final bool isEdit = user != null;
|
if (initialUser == null) {
|
||||||
|
login = fieldFactory.createUserLoginField();
|
||||||
|
login.setValue('');
|
||||||
|
password = fieldFactory.createUserPasswordField();
|
||||||
|
password.setValue(
|
||||||
|
StringGenerators.userPassword(),
|
||||||
|
);
|
||||||
|
|
||||||
login = fieldFactory.createUserLoginField();
|
super.addFields([login, password]);
|
||||||
login.setValue(isEdit ? user.login : '');
|
} else {
|
||||||
password = fieldFactory.createUserPasswordField();
|
login = fieldFactory.createRequiredStringField();
|
||||||
password.setValue(
|
login.setValue(initialUser!.login);
|
||||||
isEdit ? (user.password ?? '') : StringGenerators.userPassword(),
|
password = fieldFactory.createUserPasswordField();
|
||||||
);
|
password.setValue(
|
||||||
|
initialUser?.password ?? '',
|
||||||
|
);
|
||||||
|
|
||||||
super.addFields([login, password]);
|
super.addFields([login, password]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<void> onSubmit() {
|
FutureOr<void> onSubmit() {
|
||||||
final User user = User(
|
print('onSubmit');
|
||||||
login: login.state.value,
|
print('initialUser: $initialUser');
|
||||||
type: UserType.normal,
|
print('login: ${login.state.value}');
|
||||||
password: password.state.value,
|
print('password: ${password.state.value}');
|
||||||
);
|
if (initialUser == null) {
|
||||||
jobsCubit.addJob(CreateUserJob(user: user));
|
final User user = User(
|
||||||
|
login: login.state.value,
|
||||||
|
type: UserType.normal,
|
||||||
|
password: password.state.value,
|
||||||
|
);
|
||||||
|
jobsCubit.addJob(CreateUserJob(user: user));
|
||||||
|
} else {
|
||||||
|
final User user = User(
|
||||||
|
login: initialUser?.login ?? login.state.value,
|
||||||
|
type: initialUser?.type ?? UserType.normal,
|
||||||
|
password: password.state.value,
|
||||||
|
);
|
||||||
|
jobsCubit.addJob(ResetUserPasswordJob(user: user));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
late FieldCubit<String> login;
|
late FieldCubit<String> login;
|
||||||
|
@ -43,4 +65,5 @@ class UserFormCubit extends FormCubit {
|
||||||
}
|
}
|
||||||
|
|
||||||
final JobsCubit jobsCubit;
|
final JobsCubit jobsCubit;
|
||||||
|
final User? initialUser;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,17 @@ class CreateUserJob extends ClientJob {
|
||||||
List<Object> get props => [id, title, user];
|
List<Object> get props => [id, title, user];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ResetUserPasswordJob extends ClientJob {
|
||||||
|
ResetUserPasswordJob({
|
||||||
|
required this.user,
|
||||||
|
}) : super(title: '${"jobs.resetUserPassword".tr()} ${user.login}');
|
||||||
|
|
||||||
|
final User user;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [id, title, user];
|
||||||
|
}
|
||||||
|
|
||||||
class DeleteUserJob extends ClientJob {
|
class DeleteUserJob extends ClientJob {
|
||||||
DeleteUserJob({
|
DeleteUserJob({
|
||||||
required this.user,
|
required this.user,
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
part of 'users.dart';
|
||||||
|
|
||||||
|
class ResetPassword extends StatelessWidget {
|
||||||
|
const ResetPassword({
|
||||||
|
required this.user,
|
||||||
|
final super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final User user;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => BrandBottomSheet(
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (final BuildContext context) => UserFormCubit(
|
||||||
|
jobsCubit: context.read<JobsCubit>(),
|
||||||
|
fieldFactory: FieldCubitFactory(context),
|
||||||
|
initialUser: user,
|
||||||
|
),
|
||||||
|
child: Builder(
|
||||||
|
builder: (final BuildContext context) {
|
||||||
|
final FormCubitState formCubitState =
|
||||||
|
context.watch<UserFormCubit>().state;
|
||||||
|
|
||||||
|
return BlocListener<UserFormCubit, FormCubitState>(
|
||||||
|
listener:
|
||||||
|
(final BuildContext context, final FormCubitState state) {
|
||||||
|
if (state.isSubmitted) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
BrandHeader(
|
||||||
|
title: 'users.reset_password'.tr(),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 14),
|
||||||
|
Padding(
|
||||||
|
padding: paddingH15V0,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
CubitFormTextField(
|
||||||
|
formFieldCubit:
|
||||||
|
context.read<UserFormCubit>().password,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
alignLabelWithHint: false,
|
||||||
|
labelText: 'basis.password'.tr(),
|
||||||
|
suffixIcon: Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8),
|
||||||
|
child: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
BrandIcons.refresh,
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
onPressed: context
|
||||||
|
.read<UserFormCubit>()
|
||||||
|
.genNewPassword,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
BrandButton.rised(
|
||||||
|
onPressed: formCubitState.isSubmitting
|
||||||
|
? null
|
||||||
|
: () =>
|
||||||
|
context.read<UserFormCubit>().trySubmit(),
|
||||||
|
text: 'basis.apply'.tr(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
|
@ -43,7 +43,17 @@ class UserDetails extends StatelessWidget {
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
ListTile(
|
ListTile(
|
||||||
iconColor: Theme.of(context).colorScheme.onBackground,
|
iconColor: Theme.of(context).colorScheme.onBackground,
|
||||||
onTap: () => {},
|
onTap: () => {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
builder: (final BuildContext context) => Padding(
|
||||||
|
padding: MediaQuery.of(context).viewInsets,
|
||||||
|
child: ResetPassword(user: user),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
leading: const Icon(Icons.lock_reset_outlined),
|
leading: const Icon(Icons.lock_reset_outlined),
|
||||||
title: Text(
|
title: Text(
|
||||||
'users.reset_password'.tr(),
|
'users.reset_password'.tr(),
|
||||||
|
|
|
@ -31,6 +31,7 @@ part 'new_user.dart';
|
||||||
part 'user.dart';
|
part 'user.dart';
|
||||||
part 'user_details.dart';
|
part 'user_details.dart';
|
||||||
part 'add_user_fab.dart';
|
part 'add_user_fab.dart';
|
||||||
|
part 'reset_password.dart';
|
||||||
|
|
||||||
class UsersPage extends StatelessWidget {
|
class UsersPage extends StatelessWidget {
|
||||||
const UsersPage({final super.key});
|
const UsersPage({final super.key});
|
||||||
|
|
Loading…
Reference in New Issue