From a2358f62398350ac3310a9bb954471d49498bfe3 Mon Sep 17 00:00:00 2001 From: Kovah Date: Wed, 11 Nov 2020 23:08:48 +0100 Subject: [PATCH 01/29] Slight adjustment of the mobile navigation --- resources/views/partials/nav.blade.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/resources/views/partials/nav.blade.php b/resources/views/partials/nav.blade.php index 888f8710..773cf042 100644 --- a/resources/views/partials/nav.blade.php +++ b/resources/views/partials/nav.blade.php @@ -81,22 +81,22 @@ -
+
@lang('link.links')
From 5e79ca71a00e6612cb4fb41cd750fafb06c4f1ab Mon Sep 17 00:00:00 2001 From: Kovah Date: Thu, 12 Nov 2020 21:37:06 +0100 Subject: [PATCH 03/29] Rewording of the Wayback Machine settings --- resources/lang/de_DE/settings.php | 2 +- resources/lang/en_US/settings.php | 4 ++-- resources/lang/zh_CN/settings.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/lang/de_DE/settings.php b/resources/lang/de_DE/settings.php index da7d482e..380394b5 100644 --- a/resources/lang/de_DE/settings.php +++ b/resources/lang/de_DE/settings.php @@ -26,7 +26,7 @@ 'lists_private_default_help' => 'Aktivieren macht alle neuen Listen standardmäßig privat', 'archive_backups' => 'Internet Archive Backups', - 'archive_backups_help' => 'Wenn aktiviert, teilt LinkAce dem Internet Archive mit, den Link zu sichern. Durch die Nutzung des Internet Archive erhalten Benutzer eine kostenlose Off-Site Backup-Lösung für den Inhalt ihrer Lesezeichen. Bitte spenden Sie an das Internet Archive.', + 'archive_backups_help' => 'Wenn aktiviert, teilt LinkAce dem Wayback Machine mit, den Link zu sichern. Die Wayback Machine wird vom Internet Archive betrieben, einer gemeinnützigen Organisation. Bitte spende an das Internet Archive.', 'archive_backups_enabled' => 'Sicherungen aktivieren', 'archive_backups_enabled_help' => 'Wenn aktiviert, werden nicht-private Links vom Internet Archive gespeichert.', 'archive_private_backups_enabled' => 'Sicherungen für private Links aktivieren', diff --git a/resources/lang/en_US/settings.php b/resources/lang/en_US/settings.php index 3a353ee5..d1d4a29a 100644 --- a/resources/lang/en_US/settings.php +++ b/resources/lang/en_US/settings.php @@ -25,8 +25,8 @@ 'lists_private_default' => 'Private Lists by default', 'lists_private_default_help' => 'Enabling this will make all new lists private by default', - 'archive_backups' => 'Internet Archive backups', - 'archive_backups_help' => 'If enabled, LinkAce will tell the Internet Archive to backup the link. By using the Internet Archive, users get a free, off-site backup solution for the content of their bookmarks. Please consider donating to the Internet Archive.', + 'archive_backups' => 'Wayback Machine backups', + 'archive_backups_help' => 'If enabled, LinkAce will tell the Wayback Machine to backup your links. The Wayback Machine is powered by the Internet Archive, a non-profit organization. Please consider donating to the Internet Archive.', 'archive_backups_enabled' => 'Enable backups', 'archive_backups_enabled_help' => 'If enabled, non-private links will be saved by the Internet Archive.', 'archive_private_backups_enabled' => 'Enable backups for private links', diff --git a/resources/lang/zh_CN/settings.php b/resources/lang/zh_CN/settings.php index 44d645e2..684879c0 100644 --- a/resources/lang/zh_CN/settings.php +++ b/resources/lang/zh_CN/settings.php @@ -25,8 +25,8 @@ 'lists_private_default' => '默认私密列表', 'lists_private_default_help' => '启用此选项将默认所有新列表都是私有的', - 'archive_backups' => 'Internet Archive 备份', - 'archive_backups_help' => '如果启用,LinkAce将告诉 Internet Archive 来备份链接。 通过使用 Internet Archive,用户可以获得一个免费的、外部的书签内容备份解决方案。请考虑捐赠给 Internet Archive。', + 'archive_backups' => 'Wayback Machine 备份', + 'archive_backups_help' => '如果启用,LinkAce将告诉 Wayback Machine 备份您的链接。 Wayback Machine由非营利组织Internet Archive提供支持。 请考虑捐赠给Internet Archive 。', 'archive_backups_enabled' => '启用备份', 'archive_backups_enabled_help' => '如果启用,非私人链接将存档在 Internet Archive 中。', 'archive_private_backups_enabled' => '启用私密链接备份', From ce4bb17d64fa89a63af88510e87210654b1d18c0 Mon Sep 17 00:00:00 2001 From: Kovah Date: Fri, 13 Nov 2020 00:36:00 +0100 Subject: [PATCH 04/29] Fix issue with duplicate route names in setup --- resources/views/setup/account.blade.php | 2 +- resources/views/setup/database.blade.php | 2 +- routes/web.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/views/setup/account.blade.php b/resources/views/setup/account.blade.php index 5850ead1..2c51576d 100644 --- a/resources/views/setup/account.blade.php +++ b/resources/views/setup/account.blade.php @@ -15,7 +15,7 @@ @include('partials.alerts') -
+ @csrf
diff --git a/resources/views/setup/database.blade.php b/resources/views/setup/database.blade.php index 8c33d8e0..edf17fda 100644 --- a/resources/views/setup/database.blade.php +++ b/resources/views/setup/database.blade.php @@ -15,7 +15,7 @@ @include('partials.alerts') - + @csrf
diff --git a/routes/web.php b/routes/web.php index 7f42891e..d5cf477d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -38,11 +38,11 @@ Route::get('setup/database', [DatabaseController::class, 'index']) ->name('setup.database'); Route::post('setup/database', [DatabaseController::class, 'configure']) - ->name('setup.database'); + ->name('setup.save-database'); Route::get('setup/account', [AccountController::class, 'index']) ->name('setup.account'); Route::post('setup/account', [AccountController::class, 'register']) - ->name('setup.account'); + ->name('setup.save-account'); Route::get('setup/complete', [MetaController::class, 'complete']) ->name('setup.complete'); From 1f1289a9b505877f86f3c575b071f8e0c6f8b426 Mon Sep 17 00:00:00 2001 From: Kovah Date: Fri, 13 Nov 2020 09:19:17 +0100 Subject: [PATCH 05/29] Fix critical issue with status changes in link histories --- app/Models/Link.php | 4 ++-- app/View/Components/Links/HistoryEntry.php | 20 ++++++++++++++++++++ resources/lang/de_DE/link.php | 3 ++- resources/lang/en_US/link.php | 3 ++- resources/lang/zh_CN/link.php | 3 ++- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/app/Models/Link.php b/app/Models/Link.php index 25a7f4af..fd1d76dd 100644 --- a/app/Models/Link.php +++ b/app/Models/Link.php @@ -232,13 +232,13 @@ public function getIcon(string $additionalClasses = ''): string if ($this->status === self::STATUS_MOVED) { $icon = 'external-link'; $additionalClasses .= ' text-warning'; - $title = trans('link.status.2'); + $title = trans('link.stati.2'); } if ($this->status === self::STATUS_BROKEN) { $icon = 'unlink'; $additionalClasses .= ' text-danger'; - $title = trans('link.status.3'); + $title = trans('link.stati.3'); } if (!view()->exists('components.icon.' . $icon)) { diff --git a/app/View/Components/Links/HistoryEntry.php b/app/View/Components/Links/HistoryEntry.php index 508173b6..beada94f 100644 --- a/app/View/Components/Links/HistoryEntry.php +++ b/app/View/Components/Links/HistoryEntry.php @@ -102,6 +102,10 @@ protected function processValues() return $this->processPrivateField($oldValue, $newValue); } + if ($this->entry->fieldName() === 'status') { + return $this->processStatusField($oldValue, $newValue); + } + return [$this->entry->oldValue(), $this->entry->newValue()]; } @@ -167,6 +171,22 @@ protected function processPrivateField($oldValue, $newValue): array return [$oldValue, $newValue]; } + /** + * The Status field is a mapped constant field, thus needs to be formatted with + * the correct translated values. + * + * @param $oldValue + * @param $newValue + * @return array + */ + protected function processStatusField($oldValue, $newValue): array + { + $oldValue = trans('link.stati.' . $oldValue); + $newValue = trans('link.stati.' . $newValue); + + return [$oldValue, $newValue]; + } + /** * The deleted field displays its own string based on whether the link * was deleted or restored. diff --git a/resources/lang/de_DE/link.php b/resources/lang/de_DE/link.php index 37755a7e..7014397a 100644 --- a/resources/lang/de_DE/link.php +++ b/resources/lang/de_DE/link.php @@ -31,7 +31,8 @@ 'revlists' => 'Listen', 'is_private' => 'Privater Status', - 'status' => [ + 'status' => 'Status', + 'stati' => [ '1' => 'Funktionierend', '2' => 'Verschoben', '3' => 'Kaputt', diff --git a/resources/lang/en_US/link.php b/resources/lang/en_US/link.php index 5e69a7c5..e8c74312 100644 --- a/resources/lang/en_US/link.php +++ b/resources/lang/en_US/link.php @@ -31,7 +31,8 @@ 'revlists' => 'Lists', 'is_private' => 'Private Status', - 'status' => [ + 'status' => 'Status', + 'stati' => [ '1' => 'Working', '2' => 'Moved', '3' => 'Broken', diff --git a/resources/lang/zh_CN/link.php b/resources/lang/zh_CN/link.php index 1d1a8ba9..5230befa 100644 --- a/resources/lang/zh_CN/link.php +++ b/resources/lang/zh_CN/link.php @@ -31,7 +31,8 @@ 'revlists' => '列表', 'is_private' => '隐私状态', - 'status' => [ + 'status' => '状态', + 'stati' => [ '1' => '运行中', '2' => '移动', '3' => '已失效', From 3e5a8780b510b522d1f82cb405c7a9802e3a9d17 Mon Sep 17 00:00:00 2001 From: Kovah Date: Fri, 13 Nov 2020 09:25:54 +0100 Subject: [PATCH 06/29] Increase timeout for link checks to 10 seconds to account for slow networks and servers --- app/Console/Commands/CheckLinksCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Commands/CheckLinksCommand.php b/app/Console/Commands/CheckLinksCommand.php index c1556055..fa091a33 100644 --- a/app/Console/Commands/CheckLinksCommand.php +++ b/app/Console/Commands/CheckLinksCommand.php @@ -138,7 +138,7 @@ protected function checkLink(Link $link): void $this->output->write('Checking link ' . $link->url . ' '); try { - $response = Http::timeout(5)->get($link->url); + $response = Http::timeout(10)->get($link->url); $statusCode = $response->status(); } catch (\Exception $e) { // Set status code to null so the link will be marked as broken From c584ab4b6405fbcfc7f68f2e8f15f3b704254bda Mon Sep 17 00:00:00 2001 From: Kovah Date: Fri, 13 Nov 2020 13:40:06 +0100 Subject: [PATCH 07/29] Add a console command to purge history entries with and without offset, also always display the history, even if there is only the initial creation available --- .../Commands/CleanupLinkHistoriesCommand.php | 60 +++++++++++++++++++ app/Console/Kernel.php | 2 + resources/views/models/links/show.blade.php | 38 ++++++------ 3 files changed, 80 insertions(+), 20 deletions(-) create mode 100644 app/Console/Commands/CleanupLinkHistoriesCommand.php diff --git a/app/Console/Commands/CleanupLinkHistoriesCommand.php b/app/Console/Commands/CleanupLinkHistoriesCommand.php new file mode 100644 index 00000000..10ff255f --- /dev/null +++ b/app/Console/Commands/CleanupLinkHistoriesCommand.php @@ -0,0 +1,60 @@ +argument('field')) { + $baseQuery->where('key', $this->argument('field')); + } + + $count = $baseQuery->count(); + + if ($count === 0) { + $this->warn(sprintf('No history entries%s found!', ($this->argument('field') ? ' for this field ' : ''))); + return; + } + + $linkCount = $baseQuery->groupBy('revisionable_id')->get('revisionable_id')->count(); + + $this->info(" Found $count entries across $linkCount links."); + + if (!$this->confirm('Are you sure you want to remove these history entries?')) { + return; + } + + $this->offset = (int)$this->ask('How many history entries should be kept?', 5); + + $bar = $this->output->createProgressBar($linkCount); + $bar->start(); + + Link::withTrashed()->has('revisionHistory')->each(function (Link $link) use ($bar) { + $historyEntries = $link->revisionHistory()->orderBy('created_at', 'desc') + ->skip($this->offset)->take(9999999) + ->pluck('id'); + + Revision::whereIn('id', $historyEntries)->delete(); + $bar->advance(); + }); + + $bar->finish(); + $this->line(''); + + $this->info(" Successfully deleted $count entries."); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index d6102669..35f2f159 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -3,6 +3,7 @@ namespace App\Console; use App\Console\Commands\CheckLinksCommand; +use App\Console\Commands\CleanupLinkHistoriesCommand; use App\Console\Commands\RegisterUserCommand; use App\Console\Commands\ResetPasswordCommand; use Illuminate\Console\Scheduling\Schedule; @@ -24,6 +25,7 @@ class Kernel extends ConsoleKernel RegisterUserCommand::class, CheckLinksCommand::class, ResetPasswordCommand::class, + CleanupLinkHistoriesCommand::class, ]; /** diff --git a/resources/views/models/links/show.blade.php b/resources/views/models/links/show.blade.php index 5c44c40d..b2f5224f 100644 --- a/resources/views/models/links/show.blade.php +++ b/resources/views/models/links/show.blade.php @@ -146,27 +146,25 @@ class="mb-4 d-flex align-items-center">
- @if(count($history) > 0) - + +
+
+ +@endsection diff --git a/resources/views/auth/passwords/reset.blade.php b/resources/views/auth/passwords/reset.blade.php index 77204168..154d60b6 100644 --- a/resources/views/auth/passwords/reset.blade.php +++ b/resources/views/auth/passwords/reset.blade.php @@ -11,11 +11,13 @@
-
@csrf - + {{ implode('|',$errors->all()) }} + +
diff --git a/routes/web.php b/routes/web.php index eb878b5e..16477a9e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -46,24 +46,6 @@ Route::get('setup/complete', [MetaController::class, 'complete']) ->name('setup.complete'); -// Authentication Routes -Route::get('login', [LoginController::class, 'showLoginForm'])->name('login'); -Route::post('login', [LoginController::class, 'login']); -Route::post('logout', [LoginController::class, 'logout'])->name('logout'); - -// Registration Routes (disabled, use the `artisan registeruser` command) -//Route::get('register', 'Auth\RegisterController@showRegistrationForm')->name('register'); -//Route::post('register', 'Auth\RegisterController@register'); - -// Password Reset Routes -Route::get('password/reset', [ForgotPasswordController::class, 'showLinkRequestForm']) - ->name('password.request'); -Route::post('password/email', [ForgotPasswordController::class, 'sendResetLinkEmail']) - ->name('password.email'); -Route::get('password/reset/{token}', [ResetPasswordController::class, 'showResetForm']) - ->name('password.reset'); -Route::post('password/reset', [ResetPasswordController::class, 'reset']); - // Bookmarklet routes Route::prefix('bookmarklet')->group(function () { Route::get('add', [BookmarkletController::class, 'getLinkAddForm'])->name('bookmarklet-add'); diff --git a/tests/Controller/App/UserSettingsControllerTest.php b/tests/Controller/App/UserSettingsControllerTest.php index 11e6c874..bb681372 100644 --- a/tests/Controller/App/UserSettingsControllerTest.php +++ b/tests/Controller/App/UserSettingsControllerTest.php @@ -85,9 +85,9 @@ public function testValidUpdateApplicationSettingsResponse(): void public function testValidUpdatePasswordResponse(): void { $response = $this->post('settings/change-password', [ - 'old_password' => 'secretpassword', - 'new_password' => 'newuserpassword', - 'new_password_confirmation' => 'newuserpassword', + 'current_password' => 'secretpassword', + 'password' => 'newuserpassword', + 'password_confirmation' => 'newuserpassword', ]); $response->assertRedirect('/'); From 2986354a944b487b3c253be7419d4b5ab0a2e19b Mon Sep 17 00:00:00 2001 From: Kovah Date: Mon, 16 Nov 2020 23:17:20 +0100 Subject: [PATCH 12/29] Add two factor authentication (#172 #111) --- app/Http/Kernel.php | 1 + app/Models/User.php | 7 +- app/Providers/FortifyServiceProvider.php | 2 +- resources/lang/en_US/auth.php | 4 + resources/lang/en_US/placeholder.php | 3 + resources/lang/en_US/settings.php | 9 +++ .../partials/user/change-pw.blade.php | 2 +- .../partials/user/two-factor.blade.php | 69 ++++++++++++++++ .../views/actions/settings/user.blade.php | 2 + .../views/auth/confirm-password.blade.php | 6 +- .../views/auth/two-factor-challenge.blade.php | 81 +++++++++++++++++++ .../views/components/icon/shield.blade.php | 1 + 12 files changed, 177 insertions(+), 10 deletions(-) create mode 100644 resources/views/actions/settings/partials/user/two-factor.blade.php create mode 100644 resources/views/auth/two-factor-challenge.blade.php create mode 100644 resources/views/components/icon/shield.blade.php diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index a05d3795..a8db75f0 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -60,6 +60,7 @@ class Kernel extends HttpKernel 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'guestaccess' => \App\Http\Middleware\GuestAccess::class, + 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, ]; diff --git a/app/Models/User.php b/app/Models/User.php index e104cdb2..dc18ef56 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -3,13 +3,11 @@ namespace App\Models; use Carbon\Carbon; -use Illuminate\Contracts\Validation\Validator as ValidatorContract; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; -use Illuminate\Support\Facades\Hash; -use Illuminate\Support\Facades\Validator; +use Laravel\Fortify\TwoFactorAuthenticatable; /** * Class User @@ -21,6 +19,8 @@ * @property string $password * @property string|null $remember_token * @property string|null $api_token + * @property string|null $two_factor_recovery_codes + * @property string|null $two_factor_secret * @property Carbon|null $created_at * @property Carbon|null $updated_at */ @@ -28,6 +28,7 @@ class User extends Authenticatable { use Notifiable; use HasFactory; + use TwoFactorAuthenticatable; protected $fillable = [ 'name', diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php index 5dc70aad..14e5cfb9 100644 --- a/app/Providers/FortifyServiceProvider.php +++ b/app/Providers/FortifyServiceProvider.php @@ -50,7 +50,7 @@ public function boot() }); Fortify::twoFactorChallengeView(function () { - return view(); // @TODO + return view('auth.two-factor-challenge'); }); } } diff --git a/resources/lang/en_US/auth.php b/resources/lang/en_US/auth.php index 8893d2e0..b857b035 100644 --- a/resources/lang/en_US/auth.php +++ b/resources/lang/en_US/auth.php @@ -20,4 +20,8 @@ 'confirm' => 'Please confirm this action using your current password.', 'confirm_action' => 'Confirm action', + 'two_factor' => 'Two Factor Authentication', + 'two_factor_check' => 'Please enter the one-time-password provided by your Two Factor Authentication app now.', + 'two_factor_with_recovery' => 'Authenticate with Recovery Code', + ]; diff --git a/resources/lang/en_US/placeholder.php b/resources/lang/en_US/placeholder.php index 342fb2e8..1dae9372 100644 --- a/resources/lang/en_US/placeholder.php +++ b/resources/lang/en_US/placeholder.php @@ -14,4 +14,7 @@ 'list_name' => 'Actual name of the list', 'tag_name' => 'Actual name of the tag', + 'two_factor_otp' => 'One Time Password', + 'two_factor_recovery_code' => 'Backup Code', + ]; diff --git a/resources/lang/en_US/settings.php b/resources/lang/en_US/settings.php index d1d4a29a..213defba 100644 --- a/resources/lang/en_US/settings.php +++ b/resources/lang/en_US/settings.php @@ -61,6 +61,15 @@ 'password_updated' => 'Password changed successfully!', 'old_password_invalid' => 'The old password is not valid!', + 'two_factor_auth' => 'Two Factor Authentication', + 'two_factor_enable' => 'Enable Two Factor Authentication', + 'two_factor_disable' => 'Disable Two Factor Authentication', + 'two_factor_setup_app' => 'Two factor authentication is enabled. Please configure your authentication device now by scanning the following QR code.', + 'two_factor_setup_url' => 'QR code not working? You may also use this URL directly.', + 'two_factor_recovery_codes' => 'Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost.', + 'two_factor_recovery_codes_view' => 'View Recovery Codes', + 'two_factor_regenerate_recovery_codes' => 'Generate new Recovery Codes', + 'api_token' => 'API Token', 'api_token_generate' => 'Generate Token', 'api_token_generate_confirm' => 'Do you really want to generate a new token?', diff --git a/resources/views/actions/settings/partials/user/change-pw.blade.php b/resources/views/actions/settings/partials/user/change-pw.blade.php index 0aeed535..5e357755 100644 --- a/resources/views/actions/settings/partials/user/change-pw.blade.php +++ b/resources/views/actions/settings/partials/user/change-pw.blade.php @@ -1,5 +1,5 @@ @if(!env('APP_DEMO', false)) -
+
@lang('settings.change_password')
diff --git a/resources/views/actions/settings/partials/user/two-factor.blade.php b/resources/views/actions/settings/partials/user/two-factor.blade.php new file mode 100644 index 00000000..656cc58d --- /dev/null +++ b/resources/views/actions/settings/partials/user/two-factor.blade.php @@ -0,0 +1,69 @@ +@if(!env('APP_DEMO', false)) +
+
+ @lang('settings.two_factor_auth') +
+
+ + @if(!$user->two_factor_secret) + + @csrf + + + + + @else + +
+ @csrf + @method('DELETE') + + + +
+ + @if(session('status') === 'two-factor-authentication-enabled') + +

@lang('settings.two_factor_setup_app')

+ +
+ {!! $user->twoFactorQrCodeSvg() !!} +
+ +
+ @lang('settings.two_factor_setup_url') + {{ $user->twoFactorQrCodeUrl() }} +
+ + @endif + +
@lang('settings.two_factor_recovery_codes')
+ +
+
+
+ @lang('settings.two_factor_recovery_codes_view') + @foreach (json_decode(decrypt($user->two_factor_recovery_codes), true) as $code) + {{ $code }}
+ @endforeach +
+
+ +
+
+ @csrf + +
+
+
+ @endif + +
+
+@endif diff --git a/resources/views/actions/settings/user.blade.php b/resources/views/actions/settings/user.blade.php index 8fa013e5..889f8e62 100644 --- a/resources/views/actions/settings/user.blade.php +++ b/resources/views/actions/settings/user.blade.php @@ -10,6 +10,8 @@ @include('actions.settings.partials.user.change-pw') + @include('actions.settings.partials.user.two-factor') + @include('actions.settings.partials.user.app-settings') @endsection diff --git a/resources/views/auth/confirm-password.blade.php b/resources/views/auth/confirm-password.blade.php index 8ae26cb9..67d6bd67 100644 --- a/resources/views/auth/confirm-password.blade.php +++ b/resources/views/auth/confirm-password.blade.php @@ -5,10 +5,6 @@
- @if(env('APP_DEMO', false)) -
@lang('linkace.demo_login_hint')
- @endif -
@lang('auth.confirm_title') @@ -39,7 +35,7 @@
diff --git a/resources/views/auth/two-factor-challenge.blade.php b/resources/views/auth/two-factor-challenge.blade.php new file mode 100644 index 00000000..06e4d329 --- /dev/null +++ b/resources/views/auth/two-factor-challenge.blade.php @@ -0,0 +1,81 @@ +@extends('layouts.app') + +@section('content') + +
+
+ +
+
+ @lang('auth.two_factor') +
+
+ +

@lang('auth.two_factor_check')

+ +
+ @csrf + +
+
+
+
+ +
+
+ +
+ + @if ($errors->has('code')) + + @endif +
+ +
+ +
+ + + +
+
+
+
+
+ +
+
+ +
+ + @if ($errors->has('code')) + + @endif +
+
+ +
+ +
+
+ +
+
+ +@endsection diff --git a/resources/views/components/icon/shield.blade.php b/resources/views/components/icon/shield.blade.php new file mode 100644 index 00000000..11849595 --- /dev/null +++ b/resources/views/components/icon/shield.blade.php @@ -0,0 +1 @@ +merge(['class' => 'icon', 'viewBox' =>'0 0 512 512', 'xmlns' =>'http://www.w3.org/2000/svg']) }}> From 090acf0245e16623a984d9df787eb7f6049f80a6 Mon Sep 17 00:00:00 2001 From: Kovah Date: Mon, 16 Nov 2020 23:36:35 +0100 Subject: [PATCH 13/29] Update readme and issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 9 +++- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- README.md | 53 +++++++++-------------- 3 files changed, 28 insertions(+), 36 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 85f1302e..f6a5994e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -23,12 +23,17 @@ A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. -**Desktop (please complete the following information):** +**LinkAce setup (please complete the following information):** + - Version: [e.g. 0.0.43] + - Installed via: [e.g. PHP, Docker] + - OS: [e.g. Ubuntu, CentOS] + +**Desktop (please complete the following information if applicable):** - OS: [e.g. iOS] - Browser [e.g. chrome, safari] - Version [e.g. 22] -**Smartphone (please complete the following information):** +**Smartphone (please complete the following information if applicable):** - Device: [e.g. iPhone6] - OS: [e.g. iOS8.1] - Browser [e.g. stock browser, safari] diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 59feed3d..9843a1d8 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request about: Suggest an idea for this project title: '' -labels: New Feature +labels: Enhancement assignees: '' --- diff --git a/README.md b/README.md index 8a9aebfb..26f99e91 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,7 @@

 

