Skip to content

Commit d9a9783

Browse files
authored
Merge pull request #291 from connorabbas/develop
Confirmable password
2 parents eb5d4c8 + 53fd544 commit d9a9783

File tree

5 files changed

+158
-1
lines changed

5 files changed

+158
-1
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace App\Http\Controllers\Auth;
4+
5+
use App\Http\Controllers\Controller;
6+
use Illuminate\Http\RedirectResponse;
7+
use Illuminate\Http\Request;
8+
use Illuminate\Support\Facades\Auth;
9+
use Illuminate\Validation\ValidationException;
10+
use Inertia\Inertia;
11+
use Inertia\Response;
12+
13+
class ConfirmablePasswordController extends Controller
14+
{
15+
/**
16+
* Show the confirm password page.
17+
*/
18+
public function show(): Response
19+
{
20+
return Inertia::render('auth/ConfirmPassword');
21+
}
22+
23+
/**
24+
* Confirm the user's password.
25+
*/
26+
public function store(Request $request): RedirectResponse
27+
{
28+
$successfullyValidated = Auth::guard('web')->validate([
29+
'email' => $request->user()?->email,
30+
'password' => $request->password,
31+
]);
32+
33+
if (!$successfullyValidated) {
34+
throw ValidationException::withMessages([
35+
'password' => __('auth.password'),
36+
]);
37+
}
38+
39+
$request->session()->put('auth.password_confirmed_at', time());
40+
41+
return redirect()->intended(route('dashboard', absolute: false));
42+
}
43+
}

resources/js/layouts/UserSettingsLayout.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<script setup>
22
import { computed } from 'vue';
33
import { usePage } from '@inertiajs/vue3';
4-
import PageTitleSection from '@/components/PageTitleSection.vue';
54
65
const page = usePage();
76
const currentRoute = computed(() => {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<script setup>
2+
import { useForm } from '@inertiajs/vue3';
3+
import GuestAuthLayout from '@/layouts/GuestAuthLayout.vue';
4+
5+
const form = useForm({
6+
password: '',
7+
});
8+
9+
const submit = () => {
10+
form.post(route('password.confirm'), {
11+
onFinish: () => {
12+
form.reset();
13+
},
14+
});
15+
};
16+
</script>
17+
18+
<template>
19+
<GuestAuthLayout>
20+
<InertiaHead title="Confirm password" />
21+
22+
<form @submit.prevent="submit">
23+
<div class="space-y-6">
24+
<PageTitleSection class="text-center">
25+
<template #title>
26+
Confirm your password
27+
</template>
28+
<template #subTitle>
29+
<div class="text-sm">
30+
This is a secure area of the application. Please confirm your password before continuing.
31+
</div>
32+
</template>
33+
</PageTitleSection>
34+
35+
<div class="flex flex-col gap-2">
36+
<label for="password">Password</label>
37+
<Password
38+
v-model="form.password"
39+
:invalid="Boolean(form.errors?.password)"
40+
:feedback="false"
41+
autocomplete="current-password"
42+
inputId="password"
43+
toggleMask
44+
required
45+
fluid
46+
/>
47+
<Message
48+
v-if="form.errors?.password"
49+
severity="error"
50+
variant="simple"
51+
size="small"
52+
>
53+
{{ form.errors?.password }}
54+
</Message>
55+
</div>
56+
57+
<div class="flex justify-end items-center">
58+
<Button
59+
:loading="form.processing"
60+
type="submit"
61+
label="Confirm Password"
62+
/>
63+
</div>
64+
</div>
65+
</form>
66+
</GuestAuthLayout>
67+
</template>

routes/auth.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
use App\Http\Controllers\Auth\AuthenticatedSessionController;
4+
use App\Http\Controllers\Auth\ConfirmablePasswordController;
45
use App\Http\Controllers\Auth\EmailVerificationNotificationController;
56
use App\Http\Controllers\Auth\EmailVerificationPromptController;
67
use App\Http\Controllers\Auth\NewPasswordController;
@@ -35,6 +36,9 @@
3536
Route::post('email/verification-notification', [EmailVerificationNotificationController::class, 'store'])
3637
->middleware('throttle:6,1')
3738
->name('verification.send');
39+
Route::get('confirm-password', [ConfirmablePasswordController::class, 'show'])
40+
->name('password.confirm');
41+
Route::post('confirm-password', [ConfirmablePasswordController::class, 'store']);
3842
Route::post('logout', [AuthenticatedSessionController::class, 'destroy'])
3943
->name('logout');
4044
});
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Tests\Feature\Auth;
4+
5+
use App\Models\User;
6+
use Illuminate\Foundation\Testing\RefreshDatabase;
7+
use Tests\TestCase;
8+
9+
class PasswordConfirmationTest extends TestCase
10+
{
11+
use RefreshDatabase;
12+
13+
public function test_confirm_password_screen_can_be_rendered()
14+
{
15+
$user = User::factory()->create();
16+
17+
$response = $this->actingAs($user)->get('/confirm-password');
18+
19+
$response->assertStatus(200);
20+
}
21+
22+
public function test_password_can_be_confirmed()
23+
{
24+
$user = User::factory()->create();
25+
26+
$response = $this->actingAs($user)->post('/confirm-password', [
27+
'password' => 'password',
28+
]);
29+
30+
$response->assertRedirect();
31+
$response->assertSessionHasNoErrors();
32+
}
33+
34+
public function test_password_is_not_confirmed_with_invalid_password()
35+
{
36+
$user = User::factory()->create();
37+
38+
$response = $this->actingAs($user)->post('/confirm-password', [
39+
'password' => 'wrong-password',
40+
]);
41+
42+
$response->assertSessionHasErrors();
43+
}
44+
}

0 commit comments

Comments
 (0)