From afb5011fbebacd660f999070289b956d0e6bbb8a Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 3 Sep 2016 17:09:00 -0400 Subject: [PATCH] Update to Laravel 5.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [BREAKING] — REMOVES REMOTE API A new API will need to be implemented properly using the new Laravel Passport OAuth2 system. DingoAPI was becoming too unstable and development wasn’t really moving along enough to continue to rely on it. --- app/Exceptions/Handler.php | 37 +++- app/Http/Controllers/API/BaseController.php | 32 --- .../Controllers/API/LocationController.php | 64 ------ app/Http/Controllers/API/NodeController.php | 198 ----------------- app/Http/Controllers/API/ServerController.php | 200 ----------------- .../Controllers/API/ServiceController.php | 68 ------ app/Http/Controllers/API/UserController.php | 202 ----------------- .../Auth/ForgotPasswordController.php | 32 +++ ...AuthController.php => LoginController.php} | 70 ++---- .../Controllers/Auth/PasswordController.php | 56 ----- .../Controllers/Auth/RegisterController.php | 71 ++++++ .../Auth/ResetPasswordController.php | 32 +++ app/Http/Kernel.php | 25 ++- app/Http/Middleware/APISecretToken.php | 125 ----------- .../Middleware/RedirectIfAuthenticated.php | 25 +-- app/Http/Routes/APIRoutes.php | 150 ------------- app/Http/Routes/AuthRoutes.php | 17 +- app/Models/User.php | 16 +- app/Notifications/SendPasswordReset.php | 69 ++++++ app/Providers/BroadcastServiceProvider.php | 26 +++ app/Providers/EventServiceProvider.php | 7 +- app/Providers/RouteServiceProvider.php | 45 +++- app/Transformers/NodeTransformer.php | 42 ---- app/Transformers/ServerTransformer.php | 42 ---- app/Transformers/UserTransformer.php | 42 ---- composer.json | 36 ++- config/api.php | 209 ------------------ config/app.php | 6 +- .../email.blade.php} | 9 +- .../auth/{ => passwords}/reset.blade.php | 23 +- resources/views/emails/password.blade.php | 32 --- .../notifications/email-plain.blade.php | 22 ++ .../vendor/notifications/email.blade.php | 192 ++++++++++++++++ .../vendor/pagination/bootstrap-4.blade.php | 36 +++ .../views/vendor/pagination/default.blade.php | 36 +++ .../pagination/simple-bootstrap-4.blade.php | 17 ++ .../pagination/simple-default.blade.php | 17 ++ 37 files changed, 732 insertions(+), 1596 deletions(-) delete mode 100644 app/Http/Controllers/API/BaseController.php delete mode 100644 app/Http/Controllers/API/LocationController.php delete mode 100644 app/Http/Controllers/API/NodeController.php delete mode 100644 app/Http/Controllers/API/ServerController.php delete mode 100644 app/Http/Controllers/API/ServiceController.php delete mode 100644 app/Http/Controllers/API/UserController.php create mode 100644 app/Http/Controllers/Auth/ForgotPasswordController.php rename app/Http/Controllers/Auth/{AuthController.php => LoginController.php} (66%) delete mode 100644 app/Http/Controllers/Auth/PasswordController.php create mode 100644 app/Http/Controllers/Auth/RegisterController.php create mode 100644 app/Http/Controllers/Auth/ResetPasswordController.php delete mode 100644 app/Http/Middleware/APISecretToken.php delete mode 100644 app/Http/Routes/APIRoutes.php create mode 100644 app/Notifications/SendPasswordReset.php create mode 100644 app/Providers/BroadcastServiceProvider.php delete mode 100644 app/Transformers/NodeTransformer.php delete mode 100644 app/Transformers/ServerTransformer.php delete mode 100644 app/Transformers/UserTransformer.php delete mode 100644 config/api.php rename resources/views/auth/{password.blade.php => passwords/email.blade.php} (86%) rename resources/views/auth/{ => passwords}/reset.blade.php (71%) delete mode 100644 resources/views/emails/password.blade.php create mode 100644 resources/views/vendor/notifications/email-plain.blade.php create mode 100644 resources/views/vendor/notifications/email.blade.php create mode 100644 resources/views/vendor/pagination/bootstrap-4.blade.php create mode 100644 resources/views/vendor/pagination/default.blade.php create mode 100644 resources/views/vendor/pagination/simple-bootstrap-4.blade.php create mode 100644 resources/views/vendor/pagination/simple-default.blade.php diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index eba6f488e..661ca9a07 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -7,12 +7,7 @@ use DisplayException; use DisplayValidationException; use AccountNotFoundException; -use Illuminate\Database\Eloquent\ModelNotFoundException; -use Symfony\Component\HttpKernel\Exception\HttpException; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -use Illuminate\Auth\Access\AuthorizationException; -use Illuminate\Foundation\Validation\ValidationException; - +use Illuminate\Auth\AuthenticationException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; class Handler extends ExceptionHandler @@ -23,10 +18,12 @@ class Handler extends ExceptionHandler * @var array */ protected $dontReport = [ - HttpException::class, - ModelNotFoundException::class, - ValidationException::class, - AuthorizationException::class, + \Illuminate\Auth\AuthenticationException::class, + \Illuminate\Auth\Access\AuthorizationException::class, + \Symfony\Component\HttpKernel\Exception\HttpException::class, + \Illuminate\Database\Eloquent\ModelNotFoundException::class, + \Illuminate\Session\TokenMismatchException::class, + \Illuminate\Validation\ValidationException::class, ]; /** @@ -37,9 +34,9 @@ class Handler extends ExceptionHandler * @param \Exception $e * @return void */ - public function report(Exception $e) + public function report(Exception $exception) { - return parent::report($e); + return parent::report($exception); } /** @@ -83,4 +80,20 @@ class Handler extends ExceptionHandler return parent::render($request, $e); } + + /** + * Convert an authentication exception into an unauthenticated response. + * + * @param \Illuminate\Http\Request $request + * @param \Illuminate\Auth\AuthenticationException $exception + * @return \Illuminate\Http\Response + */ + protected function unauthenticated($request, AuthenticationException $exception) + { + if ($request->expectsJson()) { + return response()->json(['error' => 'Unauthenticated.'], 401); + } + return redirect()->guest('/auth/login'); + } + } diff --git a/app/Http/Controllers/API/BaseController.php b/app/Http/Controllers/API/BaseController.php deleted file mode 100644 index 7d897fe55..000000000 --- a/app/Http/Controllers/API/BaseController.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Http\Controllers\API; - -use Dingo\Api\Routing\Helpers; -use Illuminate\Routing\Controller; - -class BaseController extends Controller -{ - use Helpers; -} diff --git a/app/Http/Controllers/API/LocationController.php b/app/Http/Controllers/API/LocationController.php deleted file mode 100644 index e289172d3..000000000 --- a/app/Http/Controllers/API/LocationController.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Http\Controllers\API; - -use DB; -use Illuminate\Http\Request; -use Pterodactyl\Models\Location; - -/** - * @Resource("Servers") - */ -class LocationController extends BaseController -{ - - public function __construct() - { - // - } - - /** - * List All Locations - * - * Lists all locations currently on the system. - * - * @Get("/locations") - * @Versions({"v1"}) - * @Response(200) - */ - public function getLocations(Request $request) - { - $locations = Location::select('locations.*', DB::raw('GROUP_CONCAT(nodes.id) as nodes')) - ->join('nodes', 'locations.id', '=', 'nodes.location') - ->groupBy('locations.id') - ->get(); - - foreach($locations as &$location) { - $location->nodes = explode(',', $location->nodes); - } - - return $locations; - } - -} diff --git a/app/Http/Controllers/API/NodeController.php b/app/Http/Controllers/API/NodeController.php deleted file mode 100644 index 85b2ccd66..000000000 --- a/app/Http/Controllers/API/NodeController.php +++ /dev/null @@ -1,198 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Http\Controllers\API; - -use Illuminate\Http\Request; - -use Pterodactyl\Models; -use Pterodactyl\Transformers\NodeTransformer; -use Pterodactyl\Repositories\NodeRepository; - -use Pterodactyl\Exceptions\DisplayValidationException; -use Pterodactyl\Exceptions\DisplayException; -use Dingo\Api\Exception\ResourceException; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException; - -/** - * @Resource("Servers") - */ -class NodeController extends BaseController -{ - - public function __construct() - { - // - } - - /** - * List All Nodes - * - * Lists all nodes currently on the system. - * - * @Get("/nodes/{?page}") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("page", type="integer", description="The page of results to view.", default=1) - * }) - * @Response(200) - */ - public function getNodes(Request $request) - { - $nodes = Models\Node::paginate(50); - return $this->response->paginator($nodes, new NodeTransformer); - } - - /** - * Create a New Node - * - * @Post("/nodes") - * @Versions({"v1"}) - * @Transaction({ - * @Request({ - * 'name' => 'My API Node', - * 'location' => 1, - * 'public' => 1, - * 'fqdn' => 'daemon.wuzzle.woo', - * 'scheme' => 'https', - * 'memory' => 10240, - * 'memory_overallocate' => 100, - * 'disk' => 204800, - * 'disk_overallocate' => -1, - * 'daemonBase' => '/srv/daemon-data', - * 'daemonSFTP' => 2022, - * 'daemonListen' => 8080 - * }, headers={"Authorization": "Bearer "}), - * @Response(201), - * @Response(422, body={ - * "message": "A validation error occured.", - * "errors": {}, - * "status_code": 422 - * }), - * @Response(503, body={ - * "message": "There was an error while attempting to add this node to the system.", - * "status_code": 503 - * }) - * }) - */ - public function postNode(Request $request) - { - try { - $node = new NodeRepository; - $new = $node->create($request->all()); - return $this->response->created(route('api.nodes.view', [ - 'id' => $new - ])); - } catch (DisplayValidationException $ex) { - throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true)); - } catch (DisplayException $ex) { - throw new ResourceException($ex->getMessage()); - } catch (\Exception $e) { - throw new BadRequestHttpException('There was an error while attempting to add this node to the system.'); - } - } - - /** - * List Specific Node - * - * Lists specific fields about a server or all fields pertaining to that node. - * - * @Get("/nodes/{id}/{?fields}") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("id", type="integer", required=true, description="The ID of the node to get information on."), - * @Parameter("fields", type="string", required=false, description="A comma delimidated list of fields to include.") - * }) - * @Response(200) - */ - public function getNode(Request $request, $id, $fields = null) - { - $query = Models\Node::where('id', $id); - - if (!is_null($request->input('fields'))) { - foreach(explode(',', $request->input('fields')) as $field) { - if (!empty($field)) { - $query->addSelect($field); - } - } - } - - try { - if (!$query->first()) { - throw new NotFoundHttpException('No node by that ID was found.'); - } - return $query->first(); - } catch (NotFoundHttpException $ex) { - throw $ex; - } catch (\Exception $ex) { - throw new BadRequestHttpException('There was an issue with the fields passed in the request.'); - } - } - - /** - * List Node Allocations - * - * Returns a listing of all node allocations. - * - * @Get("/nodes/{id}/allocations") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("id", type="integer", required=true, description="The ID of the node to get allocations for."), - * }) - * @Response(200) - */ - public function getNodeAllocations(Request $request, $id) - { - $allocations = Models\Allocation::select('ip', 'port', 'assigned_to')->where('node', $id)->orderBy('ip', 'asc')->orderBy('port', 'asc')->get(); - if ($allocations->count() < 1) { - throw new NotFoundHttpException('No allocations where found for the requested node.'); - } - return $allocations; - } - - /** - * Delete Node - * - * @Delete("/nodes/{id}") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("id", type="integer", required=true, description="The ID of the node."), - * }) - * @Response(204) - */ - public function deleteNode(Request $request, $id) - { - try { - $node = new NodeRepository; - $node->delete($id); - return $this->response->noContent(); - } catch (DisplayException $ex) { - throw new ResourceException($ex->getMessage()); - } catch(\Exception $e) { - throw new ServiceUnavailableHttpException('An error occured while attempting to delete this node.'); - } - } - -} diff --git a/app/Http/Controllers/API/ServerController.php b/app/Http/Controllers/API/ServerController.php deleted file mode 100644 index 0d3087ae8..000000000 --- a/app/Http/Controllers/API/ServerController.php +++ /dev/null @@ -1,200 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Http\Controllers\API; - -use Illuminate\Http\Request; - -use Pterodactyl\Models; -use Pterodactyl\Transformers\ServerTransformer; -use Pterodactyl\Repositories\ServerRepository; - -use Pterodactyl\Exceptions\DisplayValidationException; -use Pterodactyl\Exceptions\DisplayException; -use Dingo\Api\Exception\ResourceException; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException; - -/** - * @Resource("Servers") - */ -class ServerController extends BaseController -{ - - public function __construct() - { - // - } - - /** - * List All Servers - * - * Lists all servers currently on the system. - * - * @Get("/servers/{?page}") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("page", type="integer", description="The page of results to view.", default=1) - * }) - * @Response(200) - */ - public function getServers(Request $request) - { - $servers = Models\Server::paginate(50); - return $this->response->paginator($servers, new ServerTransformer); - } - - /** - * Create Server - * - * @Post("/servers") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("page", type="integer", description="The page of results to view.", default=1) - * }) - * @Response(201) - */ - public function postServer(Request $request) - { - try { - $server = new ServerRepository; - $new = $server->create($request->all()); - return $this->response->created(route('api.servers.view', [ - 'id' => $new - ])); - } catch (DisplayValidationException $ex) { - throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true)); - } catch (DisplayException $ex) { - throw new ResourceException($ex->getMessage()); - } catch (\Exception $e) { - throw new BadRequestHttpException('There was an error while attempting to add this server to the system.'); - } - } - - /** - * List Specific Server - * - * Lists specific fields about a server or all fields pertaining to that server. - * - * @Get("/servers/{id}{?fields}") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("id", type="integer", required=true, description="The ID of the server to get information on."), - * @Parameter("fields", type="string", required=false, description="A comma delimidated list of fields to include.") - * }) - * @Response(200) - */ - public function getServer(Request $request, $id) - { - $query = Models\Server::where('id', $id); - - if (!is_null($request->input('fields'))) { - foreach(explode(',', $request->input('fields')) as $field) { - if (!empty($field)) { - $query->addSelect($field); - } - } - } - - try { - if (!$query->first()) { - throw new NotFoundHttpException('No server by that ID was found.'); - } - return $query->first(); - } catch (NotFoundHttpException $ex) { - throw $ex; - } catch (\Exception $ex) { - throw new BadRequestHttpException('There was an issue with the fields passed in the request.'); - } - } - - /** - * Suspend Server - * - * @Post("/servers/{id}/suspend") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("id", type="integer", required=true, description="The ID of the server."), - * }) - * @Response(204) - */ - public function postServerSuspend(Request $request, $id) - { - try { - $server = new ServerRepository; - $server->suspend($id); - } catch (DisplayException $ex) { - throw new ResourceException($ex->getMessage()); - } catch (\Exception $ex) { - throw new ServiceUnavailableHttpException('An error occured while attempting to suspend this server instance.'); - } - } - - /** - * Unsuspend Server - * - * @Post("/servers/{id}/unsuspend") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("id", type="integer", required=true, description="The ID of the server."), - * }) - * @Response(204) - */ - public function postServerUnsuspend(Request $request, $id) - { - try { - $server = new ServerRepository; - $server->unsuspend($id); - } catch (DisplayException $ex) { - throw new ResourceException($ex->getMessage()); - } catch (\Exception $ex) { - throw new ServiceUnavailableHttpException('An error occured while attempting to unsuspend this server instance.'); - } - } - - /** - * Delete Server - * - * @Delete("/servers/{id}/{force}") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("id", type="integer", required=true, description="The ID of the server."), - * @Parameter("force", type="string", required=false, description="Use 'force' if the server should be removed regardless of daemon response."), - * }) - * @Response(204) - */ - public function deleteServer(Request $request, $id, $force = null) - { - try { - $server = new ServerRepository; - $server->deleteServer($id, $force); - return $this->response->noContent(); - } catch (DisplayException $ex) { - throw new ResourceException($ex->getMessage()); - } catch(\Exception $e) { - throw new ServiceUnavailableHttpException('An error occured while attempting to delete this server.'); - } - } - -} diff --git a/app/Http/Controllers/API/ServiceController.php b/app/Http/Controllers/API/ServiceController.php deleted file mode 100644 index f59164ba9..000000000 --- a/app/Http/Controllers/API/ServiceController.php +++ /dev/null @@ -1,68 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Http\Controllers\API; - -use Illuminate\Http\Request; - -use Pterodactyl\Models; -use Pterodactyl\Transformers\ServiceTransformer; - -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; - -/** - * @Resource("Services") - */ -class ServiceController extends BaseController -{ - - public function __construct() - { - // - } - - public function getServices(Request $request) - { - return Models\Service::all(); - } - - public function getService(Request $request, $id) - { - $service = Models\Service::find($id); - if (!$service) { - throw new NotFoundHttpException('No service by that ID was found.'); - } - - $options = Models\ServiceOptions::select('id', 'name', 'description', 'tag', 'docker_image')->where('parent_service', $service->id)->get(); - foreach($options as &$opt) { - $opt->variables = Models\ServiceVariables::where('option_id', $opt->id)->get(); - } - - return [ - 'service' => $service, - 'options' => $options - ]; - - } - -} diff --git a/app/Http/Controllers/API/UserController.php b/app/Http/Controllers/API/UserController.php deleted file mode 100644 index b50aaeb8a..000000000 --- a/app/Http/Controllers/API/UserController.php +++ /dev/null @@ -1,202 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Http\Controllers\API; - -use Illuminate\Http\Request; - -use Dingo\Api\Exception\ResourceException; - -use Pterodactyl\Models; -use Pterodactyl\Transformers\UserTransformer; -use Pterodactyl\Repositories\UserRepository; - -use Pterodactyl\Exceptions\DisplayValidationException; -use Pterodactyl\Exceptions\DisplayException; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException; - -/** - * @Resource("Users") - */ -class UserController extends BaseController -{ - - /** - * List All Users - * - * Lists all users currently on the system. - * - * @Get("/users/{?page}") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("page", type="integer", description="The page of results to view.", default=1) - * }) - * @Response(200) - */ - public function getUsers(Request $request) - { - $users = Models\User::paginate(50); - return $this->response->paginator($users, new UserTransformer); - } - - /** - * List Specific User - * - * Lists specific fields about a user or all fields pertaining to that user. - * - * @Get("/users/{id}/{fields}") - * @Versions({"v1"}) - * @Parameters({ - * @Parameter("id", type="integer", required=true, description="The ID of the user to get information on."), - * @Parameter("fields", type="string", required=false, description="A comma delimidated list of fields to include.") - * }) - * @Response(200) - */ - public function getUser(Request $request, $id) - { - $query = Models\User::where('id', $id); - - if (!is_null($request->input('fields'))) { - foreach(explode(',', $request->input('fields')) as $field) { - if (!empty($field)) { - $query->addSelect($field); - } - } - } - - try { - if (!$query->first()) { - throw new NotFoundHttpException('No user by that ID was found.'); - } - return $query->first(); - } catch (NotFoundHttpException $ex) { - throw $ex; - } catch (\Exception $ex) { - throw new BadRequestHttpException('There was an issue with the fields passed in the request.'); - } - - } - - /** - * Create a New User - * - * @Post("/users") - * @Versions({"v1"}) - * @Transaction({ - * @Request({ - * "email": "foo@example.com", - * "password": "foopassword", - * "admin": false - * }, headers={"Authorization": "Bearer "}), - * @Response(201), - * @Response(422, body={ - * "message": "A validation error occured.", - * "errors": { - * "email": {"The email field is required."}, - * "password": {"The password field is required."}, - * "admin": {"The admin field is required."} - * }, - * "status_code": 422 - * }) - * }) - */ - public function postUser(Request $request) - { - try { - $user = new UserRepository; - $create = $user->create($request->input('email'), $request->input('password'), $request->input('admin')); - return $this->response->created(route('api.users.view', [ - 'id' => $create - ])); - } catch (DisplayValidationException $ex) { - throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true)); - } catch (DisplayException $ex) { - throw new ResourceException($ex->getMessage()); - } catch (\Exception $ex) { - throw new ServiceUnavailableHttpException('Unable to create a user on the system due to an error.'); - } - } - - /** - * Update an Existing User - * - * The data sent in the request will be used to update the existing user on the system. - * - * @Patch("/users/{id}") - * @Versions({"v1"}) - * @Transaction({ - * @Request({ - * "email": "new@email.com" - * }, headers={"Authorization": "Bearer "}), - * @Response(200, body={"email": "new@email.com"}), - * @Response(422) - * }) - * @Parameters({ - * @Parameter("id", type="integer", required=true, description="The ID of the user to modify.") - * }) - */ - public function patchUser(Request $request, $id) - { - try { - $user = new UserRepository; - $user->update($id, $request->all()); - return Models\User::findOrFail($id); - } catch (DisplayValidationException $ex) { - throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true)); - } catch (DisplayException $ex) { - throw new ResourceException($ex->getMessage()); - } catch (\Exception $ex) { - throw new ServiceUnavailableHttpException('Unable to update a user on the system due to an error.'); - } - } - - /** - * Delete a User - * - * @Delete("/users/{id}") - * @Versions({"v1"}) - * @Transaction({ - * @Request(headers={"Authorization": "Bearer "}), - * @Response(204), - * @Response(422) - * }) - * @Parameters({ - * @Parameter("id", type="integer", required=true, description="The ID of the user to delete.") - * }) - */ - public function deleteUser(Request $request, $id) - { - try { - $user = new UserRepository; - $user->delete($id); - return $this->response->noContent(); - } catch (DisplayException $ex) { - throw new ResourceException($ex->getMessage()); - } catch (\Exception $ex) { - throw new ServiceUnavailableHttpException('Unable to delete this user due to an error.'); - } - } - -} diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php new file mode 100644 index 000000000..6d5f4bfa1 --- /dev/null +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -0,0 +1,32 @@ +middleware('guest'); + } +} diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/LoginController.php similarity index 66% rename from app/Http/Controllers/Auth/AuthController.php rename to app/Http/Controllers/Auth/LoginController.php index 5e2b405a1..197e69592 100644 --- a/app/Http/Controllers/Auth/AuthController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -36,27 +36,28 @@ use Illuminate\Http\Request; use Illuminate\Foundation\Auth\ThrottlesLogins; use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; -class AuthController extends Controller +use Illuminate\Foundation\Auth\AuthenticatesUsers; + +class LoginController extends Controller { /* |-------------------------------------------------------------------------- - | Registration & Login Controller + | Login Controller |-------------------------------------------------------------------------- | - | This controller handles the registration of new users, as well as the - | authentication of existing users. By default, this controller uses - | a simple trait to add these behaviors. Why don't you explore it? + | This controller handles authenticating users for the application and + | redirecting them to your home screen. The controller uses a trait + | to conveniently provide its functionality to your applications. | */ - - use AuthenticatesAndRegistersUsers, ThrottlesLogins; + use AuthenticatesUsers; /** - * Post-Authentication redirect location. + * Where to redirect users after login / registration. * * @var string */ - protected $redirectPath = '/'; + protected $redirectTo = '/'; /** * Lockout time for failed login requests. @@ -73,42 +74,13 @@ class AuthController extends Controller protected $maxLoginAttempts = 3; /** - * Create a new authentication controller instance. + * Create a new controller instance. * * @return void */ public function __construct() { - // - } - - /** - * Get a validator for an incoming registration request. - * - * @param array $data - * @return \Illuminate\Contracts\Validation\Validator - */ - protected function validator(array $data) - { - return Validator::make($data, [ - 'email' => 'required|email|max:255|unique:users', - 'password' => 'required|confirmed|min:8', - ]); - } - - /** - * Create a new user instance after a valid registration. - * - * @param array $data - * @return User - */ - protected function create(array $data) - { - return User::create([ - 'name' => $data['name'], - 'email' => $data['email'], - 'password' => password_hash($data['password']), - ]); + $this->middleware('guest', ['except' => 'logout']); } /** @@ -117,7 +89,7 @@ class AuthController extends Controller * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ - public function postLogin(Request $request) + public function login(Request $request) { $this->validate($request, [ @@ -125,8 +97,8 @@ class AuthController extends Controller 'password' => 'required', ]); - $throttled = $this->isUsingThrottlesLoginsTrait(); - if ($throttled && $this->hasTooManyLoginAttempts($request)) { + if ($lockedOut = $this->hasTooManyLoginAttempts($request)) { + $this->fireLockoutEvent($request); return $this->sendLockoutResponse($request); } @@ -136,13 +108,11 @@ class AuthController extends Controller 'password' => $request->input('password') ], $request->has('remember'))) { - if ($throttled) { + if (!$lockedOut) { $this->incrementLoginAttempts($request); } - return redirect()->route('auth.login')->withInput($request->only('email', 'remember'))->withErrors([ - 'email' => $this->getFailedLoginMessage(), - ]); + return $this->sendFailedLoginResponse($request); } @@ -155,17 +125,17 @@ class AuthController extends Controller Auth::logout(); - if ($throttled) { + if (!$lockedOut) { $this->incrementLoginAttempts($request); } Alert::danger(trans('auth.totp_failed'))->flash(); - return redirect()->route('auth.login')->withInput($request->only('email', 'remember')); + return $this->sendFailedLoginResponse($request); } } - return $this->handleUserWasAuthenticated($request, $throttled); + return $this->sendLoginResponse($request); } diff --git a/app/Http/Controllers/Auth/PasswordController.php b/app/Http/Controllers/Auth/PasswordController.php deleted file mode 100644 index cd878445c..000000000 --- a/app/Http/Controllers/Auth/PasswordController.php +++ /dev/null @@ -1,56 +0,0 @@ - - * Some Modifications (c) 2015 Dylan Seidt - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Http\Controllers\Auth; - -use Pterodactyl\Http\Controllers\Controller; -use Illuminate\Foundation\Auth\ResetsPasswords; - -class PasswordController extends Controller -{ - /* - |-------------------------------------------------------------------------- - | Password Reset Controller - |-------------------------------------------------------------------------- - | - | This controller is responsible for handling password reset requests - | and uses a simple trait to include this behavior. You're free to - | explore this trait and override any methods you wish to tweak. - | - */ - - use ResetsPasswords; - - protected $redirectTo = '/'; - - /** - * Create a new password controller instance. - * - * @return void - */ - public function __construct() - { - $this->middleware('guest'); - } -} diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php new file mode 100644 index 000000000..e2663825a --- /dev/null +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -0,0 +1,71 @@ +middleware('guest'); + } + + /** + * Get a validator for an incoming registration request. + * + * @param array $data + * @return \Illuminate\Contracts\Validation\Validator + */ + protected function validator(array $data) + { + return Validator::make($data, [ + 'name' => 'required|max:255', + 'email' => 'required|email|max:255|unique:users', + 'password' => 'required|min:6|confirmed', + ]); + } + + /** + * Create a new user instance after a valid registration. + * + * @param array $data + * @return User + */ + protected function create(array $data) + { + return User::create([ + 'name' => $data['name'], + 'email' => $data['email'], + 'password' => bcrypt($data['password']), + ]); + } +} diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php new file mode 100644 index 000000000..135d3754d --- /dev/null +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -0,0 +1,32 @@ +middleware('guest'); + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 3ed333627..9e8d9f816 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -20,17 +20,40 @@ class Kernel extends HttpKernel \Pterodactyl\Http\Middleware\LanguageMiddleware::class, ]; + /** + * The application's route middleware groups. + * + * @var array + */ + protected $middlewareGroups = [ + 'web' => [ + \Pterodactyl\Http\Middleware\EncryptCookies::class, + \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\View\Middleware\ShareErrorsFromSession::class, + \Pterodactyl\Http\Middleware\VerifyCsrfToken::class, + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], + 'api' => [ + 'throttle:60,1', + 'bindings', + ], + ]; + /** * The application's route middleware. * * @var array */ protected $routeMiddleware = [ - 'auth' => \Pterodactyl\Http\Middleware\Authenticate::class, + 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'guest' => \Pterodactyl\Http\Middleware\RedirectIfAuthenticated::class, 'server' => \Pterodactyl\Http\Middleware\CheckServer::class, 'admin' => \Pterodactyl\Http\Middleware\AdminAuthenticate::class, 'csrf' => \Pterodactyl\Http\Middleware\VerifyCsrfToken::class, + 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + 'can' => \Illuminate\Auth\Middleware\Authorize::class, + 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, ]; } diff --git a/app/Http/Middleware/APISecretToken.php b/app/Http/Middleware/APISecretToken.php deleted file mode 100644 index 6db05a2ba..000000000 --- a/app/Http/Middleware/APISecretToken.php +++ /dev/null @@ -1,125 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Http\Middleware; - -use Crypt; -use IPTools\IP; -use IPTools\Range; - -use Pterodactyl\Models\APIKey; -use Pterodactyl\Models\APIPermission; - -use Illuminate\Http\Request; -use Dingo\Api\Routing\Route; -use Dingo\Api\Auth\Provider\Authorization; - -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; // 400 -use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; // 401 -use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; // 403 -use Symfony\Component\HttpKernel\Exception\HttpException; //500 - -class APISecretToken extends Authorization -{ - - protected $algo = 'sha256'; - - protected $permissionAllowed = false; - - protected $method = ''; - - protected $url = ''; - - public function __construct() - { - // - } - - public function getAuthorizationMethod() - { - return 'Authorization'; - } - - public function authenticate(Request $request, Route $route) - { - if (!$request->bearerToken() || empty($request->bearerToken())) { - throw new UnauthorizedHttpException('The authentication header was missing or malformed'); - } - - list($public, $hashed) = explode('.', $request->bearerToken()); - - $key = APIKey::where('public', $public)->first(); - if (!$key) { - throw new AccessDeniedHttpException('Invalid API Key.'); - } - - // Check for Resource Permissions - if (!empty($request->route()->getName())) { - if(!is_null($key->allowed_ips)) { - $inRange = false; - foreach(json_decode($key->allowed_ips) as $ip) { - if (Range::parse($ip)->contains(new IP($request->ip()))) { - $inRange = true; - break; - } - } - if (!$inRange) { - throw new AccessDeniedHttpException('This IP address <' . $request->ip() . '> does not have permission to use this API key.'); - } - } - - foreach(APIPermission::where('key_id', $key->id)->get() as &$row) { - if ($row->permission === '*' || $row->permission === $request->route()->getName()) { - $this->permissionAllowed = true; - continue; - } - } - - if (!$this->permissionAllowed) { - throw new AccessDeniedHttpException('You do not have permission to access this resource.'); - } - } - - try { - $decrypted = Crypt::decrypt($key->secret); - } catch (\Illuminate\Contracts\Encryption\DecryptException $ex) { - throw new HttpException('There was an error while attempting to check your secret key.'); - } - - $this->method = strtoupper($request->method()); - $this->url = urldecode($request->fullUrl()); - if($this->_generateHMAC($request->getContent(), $decrypted) !== base64_decode($hashed)) { - throw new BadRequestHttpException('The hashed body was not valid. Potential modification of contents in route.'); - } - - return true; - - } - - protected function _generateHMAC($body, $key) - { - $data = $this->method . $this->url . $body; - return hash_hmac($this->algo, $data, $key, true); - } - -} diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index 4c8f8c3b4..1735e49fe 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -3,38 +3,21 @@ namespace Pterodactyl\Http\Middleware; use Closure; -use Illuminate\Contracts\Auth\Guard; +use Illuminate\Support\Facades\Auth; class RedirectIfAuthenticated { - /** - * The Guard implementation. - * - * @var Guard - */ - protected $auth; - - /** - * Create a new filter instance. - * - * @param Guard $auth - * @return void - */ - public function __construct(Guard $auth) - { - $this->auth = $auth; - } - /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next + * @param string|null $guard * @return mixed */ - public function handle($request, Closure $next) + public function handle($request, Closure $next, $guard = null) { - if ($this->auth->check()) { + if (Auth::guard($guard)->check()) { return redirect('/'); } diff --git a/app/Http/Routes/APIRoutes.php b/app/Http/Routes/APIRoutes.php deleted file mode 100644 index 644517b79..000000000 --- a/app/Http/Routes/APIRoutes.php +++ /dev/null @@ -1,150 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Http\Routes; - -use Pterodactyl\Models; -use Illuminate\Routing\Router; - -class APIRoutes -{ - - public function map(Router $router) { - - $api = app('Dingo\Api\Routing\Router'); - $api->version('v1', ['middleware' => 'api.auth'], function ($api) { - - /** - * User Routes - */ - $api->get('users', [ - 'as' => 'api.users', - 'uses' => 'Pterodactyl\Http\Controllers\API\UserController@getUsers' - ]); - - $api->post('users', [ - 'as' => 'api.users.post', - 'uses' => 'Pterodactyl\Http\Controllers\API\UserController@postUser' - ]); - - $api->get('users/{id}', [ - 'as' => 'api.users.view', - 'uses' => 'Pterodactyl\Http\Controllers\API\UserController@getUser' - ]); - - $api->patch('users/{id}', [ - 'as' => 'api.users.patch', - 'uses' => 'Pterodactyl\Http\Controllers\API\UserController@patchUser' - ]); - - $api->delete('users/{id}', [ - 'as' => 'api.users.delete', - 'uses' => 'Pterodactyl\Http\Controllers\API\UserController@deleteUser' - ]); - - /** - * Server Routes - */ - $api->get('servers', [ - 'as' => 'api.servers', - 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@getServers' - ]); - - $api->post('servers', [ - 'as' => 'api.servers.post', - 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@postServer' - ]); - - $api->get('servers/{id}', [ - 'as' => 'api.servers.view', - 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@getServer' - ]); - - $api->post('servers/{id}/suspend', [ - 'as' => 'api.servers.suspend', - 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@postServerSuspend' - ]); - - $api->post('servers/{id}/unsuspend', [ - 'as' => 'api.servers.unsuspend', - 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@postServerUnsuspend' - ]); - - $api->delete('servers/{id}/{force?}', [ - 'as' => 'api.servers.delete', - 'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@deleteServer' - ]); - - /** - * Node Routes - */ - $api->get('nodes', [ - 'as' => 'api.nodes', - 'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@getNodes' - ]); - - $api->post('nodes', [ - 'as' => 'api.nodes.post', - 'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@postNode' - ]); - - $api->get('nodes/{id}', [ - 'as' => 'api.nodes.view', - 'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@getNode' - ]); - - $api->get('nodes/{id}/allocations', [ - 'as' => 'api.nodes.view_allocations', - 'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@getNodeAllocations' - ]); - - $api->delete('nodes/{id}', [ - 'as' => 'api.nodes.delete', - 'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@deleteNode' - ]); - - /** - * Location Routes - */ - $api->get('locations', [ - 'as' => 'api.locations', - 'uses' => 'Pterodactyl\Http\Controllers\API\LocationController@getLocations' - ]); - - /** - * Service Routes - */ - $api->get('services', [ - 'as' => 'api.services', - 'uses' => 'Pterodactyl\Http\Controllers\API\ServiceController@getServices' - ]); - - $api->get('services/{id}', [ - 'as' => 'api.services.view', - 'uses' => 'Pterodactyl\Http\Controllers\API\ServiceController@getService' - ]); - - }); - } - -} diff --git a/app/Http/Routes/AuthRoutes.php b/app/Http/Routes/AuthRoutes.php index 1f7052106..a447f3c5e 100644 --- a/app/Http/Routes/AuthRoutes.php +++ b/app/Http/Routes/AuthRoutes.php @@ -28,6 +28,7 @@ use Illuminate\Routing\Router; use Request; use Pterodactyl\Models\User as User; +use Auth; class AuthRoutes { public function map(Router $router) { @@ -42,39 +43,39 @@ class AuthRoutes { // Display Login Page $router->get('login', [ 'as' => 'auth.login', - 'uses' => 'Auth\AuthController@getLogin' + 'uses' => 'Auth\LoginController@showLoginForm' ]); // Handle Login $router->post('login', [ - 'uses' => 'Auth\AuthController@postLogin' + 'uses' => 'Auth\LoginController@login' ]); // Determine if we need to ask for a TOTP Token $router->post('login/totp', [ - 'uses' => 'Auth\AuthController@checkTotp' + 'uses' => 'Auth\LoginController@checkTotp' ]); // Show Password Reset Form $router->get('password', [ 'as' => 'auth.password', - 'uses' => 'Auth\PasswordController@getEmail' + 'uses' => 'Auth\ForgotPasswordController@showLinkRequestForm' ]); // Handle Password Reset $router->post('password', [ - 'uses' => 'Auth\PasswordController@postEmail' + 'uses' => 'Auth\ForgotPasswordController@sendResetLinkEmail' ]); // Show Verification Checkpoint $router->get('password/reset/{token}', [ 'as' => 'auth.reset', - 'uses' => 'Auth\PasswordController@getReset' + 'uses' => 'Auth\ResetPasswordController@showResetForm' ]); // Handle Verification $router->post('password/reset', [ - 'uses' => 'Auth\PasswordController@postReset' + 'uses' => 'Auth\ResetPasswordController@reset' ]); }); @@ -83,7 +84,7 @@ class AuthRoutes { $router->get('auth/logout', [ 'as' => 'auth.logout', 'middleware' => 'auth', - 'uses' => 'Auth\AuthController@getLogout' + 'uses' => 'Auth\LoginController@logout' ]); } diff --git a/app/Models/User.php b/app/Models/User.php index 2a1f635e2..ca1031ffd 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -28,8 +28,10 @@ use Google2FA; use Pterodactyl\Exceptions\AccountNotFoundException; use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Models\Permission; +use Pterodactyl\Notifications\SendPasswordReset as ResetPasswordNotification; use Illuminate\Auth\Authenticatable; +use Illuminate\Notifications\Notifiable; use Illuminate\Database\Eloquent\Model; use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Foundation\Auth\Access\Authorizable; @@ -41,7 +43,7 @@ class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract { - use Authenticatable, Authorizable, CanResetPassword; + use Authenticatable, Authorizable, CanResetPassword, Notifiable; /** * The table associated with the model. @@ -124,4 +126,16 @@ class User extends Model implements AuthenticatableContract, } + /** + * Send the password reset notification. + * + * @param string $token + * @return void + */ + public function sendPasswordResetNotification($token) + { + $this->notify(new ResetPasswordNotification($token)); + } + + } diff --git a/app/Notifications/SendPasswordReset.php b/app/Notifications/SendPasswordReset.php new file mode 100644 index 000000000..7aa95dde0 --- /dev/null +++ b/app/Notifications/SendPasswordReset.php @@ -0,0 +1,69 @@ +token = $token; + } + + /** + * Get the notification's delivery channels. + * + * @param mixed $notifiable + * @return array + */ + public function via($notifiable) + { + return ['mail']; + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return \Illuminate\Notifications\Messages\MailMessage + */ + public function toMail($notifiable) + { + return (new MailMessage) + ->subject('Reset Password') + ->line('You are receiving this email because we received a password reset request for your account.') + ->action('Reset Password', url('auth/password/reset', $this->token)) + ->line('If you did not request a password reset, no further action is required.'); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * @return array + */ + public function toArray($notifiable) + { + return [ + // + ]; + } +} diff --git a/app/Providers/BroadcastServiceProvider.php b/app/Providers/BroadcastServiceProvider.php new file mode 100644 index 000000000..1dcf8d287 --- /dev/null +++ b/app/Providers/BroadcastServiceProvider.php @@ -0,0 +1,26 @@ +id === (int) $userId; + }); + } +} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index df5adab95..d706f31ce 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -2,7 +2,7 @@ namespace Pterodactyl\Providers; -use Illuminate\Contracts\Events\Dispatcher as DispatcherContract; +use Illuminate\Support\Facades\Event; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider @@ -21,12 +21,11 @@ class EventServiceProvider extends ServiceProvider /** * Register any other events for your application. * - * @param \Illuminate\Contracts\Events\Dispatcher $events * @return void */ - public function boot(DispatcherContract $events) + public function boot() { - parent::boot($events); + parent::boot(); // } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index d223d442d..9a3305c2b 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -2,7 +2,7 @@ namespace Pterodactyl\Providers; -use Illuminate\Routing\Router; +use Illuminate\Support\Facades\Route; use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; class RouteServiceProvider extends ServiceProvider @@ -22,25 +22,58 @@ class RouteServiceProvider extends ServiceProvider * @param \Illuminate\Routing\Router $router * @return void */ - public function boot(Router $router) + public function boot() { // - parent::boot($router); + parent::boot(); } /** * Define the routes for the application. * - * @param \Illuminate\Routing\Router $router * @return void */ - public function map(Router $router) + public function map() { - $router->group(['namespace' => $this->namespace], function ($router) { + $this->mapWebRoutes(); + $this->mapApiRoutes(); + } + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + * + * @return void + */ + protected function mapWebRoutes() + { + Route::group([ + // 'middleware' => 'web', + 'namespace' => $this->namespace, + ], function ($router) { foreach (glob(app_path('Http//Routes') . '/*.php') as $file) { $this->app->make('Pterodactyl\\Http\\Routes\\' . basename($file, '.php'))->map($router); } }); } + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + * + * @return void + */ + protected function mapApiRoutes() + { + Route::group([ + 'middleware' => 'api', + 'namespace' => $this->namespace, + 'prefix' => 'api', + ], function ($router) { + foreach (glob(app_path('Http//Routes//Api') . '/*.php') as $file) { + $this->app->make('Pterodactyl\\Http\\Routes\\Api\\' . basename($file, '.php'))->map($router); + } + }); + } } diff --git a/app/Transformers/NodeTransformer.php b/app/Transformers/NodeTransformer.php deleted file mode 100644 index 9b3224c37..000000000 --- a/app/Transformers/NodeTransformer.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Transformers; - -use Pterodactyl\Models\Node; -use League\Fractal\TransformerAbstract; - -class NodeTransformer extends TransformerAbstract -{ - - /** - * Turn this item object into a generic array - * - * @return array - */ - public function transform(Node $node) - { - return $node; - } - -} diff --git a/app/Transformers/ServerTransformer.php b/app/Transformers/ServerTransformer.php deleted file mode 100644 index 482cf8419..000000000 --- a/app/Transformers/ServerTransformer.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Transformers; - -use Pterodactyl\Models\Server; -use League\Fractal\TransformerAbstract; - -class ServerTransformer extends TransformerAbstract -{ - - /** - * Turn this item object into a generic array - * - * @return array - */ - public function transform(Server $server) - { - return $server; - } - -} diff --git a/app/Transformers/UserTransformer.php b/app/Transformers/UserTransformer.php deleted file mode 100644 index abd90c34d..000000000 --- a/app/Transformers/UserTransformer.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -namespace Pterodactyl\Transformers; - -use Pterodactyl\Models\User; -use League\Fractal\TransformerAbstract; - -class UserTransformer extends TransformerAbstract -{ - - /** - * Turn this item object into a generic array - * - * @return array - */ - public function transform(User $user) - { - return $user; - } - -} diff --git a/composer.json b/composer.json index 38b86c5c4..5ef2a0d29 100644 --- a/composer.json +++ b/composer.json @@ -16,30 +16,26 @@ } ], "require": { - "php": ">=5.5.9", - "laravel/framework": "5.2.*", - "barryvdh/laravel-debugbar": "^2.0", - "dingo/api": "1.0.x-dev", - "dingo/blueprint": "0.2.x-dev", - "doctrine/dbal": "^2.5", - "guzzlehttp/guzzle": "^6.1", - "pragmarx/google2fa": "^0.7.1", + "php": ">=5.6.4", + "laravel/framework": "5.3.*", + "barryvdh/laravel-debugbar": "^2.2.3", + "doctrine/dbal": "^2.5.4", + "guzzlehttp/guzzle": "^6.2.1", + "pragmarx/google2fa": "^1.0.1", "webpatser/laravel-uuid": "^2.0", "prologue/alerts": "^0.4.0", - "s1lentium/iptools": "^1.0", + "s1lentium/iptools": "^1.1.0", "edvinaskrucas/settings": "^2.0", - "igaster/laravel-theme": "^1.1", + "igaster/laravel-theme": "^1.1.3", "nesbot/carbon": "^1.21", "mtdowling/cron-expression": "^1.1" }, "require-dev": { "fzaninotto/faker": "~1.4", "mockery/mockery": "0.9.*", - "phpunit/phpunit": "~4.0", - "phpspec/phpspec": "~2.1", - "symfony/css-selector": "~3.0", - "symfony/dom-crawler": "~3.0", - "laravel/homestead": "^3.0" + "phpunit/phpunit": "~5.0", + "symfony/css-selector": "3.1.*", + "symfony/dom-crawler": "3.1.*" }, "autoload": { "classmap": [ @@ -56,19 +52,17 @@ }, "scripts": { "post-root-package-install": [ - "php -r \"copy('.env.example', '.env');\"" + "php -r \"file_exists('.env') || copy('.env.example', '.env');\"" ], "post-create-project-cmd": [ "php artisan key:generate" ], "post-install-cmd": [ - "php artisan clear-compiled", + "Illuminate\\Foundation\\ComposerScripts::postInstall", "php artisan optimize" ], - "pre-update-cmd": [ - "php artisan clear-compiled" - ], "post-update-cmd": [ + "Illuminate\\Foundation\\ComposerScripts::postUpdate", "php artisan optimize" ], "setup-dev": [ @@ -84,7 +78,7 @@ ], "setup": [ "composer install --ansi --no-dev", - "php -r \"copy('.env.example', '.env');\"", + "php -r \"file_exists('.env') || copy('.env.example', '.env');\"", "php artisan key:generate", "php artisan pterodactyl:env", "php artisan migrate", diff --git a/config/api.php b/config/api.php deleted file mode 100644 index 234a8bca7..000000000 --- a/config/api.php +++ /dev/null @@ -1,209 +0,0 @@ - env('API_STANDARDS_TREE', 'x'), - - /* - |-------------------------------------------------------------------------- - | API Subtype - |-------------------------------------------------------------------------- - | - | Your subtype will follow the standards tree you use when used in the - | "Accept" header to negotiate the content type and version. - | - | For example: Accept: application/x.SUBTYPE.v1+json - | - */ - - 'subtype' => env('API_SUBTYPE', 'pterodactyl'), - - /* - |-------------------------------------------------------------------------- - | Default API Version - |-------------------------------------------------------------------------- - | - | This is the default version when strict mode is disabled and your API - | is accessed via a web browser. It's also used as the default version - | when generating your APIs documentation. - | - */ - - 'version' => env('API_VERSION', 'v1'), - - /* - |-------------------------------------------------------------------------- - | Default API Prefix - |-------------------------------------------------------------------------- - | - | A default prefix to use for your API routes so you don't have to - | specify it for each group. - | - */ - - 'prefix' => env('API_PREFIX', null), - - /* - |-------------------------------------------------------------------------- - | Default API Domain - |-------------------------------------------------------------------------- - | - | A default domain to use for your API routes so you don't have to - | specify it for each group. - | - */ - - 'domain' => env('API_DOMAIN', null), - - /* - |-------------------------------------------------------------------------- - | Name - |-------------------------------------------------------------------------- - | - | When documenting your API using the API Blueprint syntax you can - | configure a default name to avoid having to manually specify - | one when using the command. - | - */ - - 'name' => env('API_NAME', 'Pterodactyl Panel API'), - - /* - |-------------------------------------------------------------------------- - | Conditional Requests - |-------------------------------------------------------------------------- - | - | Globally enable conditional requests so that an ETag header is added to - | any successful response. Subsequent requests will perform a check and - | will return a 304 Not Modified. This can also be enabled or disabled - | on certain groups or routes. - | - */ - - 'conditionalRequest' => env('API_CONDITIONAL_REQUEST', true), - - /* - |-------------------------------------------------------------------------- - | Strict Mode - |-------------------------------------------------------------------------- - | - | Enabling strict mode will require clients to send a valid Accept header - | with every request. This also voids the default API version, meaning - | your API will not be browsable via a web browser. - | - */ - - 'strict' => env('API_STRICT', false), - - /* - |-------------------------------------------------------------------------- - | Debug Mode - |-------------------------------------------------------------------------- - | - | Enabling debug mode will result in error responses caused by thrown - | exceptions to have a "debug" key that will be populated with - | more detailed information on the exception. - | - */ - - 'debug' => env('API_DEBUG', false), - - /* - |-------------------------------------------------------------------------- - | Generic Error Format - |-------------------------------------------------------------------------- - | - | When some HTTP exceptions are not caught and dealt with the API will - | generate a generic error response in the format provided. Any - | keys that aren't replaced with corresponding values will be - | removed from the final response. - | - */ - - 'errorFormat' => [ - 'message' => ':message', - 'errors' => ':errors', - 'code' => ':code', - 'status_code' => ':status_code', - 'debug' => ':debug', - ], - - /* - |-------------------------------------------------------------------------- - | Authentication Providers - |-------------------------------------------------------------------------- - | - | The authentication providers that should be used when attempting to - | authenticate an incoming API request. - | - */ - - 'auth' => [ - 'custom' => 'Pterodactyl\Http\Middleware\APISecretToken' - ], - - /* - |-------------------------------------------------------------------------- - | Throttling / Rate Limiting - |-------------------------------------------------------------------------- - | - | Consumers of your API can be limited to the amount of requests they can - | make. You can create your own throttles or simply change the default - | throttles. - | - */ - - 'throttling' => [ - - ], - - /* - |-------------------------------------------------------------------------- - | Response Transformer - |-------------------------------------------------------------------------- - | - | Responses can be transformed so that they are easier to format. By - | default a Fractal transformer will be used to transform any - | responses prior to formatting. You can easily replace - | this with your own transformer. - | - */ - - 'transformer' => env('API_TRANSFORMER', Dingo\Api\Transformer\Adapter\Fractal::class), - - /* - |-------------------------------------------------------------------------- - | Response Formats - |-------------------------------------------------------------------------- - | - | Responses can be returned in multiple formats by registering different - | response formatters. You can also customize an existing response - | formatter. - | - */ - - 'defaultFormat' => env('API_DEFAULT_FORMAT', 'json'), - - 'formats' => [ - - 'json' => Dingo\Api\Http\Response\Format\Json::class, - - ], - -]; diff --git a/config/app.php b/config/app.php index 7d92f1697..892ca9090 100644 --- a/config/app.php +++ b/config/app.php @@ -114,8 +114,6 @@ return [ 'providers' => [ - Dingo\Api\Provider\LaravelServiceProvider::class, - /* * Laravel Framework Service Providers... */ @@ -140,6 +138,7 @@ return [ Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, + Illuminate\Notifications\NotificationServiceProvider::class, /* * Application Service Providers... @@ -187,8 +186,6 @@ return [ 'Crypt' => Illuminate\Support\Facades\Crypt::class, 'DB' => Illuminate\Support\Facades\DB::class, 'Debugbar' => Barryvdh\Debugbar\Facade::class, - 'DingoAPI' => Dingo\Api\Facade\API::class, - 'DingoRoute' => Dingo\Api\Facade\Route::class, 'Eloquent' => Illuminate\Database\Eloquent\Model::class, 'Event' => Illuminate\Support\Facades\Event::class, 'File' => Illuminate\Support\Facades\File::class, @@ -200,6 +197,7 @@ return [ 'Lang' => Illuminate\Support\Facades\Lang::class, 'Log' => Illuminate\Support\Facades\Log::class, 'Mail' => Illuminate\Support\Facades\Mail::class, + 'Notification' => Illuminate\Support\Facades\Notification::class, 'Password' => Illuminate\Support\Facades\Password::class, 'Queue' => Illuminate\Support\Facades\Queue::class, 'Redirect' => Illuminate\Support\Facades\Redirect::class, diff --git a/resources/views/auth/password.blade.php b/resources/views/auth/passwords/email.blade.php similarity index 86% rename from resources/views/auth/password.blade.php rename to resources/views/auth/passwords/email.blade.php index e41b8aea8..064373a53 100644 --- a/resources/views/auth/password.blade.php +++ b/resources/views/auth/passwords/email.blade.php @@ -31,7 +31,7 @@ @section('content')
-
+ {{ trans('auth.resetpassword') }}
@if (session('status')) @@ -39,10 +39,15 @@ {{ trans('strings.success') }}! {{ trans('auth.emailsent') }}
@endif -
+
+ @if ($errors->has('email')) + + {{ $errors->first('email') }} + + @endif
diff --git a/resources/views/auth/reset.blade.php b/resources/views/auth/passwords/reset.blade.php similarity index 71% rename from resources/views/auth/reset.blade.php rename to resources/views/auth/passwords/reset.blade.php index 24edfa886..3362f205b 100644 --- a/resources/views/auth/reset.blade.php +++ b/resources/views/auth/passwords/reset.blade.php @@ -31,26 +31,41 @@ @section('content')
- + {{ trans('auth.resetpassword') }}
- + + @if ($errors->has('email')) + + {{ $errors->first('email') }} + + @endif
- + + @if ($errors->has('password')) + + {{ $errors->first('password') }} + + @endif
- + + @if ($errors->has('password_confirmation')) + + {{ $errors->first('password_confirmation') }} + + @endif
diff --git a/resources/views/emails/password.blade.php b/resources/views/emails/password.blade.php deleted file mode 100644 index 5019e5c81..000000000 --- a/resources/views/emails/password.blade.php +++ /dev/null @@ -1,32 +0,0 @@ -{{-- Copyright (c) 2015 - 2016 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} - - - Pterodactyl Lost Password Recovery - - -

Pterodactyl Lost Password Recovery

-

Hello there! You are receiving this email because you requested a new password for your Pterodactyl account.

-

Please click the link below to confirm that you wish to change your password. If you did not make this request, or do not wish to continue simply ignore this email and nothing will happen. This link will expire in 1 hour.

-

{{ url('auth/password/reset/'.$token) }}

-

Please do not hesitate to contact us if you belive something is wrong. -

Thanks!
Pterodactyl

- - diff --git a/resources/views/vendor/notifications/email-plain.blade.php b/resources/views/vendor/notifications/email-plain.blade.php new file mode 100644 index 000000000..acefa6523 --- /dev/null +++ b/resources/views/vendor/notifications/email-plain.blade.php @@ -0,0 +1,22 @@ + + + + + + + + + + + 'margin: 0; padding: 0; width: 100%; background-color: #F2F4F6;', + 'email-wrapper' => 'width: 100%; margin: 0; padding: 0; background-color: #F2F4F6;', + + /* Masthead ----------------------- */ + + 'email-masthead' => 'padding: 25px 0; text-align: center;', + 'email-masthead_name' => 'font-size: 16px; font-weight: bold; color: #2F3133; text-decoration: none; text-shadow: 0 1px 0 white;', + + 'email-body' => 'width: 100%; margin: 0; padding: 0; border-top: 1px solid #EDEFF2; border-bottom: 1px solid #EDEFF2; background-color: #FFF;', + 'email-body_inner' => 'width: auto; max-width: 570px; margin: 0 auto; padding: 0;', + 'email-body_cell' => 'padding: 35px;', + + 'email-footer' => 'width: auto; max-width: 570px; margin: 0 auto; padding: 0; text-align: center;', + 'email-footer_cell' => 'color: #AEAEAE; padding: 35px; text-align: center;', + + /* Body ------------------------------ */ + + 'body_action' => 'width: 100%; margin: 30px auto; padding: 0; text-align: center;', + 'body_sub' => 'margin-top: 25px; padding-top: 25px; border-top: 1px solid #EDEFF2;', + + /* Type ------------------------------ */ + + 'anchor' => 'color: #3869D4;', + 'header-1' => 'margin-top: 0; color: #2F3133; font-size: 19px; font-weight: bold; text-align: left;', + 'paragraph' => 'margin-top: 0; color: #74787E; font-size: 16px; line-height: 1.5em;', + 'paragraph-sub' => 'margin-top: 0; color: #74787E; font-size: 12px; line-height: 1.5em;', + 'paragraph-center' => 'text-align: center;', + + /* Buttons ------------------------------ */ + + 'button' => 'display: block; display: inline-block; width: 200px; min-height: 20px; padding: 10px; + background-color: #3869D4; border-radius: 3px; color: #ffffff; font-size: 15px; line-height: 25px; + text-align: center; text-decoration: none; -webkit-text-size-adjust: none;', + + 'button--green' => 'background-color: #22BC66;', + 'button--red' => 'background-color: #dc4d2f;', + 'button--blue' => 'background-color: #3869D4;', +]; +?> + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ + {{ config('app.name') }} + +
+ + + + +
+ +

+ @if (! empty($greeting)) + {{ $greeting }} + @else + @if ($level == 'error') + Whoops! + @else + Hello! + @endif + @endif +

+ + + @foreach ($introLines as $line) +

+ {{ $line }} +

+ @endforeach + + + @if (isset($actionText)) + + + + +
+ + + + {{ $actionText }} + +
+ @endif + + + @foreach ($outroLines as $line) +

+ {{ $line }} +

+ @endforeach + + +

+ Regards,
{{ config('app.name') }} +

+ + + @if (isset($actionText)) + + + + +
+

+ If you’re having trouble clicking the "{{ $actionText }}" button, + copy and paste the URL below into your web browser: +

+ +

+ + {{ $actionUrl }} + +

+
+ @endif +
+
+ + + + +
+

+ © {{ date('Y') }} + {{ config('app.name') }}. + All rights reserved. +

+
+
+
+ + diff --git a/resources/views/vendor/pagination/bootstrap-4.blade.php b/resources/views/vendor/pagination/bootstrap-4.blade.php new file mode 100644 index 000000000..9d80428cc --- /dev/null +++ b/resources/views/vendor/pagination/bootstrap-4.blade.php @@ -0,0 +1,36 @@ +@if ($paginator->count() > 1) +
    + + @if ($paginator->onFirstPage()) +
  • «
  • + @else +
  • + @endif + + + @foreach ($elements as $element) + + @if (is_string($element)) +
  • {{ $element }}
  • + @endif + + + @if (is_array($element)) + @foreach ($element as $page => $url) + @if ($page == $paginator->currentPage()) +
  • {{ $page }}
  • + @else +
  • {{ $page }}
  • + @endif + @endforeach + @endif + @endforeach + + + @if ($paginator->hasMorePages()) +
  • + @else +
  • »
  • + @endif +
+@endif diff --git a/resources/views/vendor/pagination/default.blade.php b/resources/views/vendor/pagination/default.blade.php new file mode 100644 index 000000000..668fc1330 --- /dev/null +++ b/resources/views/vendor/pagination/default.blade.php @@ -0,0 +1,36 @@ +@if ($paginator->count() > 1) +
    + + @if ($paginator->onFirstPage()) +
  • «
  • + @else +
  • + @endif + + + @foreach ($elements as $element) + + @if (is_string($element)) +
  • {{ $element }}
  • + @endif + + + @if (is_array($element)) + @foreach ($element as $page => $url) + @if ($page == $paginator->currentPage()) +
  • {{ $page }}
  • + @else +
  • {{ $page }}
  • + @endif + @endforeach + @endif + @endforeach + + + @if ($paginator->hasMorePages()) +
  • + @else +
  • »
  • + @endif +
+@endif diff --git a/resources/views/vendor/pagination/simple-bootstrap-4.blade.php b/resources/views/vendor/pagination/simple-bootstrap-4.blade.php new file mode 100644 index 000000000..4b14efeb5 --- /dev/null +++ b/resources/views/vendor/pagination/simple-bootstrap-4.blade.php @@ -0,0 +1,17 @@ +@if ($paginator->count() > 1) +
    + + @if ($paginator->onFirstPage()) +
  • «
  • + @else +
  • + @endif + + + @if ($paginator->hasMorePages()) +
  • + @else +
  • »
  • + @endif +
+@endif diff --git a/resources/views/vendor/pagination/simple-default.blade.php b/resources/views/vendor/pagination/simple-default.blade.php new file mode 100644 index 000000000..a45097ee2 --- /dev/null +++ b/resources/views/vendor/pagination/simple-default.blade.php @@ -0,0 +1,17 @@ +@if ($paginator->count() > 1) +
    + + @if ($paginator->onFirstPage()) +
  • «
  • + @else +
  • + @endif + + + @if ($paginator->hasMorePages()) +
  • + @else +
  • »
  • + @endif +
+@endif