Skip to content

Commit

Permalink
Merge pull request UnlockedLabs#30 from PThorpe92/middleware
Browse files Browse the repository at this point in the history
feat: implement login flow that triggers reset for superadmin
  • Loading branch information
nokierae authored Dec 14, 2023
2 parents 9eb99c5 + bd323e3 commit 06dc5c8
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 141 deletions.
8 changes: 1 addition & 7 deletions app/Http/Controllers/Auth/AuthenticatedSessionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
Expand All @@ -31,13 +30,8 @@ public function create(): Response
*/
public function store(LoginRequest $request): RedirectResponse
{
$user = User::where('username', $request->username)->first();
$request->authenticate();

if ($user['password_reset']) {
return redirect()->route('password.reset', ['token' => $request->password]);
} else {
$request->authenticate();
}
$request->session()->regenerate();

return redirect()->intended(RouteServiceProvider::HOME);
Expand Down
57 changes: 3 additions & 54 deletions app/Http/Controllers/Auth/NewPasswordController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,7 @@
namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules;
use Illuminate\Validation\ValidationException;
use Inertia\Inertia;
use Inertia\Response;

Expand All @@ -23,52 +15,9 @@ class NewPasswordController extends Controller
public function create(Request $request): Response
{
return Inertia::render('Auth/ResetPassword', [
'username' => $request->username,
'token' => $request->route('token'),
]);
}

/**
* Handle an incoming new password request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'token' => 'required',
'username' => 'required|max:50',
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);

// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$userReset = User::where('username')->first();
$status = Password::reset(
$request->only('username', 'password', 'password_confirmation', 'token'),
function ($user) use ($request) {
$user->forceFill([
'password' => Hash::make($request->password),
'remember_token' => Str::random(60),
])->save();

event(new PasswordReset($user));
}
);

// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
if ($status == Password::PASSWORD_RESET) {
$userReset['reset_password'] = false;
$userReset->save();

return redirect()->route('login')->with('status', __($status));
}

throw ValidationException::withMessages([
'username' => [trans($status)],
'props' => [
'username' => $request->user()->username,
],
]);
}
}
8 changes: 5 additions & 3 deletions app/Http/Controllers/Auth/PasswordController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ class PasswordController extends Controller
public function update(Request $request): RedirectResponse
{
$validated = $request->validate([
'current_password' => ['required', 'current_password'],
'password' => ['required', Password::defaults(), 'confirmed'],
'password' => ['required', Password::defaults()],
'password_confirmation' => ['required', 'same:password'],
]);

$request->user()->update([
'password' => Hash::make($validated['password']),
'password_reset' => false,
]);
var_dump($validated);

return back();
return redirect()->route('dashboard');
}
}
2 changes: 2 additions & 0 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Kernel extends HttpKernel
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\HandleInertiaRequests::class,
\Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class,
\App\Http\Middleware\PasswordReset::class,
],

'api' => [
Expand Down Expand Up @@ -66,5 +67,6 @@ class Kernel extends HttpKernel
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'password_reset' => \App\Http\Middleware\PasswordReset::class,
];
}
32 changes: 32 additions & 0 deletions app/Http/Middleware/PasswordReset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class PasswordReset
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next)
{
// Check if the user is authenticated
if (Auth::check()) {
$user = Auth::user();

// Check if the route is not the password reset route
if ($request->route()->getName() !== 'password.reset' && $request->route()->getName() !== 'password.update' && $user->password_reset) {
// Redirect to the password reset route
return redirect()->route('password.reset');
}
}

// Continue with the request
return $next($request);
}
}
12 changes: 10 additions & 2 deletions database/seeders/DatabaseSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;

use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class DatabaseSeeder extends Seeder
{
Expand All @@ -14,6 +14,14 @@ class DatabaseSeeder extends Seeder
*/
public function run(): void
{
User::factory(10)->create();
// This needs to be defaulted and ran every time.. maybe needs to be a migration?
DB::table('users')->insert([
'name_first' => 'Super',
'name_last' => 'Admin',
'email' => '[email protected]',
'username' => 'SuperAdmin',
'password' => bcrypt('ChangeMe!'),
'password_reset' => true,
]);
}
}
30 changes: 3 additions & 27 deletions resources/js/Pages/Auth/ResetPassword.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,8 @@ import PrimaryButton from "@/Components/PrimaryButton";
import TextInput from "@/Components/TextInput";
import { Head, useForm } from "@inertiajs/react";

export default function ResetPassword({
token,
username,
}: {
token: string;
username: string;
}) {
export default function ResetPassword() {
const { data, setData, post, processing, errors, reset } = useForm({
token: token,
username: username,
password: "",
password_confirmation: "",
});
Expand All @@ -29,32 +21,16 @@ export default function ResetPassword({
const submit: FormEventHandler = (e) => {
e.preventDefault();

post(route("password.store"));
post(route("password.update"));
};

return (
<GuestLayout>
<Head title="Reset Password" />

<form onSubmit={submit}>
<div>
<InputLabel htmlFor="username" value="Username" />

<TextInput
id="username"
type="username"
name="username"
value={data.username}
className="mt-1 block w-full"
autoComplete="username"
onChange={(e) => setData("username", e.target.value)}
/>

<InputError message={errors.username} className="mt-2" />
</div>

<div className="mt-4">
<InputLabel htmlFor="password" value="Password" />
<InputLabel htmlFor="password" value="New Password" />

<TextInput
id="password"
Expand Down
11 changes: 4 additions & 7 deletions routes/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@
->name('password.request');

Route::post('forgot-password', [PasswordResetLinkController::class, 'store']);

Route::get('reset-password/{token}', [NewPasswordController::class, 'create'])
->name('password.reset');

Route::post('reset-password', [NewPasswordController::class, 'store'])
->name('password.store');
});

Route::middleware('auth')->group(function () {
Expand All @@ -38,8 +32,11 @@

Route::post('confirm-password', [ConfirmablePasswordController::class, 'store']);

Route::put('password', [PasswordController::class, 'update'])->name('password.update');
Route::post('password', [PasswordController::class, 'update'])->name('password.update');

Route::post('logout', [AuthenticatedSessionController::class, 'destroy'])
->name('logout');

Route::get('reset-password', [NewPasswordController::class, 'create'])
->name('password.reset');
});
2 changes: 1 addition & 1 deletion routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

Route::get('/dashboard', function () {
return Inertia::render('Dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');
})->middleware(['auth', 'password_reset'])->name('dashboard');

Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Expand Down
40 changes: 0 additions & 40 deletions tests/Feature/Auth/PasswordUpdateTest.php

This file was deleted.

0 comments on commit 06dc5c8

Please sign in to comment.