Skip to content

Commit cab40d8

Browse files
committed
feature: Password reset api
1 parent c00f3de commit cab40d8

File tree

7 files changed

+93
-5
lines changed

7 files changed

+93
-5
lines changed

app/Console/Kernel.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ protected function schedule(Schedule $schedule)
5656
})
5757
->daily()
5858
->name('Clean Log Tables');
59+
60+
// Clear expired password reset tokens every 60 minutes
61+
$schedule
62+
->command('auth:clear-resets')
63+
->hourly()
64+
->name('Clear Expired Password Reset Tokens');
5965
}
6066

6167
/**

app/Http/Controllers/API/AuthController.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
use App\User;
1818
use Carbon\Carbon;
1919
use GuzzleHttp\Client;
20+
use Illuminate\Auth\Events\PasswordReset;
2021
use Illuminate\Http\JsonResponse;
2122
use Illuminate\Http\Request;
2223
use Illuminate\Support\Facades\Hash;
2324
use Illuminate\Support\Facades\Log;
25+
use Illuminate\Support\Facades\Password;
2426
use Illuminate\Support\Facades\Validator;
2527
use Illuminate\Support\Str;
2628
use mervick\aesEverywhere\AES256;
@@ -236,6 +238,50 @@ public function forceChangePassword(Request $request)
236238
return response()->json(['message' => 'Şifreniz başarıyla değiştirildi.']);
237239
}
238240

241+
/**
242+
* Send password reset link
243+
*/
244+
public function sendPasswordResetLink(Request $request)
245+
{
246+
// Check email exists on database laravel validator
247+
validate([
248+
'email' => 'required|email|exists:users,email',
249+
]);
250+
251+
Password::sendResetLink($request->only('email'));
252+
253+
return response()->json(['message' => 'Şifre sıfırlama bağlantısı e-posta adresinize gönderildi.']);
254+
}
255+
256+
/**
257+
* Reset password with token
258+
*/
259+
public function resetPassword(Request $request)
260+
{
261+
$request->validate([
262+
'token' => 'required',
263+
'email' => 'required|email',
264+
'password' => 'required|min:8|confirmed',
265+
]);
266+
267+
$status = Password::reset(
268+
$request->only('email', 'password', 'password_confirmation', 'token'),
269+
function (User $user, string $password) {
270+
$user->forceFill([
271+
'password' => Hash::make($password)
272+
])->setRememberToken(Str::random(60));
273+
274+
$user->save();
275+
276+
event(new PasswordReset($user));
277+
}
278+
);
279+
280+
return $status === Password::PASSWORD_RESET
281+
? response()->json(['message' => 'Şifreniz başarıyla değiştirildi.'])
282+
: response()->json(['message' => 'Şifre sıfırlama bağlantısı geçersiz.'], 401);
283+
}
284+
239285
/**
240286
* Authenticate using Keycloak
241287
*/

app/Providers/AppServiceProvider.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
namespace App\Providers;
44

55
use App\Models\Notification;
6-
use App\Models\Permission;
76
use App\Observers\NotificationObserver;
87
use App\Observers\UserObserver;
98
use App\User;
109
use Carbon\Carbon;
10+
use Illuminate\Auth\Notifications\ResetPassword;
1111
use Illuminate\Contracts\Http\Kernel;
1212
use Illuminate\Database\Eloquent\Relations\Relation;
1313
use Illuminate\Pagination\Paginator;
1414
use Illuminate\Routing\Router;
15-
use Illuminate\Support\Facades\View;
1615
use Illuminate\Support\ServiceProvider;
1716

1817
/**
@@ -48,6 +47,10 @@ public function boot(
4847
\App\Http\Middleware\VerifyCsrfToken::class
4948
);
5049
}
50+
51+
ResetPassword::createUrlUsing(function ($user, string $token) {
52+
return request()->getSchemeAndHttpHost() . '/auth/reset_password?token=' . $token . '&email=' . $user->getEmailForPasswordReset();
53+
});
5154
}
5255

5356
/**

app/Providers/AuthServiceProvider.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace App\Providers;
44

55
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
6-
use Illuminate\Support\Facades\Gate;
76

87
/**
98
* Auth Service Provider

config/mail.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@
5555
*/
5656

5757
'from' => [
58-
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
59-
'name' => env('MAIL_FROM_NAME', 'Example'),
58+
'address' => env('MAIL_USERNAME') ?: 'destek@liman.dev',
59+
'name' => env('MAIL_FROM_NAME', 'Liman'),
6060
],
6161

6262
/*
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::create('password_resets', function (Blueprint $table) {
17+
$table->string('email')->index();
18+
$table->string('token')->index();
19+
$table->timestamp('created_at');
20+
});
21+
}
22+
23+
/**
24+
* Reverse the migrations.
25+
*
26+
* @return void
27+
*/
28+
public function down()
29+
{
30+
Schema::dropIfExists('password_resets');
31+
}
32+
};

routes/api.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
Route::post('/refresh', [AuthController::class, 'refresh']);
3333
Route::get('/user', [AuthController::class, 'userProfile']);
3434
Route::post('/change_password', [AuthController::class, 'forceChangePassword']);
35+
Route::post('/forgot_password', [AuthController::class, 'sendPasswordResetLink']);
36+
Route::post('/reset_password', [AuthController::class, 'resetPassword']);
3537
});
3638

3739
Route::post('/notifications/send', [ExternalNotificationController::class, 'accept']);

0 commit comments

Comments
 (0)