forked from SelfPrivacy/selfprivacy.org.app
Implement user password reset
parent
a0b365f496
commit
900e07f364
|
@ -483,7 +483,8 @@
|
|||
"rebootServer": "Перезагрузить сервер",
|
||||
"create_ssh_key": "Создать SSH ключ для {}",
|
||||
"delete_ssh_key": "Удалить SSH ключ для {}",
|
||||
"server_jobs": "Задачи на сервере"
|
||||
"server_jobs": "Задачи на сервере",
|
||||
"resetUserPassword": "Сбросить пароль пользователя"
|
||||
},
|
||||
"validations": {
|
||||
"required": "Обязательное поле.",
|
||||
|
|
|
@ -121,6 +121,9 @@ class JobsCubit extends Cubit<JobsState> {
|
|||
if (job is DeleteSSHKeyJob) {
|
||||
await usersCubit.deleteSshKey(job.user, job.publicKey);
|
||||
}
|
||||
if (job is ResetUserPasswordJob) {
|
||||
await usersCubit.changeUserPassword(job.user, job.user.password!);
|
||||
}
|
||||
}
|
||||
|
||||
await api.pullConfigurationUpdate();
|
||||
|
|
|
@ -11,28 +11,50 @@ class UserFormCubit extends FormCubit {
|
|||
UserFormCubit({
|
||||
required this.jobsCubit,
|
||||
required final FieldCubitFactory fieldFactory,
|
||||
final User? user,
|
||||
final this.initialUser,
|
||||
}) {
|
||||
final bool isEdit = user != null;
|
||||
|
||||
if (initialUser == null) {
|
||||
login = fieldFactory.createUserLoginField();
|
||||
login.setValue(isEdit ? user.login : '');
|
||||
login.setValue('');
|
||||
password = fieldFactory.createUserPasswordField();
|
||||
password.setValue(
|
||||
isEdit ? (user.password ?? '') : StringGenerators.userPassword(),
|
||||
StringGenerators.userPassword(),
|
||||
);
|
||||
|
||||
super.addFields([login, password]);
|
||||
} else {
|
||||
login = fieldFactory.createRequiredStringField();
|
||||
login.setValue(initialUser!.login);
|
||||
password = fieldFactory.createUserPasswordField();
|
||||
password.setValue(
|
||||
initialUser?.password ?? '',
|
||||
);
|
||||
|
||||
super.addFields([login, password]);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<void> onSubmit() {
|
||||
print('onSubmit');
|
||||
print('initialUser: $initialUser');
|
||||
print('login: ${login.state.value}');
|
||||
print('password: ${password.state.value}');
|
||||
if (initialUser == null) {
|
||||
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;
|
||||
|
@ -43,4 +65,5 @@ class UserFormCubit extends FormCubit {
|
|||
}
|
||||
|
||||
final JobsCubit jobsCubit;
|
||||
final User? initialUser;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,17 @@ class CreateUserJob extends ClientJob {
|
|||
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 {
|
||||
DeleteUserJob({
|
||||
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),
|
||||
ListTile(
|
||||
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),
|
||||
title: Text(
|
||||
'users.reset_password'.tr(),
|
||||
|
|
|
@ -31,6 +31,7 @@ part 'new_user.dart';
|
|||
part 'user.dart';
|
||||
part 'user_details.dart';
|
||||
part 'add_user_fab.dart';
|
||||
part 'reset_password.dart';
|
||||
|
||||
class UsersPage extends StatelessWidget {
|
||||
const UsersPage({final super.key});
|
||||
|
|
Loading…
Reference in New Issue