diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php
index 890283b7..a2c17b28 100644
--- a/app/Http/Controllers/AuthController.php
+++ b/app/Http/Controllers/AuthController.php
@@ -2,18 +2,36 @@
namespace App\Http\Controllers;
+use App\Mail\ResetPassword;
use App\Models\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
+use Illuminate\Support\Facades\Mail;
+use Illuminate\Support\Str;
+
+
+use Illuminate\Support\Facades\Password;
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Auth\Events\PasswordReset;
+use Illuminate\Validation\ValidationException;
/**
* @OA\Info(
- * title="Legalization API",
+ * title="Legalization API - Authorization",
* version="1.0.1"
* )
+ * @OA\SecurityScheme(
+ * securityScheme="bearerAuth",
+ * in="header",
+ * name="bearerAuth",
+ * type="http",
+ * scheme="bearer",
+ * bearerFormat="JWT",
+ * ),
*/
+
//controller where all auth process for client happens
class AuthController extends Controller
{
@@ -22,7 +40,7 @@ class AuthController extends Controller
* @OA\POST(
* path="/api/login",
* summary=" - Login user",
- * tags = {"authorization"},
+ * tags = {"Authorization"},
* @OA\RequestBody(
* @OA\MediaType(
* mediaType="application/json",
@@ -35,13 +53,13 @@ class AuthController extends Controller
* property="password",
* type="string",
* ),
- * example={"email": "ilmedovamahri@gmail.com", "password": "Hello001!"}
+ * example={"email": "ilmedovamahri@gmail.com", "password": 12345678}
* )
* )
* ),
* @OA\Response(
* response="200",
- * description="Authorization API - LOGIN user"
+ * description="OK"
* ),
* @OA\Response(
* response="401",
@@ -49,7 +67,7 @@ class AuthController extends Controller
* )
* )
*/
- public function login(Request $request){//Login - POST (function to login client from API using Sanctum)
+ public function login(Request $request){
$validatedData = request()->validate([
'email' => 'required',
'password' => 'required|min:6'
@@ -77,7 +95,7 @@ public function login(Request $request){//Login - POST (function to login client
* @OA\POST(
* path="/api/register",
* summary=" - Register user",
- * tags = {"authorization"},
+ * tags = {"Authorization"},
* @OA\RequestBody(
* @OA\MediaType(
* mediaType="application/json",
@@ -104,7 +122,7 @@ public function login(Request $request){//Login - POST (function to login client
* ),
* @OA\Response(
* response="200",
- * description="Authorization API - REGISTER user"
+ * description="OK"
* ),
* @OA\Response(
* response="401",
@@ -112,7 +130,7 @@ public function login(Request $request){//Login - POST (function to login client
* )
* )
*/
- public function register(Request $request){//Register - POST (function to register client from API using Sanctum)
+ public function register(Request $request){
$validatedData = request()->validate([
'email' => 'required',
'password' => 'required|min:6',
@@ -146,4 +164,139 @@ public function register(Request $request){//Register - POST (function to regist
return response()->json(['success' => ['token' => $tokenResult]], 200);
}
+ /**
+ * @OA\GET(
+ * path="/api/client",
+ * summary=" - Get user",
+ * tags = {"Authorization"},
+ * security={
+ * {"bearerAuth": {}}
+ * },
+ * @OA\Response(
+ * response="200",
+ * description="OK"
+ * ),
+ * @OA\Response(
+ * response="401",
+ * description="Unauthorized"
+ * )
+ * )
+ */
+ public function client(Request $request) {
+ $user = $request->user();
+ if($user){
+ return response()->json($request->user(),200);
+ }
+ return response()->json([
+ 'message' => 'token_expired'
+ ], 401);
+ }
+
+ /**
+ * @OA\POST(
+ * path="/api/logout",
+ * summary=" - Logout user",
+ * tags = {"Authorization"},
+ * security={
+ * {"bearerAuth": {}}
+ * },
+ * @OA\Response(
+ * response="200",
+ * description="OK"
+ * ),
+ * @OA\Response(
+ * response="401",
+ * description="Unauthorized"
+ * )
+ * )
+ */
+ public function logout(Request $request) {
+ // Revoke the token that was used to authenticate the current request
+ $request->user()->currentAccessToken()->delete();
+ //$request->user->tokens()->delete(); // use this to revoke all tokens (logout from all devices)
+ return response()->json([
+ 'message' => 'ok'
+ ], 200);
+ }
+
+ /**
+ * @OA\POST(
+ * path="/api/forgot-password",
+ * summary=" - Send a user password reset link",
+ * tags = {"Authorization"},
+ * @OA\RequestBody(
+ * @OA\MediaType(
+ * mediaType="application/json",
+ * @OA\Schema(
+ * @OA\Property(
+ * property="email",
+ * type="string",
+ * ),
+ * example={"email": "ilmedovamahri@gmail.com"}
+ * )
+ * )
+ * ),
+ * @OA\Response(
+ * response="200",
+ * description="OK"
+ * )
+ * )
+ */
+ public function sendPasswordResetLinkEmail(Request $request) {
+ $request->validate(['email' => 'required|email']);
+
+ $user = Client::where('email', $request->email)->first();
+ if (!$user) {
+ return back()->with('failed', 'Failed! email is not registered.');
+ }
+
+ $token = Str::random(60);
+
+ $user['token'] = $token;
+ $user['is_verified'] = 0;
+ $user->save();
+
+ Mail::to($request->email)->send(new ResetPassword($user->name, $token));
+
+ return response()->json([
+ 'message' => 'OK'
+ ], 200);
+ }
+
+ public function forgotPasswordValidate($token)
+ {
+ $user = Client::where('token', $token)->where('is_verified', 0)->first();
+ if ($user) {
+ $email = $user->email;
+ return response()->json([
+ 'message' => compact('email')
+ ]);
+ }
+ return response()->json([
+ 'message' => 'token_expired'
+ ], 419);
+ }
+
+ public function updatePassword(Request $request) {
+ $this->validate($request, [
+ 'email' => 'required',
+ 'password' => 'required|min:6',
+ 'confirm_password' => 'required|same:password'
+ ]);
+
+ $user = Client::where('email', $request->email)->first();
+ if ($user) {
+ $user['is_verified'] = 0;
+ $user['token'] = '';
+ $user['password'] = Hash::make($request->password);
+ $user->save();
+ return response()->json([
+ 'message' => 'OK'
+ ], 200);
+ }
+ return response()->json([
+ 'message' => 'not_found'
+ ], 404);
+ }
+
}
diff --git a/app/Mail/ResetPassword.php b/app/Mail/ResetPassword.php
new file mode 100644
index 00000000..d8dd50a5
--- /dev/null
+++ b/app/Mail/ResetPassword.php
@@ -0,0 +1,43 @@
+name = $name;
+ $this->token = $token;
+ }
+
+ /**
+ * Build the message.
+ *
+ * @return $this
+ */
+ public function build()
+ {
+ $user['name'] = $this->name;
+ $user['token'] = $this->token;
+
+ return $this->from("milmedova96@gmail.com", "Mahri Ilmedova")
+ ->subject('Password Reset Link')
+ ->view('emails.reset-password', ['user' => $user]);
+ }
+}
diff --git a/app/Models/Client.php b/app/Models/Client.php
index 0ee904be..d7a00566 100644
--- a/app/Models/Client.php
+++ b/app/Models/Client.php
@@ -37,6 +37,9 @@ class Client extends Authenticatable
| FUNCTIONS
|--------------------------------------------------------------------------
*/
+ public function sendPasswordResetNotification($token){
+ $this->notify(new \App\Notifications\MailResetPasswordNotification($token));
+ }
/*
|--------------------------------------------------------------------------
diff --git a/app/Notifications/MailResetPasswordNotification.php b/app/Notifications/MailResetPasswordNotification.php
new file mode 100644
index 00000000..306c9b99
--- /dev/null
+++ b/app/Notifications/MailResetPasswordNotification.php
@@ -0,0 +1,40 @@
+pageUrl = 'localhost:8080';
+ }
+ public function via($notifiable){
+ return ['mail'];
+ }
+ public function toMail($notifiable){
+ if(static::$toMailCallback) {
+ return call_user_func(static::$toMailCallback, $notifiable, $this->token);
+ }
+ return (new MailMessage)
+ ->subject(Lang::getFromJson('Reset application Password v1'))
+ ->line(Lang::getFromJson('You are receiving this email because we received a password reset request for your account.'))
+ ->action(Lang::getFromJson('Reset Password'), $this->pageUrl."?token=".$this->token)
+ ->line(Lang::getFromJson('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.users.expire')]))
+ ->line(Lang::getFromJson('If you did not request a password reset, no further action is required.'));
+ }
+}
diff --git a/config/auth.php b/config/auth.php
index f348efc6..84eab93a 100644
--- a/config/auth.php
+++ b/config/auth.php
@@ -97,7 +97,7 @@
'passwords' => [
'users' => [
- 'provider' => 'users',
+ 'provider' => 'clients',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
diff --git a/database/migrations/2022_06_30_125804_add_token_to_clients_table.php b/database/migrations/2022_06_30_125804_add_token_to_clients_table.php
new file mode 100644
index 00000000..e6c50edd
--- /dev/null
+++ b/database/migrations/2022_06_30_125804_add_token_to_clients_table.php
@@ -0,0 +1,33 @@
+string('token')->nullable();
+ $table->boolean('is_verified')->default(0);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('clients', function (Blueprint $table) {
+ //
+ });
+ }
+};
diff --git a/resources/views/emails/reset-password.blade.php b/resources/views/emails/reset-password.blade.php
new file mode 100644
index 00000000..54b83bcc
--- /dev/null
+++ b/resources/views/emails/reset-password.blade.php
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+ Programming Fields
+ |
+
+
+
+
+
+ |
+
+ Hello {{ $user ? $user['name'] : '' }},
+
+ We've received a request to reset the password.
+
+
+ You can reset your password by clicking the button below:
+
+
+
+ Reset your password
+
+
+
+
+ Thank
+ you,
+
+ Programming Fields
+ |
+
+
+ |
+
+
+ |
+
+
+
+
diff --git a/routes/api.php b/routes/api.php
index a525c70e..7b951595 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -22,10 +22,11 @@
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
-
+Route::post('/forgot-password', [AuthController::class, 'sendPasswordResetLinkEmail'])->name('passwords.sent');
+Route::post('/reset', [AuthController::class, 'sendResetResponse'])->name('passwords.reset');
+Route::get('/forgot-password/{token}', [AuthController::class, 'forgotPasswordValidate']);
Route::middleware(['auth.client','auth:api'])->group(function () {
- Route::get('/client', function (Request $request) {
- return $request->user();
- });
+ Route::get('/client', [AuthController::class, 'client']);
+ Route::post('/logout', [AuthController::class, 'logout']);
});
diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json
index 10c279e9..305989c4 100644
--- a/storage/api-docs/api-docs.json
+++ b/storage/api-docs/api-docs.json
@@ -1,14 +1,14 @@
{
"openapi": "3.0.0",
"info": {
- "title": "Legalization API",
+ "title": "Legalization API - Authorization",
"version": "1.0.1"
},
"paths": {
"/api/login": {
"post": {
"tags": [
- "authorization"
+ "Authorization"
],
"summary": " - Login user",
"operationId": "a3b306d14572d1f4bd6c064b3233e7b8",
@@ -27,7 +27,7 @@
"type": "object",
"example": {
"email": "ilmedovamahri@gmail.com",
- "password": "Hello001!"
+ "password": 12345678
}
}
}
@@ -35,7 +35,7 @@
},
"responses": {
"200": {
- "description": "Authorization API - LOGIN user"
+ "description": "OK"
},
"401": {
"description": "Unauthorized"
@@ -46,7 +46,7 @@
"/api/register": {
"post": {
"tags": [
- "authorization"
+ "Authorization"
],
"summary": " - Register user",
"operationId": "8a56853624e025573120a09a4c75d468",
@@ -81,13 +81,99 @@
},
"responses": {
"200": {
- "description": "Authorization API - REGISTER user"
+ "description": "OK"
},
"401": {
"description": "Unauthorized"
}
}
}
+ },
+ "/api/client": {
+ "get": {
+ "tags": [
+ "Authorization"
+ ],
+ "summary": " - Get user",
+ "operationId": "9f1c53ceee113e04ff7709c819ce9bf5",
+ "responses": {
+ "200": {
+ "description": "OK"
+ },
+ "401": {
+ "description": "Unauthorized"
+ }
+ },
+ "security": [
+ {
+ "bearerAuth": []
+ }
+ ]
+ }
+ },
+ "/api/logout": {
+ "post": {
+ "tags": [
+ "Authorization"
+ ],
+ "summary": " - Logout user",
+ "operationId": "fe8f3429cd6979b3b4517e186505f9f9",
+ "responses": {
+ "200": {
+ "description": "OK"
+ },
+ "401": {
+ "description": "Unauthorized"
+ }
+ },
+ "security": [
+ {
+ "bearerAuth": []
+ }
+ ]
+ }
+ },
+ "/api/forgot-password": {
+ "post": {
+ "tags": [
+ "Authorization"
+ ],
+ "summary": " - Send a user password reset link",
+ "operationId": "45bf57623119762aa1c685aff5d3716e",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "properties": {
+ "email": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "example": {
+ "email": "ilmedovamahri@gmail.com"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "OK"
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "securitySchemes": {
+ "bearerAuth": {
+ "type": "http",
+ "name": "bearerAuth",
+ "in": "header",
+ "bearerFormat": "JWT",
+ "scheme": "bearer"
+ }
}
}
}
\ No newline at end of file