diff --git a/modules/system/ServiceProvider.php b/modules/system/ServiceProvider.php index fa729eb5a..892547bc1 100644 --- a/modules/system/ServiceProvider.php +++ b/modules/system/ServiceProvider.php @@ -247,6 +247,7 @@ class ServiceProvider extends ModuleServiceProvider $this->registerConsoleCommand('october.fresh', 'System\Console\OctoberFresh'); $this->registerConsoleCommand('october.env', 'System\Console\OctoberEnv'); $this->registerConsoleCommand('october.install', 'System\Console\OctoberInstall'); + $this->registerConsoleCommand('october.passwd', 'System\Console\OctoberPasswd'); $this->registerConsoleCommand('plugin.install', 'System\Console\PluginInstall'); $this->registerConsoleCommand('plugin.remove', 'System\Console\PluginRemove'); diff --git a/modules/system/console/OctoberPasswd.php b/modules/system/console/OctoberPasswd.php new file mode 100644 index 000000000..bd2a4031d --- /dev/null +++ b/modules/system/console/OctoberPasswd.php @@ -0,0 +1,112 @@ +argument('username') + ?? $this->ask( + 'Which user would you like to change the password for?' + ); + + // Check that the user exists + try { + $user = User::where('login', $username) + ->orWhere('email', $username) + ->firstOrFail(); + } catch (ModelNotFoundException $e) { + $this->error('The specified user does not exist.'); + exit(1); + } + + $password = $this->argument('password') + ?? ( + $this->optionalSecret( + 'Enter in a new password, or press ENTER to use a generated password', + false, + false + ) ?: $this->generatePassword() + ); + + // Change password + $user->password = $password; + $user->forceSave(); + + $this->info('Password successfully changed.'); + if (!$this->generatedPassword) { + $this->output->writeLn('The new password is ' . $password . '.'); + } + exit(0); + } + + /** + * Get the console command options. + */ + protected function getArguments() + { + return [ + ['username', InputArgument::OPTIONAL, 'The username of the Backend user'], + ['password', InputArgument::OPTIONAL, 'The new password'] + ]; + } + + /** + * Prompt the user for input but hide the answer from the console. + * + * Also allows for a default to be specified. + * + * @param string $question + * @param bool $fallback + * @return string + */ + protected function optionalSecret($question, $fallback = true, $default = null) + { + $question = new Question($question, $default); + + $question->setHidden(true)->setHiddenFallback($fallback); + + return $this->output->askQuestion($question); + } + + /** + * Generate a password and flag it as an automatically-generated password. + * + * @return string + */ + protected function generatePassword() + { + $this->generatedPassword = true; + + return Str::random(22); + } +}