From 6a1b135a335ed707e83828b630cdf400cfd46b8c Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Fri, 27 Jan 2023 19:53:16 +0000 Subject: [PATCH 1/8] Auth - Working on switching auth to actions --- app/Actions/Account/CreatePassword.php | 56 ++++++++++++++++++++++++++ app/Actions/Action.php | 15 +++++-- 2 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 app/Actions/Account/CreatePassword.php diff --git a/app/Actions/Account/CreatePassword.php b/app/Actions/Account/CreatePassword.php new file mode 100644 index 0000000..14deb85 --- /dev/null +++ b/app/Actions/Account/CreatePassword.php @@ -0,0 +1,56 @@ + + * @copyright Dean Blackborough (Costs to Expect) 2018-2023 + * https://github.com/costs-to-expect/budget/blob/main/LICENSE + */ +class CreatePassword extends Action +{ + public function __invoke( + Service $api, + array $input + ): int + { + $post_response = $api->createPassword($input); + + if ($post_response['status'] === 204) { + + Notification::route('mail', $input['email']) + ->notify(new Registered()); + + PartialRegistration::query() + ->where('token', '=', $input['token']) + ->delete(); + + return 204; + } + + if ($post_response['status'] === 422) { + $this->validation_errors = $post_response['fields']; + $this->parameters = [ + 'token' => $input['token'], + 'email' => $input['email'], + ]; + + return 422; + } + + $this->message = $post_response['content']; + $this->parameters = [ + 'token' => $input['token'], + 'email' => $input['email'], + ]; + + return $post_response['status']; + } +} \ No newline at end of file diff --git a/app/Actions/Action.php b/app/Actions/Action.php index 21c5bcd..efbdbd2 100644 --- a/app/Actions/Action.php +++ b/app/Actions/Action.php @@ -14,13 +14,20 @@ abstract class Action protected array $validation_errors = []; - public function getValidationErrors(): array - { - return $this->validation_errors; - } + protected array $parameters = []; public function getMessage(): string { return $this->message; } + + public function getParameters(): array + { + return $this->parameters; + } + + public function getValidationErrors(): array + { + return $this->validation_errors; + } } From fbf903b81b556e3ffbe172ea4a089bd7555c745c Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sat, 28 Jan 2023 15:14:42 +0000 Subject: [PATCH 2/8] Move auth to actions - Register and create password switched to actions and updated to understand the corrected validation format from the API - Removed controller actions which could just be routes in the view --- app/Actions/Account/Register.php | 51 +++++ app/Http/Controllers/Authentication.php | 181 ++++++------------ .../authentication/create-password.blade.php | 20 +- .../views/authentication/register.blade.php | 20 +- routes/web.php | 12 +- 5 files changed, 128 insertions(+), 156 deletions(-) create mode 100644 app/Actions/Account/Register.php diff --git a/app/Actions/Account/Register.php b/app/Actions/Account/Register.php new file mode 100644 index 0000000..c36b6c2 --- /dev/null +++ b/app/Actions/Account/Register.php @@ -0,0 +1,51 @@ + + * @copyright Dean Blackborough (Costs to Expect) 2018-2023 + * https://github.com/costs-to-expect/budget/blob/main/LICENSE + */ +class Register extends Action +{ + public function __invoke( + Service $api, + array $input + ): int + { + $post_response = $api->register($input); + + if ($post_response['status'] === 201) { + + $this->parameters = $post_response['content']['uris']['create-password']['parameters']; + + $model = new PartialRegistration(); + $model->token = $this->parameters['token']; + $model->email = $this->parameters['email']; + $model->save(); + + Notification::route('mail', $input['email']) + ->notify((new CreatePassword($input['email'], $this->parameters['token']))->delay(now()->addMinute())); + + return 201; + } + + if ($post_response['status'] === 422) { + $this->validation_errors = $post_response['fields']; + + return 422; + } + + $this->message = $post_response['content']; + + return $post_response['status']; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Authentication.php b/app/Http/Controllers/Authentication.php index 1acd7a1..0081a86 100644 --- a/app/Http/Controllers/Authentication.php +++ b/app/Http/Controllers/Authentication.php @@ -3,11 +3,9 @@ namespace App\Http\Controllers; +use App\Actions\Account\Register; use App\Api\Service; -use App\Models\PartialRegistration; -use App\Notifications\CreatePassword; use App\Notifications\ForgotPassword; -use App\Notifications\Registered; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -21,36 +19,6 @@ */ class Authentication extends Controller { - public function createPassword(Request $request) - { - $token = null; - $email = null; - - if (session()->get('authentication.parameters') !== null) { - $token = session()->get('authentication.parameters')['token']; - $email = session()->get('authentication.parameters')['email']; - } - - if ($request->input('token') !== null && $request->input('email') !== null) { - $token = $request->input('token'); - $email = $request->input('email'); - } - - if ($token === null && $email === null) { - abort(404, 'Password cannot be created, registration parameters not found'); - } - - return view( - 'authentication.create-password', - [ - 'token' => $token, - 'email' => $email, - 'errors' => session()->get('authentication.errors'), - 'failed' => session()->get('authentication.failed'), - ] - ); - } - public function createNewPassword(Request $request) { $token = null; @@ -113,104 +81,95 @@ public function createNewPasswordProcess(Request $request) ->with('authentication.failed', $response['content']); } - public function forgotPassword() + public function createPassword(Request $request) { + $token = null; + $email = null; + + if ($request->query('token') !== null && $request->query('email') !== null) { + $token = $request->query('token'); + $email = $request->query('email'); + } + + if ($token === null && $email === null) { + abort(404, 'Password cannot be created, registration parameters not found'); + } + return view( - 'authentication.forgot-password', + 'authentication.create-password', [ - 'errors' => session()->get('authentication.errors'), - 'failed' => session()->get('authentication.failed'), + 'token' => $token, + 'email' => $email, + 'errors' => session()->get('validation.errors'), + 'failed' => session()->get('request.failed'), ] ); } - public function forgotPasswordProcess(Request $request) + public function createPasswordProcess(Request $request): RedirectResponse { $api = new Service(); - $response = $api->forgotPassword( - $request->only(['email']) + $action = new \App\Actions\Account\CreatePassword(); + $result = $action( + $api, + $request->only(['token', 'email', 'password', 'password_confirmation']) ); - if ($response['status'] === 201) { - - $config = Config::get('app.config'); - $encryptor = new \Illuminate\Encryption\Encrypter($config['forgot-password-salt']); - $parameters = $response['content']['uris']['create-new-password']['parameters']; - $token = $encryptor->decryptString($parameters['encrypted_token']); - - Notification::route('mail', $request->input('email')) - ->notify(new ForgotPassword($request->input('email'), $token)); - - return redirect()->route('forgot-password-email-issued'); + if ($result === 204) { + return redirect()->route('registration-complete'); } - if ($response['status'] === 422) { - return redirect()->route('forgot-password.view') + if ($result === 422) { + return redirect()->route('create-password.view', $action->getParameters()) ->withInput() - ->with('authentication.errors', $response['fields']); + ->with('validation.errors', $action->getValidationErrors()); } - return redirect()->route('forgot-password.view') - ->withInput() - ->with('authentication.failed', $response['content']); - } - - public function forgotPasswordEmailIssued() - { - return view( - 'authentication.forgot-password-email-issued', - [ - ] - ); + return redirect()->route('create-password.view', $action->getParameters()) + ->with('request.failed', $action->getMessage()); } - public function newPasswordCreated() + public function forgotPassword() { return view( - 'authentication.new-password-created', + 'authentication.forgot-password', [ + 'errors' => session()->get('authentication.errors'), + 'failed' => session()->get('authentication.failed'), ] ); } - public function createPasswordProcess(Request $request) + public function forgotPasswordProcess(Request $request) { $api = new Service(); - $response = $api->createPassword( - $request->only(['token', 'email', 'password', 'password_confirmation']) + $response = $api->forgotPassword( + $request->only(['email']) ); - if ($response['status'] === 204) { + if ($response['status'] === 201) { - Notification::route('mail', $request->input('email')) - ->notify(new Registered()); + $config = Config::get('app.config'); + $encryptor = new \Illuminate\Encryption\Encrypter($config['forgot-password-salt']); + $parameters = $response['content']['uris']['create-new-password']['parameters']; + $token = $encryptor->decryptString($parameters['encrypted_token']); - PartialRegistration::query() - ->where('token', '=', $request->input('token')) - ->delete(); + Notification::route('mail', $request->input('email')) + ->notify(new ForgotPassword($request->input('email'), $token)); - return redirect()->route('registration-complete'); + return redirect()->route('forgot-password-email-issued'); } if ($response['status'] === 422) { - return redirect()->route( - 'create-password.view', - [ - 'token' => $request->input('token'), - 'email' => $request->input('email'), - ]) + return redirect()->route('forgot-password.view') ->withInput() ->with('authentication.errors', $response['fields']); } - return redirect()->route( - 'create-password.view', - [ - 'token' => $request->input('token'), - 'email' => $request->input('email'), - ]) + return redirect()->route('forgot-password.view') + ->withInput() ->with('authentication.failed', $response['content']); } @@ -219,52 +178,38 @@ public function register() return view( 'authentication.register', [ - 'errors' => session()->get('authentication.errors'), - 'failed' => session()->get('authentication.failed'), + 'errors' => session()->get('validation.errors'), + 'failed' => session()->get('request.failed'), ] ); } - public function registerProcess(Request $request) + public function registerProcess(Request $request): RedirectResponse { $api = new Service(); - $response = $api->register( + $action = new Register(); + $result = $action( + $api, $request->only(['name','email']) ); - if ($response['status'] === 201) { - $parameters = $response['content']['uris']['create-password']['parameters']; - - $model = new PartialRegistration(); - $model->token = $parameters['token']; - $model->email = $parameters['email']; - $model->save(); - - Notification::route('mail', $request->input('email')) - ->notify((new CreatePassword($parameters['email'], $parameters['token']))->delay(now()->addMinute())); + if ($result === 201) { - return redirect()->route('create-password.view') - ->with('authentication.parameters', $parameters); + return redirect()->route( + 'create-password.view', + $action->getParameters() + ); } - if ($response['status'] === 422) { + if ($result === 422) { return redirect()->route('register.view') ->withInput() - ->with('authentication.errors', $response['fields']); + ->with('validation.errors', $action->getValidationErrors()); } return redirect()->route('register.view') - ->with('authentication.failed', $response['content']); - } - - public function registrationComplete() - { - return view( - 'authentication.registration-complete', - [ - ] - ); + ->with('authentication.failed', $action->getMessage()); } public function signIn() diff --git a/resources/views/authentication/create-password.blade.php b/resources/views/authentication/create-password.blade.php index bb8ce5c..65b2b62 100644 --- a/resources/views/authentication/create-password.blade.php +++ b/resources/views/authentication/create-password.blade.php @@ -81,28 +81,16 @@
- +
Please enter a password, at least 12 characters please, your password will be hashed.
- @if($errors !== null && array_key_exists('password', $errors)) -
- @foreach ($errors['password'] as $error) - {{ $error }} - @endforeach -
- @endif +
- +
Please enter your password again
- @if($errors !== null && array_key_exists('password_confirmation', $errors)) -
- @foreach ($errors['password_confirmation'] as $error) - {{ $error }} - @endforeach -
- @endif +
diff --git a/resources/views/authentication/register.blade.php b/resources/views/authentication/register.blade.php index 6664a96..dd62dbe 100644 --- a/resources/views/authentication/register.blade.php +++ b/resources/views/authentication/register.blade.php @@ -83,29 +83,17 @@
- +
Please enter a name, any name will do.
- @if($errors !== null && array_key_exists('name', $errors)) -
- @foreach ($errors['name'] as $error) - {{ $error }} - @endforeach -
- @endif +
- +
Please enter your email address, we will never share your email address.
- @if($errors !== null && array_key_exists('email', $errors)) -
- @foreach ($errors['email'] as $error) - {{ $error }} - @endforeach -
- @endif +
diff --git a/routes/web.php b/routes/web.php index 1314c37..08c4de7 100644 --- a/routes/web.php +++ b/routes/web.php @@ -50,9 +50,9 @@ [Authentication::class, 'createNewPasswordProcess'] )->name('create-new-password.process'); -Route::get( +Route::view( '/new-password-created', - [Authentication::class, 'newPasswordCreated'] + 'authentication.new-password-created', )->name('new-password-created'); Route::get( @@ -65,9 +65,9 @@ [Authentication::class, 'forgotPasswordProcess'] )->name('forgot-password.process'); -Route::get( +Route::view( '/forgot-password-email-issued', - [Authentication::class, 'forgotPasswordEmailIssued'] + 'authentication.forgot-password-email-issued', )->name('forgot-password-email-issued'); Route::post( @@ -75,9 +75,9 @@ [Authentication::class, 'createPasswordProcess'] )->name('create-password.process'); -Route::get( +Route::view( '/registration-complete', - [Authentication::class, 'registrationComplete'] + 'authentication.registration-complete' )->name('registration-complete'); From 89510d8667408ceda7c3ecaeb72ac6f2697dfc26 Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sat, 28 Jan 2023 15:16:15 +0000 Subject: [PATCH 3/8] Fix - Return required --- resources/views/authentication/create-password.blade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/authentication/create-password.blade.php b/resources/views/authentication/create-password.blade.php index 65b2b62..983063a 100644 --- a/resources/views/authentication/create-password.blade.php +++ b/resources/views/authentication/create-password.blade.php @@ -81,14 +81,14 @@
- +
Please enter a password, at least 12 characters please, your password will be hashed.
- +
Please enter your password again
From 92342a72b2888c5683c453e272f02bd081956558 Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sat, 28 Jan 2023 17:29:50 +0000 Subject: [PATCH 4/8] Auth - Updated auth --- app/Actions/Account/ForgotPassword.php | 52 +++++++++++++++++++ app/Http/Controllers/Authentication.php | 26 +++------- .../authentication/forgot-password.blade.php | 10 +--- 3 files changed, 62 insertions(+), 26 deletions(-) create mode 100644 app/Actions/Account/ForgotPassword.php diff --git a/app/Actions/Account/ForgotPassword.php b/app/Actions/Account/ForgotPassword.php new file mode 100644 index 0000000..1d3620e --- /dev/null +++ b/app/Actions/Account/ForgotPassword.php @@ -0,0 +1,52 @@ + + * @copyright Dean Blackborough (Costs to Expect) 2018-2023 + * https://github.com/costs-to-expect/budget/blob/main/LICENSE + */ +class ForgotPassword extends Action +{ + public function __invoke( + Service $api, + array $input + ): int + { + $post_response = $api->forgotPassword($input); + + if ($post_response['status'] === 201) { + + $config = Config::get('app.config'); + $encryptor = new \Illuminate\Encryption\Encrypter($config['forgot-password-salt']); + + $this->parameters = $post_response['content']['uris']['create-new-password']['parameters']; + $token = $encryptor->decryptString($this->parameters['encrypted_token']); + + Notification::route('mail', $input['email']) + ->notify(new \App\Notifications\ForgotPassword($input['email'], $token)); + + return 201; + } + + if ($post_response['status'] === 422) { + $this->validation_errors = $post_response['fields']; + + return 422; + } + + $this->message = $post_response['content']; + $this->parameters = [ + 'email' => $input['email'], + ]; + + return $post_response['status']; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Authentication.php b/app/Http/Controllers/Authentication.php index 0081a86..2618026 100644 --- a/app/Http/Controllers/Authentication.php +++ b/app/Http/Controllers/Authentication.php @@ -135,8 +135,8 @@ public function forgotPassword() return view( 'authentication.forgot-password', [ - 'errors' => session()->get('authentication.errors'), - 'failed' => session()->get('authentication.failed'), + 'errors' => session()->get('validation.errors'), + 'failed' => session()->get('request.failed'), ] ); } @@ -145,32 +145,22 @@ public function forgotPasswordProcess(Request $request) { $api = new Service(); - $response = $api->forgotPassword( - $request->only(['email']) - ); - - if ($response['status'] === 201) { - - $config = Config::get('app.config'); - $encryptor = new \Illuminate\Encryption\Encrypter($config['forgot-password-salt']); - $parameters = $response['content']['uris']['create-new-password']['parameters']; - $token = $encryptor->decryptString($parameters['encrypted_token']); - - Notification::route('mail', $request->input('email')) - ->notify(new ForgotPassword($request->input('email'), $token)); + $action = new \App\Actions\Account\ForgotPassword(); + $result = $action($api,$request->only(['email'])); + if ($result === 201) { return redirect()->route('forgot-password-email-issued'); } - if ($response['status'] === 422) { + if ($result === 422) { return redirect()->route('forgot-password.view') ->withInput() - ->with('authentication.errors', $response['fields']); + ->with('validation.errors', $action->getValidationErrors()); } return redirect()->route('forgot-password.view') ->withInput() - ->with('authentication.failed', $response['content']); + ->with('request.failed', $action->getMessage()); } public function register() diff --git a/resources/views/authentication/forgot-password.blade.php b/resources/views/authentication/forgot-password.blade.php index a0bf196..e76183b 100644 --- a/resources/views/authentication/forgot-password.blade.php +++ b/resources/views/authentication/forgot-password.blade.php @@ -82,16 +82,10 @@
- +
Please enter your email address, we will never share your email address.
- @if($errors !== null && array_key_exists('email', $errors)) -
- @foreach ($errors['email'] as $error) - {{ $error }} - @endforeach -
- @endif +
From ff9f8488df8462e1c0562963b1163f8bfee4fd3b Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sat, 28 Jan 2023 19:32:11 +0000 Subject: [PATCH 5/8] Actions - Moving all the authentication to actions --- app/Actions/Account/CreateNewPassword.php | 47 ++++++++++++++++++ app/Actions/Account/ForgotPassword.php | 6 +-- app/Api/Service.php | 2 +- app/Api/Uri.php | 2 +- app/Http/Controllers/Authentication.php | 49 +++++++------------ app/Notifications/ForgotPassword.php | 2 +- .../create-new-password.blade.php | 22 ++------- 7 files changed, 74 insertions(+), 56 deletions(-) create mode 100644 app/Actions/Account/CreateNewPassword.php diff --git a/app/Actions/Account/CreateNewPassword.php b/app/Actions/Account/CreateNewPassword.php new file mode 100644 index 0000000..a7bcf8c --- /dev/null +++ b/app/Actions/Account/CreateNewPassword.php @@ -0,0 +1,47 @@ + + * @copyright Dean Blackborough (Costs to Expect) 2018-2023 + * https://github.com/costs-to-expect/budget/blob/main/LICENSE + */ +class CreateNewPassword extends Action +{ + public function __invoke( + Service $api, + array $input + ): int + { + $post_response = $api->createNewPassword($input); + + dd($post_response); + + if ($post_response['status'] === 204) { + return 204; + } + + if ($post_response['status'] === 422) { + $this->validation_errors = $post_response['fields']; + $this->parameters = [ + 'token' => $input['token'], + 'email' => $input['email'], + ]; + + return 422; + } + + $this->message = $post_response['content']; + $this->parameters = [ + 'token' => $input['token'], + 'email' => $input['email'], + ]; + + return $post_response['status']; + } +} \ No newline at end of file diff --git a/app/Actions/Account/ForgotPassword.php b/app/Actions/Account/ForgotPassword.php index 1d3620e..e2d18db 100644 --- a/app/Actions/Account/ForgotPassword.php +++ b/app/Actions/Account/ForgotPassword.php @@ -24,14 +24,10 @@ public function __invoke( if ($post_response['status'] === 201) { - $config = Config::get('app.config'); - $encryptor = new \Illuminate\Encryption\Encrypter($config['forgot-password-salt']); - $this->parameters = $post_response['content']['uris']['create-new-password']['parameters']; - $token = $encryptor->decryptString($this->parameters['encrypted_token']); Notification::route('mail', $input['email']) - ->notify(new \App\Notifications\ForgotPassword($input['email'], $token)); + ->notify(new \App\Notifications\ForgotPassword($input['email'], $this->parameters['encrypted_token'])); return 201; } diff --git a/app/Api/Service.php b/app/Api/Service.php index f75b76b..e61333d 100644 --- a/app/Api/Service.php +++ b/app/Api/Service.php @@ -168,7 +168,7 @@ public function createPassword(array $payload): array #[ArrayShape(['status' => "integer", 'content' => "array", 'fields' => "array"])] public function createNewPassword(array $payload): array { - $uri = Uri::createNewPassword($payload['token'], $payload['email']); + $uri = Uri::createNewPassword($payload['encrypted_token'], $payload['email']); return $this->http->post( $uri['uri'], diff --git a/app/Api/Uri.php b/app/Api/Uri.php index 74068f7..b292da4 100644 --- a/app/Api/Uri.php +++ b/app/Api/Uri.php @@ -58,7 +58,7 @@ public static function createPassword(string $token, string $email): array #[ArrayShape(['uri' => "string", 'name' => "string"])] public static function createNewPassword(string $token, string $email): array { - $uri = '/' . self::VERSION . '/auth/create-new-password?token=' . + $uri = '/' . self::VERSION . '/auth/create-new-password?encrypted_token=' . urlencode($token) . '&email=' . urlencode($email); return [ diff --git a/app/Http/Controllers/Authentication.php b/app/Http/Controllers/Authentication.php index 2618026..4c52285 100644 --- a/app/Http/Controllers/Authentication.php +++ b/app/Http/Controllers/Authentication.php @@ -21,30 +21,25 @@ class Authentication extends Controller { public function createNewPassword(Request $request) { - $token = null; + $encrypted_token = null; $email = null; - if (session()->get('authentication.parameters') !== null) { - $token = session()->get('authentication.parameters')['token']; - $email = session()->get('authentication.parameters')['email']; - } - - if ($request->input('token') !== null && $request->input('email') !== null) { - $token = $request->input('token'); - $email = $request->input('email'); + if ($request->query('encrypted_token') !== null && $request->query('email') !== null) { + $encrypted_token = $request->query('encrypted_token'); + $email = $request->query('email'); } - if ($token === null && $email === null) { + if ($encrypted_token === null && $email === null) { abort(404, 'Password cannot be created, registration parameters not found'); } return view( 'authentication.create-new-password', [ - 'token' => $token, + 'encrypted_token' => $encrypted_token, 'email' => $email, - 'errors' => session()->get('authentication.errors'), - 'failed' => session()->get('authentication.failed'), + 'errors' => session()->get('validation.errors'), + 'failed' => session()->get('request.failed'), ] ); } @@ -53,32 +48,24 @@ public function createNewPasswordProcess(Request $request) { $api = new Service(); - $response = $api->createNewPassword( - $request->only(['token', 'email', 'password', 'password_confirmation']) + $action = new \App\Actions\Account\CreateNewPassword(); + $result = $action( + $api, + $request->only(['encrypted_token', 'email', 'password', 'password_confirmation']) ); - if ($response['status'] === 204) { + if ($result === 204) { return redirect()->route('new-password-created'); } - if ($response['status'] === 422) { - return redirect()->route( - 'create-new-password.view', - [ - 'token' => $request->input('token'), - 'email' => $request->input('email'), - ]) + if ($result === 422) { + return redirect()->route('create-new-password.view', $action->getParameters()) ->withInput() - ->with('authentication.errors', $response['fields']); + ->with('validation.errors', $action->getValidationErrors()); } - return redirect()->route( - 'create-new-password.view', - [ - 'token' => $request->input('token'), - 'email' => $request->input('email'), - ]) - ->with('authentication.failed', $response['content']); + return redirect()->route('create-new-password.view',$action->getParameters()) + ->with('request.failed', $action->getMessage()); } public function createPassword(Request $request) diff --git a/app/Notifications/ForgotPassword.php b/app/Notifications/ForgotPassword.php index 8aa5656..44b86ed 100644 --- a/app/Notifications/ForgotPassword.php +++ b/app/Notifications/ForgotPassword.php @@ -31,7 +31,7 @@ public function toMail($notifiable) ->subject('Budget: Create a new Password!') ->greeting('Hi Budgeteer!') ->line('Please find below the link to create a new password for your account.') - ->action('Create Password', url('/create-new-password') . '?token=' . urlencode($this->token) . '&email=' . urlencode($this->email)) + ->action('Create Password', url('/create-new-password') . '?encrypted_token=' . urlencode($this->token) . '&email=' . urlencode($this->email)) ->line('If you did not start this request, please ignore it, let us know privately if it continues to happen.') ->line('Thank you for using Budget, we hope it helps!'); } diff --git a/resources/views/authentication/create-new-password.blade.php b/resources/views/authentication/create-new-password.blade.php index 8da8238..a3f4d08 100644 --- a/resources/views/authentication/create-new-password.blade.php +++ b/resources/views/authentication/create-new-password.blade.php @@ -81,30 +81,18 @@
- +
Please enter a password, at least 12 characters please, your password will be hashed.
- @if($errors !== null && array_key_exists('password', $errors)) -
- @foreach ($errors['password'] as $error) - {{ $error }} - @endforeach -
- @endif +
- +
Please enter your password again
- @if($errors !== null && array_key_exists('password_confirmation', $errors)) -
- @foreach ($errors['password_confirmation'] as $error) - {{ $error }} - @endforeach -
- @endif +
- + From b659947a32f088c11fbfff94903494c550c8317e Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sun, 29 Jan 2023 15:45:01 +0000 Subject: [PATCH 6/8] Create new password updated - Create new password moved to action --- app/Actions/Account/CreateNewPassword.php | 6 ++---- app/Http/Controllers/Authentication.php | 2 +- .../views/authentication/create-new-password.blade.php | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/app/Actions/Account/CreateNewPassword.php b/app/Actions/Account/CreateNewPassword.php index a7bcf8c..533a310 100644 --- a/app/Actions/Account/CreateNewPassword.php +++ b/app/Actions/Account/CreateNewPassword.php @@ -20,8 +20,6 @@ public function __invoke( { $post_response = $api->createNewPassword($input); - dd($post_response); - if ($post_response['status'] === 204) { return 204; } @@ -29,7 +27,7 @@ public function __invoke( if ($post_response['status'] === 422) { $this->validation_errors = $post_response['fields']; $this->parameters = [ - 'token' => $input['token'], + 'encrypted_token' => $input['encrypted_token'], 'email' => $input['email'], ]; @@ -38,7 +36,7 @@ public function __invoke( $this->message = $post_response['content']; $this->parameters = [ - 'token' => $input['token'], + 'encrypted_token' => $input['encrypted_token'], 'email' => $input['email'], ]; diff --git a/app/Http/Controllers/Authentication.php b/app/Http/Controllers/Authentication.php index 4c52285..9fb0fb6 100644 --- a/app/Http/Controllers/Authentication.php +++ b/app/Http/Controllers/Authentication.php @@ -186,7 +186,7 @@ public function registerProcess(Request $request): RedirectResponse } return redirect()->route('register.view') - ->with('authentication.failed', $action->getMessage()); + ->with('request.failed', $action->getMessage()); } public function signIn() diff --git a/resources/views/authentication/create-new-password.blade.php b/resources/views/authentication/create-new-password.blade.php index a3f4d08..486bb5e 100644 --- a/resources/views/authentication/create-new-password.blade.php +++ b/resources/views/authentication/create-new-password.blade.php @@ -81,14 +81,14 @@
- +
Please enter a password, at least 12 characters please, your password will be hashed.
- +
Please enter your password again
From 1db942db892023f4eb9e2069c903eec64310c84d Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sun, 29 Jan 2023 16:28:56 +0000 Subject: [PATCH 7/8] Auth actions - Moved all auth code to actions and updated to use the correct format for validation errors. - Removed the decrypting --- .env.example | 2 - app/Actions/Account/SignIn.php | 44 +++++++++++++++++++ app/Auth/Guard/Api/Guard.php | 9 +--- app/Http/Controllers/Authentication.php | 24 +++++----- .../Components/ValidationErrorMessage.php | 8 +--- config/app/config.php | 3 +- .../views/account/change-password.blade.php | 4 +- .../views/account/update-profile.blade.php | 4 +- .../views/authentication/sign-in.blade.php | 22 +++------- 9 files changed, 69 insertions(+), 51 deletions(-) create mode 100644 app/Actions/Account/SignIn.php diff --git a/.env.example b/.env.example index be988ee..b51034f 100644 --- a/.env.example +++ b/.env.example @@ -13,8 +13,6 @@ ITEM_SUBTYPE_ID=Q6OV9dk5dE EXCEPTION_NOTIFICATION_EMAIL= -APP_HASH_SALT_FORGOT_PASSWORD= - LOG_CHANNEL=stack LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug diff --git a/app/Actions/Account/SignIn.php b/app/Actions/Account/SignIn.php new file mode 100644 index 0000000..9d8b7f7 --- /dev/null +++ b/app/Actions/Account/SignIn.php @@ -0,0 +1,44 @@ + + * @copyright Dean Blackborough (Costs to Expect) 2018-2023 + * https://github.com/costs-to-expect/budget/blob/main/LICENSE + */ +class SignIn extends Action +{ + public function __invoke( + array $input + ): int + { + if (array_key_exists('email', $input) === false || $input['email'] === null) { + $this->validation_errors['email']['errors'] = [ + 'You need to provide your email address' + ]; + } + if (array_key_exists('password', $input) === false || $input['password'] === null) { + $this->validation_errors['password']['errors'] = [ + 'You need to provide your password' + ]; + } + + if ($this->validation_errors !== []) { + return 422; + } + + + if (Auth::attempt($input, array_key_exists('remember_me', $input))) { + return 204; + } + + $this->validation_errors = Auth::errors(); + + return 422; + } +} \ No newline at end of file diff --git a/app/Auth/Guard/Api/Guard.php b/app/Auth/Guard/Api/Guard.php index a3db841..c000305 100644 --- a/app/Auth/Guard/Api/Guard.php +++ b/app/Auth/Guard/Api/Guard.php @@ -101,13 +101,8 @@ public function validate(array $credentials = [], bool $remember_me = false): bo return true; } - if ($response['status'] === 422) { - $this->errors = $response['content']['fields']; - return false; - } - - if ($response['status'] === 401) { - $this->errors = ['email' => [$response['content']]]; + if ($response['status'] === 422 || $response['status'] === 401) { + $this->errors = $response['fields']; return false; } diff --git a/app/Http/Controllers/Authentication.php b/app/Http/Controllers/Authentication.php index 9fb0fb6..a530d47 100644 --- a/app/Http/Controllers/Authentication.php +++ b/app/Http/Controllers/Authentication.php @@ -4,13 +4,11 @@ namespace App\Http\Controllers; use App\Actions\Account\Register; +use App\Actions\Account\SignIn; use App\Api\Service; -use App\Notifications\ForgotPassword; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\Config; -use Illuminate\Support\Facades\Notification; /** * @author Dean Blackborough @@ -194,25 +192,25 @@ public function signIn() return view( 'authentication.sign-in', [ - 'errors' => session()->get('authentication.errors') + 'errors' => session()->get('validation.errors') ] ); } public function signInProcess(Request $request) { - $credentials = $request->only(['email', 'password']); + $action = new SignIn(); + $result = $action( + $request->only(['email', 'password', 'remember_me']) + ); - if (Auth::attempt($credentials, $request->input('remember_me') !== null)) { - return redirect()->route('home'); + if ($result === 422) { + return redirect()->route('sign-in.view') + ->withInput() + ->with('validation.errors', $action->getValidationErrors()); } - return redirect()->route('sign-in.view') - ->withInput() - ->with( - 'authentication.errors', - Auth::errors() - ); + return redirect()->route('home'); } public function signOut(): RedirectResponse diff --git a/app/View/Components/ValidationErrorMessage.php b/app/View/Components/ValidationErrorMessage.php index 37258b8..2f1aa29 100644 --- a/app/View/Components/ValidationErrorMessage.php +++ b/app/View/Components/ValidationErrorMessage.php @@ -8,16 +8,12 @@ class ValidationErrorMessage extends Component { private array $errors; - public function __construct(string $field, bool $oldStyle = false) + public function __construct(string $field) { $errors = session()->get('validation.errors'); if (is_array($errors) && array_key_exists($field, $errors) === true) { - if ($oldStyle === true) { - $this->errors = $errors[$field]; - } else { - $this->errors = $errors[$field]['errors']; - } + $this->errors = $errors[$field]['errors']; } else { $this->errors = []; } diff --git a/config/app/config.php b/config/app/config.php index b908d0a..4fba579 100644 --- a/config/app/config.php +++ b/config/app/config.php @@ -13,6 +13,5 @@ 'version' => 'v1.07.0', 'release_date' => '18th January 2023', 'exception_notification_email' => env('EXCEPTION_NOTIFICATION_EMAIL'), - 'timezone' => 'UTC', // We can allow users to override this later, - 'forgot-password-salt' => env('APP_HASH_SALT_FORGOT_PASSWORD'), + 'timezone' => 'UTC', // We can allow users to override this later ]; diff --git a/resources/views/account/change-password.blade.php b/resources/views/account/change-password.blade.php index 5b59aa4..3643fff 100644 --- a/resources/views/account/change-password.blade.php +++ b/resources/views/account/change-password.blade.php @@ -41,14 +41,14 @@
Please enter your new password, at least 12 characters please, your password will be hashed.
- +
Please enter your password again, we just need to confirm you didn't make a typo.
- +
diff --git a/resources/views/account/update-profile.blade.php b/resources/views/account/update-profile.blade.php index c5b3ecb..5563347 100644 --- a/resources/views/account/update-profile.blade.php +++ b/resources/views/account/update-profile.blade.php @@ -41,14 +41,14 @@
Your email address, update if necessary.
- +
Your name, update if necessary.
- +
diff --git a/resources/views/authentication/sign-in.blade.php b/resources/views/authentication/sign-in.blade.php index 1598907..43e703f 100644 --- a/resources/views/authentication/sign-in.blade.php +++ b/resources/views/authentication/sign-in.blade.php @@ -75,32 +75,20 @@
- +
Please enter your email address, we will never share your email address.
- @if($errors !== null && array_key_exists('email', $errors)) -
- @foreach ($errors['email'] as $error) - {{ $error }} - @endforeach -
- @endif +
- +
Please enter your password, we will check this against the hashed value in our database.
- @if($errors !== null && array_key_exists('password', $errors)) -
- @foreach ($errors['password'] as $error) - {{ $error }} - @endforeach -
- @endif +
- +
From a6edd2e51d08c5236418a4f51e9c2eb9c31d2b1d Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Mon, 30 Jan 2023 11:00:42 +0000 Subject: [PATCH 8/8] Release - Set the release data and version --- config/app/config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/app/config.php b/config/app/config.php index 4fba579..9c7e2cd 100644 --- a/config/app/config.php +++ b/config/app/config.php @@ -10,8 +10,8 @@ 'item_subtype_id' => env('ITEM_SUBTYPE_ID'), 'cookie_user' => env('SESSION_NAME_USER'), 'cookie_bearer' => env('SESSION_NAME_BEARER'), - 'version' => 'v1.07.0', - 'release_date' => '18th January 2023', + 'version' => 'v1.08.0', + 'release_date' => '30th January 2023', 'exception_notification_email' => env('EXCEPTION_NOTIFICATION_EMAIL'), 'timezone' => 'UTC', // We can allow users to override this later ];