diff --git a/app/Foundation/Exceptions/Displayers/SettingsDisplayer.php b/app/Foundation/Exceptions/Displayers/SettingsDisplayer.php new file mode 100644 index 000000000000..79c5b738ab40 --- /dev/null +++ b/app/Foundation/Exceptions/Displayers/SettingsDisplayer.php @@ -0,0 +1,88 @@ +request = $request; + } + + /** + * Get the error response associated with the given exception. + * + * @param \Exception $exception + * @param string $id + * @param int $code + * @param string[] $headers + * + * @return \Symfony\Component\HttpFoundation\Response + */ + public function display(Exception $exception, string $id, int $code, array $headers) + { + return cachet_redirect('setup'); + } + + /** + * Get the supported content type. + * + * @return string + */ + public function contentType() + { + return 'text/html'; + } + + /** + * Can we display the exception? + * + * @param \Exception $original + * @param \Exception $transformed + * @param int $code + * + * @return bool + */ + public function canDisplay(Exception $original, Exception $transformed, int $code) + { + return ($transformed instanceof ReadException) && !$this->request->is('setup*'); + } + + /** + * Do we provide verbose information about the exception? + * + * @return bool + */ + public function isVerbose() + { + return false; + } +} diff --git a/app/Http/Middleware/ReadyForUse.php b/app/Http/Middleware/ReadyForUse.php index 3acfe8d2ec36..1ae77e0c94bc 100644 --- a/app/Http/Middleware/ReadyForUse.php +++ b/app/Http/Middleware/ReadyForUse.php @@ -53,7 +53,7 @@ public function __construct(Repository $settings) */ public function handle(Request $request, Closure $next) { - if (!$this->settings->get('app_name')) { + if (!$request->is('setup*') && !$this->settings->get('app_name')) { return cachet_redirect('setup'); } diff --git a/app/Http/Middleware/SetupAlreadyCompleted.php b/app/Http/Middleware/SetupAlreadyCompleted.php index 83de0ad206a3..0a7be7156be5 100644 --- a/app/Http/Middleware/SetupAlreadyCompleted.php +++ b/app/Http/Middleware/SetupAlreadyCompleted.php @@ -11,6 +11,7 @@ namespace CachetHQ\Cachet\Http\Middleware; +use CachetHQ\Cachet\Settings\ReadException; use CachetHQ\Cachet\Settings\Repository; use Closure; use Illuminate\Http\Request; @@ -53,8 +54,12 @@ public function __construct(Repository $settings) */ public function handle(Request $request, Closure $next) { - if ($this->settings->get('app_name')) { - return cachet_redirect('dashboard'); + try { + if ($this->settings->get('app_name')) { + return cachet_redirect('dashboard'); + } + } catch (ReadException $e) { + // not setup then! } return $next($request); diff --git a/app/Settings/ReadException.php b/app/Settings/ReadException.php new file mode 100644 index 000000000000..86de0ae3f9e1 --- /dev/null +++ b/app/Settings/ReadException.php @@ -0,0 +1,34 @@ + + */ +class ReadException extends SettingsException +{ + /** + * Create a new read exception instance. + * + * @param \Exception $e + * + * @return void + */ + public function __construct(Exception $e) + { + parent::__construct('Unable to read Cachet settings', $e); + } +} diff --git a/app/Settings/Repository.php b/app/Settings/Repository.php index 35cf79e914b3..e6d54038ee3f 100644 --- a/app/Settings/Repository.php +++ b/app/Settings/Repository.php @@ -12,6 +12,7 @@ namespace CachetHQ\Cachet\Settings; use CachetHQ\Cachet\Models\Setting; +use Exception; /** * This is the settings repository class. @@ -59,13 +60,19 @@ public function __construct(Setting $model) /** * Returns a setting from the database. * + * @throws \CachetHQ\Cachet\Settings\ReadException + * * @return array */ public function all() { - return $this->model->all(['name', 'value'])->pluck('value', 'name')->map(function ($value, $name) { - return $this->castSetting($name, $value); - })->toArray(); + try { + return $this->model->all(['name', 'value'])->pluck('value', 'name')->map(function ($value, $name) { + return $this->castSetting($name, $value); + })->toArray(); + } catch (Exception $e) { + throw new ReadException($e); + } } /** @@ -74,16 +81,22 @@ public function all() * @param string $name * @param string|null $value * + * @throws \CachetHQ\Cachet\Settings\WriteException + * * @return void */ public function set($name, $value) { $this->stale = true; - if ($value === null) { - $this->model->where('name', '=', $name)->delete(); - } else { - $this->model->updateOrCreate(compact('name'), compact('value')); + try { + if ($value === null) { + $this->model->where('name', '=', $name)->delete(); + } else { + $this->model->updateOrCreate(compact('name'), compact('value')); + } + } catch (Exception $e) { + throw new WriteException($e); } } @@ -93,15 +106,21 @@ public function set($name, $value) * @param string $name * @param mixed $default * + * @throws \CachetHQ\Cachet\Settings\ReadException + * * @return mixed */ public function get($name, $default = null) { - if ($setting = $this->model->where('name', '=', $name)->first()) { - return $this->castSetting($name, $setting->value); + try { + if ($setting = $this->model->where('name', '=', $name)->first()) { + return $this->castSetting($name, $setting->value); + } + + return $default; + } catch (Exception $e) { + throw new ReadException($e); } - - return $default; } /** @@ -109,25 +128,37 @@ public function get($name, $default = null) * * @param string $name * + * @throws \CachetHQ\Cachet\Settings\WriteException + * * @return void */ public function delete($name) { $this->stale = true; - $this->model->where('name', '=', $name)->delete(); + try { + $this->model->where('name', '=', $name)->delete(); + } catch (Exception $e) { + throw new WriteException($e); + } } /** * Clear all settings. * + * @throws \CachetHQ\Cachet\Settings\WriteException + * * @return void */ public function clear() { $this->stale = true; - $this->model->query()->delete(); + try { + $this->model->query()->delete(); + } catch (Exception $e) { + throw new WriteException($e); + } } /** diff --git a/app/Settings/SettingsException.php b/app/Settings/SettingsException.php new file mode 100644 index 000000000000..1716ea366d9d --- /dev/null +++ b/app/Settings/SettingsException.php @@ -0,0 +1,35 @@ + + */ +class SettingsException extends Exception +{ + /** + * Create a new write exception instance. + * + * @param string $m + * @param \Exception $e + * + * @return void + */ + public function __construct(string $m, Exception $e) + { + parent::__construct($m, 0, $e); + } +} diff --git a/app/Settings/WriteException.php b/app/Settings/WriteException.php new file mode 100644 index 000000000000..baa41ff7ac1d --- /dev/null +++ b/app/Settings/WriteException.php @@ -0,0 +1,34 @@ + + */ +class WriteException extends SettingsException +{ + /** + * Create a new write exception instance. + * + * @param \Exception $e + * + * @return void + */ + public function __construct(Exception $e) + { + parent::__construct('Unable to write Cachet settings', $e); + } +} diff --git a/composer.json b/composer.json index 1617ff7bc13f..5c50c2d26063 100644 --- a/composer.json +++ b/composer.json @@ -48,7 +48,7 @@ "graham-campbell/markdown": "^10.2", "guzzlehttp/guzzle": "^6.3.3", "jenssegers/date": "^3.4", - "laravel/framework": "5.6.*", + "laravel/framework": "5.7.*", "laravel/tinker": "^1.0", "laravolt/avatar": "^2.1", "mccool/laravel-auto-presenter": "^7.1", diff --git a/composer.lock b/composer.lock index 3f17ab62ec47..36d963024218 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": "308d1d432d962c06cdd2ae7df5544ca9", + "content-hash": "72d1c09394a4734e13155112d3c5c547", "packages": [ { "name": "alt-three/badger", @@ -2034,42 +2034,45 @@ }, { "name": "laravel/framework", - "version": "v5.6.39", + "version": "v5.7.19", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "37bb306f516669ab4f888c16003f694313ab299e" + "reference": "5c1d1ec7e8563ea31826fd5eb3f6791acf01160c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/37bb306f516669ab4f888c16003f694313ab299e", - "reference": "37bb306f516669ab4f888c16003f694313ab299e", + "url": "https://api.github.com/repos/laravel/framework/zipball/5c1d1ec7e8563ea31826fd5eb3f6791acf01160c", + "reference": "5c1d1ec7e8563ea31826fd5eb3f6791acf01160c", "shasum": "" }, "require": { - "doctrine/inflector": "~1.1", - "dragonmantank/cron-expression": "~2.0", - "erusev/parsedown": "~1.7", + "doctrine/inflector": "^1.1", + "dragonmantank/cron-expression": "^2.0", + "erusev/parsedown": "^1.7", "ext-mbstring": "*", "ext-openssl": "*", + "laravel/nexmo-notification-channel": "^1.0", + "laravel/slack-notification-channel": "^1.0", "league/flysystem": "^1.0.8", - "monolog/monolog": "~1.12", - "nesbot/carbon": "1.25.*", + "monolog/monolog": "^1.12", + "nesbot/carbon": "^1.26.3", + "opis/closure": "^3.1", "php": "^7.1.3", - "psr/container": "~1.0", + "psr/container": "^1.0", "psr/simple-cache": "^1.0", "ramsey/uuid": "^3.7", - "swiftmailer/swiftmailer": "~6.0", - "symfony/console": "~4.0", - "symfony/debug": "~4.0", - "symfony/finder": "~4.0", - "symfony/http-foundation": "~4.0", - "symfony/http-kernel": "~4.0", - "symfony/process": "~4.0", - "symfony/routing": "~4.0", - "symfony/var-dumper": "~4.0", + "swiftmailer/swiftmailer": "^6.0", + "symfony/console": "^4.1", + "symfony/debug": "^4.1", + "symfony/finder": "^4.1", + "symfony/http-foundation": "^4.1", + "symfony/http-kernel": "^4.1", + "symfony/process": "^4.1", + "symfony/routing": "^4.1", + "symfony/var-dumper": "^4.1", "tijsverkoyen/css-to-inline-styles": "^2.2.1", - "vlucas/phpdotenv": "~2.2" + "vlucas/phpdotenv": "^2.2" }, "conflict": { "tightenco/collect": "<5.5.33" @@ -2105,43 +2108,47 @@ "illuminate/view": "self.version" }, "require-dev": { - "aws/aws-sdk-php": "~3.0", - "doctrine/dbal": "~2.6", + "aws/aws-sdk-php": "^3.0", + "doctrine/dbal": "^2.6", "filp/whoops": "^2.1.4", - "league/flysystem-cached-adapter": "~1.0", - "mockery/mockery": "~1.0", + "guzzlehttp/guzzle": "^6.3", + "league/flysystem-cached-adapter": "^1.0", + "mockery/mockery": "^1.0", "moontoast/math": "^1.1", - "orchestra/testbench-core": "3.6.*", - "pda/pheanstalk": "~3.0", - "phpunit/phpunit": "~7.0", + "orchestra/testbench-core": "3.7.*", + "pda/pheanstalk": "^3.0", + "phpunit/phpunit": "^7.0", "predis/predis": "^1.1.1", - "symfony/css-selector": "~4.0", - "symfony/dom-crawler": "~4.0" + "symfony/css-selector": "^4.1", + "symfony/dom-crawler": "^4.1", + "true/punycode": "^2.1" }, "suggest": { - "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).", - "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.6).", + "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (^3.0).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6).", "ext-pcntl": "Required to use all features of the queue worker.", "ext-posix": "Required to use all features of the queue worker.", - "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", - "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~6.0).", - "laravel/tinker": "Required to use the tinker console command (~1.0).", - "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", - "league/flysystem-cached-adapter": "Required to use the Flysystem cache (~1.0).", - "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).", - "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (~1.0).", - "nexmo/client": "Required to use the Nexmo transport (~1.0).", - "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).", - "predis/predis": "Required to use the redis cache and queue drivers (~1.0).", - "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~3.0).", - "symfony/css-selector": "Required to use some of the crawler integration testing tools (~4.0).", - "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (~4.0).", - "symfony/psr-http-message-bridge": "Required to psr7 bridging features (~1.0)." + "filp/whoops": "Required for friendly error pages in development (^2.1.4).", + "fzaninotto/faker": "Required to use the eloquent factory builder (^1.4).", + "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (^6.0).", + "laravel/tinker": "Required to use the tinker console command (^1.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).", + "league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).", + "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (^1.0).", + "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).", + "moontoast/math": "Required to use ordered UUIDs (^1.1).", + "nexmo/client": "Required to use the Nexmo transport (^1.0).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^3.0).", + "predis/predis": "Required to use the redis cache and queue drivers (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^3.0).", + "symfony/css-selector": "Required to use some of the crawler integration testing tools (^4.1).", + "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (^4.1).", + "symfony/psr-http-message-bridge": "Required to psr7 bridging features (^1.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.6-dev" + "dev-master": "5.7-dev" } }, "autoload": { @@ -2169,7 +2176,121 @@ "framework", "laravel" ], - "time": "2018-10-04T14:50:41+00:00" + "time": "2018-12-18T14:00:38+00:00" + }, + { + "name": "laravel/nexmo-notification-channel", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/nexmo-notification-channel.git", + "reference": "03edd42a55b306ff980c9950899d5a2b03260d48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/nexmo-notification-channel/zipball/03edd42a55b306ff980c9950899d5a2b03260d48", + "reference": "03edd42a55b306ff980c9950899d5a2b03260d48", + "shasum": "" + }, + "require": { + "nexmo/client": "^1.0", + "php": "^7.1.3" + }, + "require-dev": { + "illuminate/notifications": "~5.7", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "laravel": { + "providers": [ + "Illuminate\\Notifications\\NexmoChannelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Notifications\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Nexmo Notification Channel for laravel.", + "keywords": [ + "laravel", + "nexmo", + "notifications" + ], + "time": "2018-12-04T12:57:08+00:00" + }, + { + "name": "laravel/slack-notification-channel", + "version": "v1.0.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/slack-notification-channel.git", + "reference": "6e164293b754a95f246faf50ab2bbea3e4923cc9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/6e164293b754a95f246faf50ab2bbea3e4923cc9", + "reference": "6e164293b754a95f246faf50ab2bbea3e4923cc9", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0", + "php": "^7.1.3" + }, + "require-dev": { + "illuminate/notifications": "~5.7", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "laravel": { + "providers": [ + "Illuminate\\Notifications\\SlackChannelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Notifications\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Slack Notification Channel for laravel.", + "keywords": [ + "laravel", + "notifications", + "slack" + ], + "time": "2018-12-12T13:12:06+00:00" }, { "name": "laravel/tinker", @@ -2713,16 +2834,16 @@ }, { "name": "nesbot/carbon", - "version": "1.25.0", + "version": "1.36.2", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4" + "reference": "cd324b98bc30290f233dd0e75e6ce49f7ab2a6c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cbcf13da0b531767e39eb86e9687f5deba9857b4", - "reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cd324b98bc30290f233dd0e75e6ce49f7ab2a6c9", + "reference": "cd324b98bc30290f233dd0e75e6ce49f7ab2a6c9", "shasum": "" }, "require": { @@ -2730,18 +2851,23 @@ "symfony/translation": "~2.6 || ~3.0 || ~4.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2", "phpunit/phpunit": "^4.8.35 || ^5.7" }, + "suggest": { + "friendsofphp/php-cs-fixer": "Needed for the `composer phpcs` command. Allow to automatically fix code style.", + "phpstan/phpstan": "Needed for the `composer phpstan` command. Allow to detect potential errors." + }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.23-dev" + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] } }, "autoload": { "psr-4": { - "Carbon\\": "src/Carbon/" + "": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -2762,7 +2888,7 @@ "datetime", "time" ], - "time": "2018-03-19T15:50:49+00:00" + "time": "2018-12-28T10:07:33+00:00" }, { "name": "nexmo/client", @@ -2863,6 +2989,67 @@ ], "time": "2018-12-26T11:32:39+00:00" }, + { + "name": "opis/closure", + "version": "3.1.2", + "source": { + "type": "git", + "url": "https://github.com/opis/closure.git", + "reference": "de00c69a2328d3ee5baa71fc584dc643222a574c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/closure/zipball/de00c69a2328d3ee5baa71fc584dc643222a574c", + "reference": "de00c69a2328d3ee5baa71fc584dc643222a574c", + "shasum": "" + }, + "require": { + "php": "^5.4 || ^7.0" + }, + "require-dev": { + "jeremeamia/superclosure": "^2.0", + "phpunit/phpunit": "^4.0|^5.0|^6.0|^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\Closure\\": "src/" + }, + "files": [ + "functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", + "homepage": "https://opis.io/closure", + "keywords": [ + "anonymous functions", + "closure", + "function", + "serializable", + "serialization", + "serialize" + ], + "time": "2018-12-16T21:48:23+00:00" + }, { "name": "php-http/guzzle6-adapter", "version": "v1.1.1", diff --git a/config/exceptions.php b/config/exceptions.php index d31878908b1b..7f3a115e7d13 100644 --- a/config/exceptions.php +++ b/config/exceptions.php @@ -47,10 +47,11 @@ */ 'displayers' => [ - 'CachetHQ\Cachet\Foundation\Exceptions\Displayers\JsonValidationDisplayer', + 'CachetHQ\Cachet\Foundation\Exceptions\Displayers\MaintenanceDisplayer', + 'CachetHQ\Cachet\Foundation\Exceptions\Displayers\SettingsDisplayer', 'CachetHQ\Cachet\Foundation\Exceptions\Displayers\RedirectDisplayer', 'CachetHQ\Cachet\Foundation\Exceptions\Displayers\ThrottleDisplayer', - 'CachetHQ\Cachet\Foundation\Exceptions\Displayers\MaintenanceDisplayer', + 'CachetHQ\Cachet\Foundation\Exceptions\Displayers\JsonValidationDisplayer', 'GrahamCampbell\Exceptions\Displayers\DebugDisplayer', 'GrahamCampbell\Exceptions\Displayers\HtmlDisplayer', 'GrahamCampbell\Exceptions\Displayers\JsonDisplayer', diff --git a/config/trustedproxy.php b/config/trustedproxy.php new file mode 100644 index 000000000000..c8cfc7c0b77d --- /dev/null +++ b/config/trustedproxy.php @@ -0,0 +1,53 @@ + null, // [,], '*' + + /* + * To trust one or more specific proxies that connect + * directly to your server, use an array of IP addresses: + */ + // 'proxies' => ['192.168.1.1'], + + /* + * Or, to trust all proxies that connect + * directly to your server, use a "*" + */ + // 'proxies' => '*', + + /* + * Which headers to use to detect proxy related data (For, Host, Proto, Port) + * + * Options include: + * + * - Illuminate\Http\Request::HEADER_X_FORWARDED_ALL (use all x-forwarded-* headers to establish trust) + * - Illuminate\Http\Request::HEADER_FORWARDED (use the FORWARDED header to establish trust) + * + * @link https://symfony.com/doc/current/deployment/proxies.html + */ + 'headers' => Illuminate\Http\Request::HEADER_X_FORWARDED_ALL, + +]; diff --git a/resources/views/errors/401.blade.php b/resources/views/errors/401.blade.php new file mode 100644 index 000000000000..10f05b88c3e0 --- /dev/null +++ b/resources/views/errors/401.blade.php @@ -0,0 +1,11 @@ +@extends('errors::illustrated-layout') + +@section('code', '401') +@section('title', __('Unauthorized')) + +@section('image') +
+
+@endsection + +@section('message', __('Sorry, you are not authorized to access this page.')) diff --git a/resources/views/errors/403.blade.php b/resources/views/errors/403.blade.php new file mode 100644 index 000000000000..bbb79a4910f3 --- /dev/null +++ b/resources/views/errors/403.blade.php @@ -0,0 +1,11 @@ +@extends('errors::illustrated-layout') + +@section('code', '403') +@section('title', __('Forbidden')) + +@section('image') +
+
+@endsection + +@section('message', __($exception->getMessage() ?: __('Sorry, you are forbidden from accessing this page.'))) diff --git a/resources/views/errors/404.blade.php b/resources/views/errors/404.blade.php new file mode 100644 index 000000000000..d2bae51f806f --- /dev/null +++ b/resources/views/errors/404.blade.php @@ -0,0 +1,11 @@ +@extends('errors::illustrated-layout') + +@section('code', '404') +@section('title', __('Page Not Found')) + +@section('image') +
+
+@endsection + +@section('message', __('Sorry, the page you are looking for could not be found.')) diff --git a/resources/views/errors/419.blade.php b/resources/views/errors/419.blade.php new file mode 100644 index 000000000000..1b00819f0b7c --- /dev/null +++ b/resources/views/errors/419.blade.php @@ -0,0 +1,11 @@ +@extends('errors::illustrated-layout') + +@section('code', '419') +@section('title', __('Page Expired')) + +@section('image') +
+
+@endsection + +@section('message', __('Sorry, your session has expired. Please refresh and try again.')) diff --git a/resources/views/errors/429.blade.php b/resources/views/errors/429.blade.php new file mode 100644 index 000000000000..2747654acf19 --- /dev/null +++ b/resources/views/errors/429.blade.php @@ -0,0 +1,11 @@ +@extends('errors::illustrated-layout') + +@section('code', '429') +@section('title', __('Too Many Requests')) + +@section('image') +
+
+@endsection + +@section('message', __('Sorry, you are making too many requests to our servers.')) diff --git a/resources/views/errors/500.blade.php b/resources/views/errors/500.blade.php new file mode 100644 index 000000000000..8868cf822bea --- /dev/null +++ b/resources/views/errors/500.blade.php @@ -0,0 +1,11 @@ +@extends('errors::illustrated-layout') + +@section('code', '500') +@section('title', __('Error')) + +@section('image') +
+
+@endsection + +@section('message', __('Whoops, something went wrong on our servers.')) diff --git a/resources/views/errors/503.blade.php b/resources/views/errors/503.blade.php new file mode 100644 index 000000000000..476ff52fe67b --- /dev/null +++ b/resources/views/errors/503.blade.php @@ -0,0 +1,11 @@ +@extends('errors::illustrated-layout') + +@section('code', '503') +@section('title', __('Service Unavailable')) + +@section('image') +
+
+@endsection + +@section('message', __($exception->getMessage() ?: __('Sorry, we are doing some maintenance. Please check back soon.'))) diff --git a/resources/views/errors/illustrated-layout.blade.php b/resources/views/errors/illustrated-layout.blade.php new file mode 100644 index 000000000000..3730d05ae79b --- /dev/null +++ b/resources/views/errors/illustrated-layout.blade.php @@ -0,0 +1,486 @@ + + + + @yield('title') + + + + + + + + + + + + +
+
+
+
+ @yield('code', __('Oh no')) +
+ +
+ +

+ @yield('message') +

+ + + + +
+
+ +
+ @yield('image') +
+
+ + diff --git a/resources/views/errors/layout.blade.php b/resources/views/errors/layout.blade.php new file mode 100644 index 000000000000..2c51d4f355b5 --- /dev/null +++ b/resources/views/errors/layout.blade.php @@ -0,0 +1,57 @@ + + + + + + + @yield('title') + + + + + + + + + +
+
+
+ @yield('message') +
+
+
+ + diff --git a/resources/views/layout/clean.blade.php b/resources/views/layout/clean.blade.php index 9af7754d65e2..680b02e0686d 100644 --- a/resources/views/layout/clean.blade.php +++ b/resources/views/layout/clean.blade.php @@ -20,7 +20,7 @@ - {{ $pageTitle or $siteTitle }} + {{ $pageTitle ?? $siteTitle }} @if($enableExternalDependencies) {{-- --}} diff --git a/resources/views/layout/dashboard.blade.php b/resources/views/layout/dashboard.blade.php index 374026cf155c..aff29c0761d1 100644 --- a/resources/views/layout/dashboard.blade.php +++ b/resources/views/layout/dashboard.blade.php @@ -20,7 +20,7 @@ - {{ $pageTitle or $siteTitle }} + {{ $pageTitle ?? $siteTitle }}