diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6f313c6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.yml] +indent_size = 2 diff --git a/.env.example b/.env.example index 715bc44..afdc119 100644 --- a/.env.example +++ b/.env.example @@ -16,7 +16,7 @@ DB_PASSWORD=secret BROADCAST_DRIVER=log CACHE_DRIVER=file SESSION_DRIVER=file -QUEUE_DRIVER=sync +QUEUE_CONNECTION=sync REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index e683ad8..1f10e04 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -49,9 +49,9 @@ public function __construct() 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', + 'name' => ['required', 'string', 'max:255'], + 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], + 'password' => ['required', 'string', 'min:6', 'confirmed'], ]); } diff --git a/app/Http/Controllers/Auth/VerificationController.php b/app/Http/Controllers/Auth/VerificationController.php new file mode 100644 index 0000000..7f87100 --- /dev/null +++ b/app/Http/Controllers/Auth/VerificationController.php @@ -0,0 +1,41 @@ +middleware('auth'); + $this->middleware('signed')->only('verify'); + $this->middleware('throttle:6,1')->only('verify', 'resend'); + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 16a0f65..6cc9a9d 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -50,7 +50,7 @@ class Kernel extends HttpKernel * @var array */ protected $routeMiddleware = [ - 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, + 'auth' => \Framework\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, @@ -58,5 +58,22 @@ class Kernel extends HttpKernel 'guest' => \Framework\Http\Middleware\RedirectIfAuthenticated::class, 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + ]; + + /** + * The priority-sorted list of middleware. + * + * This forces the listed middleware to always be in the given order. + * + * @var array + */ + protected $middlewarePriority = [ + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\View\Middleware\ShareErrorsFromSession::class, + \Framework\Http\Middleware\Authenticate::class, + \Illuminate\Session\Middleware\AuthenticateSession::class, + \Illuminate\Routing\Middleware\SubstituteBindings::class, + \Illuminate\Auth\Middleware\Authorize::class, ]; } diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php new file mode 100644 index 0000000..5abad09 --- /dev/null +++ b/app/Http/Middleware/Authenticate.php @@ -0,0 +1,21 @@ +expectsJson()) { + return route('login'); + } + } +} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 7049980..446c333 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -6,6 +6,13 @@ class VerifyCsrfToken extends BaseVerifier { + /** + * Indicates whether the XSRF-TOKEN cookie should be set on the response. + * + * @var bool + */ + protected $addHttpCookie = true; + /** * The URIs that should be excluded from CSRF verification. * diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 60e23b0..3d248ec 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -3,6 +3,8 @@ namespace Framework\Providers; use Illuminate\Support\Facades\Event; +use Illuminate\Auth\Events\Registered; +use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider @@ -13,8 +15,8 @@ class EventServiceProvider extends ServiceProvider * @var array */ protected $listen = [ - 'Framework\Events\SomeEvent' => [ - 'Framework\Listeners\EventListener', + Registered::class => [ + SendEmailVerificationNotification::class, ], ]; diff --git a/bootstrap/app.php b/bootstrap/app.php index db07a76..37cf8fc 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -12,7 +12,7 @@ */ $app = new Illuminate\Foundation\Application( - realpath(__DIR__.'/../') + dirname(__DIR__) ); /* diff --git a/composer.json b/composer.json index 85ed823..846cbcd 100644 --- a/composer.json +++ b/composer.json @@ -6,8 +6,8 @@ "type": "project", "require": { "php": ">=7.1.3", - "laravel/framework": "5.6.*", - "lucid-arch/laravel-foundation": "5.6.*", + "laravel/framework": "5.7.*", + "lucid-arch/laravel-foundation": "5.7.*", "laravel/tinker": "^1.0", "fideloper/proxy": "~4.0" }, @@ -18,7 +18,8 @@ "phpunit/phpunit": "~7.0", "symfony/css-selector": "~4.0", "symfony/dom-crawler": "~4.0", - "lucid-arch/laravel-console": "5.6.*", + "lucid-arch/laravel-console": "5.7.*", + "beyondcode/laravel-dump-server": "^1.0", "filp/whoops": "^2.0" }, "autoload": { @@ -36,7 +37,7 @@ "php -r \"file_exists('.env') || copy('.env.example', '.env');\"" ], "post-create-project-cmd": [ - "php artisan key:generate" + "@php artisan key:generate --ansi" ], "post-install-cmd": [ "Illuminate\\Foundation\\ComposerScripts::postInstall" @@ -46,7 +47,7 @@ ], "post-autoload-dump": [ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", - "@php artisan package:discover" + "@php artisan package:discover --ansi" ] }, "config": { diff --git a/config/app.php b/config/app.php index ab17e0f..6d8b298 100644 --- a/config/app.php +++ b/config/app.php @@ -21,7 +21,7 @@ | | This value determines the "environment" your application is currently | running in. This may determine how you prefer to configure various - | services your application utilizes. Set this in your ".env" file. + | services the application utilizes. Set this in your ".env" file. | */ @@ -53,6 +53,8 @@ 'url' => env('APP_URL', 'http://localhost'), + 'asset_url' => env('ASSET_URL', null), + /* |-------------------------------------------------------------------------- | Application Timezone @@ -92,6 +94,18 @@ 'fallback_locale' => 'en', + /* + |-------------------------------------------------------------------------- + | Faker Locale + |-------------------------------------------------------------------------- + | + | This locale will be used by the Faker PHP library when generating fake + | data for your database seeds. For example, this will be used to get + | localized telephone numbers, street address information and more. + | + */ + 'faker_locale' => 'en_US', + /* |-------------------------------------------------------------------------- | Encryption Key diff --git a/config/cache.php b/config/cache.php index e87f032..0c30969 100644 --- a/config/cache.php +++ b/config/cache.php @@ -1,5 +1,7 @@ [ 'driver' => 'redis', - 'connection' => 'default', + 'connection' => 'cache', ], ], @@ -86,6 +88,6 @@ | */ - 'prefix' => 'laravel', + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'), ]; diff --git a/config/database.php b/config/database.php index df36b2d..899faa8 100644 --- a/config/database.php +++ b/config/database.php @@ -37,6 +37,7 @@ 'driver' => 'sqlite', 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), ], 'mysql' => [ @@ -49,6 +50,7 @@ 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', + 'prefix_indexes' => true, 'strict' => true, 'engine' => null, ], @@ -62,6 +64,7 @@ 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'prefix' => '', + 'prefix_indexes' => true, 'schema' => 'public', 'sslmode' => 'prefer', ], @@ -87,7 +90,7 @@ |-------------------------------------------------------------------------- | | Redis is an open source, fast, and advanced key-value store that also - | provides a richer set of commands than a typical key-value systems + | provides a richer body of commands than a typical key-value system | such as APC or Memcached. Laravel makes it easy to dig right in. | */ @@ -100,7 +103,14 @@ 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), - 'database' => 0, + 'database' => env('REDIS_DB', 0), + ], + + 'cache' => [ + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'password' => env('REDIS_PASSWORD', null), + 'port' => env('REDIS_PORT', 6379), + 'database' => env('REDIS_CACHE_DB', 1), ], ], diff --git a/config/hashing.php b/config/hashing.php index f3332ed..9b89b19 100644 --- a/config/hashing.php +++ b/config/hashing.php @@ -11,7 +11,7 @@ | passwords for your application. By default, the bcrypt algorithm is | used; however, you remain free to modify this option if you wish. | - | Supported: "bcrypt", "argon" + | Supported: "bcrypt", "argon", "argon2id" | */ diff --git a/config/logging.php b/config/logging.php index 400bc7f..506f2f3 100644 --- a/config/logging.php +++ b/config/logging.php @@ -1,6 +1,7 @@ [ 'stack' => [ 'driver' => 'stack', - 'channels' => ['single'], + 'channels' => ['daily'], ], 'single' => [ @@ -48,7 +49,7 @@ 'driver' => 'daily', 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', - 'days' => 7, + 'days' => 14, ], 'slack' => [ @@ -59,6 +60,16 @@ 'level' => 'critical', ], + 'papertrail' => [ + 'driver' => 'monolog', + 'level' => 'debug', + 'handler' => SyslogUdpHandler::class, + 'handler_with' => [ + 'host' => env('PAPERTRAIL_URL'), + 'port' => env('PAPERTRAIL_PORT'), + ], + ], + 'stderr' => [ 'driver' => 'monolog', 'handler' => StreamHandler::class, diff --git a/config/mail.php b/config/mail.php index bb92224..1e21384 100644 --- a/config/mail.php +++ b/config/mail.php @@ -120,4 +120,16 @@ ], ], + /* + |-------------------------------------------------------------------------- + | Log Channel + |-------------------------------------------------------------------------- + | + | If you are using the "log" driver, you may specify the logging channel + | if you prefer to keep mail messages separate from other log entries + | for simpler reading. Otherwise, the default channel will be used. + | + */ + 'log_channel' => env('MAIL_LOG_CHANNEL'), + ]; diff --git a/config/queue.php b/config/queue.php index efb271b..9a03900 100644 --- a/config/queue.php +++ b/config/queue.php @@ -15,7 +15,7 @@ | */ - 'default' => env('QUEUE_DRIVER', 'sync'), + 'default' => env('QUEUE_CONNECTION', 'sync'), /* |-------------------------------------------------------------------------- @@ -60,7 +60,7 @@ 'redis' => [ 'driver' => 'redis', 'connection' => 'default', - 'queue' => 'default', + 'queue' => env('REDIS_QUEUE', 'default'), 'retry_after' => 90, 'block_for' => null, ], diff --git a/config/services.php b/config/services.php index aa1f7f8..dfdc56e 100644 --- a/config/services.php +++ b/config/services.php @@ -17,6 +17,7 @@ 'mailgun' => [ 'domain' => env('MAILGUN_DOMAIN'), 'secret' => env('MAILGUN_SECRET'), + 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), ], 'ses' => [ @@ -30,9 +31,13 @@ ], 'stripe' => [ - 'model' => App\User::class, + 'model' => Framework\User::class, 'key' => env('STRIPE_KEY'), 'secret' => env('STRIPE_SECRET'), + 'webhook' => [ + 'secret' => env('STRIPE_WEBHOOK_SECRET'), + 'tolerance' => env('STRIPE_WEBHOOK_TOLERANCE', 300), + ], ], ]; diff --git a/config/session.php b/config/session.php index e2779ad..5240317 100644 --- a/config/session.php +++ b/config/session.php @@ -1,5 +1,7 @@ null, + 'connection' => env('SESSION_CONNECTION', null), /* |-------------------------------------------------------------------------- @@ -96,7 +98,7 @@ | */ - 'store' => null, + 'store' => env('SESSION_STORE', null), /* |-------------------------------------------------------------------------- @@ -122,7 +124,10 @@ | */ - 'cookie' => 'laravel_session', + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + ), /* |-------------------------------------------------------------------------- diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php new file mode 100644 index 0000000..74195da --- /dev/null +++ b/database/factories/UserFactory.php @@ -0,0 +1,24 @@ +define(Framework\User::class, function (Faker $faker) { + return [ + 'name' => $faker->name, + 'email' => $faker->unique()->safeEmail, + 'email_verified_at' => now(), + 'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret + 'remember_token' => str_random(10), + ]; + }); diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 55574ee..b1308d7 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -18,6 +18,7 @@ public function up() $table->string('name'); $table->string('email')->unique(); $table->string('password'); + $table->timestamp('email_verified_at')->nullable(); $table->rememberToken(); $table->timestamps(); }); diff --git a/package.json b/package.json index 7d480e8..71de663 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,6 @@ "jquery": "^3.2", "laravel-mix": "^2.0", "lodash": "^4.17.4", - "vue": "^2.5.7" + "vue": "^2.5.17" } } diff --git a/phpunit.xml b/phpunit.xml index f6ad675..a589188 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -32,8 +32,8 @@ + - diff --git a/public/svg/403.svg b/public/svg/403.svg new file mode 100644 index 0000000..b62f1e4 --- /dev/null +++ b/public/svg/403.svg @@ -0,0 +1 @@ + diff --git a/public/svg/404.svg b/public/svg/404.svg new file mode 100644 index 0000000..bd5532c --- /dev/null +++ b/public/svg/404.svg @@ -0,0 +1 @@ + diff --git a/public/svg/500.svg b/public/svg/500.svg new file mode 100644 index 0000000..086b992 --- /dev/null +++ b/public/svg/500.svg @@ -0,0 +1 @@ + diff --git a/public/svg/503.svg b/public/svg/503.svg new file mode 100644 index 0000000..333296e --- /dev/null +++ b/public/svg/503.svg @@ -0,0 +1 @@ + diff --git a/readme.md b/readme.md index 1e2c8ed..b28eb02 100644 --- a/readme.md +++ b/readme.md @@ -28,22 +28,27 @@ If you prefer a video, watch the announcement of The Lucid Architecture at Larac - [Microservices](#microservices) ## Installation -### 5.6 +### 5.7 To start your project with Lucid right away, run the following command: ``` composer create-project lucid-arch/laravel my-project ``` -This will give you a Laravel 5.6 installation with Lucid out-of-the-box. If you wish to download other versions of Laravel you may specify it as well: +This will give you a Laravel 5.7 installation with Lucid out-of-the-box. If you wish to download other versions of Laravel you may specify it as well: + +##### 5.6 +``` +composer create-project lucid-arch/laravel=5.6.x my-project-5.6 +``` + +> Literally 5.6.x and not 5.6.0 or 5.6.1... ##### 5.5 ``` composer create-project lucid-arch/laravel=5.5.x my-project-5.5 ``` -> Literally 5.5.x and not 5.5.0 or 5.5.1... - ##### 5.4 ``` composer create-project lucid-arch/laravel=5.4.x my-project-5.4 diff --git a/resources/assets/js/app.js b/resources/assets/js/app.js deleted file mode 100644 index 9f08625..0000000 --- a/resources/assets/js/app.js +++ /dev/null @@ -1,20 +0,0 @@ - -/** - * First we will load all of this project's JavaScript dependencies which - * includes Vue and other libraries. It is a great starting point when - * building robust, powerful web applications using Vue and Laravel. - */ - -require('./bootstrap'); - -/** - * Next, we will create a fresh Vue application instance and attach it to - * the page. Then, you may begin adding components to this application - * or customize the JavaScript scaffolding to fit your unique needs. - */ - -Vue.component('example', require('./components/Example.vue')); - -const app = new Vue({ - el: '#app' -}); diff --git a/resources/assets/js/bootstrap.js b/resources/assets/js/bootstrap.js deleted file mode 100644 index e89ea5a..0000000 --- a/resources/assets/js/bootstrap.js +++ /dev/null @@ -1,46 +0,0 @@ - -window._ = require('lodash'); - -/** - * We'll load jQuery and the Bootstrap jQuery plugin which provides support - * for JavaScript based Bootstrap features such as modals and tabs. This - * code may be modified to fit the specific needs of your application. - */ - -window.$ = window.jQuery = require('jquery'); - -require('bootstrap-sass'); - -/** - * Vue is a modern JavaScript library for building interactive web interfaces - * using reactive data binding and reusable components. Vue's API is clean - * and simple, leaving you to focus on building your next great project. - */ - -window.Vue = require('vue'); - -/** - * We'll load the axios HTTP library which allows us to easily issue requests - * to our Laravel back-end. This library automatically handles sending the - * CSRF token as a header based on the value of the "XSRF" token cookie. - */ - -window.axios = require('axios'); - -window.axios.defaults.headers.common = { - 'X-CSRF-TOKEN': window.Laravel.csrfToken, - 'X-Requested-With': 'XMLHttpRequest' -}; - -/** - * Echo exposes an expressive API for subscribing to channels and listening - * for events that are broadcast by Laravel. Echo and event broadcasting - * allows your team to easily build robust real-time web applications. - */ - -// import Echo from "laravel-echo" - -// window.Echo = new Echo({ -// broadcaster: 'pusher', -// key: 'your-pusher-key' -// }); diff --git a/resources/js/app.js b/resources/js/app.js new file mode 100644 index 0000000..50a81c2 --- /dev/null +++ b/resources/js/app.js @@ -0,0 +1,30 @@ + +/** + * First we will load all of this project's JavaScript dependencies which + * includes Vue and other libraries. It is a great starting point when + * building robust, powerful web applications using Vue and Laravel. + */ + + require('./bootstrap'); + + window.Vue = require('vue'); + + /** + * The following block of code may be used to automatically register your + * Vue components. It will recursively scan this directory for the Vue + * components and automatically register them with their "basename". + * + * Eg. ./components/ExampleComponent.vue -> + */ + + Vue.component('example-component', require('./components/ExampleComponent.vue')); + + /** + * Next, we will create a fresh Vue application instance and attach it to + * the page. Then, you may begin adding components to this application + * or customize the JavaScript scaffolding to fit your unique needs. + */ + + const app = new Vue({ + el: '#app' +}); diff --git a/resources/js/bootstrap.js b/resources/js/bootstrap.js new file mode 100644 index 0000000..de60a86 --- /dev/null +++ b/resources/js/bootstrap.js @@ -0,0 +1,50 @@ + +window._ = require('lodash'); + +/** + * We'll load jQuery and the Bootstrap jQuery plugin which provides support + * for JavaScript based Bootstrap features such as modals and tabs. This + * code may be modified to fit the specific needs of your application. + */ +try { + window.Popper = require('popper.js').default; + window.$ = window.jQuery = require('jquery'); + require('bootstrap'); + } catch (e) {} + + /** + * We'll load the axios HTTP library which allows us to easily issue requests + * to our Laravel back-end. This library automatically handles sending the + * CSRF token as a header based on the value of the "XSRF" token cookie. + */ + + window.axios = require('axios'); + + window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; + + /** + * Next we will register the CSRF Token as a common header with Axios so that + * all outgoing HTTP requests automatically have it attached. This is just + * a simple convenience so we don't have to attach every token manually. + */ + + let token = document.head.querySelector('meta[name="csrf-token"]'); + + if (token) { + window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content; + } else { + console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token'); + } + +/** + * Echo exposes an expressive API for subscribing to channels and listening + * for events that are broadcast by Laravel. Echo and event broadcasting + * allows your team to easily build robust real-time web applications. + */ + +// import Echo from "laravel-echo" + +// window.Echo = new Echo({ +// broadcaster: 'pusher', +// key: 'your-pusher-key' +// }); diff --git a/resources/assets/js/components/Example.vue b/resources/js/components/Example.vue similarity index 100% rename from resources/assets/js/components/Example.vue rename to resources/js/components/Example.vue diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php index fd641f9..f1b54f4 100644 --- a/resources/lang/en/validation.php +++ b/resources/lang/en/validation.php @@ -13,79 +13,105 @@ | */ - 'accepted' => 'The :attribute must be accepted.', - 'active_url' => 'The :attribute is not a valid URL.', - 'after' => 'The :attribute must be a date after :date.', - 'after_or_equal' => 'The :attribute must be a date after or equal to :date.', - 'alpha' => 'The :attribute may only contain letters.', - 'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.', - 'alpha_num' => 'The :attribute may only contain letters and numbers.', - 'array' => 'The :attribute must be an array.', - 'before' => 'The :attribute must be a date before :date.', - 'before_or_equal' => 'The :attribute must be a date before or equal to :date.', - 'between' => [ + 'accepted' => 'The :attribute must be accepted.', + 'active_url' => 'The :attribute is not a valid URL.', + 'after' => 'The :attribute must be a date after :date.', + 'after_or_equal' => 'The :attribute must be a date after or equal to :date.', + 'alpha' => 'The :attribute may only contain letters.', + 'alpha_dash' => 'The :attribute may only contain letters, numbers, dashes and underscores.', + 'alpha_num' => 'The :attribute may only contain letters and numbers.', + 'array' => 'The :attribute must be an array.', + 'before' => 'The :attribute must be a date before :date.', + 'before_or_equal' => 'The :attribute must be a date before or equal to :date.', + 'between' => [ 'numeric' => 'The :attribute must be between :min and :max.', - 'file' => 'The :attribute must be between :min and :max kilobytes.', - 'string' => 'The :attribute must be between :min and :max characters.', - 'array' => 'The :attribute must have between :min and :max items.', + 'file' => 'The :attribute must be between :min and :max kilobytes.', + 'string' => 'The :attribute must be between :min and :max characters.', + 'array' => 'The :attribute must have between :min and :max items.', ], - 'boolean' => 'The :attribute field must be true or false.', - 'confirmed' => 'The :attribute confirmation does not match.', - 'date' => 'The :attribute is not a valid date.', - 'date_format' => 'The :attribute does not match the format :format.', - 'different' => 'The :attribute and :other must be different.', - 'digits' => 'The :attribute must be :digits digits.', - 'digits_between' => 'The :attribute must be between :min and :max digits.', - 'dimensions' => 'The :attribute has invalid image dimensions.', - 'distinct' => 'The :attribute field has a duplicate value.', - 'email' => 'The :attribute must be a valid email address.', - 'exists' => 'The selected :attribute is invalid.', - 'file' => 'The :attribute must be a file.', - 'filled' => 'The :attribute field is required.', - 'image' => 'The :attribute must be an image.', - 'in' => 'The selected :attribute is invalid.', - 'in_array' => 'The :attribute field does not exist in :other.', - 'integer' => 'The :attribute must be an integer.', - 'ip' => 'The :attribute must be a valid IP address.', - 'json' => 'The :attribute must be a valid JSON string.', - 'max' => [ + 'boolean' => 'The :attribute field must be true or false.', + 'confirmed' => 'The :attribute confirmation does not match.', + 'date' => 'The :attribute is not a valid date.', + 'date_format' => 'The :attribute does not match the format :format.', + 'different' => 'The :attribute and :other must be different.', + 'digits' => 'The :attribute must be :digits digits.', + 'digits_between' => 'The :attribute must be between :min and :max digits.', + 'dimensions' => 'The :attribute has invalid image dimensions.', + 'distinct' => 'The :attribute field has a duplicate value.', + 'email' => 'The :attribute must be a valid email address.', + 'exists' => 'The selected :attribute is invalid.', + 'file' => 'The :attribute must be a file.', + 'filled' => 'The :attribute field must have a value.', + 'gt' => [ + 'file' => 'The :attribute must be greater than :value kilobytes.', + 'string' => 'The :attribute must be greater than :value characters.', + 'array' => 'The :attribute must have more than :value items.', + ], + 'gte' => [ + 'numeric' => 'The :attribute must be greater than or equal :value.', + 'file' => 'The :attribute must be greater than or equal :value kilobytes.', + 'string' => 'The :attribute must be greater than or equal :value characters.', + 'array' => 'The :attribute must have :value items or more.', + ], + 'image' => 'The :attribute must be an image.', + 'in' => 'The selected :attribute is invalid.', + 'in_array' => 'The :attribute field does not exist in :other.', + 'integer' => 'The :attribute must be an integer.', + 'ip' => 'The :attribute must be a valid IP address.', + 'ipv4' => 'The :attribute must be a valid IPv4 address.', + 'ipv6' => 'The :attribute must be a valid IPv6 address.', + 'json' => 'The :attribute must be a valid JSON string.', + 'lt' => [ + 'numeric' => 'The :attribute must be less than :value.', + 'file' => 'The :attribute must be less than :value kilobytes.', + 'string' => 'The :attribute must be less than :value characters.', + 'array' => 'The :attribute must have less than :value items.', + ], + 'lte' => [ + 'numeric' => 'The :attribute must be less than or equal :value.', + 'file' => 'The :attribute must be less than or equal :value kilobytes.', + 'string' => 'The :attribute must be less than or equal :value characters.', + 'array' => 'The :attribute must not have more than :value items.', + ], + 'max' => [ 'numeric' => 'The :attribute may not be greater than :max.', - 'file' => 'The :attribute may not be greater than :max kilobytes.', - 'string' => 'The :attribute may not be greater than :max characters.', - 'array' => 'The :attribute may not have more than :max items.', + 'file' => 'The :attribute may not be greater than :max kilobytes.', + 'string' => 'The :attribute may not be greater than :max characters.', + 'array' => 'The :attribute may not have more than :max items.', ], - 'mimes' => 'The :attribute must be a file of type: :values.', - 'mimetypes' => 'The :attribute must be a file of type: :values.', - 'min' => [ + 'mimes' => 'The :attribute must be a file of type: :values.', + 'mimetypes' => 'The :attribute must be a file of type: :values.', + 'min' => [ 'numeric' => 'The :attribute must be at least :min.', - 'file' => 'The :attribute must be at least :min kilobytes.', - 'string' => 'The :attribute must be at least :min characters.', - 'array' => 'The :attribute must have at least :min items.', + 'file' => 'The :attribute must be at least :min kilobytes.', + 'string' => 'The :attribute must be at least :min characters.', + 'array' => 'The :attribute must have at least :min items.', ], - 'not_in' => 'The selected :attribute is invalid.', - 'not_regex' => 'The :attribute format is invalid.', - 'numeric' => 'The :attribute must be a number.', - 'present' => 'The :attribute field must be present.', - 'regex' => 'The :attribute format is invalid.', - 'required' => 'The :attribute field is required.', - 'required_if' => 'The :attribute field is required when :other is :value.', - 'required_unless' => 'The :attribute field is required unless :other is in :values.', - 'required_with' => 'The :attribute field is required when :values is present.', - 'required_with_all' => 'The :attribute field is required when :values is present.', - 'required_without' => 'The :attribute field is required when :values is not present.', + 'not_in' => 'The selected :attribute is invalid.', + 'not_regex' => 'The :attribute format is invalid.', + 'numeric' => 'The :attribute must be a number.', + 'present' => 'The :attribute field must be present.', + 'regex' => 'The :attribute format is invalid.', + 'required' => 'The :attribute field is required.', + 'required_if' => 'The :attribute field is required when :other is :value.', + 'required_unless' => 'The :attribute field is required unless :other is in :values.', + 'required_with' => 'The :attribute field is required when :values is present.', + 'required_with_all' => 'The :attribute field is required when :values are present.', + 'required_without' => 'The :attribute field is required when :values is not present.', 'required_without_all' => 'The :attribute field is required when none of :values are present.', - 'same' => 'The :attribute and :other must match.', - 'size' => [ + 'same' => 'The :attribute and :other must match.', + 'size' => [ 'numeric' => 'The :attribute must be :size.', - 'file' => 'The :attribute must be :size kilobytes.', - 'string' => 'The :attribute must be :size characters.', - 'array' => 'The :attribute must contain :size items.', + 'file' => 'The :attribute must be :size kilobytes.', + 'string' => 'The :attribute must be :size characters.', + 'array' => 'The :attribute must contain :size items.', ], - 'string' => 'The :attribute must be a string.', - 'timezone' => 'The :attribute must be a valid zone.', - 'unique' => 'The :attribute has already been taken.', - 'uploaded' => 'The :attribute failed to upload.', - 'url' => 'The :attribute format is invalid.', + 'string' => 'The :attribute must be a string.', + 'timezone' => 'The :attribute must be a valid zone.', + 'unique' => 'The :attribute has already been taken.', + 'uploaded' => 'The :attribute failed to upload.', + 'url' => 'The :attribute format is invalid.', + 'uuid' => 'The :attribute must be a valid UUID.', /* |-------------------------------------------------------------------------- @@ -109,9 +135,9 @@ | Custom Validation Attributes |-------------------------------------------------------------------------- | - | The following language lines are used to swap attribute place-holders - | with something more reader friendly such as E-Mail Address instead - | of "email". This simply helps us make messages a little cleaner. + | The following language lines are used to swap our attribute placeholder + | with something more reader friendly such as "E-Mail Address" instead + | of "email". This simply helps us make our message more expressive. | */ diff --git a/resources/assets/sass/_variables.scss b/resources/sass/_variables.scss similarity index 100% rename from resources/assets/sass/_variables.scss rename to resources/sass/_variables.scss diff --git a/resources/assets/sass/app.scss b/resources/sass/app.scss similarity index 100% rename from resources/assets/sass/app.scss rename to resources/sass/app.scss diff --git a/resources/views/auth/verify.blade.php b/resources/views/auth/verify.blade.php new file mode 100644 index 0000000..c742cb4 --- /dev/null +++ b/resources/views/auth/verify.blade.php @@ -0,0 +1,24 @@ +@extends('layouts.app') + +@section('content') +
+
+
+
+
{{ __('Verify Your Email Address') }}
+ +
+ @if (session('resent')) + + @endif + + {{ __('Before proceeding, please check your email for a verification link.') }} + {{ __('If you did not receive the email') }}, {{ __('click here to request another') }}. +
+
+
+
+
+@endsection diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php index 44b7e72..ba35a44 100644 --- a/resources/views/welcome.blade.php +++ b/resources/views/welcome.blade.php @@ -1,8 +1,7 @@ - + - Laravel @@ -52,7 +51,7 @@ .links > a { color: #636b6f; padding: 0 25px; - font-size: 12px; + font-size: 13px; font-weight: 600; letter-spacing: .1rem; text-decoration: none; @@ -72,7 +71,10 @@ Home @else Login - Register + + @if (Route::has('register')) + Register + @endif @endif @endif diff --git a/storage/framework/cache/.gitignore b/storage/framework/cache/.gitignore index d6b7ef3..01e4a6c 100644 --- a/storage/framework/cache/.gitignore +++ b/storage/framework/cache/.gitignore @@ -1,2 +1,3 @@ * +!data/ !.gitignore diff --git a/storage/framework/cache/data/.gitignore b/storage/framework/cache/data/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/cache/data/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/webpack.mix.js b/webpack.mix.js index 3e6f571..19a48fa 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -1,4 +1,4 @@ -const { mix } = require('laravel-mix'); +const mix = require('laravel-mix'); /* |-------------------------------------------------------------------------- @@ -11,5 +11,5 @@ const { mix } = require('laravel-mix'); | */ -mix.js('resources/assets/js/app.js', 'public/js') - .sass('resources/assets/sass/app.scss', 'public/css'); +mix.js('resources/js/app.js', 'public/js') + .sass('resources/sass/app.scss', 'public/css');