-

Your selfhosted bookmark archive with a simple interface and advanced features.

-

:warning: This application is still in development! :warning:

+

Your self-hosted bookmark archive. Free and open source.

Follow LinkAce on Twitter @@ -33,31 +32,28 @@ ![Preview Screenshot](https://www.linkace.org/images/preview/linkace_dashboard.png) -LinkAce is a bookmark manager similar to Shaarli and other tools. I built this tool to have something that fits my -actual needs which other bookmark managers couldn't solve, even if most features are almost the same. +LinkAce is a bookmark manager similar to Shaarli and other tools. See this tool as a long-term archive for sites you want to remember, but don't access frequently. I built this tool to have something that fits my actual needs which other bookmark managers couldn't solve, even if some features look almost the same. -#### Features +#### Feature Highlights * Save links with automatic title and description generation. -* Automated link checks to make sure your bookmarks stay available. -* Automated “backups” of your bookmarks via the Waybackmachine. -* Organize bookmarks in lists and tags. +* Automated link checks inform you when any links become unavailable or were moved. +* Automated “backups” of saved sites via the [Waybackmachine](https://web.archive.org/). +* Organize bookmarks with lists and tags. +* A full REST API offers access to all features of LinkAce from third-party apps and services. * A bookmarklet to quickly save links from any browser. -* Private or public links, so friends or internet strangers can see your collection. -* Add notes to links to add thoughts or other information. -* Advanced search including different filters and ordering. -* Import existing bookmarks from HTML exports (other methods planned). -* Support for complete database and app backups to Amazon AWS S3. +* Links can be private or public, so friends or internet strangers may see your collection. +* Add notes to links to add thoughts or other relevant information. +* An advanced search including different filters and ordering. +* Import and export of bookmarks from HTML. +* Support for complete database and application backups to Amazon AWS S3. * A built-in light and dark color scheme. -More features are already planned. Take a look at the [project board](https://github.com/Kovah/LinkAce/projects/1) -for more information. +More features are already planned. Take a look at the [project board](https://github.com/Kovah/LinkAce/projects/1) for more information. #### Documentation and Community -Any further information about all the available features and how to install the app, can be found on the -[LinkAce Website](https://www.linkace.org/). Additionally, you may visit the [community forums](https://spectrum.chat/linkace/) -to share your ideas, talk with other users or find help for specific problems. +Any further information about all the available features and how to install the app, can be found on the [LinkAce Website](https://www.linkace.org/). Additionally, you may visit the [community forums](https://spectrum.chat/linkace/) to share your ideas, talk with other users or find help for specific problems. --- @@ -65,13 +61,9 @@ to share your ideas, talk with other users or find help for specific problems. ### :bulb: Support for LinkAce -Free support is highly limited for all my free tools, including LinkAce. If you need help please visit the -[community forum](https://spectrum.chat/linkace/) and post your issue there. I do not offer free personal -support via chat or email. -Please notice that LinkAce has specific requirements to run correctly. +I built LinkAce to solve my problem, and I now offer my solution and code to your without charging anything. Thus I won't offer any free personal support, customization or installation help. If you need help please visit the [community forum](https://spectrum.chat/linkace/) and post your issue there. -If you need prioritized support you can **become a [Patreon](https://www.patreon.com/Kovah)** -or **[Github Sponsor](https://github.com/sponsors/Kovah)**. :star: +You can get personal and dedicated support by **becoming a [Patreon](https://www.patreon.com/Kovah)** or **[Github Sponsor](https://github.com/sponsors/Kovah)**. :star: --- @@ -79,8 +71,7 @@ or **[Github Sponsor](https://github.com/sponsors/Kovah)**. :star: ### :gear: Setup -LinkAce provides multiple ways of installing it on your server. The complete documentation for all installation -methods can be found [**in the wiki**](https://www.linkace.org/docs/v1/setup/). +LinkAce provides multiple ways of installing it on your server. The complete documentation for all installation methods can be found [**in the wiki**](https://www.linkace.org/docs/v1/setup/). * Setup with Docker (_recommended_) * Simple setup with 1 Docker image @@ -105,9 +96,7 @@ Please review the [**contribution guidelines**](CONTRIBUTING.md) before starting #### 1. Basic Setup -The following steps assume that you are using Docker for development, which I highly encourage. If you use -other ways to work with PHP projects you must adapt the commands to your system. -Clone the repository to your machine and run the following commands to start the Docker container system: +The following steps assume that you are using Docker for development, which I highly encourage. If you use other ways to work with PHP projects you must adapt the commands to your system. Clone the repository to your machine and run the following commands to start the Docker container system: ```bash cp .env.docker .env @@ -120,8 +109,7 @@ Now, install all dependencies from inside the PHP container: docker exec linkace-php bash -c "composer install" ``` -Last step: compile all assets. Node 10 LTS is the minimum version required and recommended to use. -You may use either NPM or Yarn for installing the asset dependencies. +Last step: compile all assets. Node 10 LTS is the minimum version required and recommended to use. You may use either NPM or Yarn for installing the asset dependencies. ```bash npm install @@ -133,8 +121,7 @@ npm run dev #### 2. Working with the Artisan command line -I recommend using the Artisan command line tool in the PHP container only, to make sure that the same environment is -used. To do so, use the following example command: +I recommend using the Artisan command line tool in the PHP container only, to make sure that the same environment is used. To do so, use the following example command: ```bash docker exec linkace-php bash -c "php artisan migrate" From 7a7693b028bc91cb3a330308a7a4ea108a015014 Mon Sep 17 00:00:00 2001 From: Kovah Date: Tue, 17 Nov 2020 00:03:39 +0100 Subject: [PATCH 14/29] Update readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 26f99e91..3016fc1c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ Docker Repository Latest Release License - Translations

 

@@ -84,6 +83,8 @@ LinkAce provides multiple ways of installing it on your server. The complete doc ### :construction: Contribution +[![Translations](https://img.shields.io/badge/Translations-Crowdin-2b303d)](https://crowdin.com/project/linkace) [![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/Kovah/LinkAce) ![Code Climate coverage](https://img.shields.io/codeclimate/coverage/Kovah/LinkAce)](https://codeclimate.com/github/Kovah/LinkAce) [![GitHub Build Status](https://img.shields.io/github/workflow/status/Kovah/LinkAce/Testing/dev?label=Dev%20Build)](https://github.com/Kovah/LinkAce/actions?query=workflow%3ATesting+branch%3Adev) + Please review the [**contribution guidelines**](CONTRIBUTING.md) before starting to work on any features. From b1dea309e39a0c078222350fe9498018249913c9 Mon Sep 17 00:00:00 2001 From: Kovah Date: Tue, 17 Nov 2020 00:47:01 +0100 Subject: [PATCH 15/29] Disable user registration and add some authentication tests for Fortify --- config/fortify.php | 2 +- tests/Controller/Auth/LoginControllerTest.php | 9 +++ tests/Controller/Auth/TwoFactorTest.php | 62 +++++++++++++++++++ .../Auth/VariousAuthenticationTest.php | 21 +++++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 tests/Controller/Auth/TwoFactorTest.php create mode 100644 tests/Controller/Auth/VariousAuthenticationTest.php diff --git a/config/fortify.php b/config/fortify.php index f8c0e1f5..5ec37723 100644 --- a/config/fortify.php +++ b/config/fortify.php @@ -131,7 +131,7 @@ */ 'features' => [ - Features::registration(), + //Features::registration(), Features::resetPasswords(), // Features::emailVerification(), Features::updateProfileInformation(), diff --git a/tests/Controller/Auth/LoginControllerTest.php b/tests/Controller/Auth/LoginControllerTest.php index f5f8ae39..d1091c08 100644 --- a/tests/Controller/Auth/LoginControllerTest.php +++ b/tests/Controller/Auth/LoginControllerTest.php @@ -4,6 +4,7 @@ use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; +use PragmaRX\Google2FA\Google2FA; use Tests\TestCase; class LoginControllerTest extends TestCase @@ -51,4 +52,12 @@ public function testInvalidLoginSubmit(): void $response->assertSessionHasErrors(['email']); } + + public function testConfirmPasswordView(): void + { + $user = User::factory()->create(); + + $confirmView = $this->actingAs($user)->get('user/confirm-password'); + $confirmView->assertSee('Confirmation required'); + } } diff --git a/tests/Controller/Auth/TwoFactorTest.php b/tests/Controller/Auth/TwoFactorTest.php new file mode 100644 index 00000000..909eefbf --- /dev/null +++ b/tests/Controller/Auth/TwoFactorTest.php @@ -0,0 +1,62 @@ +generateSecretKey(); + + $user = User::factory()->create([ + 'two_factor_secret' => encrypt($secretKey), + ]); + + $response = $this->post('login', [ + 'email' => $user->email, + 'password' => 'secretpassword', + ]); + + $response->assertRedirect('two-factor-challenge'); + + $otpView = $this->get('two-factor-challenge'); + $otpView->assertSee('Two Factor Authentication'); + + $otp = (new Google2FA)->getCurrentOtp($secretKey); + + $otpResponse = $this->post('two-factor-challenge', [ + 'code' => $otp, + ]); + + $otpResponse->assertRedirect('dashboard'); + } + + public function testInvalidLoginWith2FA(): void + { + $secretKey = (new Google2FA)->generateSecretKey(); + + $user = User::factory()->create([ + 'two_factor_secret' => encrypt($secretKey), + ]); + + $response = $this->post('login', [ + 'email' => $user->email, + 'password' => 'secretpassword', + ]); + + $response->assertRedirect('two-factor-challenge'); + + $otpResponse = $this->post('two-factor-challenge', [ + 'code' => '123456789', + ]); + + $otpResponse->assertRedirect('login'); + } +} diff --git a/tests/Controller/Auth/VariousAuthenticationTest.php b/tests/Controller/Auth/VariousAuthenticationTest.php new file mode 100644 index 00000000..d9904851 --- /dev/null +++ b/tests/Controller/Auth/VariousAuthenticationTest.php @@ -0,0 +1,21 @@ +create(); + + $confirmView = $this->actingAs($user)->get('user/confirm-password'); + $confirmView->assertSee('Confirmation required'); + } +} From 55bea8411204b5ad777a45d934a67ef07313417b Mon Sep 17 00:00:00 2001 From: Kovah Date: Tue, 17 Nov 2020 12:22:41 +0100 Subject: [PATCH 16/29] Add tests for password resets and sharing helper --- .../views/auth/passwords/reset.blade.php | 2 - .../links/partials/share-link.blade.php | 2 +- tests/Controller/Auth/PasswordResetTest.php | 75 +++++++++++++++++++ tests/Helper/HelperFunctionsTest.php | 6 +- tests/Helper/SharingTest.php | 50 +++++++++++++ 5 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 tests/Controller/Auth/PasswordResetTest.php create mode 100644 tests/Helper/SharingTest.php diff --git a/resources/views/auth/passwords/reset.blade.php b/resources/views/auth/passwords/reset.blade.php index 154d60b6..48f47b8f 100644 --- a/resources/views/auth/passwords/reset.blade.php +++ b/resources/views/auth/passwords/reset.blade.php @@ -15,8 +15,6 @@ aria-label="@lang('linkace.reset_password')"> @csrf - {{ implode('|',$errors->all()) }} -
diff --git a/resources/views/models/links/partials/share-link.blade.php b/resources/views/models/links/partials/share-link.blade.php index c81cdabc..5e08d960 100644 --- a/resources/views/models/links/partials/share-link.blade.php +++ b/resources/views/models/links/partials/share-link.blade.php @@ -1,3 +1,3 @@ - + diff --git a/tests/Controller/Auth/PasswordResetTest.php b/tests/Controller/Auth/PasswordResetTest.php new file mode 100644 index 00000000..faa2cdd3 --- /dev/null +++ b/tests/Controller/Auth/PasswordResetTest.php @@ -0,0 +1,75 @@ +get('forgot-password'); + $confirmView->assertSee('forgot-password'); + } + + public function testForgotPasswordRequest(): void + { + Notification::fake(); + + $user = User::factory()->create([ + 'email' => 'reset@linkace.org', + ]); + + $response = $this->post('forgot-password', [ + 'email' => 'reset@linkace.org', + ]); + + $response->assertSessionHas('status'); + + Notification::assertSentTo($user, ResetPassword::class); + } + + public function testPasswordResetView(): void + { + $user = User::factory()->create([ + 'email' => 'reset@linkace.org', + ]); + + $token = app('auth.password.broker')->createToken($user); + + $confirmView = $this->get('reset-password/' . $token); + $confirmView->assertSee('reset-password'); + } + + public function testPasswordResetRequest(): void + { + $user = User::factory()->create([ + 'email' => 'reset@linkace.org', + ]); + + $token = app('auth.password.broker')->createToken($user); + + $confirmView = $this->post('reset-password/', [ + 'token' => $token, + 'email' => 'reset@linkace.org', + 'password' => 'newPassword', + 'password_confirmation' => 'newPassword', + ]); + + $confirmView->assertRedirect('login'); + + $loginAttempt = Auth::attempt([ + 'email' => 'reset@linkace.org', + 'password' => 'newPassword', + ]); + + self::assertTrue($loginAttempt); + } +} diff --git a/tests/Helper/HelperFunctionsTest.php b/tests/Helper/HelperFunctionsTest.php index 70231f7b..26ebe14e 100644 --- a/tests/Helper/HelperFunctionsTest.php +++ b/tests/Helper/HelperFunctionsTest.php @@ -4,15 +4,13 @@ use App\Models\Link; use App\Models\User; -use Illuminate\Foundation\Testing\DatabaseMigrations; -use Illuminate\Foundation\Testing\DatabaseTransactions; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Storage; use Tests\TestCase; class HelperFunctionsTest extends TestCase { - use DatabaseMigrations; - use DatabaseTransactions; + use RefreshDatabase; /** @var User */ private $user; diff --git a/tests/Helper/SharingTest.php b/tests/Helper/SharingTest.php new file mode 100644 index 00000000..5a12a656 --- /dev/null +++ b/tests/Helper/SharingTest.php @@ -0,0 +1,50 @@ + 'mailto:?subject=Example%20Website&body=I%20found%20this%20awesome%20link%2C%20go%20check%20it%20out%3A%20https%3A%2F%2Fexample.com%2F"', + 'facebook' => 'https://www.facebook.com/sharer/sharer.php?u=https://example.com/', + 'twitter' => 'https://twitter.com/intent/tweet?text=I found this awesome link, go check it out: https://example.com/', + 'reddit' => 'http://www.reddit.com/submit?url=https://example.com/&title=Example Website', + 'pinterest' => 'http://pinterest.com/pin/create/button/?url=https://example.com/&description=Example Website', + 'whatsapp' => 'whatsapp://send?text=I found this awesome link, go check it out: https://example.com/', + 'telegram' => 'tg://msg?text==I found this awesome link, go check it out: https://example.com/', + 'wechat' => 'https://www.addtoany.com/ext/wechat/share/#url=https://example.com/', + 'sms' => 'sms:?&body=I found this awesome link, go check it out: https://example.com/', + 'skype' => 'https://web.skype.com/share?url=https%3A%2F%2Fexample.com%2F', + 'hackernews' => 'https://news.ycombinator.com/submitlink?u=https://example.com/&t=Example Website', + 'mastodon' => 'web+mastodon://share?text=I%20found%20this%20awesome%20link%2C%20go%20check%20it%20out%3A%20https%3A%2F%2Fexample.com%2F', + 'pocket' => 'https://getpocket.com/save?url=https://example.com/', + 'flipboard' => 'https://share.flipboard.com/bookmarklet/popout?v=Example Website&url=https%3A%2F%2Fexample.com%2F', + 'evernote' => 'https://www.evernote.com/clip.action?url=https%3A%2F%2Fexample.com%2F&title=Example Website', + 'trello' => 'https://trello.com/add-card?mode=popup&url=https%3A%2F%2Fexample.com%2F&name=Example%20Website&desc=', + 'buffer' => 'https://buffer.com/add?url=https%3A%2F%2Fexample.com%2F&text=Example%20Website', + 'tumblr' => 'http://tumblr.com/share/link?url=https://example.com/&name=Example Website', + 'xing' => 'https://www.xing.com/spi/shares/new?url=https://example.com/', + 'linkedin' => 'https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fexample.com%2F&title=Example%20Website&summary=&source=AddToAny', + ]; + + public function testCorrectShareLinkForServices(): void + { + $testLink = Link::factory()->create([ + 'url' => 'https://example.com/', + 'title' => 'Example Website', + ]); + + foreach (self::$shareData as $service => $expectedLink) { + $shareLink = Sharing::getShareLink($service, $testLink); + + self::assertStringContainsString($expectedLink, $shareLink); + } + } +} From 8debf3c56e1a3c4a43c7ba44955602c73cfa970d Mon Sep 17 00:00:00 2001 From: Kovah Date: Tue, 17 Nov 2020 17:12:27 +0100 Subject: [PATCH 17/29] Remove the custom DynamicComponent class --- app/View/Components/DynamicComponent.php | 35 ------------------------ 1 file changed, 35 deletions(-) delete mode 100644 app/View/Components/DynamicComponent.php diff --git a/app/View/Components/DynamicComponent.php b/app/View/Components/DynamicComponent.php deleted file mode 100644 index fcbf5f35..00000000 --- a/app/View/Components/DynamicComponent.php +++ /dev/null @@ -1,35 +0,0 @@ -component = $component; - } - - /** - * Get the view / contents that represent the component. - * - * @return View|string - */ - public function render() - { - if (!view()->exists('components.' . $this->component)) { - return ""; - } - - return view('components.' . $this->component, ['attributes' => $this->attributes]); - } -} From 97ec9eb5a5bbd9c1e913396cebd43b3925ed82a4 Mon Sep 17 00:00:00 2001 From: Kovah Date: Tue, 17 Nov 2020 17:21:43 +0100 Subject: [PATCH 18/29] Simplify model controllers by using route model binding, remove delete requests --- .../Controllers/Models/LinkController.php | 43 +++++++------------ .../Controllers/Models/ListController.php | 34 ++++++--------- .../Controllers/Models/NoteController.php | 25 ++++------- app/Http/Controllers/Models/TagController.php | 35 ++++++--------- .../Requests/Models/LinkDeleteRequest.php | 33 -------------- .../Requests/Models/ListDeleteRequest.php | 35 --------------- .../Requests/Models/NoteDeleteRequest.php | 35 --------------- app/Http/Requests/Models/TagDeleteRequest.php | 35 --------------- 8 files changed, 49 insertions(+), 226 deletions(-) delete mode 100644 app/Http/Requests/Models/LinkDeleteRequest.php delete mode 100644 app/Http/Requests/Models/ListDeleteRequest.php delete mode 100644 app/Http/Requests/Models/NoteDeleteRequest.php delete mode 100644 app/Http/Requests/Models/TagDeleteRequest.php diff --git a/app/Http/Controllers/Models/LinkController.php b/app/Http/Controllers/Models/LinkController.php index 84fce969..cf2ec2f9 100644 --- a/app/Http/Controllers/Models/LinkController.php +++ b/app/Http/Controllers/Models/LinkController.php @@ -3,16 +3,15 @@ namespace App\Http\Controllers\Models; use App\Http\Controllers\Controller; -use App\Http\Requests\Models\LinkDeleteRequest; use App\Http\Requests\Models\LinkStoreRequest; use App\Http\Requests\Models\LinkToggleCheckRequest; use App\Http\Requests\Models\LinkUpdateRequest; use App\Models\Link; use App\Repositories\LinkRepository; use Exception; +use Illuminate\Contracts\View\View; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\View\View; class LinkController extends Controller { @@ -94,13 +93,11 @@ public function store(LinkStoreRequest $request): RedirectResponse /** * Display the specified resource. * - * @param int $id + * @param Link $link * @return View */ - public function show($id): View + public function show(Link $link): View { - $link = Link::findOrFail($id); - return view('models.links.show', [ 'link' => $link, 'history' => $link->revisionHistory()->latest()->get(), @@ -110,28 +107,25 @@ public function show($id): View /** * Show the form for editing the specified resource. * - * @param int $id + * @param Link $link * @return View */ - public function edit($id): View + public function edit(Link $link): View { - $link = Link::findOrFail($id); - - return view('models.links.edit') - ->with('link', $link); + return view('models.links.edit', [ + 'link' => $link, + ]); } /** * Update the specified resource in storage. * * @param LinkUpdateRequest $request - * @param int $id + * @param Link $link * @return RedirectResponse */ - public function update(LinkUpdateRequest $request, $id): RedirectResponse + public function update(LinkUpdateRequest $request, Link $link): RedirectResponse { - $link = Link::findOrFail($id); - $link = LinkRepository::update($link, $request->all()); flash(trans('link.updated_successfully'), 'success'); @@ -141,18 +135,15 @@ public function update(LinkUpdateRequest $request, $id): RedirectResponse /** * Remove the specified resource from storage. * - * @param LinkDeleteRequest $request - * @param int $id + * @param Link $link * @return RedirectResponse * @throws Exception */ - public function destroy(LinkDeleteRequest $request, $id): RedirectResponse + public function destroy(Link $link): RedirectResponse { - $link = Link::findOrFail($id); - - $deletionSuccessfull = LinkRepository::delete($link); + $deletionSuccessful = LinkRepository::delete($link); - if (!$deletionSuccessfull) { + if (!$deletionSuccessful) { flash(trans('link.deletion_error'), 'error'); return redirect()->back(); } @@ -165,13 +156,11 @@ public function destroy(LinkDeleteRequest $request, $id): RedirectResponse * Toggles the setting of a link to be either checked or not. * * @param LinkToggleCheckRequest $request - * @param $id + * @param Link $link * @return RedirectResponse */ - public function updateCheckToggle(LinkToggleCheckRequest $request, $id): RedirectResponse + public function updateCheckToggle(LinkToggleCheckRequest $request, Link $link): RedirectResponse { - $link = Link::findOrFail($id); - $link->check_disabled = $request->input('toggle'); $link->save(); diff --git a/app/Http/Controllers/Models/ListController.php b/app/Http/Controllers/Models/ListController.php index d58353da..2ee84b13 100644 --- a/app/Http/Controllers/Models/ListController.php +++ b/app/Http/Controllers/Models/ListController.php @@ -3,7 +3,6 @@ namespace App\Http\Controllers\Models; use App\Http\Controllers\Controller; -use App\Http\Requests\Models\ListDeleteRequest; use App\Http\Requests\Models\ListStoreRequest; use App\Http\Requests\Models\ListUpdateRequest; use App\Models\LinkList; @@ -11,7 +10,7 @@ use Exception; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\View\View; +use \Illuminate\Contracts\View\View; class ListController extends Controller { @@ -74,14 +73,12 @@ public function store(ListStoreRequest $request): RedirectResponse /** * Display the specified resource. * - * @param Request $request - * @param int $id + * @param Request $request + * @param LinkList $list * @return View */ - public function show(Request $request, $id): View + public function show(Request $request, LinkList $list): View { - $list = LinkList::findOrFail($id); - $links = $list->links() ->byUser(auth()->id()) ->orderBy( @@ -101,13 +98,11 @@ public function show(Request $request, $id): View /** * Show the form for editing the specified resource. * - * @param int $id + * @param LinkList $list * @return View */ - public function edit($id): View + public function edit(LinkList $list): View { - $list = LinkList::findOrFail($id); - return view('models.lists.edit')->with('list', $list); } @@ -115,13 +110,11 @@ public function edit($id): View * Update the specified resource in storage. * * @param ListUpdateRequest $request - * @param int $id + * @param LinkList $list * @return RedirectResponse */ - public function update(ListUpdateRequest $request, $id): RedirectResponse + public function update(ListUpdateRequest $request, LinkList $list): RedirectResponse { - $list = LinkList::findOrFail($id); - $list = ListRepository::update($list, $request->all()); flash(trans('list.updated_successfully'), 'success'); @@ -131,18 +124,15 @@ public function update(ListUpdateRequest $request, $id): RedirectResponse /** * Remove the specified resource from storage. * - * @param ListDeleteRequest $request - * @param int $id + * @param LinkList $list * @return RedirectResponse * @throws Exception */ - public function destroy(ListDeleteRequest $request, $id): RedirectResponse + public function destroy(LinkList $list): RedirectResponse { - $list = LinkList::findOrFail($id); - - $deletionSuccessfull = ListRepository::delete($list); + $deletionSuccessful = ListRepository::delete($list); - if (!$deletionSuccessfull) { + if (!$deletionSuccessful) { flash(trans('list.deletion_error'), 'error'); return redirect()->back(); } diff --git a/app/Http/Controllers/Models/NoteController.php b/app/Http/Controllers/Models/NoteController.php index 0a20725d..f0741c65 100644 --- a/app/Http/Controllers/Models/NoteController.php +++ b/app/Http/Controllers/Models/NoteController.php @@ -10,8 +10,8 @@ use App\Models\Note; use App\Repositories\NoteRepository; use Exception; +use Illuminate\Contracts\View\View; use Illuminate\Http\RedirectResponse; -use Illuminate\View\View; class NoteController extends Controller { @@ -40,13 +40,11 @@ public function store(NoteStoreRequest $request): RedirectResponse /** * Show the form for editing the specified resource. * - * @param int $id + * @param Note $note * @return View */ - public function edit($id): View + public function edit(Note $note): View { - $note = Note::findOrFail($id); - if ($note->user_id !== auth()->id()) { abort(403); } @@ -58,13 +56,11 @@ public function edit($id): View * Update the specified resource in storage. * * @param NoteUpdateRequest $request - * @param int $id + * @param Note $note * @return RedirectResponse */ - public function update(NoteUpdateRequest $request, $id): RedirectResponse + public function update(NoteUpdateRequest $request, Note $note): RedirectResponse { - $note = Note::findOrFail($id); - $note = NoteRepository::update($note, $request->except(['_token'])); flash(trans('note.updated_successfully'), 'success'); @@ -75,20 +71,17 @@ public function update(NoteUpdateRequest $request, $id): RedirectResponse /** * Remove the specified resource from storage. * - * @param NoteDeleteRequest $request - * @param int $id + * @param Note $note * @return RedirectResponse * @throws Exception */ - public function destroy(NoteDeleteRequest $request, $id): RedirectResponse + public function destroy(Note $note): RedirectResponse { - $note = Note::findOrFail($id); - $linkId = $note->link->id; - $deletionSuccessfull = NoteRepository::delete($note); + $deletionSuccessful = NoteRepository::delete($note); - if (!$deletionSuccessfull) { + if (!$deletionSuccessful) { flash(trans('note.deletion_error'), 'error'); return redirect()->back(); } diff --git a/app/Http/Controllers/Models/TagController.php b/app/Http/Controllers/Models/TagController.php index 036d6fa5..67565c87 100644 --- a/app/Http/Controllers/Models/TagController.php +++ b/app/Http/Controllers/Models/TagController.php @@ -3,15 +3,14 @@ namespace App\Http\Controllers\Models; use App\Http\Controllers\Controller; -use App\Http\Requests\Models\TagDeleteRequest; use App\Http\Requests\Models\TagStoreRequest; use App\Http\Requests\Models\TagUpdateRequest; use App\Models\Tag; use App\Repositories\TagRepository; use Exception; +use Illuminate\Contracts\View\View; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\View\View; class TagController extends Controller { @@ -74,13 +73,11 @@ public function store(TagStoreRequest $request) * Display the specified resource. * * @param Request $request - * @param int $id + * @param Tag $tag * @return View */ - public function show(Request $request, $id): View + public function show(Request $request, Tag $tag): View { - $tag = Tag::findOrFail($id); - $links = $tag->links()->byUser(auth()->id()) ->orderBy( $request->input('orderBy', 'created_at'), @@ -100,13 +97,11 @@ public function show(Request $request, $id): View /** * Show the form for editing the specified resource. * - * @param int $id + * @param Tag $tag * @return View */ - public function edit($id): View + public function edit(Tag $tag): View { - $tag = Tag::findOrFail($id); - return view('models.tags.edit')->with('tag', $tag); } @@ -114,15 +109,12 @@ public function edit($id): View * Update the specified resource in storage. * * @param TagUpdateRequest $request - * @param int $id + * @param Tag $tag * @return RedirectResponse */ - public function update(TagUpdateRequest $request, $id): RedirectResponse + public function update(TagUpdateRequest $request, Tag $tag): RedirectResponse { - $tag = Tag::findOrFail($id); - - $data = $request->all(); - $tag = TagRepository::update($tag, $data); + $tag = TagRepository::update($tag, $request->input()); flash(trans('tag.updated_successfully'), 'success'); return redirect()->route('tags.show', [$tag->id]); @@ -131,18 +123,15 @@ public function update(TagUpdateRequest $request, $id): RedirectResponse /** * Remove the specified resource from storage. * - * @param TagDeleteRequest $request - * @param int $id + * @param Tag $tag * @return RedirectResponse * @throws Exception */ - public function destroy(TagDeleteRequest $request, $id): RedirectResponse + public function destroy(Tag $tag): RedirectResponse { - $tag = Tag::findOrFail($id); - - $deletionSuccessfull = TagRepository::delete($tag); + $deletionSuccessful = TagRepository::delete($tag); - if (!$deletionSuccessfull) { + if (!$deletionSuccessful) { flash(trans('tag.deletion_error'), 'error'); return redirect()->back(); } diff --git a/app/Http/Requests/Models/LinkDeleteRequest.php b/app/Http/Requests/Models/LinkDeleteRequest.php deleted file mode 100644 index 38ddcce2..00000000 --- a/app/Http/Requests/Models/LinkDeleteRequest.php +++ /dev/null @@ -1,33 +0,0 @@ - Date: Tue, 17 Nov 2020 17:27:58 +0100 Subject: [PATCH 19/29] Correct types view controller return types, unify code styling --- app/Http/Controllers/App/BookmarkletController.php | 2 +- app/Http/Controllers/App/DashboardController.php | 2 +- app/Http/Controllers/App/ExportController.php | 2 +- app/Http/Controllers/App/ImportController.php | 2 +- app/Http/Controllers/App/SearchController.php | 2 +- app/Http/Controllers/App/SystemSettingsController.php | 3 +-- app/Http/Controllers/App/TrashController.php | 4 +--- app/Http/Controllers/App/UserSettingsController.php | 5 +---- app/Http/Controllers/FrontController.php | 2 +- app/Http/Controllers/Guest/LinkController.php | 2 +- app/Http/Controllers/Guest/ListController.php | 8 ++++---- app/Http/Controllers/Guest/TagController.php | 9 ++++----- app/Http/Controllers/Models/ListController.php | 2 +- app/Http/Controllers/Models/NoteController.php | 2 +- app/Http/Controllers/Models/TagController.php | 2 +- app/Http/Controllers/Setup/AccountController.php | 2 +- app/Http/Controllers/Setup/DatabaseController.php | 3 +-- app/Http/Controllers/Setup/MetaController.php | 2 +- app/Http/Controllers/Setup/RequirementsController.php | 2 +- 19 files changed, 25 insertions(+), 33 deletions(-) diff --git a/app/Http/Controllers/App/BookmarkletController.php b/app/Http/Controllers/App/BookmarkletController.php index 8af3c95f..e4cce525 100644 --- a/app/Http/Controllers/App/BookmarkletController.php +++ b/app/Http/Controllers/App/BookmarkletController.php @@ -6,7 +6,7 @@ use Illuminate\Contracts\View\Factory; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; class BookmarkletController extends Controller { diff --git a/app/Http/Controllers/App/DashboardController.php b/app/Http/Controllers/App/DashboardController.php index 8d8b6d46..8988eaba 100644 --- a/app/Http/Controllers/App/DashboardController.php +++ b/app/Http/Controllers/App/DashboardController.php @@ -7,7 +7,7 @@ use App\Models\LinkList; use App\Models\Note; use App\Models\Tag; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; class DashboardController extends Controller { diff --git a/app/Http/Controllers/App/ExportController.php b/app/Http/Controllers/App/ExportController.php index fd8ff560..f8c87ebf 100644 --- a/app/Http/Controllers/App/ExportController.php +++ b/app/Http/Controllers/App/ExportController.php @@ -8,7 +8,7 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; use League\Csv\CannotInsertRecord; use League\Csv\Writer; use Symfony\Component\HttpFoundation\StreamedResponse; diff --git a/app/Http/Controllers/App/ImportController.php b/app/Http/Controllers/App/ImportController.php index 1a50dfbc..e7e8ecb2 100644 --- a/app/Http/Controllers/App/ImportController.php +++ b/app/Http/Controllers/App/ImportController.php @@ -13,7 +13,7 @@ use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Log; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; use Shaarli\NetscapeBookmarkParser\NetscapeBookmarkParser; class ImportController extends Controller diff --git a/app/Http/Controllers/App/SearchController.php b/app/Http/Controllers/App/SearchController.php index 69f24bd9..1ed2c3f4 100644 --- a/app/Http/Controllers/App/SearchController.php +++ b/app/Http/Controllers/App/SearchController.php @@ -5,7 +5,7 @@ use App\Http\Controllers\Controller; use App\Http\Controllers\Traits\SearchesLinks; use App\Http\Requests\SearchRequest; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; class SearchController extends Controller { diff --git a/app/Http/Controllers/App/SystemSettingsController.php b/app/Http/Controllers/App/SystemSettingsController.php index a286ab0b..008102de 100644 --- a/app/Http/Controllers/App/SystemSettingsController.php +++ b/app/Http/Controllers/App/SystemSettingsController.php @@ -9,7 +9,7 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Str; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; class SystemSettingsController extends Controller { @@ -65,7 +65,6 @@ public function saveSystemSettings(SystemSettingsUpdateRequest $request): Redire } flash(trans('settings.settings_saved')); - return redirect()->route('get-systemsettings'); } diff --git a/app/Http/Controllers/App/TrashController.php b/app/Http/Controllers/App/TrashController.php index 2be9ecd3..c0f03050 100644 --- a/app/Http/Controllers/App/TrashController.php +++ b/app/Http/Controllers/App/TrashController.php @@ -11,7 +11,7 @@ use App\Models\Tag; use App\Repositories\TrashRepository; use Illuminate\Http\RedirectResponse; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; class TrashController extends Controller { @@ -57,7 +57,6 @@ public function clearTrash(TrashClearRequest $request): RedirectResponse TrashRepository::delete($request->input('model')); flash(trans('trash.delete_success.' . $request->input('model')), 'success'); - return redirect()->route('get-trash'); } @@ -72,7 +71,6 @@ public function restoreEntry(TrashRestoreRequest $request): RedirectResponse TrashRepository::restore($request->input('model'), $request->input('id')); flash(trans('trash.restore.' . $request->input('model')), 'success'); - return redirect()->route('get-trash'); } } diff --git a/app/Http/Controllers/App/UserSettingsController.php b/app/Http/Controllers/App/UserSettingsController.php index 646099af..acae4445 100644 --- a/app/Http/Controllers/App/UserSettingsController.php +++ b/app/Http/Controllers/App/UserSettingsController.php @@ -14,7 +14,7 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Str; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; class UserSettingsController extends Controller { @@ -44,7 +44,6 @@ public function saveAccountSettings(Request $request): RedirectResponse (new UpdateUserProfileInformation())->update($request->user(), $request->input()); flash(trans('settings.settings_saved'), 'success'); - return redirect()->back(); } @@ -85,7 +84,6 @@ public function saveAppSettings(UserSettingsUpdateRequest $request): RedirectRes } flash(trans('settings.settings_saved'), 'success'); - return redirect()->back(); } @@ -100,7 +98,6 @@ public function changeUserPassword(Request $request): RedirectResponse (new UpdateUserPassword())->update($request->user(), $request->input()); flash(trans('settings.password_updated'), 'success'); - return redirect()->back(); } diff --git a/app/Http/Controllers/FrontController.php b/app/Http/Controllers/FrontController.php index b7ecb351..f098cdf1 100644 --- a/app/Http/Controllers/FrontController.php +++ b/app/Http/Controllers/FrontController.php @@ -3,7 +3,7 @@ namespace App\Http\Controllers; use Illuminate\Http\RedirectResponse; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; class FrontController extends Controller { diff --git a/app/Http/Controllers/Guest/LinkController.php b/app/Http/Controllers/Guest/LinkController.php index 3ab26069..9311f09e 100644 --- a/app/Http/Controllers/Guest/LinkController.php +++ b/app/Http/Controllers/Guest/LinkController.php @@ -4,8 +4,8 @@ use App\Http\Controllers\Controller; use App\Models\Link; +use Illuminate\Contracts\View\View; use Illuminate\Http\Request; -use Illuminate\View\View; class LinkController extends Controller { diff --git a/app/Http/Controllers/Guest/ListController.php b/app/Http/Controllers/Guest/ListController.php index 60101e64..c4c2c84e 100644 --- a/app/Http/Controllers/Guest/ListController.php +++ b/app/Http/Controllers/Guest/ListController.php @@ -4,8 +4,8 @@ use App\Http\Controllers\Controller; use App\Models\LinkList; +use Illuminate\Contracts\View\View; use Illuminate\Http\Request; -use Illuminate\View\View; class ListController extends Controller { @@ -36,12 +36,12 @@ public function index(Request $request): View * Display the specified resource. * * @param Request $request - * @param int $id + * @param int $listID * @return View */ - public function show(Request $request, $id): View + public function show(Request $request, $listID): View { - $list = LinkList::isPrivate(false)->findOrFail($id); + $list = LinkList::isPrivate(false)->findOrFail($listID); $links = $list->links() ->privateOnly(false) diff --git a/app/Http/Controllers/Guest/TagController.php b/app/Http/Controllers/Guest/TagController.php index ed0d397c..9d603a71 100644 --- a/app/Http/Controllers/Guest/TagController.php +++ b/app/Http/Controllers/Guest/TagController.php @@ -3,10 +3,9 @@ namespace App\Http\Controllers\Guest; use App\Http\Controllers\Controller; -use App\Models\LinkList; use App\Models\Tag; +use Illuminate\Contracts\View\View; use Illuminate\Http\Request; -use Illuminate\View\View; class TagController extends Controller { @@ -38,12 +37,12 @@ public function index(Request $request): View * Display the specified resource. * * @param Request $request - * @param int $id + * @param int $tagID * @return View */ - public function show(Request $request, $id): View + public function show(Request $request, $tagID): View { - $tag = Tag::isPrivate(false)->findOrFail($id); + $tag = Tag::isPrivate(false)->findOrFail($tagID); $links = $tag->links() ->privateOnly(false) diff --git a/app/Http/Controllers/Models/ListController.php b/app/Http/Controllers/Models/ListController.php index 2ee84b13..35163c7a 100644 --- a/app/Http/Controllers/Models/ListController.php +++ b/app/Http/Controllers/Models/ListController.php @@ -103,7 +103,7 @@ public function show(Request $request, LinkList $list): View */ public function edit(LinkList $list): View { - return view('models.lists.edit')->with('list', $list); + return view('models.lists.edit', ['list' => $list]); } /** diff --git a/app/Http/Controllers/Models/NoteController.php b/app/Http/Controllers/Models/NoteController.php index f0741c65..bda81d43 100644 --- a/app/Http/Controllers/Models/NoteController.php +++ b/app/Http/Controllers/Models/NoteController.php @@ -49,7 +49,7 @@ public function edit(Note $note): View abort(403); } - return view('models.notes.edit')->with('note', $note); + return view('models.notes.edit', ['note' => $note]); } /** diff --git a/app/Http/Controllers/Models/TagController.php b/app/Http/Controllers/Models/TagController.php index 67565c87..e14fdfe9 100644 --- a/app/Http/Controllers/Models/TagController.php +++ b/app/Http/Controllers/Models/TagController.php @@ -102,7 +102,7 @@ public function show(Request $request, Tag $tag): View */ public function edit(Tag $tag): View { - return view('models.tags.edit')->with('tag', $tag); + return view('models.tags.edit', ['tag' => $tag]); } /** diff --git a/app/Http/Controllers/Setup/AccountController.php b/app/Http/Controllers/Setup/AccountController.php index af29e86e..0c5614aa 100644 --- a/app/Http/Controllers/Setup/AccountController.php +++ b/app/Http/Controllers/Setup/AccountController.php @@ -7,7 +7,7 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; class AccountController extends Controller { diff --git a/app/Http/Controllers/Setup/DatabaseController.php b/app/Http/Controllers/Setup/DatabaseController.php index c8afcd1c..e3877af4 100644 --- a/app/Http/Controllers/Setup/DatabaseController.php +++ b/app/Http/Controllers/Setup/DatabaseController.php @@ -12,7 +12,7 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Log; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; use PDOException; class DatabaseController extends Controller @@ -42,7 +42,6 @@ public function configure(SetupDatabaseRequest $request): RedirectResponse if ($this->databaseHasData() && !$request->has('overwrite_data')) { flash(trans('setup.database.data_present'), 'danger'); - return redirect()->back()->with('data_present', true)->withInput(); } diff --git a/app/Http/Controllers/Setup/MetaController.php b/app/Http/Controllers/Setup/MetaController.php index 6e8f6314..b304a8e9 100644 --- a/app/Http/Controllers/Setup/MetaController.php +++ b/app/Http/Controllers/Setup/MetaController.php @@ -4,7 +4,7 @@ use App\Http\Controllers\Controller; use Illuminate\Support\Facades\File; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; class MetaController extends Controller { diff --git a/app/Http/Controllers/Setup/RequirementsController.php b/app/Http/Controllers/Setup/RequirementsController.php index f32fe45c..e5e977ea 100644 --- a/app/Http/Controllers/Setup/RequirementsController.php +++ b/app/Http/Controllers/Setup/RequirementsController.php @@ -4,7 +4,7 @@ use App\Http\Controllers\Controller; use Illuminate\Support\Facades\File; -use Illuminate\View\View; +use Illuminate\Contracts\View\View; class RequirementsController extends Controller { From 92b755de6afdadbee7069e6936ce1b9ad8ccf87f Mon Sep 17 00:00:00 2001 From: Kovah Date: Tue, 17 Nov 2020 17:47:54 +0100 Subject: [PATCH 20/29] Correct the bookmarklet login handling by using a new middleware --- app/Http/Kernel.php | 1 + .../Middleware/BookmarkRedirectMiddleware.php | 34 +++++++++++++++++++ .../Middleware/RedirectIfAuthenticated.php | 7 ---- 3 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 app/Http/Middleware/BookmarkRedirectMiddleware.php diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index a8db75f0..92fb7942 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -37,6 +37,7 @@ class Kernel extends HttpKernel \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \App\Http\Middleware\SettingsMiddleware::class, + \App\Http\Middleware\BookmarkRedirectMiddleware::class, ], 'api' => [ diff --git a/app/Http/Middleware/BookmarkRedirectMiddleware.php b/app/Http/Middleware/BookmarkRedirectMiddleware.php new file mode 100644 index 00000000..1e86bac6 --- /dev/null +++ b/app/Http/Middleware/BookmarkRedirectMiddleware.php @@ -0,0 +1,34 @@ +is('dashboard')) { + Session::forget('bookmarklet.login_redirect'); + + return redirect()->route('bookmarklet-add', [ + 'u' => session('bookmarklet.new_url'), + 't' => session('bookmarklet.new_title'), + ]); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index a4d28c48..7617761e 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -19,13 +19,6 @@ class RedirectIfAuthenticated public function handle($request, Closure $next, $guard = null) { if (Auth::guard($guard)->check()) { - if (Session::pull('bookmarklet.login_redirect')) { - return redirect()->route('bookmarklet-add', [ - 'u' => session('bookmarklet.new_url'), - 't' => session('bookmarklet.new_title'), - ]); - } - return redirect('/dashboard'); } From 1aeed1a0213ac72fa7a7d43b7199a0043e6319be Mon Sep 17 00:00:00 2001 From: Kovah Date: Tue, 17 Nov 2020 19:01:37 +0100 Subject: [PATCH 21/29] Fix unit tests and smaller code issues --- app/Http/Controllers/API/LinkController.php | 23 +++++++---------- .../Controllers/API/LinkNotesController.php | 6 ++--- app/Http/Controllers/API/ListController.php | 25 +++++++------------ .../Controllers/API/ListLinksController.php | 6 ++--- app/Http/Controllers/API/NoteController.php | 17 +++++-------- app/Http/Controllers/API/TagController.php | 23 ++++++----------- .../Controllers/API/TagLinksController.php | 6 ++--- .../Controllers/Models/LinkController.php | 2 +- .../Requests/Models/LinkUpdateRequest.php | 5 +--- .../Requests/Models/ListUpdateRequest.php | 5 +--- app/Http/Requests/Models/TagUpdateRequest.php | 5 +--- app/Models/Link.php | 11 -------- routes/web.php | 2 +- 13 files changed, 43 insertions(+), 93 deletions(-) diff --git a/app/Http/Controllers/API/LinkController.php b/app/Http/Controllers/API/LinkController.php index 68f0e0c3..6caaea20 100644 --- a/app/Http/Controllers/API/LinkController.php +++ b/app/Http/Controllers/API/LinkController.php @@ -48,12 +48,12 @@ public function store(LinkStoreRequest $request): JsonResponse /** * Display the specified resource. * - * @param int $id + * @param Link $link * @return JsonResponse */ - public function show($id): JsonResponse + public function show(Link $link): JsonResponse { - $link = Link::with(['lists', 'tags'])->findOrFail($id); + $link->load(['lists', 'tags']); return response()->json($link); } @@ -62,13 +62,11 @@ public function show($id): JsonResponse * Update the specified resource in storage. * * @param LinkUpdateRequest $request - * @param int $id + * @param Link $link * @return JsonResponse */ - public function update(LinkUpdateRequest $request, $id): JsonResponse + public function update(LinkUpdateRequest $request, Link $link): JsonResponse { - $link = Link::findOrFail($id); - $updatedLink = LinkRepository::update($link, $request->all()); return response()->json($updatedLink); @@ -77,17 +75,14 @@ public function update(LinkUpdateRequest $request, $id): JsonResponse /** * Remove the specified resource from storage. * - * @param LinkDeleteRequest $request - * @param int $id + * @param Link $link * @return JsonResponse */ - public function destroy(LinkDeleteRequest $request, $id): JsonResponse + public function destroy(Link $link): JsonResponse { - $link = Link::findOrFail($id); - - $deletionSuccessfull = LinkRepository::delete($link); + $deletionSuccessful = LinkRepository::delete($link); - if ($deletionSuccessfull) { + if ($deletionSuccessful) { return response()->json(null, Response::HTTP_OK); } diff --git a/app/Http/Controllers/API/LinkNotesController.php b/app/Http/Controllers/API/LinkNotesController.php index f8e6a627..6b5f5e5b 100644 --- a/app/Http/Controllers/API/LinkNotesController.php +++ b/app/Http/Controllers/API/LinkNotesController.php @@ -11,13 +11,11 @@ class LinkNotesController extends Controller /** * Get the notes for a specific link. * - * @param $linkID + * @param Link $link * @return JsonResponse */ - public function __invoke($linkID): JsonResponse + public function __invoke(Link $link): JsonResponse { - $link = Link::findOrFail($linkID); - $notes = $link->notes()->paginate(getPaginationLimit()); return response()->json($notes); diff --git a/app/Http/Controllers/API/ListController.php b/app/Http/Controllers/API/ListController.php index 1f4283bf..3400b415 100644 --- a/app/Http/Controllers/API/ListController.php +++ b/app/Http/Controllers/API/ListController.php @@ -48,14 +48,12 @@ public function store(ListStoreRequest $request): JsonResponse /** * Display the specified resource. * - * @param int $id + * @param LinkList $list * @return JsonResponse */ - public function show($id): JsonResponse + public function show(LinkList $list): JsonResponse { - $list = LinkList::findOrFail($id); - - $list->links = route('api.lists.links', [$id], true); + $list->setAttribute('links', route('api.lists.links', [$list->id], true)); return response()->json($list); } @@ -64,13 +62,11 @@ public function show($id): JsonResponse * Update the specified resource in storage. * * @param ListUpdateRequest $request - * @param int $id + * @param LinkList $list * @return JsonResponse */ - public function update(ListUpdateRequest $request, $id): JsonResponse + public function update(ListUpdateRequest $request, LinkList $list): JsonResponse { - $list = LinkList::findOrFail($id); - $updatedList = ListRepository::update($list, $request->all()); return response()->json($updatedList); @@ -79,17 +75,14 @@ public function update(ListUpdateRequest $request, $id): JsonResponse /** * Remove the specified resource from storage. * - * @param ListDeleteRequest $request - * @param int $id + * @param LinkList $list * @return JsonResponse */ - public function destroy(ListDeleteRequest $request, $id): JsonResponse + public function destroy(LinkList $list): JsonResponse { - $list = LinkList::findOrFail($id); - - $deletionSuccessfull = ListRepository::delete($list); + $deletionSuccessful = ListRepository::delete($list); - if ($deletionSuccessfull) { + if ($deletionSuccessful) { return response()->json(null, Response::HTTP_OK); } diff --git a/app/Http/Controllers/API/ListLinksController.php b/app/Http/Controllers/API/ListLinksController.php index 7c1cde82..673ad198 100644 --- a/app/Http/Controllers/API/ListLinksController.php +++ b/app/Http/Controllers/API/ListLinksController.php @@ -11,13 +11,11 @@ class ListLinksController extends Controller /** * Get the links for a specific list. * - * @param $listID + * @param LinkList $list * @return JsonResponse */ - public function __invoke($listID): JsonResponse + public function __invoke(LinkList $list): JsonResponse { - $list = LinkList::findOrFail($listID); - $links = $list->links()->paginate(getPaginationLimit()); return response()->json($links); diff --git a/app/Http/Controllers/API/NoteController.php b/app/Http/Controllers/API/NoteController.php index 5f7cc498..3d2e7323 100644 --- a/app/Http/Controllers/API/NoteController.php +++ b/app/Http/Controllers/API/NoteController.php @@ -30,13 +30,11 @@ public function store(NoteStoreRequest $request): JsonResponse * Update the specified resource in storage. * * @param NoteUpdateRequest $request - * @param int $id + * @param Note $note * @return JsonResponse */ - public function update(NoteUpdateRequest $request, $id): JsonResponse + public function update(NoteUpdateRequest $request, Note $note): JsonResponse { - $note = Note::findOrFail($id); - $updatedNote = NoteRepository::update($note, $request->all()); return response()->json($updatedNote); @@ -45,17 +43,14 @@ public function update(NoteUpdateRequest $request, $id): JsonResponse /** * Remove the specified resource from storage. * - * @param NoteDeleteRequest $request - * @param int $id + * @param Note $note * @return JsonResponse */ - public function destroy(NoteDeleteRequest $request, $id): JsonResponse + public function destroy(Note $note): JsonResponse { - $note = Note::findOrFail($id); - - $deletionSuccessfull = NoteRepository::delete($note); + $deletionSuccessful = NoteRepository::delete($note); - if ($deletionSuccessfull) { + if ($deletionSuccessful) { return response()->json(null, Response::HTTP_OK); } diff --git a/app/Http/Controllers/API/TagController.php b/app/Http/Controllers/API/TagController.php index 6f8020a9..b2b5bb07 100644 --- a/app/Http/Controllers/API/TagController.php +++ b/app/Http/Controllers/API/TagController.php @@ -48,13 +48,11 @@ public function store(TagStoreRequest $request): JsonResponse /** * Display the specified resource. * - * @param int $id + * @param Tag $tag * @return JsonResponse */ - public function show($id): JsonResponse + public function show(Tag $tag): JsonResponse { - $tag = Tag::findOrFail($id); - return response()->json($tag); } @@ -62,13 +60,11 @@ public function show($id): JsonResponse * Update the specified resource in storage. * * @param TagUpdateRequest $request - * @param int $id + * @param Tag $tag * @return JsonResponse */ - public function update(TagUpdateRequest $request, $id): JsonResponse + public function update(TagUpdateRequest $request, Tag $tag): JsonResponse { - $tag = Tag::findOrFail($id); - $updatedTag = TagRepository::update($tag, $request->all()); return response()->json($updatedTag); @@ -77,17 +73,14 @@ public function update(TagUpdateRequest $request, $id): JsonResponse /** * Remove the specified resource from storage. * - * @param TagDeleteRequest $request - * @param int $id + * @param Tag $tag * @return JsonResponse */ - public function destroy(TagDeleteRequest $request, $id): JsonResponse + public function destroy(Tag $tag): JsonResponse { - $tag = Tag::findOrFail($id); - - $deletionSuccessfull = TagRepository::delete($tag); + $deletionSuccessful = TagRepository::delete($tag); - if ($deletionSuccessfull) { + if ($deletionSuccessful) { return response()->json(null, Response::HTTP_OK); } diff --git a/app/Http/Controllers/API/TagLinksController.php b/app/Http/Controllers/API/TagLinksController.php index d8999268..03519c75 100644 --- a/app/Http/Controllers/API/TagLinksController.php +++ b/app/Http/Controllers/API/TagLinksController.php @@ -11,13 +11,11 @@ class TagLinksController extends Controller /** * Get the links for a specific tag. * - * @param $tagID + * @param Tag $tag * @return JsonResponse */ - public function __invoke($tagID): JsonResponse + public function __invoke(Tag $tag): JsonResponse { - $tag = Tag::findOrFail($tagID); - $links = $tag->links()->paginate(getPaginationLimit()); return response()->json($links); diff --git a/app/Http/Controllers/Models/LinkController.php b/app/Http/Controllers/Models/LinkController.php index cf2ec2f9..57e6ed11 100644 --- a/app/Http/Controllers/Models/LinkController.php +++ b/app/Http/Controllers/Models/LinkController.php @@ -126,7 +126,7 @@ public function edit(Link $link): View */ public function update(LinkUpdateRequest $request, Link $link): RedirectResponse { - $link = LinkRepository::update($link, $request->all()); + $link = LinkRepository::update($link, $request->input()); flash(trans('link.updated_successfully'), 'success'); return redirect()->route('links.show', [$link->id]); diff --git a/app/Http/Requests/Models/LinkUpdateRequest.php b/app/Http/Requests/Models/LinkUpdateRequest.php index 44bbe90d..859fad87 100644 --- a/app/Http/Requests/Models/LinkUpdateRequest.php +++ b/app/Http/Requests/Models/LinkUpdateRequest.php @@ -26,10 +26,7 @@ class LinkUpdateRequest extends FormRequest public function authorize(Request $request) { if ($request->input('url') !== null) { - $this->requireUniqueUrl = Link::urlHasChanged( - $request->route('link'), - $request->input('url') - ); + $this->requireUniqueUrl = $request->route('link')->url !== $request->input('url'); } return true; diff --git a/app/Http/Requests/Models/ListUpdateRequest.php b/app/Http/Requests/Models/ListUpdateRequest.php index af218379..5c99d02e 100644 --- a/app/Http/Requests/Models/ListUpdateRequest.php +++ b/app/Http/Requests/Models/ListUpdateRequest.php @@ -26,10 +26,7 @@ class ListUpdateRequest extends FormRequest public function authorize(Request $request) { if ($request->input('name') !== null) { - $this->requireUniqueName = LinkList::nameHasChanged( - $request->route('list'), - $request->input('name') - ); + $this->requireUniqueName = $request->route('list')->name !== $request->input('name'); } return true; diff --git a/app/Http/Requests/Models/TagUpdateRequest.php b/app/Http/Requests/Models/TagUpdateRequest.php index 65a40815..05348158 100644 --- a/app/Http/Requests/Models/TagUpdateRequest.php +++ b/app/Http/Requests/Models/TagUpdateRequest.php @@ -26,10 +26,7 @@ class TagUpdateRequest extends FormRequest public function authorize(Request $request) { if ($request->input('name') !== null) { - $this->requireUniqueName = Tag::nameHasChanged( - $request->route('tag'), - $request->input('name') - ); + $this->requireUniqueName = $request->route('tag')->name !== $request->input('name'); } return true; diff --git a/app/Models/Link.php b/app/Models/Link.php index fd1d76dd..f4f93558 100644 --- a/app/Models/Link.php +++ b/app/Models/Link.php @@ -268,17 +268,6 @@ public function addedAt() return $output; } - /** - * @param string|int $linkId - * @param string $newUrl - * @return bool - */ - public static function urlHasChanged($linkId, string $newUrl): bool - { - $oldUrl = self::find($linkId)->url ?? null; - return $oldUrl !== $newUrl; - } - /* * Dispatch the SaveLinkToWaybackmachine job, if Internet Archive backups * are enabled. diff --git a/routes/web.php b/routes/web.php index 16477a9e..b14fd9af 100644 --- a/routes/web.php +++ b/routes/web.php @@ -66,7 +66,7 @@ Route::resource('notes', NoteController::class) ->except(['index', 'show']); - Route::post('links/toggle-check/{id}', [LinkController::class, 'updateCheckToggle']) + Route::post('links/toggle-check/{link}', [LinkController::class, 'updateCheckToggle']) ->name('links.toggle-check'); Route::get('search', [SearchController::class, 'getSearch']) From ba07e144f067bd167a543d97220da79b05fbdd87 Mon Sep 17 00:00:00 2001 From: Kovah Date: Tue, 17 Nov 2020 19:40:25 +0100 Subject: [PATCH 22/29] Enable tests for Node 14 and PHP 8, optimize PHP CS config --- .github/workflows/test.yml | 4 ++-- composer.json | 2 +- database/seeders/ExampleSeeder.php | 4 +++- phpcs.xml | 6 ++++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 14306a2a..3aca150f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [12.x] + node-version: ['12.x', '14.x'] name: Test asset generation process on Node ${{ matrix.node-version }} @@ -40,7 +40,7 @@ jobs: strategy: matrix: operating-system: [ubuntu-latest] - php-versions: ['7.3', '7.4'] + php-versions: ['7.3', '7.4', '8.0'] name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} diff --git a/composer.json b/composer.json index 1c866210..ee0c2049 100644 --- a/composer.json +++ b/composer.json @@ -62,7 +62,7 @@ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", "@php artisan package:discover --ansi" ], - "lint": "./vendor/bin/phpcs", + "lint": "./vendor/bin/phpcs --runtime-set ignore_warnings_on_exit 1", "test": "./vendor/bin/phpunit", "code-coverage": "./vendor/bin/phpunit --coverage-clover test-coverage.xml" }, diff --git a/database/seeders/ExampleSeeder.php b/database/seeders/ExampleSeeder.php index f1bd8720..93149b81 100644 --- a/database/seeders/ExampleSeeder.php +++ b/database/seeders/ExampleSeeder.php @@ -6,6 +6,7 @@ use App\Models\LinkList; use App\Models\Tag; use App\Models\User; +use Exception; use Illuminate\Database\Seeder; class ExampleSeeder extends Seeder @@ -14,8 +15,9 @@ class ExampleSeeder extends Seeder * Run the database seeds. * * @return void + * @throws Exception */ - public function run() + public function run(): void { // Generate users, categories and tags User::factory()->create(); diff --git a/phpcs.xml b/phpcs.xml index 780038fd..774c11e9 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -4,16 +4,18 @@ ./app + ./database/factories + ./database/seeders ./tests - + - + From 44f52588fa1b96b8fb708d4de8873a806945ad60 Mon Sep 17 00:00:00 2001 From: Kovah Date: Tue, 17 Nov 2020 19:51:53 +0100 Subject: [PATCH 23/29] Remove PHP 8 test, update dependencies --- .github/workflows/test.yml | 2 +- composer.lock | 170 +++++++------ package-lock.json | 502 +++++++++++++++++++------------------ package.json | 4 +- 4 files changed, 349 insertions(+), 329 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3aca150f..9a95e590 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,7 +40,7 @@ jobs: strategy: matrix: operating-system: [ubuntu-latest] - php-versions: ['7.3', '7.4', '8.0'] + php-versions: ['7.3', '7.4'] name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} diff --git a/composer.lock b/composer.lock index ae70053c..50e9c4dd 100644 --- a/composer.lock +++ b/composer.lock @@ -323,16 +323,16 @@ }, { "name": "doctrine/dbal", - "version": "2.12.0", + "version": "2.12.1", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "c6d37b4c42aaa3c3ee175f05eca68056f4185646" + "reference": "adce7a954a1c2f14f85e94aed90c8489af204086" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/c6d37b4c42aaa3c3ee175f05eca68056f4185646", - "reference": "c6d37b4c42aaa3c3ee175f05eca68056f4185646", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/adce7a954a1c2f14f85e94aed90c8489af204086", + "reference": "adce7a954a1c2f14f85e94aed90c8489af204086", "shasum": "" }, "require": { @@ -426,7 +426,7 @@ "type": "tidelift" } ], - "time": "2020-10-22T17:26:24+00:00" + "time": "2020-11-14T20:26:58+00:00" }, { "name": "doctrine/event-manager", @@ -741,16 +741,16 @@ }, { "name": "egulias/email-validator", - "version": "2.1.23", + "version": "2.1.24", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "5fa792ad1853ae2bc60528dd3e5cbf4542d3c1df" + "reference": "ca90a3291eee1538cd48ff25163240695bd95448" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/5fa792ad1853ae2bc60528dd3e5cbf4542d3c1df", - "reference": "5fa792ad1853ae2bc60528dd3e5cbf4542d3c1df", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ca90a3291eee1538cd48ff25163240695bd95448", + "reference": "ca90a3291eee1538cd48ff25163240695bd95448", "shasum": "" }, "require": { @@ -795,7 +795,13 @@ "validation", "validator" ], - "time": "2020-10-31T20:37:35+00:00" + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2020-11-14T15:56:27+00:00" }, { "name": "fideloper/proxy", @@ -1298,16 +1304,16 @@ }, { "name": "laravel/framework", - "version": "v8.13.0", + "version": "v8.15.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "37a0abd4f3dbc51e2256296b45f8be72c8fe2196" + "reference": "22e4182fa0885dea3772106c3b6df705b7c7363e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/37a0abd4f3dbc51e2256296b45f8be72c8fe2196", - "reference": "37a0abd4f3dbc51e2256296b45f8be72c8fe2196", + "url": "https://api.github.com/repos/laravel/framework/zipball/22e4182fa0885dea3772106c3b6df705b7c7363e", + "reference": "22e4182fa0885dea3772106c3b6df705b7c7363e", "shasum": "" }, "require": { @@ -1381,7 +1387,7 @@ }, "require-dev": { "aws/aws-sdk-php": "^3.0", - "doctrine/dbal": "^2.6", + "doctrine/dbal": "^2.6|^3.0", "filp/whoops": "^2.8", "guzzlehttp/guzzle": "^6.5.5|^7.0.1", "league/flysystem-cached-adapter": "^1.0", @@ -1394,7 +1400,7 @@ }, "suggest": { "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage and SES mail driver (^3.0).", - "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6|^3.0).", "ext-ftp": "Required to use the Flysystem FTP driver.", "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", "ext-memcached": "Required to use the memcache cache driver.", @@ -1457,7 +1463,7 @@ "framework", "laravel" ], - "time": "2020-11-03T14:13:19+00:00" + "time": "2020-11-17T14:53:20+00:00" }, { "name": "league/commonmark", @@ -2807,24 +2813,24 @@ }, { "name": "spatie/db-dumper", - "version": "2.17.0", + "version": "2.18.0", "source": { "type": "git", "url": "https://github.com/spatie/db-dumper.git", - "reference": "d23bcb566443e862a8dbb6dbd5e8da03aaf98e2a" + "reference": "eddb2b7c6877817d97bbdc1c60d1a800bf5a267a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/db-dumper/zipball/d23bcb566443e862a8dbb6dbd5e8da03aaf98e2a", - "reference": "d23bcb566443e862a8dbb6dbd5e8da03aaf98e2a", + "url": "https://api.github.com/repos/spatie/db-dumper/zipball/eddb2b7c6877817d97bbdc1c60d1a800bf5a267a", + "reference": "eddb2b7c6877817d97bbdc1c60d1a800bf5a267a", "shasum": "" }, "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "symfony/process": "^4.2|^5.0" }, "require-dev": { - "phpunit/phpunit": "^7.0|^8.0" + "phpunit/phpunit": "^7.0|^8.0|^9.0" }, "type": "library", "autoload": { @@ -2859,7 +2865,7 @@ "type": "github" } ], - "time": "2020-09-10T14:52:52+00:00" + "time": "2020-11-10T09:20:18+00:00" }, { "name": "spatie/laravel-backup", @@ -2949,23 +2955,23 @@ }, { "name": "spatie/temporary-directory", - "version": "1.2.4", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/spatie/temporary-directory.git", - "reference": "8efe8e61e0ca943d84341f10e51ef3a9606af932" + "reference": "f517729b3793bca58f847c5fd383ec16f03ffec6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/8efe8e61e0ca943d84341f10e51ef3a9606af932", - "reference": "8efe8e61e0ca943d84341f10e51ef3a9606af932", + "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/f517729b3793bca58f847c5fd383ec16f03ffec6", + "reference": "f517729b3793bca58f847c5fd383ec16f03ffec6", "shasum": "" }, "require": { - "php": "^7.2" + "php": "^7.2|^8.0" }, "require-dev": { - "phpunit/phpunit": "^8.0" + "phpunit/phpunit": "^8.0|^9.0" }, "type": "library", "autoload": { @@ -2988,10 +2994,11 @@ "description": "Easily create, use and destroy temporary directories", "homepage": "https://github.com/spatie/temporary-directory", "keywords": [ + "php", "spatie", "temporary-directory" ], - "time": "2020-09-07T20:41:15+00:00" + "time": "2020-11-09T15:54:21+00:00" }, { "name": "swiftmailer/swiftmailer", @@ -5316,23 +5323,23 @@ }, { "name": "voku/portable-ascii", - "version": "1.5.3", + "version": "1.5.6", "source": { "type": "git", "url": "https://github.com/voku/portable-ascii.git", - "reference": "25bcbf01678930251fd572891447d9e318a6e2b8" + "reference": "80953678b19901e5165c56752d087fc11526017c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/25bcbf01678930251fd572891447d9e318a6e2b8", - "reference": "25bcbf01678930251fd572891447d9e318a6e2b8", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/80953678b19901e5165c56752d087fc11526017c", + "reference": "80953678b19901e5165c56752d087fc11526017c", "shasum": "" }, "require": { "php": ">=7.0.0" }, "require-dev": { - "phpunit/phpunit": "~6.0 || ~7.0" + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" }, "suggest": { "ext-intl": "Use Intl for transliterator_transliterate() support" @@ -5382,7 +5389,7 @@ "type": "tidelift" } ], - "time": "2020-07-22T23:32:04+00:00" + "time": "2020-11-12T00:07:28+00:00" } ], "packages-dev": [ @@ -5832,16 +5839,16 @@ }, { "name": "composer/xdebug-handler", - "version": "1.4.4", + "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "6e076a124f7ee146f2487554a94b6a19a74887ba" + "reference": "f28d44c286812c714741478d968104c5e604a1d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6e076a124f7ee146f2487554a94b6a19a74887ba", - "reference": "6e076a124f7ee146f2487554a94b6a19a74887ba", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f28d44c286812c714741478d968104c5e604a1d4", + "reference": "f28d44c286812c714741478d968104c5e604a1d4", "shasum": "" }, "require": { @@ -5886,7 +5893,7 @@ "type": "tidelift" } ], - "time": "2020-10-24T12:39:10+00:00" + "time": "2020-11-13T08:04:11+00:00" }, { "name": "dnoegel/php-xdg-base-dir", @@ -5923,36 +5930,31 @@ }, { "name": "doctrine/instantiator", - "version": "1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0", + "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" @@ -5966,7 +5968,7 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", @@ -5989,7 +5991,7 @@ "type": "tidelift" } ], - "time": "2020-05-29T17:27:14+00:00" + "time": "2020-11-10T18:47:58+00:00" }, { "name": "facade/flare-client-php", @@ -6054,16 +6056,16 @@ }, { "name": "facade/ignition", - "version": "2.5.0", + "version": "2.5.2", "source": { "type": "git", "url": "https://github.com/facade/ignition.git", - "reference": "81698c5e32837c74abf9bb764ff0c1b3e001afb3" + "reference": "08668034beb185fa2ac6f09b1034eaa440952ace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facade/ignition/zipball/81698c5e32837c74abf9bb764ff0c1b3e001afb3", - "reference": "81698c5e32837c74abf9bb764ff0c1b3e001afb3", + "url": "https://api.github.com/repos/facade/ignition/zipball/08668034beb185fa2ac6f09b1034eaa440952ace", + "reference": "08668034beb185fa2ac6f09b1034eaa440952ace", "shasum": "" }, "require": { @@ -6121,7 +6123,7 @@ "laravel", "page" ], - "time": "2020-10-27T13:02:22+00:00" + "time": "2020-11-17T09:18:51+00:00" }, { "name": "facade/ignition-contracts", @@ -6589,16 +6591,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.10.1", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { @@ -6639,7 +6641,7 @@ "type": "tidelift" } ], - "time": "2020-06-29T13:22:24+00:00" + "time": "2020-11-13T09:40:50+00:00" }, { "name": "nikic/php-parser", @@ -7389,16 +7391,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.4.2", + "version": "9.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3866b2eeeed21b1b099c4bc0b7a1690ac6fd5baa" + "reference": "9fa359ff5ddaa5eb2be2bedb08a6a5787a5807ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3866b2eeeed21b1b099c4bc0b7a1690ac6fd5baa", - "reference": "3866b2eeeed21b1b099c4bc0b7a1690ac6fd5baa", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9fa359ff5ddaa5eb2be2bedb08a6a5787a5807ab", + "reference": "9fa359ff5ddaa5eb2be2bedb08a6a5787a5807ab", "shasum": "" }, "require": { @@ -7484,7 +7486,7 @@ "type": "github" } ], - "time": "2020-10-19T09:23:29+00:00" + "time": "2020-11-10T12:53:30+00:00" }, { "name": "psy/psysh", @@ -7564,12 +7566,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "e440567339d5fe93d9525e377c5e686b0b08bcca" + "reference": "a7ebffcf8b453dcf36a9461cb7845885cb95d315" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/e440567339d5fe93d9525e377c5e686b0b08bcca", - "reference": "e440567339d5fe93d9525e377c5e686b0b08bcca", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/a7ebffcf8b453dcf36a9461cb7845885cb95d315", + "reference": "a7ebffcf8b453dcf36a9461cb7845885cb95d315", "shasum": "" }, "conflict": { @@ -7704,9 +7706,11 @@ "phpwhois/phpwhois": "<=4.2.5", "phpxmlrpc/extras": "<0.6.1", "pimcore/pimcore": "<6.3", + "pocketmine/pocketmine-mp": "<3.15.4", "prestashop/autoupgrade": ">=4,<4.10.1", "prestashop/contactform": ">1.0.1,<4.3", "prestashop/gamification": "<2.3.2", + "prestashop/productcomments": ">=4,<4.2", "prestashop/ps_facetedsearch": "<3.4.1", "privatebin/privatebin": "<1.2.2|>=1.3,<1.3.2", "propel/propel": ">=2-alpha.1,<=2-alpha.7", @@ -7722,7 +7726,7 @@ "serluck/phpwhois": "<=4.2.6", "shopware/core": "<=6.3.2", "shopware/platform": "<=6.3.2", - "shopware/shopware": "<5.3.7", + "shopware/shopware": "<5.6.9", "silverstripe/admin": ">=1.0.3,<1.0.4|>=1.1,<1.1.1", "silverstripe/assets": ">=1,<1.4.7|>=1.5,<1.5.2", "silverstripe/cms": "<4.3.6|>=4.4,<4.4.4", @@ -7867,7 +7871,7 @@ "type": "tidelift" } ], - "time": "2020-11-07T16:07:08+00:00" + "time": "2020-11-16T22:01:59+00:00" }, { "name": "sebastian/cli-parser", @@ -8771,16 +8775,16 @@ }, { "name": "seld/jsonlint", - "version": "1.8.2", + "version": "1.8.3", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "590cfec960b77fd55e39b7d9246659e95dd6d337" + "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/590cfec960b77fd55e39b7d9246659e95dd6d337", - "reference": "590cfec960b77fd55e39b7d9246659e95dd6d337", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9ad6ce79c342fbd44df10ea95511a1b24dee5b57", + "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57", "shasum": "" }, "require": { @@ -8826,7 +8830,7 @@ "type": "tidelift" } ], - "time": "2020-08-25T06:56:57+00:00" + "time": "2020-11-11T09:19:24+00:00" }, { "name": "seld/phar-utils", diff --git a/package-lock.json b/package-lock.json index 78bf6666..1c328464 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,9 +14,9 @@ } }, "@babel/compat-data": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.1.tgz", - "integrity": "sha512-725AQupWJZ8ba0jbKceeFblZTY90McUBWMwHhkFQ9q1zKPJ95GUktljFcgcsIVwRnTnRKlcYzfiNImg5G9m6ZQ==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.5.tgz", + "integrity": "sha512-DTsS7cxrsH3by8nqQSpFSyjSfSYl57D6Cf4q8dW3LK83tBKBDCkfcay1nYkXq1nIHXnpX8WMMb/O25HOy3h1zg==", "dev": true }, "@babel/core": { @@ -44,12 +44,12 @@ } }, "@babel/generator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.1.tgz", - "integrity": "sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", + "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", "dev": true, "requires": { - "@babel/types": "^7.12.1", + "@babel/types": "^7.12.5", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -74,14 +74,14 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.1.tgz", - "integrity": "sha512-jtBEif7jsPwP27GPHs06v4WBV0KrE8a/P7n0N0sSvHn2hwUCYnolP/CLmz51IzAW4NlN+HuoBtb9QcwnRo9F/g==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz", + "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==", "dev": true, "requires": { - "@babel/compat-data": "^7.12.1", + "@babel/compat-data": "^7.12.5", "@babel/helper-validator-option": "^7.12.1", - "browserslist": "^4.12.0", + "browserslist": "^4.14.5", "semver": "^5.5.0" } }, @@ -168,12 +168,12 @@ } }, "@babel/helper-module-imports": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.1.tgz", - "integrity": "sha512-ZeC1TlMSvikvJNy1v/wPIazCu3NdOwgYZLIkmIyAsGhqkNpiDoQQRmaCK8YP4Pq3GPTLPV9WXaPCJKvx06JxKA==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.12.5" } }, "@babel/helper-module-transforms": { @@ -229,15 +229,15 @@ } }, "@babel/helper-replace-supers": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.1.tgz", - "integrity": "sha512-zJjTvtNJnCFsCXVi5rUInstLd/EIVNmIKA1Q9ynESmMBWPWd+7sdR+G4/wdu+Mppfep0XLyG2m7EBPvjCeFyrw==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", + "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.12.1", "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1" + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" } }, "@babel/helper-simple-access": { @@ -292,14 +292,14 @@ } }, "@babel/helpers": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.1.tgz", - "integrity": "sha512-9JoDSBGoWtmbay98efmT2+mySkwjzeFeAL9BuWNoVQpkPFQF8SIIFUfY5os9u8wVzglzoiPRSW7cuJmBDUt43g==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", + "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", "dev": true, "requires": { "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1" + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" } }, "@babel/highlight": { @@ -314,9 +314,9 @@ } }, "@babel/parser": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.3.tgz", - "integrity": "sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", + "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -391,9 +391,9 @@ } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.1.tgz", - "integrity": "sha512-MR7Ok+Af3OhNTCxYVjJZHS0t97ydnJZt/DbR4WISO39iDnhiD8XHrY12xuSJ90FFEGjir0Fzyyn7g/zY6hxbxA==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.5.tgz", + "integrity": "sha512-UiAnkKuOrCyjZ3sYNHlRlfuZJbBHknMQ9VMwVeX97Ofwx7RpD6gS2HfqTCh8KNUQgcOm8IKt103oR4KIjh7Q8g==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -974,9 +974,9 @@ } }, "@babel/runtime": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz", - "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -994,26 +994,26 @@ } }, "@babel/traverse": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.1.tgz", - "integrity": "sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", + "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.1", + "@babel/generator": "^7.12.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.1", - "@babel/types": "^7.12.1", + "@babel/parser": "^7.12.5", + "@babel/types": "^7.12.5", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.1.tgz", - "integrity": "sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==", + "version": "7.12.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", + "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -1060,9 +1060,9 @@ "dev": true }, "@types/node": { - "version": "14.14.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.2.tgz", - "integrity": "sha512-jeYJU2kl7hL9U5xuI/BhKPZ4vqGM/OmK6whiFAXVhlstzZhVamWhDSmHyGLIp+RVyuF9/d0dqr2P85aFj4BvJg==", + "version": "14.14.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.7.tgz", + "integrity": "sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg==", "dev": true }, "@types/q": { @@ -1654,14 +1654,14 @@ } }, "babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.1.tgz", + "integrity": "sha512-dMF8sb2KQ8kJl21GUjkW1HWmcsL39GOV5vnzjqrCzEPNY0S0UfMLnumidiwIajDSBmKhYf5iRW+HXaM4cvCKBw==", "dev": true, "requires": { "find-cache-dir": "^2.1.0", "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", + "make-dir": "^2.1.0", "pify": "^4.0.1", "schema-utils": "^2.6.5" }, @@ -1776,9 +1776,9 @@ } }, "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, "batch": { @@ -1976,21 +1976,13 @@ } }, "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", "dev": true, "requires": { - "bn.js": "^4.1.0", + "bn.js": "^5.0.0", "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } } }, "browserify-sign": { @@ -2039,15 +2031,16 @@ } }, "browserslist": { - "version": "4.14.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.5.tgz", - "integrity": "sha512-Z+vsCZIvCBvqLoYkBFTwEYH3v5MCQbsAjp50ERycpOjnPmolg1Gjy4+KaWWpm8QOJt9GHkhdqAl14NpCX73CWA==", + "version": "4.14.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.7.tgz", + "integrity": "sha512-BSVRLCeG3Xt/j/1cCGj1019Wbty0H+Yvu2AOuZSuoaUWn3RatbL33Cxk+Q4jRMRAbOm0p7SLravLjpnT6s0vzQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001135", - "electron-to-chromium": "^1.3.571", - "escalade": "^3.1.0", - "node-releases": "^1.1.61" + "caniuse-lite": "^1.0.30001157", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.591", + "escalade": "^3.1.1", + "node-releases": "^1.1.66" } }, "buffer": { @@ -2134,6 +2127,16 @@ "unset-value": "^1.0.0" } }, + "call-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", + "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.0" + } + }, "call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", @@ -2193,9 +2196,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001150", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001150.tgz", - "integrity": "sha512-kiNKvihW0m36UhAFnl7bOAv0i1K1f6wpfVtTF5O5O82XzgtBnb05V0XeV3oZ968vfg2sRNChsHw8ASH2hDfoYQ==", + "version": "1.0.30001158", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001158.tgz", + "integrity": "sha512-s5loVYY+yKpuVA3HyW8BarzrtJvwHReuzugQXlv1iR3LKSReoFXRm86mT6hT7PEF5RxW+XQZg+6nYjlywYzQ+g==", "dev": true }, "cardinal": { @@ -2377,9 +2380,9 @@ } }, "collect.js": { - "version": "4.28.4", - "resolved": "https://registry.npmjs.org/collect.js/-/collect.js-4.28.4.tgz", - "integrity": "sha512-NJXATt6r+gtGOgDJOKLeooTY6QpGn8YQN/PkKnCmajJOguz/xGPgPrTyrBkmBBTHXnniPRIkUqjqt3AkjwCKlg==", + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/collect.js/-/collect.js-4.28.5.tgz", + "integrity": "sha512-uMhSsveaJUxQJPqt942me4IzP0Esig+RfThxGtJLIJ049GBRj60/J5fUK1hxR2crj64IrHMc17a1svBPFm2pzw==", "dev": true }, "collection-visit": { @@ -2612,12 +2615,12 @@ "dev": true }, "core-js-compat": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", - "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.7.0.tgz", + "integrity": "sha512-V8yBI3+ZLDVomoWICO6kq/CD28Y4r1M7CWeO4AGpMdMfseu8bkSubBmUPySMGKRTS+su4XQ07zUkAsiu9FCWTg==", "dev": true, "requires": { - "browserslist": "^4.8.5", + "browserslist": "^4.14.6", "semver": "7.0.0" }, "dependencies": { @@ -2954,28 +2957,28 @@ "dev": true }, "csso": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", - "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.1.1.tgz", + "integrity": "sha512-Rvq+e1e0TFB8E8X+8MQjHSY6vtol45s5gxtLI/018UsAn2IBMmwNEZRM/h+HVnAJRHjasLIKKUO3uvoMM28LvA==", "dev": true, "requires": { - "css-tree": "1.0.0-alpha.39" + "css-tree": "^1.0.0" }, "dependencies": { "css-tree": { - "version": "1.0.0-alpha.39", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", - "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.1.tgz", + "integrity": "sha512-WroX+2MvsYcRGP8QA0p+rxzOniT/zpAoQ/DTKDSJzh5T3IQKUkFHeIIfgIapm2uaP178GWY3Mime1qbk8GO/tA==", "dev": true, "requires": { - "mdn-data": "2.0.6", + "mdn-data": "2.0.12", "source-map": "^0.6.1" } }, "mdn-data": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", - "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.12.tgz", + "integrity": "sha512-ULbAlgzVb8IqZ0Hsxm6hHSlQl3Jckst2YEQS7fODu9ilNWy2LvcoSY7TRFIktABP2mdppBioc66va90T+NUs8Q==", "dev": true }, "source-map": { @@ -2987,9 +2990,9 @@ } }, "csv-parse": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.12.0.tgz", - "integrity": "sha512-wPQl3H79vWLPI8cgKFcQXl0NBgYYEqVnT1i6/So7OjMpsI540oD7p93r3w6fDSyPvwkTepG05F69/7AViX2lXg==" + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.14.1.tgz", + "integrity": "sha512-4wmcO7QbWtDAncGFaBwlWFPhEN4Akr64IbM4zvDwEOFekI8blLc04Nw7XjQjtSNy+3AUAgBgtUa9nWo5Cq89Xg==" }, "cyclist": { "version": "1.0.1", @@ -3326,9 +3329,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.582", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.582.tgz", - "integrity": "sha512-0nCJ7cSqnkMC+kUuPs0YgklFHraWGl/xHqtZWWtOeVtyi+YqkoAOMGuZQad43DscXCQI/yizcTa3u6B5r+BLww==", + "version": "1.3.597", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.597.tgz", + "integrity": "sha512-VJI21MucKaqyFw0oe3j9BIg+nDF4MHzUZAmUwZzrxho+s8zPCD13Fds07Rgu+MTtAadO4tYTKFdAUksKYUyIJw==", "dev": true }, "elliptic": { @@ -3438,9 +3441,9 @@ } }, "es-abstract": { - "version": "1.18.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", @@ -3448,7 +3451,6 @@ "has": "^1.0.3", "has-symbols": "^1.0.1", "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", "is-regex": "^1.1.1", "object-inspect": "^1.8.0", "object-keys": "^1.1.1", @@ -4241,9 +4243,9 @@ "dev": true }, "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, "get-caller-file": { @@ -4252,6 +4254,17 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", + "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -4727,9 +4740,9 @@ } }, "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true }, "iferr": { @@ -4978,9 +4991,9 @@ } }, "is-core-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz", - "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", + "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", "dev": true, "requires": { "has": "^1.0.3" @@ -5037,6 +5050,12 @@ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, + "is-docker": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "dev": true + }, "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", @@ -5312,9 +5331,9 @@ "dev": true }, "laravel-mix": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/laravel-mix/-/laravel-mix-5.0.7.tgz", - "integrity": "sha512-TL5txnQkzcwM8DYckgzjISSPGyZN6znFYb4NgtTSi9aIvfzOIEC6p0eYM6wDa/BkEKv290Ru6HWmH6Q2XApogQ==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/laravel-mix/-/laravel-mix-5.0.9.tgz", + "integrity": "sha512-1WCJiHimTRW3KlxcabRTco0q+bo4uKPaFTkc6cJ/bLEq4JT1aPkojoauUK7+PyiIlDJncw0Nt2MtDrv5C6j5IQ==", "dev": true, "requires": { "@babel/core": "^7.2.0", @@ -5873,18 +5892,33 @@ } }, "node-notifier": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", - "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", + "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", "dev": true, "requires": { "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", + "is-wsl": "^2.1.1", + "semver": "^6.3.0", "shellwords": "^0.1.1", - "which": "^1.3.0" + "which": "^1.3.1" }, "dependencies": { + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -5897,9 +5931,9 @@ } }, "node-releases": { - "version": "1.1.64", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.64.tgz", - "integrity": "sha512-Iec8O9166/x2HRMJyLLLWkd0sFFLrFNy+Xf+JQfSQsdBJzPcHpNl3JQ9gD4j+aJxmCa25jNsIbM4bmACtSbkSg==", + "version": "1.1.67", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.67.tgz", + "integrity": "sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==", "dev": true }, "normalize-path": { @@ -6003,6 +6037,28 @@ "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "object-keys": { @@ -6021,13 +6077,13 @@ } }, "object.assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", - "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.0", "has-symbols": "^1.0.1", "object-keys": "^1.1.1" } @@ -6040,27 +6096,6 @@ "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } } }, "object.omit": { @@ -6091,27 +6126,6 @@ "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } } }, "obuf": { @@ -7365,9 +7379,9 @@ } }, "regenerate": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", - "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true }, "regenerate-unicode-properties": { @@ -7418,27 +7432,6 @@ "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } } }, "regexpu-core": { @@ -7527,12 +7520,12 @@ "dev": true }, "resolve": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", - "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "requires": { - "is-core-module": "^2.0.0", + "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } }, @@ -7724,9 +7717,9 @@ "dev": true }, "sass": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.27.0.tgz", - "integrity": "sha512-0gcrER56OkzotK/GGwgg4fPrKuiFlPNitO7eUJ18Bs+/NBlofJfMxmxqpqJxjae9vu0Wq8TZzrSyxZal00WDig==", + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.29.0.tgz", + "integrity": "sha512-ZpwAUFgnvAUCdkjwPREny+17BpUj8nh5Yr6zKPGtLNTLrmtoRYIjm7njP24COhjJldjwW1dcv52Lpf4tNZVVRA==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" @@ -8493,6 +8486,28 @@ "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "string.prototype.trimstart": { @@ -8503,6 +8518,28 @@ "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "string_decoder": { @@ -8759,9 +8796,9 @@ "dev": true }, "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", "dev": true, "requires": { "setimmediate": "^1.0.4" @@ -9121,27 +9158,6 @@ "es-abstract": "^1.17.2", "has-symbols": "^1.0.1", "object.getownpropertydescriptors": "^2.1.0" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } } }, "utils-merge": { @@ -9157,9 +9173,9 @@ "dev": true }, "v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, "vary": { @@ -9187,9 +9203,9 @@ "dev": true }, "vue-loader": { - "version": "15.9.3", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.3.tgz", - "integrity": "sha512-Y67VnGGgVLH5Voostx8JBZgPQTlDQeOVBLOEsjc2cXbCYBKexSKEpOA56x0YZofoDOTszrLnIShyOX1p9uCEHA==", + "version": "15.9.5", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.5.tgz", + "integrity": "sha512-oeMOs2b5o5gRqkxfds10bCx6JeXYTwivRgbb8hzOrcThD2z1+GqEKE3EX9A2SGbsYDf4rXwRg6D5n1w0jO5SwA==", "dev": true, "requires": { "@vue/component-compiler-utils": "^3.1.0", @@ -9226,15 +9242,15 @@ "dev": true }, "watchpack": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", - "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", "dev": true, "requires": { "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.0" + "watchpack-chokidar2": "^2.0.1" }, "dependencies": { "anymatch": { @@ -9349,9 +9365,9 @@ } }, "watchpack-chokidar2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", - "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", "dev": true, "optional": true, "requires": { @@ -9782,12 +9798,12 @@ } }, "webpack-notifier": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.8.0.tgz", - "integrity": "sha512-I6t76NoPe5DZCCm5geELmDV2wlJ89LbU425uN6T2FG8Ywrrt1ZcUMz6g8yWGNg4pttqTPFQJYUPjWAlzUEQ+cQ==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.10.1.tgz", + "integrity": "sha512-1ntvm2QwT+i21Nur88HU/WaaDq1Ppq1XCpBR0//wb6gPJ65IkRkuYzIu8z8MpnkLEHj9wSf+yNUzMANyqvvtWg==", "dev": true, "requires": { - "node-notifier": "^5.1.2", + "node-notifier": "^6.0.0", "object-assign": "^4.1.0", "strip-ansi": "^3.0.1" } diff --git a/package.json b/package.json index 52839cb2..d0bd836c 100755 --- a/package.json +++ b/package.json @@ -14,9 +14,9 @@ }, "devDependencies": { "cross-env": "^6.0.3", - "laravel-mix": "^5.0.7", + "laravel-mix": "^5.0.9", "resolve-url-loader": "^3.1.2", - "sass": "^1.27.0", + "sass": "^1.29.0", "sass-loader": "^8.0.2", "vue-template-compiler": "^2.6.12" }, From 40356ad2238f555b8ab27c1a84de7c69bb441790 Mon Sep 17 00:00:00 2001 From: Kovah Date: Tue, 17 Nov 2020 20:13:30 +0100 Subject: [PATCH 24/29] Add missing AWS S3 driver, update backup package related config and docs --- .env.docker | 4 +- .env.docker.production | 4 +- composer.json | 1 + composer.lock | 191 ++++++++++++++++++++++++++++++++++++++++- config/backup.php | 63 +++++++++----- 5 files changed, 235 insertions(+), 28 deletions(-) diff --git a/.env.docker b/.env.docker index a1fa4fa1..800d3fcf 100644 --- a/.env.docker +++ b/.env.docker @@ -24,9 +24,9 @@ SESSION_LIFETIME=10080 ## Backup configuration # Enable backups here BACKUP_ENABLED=false -# Choose the destination of the backup. If you set up AWS S3 credentials below you may choose 'cloud' which is used +# Choose the destination of the backup. If you set up AWS S3 credentials below you may choose 's3' which is used # as a synonym for AWS. Leave blank or set to 'local' if you want to store backups within /storage/app/backups. -BACKUP_DISK=cloud +BACKUP_DISK=s3 # Set to false if you do not want to be notified about successful or broken backups BACKUP_NOTIFICATIONS=true # The notification email may be used to get backup notifications diff --git a/.env.docker.production b/.env.docker.production index ce16ed5d..bf327984 100644 --- a/.env.docker.production +++ b/.env.docker.production @@ -24,9 +24,9 @@ SESSION_LIFETIME=10080 ## Backup configuration # Enable backups here BACKUP_ENABLED=false -# Choose the destination of the backup. If you set up AWS S3 credentials below you may choose 'cloud' which is used +# Choose the destination of the backup. If you set up AWS S3 credentials below you may choose 's3' which is used # as a synonym for AWS. Leave blank or set to 'local' if you want to store backups within /storage/app/backups. -BACKUP_DISK=cloud +BACKUP_DISK=s3 # Set to false if you do not want to be notified about successful or broken backups BACKUP_NOTIFICATIONS=true # The notification email may be used to get backup notifications diff --git a/composer.json b/composer.json index ee0c2049..d3787ed8 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "laravel/fortify": "^1.7", "laravel/framework": "^8.0", "league/csv": "^9.6", + "league/flysystem-aws-s3-v3": "^1.0", "predis/predis": "^1.1", "shaarli/netscape-bookmark-parser": "^2.1", "spatie/laravel-backup": "^6.11.1", diff --git a/composer.lock b/composer.lock index 50e9c4dd..4d68f22e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,93 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ca1d0154e63b5d72e092e495ed8413d0", + "content-hash": "75b1c669e82522bdf5dcccfe11be3470", "packages": [ + { + "name": "aws/aws-sdk-php", + "version": "3.161.2", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "2703896142f292058ce9d6c9026a9329a89778e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2703896142f292058ce9d6c9026a9329a89778e0", + "reference": "2703896142f292058ce9d6c9026a9329a89778e0", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^5.3.3|^6.2.1|^7.0", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4.1", + "mtdowling/jmespath.php": "^2.5", + "php": ">=5.5" + }, + "require-dev": { + "andrewsville/php-token-reflection": "^1.4", + "aws/aws-php-sns-message-validator": "~1.0", + "behat/behat": "~3.0", + "doctrine/cache": "~1.4", + "ext-dom": "*", + "ext-openssl": "*", + "ext-pcntl": "*", + "ext-sockets": "*", + "nette/neon": "^2.3", + "paragonie/random_compat": ">= 2", + "phpunit/phpunit": "^4.8.35|^5.4.3", + "psr/cache": "^1.0", + "psr/simple-cache": "^1.0", + "sebastian/comparator": "^1.2.3" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Aws\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "time": "2020-11-16T19:11:59+00:00" + }, { "name": "bacon/bacon-qr-code", "version": "2.0.3", @@ -1729,6 +1814,53 @@ ], "time": "2020-08-23T07:39:11+00:00" }, + { + "name": "league/flysystem-aws-s3-v3", + "version": "1.0.29", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git", + "reference": "4e25cc0582a36a786c31115e419c6e40498f6972" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/4e25cc0582a36a786c31115e419c6e40498f6972", + "reference": "4e25cc0582a36a786c31115e419c6e40498f6972", + "shasum": "" + }, + "require": { + "aws/aws-sdk-php": "^3.20.0", + "league/flysystem": "^1.0.40", + "php": ">=5.5.0" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "~1.0.1", + "phpspec/phpspec": "^2.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Flysystem\\AwsS3v3\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Flysystem adapter for the AWS S3 SDK v3.x", + "time": "2020-10-08T18:58:37+00:00" + }, { "name": "league/mime-type-detection", "version": "1.5.1", @@ -1871,6 +2003,63 @@ ], "time": "2020-07-23T08:41:23+00:00" }, + { + "name": "mtdowling/jmespath.php", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "42dae2cbd13154083ca6d70099692fef8ca84bfb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/42dae2cbd13154083ca6d70099692fef8ca84bfb", + "reference": "42dae2cbd13154083ca6d70099692fef8ca84bfb", + "shasum": "" + }, + "require": { + "php": "^5.4 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^1.4", + "phpunit/phpunit": "^4.8.36 || ^7.5.15" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "JmesPath\\": "src/" + }, + "files": [ + "src/JmesPath.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "time": "2020-07-31T21:01:56+00:00" + }, { "name": "nesbot/carbon", "version": "2.41.5", diff --git a/config/backup.php b/config/backup.php index 4c86dd6a..b13a2e9f 100644 --- a/config/backup.php +++ b/config/backup.php @@ -1,9 +1,5 @@ [ @@ -12,7 +8,7 @@ * The name of this application. You can use this name to monitor * the backups. */ - 'name' => 'backups', + 'name' => env('APP_NAME', 'laravel-backup'), 'source' => [ @@ -33,13 +29,17 @@ 'exclude' => [ base_path('vendor'), base_path('node_modules'), - storage_path('app/backups'), ], /* * Determines if symlinks should be followed. */ 'follow_links' => false, + + /* + * Determines if it should avoid unreadable folders. + */ + 'ignore_unreadable_directories' => false, ], /* @@ -88,7 +88,7 @@ * * If you do not want any compressor at all, set it to null. */ - 'database_dump_compressor' => Spatie\DbDumper\Compressors\GzipCompressor::class, + 'database_dump_compressor' => null, 'destination' => [ @@ -101,7 +101,7 @@ * The disk names on which the backups will be stored. */ 'disks' => [ - env('BACKUP_DISK', 'local'), + env('BACKUP_DISK', 'local_backups'), ], ], @@ -113,7 +113,7 @@ /* * You can get notified when specific events occur. Out of the box you can use 'mail' and 'slack'. - * For Slack you need to install guzzlehttp/guzzle. + * For Slack you need to install guzzlehttp/guzzle and laravel/slack-notification-channel. * * You can also use your own notification classes, just make sure the class is named after one of * the `Spatie\Backup\Events` classes. @@ -121,12 +121,12 @@ 'notifications' => [ 'notifications' => [ - \Spatie\Backup\Notifications\Notifications\BackupHasFailed::class => $backupNotificationChannel, - \Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFound::class => $backupNotificationChannel, - \Spatie\Backup\Notifications\Notifications\CleanupHasFailed::class => $backupNotificationChannel, - \Spatie\Backup\Notifications\Notifications\BackupWasSuccessful::class => $backupNotificationChannel, - \Spatie\Backup\Notifications\Notifications\HealthyBackupWasFound::class => $backupNotificationChannel, - \Spatie\Backup\Notifications\Notifications\CleanupWasSuccessful::class => $backupNotificationChannel, + \Spatie\Backup\Notifications\Notifications\BackupHasFailed::class => ['mail'], + \Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFound::class => ['mail'], + \Spatie\Backup\Notifications\Notifications\CleanupHasFailed::class => ['mail'], + \Spatie\Backup\Notifications\Notifications\BackupWasSuccessful::class => ['mail'], + \Spatie\Backup\Notifications\Notifications\HealthyBackupWasFound::class => ['mail'], + \Spatie\Backup\Notifications\Notifications\CleanupWasSuccessful::class => ['mail'], ], /* @@ -136,20 +136,25 @@ 'notifiable' => \Spatie\Backup\Notifications\Notifiable::class, 'mail' => [ - 'to' => env('BACKUP_NOTIFICATION_EMAIL') ?: User::find(1)->mail ?? null, + 'to' => env('BACKUP_NOTIFICATION_EMAIL'), + + 'from' => [ + 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_FROM_NAME', 'Example'), + ], ], 'slack' => [ - 'webhook_url' => env('BACKUP_NOTIFICATION_SLACK_WEBHOOK', ''), + 'webhook_url' => '', /* * If this is set to null the default channel of the webhook will be used. */ - 'channel' => env('BACKUP_NOTIFICATION_SLACK_CHANNEL', null), + 'channel' => null, - 'username' => env('BACKUP_NOTIFICATION_SLACK_USERNAME', null), + 'username' => null, - 'icon' => env('BACKUP_NOTIFICATION_SLACK_ICON', null), + 'icon' => null, ], ], @@ -161,13 +166,24 @@ */ 'monitor_backups' => [ [ - 'name' => 'backups', + 'name' => env('APP_NAME', 'laravel-backup'), 'disks' => [env('BACKUP_DISK', 'local_backups')], 'health_checks' => [ \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1, - \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => env('BACKUP_MAX_SIZE', 512), + \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000, ], ], + + /* + [ + 'name' => 'name of the second app', + 'disks' => ['local', 's3'], + 'health_checks' => [ + \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1, + \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000, + ], + ], + */ ], 'cleanup' => [ @@ -213,7 +229,8 @@ * After cleaning up the backups remove the oldest backup until * this amount of megabytes has been reached. */ - 'delete_oldest_backups_when_using_more_megabytes_than' => env('BACKUP_MAX_SIZE', 512), + 'delete_oldest_backups_when_using_more_megabytes_than' => 5000, ], ], + ]; From 2264e7bdf686f1a890214e41240386dcc3d06371 Mon Sep 17 00:00:00 2001 From: Kovah Date: Tue, 17 Nov 2020 20:17:11 +0100 Subject: [PATCH 25/29] 0.0.44 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1c328464..e8d2e757 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "linkace", - "version": "0.0.43", + "version": "0.0.44", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d0bd836c..8ccc0c82 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "linkace", - "version": "0.0.43", + "version": "0.0.44", "description": "A small, selfhosted bookmark manager with advanced features, built with Laravel and Docker", "homepage": "https://github.com/Kovah/LinkAce", "repository": { From 5f0ad02d397f702da151e8e96864b76c8bdf91f7 Mon Sep 17 00:00:00 2001 From: Kovah Date: Thu, 19 Nov 2020 17:30:22 +0100 Subject: [PATCH 26/29] Add viewer for system logs --- composer.json | 1 + composer.lock | 61 +++++++++- resources/lang/en_US/linkace.php | 1 + resources/views/partials/nav-user.blade.php | 3 + .../vendor/laravel-log-viewer/log.blade.php | 109 ++++++++++++++++++ routes/web.php | 4 + 6 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 resources/views/vendor/laravel-log-viewer/log.blade.php diff --git a/composer.json b/composer.json index d3787ed8..17c44d74 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ "league/csv": "^9.6", "league/flysystem-aws-s3-v3": "^1.0", "predis/predis": "^1.1", + "rap2hpoutre/laravel-log-viewer": "^1.7", "shaarli/netscape-bookmark-parser": "^2.1", "spatie/laravel-backup": "^6.11.1", "venturecraft/revisionable": "^1.34" diff --git a/composer.lock b/composer.lock index 4d68f22e..bbd5f054 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": "75b1c669e82522bdf5dcccfe11be3470", + "content-hash": "7813e50f9489a043cfe6645ef4dc3435", "packages": [ { "name": "aws/aws-sdk-php", @@ -2945,6 +2945,65 @@ ], "time": "2020-08-18T17:17:46+00:00" }, + { + "name": "rap2hpoutre/laravel-log-viewer", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/rap2hpoutre/laravel-log-viewer.git", + "reference": "27392d29234b6ff38a456454558f4bcc40cc837a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rap2hpoutre/laravel-log-viewer/zipball/27392d29234b6ff38a456454558f4bcc40cc837a", + "reference": "27392d29234b6ff38a456454558f4bcc40cc837a", + "shasum": "" + }, + "require": { + "illuminate/support": "4.2.*|5.*|^6.0|^7.0|^8.0", + "php": ">=5.4.0" + }, + "require-dev": { + "orchestra/testbench": "3.7.*", + "phpunit/phpunit": "^7" + }, + "type": "laravel-package", + "extra": { + "laravel": { + "providers": [ + "Rap2hpoutre\\LaravelLogViewer\\LaravelLogViewerServiceProvider" + ] + } + }, + "autoload": { + "classmap": [ + "src/controllers" + ], + "psr-0": { + "Rap2hpoutre\\LaravelLogViewer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "rap2hpoutre", + "email": "raphaelht@gmail.com" + } + ], + "description": "A Laravel log reader", + "keywords": [ + "laravel", + "log", + "log-reader", + "log-viewer", + "logging", + "lumen" + ], + "time": "2020-09-08T12:21:27+00:00" + }, { "name": "shaarli/netscape-bookmark-parser", "version": "v2.2.0", diff --git a/resources/lang/en_US/linkace.php b/resources/lang/en_US/linkace.php index e11c9069..bb740222 100644 --- a/resources/lang/en_US/linkace.php +++ b/resources/lang/en_US/linkace.php @@ -11,6 +11,7 @@ 'logout' => 'Logout', 'remember_me' => 'Remember me', 'go_to_dashboard' => 'Go to the Dashboard', + 'system_logs' => 'System Logs', 'reset_password' => 'Reset Password', 'send_reset_email' => 'Send Password Reset Link', diff --git a/resources/views/partials/nav-user.blade.php b/resources/views/partials/nav-user.blade.php index 79941c56..80ff9072 100644 --- a/resources/views/partials/nav-user.blade.php +++ b/resources/views/partials/nav-user.blade.php @@ -27,6 +27,9 @@ @lang('settings.system_settings') + + @lang('linkace.system_logs') +
@else diff --git a/resources/views/vendor/laravel-log-viewer/log.blade.php b/resources/views/vendor/laravel-log-viewer/log.blade.php new file mode 100644 index 00000000..7a5a71c8 --- /dev/null +++ b/resources/views/vendor/laravel-log-viewer/log.blade.php @@ -0,0 +1,109 @@ +@extends('layouts.app') + +@section('content') + +
+

Laravel Log Viewer

+ +
+ @foreach($folders as $folder) +
+ + {{$folder}} + + @if ($current_folder == $folder) +
+ @foreach($folder_files as $file) + + {{$file}} + + @endforeach +
+ @endif +
+ @endforeach + @foreach($files as $file) + + {{$file}} + + @endforeach +
+
+ +
+ @if ($logs === null) +
+ Log file >50M, please download it. +
+ @else + + + + @if ($standardFormat) + + + + @else + + @endif + + + + + + @foreach($logs as $key => $log) + + @if ($standardFormat) + + + @endif + + + + @endforeach + + +
LevelContextDateLine numberContent
+ {{$log['level']}} + {{$log['context']}}{{{$log['date']}}} + {{{$log['text']}}} + @if (isset($log['in_file'])) +
{{{$log['in_file']}}} + @endif + @if ($log['stack']) + + @endif +
+ @endif + +
+ @if($current_file) + + Download file + + + + Clean file + + + + Delete file + + + @if(count($files) > 1) + + Delete all files + + @endif + @endif +
+
+@endsection diff --git a/routes/web.php b/routes/web.php index b14fd9af..2eb1da95 100644 --- a/routes/web.php +++ b/routes/web.php @@ -26,6 +26,7 @@ use App\Http\Controllers\Setup\MetaController; use App\Http\Controllers\Setup\RequirementsController; use Illuminate\Support\Facades\Route; +use Rap2hpoutre\LaravelLogViewer\LogViewerController; // Frontpage Route::get('/', FrontController::class)->name('front'); @@ -121,6 +122,9 @@ ->name('fetch-html-for-url'); Route::get('fetch/update-check', [FetchController::class, 'checkForUpdates']) ->name('fetch-update-check'); + + Route::get('system/logs', [LogViewerController::class, 'index']) + ->name('system-logs'); }); // Guest access routes From 32fca097dba87c56e949f2ac2cf0c03fcd1ee58b Mon Sep 17 00:00:00 2001 From: Kovah Date: Thu, 19 Nov 2020 17:31:55 +0100 Subject: [PATCH 27/29] Switch to Docker volumes for storage of logs --- docker-compose.production-simple.yml | 3 ++- docker-compose.production.yml | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docker-compose.production-simple.yml b/docker-compose.production-simple.yml index 3a48336c..ad11ca38 100644 --- a/docker-compose.production-simple.yml +++ b/docker-compose.production-simple.yml @@ -26,12 +26,13 @@ services: volumes: - ./.env:/app/.env - ./nginx-simple.conf:/opt/docker/etc/nginx/conf.d/linkace.conf:ro - - ./logs:/app/storage/logs + - linkace_logs:/app/storage/logs # Remove the hash of the following line if you want to use local backups #- ./backups:/app/storage/app/backups # Remove the hash of the following line if you are using HTTPS #- /path/to/your/ssl/certificates:/opt/docker/etc/nginx/ssl volumes: + linkace_logs: db: driver: local diff --git a/docker-compose.production.yml b/docker-compose.production.yml index c437bbc0..03f29774 100644 --- a/docker-compose.production.yml +++ b/docker-compose.production.yml @@ -21,9 +21,9 @@ services: depends_on: - db volumes: - - linkace_app:/app - ./.env:/app/.env - - ./logs:/app/storage/logs + - linkace_app:/app + - linkace_logs:/app/storage/logs # Remove the hash of the following line if you want to use local backups #- ./backups:/app/storage/app/backups @@ -50,5 +50,6 @@ services: volumes: linkace_app: + linkace_logs: db: driver: local From 9cddf888e9a1dd113d213a2802d84c14abe3d6d8 Mon Sep 17 00:00:00 2001 From: Kovah Date: Thu, 19 Nov 2020 23:54:20 +0100 Subject: [PATCH 28/29] Add new community in readme, switch logo image, optimize primary badges --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3016fc1c..410aecce 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- +

 

@@ -7,7 +7,8 @@

Your self-hosted bookmark archive. Free and open source.

- Follow LinkAce on Twitter + Get support for LinkAce and chat about the project + Follow LinkAce on Twitter Docker Repository Latest Release License @@ -52,7 +53,7 @@ More features are already planned. Take a look at the [project board](https://gi #### Documentation and Community -Any further information about all the available features and how to install the app, can be found on the [LinkAce Website](https://www.linkace.org/). Additionally, you may visit the [community forums](https://spectrum.chat/linkace/) to share your ideas, talk with other users or find help for specific problems. +Any further information about all the available features and how to install the app, can be found on the [LinkAce Website](https://www.linkace.org/). Additionally, you may visit the [community forums](https://community.linkace.org/) to share your ideas, talk with other users or find help for specific problems. --- @@ -60,7 +61,7 @@ Any further information about all the available features and how to install the ### :bulb: Support for LinkAce -I built LinkAce to solve my problem, and I now offer my solution and code to your without charging anything. Thus I won't offer any free personal support, customization or installation help. If you need help please visit the [community forum](https://spectrum.chat/linkace/) and post your issue there. +I built LinkAce to solve my problem, and I now offer my solution and code to your without charging anything. Thus I won't offer any free personal support, customization or installation help. If you need help please visit the [community forum](https://community.linkace.org/) and post your issue there. You can get personal and dedicated support by **becoming a [Patreon](https://www.patreon.com/Kovah)** or **[Github Sponsor](https://github.com/sponsors/Kovah)**. :star: From 2c050889a749e1182ae61024273355f39c372bed Mon Sep 17 00:00:00 2001 From: Kovah Date: Fri, 20 Nov 2020 11:20:10 +0100 Subject: [PATCH 29/29] Update the readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 410aecce..d5a34b35 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Any further information about all the available features and how to install the ### :bulb: Support for LinkAce -I built LinkAce to solve my problem, and I now offer my solution and code to your without charging anything. Thus I won't offer any free personal support, customization or installation help. If you need help please visit the [community forum](https://community.linkace.org/) and post your issue there. +I built LinkAce to solve my problem, and I now offer my solution and code to your without charging anything. I spent a lot of my free time building this application already, so I won't offer any *free* personal support, customization or installation help. If you need help please visit the [community forum](https://community.linkace.org/) and post your issue there. You can get personal and dedicated support by **becoming a [Patreon](https://www.patreon.com/Kovah)** or **[Github Sponsor](https://github.com/sponsors/Kovah)**. :star: