diff --git a/app/Http/Controllers/Api/Auth/AuthController.php b/app/Http/Controllers/Api/Auth/AuthController.php new file mode 100644 index 0000000000000000000000000000000000000000..f7aadd7e108af9e20edefe30de27fc88474388be --- /dev/null +++ b/app/Http/Controllers/Api/Auth/AuthController.php @@ -0,0 +1,174 @@ +<?php + +namespace App\Http\Controllers\Api\Auth; + +use App\Http\Controllers\Controller; +use App\Http\Requests\Auth\LoginRequest; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Password; + +class AuthController extends Controller +{ + /** + * Login + * + * @OA\Post ( + * path="/api/login", + * tags={"Auth"}, + * + * @OA\RequestBody( + * + * @OA\MediaType( + * mediaType="application/json", + * + * @OA\Schema( + * + * @OA\Property( + * type="object", + * @OA\Property( + * property="email", + * type="string" + * ), + * @OA\Property( + * property="password", + * type="string" + * ) + * ), + * example={ + * "email":"user@test.com", + * "password":"useruser1" + * } + * ) + * ) + * ), + * + * @OA\Response( + * response=200, + * description="Valid credentials. User Object", + * + * @OA\JsonContent( + * + * @OA\Property(property="user", type="object", + * @OA\Property(property="id", type="number", example=2), + * @OA\Property(property="first_name", type="string", example="Joe"), + * @OA\Property(property="middle_name", type="string", example="Lie"), + * @OA\Property(property="last_name", type="string", example="Goldberg"), + * @OA\Property(property="email", type="string", example="user@test.com"), + * @OA\Property(property="email_verified_at", type="string", example=null), + * @OA\Property(property="updated_at", type="string", example="2022-06-28 06:06:17"), + * @OA\Property(property="created_at", type="string", example="2022-06-28 06:06:17"), + * @OA\Property(property="token", type="string", example="lasjdlkajsdlajsdljasldjalksdjalsdla"), + * ), + * ) + * ), + * + * @OA\Response( + * response=402, + * description="Invalid credentials", + * + * @OA\JsonContent( + * + * @OA\Property(property="meta", type="object", + * @OA\Property(property="message", type="string", example="Invalid credentials"), + * ), + * ) + * ) + * ) + */ + public function login(LoginRequest $request) + { + if (auth()->attempt($request->validated())) { + $user = auth()->user(); + $user['token'] = $user->createToken('API Token')->accessToken; + + return response()->json([ + 'user' => $user, + ], 200); + } + + return response()->json([ + 'message' => 'Invalid credentials', + ], 402); + } + + /** + * Logout + * + * @OA\Post ( + * path="/api/logout", + * tags={"Auth"}, + * + * @OA\Response( + * response=200, + * description="You are successfully logged out", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="You are successfully logged out"), + * ) + * ) + * ) + */ + public function logout(Request $request) + { + $request->user()->token()->revoke(); + + return response()->json([ + 'message' => 'You are successfully logged out', + ]); + } + + /** + * Reset Password + * + * @OA\Post ( + * path="/api/reset", + * tags={"Auth"}, + * + * @OA\RequestBody( + * + * @OA\MediaType( + * mediaType="application/json", + * + * @OA\Schema( + * + * @OA\Property( + * type="object", + * @OA\Property( + * property="email", + * type="string" + * ), + * ), + * example={ + * "email":"user@test.com", + * } + * ) + * ) + * ), + * + * @OA\Response( + * response=200, + * description="Status", + * + * @OA\JsonContent( + * + * @OA\Property(property="status", type="string"), + * ) + * ), + * ) + */ + public function reset(Request $request) + { + $request->validate([ + 'email' => ['required', 'email'], + ]); + + $status = Password::sendResetLink( + $request->only('email') + ); + + return response()->json([ + 'status' => $status, + ]); + } +} diff --git a/app/Http/Controllers/Api/GradeController.php b/app/Http/Controllers/Api/GradeController.php new file mode 100644 index 0000000000000000000000000000000000000000..a968579790e54670d776d845d4ce61ec6b42194a --- /dev/null +++ b/app/Http/Controllers/Api/GradeController.php @@ -0,0 +1,213 @@ +<?php + +namespace App\Http\Controllers\Api; + +use App\Http\Controllers\Controller; +use App\Http\Requests\Grade\StoreRequest; +use App\Http\Requests\Grade\UpdateRequest; +use App\Http\Resources\GradeResource; +use App\Models\Subject; +use App\Models\User; +use Illuminate\Http\JsonResponse; +use Illuminate\Support\Facades\Gate; + +class GradeController extends Controller +{ + /** + * @OA\Post( + * tags={"Grade"}, + * path="/api/student/{id}/subject", + * security={ + * {"passport": {}}, + * }, + * summary="Grade store", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Student ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\RequestBody( + * required=true, + * + * @OA\MediaType( + * mediaType="application/x-www-form-urlencoded", + * + * @OA\Schema( + * required={"subject_id", "grade"}, + * + * @OA\Property( + * property="subject_id", + * type="integer" + * ), + * @OA\Property( + * property="grade", + * type="integer" + * ) + * ) + * ) + * + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent(ref="#/components/schemas/GradeResource") + * ), + * + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function store(StoreRequest $request, User $student): GradeResource + { + Gate::authorize('create-grade', $student); + $subject = $request->validated('subject_id'); + $student->subjects()->attach( + $subject, + ['grade' => $request->validated(['grade'])] + ); + + return new GradeResource([ + 'student' => $student->id, + 'subject' => $subject, + 'grade' => $request->validated(['grade']), + ]); + } + + /** + * @OA\Put( + * tags={"Grade"}, + * path="/api/student/{student}/subject/{subject}", + * security={ + * {"passport": {}}, + * }, + * summary="Grade update", + * + * @OA\Parameter( + * name="student", + * in="path", + * required=true, + * description="Student ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Parameter( + * name="subject", + * in="path", + * required=true, + * description="Subject ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\RequestBody( + * required=true, + * + * @OA\JsonContent( + * type="object", + * required={"grade"}, + * + * @OA\Property(property="grade", type="integer") + * ) + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent(ref="#/components/schemas/GradeResource") + * ), + * + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function update(UpdateRequest $request, User $student, Subject $subject): GradeResource + { + Gate::authorize('update-grade', $student); + + $student->subjects()->syncWithPivotValues( + $subject->id, + ['grade' => $request->validated(['grade'])], + false + ); + + return new GradeResource([ + 'student' => $student->id, + 'subject' => $subject->id, + 'grade' => $request->validated(['grade']), + ]); + } + + /** + * @OA\Delete( + * tags={"Grade"}, + * path="/api/student/{student}/subject/{subject}", + * security={ + * {"passport": {}}, + * }, + * summary="Grade destroy", + * + * @OA\Parameter( + * name="student", + * in="path", + * required=true, + * description="Student ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Parameter( + * name="subject", + * in="path", + * required=true, + * description="Subject ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * ), + * @OA\Response(response=404, description="Not Found"), + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function destroy(User $student, Subject $subject): JsonResponse + { + Gate::authorize('delete-grade', $student); + $student->subjects()->detach($subject->id); + + return response()->json(); + } +} diff --git a/app/Http/Controllers/Api/GroupController.php b/app/Http/Controllers/Api/GroupController.php new file mode 100644 index 0000000000000000000000000000000000000000..b26537089ee6d19d7f21cbb6d613fd653a2f6e9d --- /dev/null +++ b/app/Http/Controllers/Api/GroupController.php @@ -0,0 +1,258 @@ +<?php + +namespace App\Http\Controllers\Api; + +use App\Http\Controllers\Controller; +use App\Http\Requests\Group\StoreRequest; +use App\Http\Requests\Group\UpdateRequest; +use App\Http\Resources\GroupResource; +use App\Models\Group; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Resources\Json\ResourceCollection; + +class GroupController extends Controller +{ + public function __construct() + { + $this->authorizeResource(Group::class, 'group'); + } + + /** + * @OA\Get( + * tags={"Group"}, + * path="/api/group", + * security={ + * {"passport": {}}, + * }, + * summary="Group index", + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * type="object", + * + * @OA\Property( + * property="data", + * type="array", + * + * @OA\Items(ref="#/components/schemas/GroupResource") + * ), + * + * @OA\Property( + * property="meta", + * type="object", + * @OA\Property(property="current_page", type="integer"), + * @OA\Property(property="from", type="integer"), + * @OA\Property(property="last_page", type="integer"), + * @OA\Property( + * property="links", + * type="array", + * + * @OA\Items( + * type="object", + * + * @OA\Property(property="url", type="string"), + * @OA\Property(property="label", type="string"), + * @OA\Property(property="active", type="boolean"), + * ), + * ), + * ) + * ) + * ) + * ) + */ + public function index(): ResourceCollection + { + return GroupResource::collection(Group::filter()->paginate(5)); + } + + /** + * @OA\Post( + * tags={"Group"}, + * path="/api/group", + * security={ + * {"passport": {}}, + * }, + * summary="Group store", + * + * @OA\RequestBody( + * required=true, + * + * @OA\JsonContent( + * type="object", + * required={"name"}, + * + * @OA\Property(property="name", type="string") + * ) + * ), + * + * @OA\Response( + * response=201, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="data", ref="#/components/schemas/GroupResource") + * ) + * ), + * + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function store(StoreRequest $request): GroupResource + { + return new GroupResource(Group::create($request->validated())); + } + + /** + * @OA\Get( + * tags={"Group"}, + * path="/api/group/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Group show", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Group ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="data", ref="#/components/schemas/GroupResource") + * ) + * ), + * + * @OA\Response(response=404, description="Not Found") + * ) + */ + public function show(Group $group): GroupResource + { + return new GroupResource($group); + } + + /** + * @OA\Put( + * tags={"Group"}, + * path="/api/group/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Group update", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Group ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\RequestBody( + * required=true, + * + * @OA\JsonContent( + * type="object", + * required={"name"}, + * + * @OA\Property(property="name", type="string") + * ) + * ), + * + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="data", ref="#/components/schemas/GroupResource") + * ) + * ), + * + * @OA\Response(response=404, description="Not Found"), + * @OA\Response(response=422, description="Unprocessable Entity") + * ) + */ + public function update(UpdateRequest $request, Group $group): GroupResource + { + $group->update($request->validated()); + + return new GroupResource($group); + } + + /** + * @OA\Delete( + * tags={"Group"}, + * path="/api/group/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Group destroy", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Group ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="is_deleted", type="bool") + * ) + * ), + * + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * + * @OA\Response(response=404, description="Not Found") + * ) + */ + public function destroy(Group $group): JsonResponse + { + return response()->json(['is_deleted' => $group->delete()]); + } +} diff --git a/app/Http/Controllers/Api/StudentController.php b/app/Http/Controllers/Api/StudentController.php new file mode 100644 index 0000000000000000000000000000000000000000..24ce791f0f7abac37574a1042b3f2150305cce48 --- /dev/null +++ b/app/Http/Controllers/Api/StudentController.php @@ -0,0 +1,417 @@ +<?php + +namespace App\Http\Controllers\Api; + +use App\Events\NewUserEvent; +use App\Http\Controllers\Controller; +use App\Http\Requests\Student\StoreRequest; +use App\Http\Requests\Student\UpdateRequest; +use App\Http\Resources\UserResource; +use App\Models\User; +use App\Services\FileService; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Resources\Json\ResourceCollection; +use OpenApi\Annotations as OA; + +class StudentController extends Controller +{ + /** + * @OA\Get( + * tags={"Student"}, + * path="/api/export/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Student export", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Student ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * ), + * @OA\Response(response=404, description="Not Found") + * ) + */ + public function export(User $user, FileService $fileService): mixed + { + $this->authorize('export', User::class); + + return $fileService->apiExport($user); + } + + /** + * @OA\Get( + * tags={"Student"}, + * path="/api/student", + * security={ + * {"passport": {}}, + * }, + * summary="Student index", + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * type="object", + * + * @OA\Property( + * property="data", + * type="array", + * + * @OA\Items(ref="#/components/schemas/UserResource") + * ), + * + * @OA\Property(property="links", + * @OA\Property(property="first", type="string", example="http://localhost:8001/api/student?page=1"), + * @OA\Property(property="last", type="string", example="http://localhost:8001/api/student?page=51"), + * @OA\Property(property="prev", type="string", example="http://localhost:8001/api/student?page=1"), + * @OA\Property(property="next", type="string", example="http://localhost:8001/api/student?page=3"), + * ), + * @OA\Property( + * property="meta", + * type="object", + * @OA\Property(property="current_page", type="integer"), + * @OA\Property(property="from", type="integer"), + * @OA\Property(property="last_page", type="integer"), + * @OA\Property( + * property="links", + * type="array", + * + * @OA\Items( + * type="object", + * + * @OA\Property(property="url", type="string"), + * @OA\Property(property="label", type="string"), + * @OA\Property(property="active", type="boolean"), + * ), + * ), + * ) + * ) + * ) + * ) + */ + public function index(): ResourceCollection + { + return UserResource::collection( + User::withTrashed(auth()->user()->is_admin) + ->filter() + ->with('group')->paginate(10) + ); + } + + /** + * @OA\Post( + * tags={"Student"}, + * path="/api/student", + * security={ + * {"passport": {}}, + * }, + * summary="Student store", + * + * @OA\RequestBody( + * required=true, + * + * @OA\JsonContent( + * type="object", + * required={"first_name", "middle_name", "last_name", "birthday", "role", "group_id"}, + * + * @OA\Property(property="first_name", type="string"), + * @OA\Property(property="middle_name", type="string"), + * @OA\Property(property="last_name", type="string"), + * @OA\Property(property="role", type="integer"), + * @OA\Property(property="group_id", type="integer"), + * @OA\Property(property="birthday", type="date"), + * @OA\Property(property="city", type="string"), + * @OA\Property(property="house", type="string"), + * @OA\Property(property="street", type="string"), + * ) + * ), + * + * @OA\Response( + * response=201, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="data", ref="#/components/schemas/UserResource") + * ) + * ), + * + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function store(StoreRequest $request): UserResource + { + $this->authorize('store', [ + User::class, + $request->validated('group_id'), + $request->validated('role'), + ]); + $user = User::create($request->validated()); + event(new NewUserEvent($user)); + + return new UserResource($user); + } + + /** + * @OA\Get( + * tags={"Student"}, + * path="/api/student/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Student show", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Student ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="data", ref="#/components/schemas/UserResource") + * ) + * ), + * + * @OA\Response(response=404, description="Not Found") + * ) + */ + public function show(User $student): UserResource + { + return new UserResource($student); + } + + /** + * @OA\Put( + * tags={"Student"}, + * path="/api/student/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Student update", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Student ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\RequestBody( + * required=true, + * + * @OA\JsonContent( + * type="object", + * required={"first_name", "middle_name", "last_name", "birthday", "role", "group_id"}, + * + * @OA\Property(property="first_name", type="string"), + * @OA\Property(property="middle_name", type="string"), + * @OA\Property(property="last_name", type="string"), + * @OA\Property(property="role", type="integer"), + * @OA\Property(property="group_id", type="integer"), + * @OA\Property(property="birthday", type="date"), + * @OA\Property(property="address", + * @OA\Property(property="city", type="string"), + * @OA\Property(property="house", type="string"), + * @OA\Property(property="street", type="string"), + * ) + * ) + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="data", ref="#/components/schemas/UserResource") + * ) + * ), + * + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function update(UpdateRequest $request, User $student): UserResource + { + $this->authorize('update', [ + $student, + $request->validated('group_id'), + $request->validated('role'), + ]); + $student->update($request->validated()); + + return new UserResource($student); + } + + /** + * @OA\Delete( + * tags={"Student"}, + * path="/api/student/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Student destroy", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Student ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="is_deleted", type="bool"), + * ) + * ), + * + * @OA\Response(response=404, description="Not Found"), + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function destroy(User $student): JsonResponse + { + $this->authorize('destroy', $student); + + return response()->json(['is_deleted' => $student->delete()]); + } + + /** + * @OA\Get( + * tags={"Student"}, + * path="/api/student/restore/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Restore user", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Student ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Response(response=200, + * description="OK", + * + * @OA\JsonContent(ref="#/components/schemas/UserResource") + * ), + * + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function restore(User $student): UserResource + { + $this->authorize('restore', User::class); + $student->restore(); + + return new UserResource($student); + } + + /** + * @OA\Delete( + * tags={"Student"}, + * path="/api/student/force/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Student force delete", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Student ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="is_deleted", type="bool"), + * ) + * ), + * + * @OA\Response(response=404, description="Not Found"), + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function forceDelete(User $student): JsonResponse + { + $this->authorize('forceDelete', $student); + + return response()->json(['is_deleted' => $student->forceDelete()]); + } +} diff --git a/app/Http/Controllers/Api/SubjectController.php b/app/Http/Controllers/Api/SubjectController.php new file mode 100644 index 0000000000000000000000000000000000000000..3904e05bb259cea30ec9491886b98f714d89f946 --- /dev/null +++ b/app/Http/Controllers/Api/SubjectController.php @@ -0,0 +1,255 @@ +<?php + +namespace App\Http\Controllers\Api; + +use App\Http\Controllers\Controller; +use App\Http\Requests\Subject\StoreRequest; +use App\Http\Requests\Subject\UpdateRequest; +use App\Http\Resources\SubjectResource; +use App\Models\Subject; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Resources\Json\ResourceCollection; + +class SubjectController extends Controller +{ + public function __construct() + { + $this->authorizeResource(Subject::class, 'subject'); + } + + /** + * @OA\Get( + * tags={"Subject"}, + * path="/api/subject", + * security={ + * {"passport": {}}, + * }, + * summary="Subject index", + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * type="object", + * + * @OA\Property( + * property="data", + * type="array", + * + * @OA\Items(ref="#/components/schemas/SubjectResource") + * ), + * + * @OA\Property( + * property="meta", + * type="object", + * @OA\Property(property="current_page", type="integer"), + * @OA\Property(property="from", type="integer"), + * @OA\Property(property="last_page", type="integer"), + * @OA\Property( + * property="links", + * type="array", + * + * @OA\Items( + * type="object", + * + * @OA\Property(property="url", type="string"), + * @OA\Property(property="label", type="string"), + * @OA\Property(property="active", type="boolean"), + * ), + * ), + * ) + * ) + * ) + * ) + */ + public function index(): ResourceCollection + { + return SubjectResource::collection(Subject::filter()->paginate(5)); + } + + /** + * @OA\Post( + * tags={"Subject"}, + * path="/api/subject", + * security={ + * {"passport": {}}, + * }, + * summary="Subject store", + * + * @OA\RequestBody( + * required=true, + * + * @OA\JsonContent( + * type="object", + * required={"name"}, + * + * @OA\Property(property="name", type="string") + * ) + * ), + * + * @OA\Response( + * response=201, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="data", ref="#/components/schemas/SubjectResource") + * ) + * ), + * + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function store(StoreRequest $request): SubjectResource + { + return new SubjectResource(Subject::create($request->validated())); + } + + /** + * @OA\Get( + * tags={"Subject"}, + * path="/api/subject/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Subject show", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Subject ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="data", ref="#/components/schemas/SubjectResource") + * + * ) + * ), + * + * @OA\Response(response=404, description="Not Found") + * ) + */ + public function show(Subject $subject): SubjectResource + { + return new SubjectResource($subject); + } + + /** + * @OA\Put( + * tags={"Subject"}, + * path="/api/subject/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Subject update", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Subject ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\RequestBody( + * required=true, + * + * @OA\JsonContent( + * type="object", + * required={"name"}, + * + * @OA\Property(property="name", type="string") + * ) + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="data", ref="#/components/schemas/SubjectResource") + * ) + * ), + * + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function update(UpdateRequest $request, Subject $subject): SubjectResource + { + $subject->update($request->validated()); + + return new SubjectResource($subject); + } + + /** + * @OA\Delete( + * tags={"Subject"}, + * path="/api/subject/{id}", + * security={ + * {"passport": {}}, + * }, + * summary="Subject destroy", + * + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="Subject ID", + * + * @OA\Schema(type="integer"), + * ), + * + * @OA\Response( + * response=200, + * description="OK", + * + * @OA\JsonContent( + * + * @OA\Property(property="is_deleted", type="bool"), + * ) + * ), + * + * @OA\Response(response=404, description="Not Found"), + * @OA\Response( + * response=403, + * description="Not Auth", + * + * @OA\JsonContent( + * + * @OA\Property(property="message", type="string", example="This action is unauthorized.") + * ) + * ), + * ) + */ + public function destroy(Subject $subject): JsonResponse + { + return response()->json(['is_deleted' => $subject->delete()]); + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 77ec359ab4de60f6dd2205cbc5b2aab373d8a185..fdc88c6e2039ac2d936585b76bc0f2b291e216ad 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -6,6 +6,19 @@ use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; +/** + * @OA\Info( + * version="1.0.0", + * title="API", + * description="api", + * ) + + * + * @OA\Server( + * url=L5_SWAGGER_CONST_HOST, + * description="Host" + * ) + */ class Controller extends BaseController { use AuthorizesRequests, ValidatesRequests; diff --git a/app/Http/Controllers/Auth/AuthenticatedSessionController.php b/app/Http/Controllers/Web/Auth/AuthenticatedSessionController.php similarity index 96% rename from app/Http/Controllers/Auth/AuthenticatedSessionController.php rename to app/Http/Controllers/Web/Auth/AuthenticatedSessionController.php index 494a1064576a822aee139727a873c9823fedadfa..f113d9be03f19a7a3b0689a6c7696908e2c782a4 100644 --- a/app/Http/Controllers/Auth/AuthenticatedSessionController.php +++ b/app/Http/Controllers/Web/Auth/AuthenticatedSessionController.php @@ -1,6 +1,6 @@ <?php -namespace App\Http\Controllers\Auth; +namespace App\Http\Controllers\Web\Auth; use App\Http\Controllers\Controller; use App\Http\Requests\Auth\LoginRequest; diff --git a/app/Http/Controllers/Auth/ConfirmablePasswordController.php b/app/Http/Controllers/Web/Auth/ConfirmablePasswordController.php similarity index 96% rename from app/Http/Controllers/Auth/ConfirmablePasswordController.php rename to app/Http/Controllers/Web/Auth/ConfirmablePasswordController.php index 523ddda3c02858217fc74ee162de99d4452bdade..12ee2f4fbf6409fa744ae9f8860d00cb043c28f0 100644 --- a/app/Http/Controllers/Auth/ConfirmablePasswordController.php +++ b/app/Http/Controllers/Web/Auth/ConfirmablePasswordController.php @@ -1,6 +1,6 @@ <?php -namespace App\Http\Controllers\Auth; +namespace App\Http\Controllers\Web\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; diff --git a/app/Http/Controllers/Auth/EmailVerificationNotificationController.php b/app/Http/Controllers/Web/Auth/EmailVerificationNotificationController.php similarity index 93% rename from app/Http/Controllers/Auth/EmailVerificationNotificationController.php rename to app/Http/Controllers/Web/Auth/EmailVerificationNotificationController.php index 96ba772bd1ac4d00223e831c5ab353bcae3b8d18..76c9e6e5492b2bedb5d8d0b78dd30a659675f631 100644 --- a/app/Http/Controllers/Auth/EmailVerificationNotificationController.php +++ b/app/Http/Controllers/Web/Auth/EmailVerificationNotificationController.php @@ -1,6 +1,6 @@ <?php -namespace App\Http\Controllers\Auth; +namespace App\Http\Controllers\Web\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; diff --git a/app/Http/Controllers/Auth/EmailVerificationPromptController.php b/app/Http/Controllers/Web/Auth/EmailVerificationPromptController.php similarity index 93% rename from app/Http/Controllers/Auth/EmailVerificationPromptController.php rename to app/Http/Controllers/Web/Auth/EmailVerificationPromptController.php index 186eb97268b4ec86b9b82a48d3ce22d10fdea055..3c21b6268f17bb2697ece9cb97898fd42c683531 100644 --- a/app/Http/Controllers/Auth/EmailVerificationPromptController.php +++ b/app/Http/Controllers/Web/Auth/EmailVerificationPromptController.php @@ -1,6 +1,6 @@ <?php -namespace App\Http\Controllers\Auth; +namespace App\Http\Controllers\Web\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; diff --git a/app/Http/Controllers/Auth/NewPasswordController.php b/app/Http/Controllers/Web/Auth/NewPasswordController.php similarity index 98% rename from app/Http/Controllers/Auth/NewPasswordController.php rename to app/Http/Controllers/Web/Auth/NewPasswordController.php index 79ac3cd6530ec365936c16098e79466156e82f54..713ecad5379c5a77305fd518f5f307a465000ca0 100644 --- a/app/Http/Controllers/Auth/NewPasswordController.php +++ b/app/Http/Controllers/Web/Auth/NewPasswordController.php @@ -1,6 +1,6 @@ <?php -namespace App\Http\Controllers\Auth; +namespace App\Http\Controllers\Web\Auth; use App\Http\Controllers\Controller; use Illuminate\Auth\Events\PasswordReset; diff --git a/app/Http/Controllers/Auth/PasswordController.php b/app/Http/Controllers/Web/Auth/PasswordController.php similarity index 94% rename from app/Http/Controllers/Auth/PasswordController.php rename to app/Http/Controllers/Web/Auth/PasswordController.php index 69164091a61710120417c27d90793a6bb2074e4d..4fcca3dbf6e75ae3af4bc414e47988f21f4e0951 100644 --- a/app/Http/Controllers/Auth/PasswordController.php +++ b/app/Http/Controllers/Web/Auth/PasswordController.php @@ -1,6 +1,6 @@ <?php -namespace App\Http\Controllers\Auth; +namespace App\Http\Controllers\Web\Auth; use App\Http\Controllers\Controller; use Illuminate\Http\RedirectResponse; diff --git a/app/Http/Controllers/Auth/PasswordResetLinkController.php b/app/Http/Controllers/Web/Auth/PasswordResetLinkController.php similarity index 96% rename from app/Http/Controllers/Auth/PasswordResetLinkController.php rename to app/Http/Controllers/Web/Auth/PasswordResetLinkController.php index bf1ebfa7882b546604645fbef3a780c55f0660d7..a01a6f6345a091c7fcfa5d6792a772a4c42331f1 100644 --- a/app/Http/Controllers/Auth/PasswordResetLinkController.php +++ b/app/Http/Controllers/Web/Auth/PasswordResetLinkController.php @@ -1,6 +1,6 @@ <?php -namespace App\Http\Controllers\Auth; +namespace App\Http\Controllers\Web\Auth; use App\Http\Controllers\Controller; use Illuminate\Http\RedirectResponse; diff --git a/app/Http/Controllers/Auth/RegisteredUserController.php b/app/Http/Controllers/Web/Auth/RegisteredUserController.php similarity index 95% rename from app/Http/Controllers/Auth/RegisteredUserController.php rename to app/Http/Controllers/Web/Auth/RegisteredUserController.php index 27cc520a84f720786f407ced1a66c3ee0992e5e5..dc09458a7981975c9461f55c97a2945e8c180fcc 100644 --- a/app/Http/Controllers/Auth/RegisteredUserController.php +++ b/app/Http/Controllers/Web/Auth/RegisteredUserController.php @@ -1,6 +1,6 @@ <?php -namespace App\Http\Controllers\Auth; +namespace App\Http\Controllers\Web\Auth; use App\Enums\RoleEnum; use App\Events\NewUserEvent; diff --git a/app/Http/Controllers/Auth/VerifyEmailController.php b/app/Http/Controllers/Web/Auth/VerifyEmailController.php similarity index 95% rename from app/Http/Controllers/Auth/VerifyEmailController.php rename to app/Http/Controllers/Web/Auth/VerifyEmailController.php index ea879405dce6fea784f2b121a39e56c8b77fd383..86feebaba5cadcc04ee6712feb1a4d11bff9fd0b 100644 --- a/app/Http/Controllers/Auth/VerifyEmailController.php +++ b/app/Http/Controllers/Web/Auth/VerifyEmailController.php @@ -1,6 +1,6 @@ <?php -namespace App\Http\Controllers\Auth; +namespace App\Http\Controllers\Web\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; diff --git a/app/Http/Controllers/GradeController.php b/app/Http/Controllers/Web/GradeController.php similarity index 96% rename from app/Http/Controllers/GradeController.php rename to app/Http/Controllers/Web/GradeController.php index b010d0148c92368354f34d850711a5391844fc3b..df9158d7091d0cbd7759ae30749665cc33247a23 100644 --- a/app/Http/Controllers/GradeController.php +++ b/app/Http/Controllers/Web/GradeController.php @@ -1,7 +1,8 @@ <?php -namespace App\Http\Controllers; +namespace App\Http\Controllers\Web; +use App\Http\Controllers\Controller; use App\Http\Requests\Grade\StoreRequest; use App\Http\Requests\Grade\UpdateRequest; use App\Models\Group; @@ -74,7 +75,7 @@ public function store(StoreRequest $request, User $student): RedirectResponse { Gate::authorize('create-grade', $student); $student->subjects()->attach( - Subject::where('name', $request->validated('subject'))->first(), + $request->validated('subject_id'), ['grade' => $request->validated(['grade'])] ); diff --git a/app/Http/Controllers/GroupController.php b/app/Http/Controllers/Web/GroupController.php similarity index 94% rename from app/Http/Controllers/GroupController.php rename to app/Http/Controllers/Web/GroupController.php index 4220dd083d6965588f957f69ef1156247c816f2b..c296bc116bcd150fe298854c24dbcf6e53ca5cb0 100644 --- a/app/Http/Controllers/GroupController.php +++ b/app/Http/Controllers/Web/GroupController.php @@ -1,7 +1,8 @@ <?php -namespace App\Http\Controllers; +namespace App\Http\Controllers\Web; +use App\Http\Controllers\Controller; use App\Http\Requests\Group\StoreRequest; use App\Http\Requests\Group\UpdateRequest; use App\Models\Group; diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/Web/ProfileController.php similarity index 87% rename from app/Http/Controllers/ProfileController.php rename to app/Http/Controllers/Web/ProfileController.php index ba19bfc3a105f6ed788e9df7a249be9e66e91993..22cd3d86e724cc5b8a3654277a7c371a15a2ac5b 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/Web/ProfileController.php @@ -1,7 +1,8 @@ <?php -namespace App\Http\Controllers; +namespace App\Http\Controllers\Web; +use App\Http\Controllers\Controller; use App\Http\Requests\ProfileUpdateRequest; use App\Services\FileService; use Illuminate\Http\RedirectResponse; @@ -33,9 +34,11 @@ public function edit(Request $request): View public function update(ProfileUpdateRequest $request): RedirectResponse { $image = $request->file('image'); - $this->fileService->saveImage($image); $data = $request->validated(); - $data['image'] = $image->getClientOriginalName(); + if ($image) { + $this->fileService->saveImage($image); + $data['image'] = $image->getClientOriginalName(); + } $request->user()->fill($data); if ($request->user()->isDirty('email')) { diff --git a/app/Http/Controllers/StudentController.php b/app/Http/Controllers/Web/StudentController.php similarity index 97% rename from app/Http/Controllers/StudentController.php rename to app/Http/Controllers/Web/StudentController.php index 67df1314e937d668d58b5abb803bb5e31714fa7d..f240a19ce68c1188dc730db73e39f72b78d01eab 100644 --- a/app/Http/Controllers/StudentController.php +++ b/app/Http/Controllers/Web/StudentController.php @@ -1,9 +1,10 @@ <?php -namespace App\Http\Controllers; +namespace App\Http\Controllers\Web; use App\Enums\RoleEnum; use App\Events\NewUserEvent; +use App\Http\Controllers\Controller; use App\Http\Requests\Student\StoreRequest; use App\Http\Requests\Student\UpdateRequest; use App\Models\User; diff --git a/app/Http/Controllers/SubjectController.php b/app/Http/Controllers/Web/SubjectController.php similarity index 94% rename from app/Http/Controllers/SubjectController.php rename to app/Http/Controllers/Web/SubjectController.php index eb12fcea900fcf1413fff07419f8d5cad5557175..9c877c30cb73a24feeae18c7df90b6c03afbf5ab 100644 --- a/app/Http/Controllers/SubjectController.php +++ b/app/Http/Controllers/Web/SubjectController.php @@ -1,7 +1,8 @@ <?php -namespace App\Http\Controllers; +namespace App\Http\Controllers\Web; +use App\Http\Controllers\Controller; use App\Http\Requests\Subject\StoreRequest; use App\Http\Requests\Subject\UpdateRequest; use App\Models\Subject; diff --git a/app/Http/Requests/Grade/StoreRequest.php b/app/Http/Requests/Grade/StoreRequest.php index ce8c0932f505cadc03640d75374bcf4ddb550b40..a0474d7e33910edb3b2f1fb0b76334cacbda0866 100644 --- a/app/Http/Requests/Grade/StoreRequest.php +++ b/app/Http/Requests/Grade/StoreRequest.php @@ -2,7 +2,6 @@ namespace App\Http\Requests\Grade; -use App\Models\Subject; use App\Models\User; use Illuminate\Foundation\Http\FormRequest; @@ -24,7 +23,7 @@ public function authorize(): bool public function rules(): array { return [ - 'subject' => ['required', 'exists:subjects,name'], + 'subject_id' => ['required', 'exists:subjects,id'], 'grade' => ['required', 'min:1', 'max:5'], ]; } @@ -33,9 +32,9 @@ public function after(): array { return [ function ($validator) { - $subject = Subject::select('id')->where('name', $this->input('subject'))->first(); + $subject_id = $this->input('subject_id'); $student = $this->route('student'); - if ($subject && $student->subjects()->where('subject_id', $subject->id)->exists()) { + if ($subject_id && $student->subjects()->where('subject_id', $subject_id)->exists()) { $validator->errors()->add('exists', 'Already exists!'); } }, diff --git a/app/Http/Resources/GradeResource.php b/app/Http/Resources/GradeResource.php new file mode 100644 index 0000000000000000000000000000000000000000..157f8ad1da9f828323686006f1c290db8ad5680b --- /dev/null +++ b/app/Http/Resources/GradeResource.php @@ -0,0 +1,33 @@ +<?php + +namespace App\Http\Resources; + +use Illuminate\Http\Request; +use Illuminate\Http\Resources\Json\JsonResource; + +/** + * @OA\Schema( + * title="GradeResource", + * description="Group Properties", + * + * @OA\Property(property="student", type="integer"), + * @OA\Property(property="subject", type="integer"), + * @OA\Property(property="grade", type="integer"), + * ) + */ +class GradeResource extends JsonResource +{ + /** + * Transform the resource into an array. + * + * @return array<string, mixed> + */ + public function toArray(Request $request): array + { + return [ + 'student' => $this['student'], + 'subject' => $this['subject'], + 'grade' => $this['grade'], + ]; + } +} diff --git a/app/Http/Resources/GroupResource.php b/app/Http/Resources/GroupResource.php new file mode 100644 index 0000000000000000000000000000000000000000..1604e38ddf3fe2cef944d03f11374669d105ea7a --- /dev/null +++ b/app/Http/Resources/GroupResource.php @@ -0,0 +1,35 @@ +<?php + +namespace App\Http\Resources; + +use Illuminate\Http\Request; +use Illuminate\Http\Resources\Json\JsonResource; + +/** + * @OA\Schema( + * title="GroupResource", + * description="Group Properties", + * + * @OA\Property(property="id", type="integer"), + * @OA\Property(property="name", type="string"), + * @OA\Property(property="created_at", type="date"), + * @OA\Property(property="updated_at", type="date") + * ) + */ +class GroupResource extends JsonResource +{ + /** + * Transform the resource into an array. + * + * @return array<string, mixed> + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'name' => $this->name, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/SubjectResource.php b/app/Http/Resources/SubjectResource.php new file mode 100644 index 0000000000000000000000000000000000000000..2920eb2e8a76f0f87fe20efd65ec8b9469408c67 --- /dev/null +++ b/app/Http/Resources/SubjectResource.php @@ -0,0 +1,35 @@ +<?php + +namespace App\Http\Resources; + +use Illuminate\Http\Request; +use Illuminate\Http\Resources\Json\JsonResource; + +/** + * @OA\Schema( + * title="SubjectResource", + * description="Subject Properies", + * + * @OA\Property(property="id", type="integer"), + * @OA\Property(property="name", type="string"), + * @OA\Property(property="created_at", type="date"), + * @OA\Property(property="updated_at", type="date") + * ) + */ +class SubjectResource extends JsonResource +{ + /** + * Transform the resource into an array. + * + * @return array<string, mixed> + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'name' => $this->name, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Resources/UserResource.php b/app/Http/Resources/UserResource.php new file mode 100644 index 0000000000000000000000000000000000000000..1f2da2b1636eec20a05a524f5f1e0ef986179cce --- /dev/null +++ b/app/Http/Resources/UserResource.php @@ -0,0 +1,52 @@ +<?php + +namespace App\Http\Resources; + +use Illuminate\Http\Request; +use Illuminate\Http\Resources\Json\JsonResource; + +/** + * @OA\Schema( + * title="UserResource", + * description="User Properties", + * + * @OA\Property(property="id", type="integer"), + * @OA\Property(property="first_name", type="string"), + * @OA\Property(property="middle_name", type="string"), + * @OA\Property(property="last_name", type="string"), + * @OA\Property(property="birthday", type="date"), + * @OA\Property(property="role", type="integer"), + * @OA\Property(property="group_id", type="integer"), + * @OA\Property( + * property="address", + * @OA\Property(property="city", type="string"), + * @OA\Property(property="street", type="string"), + * @OA\Property(property="house", type="string"), + * ), + * @OA\Property(property="created_at", type="date"), + * @OA\Property(property="updated_at", type="date") + * ) + */ +class UserResource extends JsonResource +{ + /** + * Transform the resource into an array. + * + * @return array<string, mixed> + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'first_name' => $this->first_name, + 'middle_name' => $this->middle_name, + 'last_name' => $this->last_name, + 'birthday' => $this->birthday, + 'role' => $this->role, + 'group_id' => $this->group_id, + 'address' => $this->address, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Models/User.php b/app/Models/User.php index f983c15e39b3f689b77afcb5a5a6ec8831391d55..ca224eb210a3086b13b2f9c7966c9afbcce43eef 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -15,7 +15,7 @@ use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Support\Carbon; -use Laravel\Sanctum\HasApiTokens; +use Laravel\Passport\HasApiTokens; class User extends Authenticatable { diff --git a/app/Services/FileService.php b/app/Services/FileService.php index 320c37ec9ce0ffe84f908a728ed13bad96e5444e..e8ea418a631bbf433b12081c03ef75992805c4ea 100644 --- a/app/Services/FileService.php +++ b/app/Services/FileService.php @@ -4,6 +4,7 @@ use App\Models\User; use Barryvdh\DomPDF\Facade\Pdf; +use Illuminate\Http\Response; use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Storage; use Intervention\Image\Facades\Image; @@ -30,8 +31,13 @@ public function getImage(User $user, int $height, int $width): string return asset("avatar/{$dir}/sizes/{$height}x{$width}.jpg"); } - public function export(User $student): mixed + public function export(User $student): Response { return Pdf::loadView('export.student', compact('student'))->stream(); } + + public function apiExport($student): Response + { + return Pdf::loadView('export.student', compact('student'))->download(); + } } diff --git a/composer.json b/composer.json index 0cbaed1a86464a5a103b9bc258774c04988f3a4d..94e1157c1629fc069a2fc50859541120bdfd3284 100644 --- a/composer.json +++ b/composer.json @@ -7,9 +7,11 @@ "require": { "php": "^8.1", "barryvdh/laravel-dompdf": "^2.0", + "darkaonline/l5-swagger": "^8.5", "guzzlehttp/guzzle": "^7.2", "intervention/image": "^2.7", "laravel/framework": "^10.10", + "laravel/passport": "^11.9", "laravel/sanctum": "^3.2", "laravel/telescope": "^4.16", "laravel/tinker": "^2.8" diff --git a/composer.lock b/composer.lock index acee2399b46aa3e155f55b7b24a485196179037f..74086d4c064c015417299774d6cc6b290fca21f4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "68ac0a926acbc86c22203070a3688bee", + "content-hash": "8f08ad8fdd34535a40200e26db756940", "packages": [ { "name": "barryvdh/laravel-dompdf", @@ -138,6 +138,152 @@ ], "time": "2023-01-15T23:15:59+00:00" }, + { + "name": "darkaonline/l5-swagger", + "version": "8.5.1", + "source": { + "type": "git", + "url": "https://github.com/DarkaOnLine/L5-Swagger.git", + "reference": "02348149f1833c63bf52764838d5659507857394" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DarkaOnLine/L5-Swagger/zipball/02348149f1833c63bf52764838d5659507857394", + "reference": "02348149f1833c63bf52764838d5659507857394", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": "^10.0 || ^9.0 || >=8.40.0 || ^7.0", + "php": "^7.2 || ^8.0", + "swagger-api/swagger-ui": "^3.0 || >=4.1.3", + "symfony/yaml": "^5.0 || ^6.0", + "zircote/swagger-php": "^3.2.0 || ^4.0.0" + }, + "require-dev": { + "mockery/mockery": "1.*", + "orchestra/testbench": "^8.0 || 7.* || ^6.15 || 5.*", + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^10.0 || ^9.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "L5Swagger\\L5SwaggerServiceProvider" + ], + "aliases": { + "L5Swagger": "L5Swagger\\L5SwaggerFacade" + } + } + }, + "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/8.5.1" + }, + "funding": [ + { + "url": "https://github.com/DarkaOnLine", + "type": "github" + } + ], + "time": "2023-06-05T04:21:50+00:00" + }, + { + "name": "defuse/php-encryption", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/defuse/php-encryption.git", + "reference": "f53396c2d34225064647a05ca76c1da9d99e5828" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/defuse/php-encryption/zipball/f53396c2d34225064647a05ca76c1da9d99e5828", + "reference": "f53396c2d34225064647a05ca76c1da9d99e5828", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "paragonie/random_compat": ">= 2", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "^5|^6|^7|^8|^9|^10", + "yoast/phpunit-polyfills": "^2.0.0" + }, + "bin": [ + "bin/generate-defuse-key" + ], + "type": "library", + "autoload": { + "psr-4": { + "Defuse\\Crypto\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Hornby", + "email": "taylor@defuse.ca", + "homepage": "https://defuse.ca/" + }, + { + "name": "Scott Arciszewski", + "email": "info@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "Secure PHP Encryption Library", + "keywords": [ + "aes", + "authenticated encryption", + "cipher", + "crypto", + "cryptography", + "encrypt", + "encryption", + "openssl", + "security", + "symmetric key cryptography" + ], + "support": { + "issues": "https://github.com/defuse/php-encryption/issues", + "source": "https://github.com/defuse/php-encryption/tree/v2.4.0" + }, + "time": "2023-06-19T06:10:36+00:00" + }, { "name": "dflydev/dot-access-data", "version": "v3.0.2", @@ -213,6 +359,82 @@ }, "time": "2022-10-27T11:44:00+00:00" }, + { + "name": "doctrine/annotations", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", + "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.8.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^5.4 || ^6", + "vimeo/psalm": "^4.10" + }, + "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.1" + }, + "time": "2023-02-02T22:02:53+00:00" + }, { "name": "doctrine/inflector", "version": "2.0.8", @@ -571,6 +793,69 @@ ], "time": "2023-01-14T14:17:03+00:00" }, + { + "name": "firebase/php-jwt", + "version": "v6.8.1", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "5dbc8959427416b8ee09a100d7a8588c00fb2e26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/5dbc8959427416b8ee09a100d7a8588c00fb2e26", + "reference": "5dbc8959427416b8ee09a100d7a8588c00fb2e26", + "shasum": "" + }, + "require": { + "php": "^7.4||^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^6.5||^7.4", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^1.0||^2.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.8.1" + }, + "time": "2023-07-14T18:33:00+00:00" + }, { "name": "fruitcake/php-cors", "version": "v1.2.0", @@ -1393,6 +1678,84 @@ }, "time": "2023-08-29T13:55:56+00:00" }, + { + "name": "laravel/passport", + "version": "v11.9.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/passport.git", + "reference": "93bb9c36045fe5be2eaeacf35e836c00b392b761" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/passport/zipball/93bb9c36045fe5be2eaeacf35e836c00b392b761", + "reference": "93bb9c36045fe5be2eaeacf35e836c00b392b761", + "shasum": "" + }, + "require": { + "ext-json": "*", + "firebase/php-jwt": "^6.4", + "illuminate/auth": "^9.0|^10.0", + "illuminate/console": "^9.0|^10.0", + "illuminate/container": "^9.0|^10.0", + "illuminate/contracts": "^9.0|^10.0", + "illuminate/cookie": "^9.0|^10.0", + "illuminate/database": "^9.0|^10.0", + "illuminate/encryption": "^9.0|^10.0", + "illuminate/http": "^9.0|^10.0", + "illuminate/support": "^9.0|^10.0", + "lcobucci/jwt": "^4.3|^5.0", + "league/oauth2-server": "^8.5.3", + "nyholm/psr7": "^1.5", + "php": "^8.0", + "phpseclib/phpseclib": "^2.0|^3.0", + "symfony/psr-http-message-bridge": "^2.1" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^7.0|^8.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Passport\\PassportServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Passport\\": "src/", + "Laravel\\Passport\\Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Passport provides OAuth2 server support to Laravel.", + "keywords": [ + "laravel", + "oauth", + "passport" + ], + "support": { + "issues": "https://github.com/laravel/passport/issues", + "source": "https://github.com/laravel/passport" + }, + "time": "2023-09-01T14:20:24+00:00" + }, { "name": "laravel/prompts", "version": "v0.1.6", @@ -1708,44 +2071,183 @@ "time": "2023-08-15T14:27:00+00:00" }, { - "name": "league/commonmark", - "version": "2.4.1", + "name": "lcobucci/clock", + "version": "3.1.0", "source": { "type": "git", - "url": "https://github.com/thephpleague/commonmark.git", - "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5" + "url": "https://github.com/lcobucci/clock.git", + "reference": "30a854ceb22bd87d83a7a4563b3f6312453945fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/3669d6d5f7a47a93c08ddff335e6d945481a1dd5", - "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/30a854ceb22bd87d83a7a4563b3f6312453945fc", + "reference": "30a854ceb22bd87d83a7a4563b3f6312453945fc", "shasum": "" }, "require": { - "ext-mbstring": "*", - "league/config": "^1.1.1", - "php": "^7.4 || ^8.0", - "psr/event-dispatcher": "^1.0", - "symfony/deprecation-contracts": "^2.1 || ^3.0", - "symfony/polyfill-php80": "^1.16" + "php": "~8.2.0", + "psr/clock": "^1.0" + }, + "provide": { + "psr/clock-implementation": "1.0" }, "require-dev": { - "cebe/markdown": "^1.0", - "commonmark/cmark": "0.30.0", - "commonmark/commonmark.js": "0.30.0", - "composer/package-versions-deprecated": "^1.8", - "embed/embed": "^4.4", - "erusev/parsedown": "^1.0", - "ext-json": "*", - "github/gfm": "0.29.0", - "michelf/php-markdown": "^1.4 || ^2.0", - "nyholm/psr7": "^1.5", - "phpstan/phpstan": "^1.8.2", - "phpunit/phpunit": "^9.5.21", - "scrutinizer/ocular": "^1.8.1", - "symfony/finder": "^5.3 | ^6.0", - "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", - "unleashedtech/php-coding-standard": "^3.1.1", + "infection/infection": "^0.26", + "lcobucci/coding-standard": "^10.0.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.10.7", + "phpstan/phpstan-deprecation-rules": "^1.1.3", + "phpstan/phpstan-phpunit": "^1.3.10", + "phpstan/phpstan-strict-rules": "^1.5.0", + "phpunit/phpunit": "^10.0.17" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\Clock\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "LuÃs Cobucci", + "email": "lcobucci@gmail.com" + } + ], + "description": "Yet another clock abstraction", + "support": { + "issues": "https://github.com/lcobucci/clock/issues", + "source": "https://github.com/lcobucci/clock/tree/3.1.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2023-03-20T19:12:25+00:00" + }, + { + "name": "lcobucci/jwt", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "47bdb0e0b5d00c2f89ebe33e7e384c77e84e7c34" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/47bdb0e0b5d00c2f89ebe33e7e384c77e84e7c34", + "reference": "47bdb0e0b5d00c2f89ebe33e7e384c77e84e7c34", + "shasum": "" + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-openssl": "*", + "ext-sodium": "*", + "php": "~8.1.0 || ~8.2.0", + "psr/clock": "^1.0" + }, + "require-dev": { + "infection/infection": "^0.26.19", + "lcobucci/clock": "^3.0", + "lcobucci/coding-standard": "^9.0", + "phpbench/phpbench": "^1.2.8", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.10.3", + "phpstan/phpstan-deprecation-rules": "^1.1.2", + "phpstan/phpstan-phpunit": "^1.3.8", + "phpstan/phpstan-strict-rules": "^1.5.0", + "phpunit/phpunit": "^10.0.12" + }, + "suggest": { + "lcobucci/clock": ">= 3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "LuÃs Cobucci", + "email": "lcobucci@gmail.com", + "role": "Developer" + } + ], + "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "keywords": [ + "JWS", + "jwt" + ], + "support": { + "issues": "https://github.com/lcobucci/jwt/issues", + "source": "https://github.com/lcobucci/jwt/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2023-02-25T21:35:16+00:00" + }, + { + "name": "league/commonmark", + "version": "2.4.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/3669d6d5f7a47a93c08ddff335e6d945481a1dd5", + "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.0", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", + "unleashedtech/php-coding-standard": "^3.1.1", "vimeo/psalm": "^4.24.0 || ^5.0.0" }, "suggest": { @@ -1895,6 +2397,60 @@ ], "time": "2022-12-11T20:36:23+00:00" }, + { + "name": "league/event", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/event.git", + "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/event/zipball/d2cc124cf9a3fab2bb4ff963307f60361ce4d119", + "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "~1.0.1", + "phpspec/phpspec": "^2.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Event\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Event package", + "keywords": [ + "emitter", + "event", + "listener" + ], + "support": { + "issues": "https://github.com/thephpleague/event/issues", + "source": "https://github.com/thephpleague/event/tree/master" + }, + "time": "2018-11-26T11:52:41+00:00" + }, { "name": "league/flysystem", "version": "3.15.1", @@ -2097,7 +2653,269 @@ "type": "tidelift" } ], - "time": "2023-08-05T12:09:49+00:00" + "time": "2023-08-05T12:09:49+00:00" + }, + { + "name": "league/oauth2-server", + "version": "8.5.4", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth2-server.git", + "reference": "ab7714d073844497fd222d5d0a217629089936bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/ab7714d073844497fd222d5d0a217629089936bc", + "reference": "ab7714d073844497fd222d5d0a217629089936bc", + "shasum": "" + }, + "require": { + "defuse/php-encryption": "^2.3", + "ext-openssl": "*", + "lcobucci/clock": "^2.2 || ^3.0", + "lcobucci/jwt": "^4.3 || ^5.0", + "league/event": "^2.2", + "league/uri": "^6.7 || ^7.0", + "php": "^8.0", + "psr/http-message": "^1.0.1 || ^2.0" + }, + "replace": { + "league/oauth2server": "*", + "lncd/oauth2": "*" + }, + "require-dev": { + "laminas/laminas-diactoros": "^3.0.0", + "phpstan/phpstan": "^0.12.57", + "phpstan/phpstan-phpunit": "^0.12.16", + "phpunit/phpunit": "^9.6.6", + "roave/security-advisories": "dev-master" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\OAuth2\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alex Bilbie", + "email": "hello@alexbilbie.com", + "homepage": "http://www.alexbilbie.com", + "role": "Developer" + }, + { + "name": "Andy Millington", + "email": "andrew@noexceptions.io", + "homepage": "https://www.noexceptions.io", + "role": "Developer" + } + ], + "description": "A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.", + "homepage": "https://oauth2.thephpleague.com/", + "keywords": [ + "Authentication", + "api", + "auth", + "authorisation", + "authorization", + "oauth", + "oauth 2", + "oauth 2.0", + "oauth2", + "protect", + "resource", + "secure", + "server" + ], + "support": { + "issues": "https://github.com/thephpleague/oauth2-server/issues", + "source": "https://github.com/thephpleague/oauth2-server/tree/8.5.4" + }, + "funding": [ + { + "url": "https://github.com/sephster", + "type": "github" + } + ], + "time": "2023-08-25T22:35:12+00:00" + }, + { + "name": "league/uri", + "version": "7.3.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "36743c3961bb82bf93da91917b6bced0358a8d45" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/36743c3961bb82bf93da91917b6bced0358a8d45", + "reference": "36743c3961bb82bf93da91917b6bced0358a8d45", + "shasum": "" + }, + "require": { + "league/uri-interfaces": "^7.3", + "php": "^8.1" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", + "league/uri-components": "Needed to easily manipulate URI objects components", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.3.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2023-09-09T17:21:43+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "7.3.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "c409b60ed2245ff94c965a8c798a60166db53361" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/c409b60ed2245ff94c965a8c798a60166db53361", + "reference": "c409b60ed2245ff94c965a8c798a60166db53361", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-factory": "^1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common interfaces and classes for URI representation and interaction", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.3.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2023-09-09T17:21:43+00:00" }, { "name": "masterminds/html5", @@ -2664,6 +3482,201 @@ ], "time": "2023-02-08T01:06:31+00:00" }, + { + "name": "nyholm/psr7", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "3cb4d163b58589e47b35103e8e5e6a6a475b47be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/3cb4d163b58589e47b35103e8e5e6a6a475b47be", + "reference": "3cb4d163b58589e47b35103e8e5e6a6a475b47be", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0", + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.8.0" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-05-02T11:26:24+00:00" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.6.3", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "58c3f47f650c94ec05a151692652a868995d2938" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", + "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2022-06-14T06:56:20+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, { "name": "phenx/php-font-lib", "version": "0.5.4", @@ -2829,6 +3842,165 @@ ], "time": "2023-02-25T19:38:58+00:00" }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.23", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "866cc78fbd82462ffd880e3f65692afe928bed50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/866cc78fbd82462ffd880e3f65692afe928bed50", + "reference": "866cc78fbd82462ffd880e3f65692afe928bed50", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.23" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2023-09-18T17:22:01+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", "version": "1.0.0", @@ -3582,18 +4754,79 @@ "name": "Raphael Schweikert" } ], - "description": "Parser for CSS Files written in PHP", - "homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser", + "description": "Parser for CSS Files written in PHP", + "homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser", + "keywords": [ + "css", + "parser", + "stylesheet" + ], + "support": { + "issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues", + "source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/8.4.0" + }, + "time": "2021-12-11T13:40:54+00:00" + }, + { + "name": "swagger-api/swagger-ui", + "version": "v5.7.2", + "source": { + "type": "git", + "url": "https://github.com/swagger-api/swagger-ui.git", + "reference": "7b8fee352a2fc47d18308a7292bc5498ec0022be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/7b8fee352a2fc47d18308a7292bc5498ec0022be", + "reference": "7b8fee352a2fc47d18308a7292bc5498ec0022be", + "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": [ - "css", - "parser", - "stylesheet" + "api", + "documentation", + "openapi", + "specification", + "swagger", + "ui" ], "support": { - "issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues", - "source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/8.4.0" + "issues": "https://github.com/swagger-api/swagger-ui/issues", + "source": "https://github.com/swagger-api/swagger-ui/tree/v5.7.2" }, - "time": "2021-12-11T13:40:54+00:00" + "time": "2023-09-18T07:43:59+00:00" }, { "name": "symfony/console", @@ -5264,6 +6497,95 @@ ], "time": "2023-08-07T10:39:22+00:00" }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "581ca6067eb62640de5ff08ee1ba6850a0ee472e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/581ca6067eb62640de5ff08ee1ba6850a0ee472e", + "reference": "581ca6067eb62640de5ff08ee1ba6850a0ee472e", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/http-message": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/http-foundation": "^5.4 || ^6.0" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "psr/log": "^1.1 || ^2 || ^3", + "symfony/browser-kit": "^5.4 || ^6.0", + "symfony/config": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/framework-bundle": "^5.4 || ^6.0", + "symfony/http-kernel": "^5.4 || ^6.0", + "symfony/phpunit-bridge": "^6.2" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-main": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/symfony/psr-http-message-bridge/issues", + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.3.1" + }, + "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": "2023-07-26T11:53:26+00:00" + }, { "name": "symfony/routing", "version": "v6.3.3", @@ -5846,6 +7168,78 @@ ], "time": "2023-08-24T14:51:05+00:00" }, + { + "name": "symfony/yaml", + "version": "v6.3.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "e23292e8c07c85b971b44c1c4b87af52133e2add" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/e23292e8c07c85b971b44c1c4b87af52133e2add", + "reference": "e23292e8c07c85b971b44c1c4b87af52133e2add", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.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/v6.3.3" + }, + "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": "2023-07-31T07:08:24+00:00" + }, { "name": "tijsverkoyen/css-to-inline-styles", "version": "2.2.6", @@ -6114,6 +7508,84 @@ "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, "time": "2022-06-03T18:03:27+00:00" + }, + { + "name": "zircote/swagger-php", + "version": "4.7.14", + "source": { + "type": "git", + "url": "https://github.com/zircote/swagger-php.git", + "reference": "e53c0c7a6e250c435cc13ab50792247a8eb07da3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/e53c0c7a6e250c435cc13ab50792247a8eb07da3", + "reference": "e53c0c7a6e250c435cc13ab50792247a8eb07da3", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.7 || ^2.0", + "ext-json": "*", + "php": ">=7.2", + "psr/log": "^1.1 || ^2.0 || ^3.0", + "symfony/deprecation-contracts": "^2 || ^3", + "symfony/finder": ">=2.2", + "symfony/yaml": ">=3.3" + }, + "require-dev": { + "composer/package-versions-deprecated": "^1.11", + "friendsofphp/php-cs-fixer": "^2.17 || ^3.0", + "phpstan/phpstan": "^1.6", + "phpunit/phpunit": ">=8", + "vimeo/psalm": "^4.23" + }, + "bin": [ + "bin/openapi" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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": "swagger-php - Generate interactive documentation for your RESTful API using 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/4.7.14" + }, + "time": "2023-09-12T00:18:13+00:00" } ], "packages-dev": [ @@ -8491,78 +9963,6 @@ ], "time": "2023-08-23T06:24:34+00:00" }, - { - "name": "symfony/yaml", - "version": "v6.3.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "e23292e8c07c85b971b44c1c4b87af52133e2add" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e23292e8c07c85b971b44c1c4b87af52133e2add", - "reference": "e23292e8c07c85b971b44c1c4b87af52133e2add", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<5.4" - }, - "require-dev": { - "symfony/console": "^5.4|^6.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/v6.3.3" - }, - "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": "2023-07-31T07:08:24+00:00" - }, { "name": "theseer/tokenizer", "version": "1.2.1", diff --git a/config/app.php b/config/app.php index 841e18ec649458b3f766eeda85f9cf3da5762b04..eaac0f1b7d0261a35375d4dc8e5c487f5d55f4a5 100644 --- a/config/app.php +++ b/config/app.php @@ -55,7 +55,7 @@ | */ - 'url' => env('APP_URL', 'http://localhost'), + 'url' => env('APP_URL', 'http://localhost:8000'), 'asset_url' => env('ASSET_URL'), diff --git a/config/auth.php b/config/auth.php index 9548c15de9407839ac1068eb208c008b56e54b52..c9742ceaf49b1706ca493e1c6ce973d60f347714 100644 --- a/config/auth.php +++ b/config/auth.php @@ -40,6 +40,10 @@ 'driver' => 'session', 'provider' => 'users', ], + 'api' => [ + 'driver' => 'passport', + 'provider' => 'users', + ], ], /* diff --git a/config/l5-swagger.php b/config/l5-swagger.php new file mode 100644 index 0000000000000000000000000000000000000000..886b638d6ffa124c3e77b07ecdb459f558f77907 --- /dev/null +++ b/config/l5-swagger.php @@ -0,0 +1,310 @@ +<?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), + + /* + * 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' => [ + \App\Http\Middleware\EncryptCookies::class, + \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\View\Middleware\ShareErrorsFromSession::class, + \App\Http\Middleware\VerifyCsrfToken::class, + \Illuminate\Routing\Middleware\SubstituteBindings::class, + \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class, + 'auth', + ], + '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), + + /* + * 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/'), + + /* + * Absolute path to directories that should be exclude from scanning + * @deprecated Please use `scanOptions.exclude` + * `scanOptions.exclude` overwrites this + */ + 'excludes' => [], + ], + + 'scanOptions' => [ + /** + * 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/schema-query-parameter-processor + * @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' => [ + /* + * 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://localhost:8000'), + ], + ], +]; diff --git a/resources/views/grades/form.blade.php b/resources/views/grades/form.blade.php index 4997495c94aae8b2a1a1b2562af816aa5317226f..c63043cef0f7d33a77a7725a993968fe3562fd17 100644 --- a/resources/views/grades/form.blade.php +++ b/resources/views/grades/form.blade.php @@ -10,8 +10,8 @@ @method($method) @if ($method == 'POST') <div class="d-flex w-100 justify-content-center mt-2"> - <input type="text" maxlength="16" name="subject" class="form-control w-50" - placeholder="Subject Name"> + <input type="text" maxlength="16" name="subject_id" class="form-control w-50" + placeholder="Subject Id"> </div> @endif <div class="d-flex w-100 justify-content-center mt-2"> diff --git a/resources/views/vendor/l5-swagger/.gitkeep b/resources/views/vendor/l5-swagger/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/resources/views/vendor/l5-swagger/index.blade.php b/resources/views/vendor/l5-swagger/index.blade.php new file mode 100644 index 0000000000000000000000000000000000000000..da60adac75da61cccc5ba484d2c93a8a8ac2dffc --- /dev/null +++ b/resources/views/vendor/l5-swagger/index.blade.php @@ -0,0 +1,78 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <title>{{config('l5-swagger.documentations.'.$documentation.'.api.title')}}</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> +</head> + +<body> +<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() { + // Build a system + const ui = SwaggerUIBundle({ + dom_id: '#swagger-ui', + url: "{!! $urlToDocs !!}", + 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> diff --git a/routes/api.php b/routes/api.php index 889937e11a55065725869401d22252f888029c2f..700fa8653cd2ae20e9e4c8dfa8e9e11666c7e216 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,6 +1,10 @@ <?php -use Illuminate\Http\Request; +use App\Http\Controllers\Api\Auth\AuthController; +use App\Http\Controllers\Api\GradeController; +use App\Http\Controllers\Api\GroupController; +use App\Http\Controllers\Api\StudentController; +use App\Http\Controllers\Api\SubjectController; use Illuminate\Support\Facades\Route; /* @@ -14,6 +18,19 @@ | */ -Route::middleware('auth:sanctum')->get('/user', function (Request $request) { - return $request->user(); +Route::post('/login', [AuthController::class, 'login']); + +Route::middleware('auth:api')->group(function () { + Route::post('/logout', [AuthController::class, 'logout']); + Route::post('/reset', [AuthController::class, 'reset']); + + Route::resources([ + 'group' => GroupController::class, + 'subject' => SubjectController::class, + 'student' => StudentController::class, + ]); + Route::resource('student.subject', GradeController::class)->except('index', 'show'); + Route::delete('/student/force/{student}', [StudentController::class, 'forceDelete'])->withTrashed()->name('student.force'); + Route::get('/student/restore/{student}', [StudentController::class, 'restore'])->withTrashed()->name('student.restore'); + Route::get('/export/{user}', [StudentController::class, 'export'])->name('student.export'); }); diff --git a/routes/auth.php b/routes/auth.php index 3926ecf72a8b0ceb1d796215be602d6b6accf846..a9c63759a67a3dc62a930e55fb6863514bc94f80 100644 --- a/routes/auth.php +++ b/routes/auth.php @@ -1,14 +1,14 @@ <?php -use App\Http\Controllers\Auth\AuthenticatedSessionController; -use App\Http\Controllers\Auth\ConfirmablePasswordController; -use App\Http\Controllers\Auth\EmailVerificationNotificationController; -use App\Http\Controllers\Auth\EmailVerificationPromptController; -use App\Http\Controllers\Auth\NewPasswordController; -use App\Http\Controllers\Auth\PasswordController; -use App\Http\Controllers\Auth\PasswordResetLinkController; -use App\Http\Controllers\Auth\RegisteredUserController; -use App\Http\Controllers\Auth\VerifyEmailController; +use App\Http\Controllers\Web\Auth\AuthenticatedSessionController; +use App\Http\Controllers\Web\Auth\ConfirmablePasswordController; +use App\Http\Controllers\Web\Auth\EmailVerificationNotificationController; +use App\Http\Controllers\Web\Auth\EmailVerificationPromptController; +use App\Http\Controllers\Web\Auth\NewPasswordController; +use App\Http\Controllers\Web\Auth\PasswordController; +use App\Http\Controllers\Web\Auth\PasswordResetLinkController; +use App\Http\Controllers\Web\Auth\RegisteredUserController; +use App\Http\Controllers\Web\Auth\VerifyEmailController; use Illuminate\Support\Facades\Route; Route::middleware('guest')->group(function () { diff --git a/routes/web.php b/routes/web.php index e3e8c03366ed7ddacc1263662e0cc2d847601c6b..cfed1500fdeb242e17e34aa3612aaf167a76ea9a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,10 +1,10 @@ <?php -use App\Http\Controllers\GradeController; -use App\Http\Controllers\GroupController; -use App\Http\Controllers\ProfileController; -use App\Http\Controllers\StudentController; -use App\Http\Controllers\SubjectController; +use App\Http\Controllers\Web\GradeController; +use App\Http\Controllers\Web\GroupController; +use App\Http\Controllers\Web\ProfileController; +use App\Http\Controllers\Web\StudentController; +use App\Http\Controllers\Web\SubjectController; use Illuminate\Support\Facades\Route; /* diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json new file mode 100644 index 0000000000000000000000000000000000000000..6f01949b9712e42235c65f490d075ec33e9e7567 --- /dev/null +++ b/storage/api-docs/api-docs.json @@ -0,0 +1,1699 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "API", + "description": "api", + "version": "1.0.0" + }, + "servers": [ + { + "url": "http://localhost:8000", + "description": "Host" + } + ], + "paths": { + "/api/login": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Login", + "operationId": "ea134134deae11eb974c719450ef8a02", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "": { + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "example": { + "email": "user@test.com", + "password": "useruser1" + } + } + } + } + }, + "responses": { + "200": { + "description": "Valid credentials. User Object", + "content": { + "application/json": { + "schema": { + "properties": { + "user": { + "properties": { + "id": { + "type": "number", + "example": 2 + }, + "first_name": { + "type": "string", + "example": "Joe" + }, + "middle_name": { + "type": "string", + "example": "Lie" + }, + "last_name": { + "type": "string", + "example": "Goldberg" + }, + "email": { + "type": "string", + "example": "user@test.com" + }, + "email_verified_at": { + "type": "string", + "example": null + }, + "updated_at": { + "type": "string", + "example": "2022-06-28 06:06:17" + }, + "created_at": { + "type": "string", + "example": "2022-06-28 06:06:17" + }, + "token": { + "type": "string", + "example": "lasjdlkajsdlajsdljasldjalksdjalsdla" + } + }, + "type": "object" + } + }, + "type": "object" + } + } + } + }, + "402": { + "description": "Invalid credentials", + "content": { + "application/json": { + "schema": { + "properties": { + "meta": { + "properties": { + "message": { + "type": "string", + "example": "Invalid credentials" + } + }, + "type": "object" + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/api/logout": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Logout", + "operationId": "5ebea01ab5f21df71d38f3505718a1d7", + "responses": { + "200": { + "description": "You are successfully logged out", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "You are successfully logged out" + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/api/reset": { + "post": { + "tags": [ + "Auth" + ], + "summary": "Reset Password", + "operationId": "cb1de25c4bc4b4db1025935ce501bc6e", + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "": { + "properties": { + "email": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "example": { + "email": "user@test.com" + } + } + } + } + }, + "responses": { + "200": { + "description": "Status", + "content": { + "application/json": { + "schema": { + "properties": { + "status": { + "type": "string" + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/api/student/{id}/subject": { + "post": { + "tags": [ + "Grade" + ], + "summary": "Grade store", + "operationId": "8c7dd1a4609e1c100cae348c81c6f6eb", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Student ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "required": [ + "subject_id", + "grade" + ], + "properties": { + "subject_id": { + "type": "integer" + }, + "grade": { + "type": "integer" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GradeResource" + } + } + } + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + } + }, + "/api/student/{student}/subject/{subject}": { + "put": { + "tags": [ + "Grade" + ], + "summary": "Grade update", + "operationId": "5e748000e1d6f250801dcb5c46a2f402", + "parameters": [ + { + "name": "student", + "in": "path", + "description": "Student ID", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "subject", + "in": "path", + "description": "Subject ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "grade" + ], + "properties": { + "grade": { + "type": "integer" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GradeResource" + } + } + } + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + }, + "delete": { + "tags": [ + "Grade" + ], + "summary": "Grade destroy", + "operationId": "4220d82c13b14c9a49fc7bdad882813a", + "parameters": [ + { + "name": "student", + "in": "path", + "description": "Student ID", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "subject", + "in": "path", + "description": "Subject ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Not Found" + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + } + }, + "/api/group": { + "get": { + "tags": [ + "Group" + ], + "summary": "Group index", + "operationId": "ae8cb57d72c26bd30a12d73661e1a83b", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GroupResource" + } + }, + "meta": { + "properties": { + "current_page": { + "type": "integer" + }, + "from": { + "type": "integer" + }, + "last_page": { + "type": "integer" + }, + "links": { + "type": "array", + "items": { + "properties": { + "url": { + "type": "string" + }, + "label": { + "type": "string" + }, + "active": { + "type": "boolean" + } + }, + "type": "object" + } + } + }, + "type": "object" + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + }, + "post": { + "tags": [ + "Group" + ], + "summary": "Group store", + "operationId": "b57b30a7900d9c58f314312ecad49606", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "201": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/GroupResource" + } + }, + "type": "object" + } + } + } + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + } + }, + "/api/group/{id}": { + "get": { + "tags": [ + "Group" + ], + "summary": "Group show", + "operationId": "e0bc0f2b0bed3af250f53be41e0b2c86", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Group ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/GroupResource" + } + }, + "type": "object" + } + } + } + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "passport": [] + } + ] + }, + "put": { + "tags": [ + "Group" + ], + "summary": "Group update", + "operationId": "a158bf58f21b0db6b4367218b56e1f14", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Group ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + }, + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/GroupResource" + } + }, + "type": "object" + } + } + } + }, + "404": { + "description": "Not Found" + }, + "422": { + "description": "Unprocessable Entity" + } + }, + "security": [ + { + "passport": [] + } + ] + }, + "delete": { + "tags": [ + "Group" + ], + "summary": "Group destroy", + "operationId": "0fce1f52c40fcb74a2ab5f4d7145fa64", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Group ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "is_deleted": { + "type": "boolean" + } + }, + "type": "object" + } + } + } + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "passport": [] + } + ] + } + }, + "/api/export/{id}": { + "get": { + "tags": [ + "Student" + ], + "summary": "Student export", + "operationId": "b32cca69905f4122de9be458a4da4d62", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Student ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "passport": [] + } + ] + } + }, + "/api/student": { + "get": { + "tags": [ + "Student" + ], + "summary": "Student index", + "operationId": "765b556486fcf7bd523d615e8292eb17", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserResource" + } + }, + "links": { + "properties": { + "first": { + "type": "string", + "example": "http://localhost:8001/api/student?page=1" + }, + "last": { + "type": "string", + "example": "http://localhost:8001/api/student?page=51" + }, + "prev": { + "type": "string", + "example": "http://localhost:8001/api/student?page=1" + }, + "next": { + "type": "string", + "example": "http://localhost:8001/api/student?page=3" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "current_page": { + "type": "integer" + }, + "from": { + "type": "integer" + }, + "last_page": { + "type": "integer" + }, + "links": { + "type": "array", + "items": { + "properties": { + "url": { + "type": "string" + }, + "label": { + "type": "string" + }, + "active": { + "type": "boolean" + } + }, + "type": "object" + } + } + }, + "type": "object" + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + }, + "post": { + "tags": [ + "Student" + ], + "summary": "Student store", + "operationId": "9e3556e4c7f693577b42bd83f3800d21", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "first_name", + "middle_name", + "last_name", + "birthday", + "role", + "group_id" + ], + "properties": { + "first_name": { + "type": "string" + }, + "middle_name": { + "type": "string" + }, + "last_name": { + "type": "string" + }, + "role": { + "type": "integer" + }, + "group_id": { + "type": "integer" + }, + "birthday": { + "type": "string", + "format": "date" + }, + "city": { + "type": "string" + }, + "house": { + "type": "string" + }, + "street": { + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "201": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/UserResource" + } + }, + "type": "object" + } + } + } + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + } + }, + "/api/student/{id}": { + "get": { + "tags": [ + "Student" + ], + "summary": "Student show", + "operationId": "0902369cd3b5356b55e0ddedf3a394df", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Student ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/UserResource" + } + }, + "type": "object" + } + } + } + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "passport": [] + } + ] + }, + "put": { + "tags": [ + "Student" + ], + "summary": "Student update", + "operationId": "f1318cff9b5cc8f35a8e48b38425e00c", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Student ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "first_name", + "middle_name", + "last_name", + "birthday", + "role", + "group_id" + ], + "properties": { + "first_name": { + "type": "string" + }, + "middle_name": { + "type": "string" + }, + "last_name": { + "type": "string" + }, + "role": { + "type": "integer" + }, + "group_id": { + "type": "integer" + }, + "birthday": { + "type": "string", + "format": "date" + }, + "address": { + "properties": { + "city": { + "type": "string" + }, + "house": { + "type": "string" + }, + "street": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/UserResource" + } + }, + "type": "object" + } + } + } + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + }, + "delete": { + "tags": [ + "Student" + ], + "summary": "Student destroy", + "operationId": "0685726002193a89ffe002b7d4d5b84d", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Student ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "is_deleted": { + "type": "boolean" + } + }, + "type": "object" + } + } + } + }, + "404": { + "description": "Not Found" + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + } + }, + "/api/student/restore/{id}": { + "get": { + "tags": [ + "Student" + ], + "summary": "Restore user", + "operationId": "da9836ff3098daf804fd81dc727b5fab", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Student ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserResource" + } + } + } + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + } + }, + "/api/student/force/{id}": { + "delete": { + "tags": [ + "Student" + ], + "summary": "Student force delete", + "operationId": "8f5638c92849a62fe367b888f85b755b", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Student ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "is_deleted": { + "type": "boolean" + } + }, + "type": "object" + } + } + } + }, + "404": { + "description": "Not Found" + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + } + }, + "/api/subject": { + "get": { + "tags": [ + "Subject" + ], + "summary": "Subject index", + "operationId": "2c5c608026c1ff0b4c65751eb8eb8034", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SubjectResource" + } + }, + "meta": { + "properties": { + "current_page": { + "type": "integer" + }, + "from": { + "type": "integer" + }, + "last_page": { + "type": "integer" + }, + "links": { + "type": "array", + "items": { + "properties": { + "url": { + "type": "string" + }, + "label": { + "type": "string" + }, + "active": { + "type": "boolean" + } + }, + "type": "object" + } + } + }, + "type": "object" + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + }, + "post": { + "tags": [ + "Subject" + ], + "summary": "Subject store", + "operationId": "2f6e9badee8261315c45d7bfcba0dd1f", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "201": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/SubjectResource" + } + }, + "type": "object" + } + } + } + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + } + }, + "/api/subject/{id}": { + "get": { + "tags": [ + "Subject" + ], + "summary": "Subject show", + "operationId": "23031e917e8ed156058b427d1efc012b", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Subject ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/SubjectResource" + } + }, + "type": "object" + } + } + } + }, + "404": { + "description": "Not Found" + } + }, + "security": [ + { + "passport": [] + } + ] + }, + "put": { + "tags": [ + "Subject" + ], + "summary": "Subject update", + "operationId": "4f3526320a723001ee64573d6096d817", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Subject ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/SubjectResource" + } + }, + "type": "object" + } + } + } + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + }, + "delete": { + "tags": [ + "Subject" + ], + "summary": "Subject destroy", + "operationId": "e3cb38f24fff1418a4352d25c4fb0131", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Subject ID", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "is_deleted": { + "type": "boolean" + } + }, + "type": "object" + } + } + } + }, + "404": { + "description": "Not Found" + }, + "403": { + "description": "Not Auth", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string", + "example": "This action is unauthorized." + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "passport": [] + } + ] + } + } + }, + "components": { + "schemas": { + "GradeResource": { + "title": "GradeResource", + "description": "Group Properties", + "properties": { + "student": { + "type": "integer" + }, + "subject": { + "type": "integer" + }, + "grade": { + "type": "integer" + } + }, + "type": "object" + }, + "GroupResource": { + "title": "GroupResource", + "description": "Group Properties", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date" + }, + "updated_at": { + "type": "string", + "format": "date" + } + }, + "type": "object" + }, + "SubjectResource": { + "title": "SubjectResource", + "description": "Subject Properies", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date" + }, + "updated_at": { + "type": "string", + "format": "date" + } + }, + "type": "object" + }, + "UserResource": { + "title": "UserResource", + "description": "User Properties", + "properties": { + "id": { + "type": "integer" + }, + "first_name": { + "type": "string" + }, + "middle_name": { + "type": "string" + }, + "last_name": { + "type": "string" + }, + "birthday": { + "type": "string", + "format": "date" + }, + "role": { + "type": "integer" + }, + "group_id": { + "type": "integer" + }, + "address": { + "properties": { + "city": { + "type": "string" + }, + "street": { + "type": "string" + }, + "house": { + "type": "string" + } + }, + "type": "object" + }, + "created_at": { + "type": "string", + "format": "date" + }, + "updated_at": { + "type": "string", + "format": "date" + } + }, + "type": "object" + } + }, + "securitySchemes": { + "passport": { + "type": "oauth2", + "description": "Laravel passport oauth2 security.", + "in": "header", + "scheme": "https", + "flows": { + "password": { + "authorizationUrl": "http://localhost:8000/oauth/authorize", + "tokenUrl": "http://localhost:8000/oauth/token", + "refreshUrl": "http://localhost:8000/token/refresh", + "scopes": [] + } + } + } + } + } +} \ No newline at end of file