From 9f38429c2a932acf407f6be8b2990a67f65eeb56 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Thu, 10 Jul 2025 11:32:53 -0500 Subject: [PATCH] feat: adds command to rest user password --- .../Command/UserResetPasswordCommand.php | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/Base/Framework/Command/UserResetPasswordCommand.php diff --git a/src/Base/Framework/Command/UserResetPasswordCommand.php b/src/Base/Framework/Command/UserResetPasswordCommand.php new file mode 100644 index 0000000..3e973eb --- /dev/null +++ b/src/Base/Framework/Command/UserResetPasswordCommand.php @@ -0,0 +1,112 @@ +security = $security; + $this->userRepository = $userRepository; + $this->hasher = $hasher; + } + + protected function configure(): void + { + $this + ->addOption('id', null, InputOption::VALUE_REQUIRED, 'The ID of the user in the database.') + ->addOption('email', null, InputOption::VALUE_REQUIRED, 'The email of the user.') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + + $queryParams = $this->parseInput($input, $io); + if ([] === $queryParams) { + $io->error('No ID or Email specified. Please run again and pass the "--id" or "--email" option.'); + return Command::FAILURE; + } + + $user = $this->userRepository->findOneBy($queryParams); + if (null === $user) { + $io->error('No such user exists.'); + return Command::FAILURE; + } + + try { + $newPassword = $this->askForPassword($input, $output); + $this->updateUsersPassword($user, $newPassword); + } catch (\Throwable $exception) { + $io->error($exception->getMessage()); + return Command::FAILURE; + } + + $io->success('Success. The password has been reset.'); + + return Command::SUCCESS; + } + + private function parseInput(InputInterface $input, SymfonyStyle $io): array + { + if ($input->getOption('id')) { + return ['id' => $input->getOption('id')]; + } elseif ($input->getOption('email')) { + return ['email' => $input->getOption('email')]; + } + + return []; + } + + private function askForPassword(InputInterface $input, OutputInterface $output): ?string + { + $questionHelper = new QuestionHelper(); + $question = new Question('New password (input is hidden): ') + ->setHidden(true) + ->setHiddenFallback(false) + ->setNormalizer(function (?string $value): string { + return $value ?? ''; + }) + ->setValidator(function (string $value): string { + if ('' === trim($value)) { + throw new \Exception('The password cannot be empty'); + } + return $value; + }) + ->setMaxAttempts(5) + ; + + return $questionHelper->ask($input, $output, $question); + } + + private function updateUsersPassword(UserInterface $user, string $newPassword): void + { + $user->setPassword( + $this->hasher->hashPassword($user, $newPassword) + ); + $this->userRepository->getEntityManager()->flush(); + } +}