Compare commits
10 Commits
ef378d450d
...
0b8fbd6638
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b8fbd6638 | ||
|
|
14f04804b4 | ||
|
|
59f5e4d05f | ||
|
|
39c16fc9ce | ||
|
|
b1945e91d6 | ||
|
|
a71bb7e00d | ||
|
|
2078ec9521 | ||
|
|
dad10fc532 | ||
|
|
a42b9967d9 | ||
|
|
6e8f115396 |
306
API/JWT/JWT Authentication.postman_collection.json
Normal file
306
API/JWT/JWT Authentication.postman_collection.json
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
{
|
||||||
|
"info": {
|
||||||
|
"_postman_id": "845fc421-f049-436a-a73c-c42496b5b105",
|
||||||
|
"name": "JWT Authentication",
|
||||||
|
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||||
|
"_exporter_id": "26260450"
|
||||||
|
},
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Register",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "noauth"
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"name\":\"nima\",\n \"email\":\"nima_8a@yahoo.com\",\n \"password\":\"12345678\",\n \"password_confirmation\":\"12345678\"\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/register",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"register"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Login",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "noauth"
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"email\":\"nima_8a@yahoo.com\",\n \"password\":\"12345678\"\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/login",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"login"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Logout",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "bearer",
|
||||||
|
"bearer": [
|
||||||
|
{
|
||||||
|
"key": "token",
|
||||||
|
"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgwMDAvYXBpL2xvZ2luIiwiaWF0IjoxNzQ1NDMwNjM3LCJleHAiOjE3NDU0MzQyMzcsIm5iZiI6MTc0NTQzMDYzNywianRpIjoieTZ4SzNpc2lpYm5Pc0hTeSIsInN1YiI6IjIiLCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.Vl0MDCZ3225YGLQYamlA6A1_iwMscz2Uj1vFMW2s6mU",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/logout",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"logout"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Delete Account",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "bearer",
|
||||||
|
"bearer": [
|
||||||
|
{
|
||||||
|
"key": "token",
|
||||||
|
"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgwMDAvYXBpL2xvZ2luIiwiaWF0IjoxNzQ1NDMwODY0LCJleHAiOjE3NDU0MzQ0NjQsIm5iZiI6MTc0NTQzMDg2NCwianRpIjoiOUNWWmxaNjhVV0Y1QXBLSiIsInN1YiI6IjIiLCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.Ao2vzDJnkfjXgpCSKuh1Fh63RvEEpLFAqjrXoJfg6jw",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"method": "DELETE",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/deleteAcconut",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"deleteAcconut"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Email Notification Send",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "bearer",
|
||||||
|
"bearer": [
|
||||||
|
{
|
||||||
|
"key": "token",
|
||||||
|
"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgwMDAvYXBpL2xvZ2luIiwiaWF0IjoxNzQ1NDMxMTAyLCJleHAiOjE3NDU0MzQ3MDIsIm5iZiI6MTc0NTQzMTEwMiwianRpIjoiQjZRbXRlRkRuVGZ1WVhZZiIsInN1YiI6IjEiLCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.ap0sM1lcDrQ2W2oTVCDQLQZK2aS94pKmj1K6p77RNA8",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/email/verification-notification",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"email",
|
||||||
|
"verification-notification"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Verify Email",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "bearer",
|
||||||
|
"bearer": [
|
||||||
|
{
|
||||||
|
"key": "token",
|
||||||
|
"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgwMDAvYXBpL2xvZ2luIiwiaWF0IjoxNzQ1NDMxMTAyLCJleHAiOjE3NDU0MzQ3MDIsIm5iZiI6MTc0NTQzMTEwMiwianRpIjoiQjZRbXRlRkRuVGZ1WVhZZiIsInN1YiI6IjEiLCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.ap0sM1lcDrQ2W2oTVCDQLQZK2aS94pKmj1K6p77RNA8",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/email/verify/1/a410347aabe0039597cb405f771f043d411e4167?expires=1745434739&signature=6add506c4c1a09ac0fb7556d32f20cc84afeb2d523a6a77b400e0a4d0eff2920",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"email",
|
||||||
|
"verify",
|
||||||
|
"1",
|
||||||
|
"a410347aabe0039597cb405f771f043d411e4167"
|
||||||
|
],
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"key": "expires",
|
||||||
|
"value": "1745434739"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "signature",
|
||||||
|
"value": "6add506c4c1a09ac0fb7556d32f20cc84afeb2d523a6a77b400e0a4d0eff2920"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Forgot Password",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "noauth"
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"email\":\"nima.8ak@gmail.com\"\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/forgot-password",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"forgot-password"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -9,6 +9,32 @@ use Illuminate\Support\Facades\Auth;
|
|||||||
|
|
||||||
class DeleteAccountController extends Controller
|
class DeleteAccountController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Delete(
|
||||||
|
* path="/api/deleteAcconut",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* summary="Delete user account",
|
||||||
|
* description="Deletes the currently authenticated user's account and invalidates the JWT token.",
|
||||||
|
* security={{"bearerAuth":{}}},
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Account deleted successfully",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Your account has been deleted successfully. We’re sorry to see you go.")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Account deletion failed",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="We couldn’t delete your account at this moment. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function deleteAcconut()
|
public function deleteAcconut()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -10,6 +10,52 @@ use Tymon\JWTAuth\Facades\JWTAuth;
|
|||||||
|
|
||||||
class LoginController extends BaseController
|
class LoginController extends BaseController
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/login",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* summary="User login",
|
||||||
|
* description="Logs in a user and returns a JWT token if credentials are correct.",
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* required=true,
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* required={"email", "password"},
|
||||||
|
* @OA\Property(property="email", type="string", format="email", example="nima.8ak@gmail.com"),
|
||||||
|
* @OA\Property(property="password", type="string", format="password", example="12345678")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Login successful",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Login successful. Welcome back!"),
|
||||||
|
* @OA\Property(property="data", type="object",
|
||||||
|
* @OA\Property(property="name", type="string", example="Nima Malakooti"),
|
||||||
|
* @OA\Property(property="email", type="string", example="nima.8ak@gmail.com"),
|
||||||
|
* @OA\Property(property="token", type="string", example="Bearer eyJ0eXAiOiJKV1QiLCJhbGci...")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=401,
|
||||||
|
* description="Unauthorized access",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="message", type="string", example="Unauthorized access. Please check your credentials and try again.")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Failed to login",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="message", type="string", example="Failed to login user. Please try again later."),
|
||||||
|
* @OA\Property(property="error", type="string", example="Exception message here")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function login(LoginRequest $request)
|
public function login(LoginRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -9,6 +9,32 @@ use Illuminate\Support\Facades\Auth;
|
|||||||
|
|
||||||
class LogoutController extends Controller
|
class LogoutController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/logout",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* summary="Logout user",
|
||||||
|
* description="Logs out the currently authenticated user by invalidating the JWT token.",
|
||||||
|
* security={{"bearerAuth":{}}},
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Logout successful",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="You have been logged out successfully. Come back soon!")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Logout failed",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="message", type="string", example="Oops! Something went wrong while logging out. Please try again later."),
|
||||||
|
* @OA\Property(property="error", type="string", example="Exception message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function logout()
|
public function logout()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -7,6 +7,32 @@ use Illuminate\Http\Request;
|
|||||||
|
|
||||||
class SendMailNotificationController extends Controller
|
class SendMailNotificationController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/email/verification-notification",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* summary="Send verification email",
|
||||||
|
* description="Sends a verification email to the authenticated user.",
|
||||||
|
* security={{"bearerAuth":{}}},
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Verification email sent",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Please check your email for the verification link.")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Error while sending email",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="We encountered an issue while sending the verification email. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function mailNotification(Request $request)
|
public function mailNotification(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -8,6 +8,45 @@ use Illuminate\Http\Request;
|
|||||||
|
|
||||||
class VerifyMailController extends Controller
|
class VerifyMailController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/email/verify/{id}/{hash}",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* summary="Verify user email",
|
||||||
|
* description="Verifies the user's email using the verification link.",
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* required=true,
|
||||||
|
* description="User ID",
|
||||||
|
* @OA\Schema(type="integer", example=1)
|
||||||
|
* ),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="hash",
|
||||||
|
* in="path",
|
||||||
|
* required=true,
|
||||||
|
* description="Email verification hash",
|
||||||
|
* @OA\Schema(type="string", example="9e4f889aabbc...")
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Email verified successfully",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Your email has been successfully verified. Thank you!")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Verification failed",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="Your verification link was found, but something went wrong during the confirmation process. Please try again or request a new verification email."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function verifyMail(EmailVerificationRequest $request)
|
public function verifyMail(EmailVerificationRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -9,6 +9,38 @@ use App\Http\Requests\NotificationPasswordRequest;
|
|||||||
|
|
||||||
class NotificationPasswordController extends Controller
|
class NotificationPasswordController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/forgot-password",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* summary="Send password reset link",
|
||||||
|
* description="Sends a password reset link to the user's email address.",
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* required=true,
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* required={"email"},
|
||||||
|
* @OA\Property(property="email", type="string", format="email", example="nima.8ak@gmail.com")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Password reset link sent or email not found",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="We’ve emailed you the password reset link. Please check your inbox!")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Failed to send password reset email",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="We couldn’t send the password reset email due to an error. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function passwordNotification(NotificationPasswordRequest $request)
|
public function passwordNotification(NotificationPasswordRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -13,6 +13,49 @@ use App\Http\Requests\ResetPasswordRequest;
|
|||||||
|
|
||||||
class ResetPasswordController extends Controller
|
class ResetPasswordController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/reset-password",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* summary="Reset the user's password",
|
||||||
|
* description="Resets the password for the user using the provided token and new password.",
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* required=true,
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* required={"email", "password", "password_confirmation", "token"},
|
||||||
|
* @OA\Property(property="email", type="string", format="email", example="nima.8ak@gmail.com"),
|
||||||
|
* @OA\Property(property="password", type="string", format="password", example="12345678"),
|
||||||
|
* @OA\Property(property="password_confirmation", type="string", format="password", example="12345678"),
|
||||||
|
* @OA\Property(property="token", type="string", example="valid-reset-token-here")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Password reset successfully",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Your password has been reset!")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=400,
|
||||||
|
* description="Invalid token or mismatched password confirmation",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="message", type="string", example="This password reset token is invalid.")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Internal server error",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="We couldn’t process the request due to an error. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function resetPassword(ResetPasswordRequest $request)
|
public function resetPassword(ResetPasswordRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -12,6 +12,47 @@ use App\Http\Controllers\API\Auth\BaseController;
|
|||||||
|
|
||||||
class RegisterController extends BaseController
|
class RegisterController extends BaseController
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/register",
|
||||||
|
* summary="Register a new user",
|
||||||
|
* description="Registers a user and returns a JWT token.",
|
||||||
|
* operationId="registerUser",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* required=true,
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* required={"name","email","password","password_confirmation"},
|
||||||
|
* @OA\Property(property="name", type="string", example="Nima Malakooti"),
|
||||||
|
* @OA\Property(property="email", type="string", format="email", example="nima.8ak@gmail.com"),
|
||||||
|
* @OA\Property(property="password", type="string", format="password", example="12345678"),
|
||||||
|
* @OA\Property(property="password_confirmation", type="string", format="password", example="12345678"),
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Successful registration",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="User registered successfully."),
|
||||||
|
* @OA\Property(property="data", type="object",
|
||||||
|
* @OA\Property(property="name", type="string", example="Nima Malakooti"),
|
||||||
|
* @OA\Property(property="email", type="string", example="nima.8ak@gmail.com"),
|
||||||
|
* @OA\Property(property="token", type="string", example="Bearer eyJ0eXAiOiJKV1...")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Registration failed",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="message", type="string", example="Failed to register user. Please try again later."),
|
||||||
|
* @OA\Property(property="error", type="string", example="Detailed error message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function register(RegisterRequest $request)
|
public function register(RegisterRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -4,6 +4,11 @@ namespace App\Http\Controllers;
|
|||||||
|
|
||||||
use Tymon\JWTAuth\Facades\JWTAuth;
|
use Tymon\JWTAuth\Facades\JWTAuth;
|
||||||
|
|
||||||
abstract class Controller {
|
|
||||||
|
/**
|
||||||
}
|
* @OA\Info(
|
||||||
|
* title="API Documentation",
|
||||||
|
* version="1.0.0"
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
abstract class Controller {}
|
||||||
|
|||||||
@ -10,11 +10,13 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
|
"darkaonline/l5-swagger": "^9.0",
|
||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/sanctum": "^4.0",
|
"laravel/sanctum": "^4.0",
|
||||||
"laravel/tinker": "^2.10.1",
|
"laravel/tinker": "^2.10.1",
|
||||||
"mailersend/laravel-driver": "^2.9",
|
"mailersend/laravel-driver": "^2.9",
|
||||||
"tymon/jwt-auth": "^2.2"
|
"tymon/jwt-auth": "^2.2",
|
||||||
|
"zircote/swagger-php": "^5.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"fakerphp/faker": "^1.23",
|
"fakerphp/faker": "^1.23",
|
||||||
|
|||||||
499
API/JWT/composer.lock
generated
499
API/JWT/composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "46e6ca5d2fa1d64427ac16a117a3d06f",
|
"content-hash": "a988fd7da2b7e95aaa56b960a9030fa7",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "beberlei/assert",
|
"name": "beberlei/assert",
|
||||||
@ -268,6 +268,87 @@
|
|||||||
],
|
],
|
||||||
"time": "2023-12-20T15:40:13+00:00"
|
"time": "2023-12-20T15:40:13+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "darkaonline/l5-swagger",
|
||||||
|
"version": "9.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/DarkaOnLine/L5-Swagger.git",
|
||||||
|
"reference": "2c26427f8c41db8e72232415e7287313e6b6a2e2"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/DarkaOnLine/L5-Swagger/zipball/2c26427f8c41db8e72232415e7287313e6b6a2e2",
|
||||||
|
"reference": "2c26427f8c41db8e72232415e7287313e6b6a2e2",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/annotations": "^1.0 || ^2.0",
|
||||||
|
"ext-json": "*",
|
||||||
|
"laravel/framework": "^12.0 || ^11.0",
|
||||||
|
"php": "^8.2",
|
||||||
|
"swagger-api/swagger-ui": ">=5.18.3",
|
||||||
|
"symfony/yaml": "^5.0 || ^6.0 || ^7.0",
|
||||||
|
"zircote/swagger-php": "^5.0.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"mockery/mockery": "1.*",
|
||||||
|
"orchestra/testbench": "^10.0 || ^9.0 || ^8.0 || 7.* || ^6.15 || 5.*",
|
||||||
|
"php-coveralls/php-coveralls": "^2.0",
|
||||||
|
"phpstan/phpstan": "^2.1",
|
||||||
|
"phpunit/phpunit": "^11.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"aliases": {
|
||||||
|
"L5Swagger": "L5Swagger\\L5SwaggerFacade"
|
||||||
|
},
|
||||||
|
"providers": [
|
||||||
|
"L5Swagger\\L5SwaggerServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/helpers.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"L5Swagger\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Darius Matulionis",
|
||||||
|
"email": "darius@matulionis.lt"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "OpenApi or Swagger integration to Laravel",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"documentation",
|
||||||
|
"laravel",
|
||||||
|
"openapi",
|
||||||
|
"specification",
|
||||||
|
"swagger",
|
||||||
|
"ui"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/DarkaOnLine/L5-Swagger/issues",
|
||||||
|
"source": "https://github.com/DarkaOnLine/L5-Swagger/tree/9.0.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/DarkaOnLine",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-02-28T06:25:02+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dflydev/dot-access-data",
|
"name": "dflydev/dot-access-data",
|
||||||
"version": "v3.0.3",
|
"version": "v3.0.3",
|
||||||
@ -343,6 +424,82 @@
|
|||||||
},
|
},
|
||||||
"time": "2024-07-08T12:26:09+00:00"
|
"time": "2024-07-08T12:26:09+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "doctrine/annotations",
|
||||||
|
"version": "2.0.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine/annotations.git",
|
||||||
|
"reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine/annotations/zipball/901c2ee5d26eb64ff43c47976e114bf00843acf7",
|
||||||
|
"reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/lexer": "^2 || ^3",
|
||||||
|
"ext-tokenizer": "*",
|
||||||
|
"php": "^7.2 || ^8.0",
|
||||||
|
"psr/cache": "^1 || ^2 || ^3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/cache": "^2.0",
|
||||||
|
"doctrine/coding-standard": "^10",
|
||||||
|
"phpstan/phpstan": "^1.10.28",
|
||||||
|
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||||
|
"symfony/cache": "^5.4 || ^6.4 || ^7",
|
||||||
|
"vimeo/psalm": "^4.30 || ^5.14"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Guilherme Blanco",
|
||||||
|
"email": "guilhermeblanco@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Roman Borschel",
|
||||||
|
"email": "roman@code-factory.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Benjamin Eberlei",
|
||||||
|
"email": "kontakt@beberlei.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonathan Wage",
|
||||||
|
"email": "jonwage@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Johannes Schmitt",
|
||||||
|
"email": "schmittjoh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Docblock Annotations Parser",
|
||||||
|
"homepage": "https://www.doctrine-project.org/projects/annotations.html",
|
||||||
|
"keywords": [
|
||||||
|
"annotations",
|
||||||
|
"docblock",
|
||||||
|
"parser"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/doctrine/annotations/issues",
|
||||||
|
"source": "https://github.com/doctrine/annotations/tree/2.0.2"
|
||||||
|
},
|
||||||
|
"time": "2024-09-05T10:17:24+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/inflector",
|
"name": "doctrine/inflector",
|
||||||
"version": "2.0.10",
|
"version": "2.0.10",
|
||||||
@ -3517,6 +3674,55 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-07-20T21:41:07+00:00"
|
"time": "2024-07-20T21:41:07+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/cache",
|
||||||
|
"version": "3.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/cache.git",
|
||||||
|
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
|
||||||
|
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Cache\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "https://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interface for caching libraries",
|
||||||
|
"keywords": [
|
||||||
|
"cache",
|
||||||
|
"psr",
|
||||||
|
"psr-6"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/cache/tree/3.0.0"
|
||||||
|
},
|
||||||
|
"time": "2021-02-03T23:26:27+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/clock",
|
"name": "psr/clock",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@ -4220,6 +4426,67 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-04-27T21:32:50+00:00"
|
"time": "2024-04-27T21:32:50+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "swagger-api/swagger-ui",
|
||||||
|
"version": "v5.21.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/swagger-api/swagger-ui.git",
|
||||||
|
"reference": "fceaec605072fbc717a04895bd19814d9a1c8e6d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/fceaec605072fbc717a04895bd19814d9a1c8e6d",
|
||||||
|
"reference": "fceaec605072fbc717a04895bd19814d9a1c8e6d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"Apache-2.0"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Anna Bodnia",
|
||||||
|
"email": "anna.bodnia@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Buu Nguyen",
|
||||||
|
"email": "buunguyen@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Josh Ponelat",
|
||||||
|
"email": "jponelat@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kyle Shockey",
|
||||||
|
"email": "kyleshockey1@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Robert Barnwell",
|
||||||
|
"email": "robert@robertismy.name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sahar Jafari",
|
||||||
|
"email": "shr.jafari@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": " Swagger UI is a collection of HTML, Javascript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.",
|
||||||
|
"homepage": "http://swagger.io",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"documentation",
|
||||||
|
"openapi",
|
||||||
|
"specification",
|
||||||
|
"swagger",
|
||||||
|
"ui"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/swagger-api/swagger-ui/issues",
|
||||||
|
"source": "https://github.com/swagger-api/swagger-ui/tree/v5.21.0"
|
||||||
|
},
|
||||||
|
"time": "2025-04-13T19:37:38+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/clock",
|
"name": "symfony/clock",
|
||||||
"version": "v7.2.0",
|
"version": "v7.2.0",
|
||||||
@ -6515,6 +6782,78 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-01-17T11:39:41+00:00"
|
"time": "2025-01-17T11:39:41+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/yaml",
|
||||||
|
"version": "v7.2.5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/yaml.git",
|
||||||
|
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/yaml/zipball/4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
||||||
|
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.2",
|
||||||
|
"symfony/deprecation-contracts": "^2.5|^3.0",
|
||||||
|
"symfony/polyfill-ctype": "^1.8"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/console": "<6.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/console": "^6.4|^7.0"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"Resources/bin/yaml-lint"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Yaml\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Loads and dumps YAML files",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/yaml/tree/v7.2.5"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-03-03T07:12:39+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "tijsverkoyen/css-to-inline-styles",
|
"name": "tijsverkoyen/css-to-inline-styles",
|
||||||
"version": "v2.3.0",
|
"version": "v2.3.0",
|
||||||
@ -6869,6 +7208,92 @@
|
|||||||
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
|
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
|
||||||
},
|
},
|
||||||
"time": "2022-06-03T18:03:27+00:00"
|
"time": "2022-06-03T18:03:27+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "zircote/swagger-php",
|
||||||
|
"version": "5.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/zircote/swagger-php.git",
|
||||||
|
"reference": "a9b953c25f5bd11ea0542636936de04504496bd9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/a9b953c25f5bd11ea0542636936de04504496bd9",
|
||||||
|
"reference": "a9b953c25f5bd11ea0542636936de04504496bd9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-json": "*",
|
||||||
|
"nikic/php-parser": "^4.19 || ^5.0",
|
||||||
|
"php": ">=7.4",
|
||||||
|
"psr/log": "^1.1 || ^2.0 || ^3.0",
|
||||||
|
"symfony/deprecation-contracts": "^2 || ^3",
|
||||||
|
"symfony/finder": "^5.0 || ^6.0 || ^7.0",
|
||||||
|
"symfony/yaml": "^5.0 || ^6.0 || ^7.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/process": ">=6, <6.4.14"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"composer/package-versions-deprecated": "^1.11",
|
||||||
|
"doctrine/annotations": "^2.0",
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.62.0",
|
||||||
|
"phpstan/phpstan": "^1.6 || ^2.0",
|
||||||
|
"phpunit/phpunit": "^9.0",
|
||||||
|
"rector/rector": "^1.0 || ^2.0",
|
||||||
|
"vimeo/psalm": "^4.30 || ^5.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"doctrine/annotations": "^2.0"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"bin/openapi"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "5.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"OpenApi\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"Apache-2.0"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Robert Allen",
|
||||||
|
"email": "zircote@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bob Fanger",
|
||||||
|
"email": "bfanger@gmail.com",
|
||||||
|
"homepage": "https://bfanger.nl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Martin Rademacher",
|
||||||
|
"email": "mano@radebatz.net",
|
||||||
|
"homepage": "https://radebatz.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Generate interactive documentation for your RESTful API using PHP attributes (preferred) or PHPDoc annotations",
|
||||||
|
"homepage": "https://github.com/zircote/swagger-php",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"json",
|
||||||
|
"rest",
|
||||||
|
"service discovery"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/zircote/swagger-php/issues",
|
||||||
|
"source": "https://github.com/zircote/swagger-php/tree/5.1.0"
|
||||||
|
},
|
||||||
|
"time": "2025-04-18T00:35:12+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
@ -9908,78 +10333,6 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-10-20T05:08:20+00:00"
|
"time": "2024-10-20T05:08:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "symfony/yaml",
|
|
||||||
"version": "v7.2.5",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/yaml.git",
|
|
||||||
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
|
||||||
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=8.2",
|
|
||||||
"symfony/deprecation-contracts": "^2.5|^3.0",
|
|
||||||
"symfony/polyfill-ctype": "^1.8"
|
|
||||||
},
|
|
||||||
"conflict": {
|
|
||||||
"symfony/console": "<6.4"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"symfony/console": "^6.4|^7.0"
|
|
||||||
},
|
|
||||||
"bin": [
|
|
||||||
"Resources/bin/yaml-lint"
|
|
||||||
],
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Symfony\\Component\\Yaml\\": ""
|
|
||||||
},
|
|
||||||
"exclude-from-classmap": [
|
|
||||||
"/Tests/"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Fabien Potencier",
|
|
||||||
"email": "fabien@symfony.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "https://symfony.com/contributors"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Loads and dumps YAML files",
|
|
||||||
"homepage": "https://symfony.com",
|
|
||||||
"support": {
|
|
||||||
"source": "https://github.com/symfony/yaml/tree/v7.2.5"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://symfony.com/sponsor",
|
|
||||||
"type": "custom"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://github.com/fabpot",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
|
||||||
"type": "tidelift"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2025-03-03T07:12:39+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "ta-tikoma/phpunit-architecture-test",
|
"name": "ta-tikoma/phpunit-architecture-test",
|
||||||
"version": "0.8.4",
|
"version": "0.8.4",
|
||||||
|
|||||||
318
API/JWT/config/l5-swagger.php
Normal file
318
API/JWT/config/l5-swagger.php
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'default' => 'default',
|
||||||
|
'documentations' => [
|
||||||
|
'default' => [
|
||||||
|
'api' => [
|
||||||
|
'title' => 'L5 Swagger UI',
|
||||||
|
],
|
||||||
|
|
||||||
|
'routes' => [
|
||||||
|
/*
|
||||||
|
* Route for accessing api documentation interface
|
||||||
|
*/
|
||||||
|
'api' => 'api/documentation',
|
||||||
|
],
|
||||||
|
'paths' => [
|
||||||
|
/*
|
||||||
|
* Edit to include full URL in ui for assets
|
||||||
|
*/
|
||||||
|
'use_absolute_path' => env('L5_SWAGGER_USE_ABSOLUTE_PATH', true),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edit to set path where swagger ui assets should be stored
|
||||||
|
*/
|
||||||
|
'swagger_ui_assets_path' => env('L5_SWAGGER_UI_ASSETS_PATH', 'vendor/swagger-api/swagger-ui/dist/'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File name of the generated json documentation file
|
||||||
|
*/
|
||||||
|
'docs_json' => 'api-docs.json',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File name of the generated YAML documentation file
|
||||||
|
*/
|
||||||
|
'docs_yaml' => 'api-docs.yaml',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set this to `json` or `yaml` to determine which documentation file to use in UI
|
||||||
|
*/
|
||||||
|
'format_to_use_for_docs' => env('L5_FORMAT_TO_USE_FOR_DOCS', 'json'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute paths to directory containing the swagger annotations are stored.
|
||||||
|
*/
|
||||||
|
'annotations' => [
|
||||||
|
base_path('app'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'defaults' => [
|
||||||
|
'routes' => [
|
||||||
|
/*
|
||||||
|
* Route for accessing parsed swagger annotations.
|
||||||
|
*/
|
||||||
|
'docs' => 'docs',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Route for Oauth2 authentication callback.
|
||||||
|
*/
|
||||||
|
'oauth2_callback' => 'api/oauth2-callback',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Middleware allows to prevent unexpected access to API documentation
|
||||||
|
*/
|
||||||
|
'middleware' => [
|
||||||
|
'api' => [],
|
||||||
|
'asset' => [],
|
||||||
|
'docs' => [],
|
||||||
|
'oauth2_callback' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Route Group options
|
||||||
|
*/
|
||||||
|
'group_options' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
'paths' => [
|
||||||
|
/*
|
||||||
|
* Absolute path to location where parsed annotations will be stored
|
||||||
|
*/
|
||||||
|
'docs' => storage_path('api-docs'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute path to directory where to export views
|
||||||
|
*/
|
||||||
|
'views' => base_path('resources/views/vendor/l5-swagger'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edit to set the api's base path
|
||||||
|
*/
|
||||||
|
'base' => env('L5_SWAGGER_BASE_PATH', null),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute path to directories that should be excluded from scanning
|
||||||
|
* @deprecated Please use `scanOptions.exclude`
|
||||||
|
* `scanOptions.exclude` overwrites this
|
||||||
|
*/
|
||||||
|
'excludes' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
'scanOptions' => [
|
||||||
|
/**
|
||||||
|
* Configuration for default processors. Allows to pass processors configuration to swagger-php.
|
||||||
|
*
|
||||||
|
* @link https://zircote.github.io/swagger-php/reference/processors.html
|
||||||
|
*/
|
||||||
|
'default_processors_configuration' => [
|
||||||
|
/** Example */
|
||||||
|
/**
|
||||||
|
* 'operationId.hash' => true,
|
||||||
|
* 'pathFilter' => [
|
||||||
|
* 'tags' => [
|
||||||
|
* '/pets/',
|
||||||
|
* '/store/',
|
||||||
|
* ],
|
||||||
|
* ],.
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* analyser: defaults to \OpenApi\StaticAnalyser .
|
||||||
|
*
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'analyser' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* analysis: defaults to a new \OpenApi\Analysis .
|
||||||
|
*
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'analysis' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom query path processors classes.
|
||||||
|
*
|
||||||
|
* @link https://github.com/zircote/swagger-php/tree/master/Examples/processors/schema-query-parameter
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'processors' => [
|
||||||
|
// new \App\SwaggerProcessors\SchemaQueryParameter(),
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pattern: string $pattern File pattern(s) to scan (default: *.php) .
|
||||||
|
*
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'pattern' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute path to directories that should be excluded from scanning
|
||||||
|
* @note This option overwrites `paths.excludes`
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'exclude' => [],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allows to generate specs either for OpenAPI 3.0.0 or OpenAPI 3.1.0.
|
||||||
|
* By default the spec will be in version 3.0.0
|
||||||
|
*/
|
||||||
|
'open_api_spec_version' => env('L5_SWAGGER_OPEN_API_SPEC_VERSION', \L5Swagger\Generator::OPEN_API_DEFAULT_SPEC_VERSION),
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* API security definitions. Will be generated into documentation file.
|
||||||
|
*/
|
||||||
|
'securityDefinitions' => [
|
||||||
|
'securitySchemes' => [
|
||||||
|
/*
|
||||||
|
* Examples of Security schemes
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
'api_key_security_example' => [ // Unique name of security
|
||||||
|
'type' => 'apiKey', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'A short description for security scheme',
|
||||||
|
'name' => 'api_key', // The name of the header or query parameter to be used.
|
||||||
|
'in' => 'header', // The location of the API key. Valid values are "query" or "header".
|
||||||
|
],
|
||||||
|
'oauth2_security_example' => [ // Unique name of security
|
||||||
|
'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'A short description for oauth2 security scheme.',
|
||||||
|
'flow' => 'implicit', // The flow used by the OAuth2 security scheme. Valid values are "implicit", "password", "application" or "accessCode".
|
||||||
|
'authorizationUrl' => 'http://example.com/auth', // The authorization URL to be used for (implicit/accessCode)
|
||||||
|
//'tokenUrl' => 'http://example.com/auth' // The authorization URL to be used for (password/application/accessCode)
|
||||||
|
'scopes' => [
|
||||||
|
'read:projects' => 'read your projects',
|
||||||
|
'write:projects' => 'modify projects in your account',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Open API 3.0 support
|
||||||
|
'passport' => [ // Unique name of security
|
||||||
|
'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'Laravel passport oauth2 security.',
|
||||||
|
'in' => 'header',
|
||||||
|
'scheme' => 'https',
|
||||||
|
'flows' => [
|
||||||
|
"password" => [
|
||||||
|
"authorizationUrl" => config('app.url') . '/oauth/authorize',
|
||||||
|
"tokenUrl" => config('app.url') . '/oauth/token',
|
||||||
|
"refreshUrl" => config('app.url') . '/token/refresh',
|
||||||
|
"scopes" => []
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'sanctum' => [ // Unique name of security
|
||||||
|
'type' => 'apiKey', // Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'Enter token in format (Bearer <token>)',
|
||||||
|
'name' => 'Authorization', // The name of the header or query parameter to be used.
|
||||||
|
'in' => 'header', // The location of the API key. Valid values are "query" or "header".
|
||||||
|
],
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
'security' => [
|
||||||
|
/*
|
||||||
|
* Examples of Securities
|
||||||
|
*/
|
||||||
|
[
|
||||||
|
/*
|
||||||
|
'oauth2_security_example' => [
|
||||||
|
'read',
|
||||||
|
'write'
|
||||||
|
],
|
||||||
|
|
||||||
|
'passport' => []
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set this to `true` in development mode so that docs would be regenerated on each request
|
||||||
|
* Set this to `false` to disable swagger generation on production
|
||||||
|
*/
|
||||||
|
'generate_always' => env('L5_SWAGGER_GENERATE_ALWAYS', false),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set this to `true` to generate a copy of documentation in yaml format
|
||||||
|
*/
|
||||||
|
'generate_yaml_copy' => env('L5_SWAGGER_GENERATE_YAML_COPY', false),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edit to trust the proxy's ip address - needed for AWS Load Balancer
|
||||||
|
* string[]
|
||||||
|
*/
|
||||||
|
'proxy' => false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configs plugin allows to fetch external configs instead of passing them to SwaggerUIBundle.
|
||||||
|
* See more at: https://github.com/swagger-api/swagger-ui#configs-plugin
|
||||||
|
*/
|
||||||
|
'additional_config_url' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically),
|
||||||
|
* 'method' (sort by HTTP method).
|
||||||
|
* Default is the order returned by the server unchanged.
|
||||||
|
*/
|
||||||
|
'operations_sort' => env('L5_SWAGGER_OPERATIONS_SORT', null),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pass the validatorUrl parameter to SwaggerUi init on the JS side.
|
||||||
|
* A null value here disables validation.
|
||||||
|
*/
|
||||||
|
'validator_url' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Swagger UI configuration parameters
|
||||||
|
*/
|
||||||
|
'ui' => [
|
||||||
|
'display' => [
|
||||||
|
'dark_mode' => env('L5_SWAGGER_UI_DARK_MODE', false),
|
||||||
|
/*
|
||||||
|
* Controls the default expansion setting for the operations and tags. It can be :
|
||||||
|
* 'list' (expands only the tags),
|
||||||
|
* 'full' (expands the tags and operations),
|
||||||
|
* 'none' (expands nothing).
|
||||||
|
*/
|
||||||
|
'doc_expansion' => env('L5_SWAGGER_UI_DOC_EXPANSION', 'none'),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set, enables filtering. The top bar will show an edit box that
|
||||||
|
* you can use to filter the tagged operations that are shown. Can be
|
||||||
|
* Boolean to enable or disable, or a string, in which case filtering
|
||||||
|
* will be enabled using that string as the filter expression. Filtering
|
||||||
|
* is case-sensitive matching the filter expression anywhere inside
|
||||||
|
* the tag.
|
||||||
|
*/
|
||||||
|
'filter' => env('L5_SWAGGER_UI_FILTERS', true), // true | false
|
||||||
|
],
|
||||||
|
|
||||||
|
'authorization' => [
|
||||||
|
/*
|
||||||
|
* If set to true, it persists authorization data, and it would not be lost on browser close/refresh
|
||||||
|
*/
|
||||||
|
'persist_authorization' => env('L5_SWAGGER_UI_PERSIST_AUTHORIZATION', false),
|
||||||
|
|
||||||
|
'oauth2' => [
|
||||||
|
/*
|
||||||
|
* If set to true, adds PKCE to AuthorizationCodeGrant flow
|
||||||
|
*/
|
||||||
|
'use_pkce_with_authorization_code_grant' => false,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
/*
|
||||||
|
* Constants which can be used in annotations
|
||||||
|
*/
|
||||||
|
'constants' => [
|
||||||
|
'L5_SWAGGER_CONST_HOST' => env('L5_SWAGGER_CONST_HOST', 'http://my-default-host.com'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
0
API/JWT/resources/views/vendor/l5-swagger/.gitkeep
vendored
Normal file
0
API/JWT/resources/views/vendor/l5-swagger/.gitkeep
vendored
Normal file
174
API/JWT/resources/views/vendor/l5-swagger/index.blade.php
vendored
Normal file
174
API/JWT/resources/views/vendor/l5-swagger/index.blade.php
vendored
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{{ $documentationTitle }}</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ l5_swagger_asset($documentation, 'swagger-ui.css') }}">
|
||||||
|
<link rel="icon" type="image/png" href="{{ l5_swagger_asset($documentation, 'favicon-32x32.png') }}" sizes="32x32"/>
|
||||||
|
<link rel="icon" type="image/png" href="{{ l5_swagger_asset($documentation, 'favicon-16x16.png') }}" sizes="16x16"/>
|
||||||
|
<style>
|
||||||
|
html
|
||||||
|
{
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: -moz-scrollbars-vertical;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after
|
||||||
|
{
|
||||||
|
box-sizing: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin:0;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@if(config('l5-swagger.defaults.ui.display.dark_mode'))
|
||||||
|
<style>
|
||||||
|
body#dark-mode,
|
||||||
|
#dark-mode .scheme-container {
|
||||||
|
background: #1b1b1b;
|
||||||
|
}
|
||||||
|
#dark-mode .scheme-container,
|
||||||
|
#dark-mode .opblock .opblock-section-header{
|
||||||
|
box-shadow: 0 1px 2px 0 rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
#dark-mode .operation-filter-input,
|
||||||
|
#dark-mode .dialog-ux .modal-ux,
|
||||||
|
#dark-mode input[type=email],
|
||||||
|
#dark-mode input[type=file],
|
||||||
|
#dark-mode input[type=password],
|
||||||
|
#dark-mode input[type=search],
|
||||||
|
#dark-mode input[type=text],
|
||||||
|
#dark-mode textarea{
|
||||||
|
background: #343434;
|
||||||
|
color: #e7e7e7;
|
||||||
|
}
|
||||||
|
#dark-mode .title,
|
||||||
|
#dark-mode li,
|
||||||
|
#dark-mode p,
|
||||||
|
#dark-mode table,
|
||||||
|
#dark-mode label,
|
||||||
|
#dark-mode .opblock-tag,
|
||||||
|
#dark-mode .opblock .opblock-summary-operation-id,
|
||||||
|
#dark-mode .opblock .opblock-summary-path,
|
||||||
|
#dark-mode .opblock .opblock-summary-path__deprecated,
|
||||||
|
#dark-mode h1,
|
||||||
|
#dark-mode h2,
|
||||||
|
#dark-mode h3,
|
||||||
|
#dark-mode h4,
|
||||||
|
#dark-mode h5,
|
||||||
|
#dark-mode .btn,
|
||||||
|
#dark-mode .tab li,
|
||||||
|
#dark-mode .parameter__name,
|
||||||
|
#dark-mode .parameter__type,
|
||||||
|
#dark-mode .prop-format,
|
||||||
|
#dark-mode .loading-container .loading:after{
|
||||||
|
color: #e7e7e7;
|
||||||
|
}
|
||||||
|
#dark-mode .opblock-description-wrapper p,
|
||||||
|
#dark-mode .opblock-external-docs-wrapper p,
|
||||||
|
#dark-mode .opblock-title_normal p,
|
||||||
|
#dark-mode .response-col_status,
|
||||||
|
#dark-mode table thead tr td,
|
||||||
|
#dark-mode table thead tr th,
|
||||||
|
#dark-mode .response-col_links,
|
||||||
|
#dark-mode .swagger-ui{
|
||||||
|
color: wheat;
|
||||||
|
}
|
||||||
|
#dark-mode .parameter__extension,
|
||||||
|
#dark-mode .parameter__in,
|
||||||
|
#dark-mode .model-title{
|
||||||
|
color: #949494;
|
||||||
|
}
|
||||||
|
#dark-mode table thead tr td,
|
||||||
|
#dark-mode table thead tr th{
|
||||||
|
border-color: rgba(120,120,120,.2);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock .opblock-section-header{
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-post{
|
||||||
|
background: rgba(73,204,144,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-get{
|
||||||
|
background: rgba(97,175,254,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-put{
|
||||||
|
background: rgba(252,161,48,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-delete{
|
||||||
|
background: rgba(249,62,62,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .loading-container .loading:before{
|
||||||
|
border-color: rgba(255,255,255,10%);
|
||||||
|
border-top-color: rgba(255,255,255,.6);
|
||||||
|
}
|
||||||
|
#dark-mode svg:not(:root){
|
||||||
|
fill: #e7e7e7;
|
||||||
|
}
|
||||||
|
#dark-mode .opblock-summary-description {
|
||||||
|
color: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@endif
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body @if(config('l5-swagger.defaults.ui.display.dark_mode')) id="dark-mode" @endif>
|
||||||
|
<div id="swagger-ui"></div>
|
||||||
|
|
||||||
|
<script src="{{ l5_swagger_asset($documentation, 'swagger-ui-bundle.js') }}"></script>
|
||||||
|
<script src="{{ l5_swagger_asset($documentation, 'swagger-ui-standalone-preset.js') }}"></script>
|
||||||
|
<script>
|
||||||
|
window.onload = function() {
|
||||||
|
const urls = [];
|
||||||
|
|
||||||
|
@foreach($urlsToDocs as $title => $url)
|
||||||
|
urls.push({name: "{{ $title }}", url: "{{ $url }}"});
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
// Build a system
|
||||||
|
const ui = SwaggerUIBundle({
|
||||||
|
dom_id: '#swagger-ui',
|
||||||
|
urls: urls,
|
||||||
|
"urls.primaryName": "{{ $documentationTitle }}",
|
||||||
|
operationsSorter: {!! isset($operationsSorter) ? '"' . $operationsSorter . '"' : 'null' !!},
|
||||||
|
configUrl: {!! isset($configUrl) ? '"' . $configUrl . '"' : 'null' !!},
|
||||||
|
validatorUrl: {!! isset($validatorUrl) ? '"' . $validatorUrl . '"' : 'null' !!},
|
||||||
|
oauth2RedirectUrl: "{{ route('l5-swagger.'.$documentation.'.oauth2_callback', [], $useAbsolutePath) }}",
|
||||||
|
|
||||||
|
requestInterceptor: function(request) {
|
||||||
|
request.headers['X-CSRF-TOKEN'] = '{{ csrf_token() }}';
|
||||||
|
return request;
|
||||||
|
},
|
||||||
|
|
||||||
|
presets: [
|
||||||
|
SwaggerUIBundle.presets.apis,
|
||||||
|
SwaggerUIStandalonePreset
|
||||||
|
],
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
SwaggerUIBundle.plugins.DownloadUrl
|
||||||
|
],
|
||||||
|
|
||||||
|
layout: "StandaloneLayout",
|
||||||
|
docExpansion : "{!! config('l5-swagger.defaults.ui.display.doc_expansion', 'none') !!}",
|
||||||
|
deepLinking: true,
|
||||||
|
filter: {!! config('l5-swagger.defaults.ui.display.filter') ? 'true' : 'false' !!},
|
||||||
|
persistAuthorization: "{!! config('l5-swagger.defaults.ui.authorization.persist_authorization') ? 'true' : 'false' !!}",
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
window.ui = ui
|
||||||
|
|
||||||
|
@if(in_array('oauth2', array_column(config('l5-swagger.defaults.securityDefinitions.securitySchemes'), 'type')))
|
||||||
|
ui.initOAuth({
|
||||||
|
usePkceWithAuthorizationCodeGrant: "{!! (bool)config('l5-swagger.defaults.ui.authorization.oauth2.use_pkce_with_authorization_code_grant') !!}"
|
||||||
|
})
|
||||||
|
@endif
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -20,7 +20,7 @@ Route::post('login', [LoginController::class, 'login'])->name('login');
|
|||||||
|
|
||||||
Route::group(['middleware' => 'auth:api'], function () {
|
Route::group(['middleware' => 'auth:api'], function () {
|
||||||
Route::post('logout', [LogoutController::class, 'logout'])->name('logout');
|
Route::post('logout', [LogoutController::class, 'logout'])->name('logout');
|
||||||
Route::post('deleteAcconut', [DeleteAccountController::class, 'deleteAcconut'])->name('delete.acconut');
|
Route::delete('deleteAcconut', [DeleteAccountController::class, 'deleteAcconut'])->name('delete.acconut');
|
||||||
|
|
||||||
//email verification
|
//email verification
|
||||||
Route::post('/email/verification-notification', [SendMailNotificationController::class, 'mailNotification'])->name('mail.notification');
|
Route::post('/email/verification-notification', [SendMailNotificationController::class, 'mailNotification'])->name('mail.notification');
|
||||||
|
|||||||
694
API/JWT/storage/api-docs/api-docs.json
Normal file
694
API/JWT/storage/api-docs/api-docs.json
Normal file
@ -0,0 +1,694 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.0.0",
|
||||||
|
"info": {
|
||||||
|
"title": "API Documentation",
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"/api/deleteAcconut": {
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "Delete user account",
|
||||||
|
"description": "Deletes the currently authenticated user's account and invalidates the JWT token.",
|
||||||
|
"operationId": "4cf0edfc2e1177da97815505b73e16e0",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Account deleted successfully",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Your account has been deleted successfully. We’re sorry to see you go."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Account deletion failed",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We couldn’t delete your account at this moment. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearerAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/login": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "User login",
|
||||||
|
"description": "Logs in a user and returns a JWT token if credentials are correct.",
|
||||||
|
"operationId": "e3ce052cc00fd9dd647e77abd7807e14",
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"email",
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "12345678"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Login successful",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Login successful. Welcome back!"
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Nima Malakooti"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Bearer eyJ0eXAiOiJKV1QiLCJhbGci..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized access",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Unauthorized access. Please check your credentials and try again."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Failed to login",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Failed to login user. Please try again later."
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message here"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/logout": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "Logout user",
|
||||||
|
"description": "Logs out the currently authenticated user by invalidating the JWT token.",
|
||||||
|
"operationId": "ad0ae046131d33ce33ee57a7f8a6a3f0",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Logout successful",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "You have been logged out successfully. Come back soon!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Logout failed",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Oops! Something went wrong while logging out. Please try again later."
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearerAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/email/verification-notification": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "Send verification email",
|
||||||
|
"description": "Sends a verification email to the authenticated user.",
|
||||||
|
"operationId": "379b3fb09eb88cee77701aff98e2ee2b",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Verification email sent",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Please check your email for the verification link."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Error while sending email",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We encountered an issue while sending the verification email. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearerAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/email/verify/{id}/{hash}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "Verify user email",
|
||||||
|
"description": "Verifies the user's email using the verification link.",
|
||||||
|
"operationId": "ddc92b84a9a7691538056ed633a285a6",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"description": "User ID",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hash",
|
||||||
|
"in": "path",
|
||||||
|
"description": "Email verification hash",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "9e4f889aabbc..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Email verified successfully",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Your email has been successfully verified. Thank you!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Verification failed",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Your verification link was found, but something went wrong during the confirmation process. Please try again or request a new verification email."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/forgot-password": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "Send password reset link",
|
||||||
|
"description": "Sends a password reset link to the user's email address.",
|
||||||
|
"operationId": "ce31c7b7aa42b76f9e462c54075c43aa",
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"email"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Password reset link sent or email not found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We’ve emailed you the password reset link. Please check your inbox!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Failed to send password reset email",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We couldn’t send the password reset email due to an error. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/reset-password": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "Reset the user's password",
|
||||||
|
"description": "Resets the password for the user using the provided token and new password.",
|
||||||
|
"operationId": "8e8229015b36555c6ad9564278a79929",
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"email",
|
||||||
|
"password",
|
||||||
|
"password_confirmation",
|
||||||
|
"token"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "12345678"
|
||||||
|
},
|
||||||
|
"password_confirmation": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "12345678"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "valid-reset-token-here"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Password reset successfully",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Your password has been reset!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid token or mismatched password confirmation",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "This password reset token is invalid."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal server error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We couldn’t process the request due to an error. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/register": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "Register a new user",
|
||||||
|
"description": "Registers a user and returns a JWT token.",
|
||||||
|
"operationId": "registerUser",
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"email",
|
||||||
|
"password",
|
||||||
|
"password_confirmation"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Nima Malakooti"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "12345678"
|
||||||
|
},
|
||||||
|
"password_confirmation": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "12345678"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful registration",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "User registered successfully."
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Nima Malakooti"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Bearer eyJ0eXAiOiJKV1..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Registration failed",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Failed to register user. Please try again later."
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Detailed error message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"name": "Authentication",
|
||||||
|
"description": "Authentication"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
APP_NAME=Laravel
|
APP_NAME=Laravel
|
||||||
APP_ENV=local
|
APP_ENV=local
|
||||||
APP_KEY=
|
APP_KEY=base64:V6i/TCdmhvicg+00BFlIr9I1KyvdBdcpbiLjhDMB2mM=
|
||||||
APP_DEBUG=true
|
APP_DEBUG=true
|
||||||
APP_URL=http://localhost
|
APP_URL=http://localhost
|
||||||
|
|
||||||
@ -47,19 +47,21 @@ REDIS_HOST=127.0.0.1
|
|||||||
REDIS_PASSWORD=null
|
REDIS_PASSWORD=null
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
|
|
||||||
MAIL_MAILER=log
|
MAIL_MAILER=mailersend
|
||||||
MAIL_SCHEME=null
|
MAIL_SCHEME=null
|
||||||
MAIL_HOST=127.0.0.1
|
MAIL_HOST=smtp.mailersend.net
|
||||||
MAIL_PORT=2525
|
MAIL_PORT=2525
|
||||||
MAIL_USERNAME=null
|
MAIL_USERNAME=MS_FAoqjp@test-r9084zvr718gw63d.mlsender.net
|
||||||
MAIL_PASSWORD=null
|
MAIL_PASSWORD=mssp.CsCr6Yq.0r83ql3okymlzw1j.Jx1ydT6
|
||||||
MAIL_FROM_ADDRESS="hello@example.com"
|
MAIL_FROM_ADDRESS="AuthenticationApp@test-r9084zvr718gw63d.mlsender.net"
|
||||||
MAIL_FROM_NAME="${APP_NAME}"
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
MAILERSEND_API_KEY=mlsn.0e9fb98df3973571533bb560b9f315f9a71543db47234108595e0b32366ca19d
|
||||||
|
|
||||||
AWS_ACCESS_KEY_ID=
|
AWS_ACCESS_KEY_ID=
|
||||||
AWS_SECRET_ACCESS_KEY=
|
AWS_SECRET_ACCESS_KEY=
|
||||||
AWS_DEFAULT_REGION=us-east-1
|
AWS_DEFAULT_REGION=us-east-1
|
||||||
AWS_BUCKET=
|
AWS_BUCKET=
|
||||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||||
|
|
||||||
VITE_APP_NAME="${APP_NAME}"
|
VITE_APP_NAME="${APP_NAME}"
|
||||||
338
API/Passport/Laravel Passport.postman_collection.json
Normal file
338
API/Passport/Laravel Passport.postman_collection.json
Normal file
@ -0,0 +1,338 @@
|
|||||||
|
{
|
||||||
|
"info": {
|
||||||
|
"_postman_id": "9aa6f0d5-b395-476e-b3fb-5c6de9f9bb6f",
|
||||||
|
"name": "Laravel Passport",
|
||||||
|
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||||
|
"_exporter_id": "26260450"
|
||||||
|
},
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "register",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "noauth"
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"name\":\"nima\",\n \"email\":\"nima@yahoo.com\",\n \"password\":\"12345678\",\n \"password_confirmation\":\"12345678\"\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/register",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"register"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "login",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "noauth"
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"email\":\"nima@yahoo.com\",\n \"password\":\"12345678\"\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/login",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"login"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "logout",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "bearer",
|
||||||
|
"bearer": [
|
||||||
|
{
|
||||||
|
"key": "token",
|
||||||
|
"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI5ZWJlZTVjNS0zNzI5LTRkMWItOTFjZC01ZjUzM2JiNDgzMWEiLCJqdGkiOiJhM2VkNjg2ODBjYzQyMTI2NWU5NTk5YTM4MzVjNGEwYzc5MzM0YTY1Yjc4MmI4ZGQ5ZmVkYThhNmRhN2M2Y2UyMDFlOThmOGEzNmY4MGY2OSIsImlhdCI6MTc0NTQyNzQ4My4xODAzNjgsIm5iZiI6MTc0NTQyNzQ4My4xODAzNywiZXhwIjoxNzc2OTYzNDgzLjE3OTEwMywic3ViIjoiMiIsInNjb3BlcyI6W119.jqA7XFOEt9bYnDOYEZtbObz6leTjiu7GMVheg6whuEIBqbwwP38HK20mJWjKIc9Ay05oxyBaUtJN85GMN4KSrj7EjU5ECjUSYie60sQyBijylebdjXqdcKtzCH3Fj0pWrB4xhnzhv2DPf8Z2-7qLF-tzcT0zlajdc1wFF-tu0ZGHBBKSnrPewQ5facitX_xWY9_lj9kY4dhVjLumyrTAt5czocq4cQwkQBAs5Sgo6MUtSvc47b5NqWn-fBFO5bR1T5o51UnjZD9_KJOxNMfdvGoLCDWBI4RB2guhR4yGpswwJIziajXjYKPYcJAIz87nPk-E1w8pngYDMV9-9yFGdIrV82lMtJh_igQyZCtyB9I9Si2z0EDffOKCIP3dkTiQ7ps9cS9ILws2c93vhRK8DGSuFupriOq9XCxhV4jeIf0cdrxFvXlf-ctyMqe7sqnes1p90qQhEm0KWySAOWMsovcsbswtP6yxbqLAowrz8EUhveU7cAJQxiOP-5Qkr3feQuH_x_PY_9YnGmPkXGy_B9GMdSMtkbvzaA0LRACpXNvsjFFETyvtL0CKVE21r44SCB7B7xPLYBcONk-Pak7RvNTCKfs77kJcj3bO-8nYocVVP4v79wybkoqOl3c1RTjO3Bz8sDkSI3-e2CxF4x6lfSTEa8J-C0Et6jCJLyrYSXE",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/logout",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"logout"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Send Mail Notification",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "bearer",
|
||||||
|
"bearer": [
|
||||||
|
{
|
||||||
|
"key": "token",
|
||||||
|
"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI5ZWJlZTVjNS0zNzI5LTRkMWItOTFjZC01ZjUzM2JiNDgzMWEiLCJqdGkiOiJjMWRmOTAyMWM5NzJjOWY2YWU3NGMyZDdjZWM0Y2U0MzNhZjlmYjkwNjQwZWMwZGJlODY3MDBkMTVjMjM3YTg1ZGUyNWM1YzNmODgxNGZjNCIsImlhdCI6MTc0NTQyODI0Mi4xNjU0NCwibmJmIjoxNzQ1NDI4MjQyLjE2NTQ0MiwiZXhwIjoxNzc2OTY0MjQyLjE1OTM5OCwic3ViIjoiMiIsInNjb3BlcyI6W119.eqJd1MK8zi0k40H7wlJBWvD_F36YgmnISqm8GQmb1cMoTmB4jzMbhamOR-igmsfXQPRmKYhe9BNcvOauLC4LbwNryR2eyKXa6kIKVB42G8RHi6i8wi-CinYxA_vV7L3VFLRFpOxql_GBk5XAcmhO80zlCXMh5hi1IITDbsnM4HKWRCGr8hUxzA4sWeNGNEFnxuYPAGClsrI7ncgaqH6nDCr-TwTE0GltEZiB9fpMjGPTgYwgtNc2ydii4suOkAW0JO6g0OfuRqi2HFJ7MdfBjxoIHTtHdrx4_QiqOAb1mrrv8ICPJiP7DudAIHPHvh7fU9BnvpReH3KjUevymrFoGynpp7FEtS6x3d5yP-KoRULgWo0fwlwVgC9sVzjrvUx0lAkomtyScPOLGvVBl6w0pi2yR_WpM3JV8T-BDAJrBJ6g82lwoi2Qucw0-pql2-qwZAubam4LHTDI74Lo648BWtNqep3-0_pZgQltPTbYdNRdFNC7U-OnsCejWl90M6nIfvVZ9GjoToLFe6dGMCARtj7v-rCq37M8QikS6HHBR0ywTlSYVjN87iyrNNJ0lSx99afAQYfL7-PTQieb0SiikONn1lmhmG4d_kwDgR3FB8_KsjNRyjNcM_1MRQV3sumOkzm0jEkpavaEYufeIPDoTAt2-0o8uPi0zg7EpqvpBYE",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/email/verification-notification",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"email",
|
||||||
|
"verification-notification"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Verify Mail",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "bearer",
|
||||||
|
"bearer": [
|
||||||
|
{
|
||||||
|
"key": "token",
|
||||||
|
"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI5ZWJlZTVjNS0zNzI5LTRkMWItOTFjZC01ZjUzM2JiNDgzMWEiLCJqdGkiOiJjMWRmOTAyMWM5NzJjOWY2YWU3NGMyZDdjZWM0Y2U0MzNhZjlmYjkwNjQwZWMwZGJlODY3MDBkMTVjMjM3YTg1ZGUyNWM1YzNmODgxNGZjNCIsImlhdCI6MTc0NTQyODI0Mi4xNjU0NCwibmJmIjoxNzQ1NDI4MjQyLjE2NTQ0MiwiZXhwIjoxNzc2OTY0MjQyLjE1OTM5OCwic3ViIjoiMiIsInNjb3BlcyI6W119.eqJd1MK8zi0k40H7wlJBWvD_F36YgmnISqm8GQmb1cMoTmB4jzMbhamOR-igmsfXQPRmKYhe9BNcvOauLC4LbwNryR2eyKXa6kIKVB42G8RHi6i8wi-CinYxA_vV7L3VFLRFpOxql_GBk5XAcmhO80zlCXMh5hi1IITDbsnM4HKWRCGr8hUxzA4sWeNGNEFnxuYPAGClsrI7ncgaqH6nDCr-TwTE0GltEZiB9fpMjGPTgYwgtNc2ydii4suOkAW0JO6g0OfuRqi2HFJ7MdfBjxoIHTtHdrx4_QiqOAb1mrrv8ICPJiP7DudAIHPHvh7fU9BnvpReH3KjUevymrFoGynpp7FEtS6x3d5yP-KoRULgWo0fwlwVgC9sVzjrvUx0lAkomtyScPOLGvVBl6w0pi2yR_WpM3JV8T-BDAJrBJ6g82lwoi2Qucw0-pql2-qwZAubam4LHTDI74Lo648BWtNqep3-0_pZgQltPTbYdNRdFNC7U-OnsCejWl90M6nIfvVZ9GjoToLFe6dGMCARtj7v-rCq37M8QikS6HHBR0ywTlSYVjN87iyrNNJ0lSx99afAQYfL7-PTQieb0SiikONn1lmhmG4d_kwDgR3FB8_KsjNRyjNcM_1MRQV3sumOkzm0jEkpavaEYufeIPDoTAt2-0o8uPi0zg7EpqvpBYE",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/email/verify/2/a410347aabe0039597cb405f771f043d411e4167?expires=1745431850&signature=23fbb6d834d136765894fe4b0f8a19fbfd78bbe6316c0955e7285f88b66dc64c",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"email",
|
||||||
|
"verify",
|
||||||
|
"2",
|
||||||
|
"a410347aabe0039597cb405f771f043d411e4167"
|
||||||
|
],
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"key": "expires",
|
||||||
|
"value": "1745431850"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "signature",
|
||||||
|
"value": "23fbb6d834d136765894fe4b0f8a19fbfd78bbe6316c0955e7285f88b66dc64c"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Delete Account",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "bearer",
|
||||||
|
"bearer": [
|
||||||
|
{
|
||||||
|
"key": "token",
|
||||||
|
"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI5ZWJlZTVjNS0zNzI5LTRkMWItOTFjZC01ZjUzM2JiNDgzMWEiLCJqdGkiOiIyMTQ4ZTI0MmIxMDExMmU3Y2I5ZGNhYzJkYWJkODI5MTMzOWM3YzcyNWQzMTQ1M2EwZWJmODc4NTdhODc4MWZhMWRiNDdiOTk3OWY1MTBjYSIsImlhdCI6MTc0NTQyODkyNi4wODMwNzUsIm5iZiI6MTc0NTQyODkyNi4wODMwNzcsImV4cCI6MTc3Njk2NDkyNi4wODIxMTQsInN1YiI6IjMiLCJzY29wZXMiOltdfQ.uXxWBB00s7quUbiCBV7btvIL2CCCAjwUtWYTWJncHKmD-DkJB0GfDmGX3-aM6RmuRjk073Vb8bXoUSlTEJK92XA39e1XA5YDkcF9ZTsmhmrq_rJstN3ZkB5GVg8Wlxlars8bRff3QrkGPP_pzY0ziGwJZbb-hCSzitQcu5kRuxpWSfDZ_5DMHGaah1e5rV4XtB5LYJu2ESLKM1zQhAkbU8m5WD2YgbgUxmxtzUlLtD21EqlLqTabuhi3NP0mv-Sp3VlFKRF_cgRJMSgscg3j2zzVnziTytU55qL3P0IAqAi0Wpgxzs9IQV85Ibq6niNlYgiYdHzLx4yJqKD7WpOtnUIHiRO3CmaDL_LL--CTC3vqaKbjRFG5AYdub_P87yA0t44DVxZerOWfu0NklaoG9pQqE3VvrjDE1ABZUeHHPEULpPVucN6MG0cSEPnANhxY29VNrlaQUuojI1zgY61U-Qh-QZXbHwWJVrCLNu4hup98d5YCRHHqSflNij2o7zzo4MDdi7fWTNOD0Ox3rJ89Lve3E8t4YBNYDLlPTY4ukqkiSWdzsuDEDCn1aVnFnq8GLixMz3uAt_9ugRedvwfaN3lx4lyf-jLBSVERFbKReFAy-VcQj4ObkpXeTO631mlO0QyJZkadXyQo62F0JNAgRYvgFZLDHzk6JKpmaJUsej4",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"method": "DELETE",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/deleteAccount",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"deleteAccount"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Forgot Password",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "noauth"
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"email\":\"nima.8ak@gmail.com\"\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/forgot-password",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"forgot-password"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Reset Password",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "noauth"
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"token\":\"9bc7282d568dd8c3e1ab7b3036434cb7c9ce2872342febe07613016f3729b423\",\n \"email\":\"nima.8ak@gmail.com\",\n \"password\":\"09138014541\",\n \"password_confirmation\":\"09138014541\"\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/reset-password",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"reset-password"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -8,6 +8,33 @@ use Illuminate\Support\Facades\Auth;
|
|||||||
|
|
||||||
class DeleteAccountController extends Controller
|
class DeleteAccountController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Delete(
|
||||||
|
* path="/api/deleteAccount",
|
||||||
|
* summary="Delete user account",
|
||||||
|
* tags={"Auth"},
|
||||||
|
* security={
|
||||||
|
* {"passport": {}}
|
||||||
|
* },
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Account successfully deleted",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Your account has been deleted successfully. We’re sorry to see you go.")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Account deletion failed",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="We couldn’t delete your account at this moment. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception details here")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function deleteAccount(Request $request)
|
public function deleteAccount(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -8,6 +8,53 @@ use Illuminate\Support\Facades\Auth;
|
|||||||
|
|
||||||
class LoginController extends Controller
|
class LoginController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/login",
|
||||||
|
* summary="Login user and get access token",
|
||||||
|
* tags={"Auth"},
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* required=true,
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* required={"email", "password"},
|
||||||
|
* @OA\Property(property="email", type="string", format="email", example="nima@example.com"),
|
||||||
|
* @OA\Property(property="password", type="string", format="password", example="12345678")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Login successful",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Login successful. Welcome back!"),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="data",
|
||||||
|
* type="object",
|
||||||
|
* @OA\Property(property="name", type="string", example="Nima Malakooti"),
|
||||||
|
* @OA\Property(property="email", type="string", example="nima@example.com"),
|
||||||
|
* @OA\Property(property="token", type="string", example="access_token_string")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=401,
|
||||||
|
* description="Unauthorized access",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="message", type="string", example="Unauthorized access. Please check your credentials and try again.")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Login failed",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="Failed to login user. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Some internal error message...")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function login(LoginRequest $request)
|
public function login(LoginRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -7,6 +7,32 @@ use Illuminate\Http\Request;
|
|||||||
|
|
||||||
class LogoutController extends Controller
|
class LogoutController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/logout",
|
||||||
|
* summary="Logout the authenticated user",
|
||||||
|
* description="Revoke the access token of the currently authenticated user using Laravel Passport.",
|
||||||
|
* tags={"Auth"},
|
||||||
|
* security={{"passport": {}}},
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="User logged out successfully",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="You have been logged out successfully. Come back soon!")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Logout failed",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="Oops! Something went wrong while logging out. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Internal server error message here")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function logout(Request $request)
|
public function logout(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -7,6 +7,32 @@ use Illuminate\Http\Request;
|
|||||||
|
|
||||||
class SendMailNotificationController extends Controller
|
class SendMailNotificationController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/email/verification-notification",
|
||||||
|
* summary="Send email verification link",
|
||||||
|
* description="Sends a verification email to the authenticated user.",
|
||||||
|
* tags={"Auth"},
|
||||||
|
* security={{"passport": {}}},
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Verification email sent",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Please check your email for the verification link.")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Failed to send verification email",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="We encountered an issue while sending the verification email. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Some internal error here...")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function sendNotification(Request $request)
|
public function sendNotification(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -8,6 +8,41 @@ use Illuminate\Http\Request;
|
|||||||
|
|
||||||
class VerifyMailController extends Controller
|
class VerifyMailController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/email/verify",
|
||||||
|
* summary="Verify user email",
|
||||||
|
* tags={"Auth"},
|
||||||
|
* security={
|
||||||
|
* {"passport": {}}
|
||||||
|
* },
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* required=true,
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* required={"email", "verification_token"},
|
||||||
|
* @OA\Property(property="email", type="string", format="email", example="nima@example.com"),
|
||||||
|
* @OA\Property(property="verification_token", type="string", example="12345678")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Email successfully verified",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Your email has been successfully verified. Thank you!")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Verification failed",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="Your verification link was found, but something went wrong during the confirmation process. Please try again or request a new verification email."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception details here")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function verifyMail(EmailVerificationRequest $request)
|
public function verifyMail(EmailVerificationRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -13,6 +13,40 @@ use App\Http\Requests\ResetPasswordRequest;
|
|||||||
|
|
||||||
class ResetPasswordController extends Controller
|
class ResetPasswordController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/reset-password",
|
||||||
|
* summary="Reset user password using token",
|
||||||
|
* tags={"Auth"},
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* required=true,
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* required={"email", "password", "password_confirmation", "token"},
|
||||||
|
* @OA\Property(property="email", type="string", format="email", example="nima.8ak@gmail.com"),
|
||||||
|
* @OA\Property(property="password", type="string", format="password", example="new_secure_password"),
|
||||||
|
* @OA\Property(property="password_confirmation", type="string", format="password", example="new_secure_password"),
|
||||||
|
* @OA\Property(property="token", type="string", example="abcdef123456")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Password reset successful or invalid token",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Your password has been reset!")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Internal Server Error",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="We couldn’t process the request due to an error. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception message here")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function resetPassword(ResetPasswordRequest $request)
|
public function resetPassword(ResetPasswordRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -9,6 +9,45 @@ use App\Http\Requests\PasswordNotificationRequest;
|
|||||||
|
|
||||||
class SendPasswordNotificationController extends Controller
|
class SendPasswordNotificationController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/forgot-password",
|
||||||
|
* summary="Send password reset link to user's email",
|
||||||
|
* tags={"Auth"},
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* required=true,
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* required={"email"},
|
||||||
|
* @OA\Property(property="email", type="string", format="email", example="nima.8ak@gmail.com")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Success or user not found",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* oneOf={
|
||||||
|
* @OA\Schema(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="We’ve emailed you the password reset link. Please check your inbox!")
|
||||||
|
* ),
|
||||||
|
* @OA\Schema(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="message", type="string", example="We can’t find a user with that email address.")
|
||||||
|
* )
|
||||||
|
* }
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Server error",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="We couldn’t send the password reset email due to an error."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Some exception message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function passwordNotification(PasswordNotificationRequest $request)
|
public function passwordNotification(PasswordNotificationRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -10,12 +10,53 @@ use App\Http\Requests\RegisterRequest;
|
|||||||
|
|
||||||
class RegisterController extends Controller
|
class RegisterController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/register",
|
||||||
|
* summary="Register a new user",
|
||||||
|
* tags={"Auth"},
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* required=true,
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* required={"name", "email", "password", "password_confirmation"},
|
||||||
|
* @OA\Property(property="name", type="string", example="Nima Malakooti"),
|
||||||
|
* @OA\Property(property="email", type="string", format="email", example="nima@example.com"),
|
||||||
|
* @OA\Property(property="password", type="string", format="password", example="12345678"),
|
||||||
|
* @OA\Property(property="password_confirmation", type="string", format="password", example="12345678")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="User registered successfully.",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="User registered successfully."),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="user",
|
||||||
|
* type="object",
|
||||||
|
* @OA\Property(property="name", type="string", example="Nima Malakooti"),
|
||||||
|
* @OA\Property(property="email", type="string", example="nima@example.com"),
|
||||||
|
* @OA\Property(property="token", type="string", example="access_token_string")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Registration failed",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="Failed to register user. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="SQLSTATE[23000]: Integrity constraint violation...")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function register(RegisterRequest $request)
|
public function register(RegisterRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$inputs = $request->only(['name', 'email', 'password']);
|
$inputs = $request->only(['name', 'email', 'password']);
|
||||||
$inputs["password"] = Hash::make($inputs["password"]);
|
$inputs["password"] = Hash::make($inputs["password"]);
|
||||||
|
|
||||||
$user = User::create($inputs);
|
$user = User::create($inputs);
|
||||||
|
|
||||||
//create token for table oauth_access_token
|
//create token for table oauth_access_token
|
||||||
|
|||||||
@ -2,6 +2,13 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Info(
|
||||||
|
* title="API Documentation",
|
||||||
|
* version="1.0.0"
|
||||||
|
* )
|
||||||
|
*/
|
||||||
abstract class Controller
|
abstract class Controller
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|||||||
@ -10,11 +10,13 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
|
"darkaonline/l5-swagger": "^9.0",
|
||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/passport": "^12.0",
|
"laravel/passport": "^12.0",
|
||||||
"laravel/socialite": "^5.19",
|
"laravel/socialite": "^5.19",
|
||||||
"laravel/tinker": "^2.10.1",
|
"laravel/tinker": "^2.10.1",
|
||||||
"mailersend/laravel-driver": "^2.9"
|
"mailersend/laravel-driver": "^2.9",
|
||||||
|
"zircote/swagger-php": "^5.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"fakerphp/faker": "^1.23",
|
"fakerphp/faker": "^1.23",
|
||||||
|
|||||||
499
API/Passport/composer.lock
generated
499
API/Passport/composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "1ade29b472eb926a907f3551d941c1f2",
|
"content-hash": "58768fe7ec128d59fdf551e8351ec4f4",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "beberlei/assert",
|
"name": "beberlei/assert",
|
||||||
@ -268,6 +268,87 @@
|
|||||||
],
|
],
|
||||||
"time": "2023-12-20T15:40:13+00:00"
|
"time": "2023-12-20T15:40:13+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "darkaonline/l5-swagger",
|
||||||
|
"version": "9.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/DarkaOnLine/L5-Swagger.git",
|
||||||
|
"reference": "2c26427f8c41db8e72232415e7287313e6b6a2e2"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/DarkaOnLine/L5-Swagger/zipball/2c26427f8c41db8e72232415e7287313e6b6a2e2",
|
||||||
|
"reference": "2c26427f8c41db8e72232415e7287313e6b6a2e2",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/annotations": "^1.0 || ^2.0",
|
||||||
|
"ext-json": "*",
|
||||||
|
"laravel/framework": "^12.0 || ^11.0",
|
||||||
|
"php": "^8.2",
|
||||||
|
"swagger-api/swagger-ui": ">=5.18.3",
|
||||||
|
"symfony/yaml": "^5.0 || ^6.0 || ^7.0",
|
||||||
|
"zircote/swagger-php": "^5.0.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"mockery/mockery": "1.*",
|
||||||
|
"orchestra/testbench": "^10.0 || ^9.0 || ^8.0 || 7.* || ^6.15 || 5.*",
|
||||||
|
"php-coveralls/php-coveralls": "^2.0",
|
||||||
|
"phpstan/phpstan": "^2.1",
|
||||||
|
"phpunit/phpunit": "^11.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"aliases": {
|
||||||
|
"L5Swagger": "L5Swagger\\L5SwaggerFacade"
|
||||||
|
},
|
||||||
|
"providers": [
|
||||||
|
"L5Swagger\\L5SwaggerServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/helpers.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"L5Swagger\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Darius Matulionis",
|
||||||
|
"email": "darius@matulionis.lt"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "OpenApi or Swagger integration to Laravel",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"documentation",
|
||||||
|
"laravel",
|
||||||
|
"openapi",
|
||||||
|
"specification",
|
||||||
|
"swagger",
|
||||||
|
"ui"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/DarkaOnLine/L5-Swagger/issues",
|
||||||
|
"source": "https://github.com/DarkaOnLine/L5-Swagger/tree/9.0.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/DarkaOnLine",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-02-28T06:25:02+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "defuse/php-encryption",
|
"name": "defuse/php-encryption",
|
||||||
"version": "v2.4.0",
|
"version": "v2.4.0",
|
||||||
@ -410,6 +491,82 @@
|
|||||||
},
|
},
|
||||||
"time": "2024-07-08T12:26:09+00:00"
|
"time": "2024-07-08T12:26:09+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "doctrine/annotations",
|
||||||
|
"version": "2.0.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine/annotations.git",
|
||||||
|
"reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine/annotations/zipball/901c2ee5d26eb64ff43c47976e114bf00843acf7",
|
||||||
|
"reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/lexer": "^2 || ^3",
|
||||||
|
"ext-tokenizer": "*",
|
||||||
|
"php": "^7.2 || ^8.0",
|
||||||
|
"psr/cache": "^1 || ^2 || ^3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/cache": "^2.0",
|
||||||
|
"doctrine/coding-standard": "^10",
|
||||||
|
"phpstan/phpstan": "^1.10.28",
|
||||||
|
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||||
|
"symfony/cache": "^5.4 || ^6.4 || ^7",
|
||||||
|
"vimeo/psalm": "^4.30 || ^5.14"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Guilherme Blanco",
|
||||||
|
"email": "guilhermeblanco@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Roman Borschel",
|
||||||
|
"email": "roman@code-factory.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Benjamin Eberlei",
|
||||||
|
"email": "kontakt@beberlei.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonathan Wage",
|
||||||
|
"email": "jonwage@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Johannes Schmitt",
|
||||||
|
"email": "schmittjoh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Docblock Annotations Parser",
|
||||||
|
"homepage": "https://www.doctrine-project.org/projects/annotations.html",
|
||||||
|
"keywords": [
|
||||||
|
"annotations",
|
||||||
|
"docblock",
|
||||||
|
"parser"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/doctrine/annotations/issues",
|
||||||
|
"source": "https://github.com/doctrine/annotations/tree/2.0.2"
|
||||||
|
},
|
||||||
|
"time": "2024-09-05T10:17:24+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/inflector",
|
"name": "doctrine/inflector",
|
||||||
"version": "2.0.10",
|
"version": "2.0.10",
|
||||||
@ -4175,6 +4332,55 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-12-14T21:12:59+00:00"
|
"time": "2024-12-14T21:12:59+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/cache",
|
||||||
|
"version": "3.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/cache.git",
|
||||||
|
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
|
||||||
|
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Cache\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "https://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interface for caching libraries",
|
||||||
|
"keywords": [
|
||||||
|
"cache",
|
||||||
|
"psr",
|
||||||
|
"psr-6"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/cache/tree/3.0.0"
|
||||||
|
},
|
||||||
|
"time": "2021-02-03T23:26:27+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/clock",
|
"name": "psr/clock",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@ -4878,6 +5084,67 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-04-27T21:32:50+00:00"
|
"time": "2024-04-27T21:32:50+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "swagger-api/swagger-ui",
|
||||||
|
"version": "v5.21.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/swagger-api/swagger-ui.git",
|
||||||
|
"reference": "fceaec605072fbc717a04895bd19814d9a1c8e6d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/fceaec605072fbc717a04895bd19814d9a1c8e6d",
|
||||||
|
"reference": "fceaec605072fbc717a04895bd19814d9a1c8e6d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"Apache-2.0"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Anna Bodnia",
|
||||||
|
"email": "anna.bodnia@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Buu Nguyen",
|
||||||
|
"email": "buunguyen@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Josh Ponelat",
|
||||||
|
"email": "jponelat@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kyle Shockey",
|
||||||
|
"email": "kyleshockey1@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Robert Barnwell",
|
||||||
|
"email": "robert@robertismy.name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sahar Jafari",
|
||||||
|
"email": "shr.jafari@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": " Swagger UI is a collection of HTML, Javascript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.",
|
||||||
|
"homepage": "http://swagger.io",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"documentation",
|
||||||
|
"openapi",
|
||||||
|
"specification",
|
||||||
|
"swagger",
|
||||||
|
"ui"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/swagger-api/swagger-ui/issues",
|
||||||
|
"source": "https://github.com/swagger-api/swagger-ui/tree/v5.21.0"
|
||||||
|
},
|
||||||
|
"time": "2025-04-13T19:37:38+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/clock",
|
"name": "symfony/clock",
|
||||||
"version": "v7.2.0",
|
"version": "v7.2.0",
|
||||||
@ -7256,6 +7523,78 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-01-17T11:39:41+00:00"
|
"time": "2025-01-17T11:39:41+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/yaml",
|
||||||
|
"version": "v7.2.5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/yaml.git",
|
||||||
|
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/yaml/zipball/4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
||||||
|
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.2",
|
||||||
|
"symfony/deprecation-contracts": "^2.5|^3.0",
|
||||||
|
"symfony/polyfill-ctype": "^1.8"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/console": "<6.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/console": "^6.4|^7.0"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"Resources/bin/yaml-lint"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Yaml\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Loads and dumps YAML files",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/yaml/tree/v7.2.5"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-03-03T07:12:39+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "tijsverkoyen/css-to-inline-styles",
|
"name": "tijsverkoyen/css-to-inline-styles",
|
||||||
"version": "v2.3.0",
|
"version": "v2.3.0",
|
||||||
@ -7526,6 +7865,92 @@
|
|||||||
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
|
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
|
||||||
},
|
},
|
||||||
"time": "2022-06-03T18:03:27+00:00"
|
"time": "2022-06-03T18:03:27+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "zircote/swagger-php",
|
||||||
|
"version": "5.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/zircote/swagger-php.git",
|
||||||
|
"reference": "a9b953c25f5bd11ea0542636936de04504496bd9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/a9b953c25f5bd11ea0542636936de04504496bd9",
|
||||||
|
"reference": "a9b953c25f5bd11ea0542636936de04504496bd9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-json": "*",
|
||||||
|
"nikic/php-parser": "^4.19 || ^5.0",
|
||||||
|
"php": ">=7.4",
|
||||||
|
"psr/log": "^1.1 || ^2.0 || ^3.0",
|
||||||
|
"symfony/deprecation-contracts": "^2 || ^3",
|
||||||
|
"symfony/finder": "^5.0 || ^6.0 || ^7.0",
|
||||||
|
"symfony/yaml": "^5.0 || ^6.0 || ^7.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/process": ">=6, <6.4.14"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"composer/package-versions-deprecated": "^1.11",
|
||||||
|
"doctrine/annotations": "^2.0",
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.62.0",
|
||||||
|
"phpstan/phpstan": "^1.6 || ^2.0",
|
||||||
|
"phpunit/phpunit": "^9.0",
|
||||||
|
"rector/rector": "^1.0 || ^2.0",
|
||||||
|
"vimeo/psalm": "^4.30 || ^5.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"doctrine/annotations": "^2.0"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"bin/openapi"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "5.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"OpenApi\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"Apache-2.0"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Robert Allen",
|
||||||
|
"email": "zircote@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bob Fanger",
|
||||||
|
"email": "bfanger@gmail.com",
|
||||||
|
"homepage": "https://bfanger.nl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Martin Rademacher",
|
||||||
|
"email": "mano@radebatz.net",
|
||||||
|
"homepage": "https://radebatz.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Generate interactive documentation for your RESTful API using PHP attributes (preferred) or PHPDoc annotations",
|
||||||
|
"homepage": "https://github.com/zircote/swagger-php",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"json",
|
||||||
|
"rest",
|
||||||
|
"service discovery"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/zircote/swagger-php/issues",
|
||||||
|
"source": "https://github.com/zircote/swagger-php/tree/5.1.0"
|
||||||
|
},
|
||||||
|
"time": "2025-04-18T00:35:12+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
@ -10565,78 +10990,6 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-10-20T05:08:20+00:00"
|
"time": "2024-10-20T05:08:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "symfony/yaml",
|
|
||||||
"version": "v7.2.5",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/yaml.git",
|
|
||||||
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
|
||||||
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=8.2",
|
|
||||||
"symfony/deprecation-contracts": "^2.5|^3.0",
|
|
||||||
"symfony/polyfill-ctype": "^1.8"
|
|
||||||
},
|
|
||||||
"conflict": {
|
|
||||||
"symfony/console": "<6.4"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"symfony/console": "^6.4|^7.0"
|
|
||||||
},
|
|
||||||
"bin": [
|
|
||||||
"Resources/bin/yaml-lint"
|
|
||||||
],
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Symfony\\Component\\Yaml\\": ""
|
|
||||||
},
|
|
||||||
"exclude-from-classmap": [
|
|
||||||
"/Tests/"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Fabien Potencier",
|
|
||||||
"email": "fabien@symfony.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "https://symfony.com/contributors"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Loads and dumps YAML files",
|
|
||||||
"homepage": "https://symfony.com",
|
|
||||||
"support": {
|
|
||||||
"source": "https://github.com/symfony/yaml/tree/v7.2.5"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://symfony.com/sponsor",
|
|
||||||
"type": "custom"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://github.com/fabpot",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
|
||||||
"type": "tidelift"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2025-03-03T07:12:39+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "ta-tikoma/phpunit-architecture-test",
|
"name": "ta-tikoma/phpunit-architecture-test",
|
||||||
"version": "0.8.4",
|
"version": "0.8.4",
|
||||||
|
|||||||
322
API/Passport/config/l5-swagger.php
Normal file
322
API/Passport/config/l5-swagger.php
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'default' => 'default',
|
||||||
|
'documentations' => [
|
||||||
|
'default' => [
|
||||||
|
'api' => [
|
||||||
|
'title' => 'L5 Swagger UI',
|
||||||
|
],
|
||||||
|
|
||||||
|
'routes' => [
|
||||||
|
/*
|
||||||
|
* Route for accessing api documentation interface
|
||||||
|
*/
|
||||||
|
'api' => 'api/documentation',
|
||||||
|
],
|
||||||
|
'paths' => [
|
||||||
|
/*
|
||||||
|
* Edit to include full URL in ui for assets
|
||||||
|
*/
|
||||||
|
'use_absolute_path' => env('L5_SWAGGER_USE_ABSOLUTE_PATH', true),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edit to set path where swagger ui assets should be stored
|
||||||
|
*/
|
||||||
|
'swagger_ui_assets_path' => env('L5_SWAGGER_UI_ASSETS_PATH', 'vendor/swagger-api/swagger-ui/dist/'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File name of the generated json documentation file
|
||||||
|
*/
|
||||||
|
'docs_json' => 'api-docs.json',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File name of the generated YAML documentation file
|
||||||
|
*/
|
||||||
|
'docs_yaml' => 'api-docs.yaml',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set this to `json` or `yaml` to determine which documentation file to use in UI
|
||||||
|
*/
|
||||||
|
'format_to_use_for_docs' => env('L5_FORMAT_TO_USE_FOR_DOCS', 'json'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute paths to directory containing the swagger annotations are stored.
|
||||||
|
*/
|
||||||
|
'annotations' => [
|
||||||
|
base_path('app'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'defaults' => [
|
||||||
|
'routes' => [
|
||||||
|
/*
|
||||||
|
* Route for accessing parsed swagger annotations.
|
||||||
|
*/
|
||||||
|
'docs' => 'docs',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Route for Oauth2 authentication callback.
|
||||||
|
*/
|
||||||
|
'oauth2_callback' => 'api/oauth2-callback',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Middleware allows to prevent unexpected access to API documentation
|
||||||
|
*/
|
||||||
|
'middleware' => [
|
||||||
|
'api' => [],
|
||||||
|
'asset' => [],
|
||||||
|
'docs' => [],
|
||||||
|
'oauth2_callback' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Route Group options
|
||||||
|
*/
|
||||||
|
'group_options' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
'paths' => [
|
||||||
|
/*
|
||||||
|
* Absolute path to location where parsed annotations will be stored
|
||||||
|
*/
|
||||||
|
'docs' => storage_path('api-docs'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute path to directory where to export views
|
||||||
|
*/
|
||||||
|
'views' => base_path('resources/views/vendor/l5-swagger'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edit to set the api's base path
|
||||||
|
*/
|
||||||
|
'base' => env('L5_SWAGGER_BASE_PATH', null),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute path to directories that should be excluded from scanning
|
||||||
|
* @deprecated Please use `scanOptions.exclude`
|
||||||
|
* `scanOptions.exclude` overwrites this
|
||||||
|
*/
|
||||||
|
'excludes' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
'scanOptions' => [
|
||||||
|
/**
|
||||||
|
* Configuration for default processors. Allows to pass processors configuration to swagger-php.
|
||||||
|
*
|
||||||
|
* @link https://zircote.github.io/swagger-php/reference/processors.html
|
||||||
|
*/
|
||||||
|
'default_processors_configuration' => [
|
||||||
|
/** Example */
|
||||||
|
/**
|
||||||
|
* 'operationId.hash' => true,
|
||||||
|
* 'pathFilter' => [
|
||||||
|
* 'tags' => [
|
||||||
|
* '/pets/',
|
||||||
|
* '/store/',
|
||||||
|
* ],
|
||||||
|
* ],.
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* analyser: defaults to \OpenApi\StaticAnalyser .
|
||||||
|
*
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'analyser' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* analysis: defaults to a new \OpenApi\Analysis .
|
||||||
|
*
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'analysis' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom query path processors classes.
|
||||||
|
*
|
||||||
|
* @link https://github.com/zircote/swagger-php/tree/master/Examples/processors/schema-query-parameter
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'processors' => [
|
||||||
|
// new \App\SwaggerProcessors\SchemaQueryParameter(),
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pattern: string $pattern File pattern(s) to scan (default: *.php) .
|
||||||
|
*
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'pattern' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute path to directories that should be excluded from scanning
|
||||||
|
* @note This option overwrites `paths.excludes`
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'exclude' => [],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allows to generate specs either for OpenAPI 3.0.0 or OpenAPI 3.1.0.
|
||||||
|
* By default the spec will be in version 3.0.0
|
||||||
|
*/
|
||||||
|
'open_api_spec_version' => env('L5_SWAGGER_OPEN_API_SPEC_VERSION', \L5Swagger\Generator::OPEN_API_DEFAULT_SPEC_VERSION),
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* API security definitions. Will be generated into documentation file.
|
||||||
|
*/
|
||||||
|
'securityDefinitions' => [
|
||||||
|
'passport' => [
|
||||||
|
'type' => 'apiKey',
|
||||||
|
'in' => 'header',
|
||||||
|
'name' => 'Authorization',
|
||||||
|
'description' => 'Bearer token for authenticating requests',
|
||||||
|
],
|
||||||
|
'securitySchemes' => [
|
||||||
|
/*
|
||||||
|
* Examples of Security schemes
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
'api_key_security_example' => [ // Unique name of security
|
||||||
|
'type' => 'apiKey', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'A short description for security scheme',
|
||||||
|
'name' => 'api_key', // The name of the header or query parameter to be used.
|
||||||
|
'in' => 'header', // The location of the API key. Valid values are "query" or "header".
|
||||||
|
],
|
||||||
|
'oauth2_security_example' => [ // Unique name of security
|
||||||
|
'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'A short description for oauth2 security scheme.',
|
||||||
|
'flow' => 'implicit', // The flow used by the OAuth2 security scheme. Valid values are "implicit", "password", "application" or "accessCode".
|
||||||
|
'authorizationUrl' => 'http://example.com/auth', // The authorization URL to be used for (implicit/accessCode)
|
||||||
|
//'tokenUrl' => 'http://example.com/auth' // The authorization URL to be used for (password/application/accessCode)
|
||||||
|
'scopes' => [
|
||||||
|
'read:projects' => 'read your projects',
|
||||||
|
'write:projects' => 'modify projects in your account',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Open API 3.0 support
|
||||||
|
'passport' => [ // Unique name of security
|
||||||
|
'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'Laravel passport oauth2 security.',
|
||||||
|
'in' => 'header',
|
||||||
|
'scheme' => 'https',
|
||||||
|
'flows' => [
|
||||||
|
"password" => [
|
||||||
|
"authorizationUrl" => config('app.url') . '/oauth/authorize',
|
||||||
|
"tokenUrl" => config('app.url') . '/oauth/token',
|
||||||
|
"refreshUrl" => config('app.url') . '/token/refresh',
|
||||||
|
"scopes" => []
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'sanctum' => [ // Unique name of security
|
||||||
|
'type' => 'apiKey', // Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'Enter token in format (Bearer <token>)',
|
||||||
|
'name' => 'Authorization', // The name of the header or query parameter to be used.
|
||||||
|
'in' => 'header', // The location of the API key. Valid values are "query" or "header".
|
||||||
|
],
|
||||||
|
*/],
|
||||||
|
'security' => [
|
||||||
|
/*
|
||||||
|
* Examples of Securities
|
||||||
|
*/
|
||||||
|
[
|
||||||
|
/*
|
||||||
|
'oauth2_security_example' => [
|
||||||
|
'read',
|
||||||
|
'write'
|
||||||
|
],
|
||||||
|
|
||||||
|
'passport' => []
|
||||||
|
*/],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set this to `true` in development mode so that docs would be regenerated on each request
|
||||||
|
* Set this to `false` to disable swagger generation on production
|
||||||
|
*/
|
||||||
|
'generate_always' => env('L5_SWAGGER_GENERATE_ALWAYS', false),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set this to `true` to generate a copy of documentation in yaml format
|
||||||
|
*/
|
||||||
|
'generate_yaml_copy' => env('L5_SWAGGER_GENERATE_YAML_COPY', false),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edit to trust the proxy's ip address - needed for AWS Load Balancer
|
||||||
|
* string[]
|
||||||
|
*/
|
||||||
|
'proxy' => false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configs plugin allows to fetch external configs instead of passing them to SwaggerUIBundle.
|
||||||
|
* See more at: https://github.com/swagger-api/swagger-ui#configs-plugin
|
||||||
|
*/
|
||||||
|
'additional_config_url' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically),
|
||||||
|
* 'method' (sort by HTTP method).
|
||||||
|
* Default is the order returned by the server unchanged.
|
||||||
|
*/
|
||||||
|
'operations_sort' => env('L5_SWAGGER_OPERATIONS_SORT', null),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pass the validatorUrl parameter to SwaggerUi init on the JS side.
|
||||||
|
* A null value here disables validation.
|
||||||
|
*/
|
||||||
|
'validator_url' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Swagger UI configuration parameters
|
||||||
|
*/
|
||||||
|
'ui' => [
|
||||||
|
'display' => [
|
||||||
|
'dark_mode' => env('L5_SWAGGER_UI_DARK_MODE', false),
|
||||||
|
/*
|
||||||
|
* Controls the default expansion setting for the operations and tags. It can be :
|
||||||
|
* 'list' (expands only the tags),
|
||||||
|
* 'full' (expands the tags and operations),
|
||||||
|
* 'none' (expands nothing).
|
||||||
|
*/
|
||||||
|
'doc_expansion' => env('L5_SWAGGER_UI_DOC_EXPANSION', 'none'),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set, enables filtering. The top bar will show an edit box that
|
||||||
|
* you can use to filter the tagged operations that are shown. Can be
|
||||||
|
* Boolean to enable or disable, or a string, in which case filtering
|
||||||
|
* will be enabled using that string as the filter expression. Filtering
|
||||||
|
* is case-sensitive matching the filter expression anywhere inside
|
||||||
|
* the tag.
|
||||||
|
*/
|
||||||
|
'filter' => env('L5_SWAGGER_UI_FILTERS', true), // true | false
|
||||||
|
],
|
||||||
|
|
||||||
|
'authorization' => [
|
||||||
|
/*
|
||||||
|
* If set to true, it persists authorization data, and it would not be lost on browser close/refresh
|
||||||
|
*/
|
||||||
|
'persist_authorization' => env('L5_SWAGGER_UI_PERSIST_AUTHORIZATION', false),
|
||||||
|
|
||||||
|
'oauth2' => [
|
||||||
|
/*
|
||||||
|
* If set to true, adds PKCE to AuthorizationCodeGrant flow
|
||||||
|
*/
|
||||||
|
'use_pkce_with_authorization_code_grant' => false,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
/*
|
||||||
|
* Constants which can be used in annotations
|
||||||
|
*/
|
||||||
|
'constants' => [
|
||||||
|
'L5_SWAGGER_CONST_HOST' => env('L5_SWAGGER_CONST_HOST', 'http://my-default-host.com'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
0
API/Passport/resources/views/vendor/l5-swagger/.gitkeep
vendored
Normal file
0
API/Passport/resources/views/vendor/l5-swagger/.gitkeep
vendored
Normal file
174
API/Passport/resources/views/vendor/l5-swagger/index.blade.php
vendored
Normal file
174
API/Passport/resources/views/vendor/l5-swagger/index.blade.php
vendored
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{{ $documentationTitle }}</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ l5_swagger_asset($documentation, 'swagger-ui.css') }}">
|
||||||
|
<link rel="icon" type="image/png" href="{{ l5_swagger_asset($documentation, 'favicon-32x32.png') }}" sizes="32x32"/>
|
||||||
|
<link rel="icon" type="image/png" href="{{ l5_swagger_asset($documentation, 'favicon-16x16.png') }}" sizes="16x16"/>
|
||||||
|
<style>
|
||||||
|
html
|
||||||
|
{
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: -moz-scrollbars-vertical;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after
|
||||||
|
{
|
||||||
|
box-sizing: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin:0;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@if(config('l5-swagger.defaults.ui.display.dark_mode'))
|
||||||
|
<style>
|
||||||
|
body#dark-mode,
|
||||||
|
#dark-mode .scheme-container {
|
||||||
|
background: #1b1b1b;
|
||||||
|
}
|
||||||
|
#dark-mode .scheme-container,
|
||||||
|
#dark-mode .opblock .opblock-section-header{
|
||||||
|
box-shadow: 0 1px 2px 0 rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
#dark-mode .operation-filter-input,
|
||||||
|
#dark-mode .dialog-ux .modal-ux,
|
||||||
|
#dark-mode input[type=email],
|
||||||
|
#dark-mode input[type=file],
|
||||||
|
#dark-mode input[type=password],
|
||||||
|
#dark-mode input[type=search],
|
||||||
|
#dark-mode input[type=text],
|
||||||
|
#dark-mode textarea{
|
||||||
|
background: #343434;
|
||||||
|
color: #e7e7e7;
|
||||||
|
}
|
||||||
|
#dark-mode .title,
|
||||||
|
#dark-mode li,
|
||||||
|
#dark-mode p,
|
||||||
|
#dark-mode table,
|
||||||
|
#dark-mode label,
|
||||||
|
#dark-mode .opblock-tag,
|
||||||
|
#dark-mode .opblock .opblock-summary-operation-id,
|
||||||
|
#dark-mode .opblock .opblock-summary-path,
|
||||||
|
#dark-mode .opblock .opblock-summary-path__deprecated,
|
||||||
|
#dark-mode h1,
|
||||||
|
#dark-mode h2,
|
||||||
|
#dark-mode h3,
|
||||||
|
#dark-mode h4,
|
||||||
|
#dark-mode h5,
|
||||||
|
#dark-mode .btn,
|
||||||
|
#dark-mode .tab li,
|
||||||
|
#dark-mode .parameter__name,
|
||||||
|
#dark-mode .parameter__type,
|
||||||
|
#dark-mode .prop-format,
|
||||||
|
#dark-mode .loading-container .loading:after{
|
||||||
|
color: #e7e7e7;
|
||||||
|
}
|
||||||
|
#dark-mode .opblock-description-wrapper p,
|
||||||
|
#dark-mode .opblock-external-docs-wrapper p,
|
||||||
|
#dark-mode .opblock-title_normal p,
|
||||||
|
#dark-mode .response-col_status,
|
||||||
|
#dark-mode table thead tr td,
|
||||||
|
#dark-mode table thead tr th,
|
||||||
|
#dark-mode .response-col_links,
|
||||||
|
#dark-mode .swagger-ui{
|
||||||
|
color: wheat;
|
||||||
|
}
|
||||||
|
#dark-mode .parameter__extension,
|
||||||
|
#dark-mode .parameter__in,
|
||||||
|
#dark-mode .model-title{
|
||||||
|
color: #949494;
|
||||||
|
}
|
||||||
|
#dark-mode table thead tr td,
|
||||||
|
#dark-mode table thead tr th{
|
||||||
|
border-color: rgba(120,120,120,.2);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock .opblock-section-header{
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-post{
|
||||||
|
background: rgba(73,204,144,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-get{
|
||||||
|
background: rgba(97,175,254,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-put{
|
||||||
|
background: rgba(252,161,48,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-delete{
|
||||||
|
background: rgba(249,62,62,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .loading-container .loading:before{
|
||||||
|
border-color: rgba(255,255,255,10%);
|
||||||
|
border-top-color: rgba(255,255,255,.6);
|
||||||
|
}
|
||||||
|
#dark-mode svg:not(:root){
|
||||||
|
fill: #e7e7e7;
|
||||||
|
}
|
||||||
|
#dark-mode .opblock-summary-description {
|
||||||
|
color: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@endif
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body @if(config('l5-swagger.defaults.ui.display.dark_mode')) id="dark-mode" @endif>
|
||||||
|
<div id="swagger-ui"></div>
|
||||||
|
|
||||||
|
<script src="{{ l5_swagger_asset($documentation, 'swagger-ui-bundle.js') }}"></script>
|
||||||
|
<script src="{{ l5_swagger_asset($documentation, 'swagger-ui-standalone-preset.js') }}"></script>
|
||||||
|
<script>
|
||||||
|
window.onload = function() {
|
||||||
|
const urls = [];
|
||||||
|
|
||||||
|
@foreach($urlsToDocs as $title => $url)
|
||||||
|
urls.push({name: "{{ $title }}", url: "{{ $url }}"});
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
// Build a system
|
||||||
|
const ui = SwaggerUIBundle({
|
||||||
|
dom_id: '#swagger-ui',
|
||||||
|
urls: urls,
|
||||||
|
"urls.primaryName": "{{ $documentationTitle }}",
|
||||||
|
operationsSorter: {!! isset($operationsSorter) ? '"' . $operationsSorter . '"' : 'null' !!},
|
||||||
|
configUrl: {!! isset($configUrl) ? '"' . $configUrl . '"' : 'null' !!},
|
||||||
|
validatorUrl: {!! isset($validatorUrl) ? '"' . $validatorUrl . '"' : 'null' !!},
|
||||||
|
oauth2RedirectUrl: "{{ route('l5-swagger.'.$documentation.'.oauth2_callback', [], $useAbsolutePath) }}",
|
||||||
|
|
||||||
|
requestInterceptor: function(request) {
|
||||||
|
request.headers['X-CSRF-TOKEN'] = '{{ csrf_token() }}';
|
||||||
|
return request;
|
||||||
|
},
|
||||||
|
|
||||||
|
presets: [
|
||||||
|
SwaggerUIBundle.presets.apis,
|
||||||
|
SwaggerUIStandalonePreset
|
||||||
|
],
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
SwaggerUIBundle.plugins.DownloadUrl
|
||||||
|
],
|
||||||
|
|
||||||
|
layout: "StandaloneLayout",
|
||||||
|
docExpansion : "{!! config('l5-swagger.defaults.ui.display.doc_expansion', 'none') !!}",
|
||||||
|
deepLinking: true,
|
||||||
|
filter: {!! config('l5-swagger.defaults.ui.display.filter') ? 'true' : 'false' !!},
|
||||||
|
persistAuthorization: "{!! config('l5-swagger.defaults.ui.authorization.persist_authorization') ? 'true' : 'false' !!}",
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
window.ui = ui
|
||||||
|
|
||||||
|
@if(in_array('oauth2', array_column(config('l5-swagger.defaults.securityDefinitions.securitySchemes'), 'type')))
|
||||||
|
ui.initOAuth({
|
||||||
|
usePkceWithAuthorizationCodeGrant: "{!! (bool)config('l5-swagger.defaults.ui.authorization.oauth2.use_pkce_with_authorization_code_grant') !!}"
|
||||||
|
})
|
||||||
|
@endif
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -20,7 +20,7 @@ Route::post('login', [LoginController::class, 'login'])->name('login');
|
|||||||
|
|
||||||
Route::group(['middleware' => ['auth:api']], function () {
|
Route::group(['middleware' => ['auth:api']], function () {
|
||||||
Route::post('logout', [LogoutController::class, 'logout'])->name('logout');
|
Route::post('logout', [LogoutController::class, 'logout'])->name('logout');
|
||||||
Route::post('deleteAccount', [DeleteAccountController::class, 'deleteAccount'])->name('deleteAccount');
|
Route::delete('deleteAccount', [DeleteAccountController::class, 'deleteAccount'])->name('deleteAccount');
|
||||||
|
|
||||||
//verified email route
|
//verified email route
|
||||||
Route::post('email/verification-notification', [SendMailNotificationController::class, 'sendNotification'])->name('mail.notification');
|
Route::post('email/verification-notification', [SendMailNotificationController::class, 'sendNotification'])->name('mail.notification');
|
||||||
|
|||||||
693
API/Passport/storage/api-docs/api-docs.json
Normal file
693
API/Passport/storage/api-docs/api-docs.json
Normal file
@ -0,0 +1,693 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.0.0",
|
||||||
|
"info": {
|
||||||
|
"title": "API Documentation",
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"/api/deleteAccount": {
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Delete user account",
|
||||||
|
"operationId": "dab9c1b923636bca3b073db3bdf87db0",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Account successfully deleted",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Your account has been deleted successfully. We’re sorry to see you go."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Account deletion failed",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We couldn’t delete your account at this moment. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception details here"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"passport": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/login": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Login user and get access token",
|
||||||
|
"operationId": "e3ce052cc00fd9dd647e77abd7807e14",
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"email",
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"example": "nima@example.com"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "12345678"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Login successful",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Login successful. Welcome back!"
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Nima Malakooti"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "nima@example.com"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "access_token_string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized access",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Unauthorized access. Please check your credentials and try again."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Login failed",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Failed to login user. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Some internal error message..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/logout": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Logout the authenticated user",
|
||||||
|
"description": "Revoke the access token of the currently authenticated user using Laravel Passport.",
|
||||||
|
"operationId": "ad0ae046131d33ce33ee57a7f8a6a3f0",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "User logged out successfully",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "You have been logged out successfully. Come back soon!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Logout failed",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Oops! Something went wrong while logging out. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Internal server error message here"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"passport": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/email/verification-notification": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Send email verification link",
|
||||||
|
"description": "Sends a verification email to the authenticated user.",
|
||||||
|
"operationId": "8ec40714c737be195e9d133ed44603d9",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Verification email sent",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Please check your email for the verification link."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Failed to send verification email",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We encountered an issue while sending the verification email. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Some internal error here..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"passport": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/email/verify": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Verify user email",
|
||||||
|
"operationId": "9cc4882d8f915148bcc1fce772ebcfde",
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"email",
|
||||||
|
"verification_token"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"example": "nima@example.com"
|
||||||
|
},
|
||||||
|
"verification_token": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "12345678"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Email successfully verified",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Your email has been successfully verified. Thank you!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Verification failed",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Your verification link was found, but something went wrong during the confirmation process. Please try again or request a new verification email."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception details here"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"passport": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/reset-password": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Reset user password using token",
|
||||||
|
"operationId": "8e8229015b36555c6ad9564278a79929",
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"email",
|
||||||
|
"password",
|
||||||
|
"password_confirmation",
|
||||||
|
"token"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "new_secure_password"
|
||||||
|
},
|
||||||
|
"password_confirmation": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "new_secure_password"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "abcdef123456"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Password reset successful or invalid token",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Your password has been reset!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We couldn’t process the request due to an error. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message here"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/forgot-password": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Send password reset link to user's email",
|
||||||
|
"operationId": "0cb521700d859fa50b6075f190634833",
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"email"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success or user not found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We’ve emailed you the password reset link. Please check your inbox!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We can’t find a user with that email address."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Server error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We couldn’t send the password reset email due to an error."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Some exception message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/register": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Register a new user",
|
||||||
|
"operationId": "97cd8d12c6b5cf0267b29ff739a126f8",
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"email",
|
||||||
|
"password",
|
||||||
|
"password_confirmation"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Nima Malakooti"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"example": "nima@example.com"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "12345678"
|
||||||
|
},
|
||||||
|
"password_confirmation": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "12345678"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "User registered successfully.",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "User registered successfully."
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Nima Malakooti"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "nima@example.com"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "access_token_string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Registration failed",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Failed to register user. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "SQLSTATE[23000]: Integrity constraint violation..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"name": "Auth",
|
||||||
|
"description": "Auth"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
131
API/Sanctum/Laravel Sanctum.postman_collection.json
Normal file
131
API/Sanctum/Laravel Sanctum.postman_collection.json
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
{
|
||||||
|
"info": {
|
||||||
|
"_postman_id": "58a30285-dcfc-4af7-a98e-939a1d300340",
|
||||||
|
"name": "Laravel Sanctum",
|
||||||
|
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||||
|
"_exporter_id": "26260450"
|
||||||
|
},
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Register",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "noauth"
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"email\":\"nima_8a@yahoo.com\",\n \"password\":\"12345678\"\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/login",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"login"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Login",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "noauth"
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"email\":\"nima_8a@yahoo.com\",\n \"password\":\"12345678\"\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/login",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"login"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Logout",
|
||||||
|
"request": {
|
||||||
|
"auth": {
|
||||||
|
"type": "bearer",
|
||||||
|
"bearer": [
|
||||||
|
{
|
||||||
|
"key": "token",
|
||||||
|
"value": "jFu0UzaYXDquafG23eHWJnkHrrFyy5ZDhcNItWorbcc49ba6",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "http://127.0.0.1:8000/api/logout",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"127",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"port": "8000",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"logout"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -7,6 +7,31 @@ use Illuminate\Http\Request;
|
|||||||
|
|
||||||
class DeleteAccountController extends Controller
|
class DeleteAccountController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Delete(
|
||||||
|
* path="/api/deleteAccount",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* summary="Delete user account",
|
||||||
|
* description="Deletes the user's account and invalidates their tokens.",
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Account deleted successfully",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Your account has been deleted successfully. We’re sorry to see you go.")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Internal server error",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="We couldn’t delete your account at this moment. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function deleteAccount(Request $request)
|
public function deleteAccount(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -9,6 +9,52 @@ use Illuminate\Support\Facades\Auth;
|
|||||||
|
|
||||||
class LoginController extends Controller
|
class LoginController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/login",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* summary="Login user",
|
||||||
|
* description="Login a user with email and password, and return an authentication token.",
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* required=true,
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* required={"email", "password"},
|
||||||
|
* @OA\Property(property="email", type="string", format="email", example="nima.8ak@gmail.com"),
|
||||||
|
* @OA\Property(property="password", type="string", format="password", example="12345678")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="User successfully logged in and token provided",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="Login successful. Welcome back!"),
|
||||||
|
* @OA\Property(property="data", type="object",
|
||||||
|
* @OA\Property(property="email", type="string", example="nima.8ak@gmail.com"),
|
||||||
|
* @OA\Property(property="name", type="string", example="nima malakooti"),
|
||||||
|
* @OA\Property(property="token", type="string", example="your-token-here")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=401,
|
||||||
|
* description="Unauthorized access",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="message", type="string", example="Unauthorized access. Please check your credentials and try again.")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Internal server error",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="Failed to login user. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function login(LoginRequest $request)
|
public function login(LoginRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -7,6 +7,31 @@ use Illuminate\Http\Request;
|
|||||||
|
|
||||||
class LogoutController extends Controller
|
class LogoutController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/logout",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* summary="Logout the user",
|
||||||
|
* description="Invalidate the user's session by deleting their tokens and logging them out.",
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Successfully logged out",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="You have been logged out successfully. Come back soon!")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Internal server error",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="Oops! Something went wrong while logging out. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function logout(Request $request)
|
public function logout(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -10,6 +10,46 @@ use App\Http\Requests\RegisterRequest;
|
|||||||
|
|
||||||
class RegisterController extends Controller
|
class RegisterController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/register",
|
||||||
|
* tags={"Authentication"},
|
||||||
|
* summary="Register a new user",
|
||||||
|
* description="Register a new user with name, email, and password and return a user object with authentication token.",
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* required=true,
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* required={"name", "email", "password","password_confirmation"},
|
||||||
|
* @OA\Property(property="name", type="string", example="nima malakooti"),
|
||||||
|
* @OA\Property(property="email", type="string", format="email", example="nima.8ak@gmail.com"),
|
||||||
|
* @OA\Property(property="password", type="string", format="password", example="12345678"),
|
||||||
|
* @OA\Property(property="password_confirmation", type="string", format="password", example="12345678")
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="User successfully registered and token provided",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=1),
|
||||||
|
* @OA\Property(property="message", type="string", example="User registered successfully."),
|
||||||
|
* @OA\Property(property="user", type="object",
|
||||||
|
* @OA\Property(property="name", type="string", example="nima malakooti"),
|
||||||
|
* @OA\Property(property="email", type="string", example="nima.8ak@gmail.com"),
|
||||||
|
* @OA\Property(property="token", type="string", example="your-token-here")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=500,
|
||||||
|
* description="Internal server error",
|
||||||
|
* @OA\JsonContent(
|
||||||
|
* @OA\Property(property="status", type="integer", example=0),
|
||||||
|
* @OA\Property(property="error", type="string", example="Failed to register user. Please try again later."),
|
||||||
|
* @OA\Property(property="message", type="string", example="Exception message")
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
public function register(RegisterRequest $request)
|
public function register(RegisterRequest $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -2,6 +2,13 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Info(
|
||||||
|
* title="API Documentation",
|
||||||
|
* version="1.0.0"
|
||||||
|
* )
|
||||||
|
*/
|
||||||
abstract class Controller
|
abstract class Controller
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|||||||
@ -10,10 +10,12 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
|
"darkaonline/l5-swagger": "^9.0",
|
||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/sanctum": "^4.0",
|
"laravel/sanctum": "^4.0",
|
||||||
"laravel/tinker": "^2.10.1",
|
"laravel/tinker": "^2.10.1",
|
||||||
"mailersend/laravel-driver": "^2.9"
|
"mailersend/laravel-driver": "^2.9",
|
||||||
|
"zircote/swagger-php": "^5.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"fakerphp/faker": "^1.23",
|
"fakerphp/faker": "^1.23",
|
||||||
|
|||||||
499
API/Sanctum/composer.lock
generated
499
API/Sanctum/composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "680c068b443896d778e7531313a85853",
|
"content-hash": "7e2a1a2576fd14d799b21a6880aaa37f",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "beberlei/assert",
|
"name": "beberlei/assert",
|
||||||
@ -268,6 +268,87 @@
|
|||||||
],
|
],
|
||||||
"time": "2023-12-20T15:40:13+00:00"
|
"time": "2023-12-20T15:40:13+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "darkaonline/l5-swagger",
|
||||||
|
"version": "9.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/DarkaOnLine/L5-Swagger.git",
|
||||||
|
"reference": "2c26427f8c41db8e72232415e7287313e6b6a2e2"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/DarkaOnLine/L5-Swagger/zipball/2c26427f8c41db8e72232415e7287313e6b6a2e2",
|
||||||
|
"reference": "2c26427f8c41db8e72232415e7287313e6b6a2e2",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/annotations": "^1.0 || ^2.0",
|
||||||
|
"ext-json": "*",
|
||||||
|
"laravel/framework": "^12.0 || ^11.0",
|
||||||
|
"php": "^8.2",
|
||||||
|
"swagger-api/swagger-ui": ">=5.18.3",
|
||||||
|
"symfony/yaml": "^5.0 || ^6.0 || ^7.0",
|
||||||
|
"zircote/swagger-php": "^5.0.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"mockery/mockery": "1.*",
|
||||||
|
"orchestra/testbench": "^10.0 || ^9.0 || ^8.0 || 7.* || ^6.15 || 5.*",
|
||||||
|
"php-coveralls/php-coveralls": "^2.0",
|
||||||
|
"phpstan/phpstan": "^2.1",
|
||||||
|
"phpunit/phpunit": "^11.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"aliases": {
|
||||||
|
"L5Swagger": "L5Swagger\\L5SwaggerFacade"
|
||||||
|
},
|
||||||
|
"providers": [
|
||||||
|
"L5Swagger\\L5SwaggerServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/helpers.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"L5Swagger\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Darius Matulionis",
|
||||||
|
"email": "darius@matulionis.lt"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "OpenApi or Swagger integration to Laravel",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"documentation",
|
||||||
|
"laravel",
|
||||||
|
"openapi",
|
||||||
|
"specification",
|
||||||
|
"swagger",
|
||||||
|
"ui"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/DarkaOnLine/L5-Swagger/issues",
|
||||||
|
"source": "https://github.com/DarkaOnLine/L5-Swagger/tree/9.0.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/DarkaOnLine",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-02-28T06:25:02+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dflydev/dot-access-data",
|
"name": "dflydev/dot-access-data",
|
||||||
"version": "v3.0.3",
|
"version": "v3.0.3",
|
||||||
@ -343,6 +424,82 @@
|
|||||||
},
|
},
|
||||||
"time": "2024-07-08T12:26:09+00:00"
|
"time": "2024-07-08T12:26:09+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "doctrine/annotations",
|
||||||
|
"version": "2.0.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine/annotations.git",
|
||||||
|
"reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine/annotations/zipball/901c2ee5d26eb64ff43c47976e114bf00843acf7",
|
||||||
|
"reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/lexer": "^2 || ^3",
|
||||||
|
"ext-tokenizer": "*",
|
||||||
|
"php": "^7.2 || ^8.0",
|
||||||
|
"psr/cache": "^1 || ^2 || ^3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/cache": "^2.0",
|
||||||
|
"doctrine/coding-standard": "^10",
|
||||||
|
"phpstan/phpstan": "^1.10.28",
|
||||||
|
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||||
|
"symfony/cache": "^5.4 || ^6.4 || ^7",
|
||||||
|
"vimeo/psalm": "^4.30 || ^5.14"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Guilherme Blanco",
|
||||||
|
"email": "guilhermeblanco@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Roman Borschel",
|
||||||
|
"email": "roman@code-factory.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Benjamin Eberlei",
|
||||||
|
"email": "kontakt@beberlei.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonathan Wage",
|
||||||
|
"email": "jonwage@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Johannes Schmitt",
|
||||||
|
"email": "schmittjoh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Docblock Annotations Parser",
|
||||||
|
"homepage": "https://www.doctrine-project.org/projects/annotations.html",
|
||||||
|
"keywords": [
|
||||||
|
"annotations",
|
||||||
|
"docblock",
|
||||||
|
"parser"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/doctrine/annotations/issues",
|
||||||
|
"source": "https://github.com/doctrine/annotations/tree/2.0.2"
|
||||||
|
},
|
||||||
|
"time": "2024-09-05T10:17:24+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/inflector",
|
"name": "doctrine/inflector",
|
||||||
"version": "2.0.10",
|
"version": "2.0.10",
|
||||||
@ -3379,6 +3536,55 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-07-20T21:41:07+00:00"
|
"time": "2024-07-20T21:41:07+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/cache",
|
||||||
|
"version": "3.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/cache.git",
|
||||||
|
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
|
||||||
|
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Cache\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "https://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interface for caching libraries",
|
||||||
|
"keywords": [
|
||||||
|
"cache",
|
||||||
|
"psr",
|
||||||
|
"psr-6"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/php-fig/cache/tree/3.0.0"
|
||||||
|
},
|
||||||
|
"time": "2021-02-03T23:26:27+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/clock",
|
"name": "psr/clock",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@ -4082,6 +4288,67 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-04-27T21:32:50+00:00"
|
"time": "2024-04-27T21:32:50+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "swagger-api/swagger-ui",
|
||||||
|
"version": "v5.21.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/swagger-api/swagger-ui.git",
|
||||||
|
"reference": "fceaec605072fbc717a04895bd19814d9a1c8e6d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/fceaec605072fbc717a04895bd19814d9a1c8e6d",
|
||||||
|
"reference": "fceaec605072fbc717a04895bd19814d9a1c8e6d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"Apache-2.0"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Anna Bodnia",
|
||||||
|
"email": "anna.bodnia@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Buu Nguyen",
|
||||||
|
"email": "buunguyen@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Josh Ponelat",
|
||||||
|
"email": "jponelat@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kyle Shockey",
|
||||||
|
"email": "kyleshockey1@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Robert Barnwell",
|
||||||
|
"email": "robert@robertismy.name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sahar Jafari",
|
||||||
|
"email": "shr.jafari@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": " Swagger UI is a collection of HTML, Javascript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.",
|
||||||
|
"homepage": "http://swagger.io",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"documentation",
|
||||||
|
"openapi",
|
||||||
|
"specification",
|
||||||
|
"swagger",
|
||||||
|
"ui"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/swagger-api/swagger-ui/issues",
|
||||||
|
"source": "https://github.com/swagger-api/swagger-ui/tree/v5.21.0"
|
||||||
|
},
|
||||||
|
"time": "2025-04-13T19:37:38+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/clock",
|
"name": "symfony/clock",
|
||||||
"version": "v7.2.0",
|
"version": "v7.2.0",
|
||||||
@ -6377,6 +6644,78 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-01-17T11:39:41+00:00"
|
"time": "2025-01-17T11:39:41+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/yaml",
|
||||||
|
"version": "v7.2.5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/yaml.git",
|
||||||
|
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/yaml/zipball/4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
||||||
|
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.2",
|
||||||
|
"symfony/deprecation-contracts": "^2.5|^3.0",
|
||||||
|
"symfony/polyfill-ctype": "^1.8"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/console": "<6.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/console": "^6.4|^7.0"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"Resources/bin/yaml-lint"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Yaml\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Loads and dumps YAML files",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/yaml/tree/v7.2.5"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-03-03T07:12:39+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "tijsverkoyen/css-to-inline-styles",
|
"name": "tijsverkoyen/css-to-inline-styles",
|
||||||
"version": "v2.3.0",
|
"version": "v2.3.0",
|
||||||
@ -6647,6 +6986,92 @@
|
|||||||
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
|
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
|
||||||
},
|
},
|
||||||
"time": "2022-06-03T18:03:27+00:00"
|
"time": "2022-06-03T18:03:27+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "zircote/swagger-php",
|
||||||
|
"version": "5.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/zircote/swagger-php.git",
|
||||||
|
"reference": "a9b953c25f5bd11ea0542636936de04504496bd9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/a9b953c25f5bd11ea0542636936de04504496bd9",
|
||||||
|
"reference": "a9b953c25f5bd11ea0542636936de04504496bd9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-json": "*",
|
||||||
|
"nikic/php-parser": "^4.19 || ^5.0",
|
||||||
|
"php": ">=7.4",
|
||||||
|
"psr/log": "^1.1 || ^2.0 || ^3.0",
|
||||||
|
"symfony/deprecation-contracts": "^2 || ^3",
|
||||||
|
"symfony/finder": "^5.0 || ^6.0 || ^7.0",
|
||||||
|
"symfony/yaml": "^5.0 || ^6.0 || ^7.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/process": ">=6, <6.4.14"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"composer/package-versions-deprecated": "^1.11",
|
||||||
|
"doctrine/annotations": "^2.0",
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.62.0",
|
||||||
|
"phpstan/phpstan": "^1.6 || ^2.0",
|
||||||
|
"phpunit/phpunit": "^9.0",
|
||||||
|
"rector/rector": "^1.0 || ^2.0",
|
||||||
|
"vimeo/psalm": "^4.30 || ^5.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"doctrine/annotations": "^2.0"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"bin/openapi"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "5.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"OpenApi\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"Apache-2.0"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Robert Allen",
|
||||||
|
"email": "zircote@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bob Fanger",
|
||||||
|
"email": "bfanger@gmail.com",
|
||||||
|
"homepage": "https://bfanger.nl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Martin Rademacher",
|
||||||
|
"email": "mano@radebatz.net",
|
||||||
|
"homepage": "https://radebatz.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Generate interactive documentation for your RESTful API using PHP attributes (preferred) or PHPDoc annotations",
|
||||||
|
"homepage": "https://github.com/zircote/swagger-php",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"json",
|
||||||
|
"rest",
|
||||||
|
"service discovery"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/zircote/swagger-php/issues",
|
||||||
|
"source": "https://github.com/zircote/swagger-php/tree/5.1.0"
|
||||||
|
},
|
||||||
|
"time": "2025-04-18T00:35:12+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
@ -9686,78 +10111,6 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-10-20T05:08:20+00:00"
|
"time": "2024-10-20T05:08:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "symfony/yaml",
|
|
||||||
"version": "v7.2.5",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/yaml.git",
|
|
||||||
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
|
||||||
"reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=8.2",
|
|
||||||
"symfony/deprecation-contracts": "^2.5|^3.0",
|
|
||||||
"symfony/polyfill-ctype": "^1.8"
|
|
||||||
},
|
|
||||||
"conflict": {
|
|
||||||
"symfony/console": "<6.4"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"symfony/console": "^6.4|^7.0"
|
|
||||||
},
|
|
||||||
"bin": [
|
|
||||||
"Resources/bin/yaml-lint"
|
|
||||||
],
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Symfony\\Component\\Yaml\\": ""
|
|
||||||
},
|
|
||||||
"exclude-from-classmap": [
|
|
||||||
"/Tests/"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Fabien Potencier",
|
|
||||||
"email": "fabien@symfony.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "https://symfony.com/contributors"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Loads and dumps YAML files",
|
|
||||||
"homepage": "https://symfony.com",
|
|
||||||
"support": {
|
|
||||||
"source": "https://github.com/symfony/yaml/tree/v7.2.5"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://symfony.com/sponsor",
|
|
||||||
"type": "custom"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://github.com/fabpot",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
|
||||||
"type": "tidelift"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2025-03-03T07:12:39+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "ta-tikoma/phpunit-architecture-test",
|
"name": "ta-tikoma/phpunit-architecture-test",
|
||||||
"version": "0.8.4",
|
"version": "0.8.4",
|
||||||
|
|||||||
318
API/Sanctum/config/l5-swagger.php
Normal file
318
API/Sanctum/config/l5-swagger.php
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'default' => 'default',
|
||||||
|
'documentations' => [
|
||||||
|
'default' => [
|
||||||
|
'api' => [
|
||||||
|
'title' => 'L5 Swagger UI',
|
||||||
|
],
|
||||||
|
|
||||||
|
'routes' => [
|
||||||
|
/*
|
||||||
|
* Route for accessing api documentation interface
|
||||||
|
*/
|
||||||
|
'api' => 'api/documentation',
|
||||||
|
],
|
||||||
|
'paths' => [
|
||||||
|
/*
|
||||||
|
* Edit to include full URL in ui for assets
|
||||||
|
*/
|
||||||
|
'use_absolute_path' => env('L5_SWAGGER_USE_ABSOLUTE_PATH', true),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edit to set path where swagger ui assets should be stored
|
||||||
|
*/
|
||||||
|
'swagger_ui_assets_path' => env('L5_SWAGGER_UI_ASSETS_PATH', 'vendor/swagger-api/swagger-ui/dist/'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File name of the generated json documentation file
|
||||||
|
*/
|
||||||
|
'docs_json' => 'api-docs.json',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File name of the generated YAML documentation file
|
||||||
|
*/
|
||||||
|
'docs_yaml' => 'api-docs.yaml',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set this to `json` or `yaml` to determine which documentation file to use in UI
|
||||||
|
*/
|
||||||
|
'format_to_use_for_docs' => env('L5_FORMAT_TO_USE_FOR_DOCS', 'json'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute paths to directory containing the swagger annotations are stored.
|
||||||
|
*/
|
||||||
|
'annotations' => [
|
||||||
|
base_path('app'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'defaults' => [
|
||||||
|
'routes' => [
|
||||||
|
/*
|
||||||
|
* Route for accessing parsed swagger annotations.
|
||||||
|
*/
|
||||||
|
'docs' => 'docs',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Route for Oauth2 authentication callback.
|
||||||
|
*/
|
||||||
|
'oauth2_callback' => 'api/oauth2-callback',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Middleware allows to prevent unexpected access to API documentation
|
||||||
|
*/
|
||||||
|
'middleware' => [
|
||||||
|
'api' => [],
|
||||||
|
'asset' => [],
|
||||||
|
'docs' => [],
|
||||||
|
'oauth2_callback' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Route Group options
|
||||||
|
*/
|
||||||
|
'group_options' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
'paths' => [
|
||||||
|
/*
|
||||||
|
* Absolute path to location where parsed annotations will be stored
|
||||||
|
*/
|
||||||
|
'docs' => storage_path('api-docs'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute path to directory where to export views
|
||||||
|
*/
|
||||||
|
'views' => base_path('resources/views/vendor/l5-swagger'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edit to set the api's base path
|
||||||
|
*/
|
||||||
|
'base' => env('L5_SWAGGER_BASE_PATH', null),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute path to directories that should be excluded from scanning
|
||||||
|
* @deprecated Please use `scanOptions.exclude`
|
||||||
|
* `scanOptions.exclude` overwrites this
|
||||||
|
*/
|
||||||
|
'excludes' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
'scanOptions' => [
|
||||||
|
/**
|
||||||
|
* Configuration for default processors. Allows to pass processors configuration to swagger-php.
|
||||||
|
*
|
||||||
|
* @link https://zircote.github.io/swagger-php/reference/processors.html
|
||||||
|
*/
|
||||||
|
'default_processors_configuration' => [
|
||||||
|
/** Example */
|
||||||
|
/**
|
||||||
|
* 'operationId.hash' => true,
|
||||||
|
* 'pathFilter' => [
|
||||||
|
* 'tags' => [
|
||||||
|
* '/pets/',
|
||||||
|
* '/store/',
|
||||||
|
* ],
|
||||||
|
* ],.
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* analyser: defaults to \OpenApi\StaticAnalyser .
|
||||||
|
*
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'analyser' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* analysis: defaults to a new \OpenApi\Analysis .
|
||||||
|
*
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'analysis' => null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom query path processors classes.
|
||||||
|
*
|
||||||
|
* @link https://github.com/zircote/swagger-php/tree/master/Examples/processors/schema-query-parameter
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'processors' => [
|
||||||
|
// new \App\SwaggerProcessors\SchemaQueryParameter(),
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pattern: string $pattern File pattern(s) to scan (default: *.php) .
|
||||||
|
*
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'pattern' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Absolute path to directories that should be excluded from scanning
|
||||||
|
* @note This option overwrites `paths.excludes`
|
||||||
|
* @see \OpenApi\scan
|
||||||
|
*/
|
||||||
|
'exclude' => [],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allows to generate specs either for OpenAPI 3.0.0 or OpenAPI 3.1.0.
|
||||||
|
* By default the spec will be in version 3.0.0
|
||||||
|
*/
|
||||||
|
'open_api_spec_version' => env('L5_SWAGGER_OPEN_API_SPEC_VERSION', \L5Swagger\Generator::OPEN_API_DEFAULT_SPEC_VERSION),
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* API security definitions. Will be generated into documentation file.
|
||||||
|
*/
|
||||||
|
'securityDefinitions' => [
|
||||||
|
'securitySchemes' => [
|
||||||
|
/*
|
||||||
|
* Examples of Security schemes
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
'api_key_security_example' => [ // Unique name of security
|
||||||
|
'type' => 'apiKey', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'A short description for security scheme',
|
||||||
|
'name' => 'api_key', // The name of the header or query parameter to be used.
|
||||||
|
'in' => 'header', // The location of the API key. Valid values are "query" or "header".
|
||||||
|
],
|
||||||
|
'oauth2_security_example' => [ // Unique name of security
|
||||||
|
'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'A short description for oauth2 security scheme.',
|
||||||
|
'flow' => 'implicit', // The flow used by the OAuth2 security scheme. Valid values are "implicit", "password", "application" or "accessCode".
|
||||||
|
'authorizationUrl' => 'http://example.com/auth', // The authorization URL to be used for (implicit/accessCode)
|
||||||
|
//'tokenUrl' => 'http://example.com/auth' // The authorization URL to be used for (password/application/accessCode)
|
||||||
|
'scopes' => [
|
||||||
|
'read:projects' => 'read your projects',
|
||||||
|
'write:projects' => 'modify projects in your account',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Open API 3.0 support
|
||||||
|
'passport' => [ // Unique name of security
|
||||||
|
'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'Laravel passport oauth2 security.',
|
||||||
|
'in' => 'header',
|
||||||
|
'scheme' => 'https',
|
||||||
|
'flows' => [
|
||||||
|
"password" => [
|
||||||
|
"authorizationUrl" => config('app.url') . '/oauth/authorize',
|
||||||
|
"tokenUrl" => config('app.url') . '/oauth/token',
|
||||||
|
"refreshUrl" => config('app.url') . '/token/refresh',
|
||||||
|
"scopes" => []
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'sanctum' => [ // Unique name of security
|
||||||
|
'type' => 'apiKey', // Valid values are "basic", "apiKey" or "oauth2".
|
||||||
|
'description' => 'Enter token in format (Bearer <token>)',
|
||||||
|
'name' => 'Authorization', // The name of the header or query parameter to be used.
|
||||||
|
'in' => 'header', // The location of the API key. Valid values are "query" or "header".
|
||||||
|
],
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
'security' => [
|
||||||
|
/*
|
||||||
|
* Examples of Securities
|
||||||
|
*/
|
||||||
|
[
|
||||||
|
/*
|
||||||
|
'oauth2_security_example' => [
|
||||||
|
'read',
|
||||||
|
'write'
|
||||||
|
],
|
||||||
|
|
||||||
|
'passport' => []
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set this to `true` in development mode so that docs would be regenerated on each request
|
||||||
|
* Set this to `false` to disable swagger generation on production
|
||||||
|
*/
|
||||||
|
'generate_always' => env('L5_SWAGGER_GENERATE_ALWAYS', false),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set this to `true` to generate a copy of documentation in yaml format
|
||||||
|
*/
|
||||||
|
'generate_yaml_copy' => env('L5_SWAGGER_GENERATE_YAML_COPY', false),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edit to trust the proxy's ip address - needed for AWS Load Balancer
|
||||||
|
* string[]
|
||||||
|
*/
|
||||||
|
'proxy' => false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configs plugin allows to fetch external configs instead of passing them to SwaggerUIBundle.
|
||||||
|
* See more at: https://github.com/swagger-api/swagger-ui#configs-plugin
|
||||||
|
*/
|
||||||
|
'additional_config_url' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically),
|
||||||
|
* 'method' (sort by HTTP method).
|
||||||
|
* Default is the order returned by the server unchanged.
|
||||||
|
*/
|
||||||
|
'operations_sort' => env('L5_SWAGGER_OPERATIONS_SORT', null),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pass the validatorUrl parameter to SwaggerUi init on the JS side.
|
||||||
|
* A null value here disables validation.
|
||||||
|
*/
|
||||||
|
'validator_url' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Swagger UI configuration parameters
|
||||||
|
*/
|
||||||
|
'ui' => [
|
||||||
|
'display' => [
|
||||||
|
'dark_mode' => env('L5_SWAGGER_UI_DARK_MODE', false),
|
||||||
|
/*
|
||||||
|
* Controls the default expansion setting for the operations and tags. It can be :
|
||||||
|
* 'list' (expands only the tags),
|
||||||
|
* 'full' (expands the tags and operations),
|
||||||
|
* 'none' (expands nothing).
|
||||||
|
*/
|
||||||
|
'doc_expansion' => env('L5_SWAGGER_UI_DOC_EXPANSION', 'none'),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set, enables filtering. The top bar will show an edit box that
|
||||||
|
* you can use to filter the tagged operations that are shown. Can be
|
||||||
|
* Boolean to enable or disable, or a string, in which case filtering
|
||||||
|
* will be enabled using that string as the filter expression. Filtering
|
||||||
|
* is case-sensitive matching the filter expression anywhere inside
|
||||||
|
* the tag.
|
||||||
|
*/
|
||||||
|
'filter' => env('L5_SWAGGER_UI_FILTERS', true), // true | false
|
||||||
|
],
|
||||||
|
|
||||||
|
'authorization' => [
|
||||||
|
/*
|
||||||
|
* If set to true, it persists authorization data, and it would not be lost on browser close/refresh
|
||||||
|
*/
|
||||||
|
'persist_authorization' => env('L5_SWAGGER_UI_PERSIST_AUTHORIZATION', false),
|
||||||
|
|
||||||
|
'oauth2' => [
|
||||||
|
/*
|
||||||
|
* If set to true, adds PKCE to AuthorizationCodeGrant flow
|
||||||
|
*/
|
||||||
|
'use_pkce_with_authorization_code_grant' => false,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
/*
|
||||||
|
* Constants which can be used in annotations
|
||||||
|
*/
|
||||||
|
'constants' => [
|
||||||
|
'L5_SWAGGER_CONST_HOST' => env('L5_SWAGGER_CONST_HOST', 'http://my-default-host.com'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
0
API/Sanctum/resources/views/vendor/l5-swagger/.gitkeep
vendored
Normal file
0
API/Sanctum/resources/views/vendor/l5-swagger/.gitkeep
vendored
Normal file
174
API/Sanctum/resources/views/vendor/l5-swagger/index.blade.php
vendored
Normal file
174
API/Sanctum/resources/views/vendor/l5-swagger/index.blade.php
vendored
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{{ $documentationTitle }}</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ l5_swagger_asset($documentation, 'swagger-ui.css') }}">
|
||||||
|
<link rel="icon" type="image/png" href="{{ l5_swagger_asset($documentation, 'favicon-32x32.png') }}" sizes="32x32"/>
|
||||||
|
<link rel="icon" type="image/png" href="{{ l5_swagger_asset($documentation, 'favicon-16x16.png') }}" sizes="16x16"/>
|
||||||
|
<style>
|
||||||
|
html
|
||||||
|
{
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: -moz-scrollbars-vertical;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after
|
||||||
|
{
|
||||||
|
box-sizing: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin:0;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@if(config('l5-swagger.defaults.ui.display.dark_mode'))
|
||||||
|
<style>
|
||||||
|
body#dark-mode,
|
||||||
|
#dark-mode .scheme-container {
|
||||||
|
background: #1b1b1b;
|
||||||
|
}
|
||||||
|
#dark-mode .scheme-container,
|
||||||
|
#dark-mode .opblock .opblock-section-header{
|
||||||
|
box-shadow: 0 1px 2px 0 rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
#dark-mode .operation-filter-input,
|
||||||
|
#dark-mode .dialog-ux .modal-ux,
|
||||||
|
#dark-mode input[type=email],
|
||||||
|
#dark-mode input[type=file],
|
||||||
|
#dark-mode input[type=password],
|
||||||
|
#dark-mode input[type=search],
|
||||||
|
#dark-mode input[type=text],
|
||||||
|
#dark-mode textarea{
|
||||||
|
background: #343434;
|
||||||
|
color: #e7e7e7;
|
||||||
|
}
|
||||||
|
#dark-mode .title,
|
||||||
|
#dark-mode li,
|
||||||
|
#dark-mode p,
|
||||||
|
#dark-mode table,
|
||||||
|
#dark-mode label,
|
||||||
|
#dark-mode .opblock-tag,
|
||||||
|
#dark-mode .opblock .opblock-summary-operation-id,
|
||||||
|
#dark-mode .opblock .opblock-summary-path,
|
||||||
|
#dark-mode .opblock .opblock-summary-path__deprecated,
|
||||||
|
#dark-mode h1,
|
||||||
|
#dark-mode h2,
|
||||||
|
#dark-mode h3,
|
||||||
|
#dark-mode h4,
|
||||||
|
#dark-mode h5,
|
||||||
|
#dark-mode .btn,
|
||||||
|
#dark-mode .tab li,
|
||||||
|
#dark-mode .parameter__name,
|
||||||
|
#dark-mode .parameter__type,
|
||||||
|
#dark-mode .prop-format,
|
||||||
|
#dark-mode .loading-container .loading:after{
|
||||||
|
color: #e7e7e7;
|
||||||
|
}
|
||||||
|
#dark-mode .opblock-description-wrapper p,
|
||||||
|
#dark-mode .opblock-external-docs-wrapper p,
|
||||||
|
#dark-mode .opblock-title_normal p,
|
||||||
|
#dark-mode .response-col_status,
|
||||||
|
#dark-mode table thead tr td,
|
||||||
|
#dark-mode table thead tr th,
|
||||||
|
#dark-mode .response-col_links,
|
||||||
|
#dark-mode .swagger-ui{
|
||||||
|
color: wheat;
|
||||||
|
}
|
||||||
|
#dark-mode .parameter__extension,
|
||||||
|
#dark-mode .parameter__in,
|
||||||
|
#dark-mode .model-title{
|
||||||
|
color: #949494;
|
||||||
|
}
|
||||||
|
#dark-mode table thead tr td,
|
||||||
|
#dark-mode table thead tr th{
|
||||||
|
border-color: rgba(120,120,120,.2);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock .opblock-section-header{
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-post{
|
||||||
|
background: rgba(73,204,144,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-get{
|
||||||
|
background: rgba(97,175,254,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-put{
|
||||||
|
background: rgba(252,161,48,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .opblock.opblock-delete{
|
||||||
|
background: rgba(249,62,62,.25);
|
||||||
|
}
|
||||||
|
#dark-mode .loading-container .loading:before{
|
||||||
|
border-color: rgba(255,255,255,10%);
|
||||||
|
border-top-color: rgba(255,255,255,.6);
|
||||||
|
}
|
||||||
|
#dark-mode svg:not(:root){
|
||||||
|
fill: #e7e7e7;
|
||||||
|
}
|
||||||
|
#dark-mode .opblock-summary-description {
|
||||||
|
color: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@endif
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body @if(config('l5-swagger.defaults.ui.display.dark_mode')) id="dark-mode" @endif>
|
||||||
|
<div id="swagger-ui"></div>
|
||||||
|
|
||||||
|
<script src="{{ l5_swagger_asset($documentation, 'swagger-ui-bundle.js') }}"></script>
|
||||||
|
<script src="{{ l5_swagger_asset($documentation, 'swagger-ui-standalone-preset.js') }}"></script>
|
||||||
|
<script>
|
||||||
|
window.onload = function() {
|
||||||
|
const urls = [];
|
||||||
|
|
||||||
|
@foreach($urlsToDocs as $title => $url)
|
||||||
|
urls.push({name: "{{ $title }}", url: "{{ $url }}"});
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
// Build a system
|
||||||
|
const ui = SwaggerUIBundle({
|
||||||
|
dom_id: '#swagger-ui',
|
||||||
|
urls: urls,
|
||||||
|
"urls.primaryName": "{{ $documentationTitle }}",
|
||||||
|
operationsSorter: {!! isset($operationsSorter) ? '"' . $operationsSorter . '"' : 'null' !!},
|
||||||
|
configUrl: {!! isset($configUrl) ? '"' . $configUrl . '"' : 'null' !!},
|
||||||
|
validatorUrl: {!! isset($validatorUrl) ? '"' . $validatorUrl . '"' : 'null' !!},
|
||||||
|
oauth2RedirectUrl: "{{ route('l5-swagger.'.$documentation.'.oauth2_callback', [], $useAbsolutePath) }}",
|
||||||
|
|
||||||
|
requestInterceptor: function(request) {
|
||||||
|
request.headers['X-CSRF-TOKEN'] = '{{ csrf_token() }}';
|
||||||
|
return request;
|
||||||
|
},
|
||||||
|
|
||||||
|
presets: [
|
||||||
|
SwaggerUIBundle.presets.apis,
|
||||||
|
SwaggerUIStandalonePreset
|
||||||
|
],
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
SwaggerUIBundle.plugins.DownloadUrl
|
||||||
|
],
|
||||||
|
|
||||||
|
layout: "StandaloneLayout",
|
||||||
|
docExpansion : "{!! config('l5-swagger.defaults.ui.display.doc_expansion', 'none') !!}",
|
||||||
|
deepLinking: true,
|
||||||
|
filter: {!! config('l5-swagger.defaults.ui.display.filter') ? 'true' : 'false' !!},
|
||||||
|
persistAuthorization: "{!! config('l5-swagger.defaults.ui.authorization.persist_authorization') ? 'true' : 'false' !!}",
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
window.ui = ui
|
||||||
|
|
||||||
|
@if(in_array('oauth2', array_column(config('l5-swagger.defaults.securityDefinitions.securitySchemes'), 'type')))
|
||||||
|
ui.initOAuth({
|
||||||
|
usePkceWithAuthorizationCodeGrant: "{!! (bool)config('l5-swagger.defaults.ui.authorization.oauth2.use_pkce_with_authorization_code_grant') !!}"
|
||||||
|
})
|
||||||
|
@endif
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -11,13 +11,13 @@ Route::get('/user', function (Request $request) {
|
|||||||
return $request->user();
|
return $request->user();
|
||||||
})->middleware('auth:sanctum');
|
})->middleware('auth:sanctum');
|
||||||
|
|
||||||
Route::group(['prefix' => 'auth', 'middleware' => ['guest']], function () {
|
Route::group(['middleware' => ['guest']], function () {
|
||||||
Route::post('register', [RegisterController::class, 'register'])->name('register');
|
Route::post('register', [RegisterController::class, 'register'])->name('register');
|
||||||
Route::post('login', [LoginController::class, 'login'])->name('login');
|
Route::post('login', [LoginController::class, 'login'])->name('login');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::group(['prefix' => ['auth'], 'middleware' => ['auth:sanctum']], function () {
|
Route::group(['middleware' => ['auth:sanctum']], function () {
|
||||||
Route::post('logout', action: [LogoutController::class, 'logout'])->name('logout');
|
Route::post('logout', action: [LogoutController::class, 'logout'])->name('logout');
|
||||||
Route::get(uri: 'profile', action: [RegisterController::class, 'profile'])->name('profile');
|
Route::get(uri: 'profile', action: [RegisterController::class, 'profile'])->name('profile');
|
||||||
Route::post('deleteAccount', [DeleteAccountController::class, 'deleteAccount'])->name('delete.account');
|
Route::delete('deleteAccount', [DeleteAccountController::class, 'deleteAccount'])->name('delete.account');
|
||||||
});
|
});
|
||||||
|
|||||||
356
API/Sanctum/storage/api-docs/api-docs.json
Normal file
356
API/Sanctum/storage/api-docs/api-docs.json
Normal file
@ -0,0 +1,356 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.0.0",
|
||||||
|
"info": {
|
||||||
|
"title": "API Documentation",
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"/api/deleteAccount": {
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "Delete user account",
|
||||||
|
"description": "Deletes the user's account and invalidates their tokens.",
|
||||||
|
"operationId": "dab9c1b923636bca3b073db3bdf87db0",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Account deleted successfully",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Your account has been deleted successfully. We’re sorry to see you go."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal server error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "We couldn’t delete your account at this moment. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/login": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "Login user",
|
||||||
|
"description": "Login a user with email and password, and return an authentication token.",
|
||||||
|
"operationId": "e3ce052cc00fd9dd647e77abd7807e14",
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"email",
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "12345678"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "User successfully logged in and token provided",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Login successful. Welcome back!"
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "nima malakooti"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "your-token-here"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized access",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Unauthorized access. Please check your credentials and try again."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal server error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Failed to login user. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/logout": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "Logout the user",
|
||||||
|
"description": "Invalidate the user's session by deleting their tokens and logging them out.",
|
||||||
|
"operationId": "ad0ae046131d33ce33ee57a7f8a6a3f0",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successfully logged out",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "You have been logged out successfully. Come back soon!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal server error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Oops! Something went wrong while logging out. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/register": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Authentication"
|
||||||
|
],
|
||||||
|
"summary": "Register a new user",
|
||||||
|
"description": "Register a new user with name, email, and password and return a user object with authentication token.",
|
||||||
|
"operationId": "97cd8d12c6b5cf0267b29ff739a126f8",
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"email",
|
||||||
|
"password",
|
||||||
|
"password_confirmation"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "nima malakooti"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "12345678"
|
||||||
|
},
|
||||||
|
"password_confirmation": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "password",
|
||||||
|
"example": "12345678"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "User successfully registered and token provided",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "User registered successfully."
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "nima malakooti"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "nima.8ak@gmail.com"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "your-token-here"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal server error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 0
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Failed to register user. Please try again later."
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Exception message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"name": "Authentication",
|
||||||
|
"description": "Authentication"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
109
README.md
109
README.md
@ -1,2 +1,107 @@
|
|||||||
# Laravel-Authentication-System
|
# Laravel Authentication System 🔐
|
||||||
Practical examples of Laravel authentication using official packages like Fortify, Passport & more.
|
|
||||||
|
A complete authentication setup with Passport, Sanctum, JWT, Fortify, Starter Kit, and manual implementations for both API and Web — all in one place.
|
||||||
|
|
||||||
|
[GitHub Repository](https://github.com/Nima8FT/Laravel-Authentication-System)
|
||||||
|
|
||||||
|
Version: [1.0.0]
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
1. [🚀 Overview](#1-overview)
|
||||||
|
2. [✨ Features](#2-features)
|
||||||
|
3. [🛠️ Installation](#3-installation)
|
||||||
|
4. [⚙️ Configuration](#4-configuration)
|
||||||
|
5. [💻 Usage](#5-usage)
|
||||||
|
6. [🗂️ Project Structure](#6-project-structure)
|
||||||
|
7. [🧪 Running Tests](#7-running-tests)
|
||||||
|
8. [🤝 Contributing](#8-contributing)
|
||||||
|
9. [📝 License](#9-license)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 1. Overview
|
||||||
|
|
||||||
|
This repository implements all major Laravel authentication packages for both API and web contexts. For API, it integrates Passport, Sanctum, and JWT; for web, it uses Fortify, the Laravel Starter Kit, and a manual implementation. The goal is to provide a one-stop reference so developers can immediately leverage a complete auth stack without extra wiring.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Features
|
||||||
|
|
||||||
|
**🔐 API Authentication**
|
||||||
|
- **Laravel Passport** – OAuth2-based full-featured API authentication
|
||||||
|
- **Laravel Sanctum** – Lightweight SPA token authentication
|
||||||
|
- **JWT** – Using `tymondesigns/jwt-auth` for stateless APIs
|
||||||
|
|
||||||
|
**🧭 Web Authentication**
|
||||||
|
- **Fortify** – Backend auth logic (no UI)
|
||||||
|
- **Starter Kit** – Prebuilt Blade or Vue scaffolding
|
||||||
|
- **Manual** – Fully custom controllers & middleware
|
||||||
|
|
||||||
|
**💡 Common Features**
|
||||||
|
- User registration, login, logout, and deletion
|
||||||
|
- "Remember Me", email verification, password reset
|
||||||
|
- Social login (Google, Facebook)
|
||||||
|
- Two-Factor Authentication (2FA)
|
||||||
|
- Session management (“Logout Other Devices”)
|
||||||
|
- Profile management, CAPTCHA protection
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/Nima8FT/Laravel-Authentication-System.git
|
||||||
|
cd Laravel-Authentication-System
|
||||||
|
composer install
|
||||||
|
cp .env.example .env
|
||||||
|
php artisan key:generate
|
||||||
|
php artisan migrate
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Configuration
|
||||||
|
|
||||||
|
Update your `.env` file with the proper DB credentials and any third-party API keys for social login or CAPTCHA.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Usage
|
||||||
|
|
||||||
|
- Use Postman or your preferred client to interact with the API routes.
|
||||||
|
- Web routes are accessible via your browser.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. Project Structure
|
||||||
|
|
||||||
|
- `app/Http/Controllers/Auth/` - Custom auth logic
|
||||||
|
- `routes/web.php` and `routes/api.php` - Separate route files for web and API
|
||||||
|
- `config/auth.php` - Auth guard configuration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 7. Running Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
php artisan serve
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 8. Contributing
|
||||||
|
|
||||||
|
1. Fork this repository.
|
||||||
|
2. Create a branch: `git checkout -b my-feature`.
|
||||||
|
3. Make your changes and commit them: `git commit -m 'Add some feature'`.
|
||||||
|
4. Push to the branch: `git push origin my-feature`.
|
||||||
|
5. Submit a pull request.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 9. License
|
||||||
|
|
||||||
|
This project is open-sourced software
|
||||||
|
|
||||||
|
---
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\DeviceSession;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class BrowseSessionController extends Controller
|
||||||
|
{
|
||||||
|
public function browseSession()
|
||||||
|
{
|
||||||
|
$user = Auth::user();
|
||||||
|
$device_sessions = DeviceSession::where("user_id", $user->id)->get();
|
||||||
|
return view("auth.browse-session", compact(['device_sessions','user']));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,10 +2,13 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Auth;
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use Jenssegers\Agent\Agent;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\DeviceSession;
|
||||||
use App\Http\Requests\LoginRequest;
|
use App\Http\Requests\LoginRequest;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
|
||||||
class LoginController extends Controller
|
class LoginController extends Controller
|
||||||
{
|
{
|
||||||
@ -21,19 +24,45 @@ class LoginController extends Controller
|
|||||||
|
|
||||||
$remember = $request->has('remember');
|
$remember = $request->has('remember');
|
||||||
|
|
||||||
|
//captcha
|
||||||
|
$response = Http::asForm()->post('https://hcaptcha.com/siteverify', [
|
||||||
|
'secret' => 'ES_f05ab02ddc424bbabca7e82b79f1c09f',
|
||||||
|
'response' => $request->input('h-captcha-response'),
|
||||||
|
'remoteip' => $request->ip(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$verification = $response->json();
|
||||||
|
|
||||||
|
if (!isset($verification['success']) || $verification['success'] !== true) {
|
||||||
|
return back()->withErrors(['error' => 'The captcha is incorrect.']);
|
||||||
|
}
|
||||||
|
|
||||||
if (!Auth::attempt($credentials, $remember)) {
|
if (!Auth::attempt($credentials, $remember)) {
|
||||||
return back()->withErrors([
|
return back()->withErrors([
|
||||||
'email' => 'The provided credentials do not match our records.',
|
'email' => 'These credentials do not match our records.',
|
||||||
])->onlyInput('email');
|
])->onlyInput('email');
|
||||||
}
|
}
|
||||||
|
|
||||||
$request->session()->regenerate();
|
$request->session()->regenerate();
|
||||||
|
|
||||||
return redirect()->route('dashboard')->with("success", "login successfully");
|
//browse session
|
||||||
|
$agent = new Agent();
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
DeviceSession::create([
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'session_id' => session()->getId(),
|
||||||
|
'browser' => $agent->browser(),
|
||||||
|
'os' => $agent->platform(),
|
||||||
|
'device' => $agent->device(),
|
||||||
|
'is_mobile' => $agent->isMobile()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->route('dashboard')->with("success", "Logged in successfully.");
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('login.create')
|
->route('login.create')
|
||||||
->with('error', 'not login please try again' . $e->getMessage());
|
->with('error', 'Login failed. Please try again. ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,9 +3,11 @@
|
|||||||
namespace App\Http\Controllers\Auth;
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\DeviceSession;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Session;
|
||||||
|
|
||||||
class LogoutController extends Controller
|
class LogoutController extends Controller
|
||||||
{
|
{
|
||||||
@ -21,6 +23,8 @@ class LogoutController extends Controller
|
|||||||
'verify2fa' => 0,
|
'verify2fa' => 0,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
DeviceSession::where('session_id', session()->getId())->delete();
|
||||||
|
|
||||||
Auth::logout();
|
Auth::logout();
|
||||||
|
|
||||||
$request->session()->invalidate();
|
$request->session()->invalidate();
|
||||||
@ -36,8 +40,26 @@ class LogoutController extends Controller
|
|||||||
$request->session()->invalidate();
|
$request->session()->invalidate();
|
||||||
$request->session()->regenerateToken();
|
$request->session()->regenerateToken();
|
||||||
|
|
||||||
|
DeviceSession::where('user_id', $this->user->id)->delete();
|
||||||
|
|
||||||
$this->user->delete();
|
$this->user->delete();
|
||||||
|
|
||||||
return redirect()->route('login')->with('success', 'Your account has been deleted successfully.');
|
return redirect()->route('login')->with('success', 'Your account has been deleted successfully.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function logoutOtherDevice(Request $request)
|
||||||
|
{
|
||||||
|
$currentSessionId = Session::getId();
|
||||||
|
|
||||||
|
DB::table('sessions')
|
||||||
|
->where('user_id', $this->user->id)
|
||||||
|
->where('id', '!=', $currentSessionId)
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
DeviceSession::where('user_id', $this->user->id)
|
||||||
|
->where('session_id', '!=', $currentSessionId)
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
return back()->with('success', 'logout other system successfully');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,8 @@ use App\Models\User;
|
|||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\ChangePasswordRequest;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Facades\Password;
|
use Illuminate\Support\Facades\Password;
|
||||||
use Illuminate\Auth\Events\PasswordReset;
|
use Illuminate\Auth\Events\PasswordReset;
|
||||||
@ -54,4 +56,23 @@ class PasswordController extends Controller
|
|||||||
? redirect()->route('login')->with('status', __($status))
|
? redirect()->route('login')->with('status', __($status))
|
||||||
: back()->withErrors(['email' => [__($status)]]);
|
: back()->withErrors(['email' => [__($status)]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function changePasswordPage()
|
||||||
|
{
|
||||||
|
$user = Auth::user();
|
||||||
|
return view('auth.change-password', compact('user'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function changePassword(ChangePasswordRequest $request)
|
||||||
|
{
|
||||||
|
$inputs = $request->all();
|
||||||
|
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
$user->update([
|
||||||
|
'password' => Hash::make($inputs['password']),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->route('dashboard')->with('success', 'Password updated successfully.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\ProfileRequest;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class ProfileController extends Controller
|
||||||
|
{
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->user = Auth::user();
|
||||||
|
}
|
||||||
|
public function showProfile()
|
||||||
|
{
|
||||||
|
$user = $this->user;
|
||||||
|
return view("auth.profile", compact("user"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateProfile(ProfileRequest $request)
|
||||||
|
{
|
||||||
|
$inputs = $request->only('name', 'email');
|
||||||
|
$data = ['name' => $inputs['name']];
|
||||||
|
|
||||||
|
if ($inputs['email'] !== $this->user->email) {
|
||||||
|
$data['email'] = $inputs['email'];
|
||||||
|
$data['email_verified_at'] = null;
|
||||||
|
$data['remember_token'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->user->update($data);
|
||||||
|
|
||||||
|
return redirect()->route("dashboard")->with("success", "Profile updated successfully.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,7 +3,9 @@
|
|||||||
namespace App\Http\Controllers\Auth;
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Jenssegers\Agent\Agent;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\DeviceSession;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
@ -27,11 +29,24 @@ class RegisterController extends Controller
|
|||||||
|
|
||||||
Auth::login($user);
|
Auth::login($user);
|
||||||
|
|
||||||
return redirect()->route('dashboard')->with('success', 'register successfully');
|
//browse session
|
||||||
|
$agent = new Agent();
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
DeviceSession::create([
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'session_id' => session()->getId(),
|
||||||
|
'browser' => $agent->browser(),
|
||||||
|
'os' => $agent->platform(),
|
||||||
|
'device' => $agent->device(),
|
||||||
|
'is_mobile' => $agent->isMobile()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->route('dashboard')->with('success', 'Registered successfully.');
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('register.create')
|
->route('register.create')
|
||||||
->with('error', 'not register please try again' . $e->getMessage());
|
->with('error', 'Registration failed. Please try again. ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class ChangePasswordRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'password' => 'required|min:8|confirmed',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,6 +24,7 @@ class LoginRequest extends FormRequest
|
|||||||
return [
|
return [
|
||||||
'email' => 'required|email',
|
'email' => 'required|email',
|
||||||
'password' => 'required|min:8',
|
'password' => 'required|min:8',
|
||||||
|
'h-captcha-response' => 'required',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class ProfileRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => 'required|string|max:255',
|
||||||
|
'email' => 'required|email|unique:users,email,' . auth()->id(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Web-Application/Manually/app/Models/DeviceSession.php
Normal file
12
Web-Application/Manually/app/Models/DeviceSession.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class DeviceSession extends Model
|
||||||
|
{
|
||||||
|
protected $table = "device_sessions";
|
||||||
|
|
||||||
|
protected $fillable = ['user_id', 'session_id', 'browser', 'os', 'device', 'is_mobile'];
|
||||||
|
}
|
||||||
@ -25,7 +25,9 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||||||
'github_token',
|
'github_token',
|
||||||
'github_refresh_token',
|
'github_refresh_token',
|
||||||
'google2fa_secret',
|
'google2fa_secret',
|
||||||
'verify2fa'
|
'verify2fa',
|
||||||
|
'email_verified_at',
|
||||||
|
'remember_token'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
"bacon/bacon-qr-code": "^3.0",
|
"bacon/bacon-qr-code": "^3.0",
|
||||||
|
"jenssegers/agent": "^2.6",
|
||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/socialite": "^5.20",
|
"laravel/socialite": "^5.20",
|
||||||
"laravel/tinker": "^2.10.1",
|
"laravel/tinker": "^2.10.1",
|
||||||
|
|||||||
199
Web-Application/Manually/composer.lock
generated
199
Web-Application/Manually/composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "7ec9c18ae33503f4d06a9ce3cef2e3cf",
|
"content-hash": "697d12ed7febd693f209d0ab08d7631b",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "bacon/bacon-qr-code",
|
"name": "bacon/bacon-qr-code",
|
||||||
@ -1354,6 +1354,141 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-02-03T10:55:03+00:00"
|
"time": "2025-02-03T10:55:03+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "jaybizzle/crawler-detect",
|
||||||
|
"version": "v1.3.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/JayBizzle/Crawler-Detect.git",
|
||||||
|
"reference": "d3b7ff28994e1b0de764ab7412fa269a79634ff3"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/d3b7ff28994e1b0de764ab7412fa269a79634ff3",
|
||||||
|
"reference": "d3b7ff28994e1b0de764ab7412fa269a79634ff3",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.8|^5.5|^6.5|^9.4"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Jaybizzle\\CrawlerDetect\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mark Beech",
|
||||||
|
"email": "m@rkbee.ch",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "CrawlerDetect is a PHP class for detecting bots/crawlers/spiders via the user agent",
|
||||||
|
"homepage": "https://github.com/JayBizzle/Crawler-Detect/",
|
||||||
|
"keywords": [
|
||||||
|
"crawler",
|
||||||
|
"crawler detect",
|
||||||
|
"crawler detector",
|
||||||
|
"crawlerdetect",
|
||||||
|
"php crawler detect"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/JayBizzle/Crawler-Detect/issues",
|
||||||
|
"source": "https://github.com/JayBizzle/Crawler-Detect/tree/v1.3.4"
|
||||||
|
},
|
||||||
|
"time": "2025-03-05T23:12:10+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "jenssegers/agent",
|
||||||
|
"version": "v2.6.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/jenssegers/agent.git",
|
||||||
|
"reference": "daa11c43729510b3700bc34d414664966b03bffe"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/jenssegers/agent/zipball/daa11c43729510b3700bc34d414664966b03bffe",
|
||||||
|
"reference": "daa11c43729510b3700bc34d414664966b03bffe",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"jaybizzle/crawler-detect": "^1.2",
|
||||||
|
"mobiledetect/mobiledetectlib": "^2.7.6",
|
||||||
|
"php": ">=5.6"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"php-coveralls/php-coveralls": "^2.1",
|
||||||
|
"phpunit/phpunit": "^5.0|^6.0|^7.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"illuminate/support": "Required for laravel service providers"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"aliases": {
|
||||||
|
"Agent": "Jenssegers\\Agent\\Facades\\Agent"
|
||||||
|
},
|
||||||
|
"providers": [
|
||||||
|
"Jenssegers\\Agent\\AgentServiceProvider"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Jenssegers\\Agent\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jens Segers",
|
||||||
|
"homepage": "https://jenssegers.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Desktop/mobile user agent parser with support for Laravel, based on Mobiledetect",
|
||||||
|
"homepage": "https://github.com/jenssegers/agent",
|
||||||
|
"keywords": [
|
||||||
|
"Agent",
|
||||||
|
"browser",
|
||||||
|
"desktop",
|
||||||
|
"laravel",
|
||||||
|
"mobile",
|
||||||
|
"platform",
|
||||||
|
"user agent",
|
||||||
|
"useragent"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/jenssegers/agent/issues",
|
||||||
|
"source": "https://github.com/jenssegers/agent/tree/v2.6.4"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/jenssegers",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/jenssegers/agent",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2020-06-13T08:05:20+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/framework",
|
"name": "laravel/framework",
|
||||||
"version": "v12.10.0",
|
"version": "v12.10.0",
|
||||||
@ -2590,6 +2725,68 @@
|
|||||||
},
|
},
|
||||||
"time": "2025-04-03T12:16:11+00:00"
|
"time": "2025-04-03T12:16:11+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "mobiledetect/mobiledetectlib",
|
||||||
|
"version": "2.8.45",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/serbanghita/Mobile-Detect.git",
|
||||||
|
"reference": "96aaebcf4f50d3d2692ab81d2c5132e425bca266"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/96aaebcf4f50d3d2692ab81d2c5132e425bca266",
|
||||||
|
"reference": "96aaebcf4f50d3d2692ab81d2c5132e425bca266",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.0.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.8.36"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Detection": "namespaced/"
|
||||||
|
},
|
||||||
|
"classmap": [
|
||||||
|
"Mobile_Detect.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Serban Ghita",
|
||||||
|
"email": "serbanghita@gmail.com",
|
||||||
|
"homepage": "http://mobiledetect.net",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.",
|
||||||
|
"homepage": "https://github.com/serbanghita/Mobile-Detect",
|
||||||
|
"keywords": [
|
||||||
|
"detect mobile devices",
|
||||||
|
"mobile",
|
||||||
|
"mobile detect",
|
||||||
|
"mobile detector",
|
||||||
|
"php mobile detect"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/serbanghita/Mobile-Detect/issues",
|
||||||
|
"source": "https://github.com/serbanghita/Mobile-Detect/tree/2.8.45"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/serbanghita",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2023-11-07T21:57:25+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "monolog/monolog",
|
"name": "monolog/monolog",
|
||||||
"version": "3.9.0",
|
"version": "3.9.0",
|
||||||
|
|||||||
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('device_sessions', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('user_id')->constrained()->onDelete('cascade');
|
||||||
|
$table->string('session_id')->nullable()->unique();
|
||||||
|
$table->string('browser')->nullable();
|
||||||
|
$table->string('os')->nullable();
|
||||||
|
$table->string('device')->nullable();
|
||||||
|
$table->boolean('is_mobile')->default(false);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('device_sessions');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
@extends('layouts.aside')
|
||||||
|
|
||||||
|
@section('main')
|
||||||
|
|
||||||
|
<main class="min-h-screen w-full flex items-center justify-center bg-[#0d1b2a] overflow-auto py-5">
|
||||||
|
<div class="bg-[#1b263b] p-8 rounded-xl shadow-2xl max-w-[800px] w-full transition-all duration-300">
|
||||||
|
|
||||||
|
<h1 class="text-3xl font-semibold text-center text-[#e0e1dd] mb-10">Browse Session</h1>
|
||||||
|
|
||||||
|
@foreach($device_sessions as $session)
|
||||||
|
<div class="bg-[#0d1b2a] text-[#e0e1dd] p-4 my-2 rounded-xl shadow">
|
||||||
|
🖥️ {{ $session->browser }} - {{ $session->os }}
|
||||||
|
<br>
|
||||||
|
🕐 {{ $session->created_at->diffForHumans() }}
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<form action="{{route('logout.other.device')}}" method="POST" class="mt-8 text-center">
|
||||||
|
@csrf
|
||||||
|
<button type="submit"
|
||||||
|
class="bg-red-600 cursor-pointer hover:bg-red-700 text-white font-semibold px-6 py-2 rounded-lg shadow-md transition duration-300 ease-in-out">
|
||||||
|
Logout Other Devices
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
@endsection
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
@extends('layouts.aside')
|
||||||
|
|
||||||
|
@section('main')
|
||||||
|
|
||||||
|
<main class="min-h-screen w-full flex items-center justify-center bg-[#0d1b2a] overflow-auto py-5">
|
||||||
|
<div class="bg-[#1b263b] p-8 rounded-xl shadow-2xl max-w-[800px] w-full transition-all duration-300">
|
||||||
|
|
||||||
|
<h1 class="text-3xl font-semibold text-center text-[#e0e1dd] mb-10">Change Password</h1>
|
||||||
|
|
||||||
|
<form action="{{ route('change.password') }}" method="POST" class="space-y-6">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="current_password" class="block text-[#e0e1dd] mb-2">Current Password</label>
|
||||||
|
<input type="password" id="current_password" name="current_password" value="{{$user->password}}"
|
||||||
|
class="w-full px-4 py-3 rounded-lg bg-[#415a77] text-white placeholder-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
||||||
|
<p class="w-full text-red-500 text-sm mt-1">@error('current_password') {{ $message }} @enderror</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="password" class="block text-[#e0e1dd] mb-2">New Password</label>
|
||||||
|
<input type="password" id="password" name="password"
|
||||||
|
class="w-full px-4 py-3 rounded-lg bg-[#415a77] text-white placeholder-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
||||||
|
<p class="w-full text-red-500 text-sm mt-1">@error('password') {{ $message }} @enderror</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="password_confirmation" class="block text-[#e0e1dd] mb-2">Confirm New Password</label>
|
||||||
|
<input type="password" id="password_confirmation" name="password_confirmation"
|
||||||
|
class="w-full px-4 py-3 rounded-lg bg-[#415a77] text-white placeholder-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<button type="submit"
|
||||||
|
class="inline-block cursor-pointer px-6 py-3 border border-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700 transition ease-in-out duration-300">
|
||||||
|
Update Password
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
@endsection
|
||||||
@ -45,6 +45,7 @@
|
|||||||
{{ $message }}
|
{{ $message }}
|
||||||
@enderror
|
@enderror
|
||||||
</p>
|
</p>
|
||||||
|
{{-- captcha scction --}}
|
||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="border border-[#e0e1dd] font-medium w-full p-2 rounded-md bg-[#e0e1dd] cursor-pointer hover:opacity-85 transition duration-300 ease-in-out text-black">Login</button>
|
class="border border-[#e0e1dd] font-medium w-full p-2 rounded-md bg-[#e0e1dd] cursor-pointer hover:opacity-85 transition duration-300 ease-in-out text-black">Login</button>
|
||||||
|
|||||||
@ -0,0 +1,42 @@
|
|||||||
|
@extends('layouts.aside')
|
||||||
|
|
||||||
|
@section('main')
|
||||||
|
<main class="min-h-screen w-full flex items-center justify-center bg-[#0d1b2a] overflow-auto py-5">
|
||||||
|
<div class="bg-[#1b263b] p-8 rounded-xl shadow-2xl max-w-[800px] w-full transition-all duration-300">
|
||||||
|
|
||||||
|
<h1 class="text-3xl font-semibold text-center text-[#e0e1dd] mb-10">Edit Profile</h1>
|
||||||
|
|
||||||
|
<form action="{{ route('profile.update') }}" method="POST" class="space-y-6">
|
||||||
|
@csrf
|
||||||
|
@method('PUT')
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="name" class="block text-[#e0e1dd] mb-2">Name</label>
|
||||||
|
<input type="text" id="name" name="name" value="{{ $user->name }}"
|
||||||
|
class="w-full px-4 py-3 rounded-lg bg-[#415a77] text-white placeholder-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
||||||
|
<p class="w-full text-red-500">@error('name') {{ $message }} @enderror</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="email" class="block text-[#e0e1dd] mb-2">Email</label>
|
||||||
|
<input type="email" id="email" name="email" value="{{ $user->email }}"
|
||||||
|
class="w-full px-4 py-3 rounded-lg bg-[#415a77] text-white placeholder-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
||||||
|
<p class="w-full text-red-500">@error('email') {{ $message }} @enderror</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<button type="submit"
|
||||||
|
class="inline-block cursor-pointer px-6 py-3 border border-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700 transition ease-in-out duration-300">
|
||||||
|
Save Changes
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@ -39,7 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div class="mt-4 flex justify-between items-center gap-4">
|
<div class="mt-4 flex justify-between items-center gap-4">
|
||||||
<form action="#" method="GET" class="w-full">
|
<form action="{{route('github.redirect')}}" method="GET" class="w-full">
|
||||||
<button
|
<button
|
||||||
class="border border-[#e0e1dd] text-[#e0e1dd] w-full p-2 rounded-md font-medium cursor-pointer hover:opacity-85 transition duration-300 ease-in-out hover:bg-[#e0e1dd] hover:text-[#1b263b]">With
|
class="border border-[#e0e1dd] text-[#e0e1dd] w-full p-2 rounded-md font-medium cursor-pointer hover:opacity-85 transition duration-300 ease-in-out hover:bg-[#e0e1dd] hover:text-[#1b263b]">With
|
||||||
Github</button>
|
Github</button>
|
||||||
|
|||||||
@ -1,102 +1,64 @@
|
|||||||
@extends('layouts.app')
|
@extends('layouts.aside')
|
||||||
|
|
||||||
@section('content')
|
@section('main')
|
||||||
<div class="bg-[#0d1b2a] min-h-screen flex justify-center items-center space-x-4">
|
<main class="min-h-screen w-full flex items-center justify-center bg-[#0d1b2a] overflow-auto py-5">
|
||||||
<aside class="bg-[#1b263b] h-screen w-[300px] rounded-xl flex flex-col justify-between p-5 text-white shadow-lg">
|
<div class="bg-[#1b263b] p-8 rounded-xl shadow-2xl max-w-[800px] w-full transition-all duration-300">
|
||||||
<div class="mt-5">
|
<h1 class="text-3xl font-semibold text-center text-[#e0e1dd] mb-5">
|
||||||
<div class="text-center mb-6">
|
{{ $user->email }}
|
||||||
<h1 class="font-bold text-3xl">{{$user->name}} Panel</h1>
|
</h1>
|
||||||
<p class="text-gray-300 mt-1">You are logged in!</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<nav class="space-y-2">
|
@if (session('success'))
|
||||||
<a href="{{ route('dashboard') }}" class="block px-4 py-2 rounded-lg hover:bg-[#415a77] transition">
|
<div
|
||||||
📊 Dashboard
|
class="mb-4 px-4 py-3 rounded-md bg-green-600/20 text-green-300 border border-green-500 flex items-center justify-between shadow">
|
||||||
</a>
|
<span>{{ session('success') }}</span>
|
||||||
<a href="#" class="block px-4 py-2 rounded-lg hover:bg-[#415a77] transition">👤
|
<button onclick="this.parentElement.remove()"
|
||||||
Profile</a>
|
class="text-green-300 hover:text-white transition duration-200 cursor-pointer">×</button>
|
||||||
<a href="#" class="block px-4 py-2 rounded-lg hover:bg-[#415a77] transition">
|
|
||||||
🔐 Change Password
|
|
||||||
</a>
|
|
||||||
<a href="#" class="block px-4 py-2 rounded-lg hover:bg-[#415a77] transition">
|
|
||||||
🖥️ Browse Session
|
|
||||||
</a>
|
|
||||||
</nav>
|
|
||||||
</div>
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="mt-6 space-y-4">
|
<div class="flex flex-col max-w-md mx-auto">
|
||||||
<form action="{{route('logout')}}" method="POST">
|
|
||||||
@csrf
|
|
||||||
<button type="submit"
|
|
||||||
class="block text-center w-full border border-red-500 text-red-500 hover:bg-red-500 hover:text-white transition-all duration-300 rounded-lg py-2 cursor-pointer">Logout</button>
|
|
||||||
</form>
|
|
||||||
<form action="{{route('delete.account')}}" method="POST">
|
|
||||||
@csrf
|
|
||||||
<button type="submit"
|
|
||||||
class="block text-center w-full border border-red-500 text-red-500 hover:bg-red-500 hover:text-white transition-all duration-300 rounded-lg py-2 cursor-pointer">Delete
|
|
||||||
Account</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<main class="min-h-screen w-full flex items-center justify-center bg-[#0d1b2a] overflow-auto py-5">
|
{{-- Email Verification --}}
|
||||||
<div class="bg-[#1b263b] p-8 rounded-xl shadow-2xl max-w-[800px] w-full transition-all duration-300">
|
<div class="bg-[#1b263b] p-5 rounded-xl shadow">
|
||||||
<h1 class="text-3xl font-semibold text-center text-[#e0e1dd] mb-5">
|
@if (!$user->email_verified_at)
|
||||||
{{ $user->email }}
|
<form action="{{ route('verification.send') }}" method="POST">
|
||||||
</h1>
|
@csrf
|
||||||
|
<button type="submit"
|
||||||
@if (session('success'))
|
class="w-full cursor-pointer px-6 py-3 bg-blue-600 text-white rounded-lg font-semibold hover:bg-blue-700 transition ease-in-out duration-300">
|
||||||
<div
|
Verify Your Email
|
||||||
class="mb-4 px-4 py-3 rounded-md bg-green-600/20 text-green-300 border border-green-500 flex items-center justify-between shadow">
|
</button>
|
||||||
<span>{{ session('success') }}</span>
|
</form>
|
||||||
<button onclick="this.parentElement.remove()"
|
<p class="mt-2 text-sm text-red-300 text-center">Your email is not verified.</p>
|
||||||
class="text-green-300 hover:text-white transition duration-200 cursor-pointer">×</button>
|
@else
|
||||||
</div>
|
<div class="px-5 py-3 bg-green-600/20 text-green-400 border border-green-600 rounded-md shadow-sm">
|
||||||
@endif
|
✅ Your Email Is Verified
|
||||||
|
|
||||||
<div class="flex flex-col max-w-md mx-auto">
|
|
||||||
|
|
||||||
{{-- Email Verification --}}
|
|
||||||
<div class="bg-[#1b263b] p-5 rounded-xl shadow">
|
|
||||||
@if (!$user->email_verified_at)
|
|
||||||
<form action="{{ route('verification.send') }}" method="POST">
|
|
||||||
@csrf
|
|
||||||
<button type="submit"
|
|
||||||
class="w-full cursor-pointer px-6 py-3 bg-blue-600 text-white rounded-lg font-semibold hover:bg-blue-700 transition ease-in-out duration-300">
|
|
||||||
Verify Your Email
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
<p class="mt-2 text-sm text-red-300 text-center">Your email is not verified.</p>
|
|
||||||
@else
|
|
||||||
<div class="px-5 py-3 bg-green-600/20 text-green-400 border border-green-600 rounded-md shadow-sm">
|
|
||||||
✅ Your Email Is Verified
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
{{-- Two Factor Authentication --}}
|
{{-- Two Factor Authentication --}}
|
||||||
<div class="bg-[#1b263b] rounded-xl shadow">
|
<div class="bg-[#1b263b] rounded-xl shadow">
|
||||||
@if (!$user->google2fa_secret)
|
@if (!$user->google2fa_secret)
|
||||||
<form method="GET" action="{{route('enable.2fa.show')}}">
|
<form method="GET" action="{{route('enable.2fa.show')}}">
|
||||||
@csrf
|
@csrf
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="w-full cursor-pointer px-6 py-3 border border-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700 transition ease-in-out duration-300">
|
class="w-full cursor-pointer px-6 py-3 border border-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700 transition ease-in-out duration-300">
|
||||||
Enable Two Factor Authentication
|
Enable Two Factor Authentication
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
@else
|
@else
|
||||||
<form method="POST" action="{{route('disable.2fa')}}">
|
<form method="POST" action="{{route('disable.2fa')}}">
|
||||||
@csrf
|
@csrf
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="w-full cursor-pointer px-6 py-3 border border-red-600 text-white font-semibold rounded-lg hover:bg-red-700 transition ease-in-out duration-300">
|
class="w-full cursor-pointer px-6 py-3 border border-red-600 text-white font-semibold rounded-lg hover:bg-red-700 transition ease-in-out duration-300">
|
||||||
Disable Two Factor Authentication
|
Disable Two Factor Authentication
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
@yield('content')
|
@yield('content')
|
||||||
|
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="bg-[#0d1b2a] min-h-screen flex justify-center items-center space-x-4">
|
||||||
|
<aside class="bg-[#1b263b] h-screen w-[300px] rounded-xl flex flex-col justify-between p-5 text-white shadow-lg">
|
||||||
|
<div class="mt-5">
|
||||||
|
<div class="text-center mb-6">
|
||||||
|
<h1 class="font-bold text-3xl">{{$user->name}} Panel</h1>
|
||||||
|
<p class="text-gray-300 mt-1">You are logged in!</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="space-y-2">
|
||||||
|
<a href="{{ route('dashboard') }}" class="block px-4 py-2 rounded-lg hover:bg-[#415a77] transition">
|
||||||
|
📊 Dashboard
|
||||||
|
</a>
|
||||||
|
<a href="{{route('profile.show')}}" class="block px-4 py-2 rounded-lg hover:bg-[#415a77] transition">👤
|
||||||
|
Profile</a>
|
||||||
|
<a href="{{route('change.password.show')}}"
|
||||||
|
class="block px-4 py-2 rounded-lg hover:bg-[#415a77] transition">
|
||||||
|
🔐 Change Password
|
||||||
|
</a>
|
||||||
|
<a href="{{route('browse.session')}}" class="block px-4 py-2 rounded-lg hover:bg-[#415a77] transition">
|
||||||
|
🖥️ Browse Session
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-6 space-y-4">
|
||||||
|
<form action="{{route('logout')}}" method="POST">
|
||||||
|
@csrf
|
||||||
|
<button type="submit"
|
||||||
|
class="block text-center w-full border border-red-500 text-red-500 hover:bg-red-500 hover:text-white transition-all duration-300 rounded-lg py-2 cursor-pointer">Logout</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{route('delete.account')}}" method="POST">
|
||||||
|
@csrf
|
||||||
|
<button type="submit"
|
||||||
|
class="block text-center w-full border border-red-500 text-red-500 hover:bg-red-500 hover:text-white transition-all duration-300 rounded-lg py-2 cursor-pointer">Delete
|
||||||
|
Account</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
@yield('main')
|
||||||
|
@endsection
|
||||||
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\Auth\BrowseSessionController;
|
||||||
use App\Http\Controllers\Auth\SocialLoginController;
|
use App\Http\Controllers\Auth\SocialLoginController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Laravel\Socialite\Facades\Socialite;
|
use Laravel\Socialite\Facades\Socialite;
|
||||||
@ -8,6 +9,7 @@ use App\Http\Controllers\DashboardController;
|
|||||||
use App\Http\Controllers\Auth\LoginController;
|
use App\Http\Controllers\Auth\LoginController;
|
||||||
use App\Http\Controllers\Auth\LogoutController;
|
use App\Http\Controllers\Auth\LogoutController;
|
||||||
use App\Http\Controllers\Auth\PasswordController;
|
use App\Http\Controllers\Auth\PasswordController;
|
||||||
|
use App\Http\Controllers\Auth\ProfileController;
|
||||||
use App\Http\Controllers\Auth\RegisterController;
|
use App\Http\Controllers\Auth\RegisterController;
|
||||||
use App\Http\Controllers\Auth\TwoFactorAuthenticationController;
|
use App\Http\Controllers\Auth\TwoFactorAuthenticationController;
|
||||||
|
|
||||||
@ -26,6 +28,7 @@ Route::group(['middleware' => 'auth'], function () {
|
|||||||
|
|
||||||
Route::post('logout', action: [LogoutController::class, 'logout'])->name('logout');
|
Route::post('logout', action: [LogoutController::class, 'logout'])->name('logout');
|
||||||
Route::post('delete-account', action: [LogoutController::class, 'deleteAccount'])->name('delete.account');
|
Route::post('delete-account', action: [LogoutController::class, 'deleteAccount'])->name('delete.account');
|
||||||
|
Route::post('logout-other-device', [LogoutController::class, 'logoutOtherDevice'])->name('logout.other.device');
|
||||||
|
|
||||||
//verify mail
|
//verify mail
|
||||||
Route::post('email/verification-notification', [MailController::class, 'notification'])->name('verification.send');
|
Route::post('email/verification-notification', [MailController::class, 'notification'])->name('verification.send');
|
||||||
@ -37,6 +40,17 @@ Route::group(['middleware' => 'auth'], function () {
|
|||||||
Route::post('disable-2fa', [TwoFactorAuthenticationController::class, 'disable2FA'])->name('disable.2fa');
|
Route::post('disable-2fa', [TwoFactorAuthenticationController::class, 'disable2FA'])->name('disable.2fa');
|
||||||
Route::get('secret-code-show', [TwoFactorAuthenticationController::class, 'secretCodeShow'])->name('secret.code.show');
|
Route::get('secret-code-show', [TwoFactorAuthenticationController::class, 'secretCodeShow'])->name('secret.code.show');
|
||||||
Route::post('secret-code', [TwoFactorAuthenticationController::class, 'secretCode'])->name('secret.code');
|
Route::post('secret-code', [TwoFactorAuthenticationController::class, 'secretCode'])->name('secret.code');
|
||||||
|
|
||||||
|
//profile
|
||||||
|
Route::get('profile', [ProfileController::class, 'showProfile'])->name('profile.show');
|
||||||
|
Route::put('profile', [ProfileController::class, 'updateProfile'])->name('profile.update');
|
||||||
|
|
||||||
|
//change password in profile
|
||||||
|
Route::get('change-password', [PasswordController::class, 'changePasswordPage'])->name('change.password.show');
|
||||||
|
Route::post('change-password', [PasswordController::class, 'changePassword'])->name('change.password');
|
||||||
|
|
||||||
|
//browse session
|
||||||
|
Route::get('browse-session', [BrowseSessionController::class, 'browseSession'])->name('browse.session');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user