From ca764caf2d55a5c9bac61718d656423b0c3a060b Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 8 Oct 2021 23:19:37 +0100 Subject: [PATCH 1/9] Added throttling to password reset requests --- app/Config/auth.php | 1 + .../Auth/ForgotPasswordController.php | 2 +- tests/Auth/AuthTest.php | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app/Config/auth.php b/app/Config/auth.php index 404b5352d..23b9039b9 100644 --- a/app/Config/auth.php +++ b/app/Config/auth.php @@ -70,6 +70,7 @@ return [ 'email' => 'emails.password', 'table' => 'password_resets', 'expire' => 60, + 'throttle' => 60, ], ], diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php index 3df0608f8..8eaee08a2 100644 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -56,7 +56,7 @@ class ForgotPasswordController extends Controller $this->logActivity(ActivityType::AUTH_PASSWORD_RESET, $request->get('email')); } - if ($response === Password::RESET_LINK_SENT || $response === Password::INVALID_USER) { + if (in_array($response, [Password::RESET_LINK_SENT, Password::INVALID_USER, Password::RESET_THROTTLED])) { $message = trans('auth.reset_password_sent', ['email' => $request->get('email')]); $this->showSuccessNotification($message); diff --git a/tests/Auth/AuthTest.php b/tests/Auth/AuthTest.php index d037b5701..f19011c46 100644 --- a/tests/Auth/AuthTest.php +++ b/tests/Auth/AuthTest.php @@ -282,6 +282,22 @@ class AuthTest extends TestCase ->assertElementContains('a', 'Sign up'); } + public function test_reset_password_request_is_throttled() + { + $editor = $this->getEditor(); + Notification::fake(); + $this->get('/password/email'); + $this->followingRedirects()->post('/password/email', [ + 'email' => $editor->email, + ]); + + $resp = $this->followingRedirects()->post('/password/email', [ + 'email' => $editor->email, + ]); + Notification::assertTimesSent(1, ResetPassword::class); + $resp->assertSee('A password reset link will be sent to ' . $editor->email . ' if that email address is found in the system.'); + } + public function test_login_redirects_to_initially_requested_url_correctly() { config()->set('app.url', 'http://localhost'); From b043257d9a7570e5055500948358c3ef95795378 Mon Sep 17 00:00:00 2001 From: Haxatron <76475453+Haxatron@users.noreply.github.com> Date: Sun, 10 Oct 2021 01:06:08 +0800 Subject: [PATCH 2/9] Update dompdf.php base_path => public_path --- app/Config/dompdf.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Config/dompdf.php b/app/Config/dompdf.php index cf07312e8..a5490294c 100644 --- a/app/Config/dompdf.php +++ b/app/Config/dompdf.php @@ -70,7 +70,7 @@ return [ * direct class use like: * $dompdf = new DOMPDF(); $dompdf->load_html($htmldata); $dompdf->render(); $pdfdata = $dompdf->output(); */ - 'chroot' => realpath(base_path()), + 'chroot' => realpath(public_path()), /** * Whether to use Unicode fonts or not. From 9b8bb49a33b0461e723ccb9a38091547e2273eaf Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 14 Oct 2021 15:33:08 +0100 Subject: [PATCH 3/9] Added custom whoops-based debug view Provides a simple bookstack focused view that does not rely on JavaScript. Contains links to BookStack specific resources in addition to commonly desired debug details. --- .../WhoopsBookStackPrettyHandler.php | 51 ++++ app/Providers/AppServiceProvider.php | 6 + composer.json | 2 +- composer.lock | 286 +----------------- resources/views/errors/debug.blade.php | 146 +++++++++ 5 files changed, 212 insertions(+), 279 deletions(-) create mode 100644 app/Exceptions/WhoopsBookStackPrettyHandler.php create mode 100644 resources/views/errors/debug.blade.php diff --git a/app/Exceptions/WhoopsBookStackPrettyHandler.php b/app/Exceptions/WhoopsBookStackPrettyHandler.php new file mode 100644 index 000000000..4e92b1d84 --- /dev/null +++ b/app/Exceptions/WhoopsBookStackPrettyHandler.php @@ -0,0 +1,51 @@ +getException(); + echo view('errors.debug', [ + 'error' => $exception->getMessage(), + 'errorClass' => get_class($exception), + 'trace' => $exception->getTraceAsString(), + 'environment' => $this->getEnvironment(), + ])->render(); + return Handler::QUIT; + } + + protected function safeReturn(callable $callback, $default = null) { + try { + return $callback(); + } catch (\Exception $e) { + return $default; + } + } + + protected function getEnvironment(): array + { + return [ + 'PHP Version' => phpversion(), + 'BookStack Version' => $this->safeReturn(function() { + $versionFile = base_path('version'); + return trim(file_get_contents($versionFile)); + }, 'unknown'), + 'Theme Configured' => $this->safeReturn(function() { + return config('view.theme'); + }) ?? 'None', + ]; + } +} \ No newline at end of file diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 8334bb179..0316b02aa 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -9,6 +9,7 @@ use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Bookshelf; use BookStack\Entities\Models\Chapter; use BookStack\Entities\Models\Page; +use BookStack\Exceptions\WhoopsBookStackPrettyHandler; use BookStack\Settings\Setting; use BookStack\Settings\SettingService; use BookStack\Util\CspService; @@ -20,6 +21,7 @@ use Illuminate\Support\Facades\URL; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; use Laravel\Socialite\Contracts\Factory as SocialiteFactory; +use Whoops\Handler\HandlerInterface; class AppServiceProvider extends ServiceProvider { @@ -65,6 +67,10 @@ class AppServiceProvider extends ServiceProvider */ public function register() { + $this->app->bind(HandlerInterface::class, function($app) { + return $app->make(WhoopsBookStackPrettyHandler::class); + }); + $this->app->singleton(SettingService::class, function ($app) { return new SettingService($app->make(Setting::class), $app->make(Repository::class)); }); diff --git a/composer.json b/composer.json index 31ecbef84..e59b0d1f0 100644 --- a/composer.json +++ b/composer.json @@ -17,8 +17,8 @@ "barryvdh/laravel-dompdf": "^0.9.0", "barryvdh/laravel-snappy": "^0.4.8", "doctrine/dbal": "^2.12.1", - "facade/ignition": "^1.16.4", "fideloper/proxy": "^4.4.1", + "filp/whoops": "^2.14", "intervention/image": "^2.5.1", "laravel/framework": "^6.20.33", "laravel/socialite": "^5.1", diff --git a/composer.lock b/composer.lock index fe779d071..6ea3a6338 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": "10825887b8f66d1d412b92bcc0ca864f", + "content-hash": "d59a665fcd692fc0ddf12e7e4f96d4f1", "packages": [ { "name": "aws/aws-crt-php", @@ -1102,200 +1102,6 @@ ], "time": "2020-12-29T14:50:06+00:00" }, - { - "name": "facade/flare-client-php", - "version": "1.9.1", - "source": { - "type": "git", - "url": "https://github.com/facade/flare-client-php.git", - "reference": "b2adf1512755637d0cef4f7d1b54301325ac78ed" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/facade/flare-client-php/zipball/b2adf1512755637d0cef4f7d1b54301325ac78ed", - "reference": "b2adf1512755637d0cef4f7d1b54301325ac78ed", - "shasum": "" - }, - "require": { - "facade/ignition-contracts": "~1.0", - "illuminate/pipeline": "^5.5|^6.0|^7.0|^8.0", - "php": "^7.1|^8.0", - "symfony/http-foundation": "^3.3|^4.1|^5.0", - "symfony/mime": "^3.4|^4.0|^5.1", - "symfony/var-dumper": "^3.4|^4.0|^5.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.14", - "phpunit/phpunit": "^7.5.16", - "spatie/phpunit-snapshot-assertions": "^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "Facade\\FlareClient\\": "src" - }, - "files": [ - "src/helpers.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Send PHP errors to Flare", - "homepage": "https://github.com/facade/flare-client-php", - "keywords": [ - "exception", - "facade", - "flare", - "reporting" - ], - "support": { - "issues": "https://github.com/facade/flare-client-php/issues", - "source": "https://github.com/facade/flare-client-php/tree/1.9.1" - }, - "funding": [ - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2021-09-13T12:16:46+00:00" - }, - { - "name": "facade/ignition", - "version": "1.18.0", - "source": { - "type": "git", - "url": "https://github.com/facade/ignition.git", - "reference": "fca0cbe5f900f94773d821b481c16d4ea3503491" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/facade/ignition/zipball/fca0cbe5f900f94773d821b481c16d4ea3503491", - "reference": "fca0cbe5f900f94773d821b481c16d4ea3503491", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "facade/flare-client-php": "^1.3", - "facade/ignition-contracts": "^1.0", - "filp/whoops": "^2.4", - "illuminate/support": "~5.5.0 || ~5.6.0 || ~5.7.0 || ~5.8.0 || ^6.0", - "monolog/monolog": "^1.12 || ^2.0", - "php": "^7.1|^8.0", - "scrivo/highlight.php": "^9.15", - "symfony/console": "^3.4 || ^4.0", - "symfony/var-dumper": "^3.4 || ^4.0" - }, - "require-dev": { - "mockery/mockery": "~1.3.3|^1.4.2", - "orchestra/testbench": "^3.5 || ^3.6 || ^3.7 || ^3.8 || ^4.0" - }, - "suggest": { - "laravel/telescope": "^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - }, - "laravel": { - "providers": [ - "Facade\\Ignition\\IgnitionServiceProvider" - ], - "aliases": { - "Flare": "Facade\\Ignition\\Facades\\Flare" - } - } - }, - "autoload": { - "psr-4": { - "Facade\\Ignition\\": "src" - }, - "files": [ - "src/helpers.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A beautiful error page for Laravel applications.", - "homepage": "https://github.com/facade/ignition", - "keywords": [ - "error", - "flare", - "laravel", - "page" - ], - "support": { - "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", - "forum": "https://twitter.com/flareappio", - "issues": "https://github.com/facade/ignition/issues", - "source": "https://github.com/facade/ignition" - }, - "time": "2021-08-02T07:45:03+00:00" - }, - { - "name": "facade/ignition-contracts", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/facade/ignition-contracts.git", - "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/facade/ignition-contracts/zipball/3c921a1cdba35b68a7f0ccffc6dffc1995b18267", - "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267", - "shasum": "" - }, - "require": { - "php": "^7.3|^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^v2.15.8", - "phpunit/phpunit": "^9.3.11", - "vimeo/psalm": "^3.17.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Facade\\IgnitionContracts\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://flareapp.io", - "role": "Developer" - } - ], - "description": "Solution contracts for Ignition", - "homepage": "https://github.com/facade/ignition-contracts", - "keywords": [ - "contracts", - "flare", - "ignition" - ], - "support": { - "issues": "https://github.com/facade/ignition-contracts/issues", - "source": "https://github.com/facade/ignition-contracts/tree/1.0.2" - }, - "time": "2020-10-16T08:27:54+00:00" - }, { "name": "fideloper/proxy", "version": "4.4.1", @@ -1356,21 +1162,21 @@ }, { "name": "filp/whoops", - "version": "2.14.1", + "version": "2.14.4", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "15ead64e9828f0fc90932114429c4f7923570cb1" + "reference": "f056f1fe935d9ed86e698905a957334029899895" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/15ead64e9828f0fc90932114429c4f7923570cb1", - "reference": "15ead64e9828f0fc90932114429c4f7923570cb1", + "url": "https://api.github.com/repos/filp/whoops/zipball/f056f1fe935d9ed86e698905a957334029899895", + "reference": "f056f1fe935d9ed86e698905a957334029899895", "shasum": "" }, "require": { "php": "^5.5.9 || ^7.0 || ^8.0", - "psr/log": "^1.0.1" + "psr/log": "^1.0.1 || ^2.0 || ^3.0" }, "require-dev": { "mockery/mockery": "^0.9 || ^1.0", @@ -1415,7 +1221,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.14.1" + "source": "https://github.com/filp/whoops/tree/2.14.4" }, "funding": [ { @@ -1423,7 +1229,7 @@ "type": "github" } ], - "time": "2021-08-29T12:00:00+00:00" + "time": "2021-10-03T12:00:00+00:00" }, { "name": "guzzlehttp/guzzle", @@ -3939,82 +3745,6 @@ }, "time": "2020-06-01T09:10:00+00:00" }, - { - "name": "scrivo/highlight.php", - "version": "v9.18.1.7", - "source": { - "type": "git", - "url": "https://github.com/scrivo/highlight.php.git", - "reference": "05996fcc61e97978d76ca7d1ac14b65e7cd26f91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/05996fcc61e97978d76ca7d1ac14b65e7cd26f91", - "reference": "05996fcc61e97978d76ca7d1ac14b65e7cd26f91", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "php": ">=5.4" - }, - "require-dev": { - "phpunit/phpunit": "^4.8|^5.7", - "sabberworm/php-css-parser": "^8.3", - "symfony/finder": "^2.8|^3.4", - "symfony/var-dumper": "^2.8|^3.4" - }, - "type": "library", - "autoload": { - "psr-0": { - "Highlight\\": "", - "HighlightUtilities\\": "" - }, - "files": [ - "HighlightUtilities/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Geert Bergman", - "homepage": "http://www.scrivo.org/", - "role": "Project Author" - }, - { - "name": "Vladimir Jimenez", - "homepage": "https://allejo.io", - "role": "Maintainer" - }, - { - "name": "Martin Folkers", - "homepage": "https://twobrain.io", - "role": "Contributor" - } - ], - "description": "Server side syntax highlighter that supports 185 languages. It's a PHP port of highlight.js", - "keywords": [ - "code", - "highlight", - "highlight.js", - "highlight.php", - "syntax" - ], - "support": { - "issues": "https://github.com/scrivo/highlight.php/issues", - "source": "https://github.com/scrivo/highlight.php" - }, - "funding": [ - { - "url": "https://github.com/allejo", - "type": "github" - } - ], - "time": "2021-07-09T00:30:39+00:00" - }, { "name": "socialiteproviders/discord", "version": "4.1.1", diff --git a/resources/views/errors/debug.blade.php b/resources/views/errors/debug.blade.php new file mode 100644 index 000000000..e7155431c --- /dev/null +++ b/resources/views/errors/debug.blade.php @@ -0,0 +1,146 @@ + + + + + + Error: {{ $error }} + + + + +
+ +

+ WARNING: Application is in debug mode. This mode has the potential to leak confidential + information and therefore should not be used in production or publicly + accessible environments. +

+ +
+

Error

+

{{ $errorClass }}

+

{{ $error }}

+
+ + + +
+

Environment

+
    + @foreach($environment as $label => $text) +
  • {{ $label }}: {{ $text }}
  • + @endforeach +
+
+ +
+

Stack Trace

+
{{ $trace }}
+
+ +
+ + \ No newline at end of file From ffa4377e65d8ea7342ea669f47a6d538d0c69194 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 14 Oct 2021 17:40:22 +0100 Subject: [PATCH 4/9] Added testing to cover debug view --- .../WhoopsBookStackPrettyHandler.php | 7 +-- tests/DebugViewTest.php | 54 +++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 tests/DebugViewTest.php diff --git a/app/Exceptions/WhoopsBookStackPrettyHandler.php b/app/Exceptions/WhoopsBookStackPrettyHandler.php index 4e92b1d84..22a49e04a 100644 --- a/app/Exceptions/WhoopsBookStackPrettyHandler.php +++ b/app/Exceptions/WhoopsBookStackPrettyHandler.php @@ -12,18 +12,15 @@ class WhoopsBookStackPrettyHandler extends Handler */ public function handle() { - // TODO - Assistance View - // Docs links - // Discord Links - // Github Issue Links (With pre-filled search?) - $exception = $this->getException(); + echo view('errors.debug', [ 'error' => $exception->getMessage(), 'errorClass' => get_class($exception), 'trace' => $exception->getTraceAsString(), 'environment' => $this->getEnvironment(), ])->render(); + return Handler::QUIT; } diff --git a/tests/DebugViewTest.php b/tests/DebugViewTest.php new file mode 100644 index 000000000..3485b4598 --- /dev/null +++ b/tests/DebugViewTest.php @@ -0,0 +1,54 @@ +set('app.debug', true); + $resp = $this->getDebugViewForException(new \InvalidArgumentException('An error occurred during testing')); + + // Error message + $resp->assertSeeText('An error occurred during testing'); + // Exception Class + $resp->assertSeeText('InvalidArgumentException'); + // Stack trace + $resp->assertSeeText('#0'); + $resp->assertSeeText('#1'); + // Warning message + $resp->assertSeeText('WARNING: Application is in debug mode. This mode has the potential to leak'); + // PHP version + $resp->assertSeeText('PHP Version: ' . phpversion()); + // BookStack version + $resp->assertSeeText('BookStack Version: ' . trim(file_get_contents(base_path('version')))); + // Dynamic help links + $resp->assertElementExists('a[href*="q=' . urlencode('BookStack An error occurred during testing') . '"]'); + $resp->assertElementExists('a[href*="?q=is%3Aissue+' . urlencode('An error occurred during testing') . '"]'); + } + + public function test_debug_view_only_shows_when_debug_mode_is_enabled() + { + config()->set('app.debug', true); + $resp = $this->getDebugViewForException(new \InvalidArgumentException('An error occurred during testing')); + $resp->assertSeeText('Stack Trace'); + $resp->assertDontSeeText('An unknown error occurred'); + + config()->set('app.debug', false); + $resp = $this->getDebugViewForException(new \InvalidArgumentException('An error occurred during testing')); + $resp->assertDontSeeText('Stack Trace'); + $resp->assertSeeText('An unknown error occurred'); + } + + + protected function getDebugViewForException(\Exception $exception): TestResponse + { + // Fake an error via social auth service used on login page + $mockService = $this->mock(SocialAuthService::class); + $mockService->shouldReceive('getActiveDrivers')->andThrow($exception); + return $this->get('/login'); + } + +} \ No newline at end of file From c9c0e5e16f029f8c3cb159c45f9dcaf99dd2426b Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 14 Oct 2021 18:02:16 +0100 Subject: [PATCH 5/9] Fixed guest user email showing in TOTP setup url - Occured during enforced MFA setup upon login. - Added test to cover. Fixes #2971 --- app/Auth/Access/Mfa/TotpService.php | 5 +++-- .../Controllers/Auth/MfaTotpController.php | 2 +- tests/Auth/MfaConfigurationTest.php | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/app/Auth/Access/Mfa/TotpService.php b/app/Auth/Access/Mfa/TotpService.php index 0d9bd37ce..e73c549fe 100644 --- a/app/Auth/Access/Mfa/TotpService.php +++ b/app/Auth/Access/Mfa/TotpService.php @@ -8,6 +8,7 @@ use BaconQrCode\Renderer\ImageRenderer; use BaconQrCode\Renderer\RendererStyle\Fill; use BaconQrCode\Renderer\RendererStyle\RendererStyle; use BaconQrCode\Writer; +use BookStack\Auth\User; use PragmaRX\Google2FA\Google2FA; use PragmaRX\Google2FA\Support\Constants; @@ -36,11 +37,11 @@ class TotpService /** * Generate a TOTP URL from secret key. */ - public function generateUrl(string $secret): string + public function generateUrl(string $secret, User $user): string { return $this->google2fa->getQRCodeUrl( setting('app-name'), - user()->email, + $user->email, $secret ); } diff --git a/app/Http/Controllers/Auth/MfaTotpController.php b/app/Http/Controllers/Auth/MfaTotpController.php index 694d69d76..5644f0268 100644 --- a/app/Http/Controllers/Auth/MfaTotpController.php +++ b/app/Http/Controllers/Auth/MfaTotpController.php @@ -31,7 +31,7 @@ class MfaTotpController extends Controller session()->put(static::SETUP_SECRET_SESSION_KEY, encrypt($totpSecret)); } - $qrCodeUrl = $totp->generateUrl($totpSecret); + $qrCodeUrl = $totp->generateUrl($totpSecret, $this->currentOrLastAttemptedUser()); $svg = $totp->generateQrCodeSvg($qrCodeUrl); return view('mfa.totp-generate', [ diff --git a/tests/Auth/MfaConfigurationTest.php b/tests/Auth/MfaConfigurationTest.php index 685aad83a..4223d052d 100644 --- a/tests/Auth/MfaConfigurationTest.php +++ b/tests/Auth/MfaConfigurationTest.php @@ -4,6 +4,7 @@ namespace Tests\Auth; use BookStack\Actions\ActivityType; use BookStack\Auth\Access\Mfa\MfaValue; +use BookStack\Auth\Role; use BookStack\Auth\User; use PragmaRX\Google2FA\Google2FA; use Tests\TestCase; @@ -164,4 +165,22 @@ class MfaConfigurationTest extends TestCase $this->assertActivityExists(ActivityType::MFA_REMOVE_METHOD); $this->assertEquals(0, $admin->mfaValues()->count()); } + + public function test_totp_setup_url_shows_correct_user_when_setup_forced_upon_login() + { + $admin = $this->getAdmin(); + /** @var Role $role */ + $role = $admin->roles()->first(); + $role->mfa_enforced = true; + $role->save(); + + $resp = $this->post('/login', ['email' => $admin->email, 'password' => 'password']); + $this->assertFalse(auth()->check()); + $resp->assertRedirect('/mfa/verify'); + + $resp = $this->get('/mfa/totp/generate'); + $resp->assertSeeText('Mobile App Setup'); + $resp->assertDontSee("otpauth://totp/BookStack:guest%40example.com"); + $resp->assertSee("otpauth://totp/BookStack:admin%40admin.com"); + } } From 747f81d5d8054c4ac74513b45028f19e6d91477e Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 15 Oct 2021 13:15:32 +0100 Subject: [PATCH 6/9] Updated php dependancies --- composer.lock | 300 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 182 insertions(+), 118 deletions(-) diff --git a/composer.lock b/composer.lock index 6ea3a6338..dee5aff4c 100644 --- a/composer.lock +++ b/composer.lock @@ -58,16 +58,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.194.1", + "version": "3.198.5", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "67bdee05acef9e8ad60098090996690b49babd09" + "reference": "ec63e1ad1b30689e530089e4c9cb18f2ef5c290b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/67bdee05acef9e8ad60098090996690b49babd09", - "reference": "67bdee05acef9e8ad60098090996690b49babd09", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/ec63e1ad1b30689e530089e4c9cb18f2ef5c290b", + "reference": "ec63e1ad1b30689e530089e4c9cb18f2ef5c290b", "shasum": "" }, "require": { @@ -143,9 +143,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.194.1" + "source": "https://github.com/aws/aws-sdk-php/tree/3.198.5" }, - "time": "2021-09-17T18:15:42+00:00" + "time": "2021-10-14T18:15:37+00:00" }, { "name": "bacon/bacon-qr-code", @@ -479,16 +479,16 @@ }, { "name": "doctrine/dbal", - "version": "2.13.3", + "version": "2.13.4", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "0d7adf4cadfee6f70850e5b163e6cdd706417838" + "reference": "2411a55a2a628e6d8dd598388ab13474802c7b6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/0d7adf4cadfee6f70850e5b163e6cdd706417838", - "reference": "0d7adf4cadfee6f70850e5b163e6cdd706417838", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/2411a55a2a628e6d8dd598388ab13474802c7b6e", + "reference": "2411a55a2a628e6d8dd598388ab13474802c7b6e", "shasum": "" }, "require": { @@ -501,8 +501,8 @@ "require-dev": { "doctrine/coding-standard": "9.0.0", "jetbrains/phpstorm-stubs": "2021.1", - "phpstan/phpstan": "0.12.96", - "phpunit/phpunit": "^7.5.20|^8.5|9.5.5", + "phpstan/phpstan": "0.12.99", + "phpunit/phpunit": "^7.5.20|^8.5|9.5.10", "psalm/plugin-phpunit": "0.16.1", "squizlabs/php_codesniffer": "3.6.0", "symfony/cache": "^4.4", @@ -568,7 +568,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/2.13.3" + "source": "https://github.com/doctrine/dbal/tree/2.13.4" }, "funding": [ { @@ -584,7 +584,7 @@ "type": "tidelift" } ], - "time": "2021-09-12T19:11:48+00:00" + "time": "2021-10-02T15:59:26+00:00" }, { "name": "doctrine/deprecations", @@ -1336,16 +1336,16 @@ }, { "name": "guzzlehttp/promises", - "version": "1.4.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" + "reference": "136a635e2b4a49b9d79e9c8fee267ffb257fdba0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", + "url": "https://api.github.com/repos/guzzle/promises/zipball/136a635e2b4a49b9d79e9c8fee267ffb257fdba0", + "reference": "136a635e2b4a49b9d79e9c8fee267ffb257fdba0", "shasum": "" }, "require": { @@ -1357,7 +1357,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.5-dev" } }, "autoload": { @@ -1373,10 +1373,25 @@ "MIT" ], "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], "description": "Guzzle promises library", @@ -1385,22 +1400,36 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.4.1" + "source": "https://github.com/guzzle/promises/tree/1.5.0" }, - "time": "2021-03-07T09:25:29+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2021-10-07T13:05:22+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.8.2", + "version": "1.8.3", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91" + "reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/1afdd860a2566ed3c2b0b4a3de6e23434a79ec85", + "reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85", "shasum": "" }, "require": { @@ -1437,13 +1466,34 @@ "MIT" ], "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, { "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", "homepage": "https://github.com/Tobion" } ], @@ -1460,22 +1510,36 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/1.8.2" + "source": "https://github.com/guzzle/psr7/tree/1.8.3" }, - "time": "2021-04-26T09:17:50+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2021-10-05T13:56:00+00:00" }, { "name": "intervention/image", - "version": "2.6.1", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/Intervention/image.git", - "reference": "0925f10b259679b5d8ca58f3a2add9255ffcda45" + "reference": "9a8cc99d30415ec0b3f7649e1647d03a55698545" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Intervention/image/zipball/0925f10b259679b5d8ca58f3a2add9255ffcda45", - "reference": "0925f10b259679b5d8ca58f3a2add9255ffcda45", + "url": "https://api.github.com/repos/Intervention/image/zipball/9a8cc99d30415ec0b3f7649e1647d03a55698545", + "reference": "9a8cc99d30415ec0b3f7649e1647d03a55698545", "shasum": "" }, "require": { @@ -1534,7 +1598,7 @@ ], "support": { "issues": "https://github.com/Intervention/image/issues", - "source": "https://github.com/Intervention/image/tree/2.6.1" + "source": "https://github.com/Intervention/image/tree/2.7.0" }, "funding": [ { @@ -1546,7 +1610,7 @@ "type": "github" } ], - "time": "2021-07-22T14:31:53+00:00" + "time": "2021-10-03T14:17:12+00:00" }, { "name": "knplabs/knp-snappy", @@ -1620,16 +1684,16 @@ }, { "name": "laravel/framework", - "version": "v6.20.34", + "version": "v6.20.35", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "72a6da88c90cee793513b3fe49cf0fcb368eefa0" + "reference": "5e55aa4063b9f7cf3249bfebcc37a6fbad4f159a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/72a6da88c90cee793513b3fe49cf0fcb368eefa0", - "reference": "72a6da88c90cee793513b3fe49cf0fcb368eefa0", + "url": "https://api.github.com/repos/laravel/framework/zipball/5e55aa4063b9f7cf3249bfebcc37a6fbad4f159a", + "reference": "5e55aa4063b9f7cf3249bfebcc37a6fbad4f159a", "shasum": "" }, "require": { @@ -1769,7 +1833,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2021-09-07T13:28:55+00:00" + "time": "2021-10-05T14:05:19+00:00" }, { "name": "laravel/socialite", @@ -2177,16 +2241,16 @@ }, { "name": "league/mime-type-detection", - "version": "1.7.0", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3" + "reference": "b38b25d7b372e9fddb00335400467b223349fd7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", - "reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/b38b25d7b372e9fddb00335400467b223349fd7e", + "reference": "b38b25d7b372e9fddb00335400467b223349fd7e", "shasum": "" }, "require": { @@ -2217,7 +2281,7 @@ "description": "Mime-type detection for Flysystem", "support": { "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.7.0" + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.8.0" }, "funding": [ { @@ -2229,7 +2293,7 @@ "type": "tidelift" } ], - "time": "2021-01-18T20:58:21+00:00" + "time": "2021-09-25T08:23:19+00:00" }, { "name": "league/oauth1-client", @@ -2309,16 +2373,16 @@ }, { "name": "monolog/monolog", - "version": "2.3.4", + "version": "2.3.5", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "437e7a1c50044b92773b361af77620efb76fff59" + "reference": "fd4380d6fc37626e2f799f29d91195040137eba9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/437e7a1c50044b92773b361af77620efb76fff59", - "reference": "437e7a1c50044b92773b361af77620efb76fff59", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd4380d6fc37626e2f799f29d91195040137eba9", + "reference": "fd4380d6fc37626e2f799f29d91195040137eba9", "shasum": "" }, "require": { @@ -2334,7 +2398,7 @@ "elasticsearch/elasticsearch": "^7", "graylog2/gelf-php": "^1.4.2", "mongodb/mongodb": "^1.8", - "php-amqplib/php-amqplib": "~2.4", + "php-amqplib/php-amqplib": "~2.4 || ^3", "php-console/php-console": "^3.1.3", "phpspec/prophecy": "^1.6.1", "phpstan/phpstan": "^0.12.91", @@ -2392,7 +2456,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.3.4" + "source": "https://github.com/Seldaek/monolog/tree/2.3.5" }, "funding": [ { @@ -2404,7 +2468,7 @@ "type": "tidelift" } ], - "time": "2021-09-15T11:27:21+00:00" + "time": "2021-10-01T21:08:31+00:00" }, { "name": "mtdowling/jmespath.php", @@ -3189,16 +3253,16 @@ }, { "name": "predis/predis", - "version": "v1.1.7", + "version": "v1.1.9", "source": { "type": "git", "url": "https://github.com/predis/predis.git", - "reference": "b240daa106d4e02f0c5b7079b41e31ddf66fddf8" + "reference": "c50c3393bb9f47fa012d0cdfb727a266b0818259" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/predis/predis/zipball/b240daa106d4e02f0c5b7079b41e31ddf66fddf8", - "reference": "b240daa106d4e02f0c5b7079b41e31ddf66fddf8", + "url": "https://api.github.com/repos/predis/predis/zipball/c50c3393bb9f47fa012d0cdfb727a266b0818259", + "reference": "c50c3393bb9f47fa012d0cdfb727a266b0818259", "shasum": "" }, "require": { @@ -3243,7 +3307,7 @@ ], "support": { "issues": "https://github.com/predis/predis/issues", - "source": "https://github.com/predis/predis/tree/v1.1.7" + "source": "https://github.com/predis/predis/tree/v1.1.9" }, "funding": [ { @@ -3251,7 +3315,7 @@ "type": "github" } ], - "time": "2021-04-04T19:34:46+00:00" + "time": "2021-10-05T19:02:38+00:00" }, { "name": "psr/container", @@ -3553,22 +3617,22 @@ }, { "name": "ramsey/uuid", - "version": "3.9.4", + "version": "3.9.6", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "be2451bef8147b7352a28fb4cddb08adc497ada3" + "reference": "ffa80ab953edd85d5b6c004f96181a538aad35a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/be2451bef8147b7352a28fb4cddb08adc497ada3", - "reference": "be2451bef8147b7352a28fb4cddb08adc497ada3", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/ffa80ab953edd85d5b6c004f96181a538aad35a3", + "reference": "ffa80ab953edd85d5b6c004f96181a538aad35a3", "shasum": "" }, "require": { "ext-json": "*", "paragonie/random_compat": "^1 | ^2 | ^9.99.99", - "php": "^5.4 | ^7 | ^8", + "php": "^5.4 | ^7.0 | ^8.0", "symfony/polyfill-ctype": "^1.8" }, "replace": { @@ -3577,14 +3641,16 @@ "require-dev": { "codeception/aspect-mock": "^1 | ^2", "doctrine/annotations": "^1.2", - "goaop/framework": "1.0.0-alpha.2 | ^1 | ^2.1", - "jakub-onderka/php-parallel-lint": "^1", + "goaop/framework": "1.0.0-alpha.2 | ^1 | >=2.1.0 <=2.3.2", "mockery/mockery": "^0.9.11 | ^1", "moontoast/math": "^1.1", + "nikic/php-parser": "<=4.5.0", "paragonie/random-lib": "^2", - "php-mock/php-mock-phpunit": "^0.3 | ^1.1", - "phpunit/phpunit": "^4.8 | ^5.4 | ^6.5", - "squizlabs/php_codesniffer": "^3.5" + "php-mock/php-mock-phpunit": "^0.3 | ^1.1 | ^2.6", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpunit/phpunit": ">=4.8.36 <9.0.0 | >=9.3.0", + "squizlabs/php_codesniffer": "^3.5", + "yoast/phpunit-polyfills": "^1.0" }, "suggest": { "ext-ctype": "Provides support for PHP Ctype functions", @@ -3652,7 +3718,7 @@ "type": "tidelift" } ], - "time": "2021-08-06T20:32:15+00:00" + "time": "2021-09-25T23:07:42+00:00" }, { "name": "robrichards/xmlseclibs", @@ -4917,16 +4983,16 @@ }, { "name": "symfony/http-kernel", - "version": "v4.4.30", + "version": "v4.4.32", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "87f7ea4a8a7a30c967e26001de99f12943bf57ae" + "reference": "f7bda3ea8f05ae90627400e58af5179b25ce0f38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/87f7ea4a8a7a30c967e26001de99f12943bf57ae", - "reference": "87f7ea4a8a7a30c967e26001de99f12943bf57ae", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f7bda3ea8f05ae90627400e58af5179b25ce0f38", + "reference": "f7bda3ea8f05ae90627400e58af5179b25ce0f38", "shasum": "" }, "require": { @@ -5001,7 +5067,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v4.4.30" + "source": "https://github.com/symfony/http-kernel/tree/v4.4.32" }, "funding": [ { @@ -5017,20 +5083,20 @@ "type": "tidelift" } ], - "time": "2021-08-30T12:27:20+00:00" + "time": "2021-09-28T10:20:04+00:00" }, { "name": "symfony/mime", - "version": "v5.3.7", + "version": "v5.3.8", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "ae887cb3b044658676129f5e97aeb7e9eb69c2d8" + "reference": "a756033d0a7e53db389618653ae991eba5a19a11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/ae887cb3b044658676129f5e97aeb7e9eb69c2d8", - "reference": "ae887cb3b044658676129f5e97aeb7e9eb69c2d8", + "url": "https://api.github.com/repos/symfony/mime/zipball/a756033d0a7e53db389618653ae991eba5a19a11", + "reference": "a756033d0a7e53db389618653ae991eba5a19a11", "shasum": "" }, "require": { @@ -5084,7 +5150,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.3.7" + "source": "https://github.com/symfony/mime/tree/v5.3.8" }, "funding": [ { @@ -5100,7 +5166,7 @@ "type": "tidelift" } ], - "time": "2021-08-20T11:40:01+00:00" + "time": "2021-09-10T12:30:38+00:00" }, { "name": "symfony/polyfill-ctype", @@ -5982,7 +6048,7 @@ }, { "name": "symfony/translation", - "version": "v4.4.30", + "version": "v4.4.32", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", @@ -6051,7 +6117,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v4.4.30" + "source": "https://github.com/symfony/translation/tree/v4.4.32" }, "funding": [ { @@ -6149,16 +6215,16 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.30", + "version": "v4.4.31", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "7f65c44c2ce80d3a0fcdb6385ee0ad535e45660c" + "reference": "1f12cc0c2e880a5f39575c19af81438464717839" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/7f65c44c2ce80d3a0fcdb6385ee0ad535e45660c", - "reference": "7f65c44c2ce80d3a0fcdb6385ee0ad535e45660c", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1f12cc0c2e880a5f39575c19af81438464717839", + "reference": "1f12cc0c2e880a5f39575c19af81438464717839", "shasum": "" }, "require": { @@ -6218,7 +6284,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v4.4.30" + "source": "https://github.com/symfony/var-dumper/tree/v4.4.31" }, "funding": [ { @@ -6234,7 +6300,7 @@ "type": "tidelift" } ], - "time": "2021-08-04T20:31:23+00:00" + "time": "2021-09-24T15:30:11+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -6291,16 +6357,16 @@ }, { "name": "vlucas/phpdotenv", - "version": "v3.6.8", + "version": "v3.6.9", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "5e679f7616db829358341e2d5cccbd18773bdab8" + "reference": "a1bf4c9853d90ade427b4efe35355fc41b3d6988" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/5e679f7616db829358341e2d5cccbd18773bdab8", - "reference": "5e679f7616db829358341e2d5cccbd18773bdab8", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/a1bf4c9853d90ade427b4efe35355fc41b3d6988", + "reference": "a1bf4c9853d90ade427b4efe35355fc41b3d6988", "shasum": "" }, "require": { @@ -6311,7 +6377,7 @@ "require-dev": { "ext-filter": "*", "ext-pcre": "*", - "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20" + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.21" }, "suggest": { "ext-filter": "Required to use the boolean validator.", @@ -6335,13 +6401,11 @@ "authors": [ { "name": "Graham Campbell", - "email": "graham@alt-three.com", - "homepage": "https://gjcampbell.co.uk/" + "email": "hello@gjcampbell.co.uk" }, { "name": "Vance Lucas", - "email": "vance@vancelucas.com", - "homepage": "https://vancelucas.com/" + "email": "vance@vancelucas.com" } ], "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", @@ -6352,7 +6416,7 @@ ], "support": { "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v3.6.8" + "source": "https://github.com/vlucas/phpdotenv/tree/v3.6.9" }, "funding": [ { @@ -6364,7 +6428,7 @@ "type": "tidelift" } ], - "time": "2021-01-20T14:39:46+00:00" + "time": "2021-10-02T19:07:56+00:00" } ], "packages-dev": [ @@ -7510,16 +7574,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.12.0", + "version": "v4.13.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143" + "reference": "50953a2691a922aa1769461637869a0a2faa3f53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53", + "reference": "50953a2691a922aa1769461637869a0a2faa3f53", "shasum": "" }, "require": { @@ -7560,9 +7624,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0" }, - "time": "2021-07-21T10:44:31+00:00" + "time": "2021-09-20T12:20:58+00:00" }, { "name": "phar-io/manifest", @@ -7786,16 +7850,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.5.0", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f" + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/30f38bffc6f24293dadd1823936372dfa9e86e2f", - "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", "shasum": "" }, "require": { @@ -7830,9 +7894,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" }, - "time": "2021-09-17T15:28:14+00:00" + "time": "2021-10-02T14:08:47+00:00" }, { "name": "phpspec/prophecy", @@ -8221,16 +8285,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.9", + "version": "9.5.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b" + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b", - "reference": "ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", "shasum": "" }, "require": { @@ -8246,7 +8310,7 @@ "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.3", + "phpunit/php-code-coverage": "^9.2.7", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -8308,7 +8372,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.9" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" }, "funding": [ { @@ -8320,7 +8384,7 @@ "type": "github" } ], - "time": "2021-08-31T06:47:40+00:00" + "time": "2021-09-25T07:38:51+00:00" }, { "name": "react/promise", From f3c147d33bc3457350e7e971a3bfd074493ee36d Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 15 Oct 2021 14:16:45 +0100 Subject: [PATCH 7/9] Applied latest styleci changes --- .../WhoopsBookStackPrettyHandler.php | 23 ++++++++++--------- app/Providers/AppServiceProvider.php | 2 +- tests/Auth/MfaConfigurationTest.php | 4 ++-- tests/DebugViewTest.php | 5 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/Exceptions/WhoopsBookStackPrettyHandler.php b/app/Exceptions/WhoopsBookStackPrettyHandler.php index 22a49e04a..dcf50fa8e 100644 --- a/app/Exceptions/WhoopsBookStackPrettyHandler.php +++ b/app/Exceptions/WhoopsBookStackPrettyHandler.php @@ -6,7 +6,6 @@ use Whoops\Handler\Handler; class WhoopsBookStackPrettyHandler extends Handler { - /** * @return int|null A handler may return nothing, or a Handler::HANDLE_* constant */ @@ -15,16 +14,17 @@ class WhoopsBookStackPrettyHandler extends Handler $exception = $this->getException(); echo view('errors.debug', [ - 'error' => $exception->getMessage(), - 'errorClass' => get_class($exception), - 'trace' => $exception->getTraceAsString(), + 'error' => $exception->getMessage(), + 'errorClass' => get_class($exception), + 'trace' => $exception->getTraceAsString(), 'environment' => $this->getEnvironment(), ])->render(); return Handler::QUIT; } - protected function safeReturn(callable $callback, $default = null) { + protected function safeReturn(callable $callback, $default = null) + { try { return $callback(); } catch (\Exception $e) { @@ -35,14 +35,15 @@ class WhoopsBookStackPrettyHandler extends Handler protected function getEnvironment(): array { return [ - 'PHP Version' => phpversion(), - 'BookStack Version' => $this->safeReturn(function() { + 'PHP Version' => phpversion(), + 'BookStack Version' => $this->safeReturn(function () { $versionFile = base_path('version'); + return trim(file_get_contents($versionFile)); }, 'unknown'), - 'Theme Configured' => $this->safeReturn(function() { - return config('view.theme'); - }) ?? 'None', + 'Theme Configured' => $this->safeReturn(function () { + return config('view.theme'); + }) ?? 'None', ]; } -} \ No newline at end of file +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 0316b02aa..4446c2a0a 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -67,7 +67,7 @@ class AppServiceProvider extends ServiceProvider */ public function register() { - $this->app->bind(HandlerInterface::class, function($app) { + $this->app->bind(HandlerInterface::class, function ($app) { return $app->make(WhoopsBookStackPrettyHandler::class); }); diff --git a/tests/Auth/MfaConfigurationTest.php b/tests/Auth/MfaConfigurationTest.php index 4223d052d..59a2a41b5 100644 --- a/tests/Auth/MfaConfigurationTest.php +++ b/tests/Auth/MfaConfigurationTest.php @@ -180,7 +180,7 @@ class MfaConfigurationTest extends TestCase $resp = $this->get('/mfa/totp/generate'); $resp->assertSeeText('Mobile App Setup'); - $resp->assertDontSee("otpauth://totp/BookStack:guest%40example.com"); - $resp->assertSee("otpauth://totp/BookStack:admin%40admin.com"); + $resp->assertDontSee('otpauth://totp/BookStack:guest%40example.com'); + $resp->assertSee('otpauth://totp/BookStack:admin%40admin.com'); } } diff --git a/tests/DebugViewTest.php b/tests/DebugViewTest.php index 3485b4598..63d6472b9 100644 --- a/tests/DebugViewTest.php +++ b/tests/DebugViewTest.php @@ -42,13 +42,12 @@ class DebugViewTest extends TestCase $resp->assertSeeText('An unknown error occurred'); } - protected function getDebugViewForException(\Exception $exception): TestResponse { // Fake an error via social auth service used on login page $mockService = $this->mock(SocialAuthService::class); $mockService->shouldReceive('getActiveDrivers')->andThrow($exception); + return $this->get('/login'); } - -} \ No newline at end of file +} From 5647a8a0918ac206d711351c3877387177caa097 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 15 Oct 2021 14:17:32 +0100 Subject: [PATCH 8/9] New Crowdin updates (#2980) * New translations entities.php (Spanish, Argentina) * New translations activities.php (Spanish, Argentina) * New translations auth.php (Spanish, Argentina) * New translations settings.php (Spanish, Argentina) * New translations validation.php (Spanish, Argentina) * New translations auth.php (Spanish, Argentina) --- resources/lang/es_AR/activities.php | 4 ++-- resources/lang/es_AR/auth.php | 32 ++++++++++++++--------------- resources/lang/es_AR/entities.php | 2 +- resources/lang/es_AR/settings.php | 12 +++++------ resources/lang/es_AR/validation.php | 4 ++-- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/resources/lang/es_AR/activities.php b/resources/lang/es_AR/activities.php index 861115fc5..540bd4b82 100644 --- a/resources/lang/es_AR/activities.php +++ b/resources/lang/es_AR/activities.php @@ -48,8 +48,8 @@ return [ 'favourite_remove_notification' => '".name" se eliminó de sus favoritos', // MFA - 'mfa_setup_method_notification' => 'Método de Autenticación en Dos Pasos configurado correctamente', - 'mfa_remove_method_notification' => 'Método de Autenticación en Dos Pasos eliminado correctamente', + 'mfa_setup_method_notification' => 'Método de autenticación de múltiples factores configurado satisfactoriamente', + 'mfa_remove_method_notification' => 'Método de autenticación de múltiples factores eliminado satisfactoriamente', // Other 'commented_on' => 'comentado', diff --git a/resources/lang/es_AR/auth.php b/resources/lang/es_AR/auth.php index c57b26746..cb18a9405 100644 --- a/resources/lang/es_AR/auth.php +++ b/resources/lang/es_AR/auth.php @@ -76,37 +76,37 @@ return [ 'user_invite_success' => 'Contraseña establecida, ahora tiene acceso a :appName!', // Multi-factor Authentication - 'mfa_setup' => 'Configurar Autenticación en Dos Pasos', - 'mfa_setup_desc' => 'La autenticación en dos pasos añade una capa de seguridad adicional a tu cuenta de usuario.', + 'mfa_setup' => 'Configurar autenticación de múltiples factores', + 'mfa_setup_desc' => 'Configure la autenticación de múltiples factores como una capa extra de seguridad para su cuenta de usuario.', 'mfa_setup_configured' => 'Ya está configurado', 'mfa_setup_reconfigure' => 'Reconfigurar', - 'mfa_setup_remove_confirmation' => '¿Está seguro de que desea eliminar este método de autenticación de dos pasos?', + 'mfa_setup_remove_confirmation' => '¿Está seguro que desea eliminar este método de autenticación de múltiples factores?', 'mfa_setup_action' => 'Configuración', - 'mfa_backup_codes_usage_limit_warning' => 'Quedan menos de 5 códigos de respaldo, Por favor, genera y almacena un nuevo conjunto antes de que te quedes sin códigos para evitar que te bloquees fuera de tu cuenta.', - 'mfa_option_totp_title' => 'Aplicación para móviles', - 'mfa_option_totp_desc' => 'Para utilizar la autenticación de dos pasos necesitarás una aplicación móvil que soporte TOTP como Google Authenticator, Authy o Microsoft Authenticator.', + 'mfa_backup_codes_usage_limit_warning' => 'Quedan menos de 5 códigos de respaldo, Por favor, genere y guarde un nuevo conjunto antes de que se quede sin códigos para evitar que se bloquee su cuenta.', + 'mfa_option_totp_title' => 'Aplicación móvil', + 'mfa_option_totp_desc' => 'Para utilizar la autenticación en dos pasos necesitará una aplicación móvil que soporte TOTP como Google Authenticator, Authy o Microsoft Authenticator.', 'mfa_option_backup_codes_title' => 'Códigos de Respaldo', - 'mfa_option_backup_codes_desc' => 'Almacena de forma segura un conjunto de códigos de respaldo de un solo uso que puedes introducir para verificar tu identidad.', + 'mfa_option_backup_codes_desc' => 'Almacene de forma segura un conjunto de códigos de respaldo de un solo uso que pueda introducir para verificar su identidad.', 'mfa_gen_confirm_and_enable' => 'Confirmar y Activar', 'mfa_gen_backup_codes_title' => 'Configuración de Códigos de Respaldo', - 'mfa_gen_backup_codes_desc' => 'Guarda la siguiente lista de códigos en un lugar seguro. Al acceder al sistema podrás usar uno de los códigos como un segundo mecanismo de autenticación.', + 'mfa_gen_backup_codes_desc' => 'Guarde la siguiente lista de códigos en un lugar seguro. Al acceder al sistema podrá usar uno de los códigos como un segundo mecanismo de autenticación.', 'mfa_gen_backup_codes_download' => 'Descargar Códigos', - 'mfa_gen_backup_codes_usage_warning' => 'Cada código sólo puede utilizarse una vez', + 'mfa_gen_backup_codes_usage_warning' => 'Cada código puede utilizarse sólo una vez', 'mfa_gen_totp_title' => 'Configuración de Aplicación móvil', - 'mfa_gen_totp_desc' => 'Para utilizar la autenticación de dos pasos necesitarás una aplicación móvil que soporte TOTP como Google Authenticator, Authy o Microsoft Authenticator.', + 'mfa_gen_totp_desc' => 'Para utilizar la autenticación en dos pasos necesitará una aplicación móvil que soporte TOTP como Google Authenticator, Authy o Microsoft Authenticator.', 'mfa_gen_totp_scan' => 'Escanea el código QR mostrado a continuación usando tu aplicación de autenticación preferida para empezar.', 'mfa_gen_totp_verify_setup' => 'Verificar Configuración', 'mfa_gen_totp_verify_setup_desc' => 'Verifica que todo está funcionando introduciendo un código, generado en tu aplicación de autenticación, en el campo de texto a continuación:', 'mfa_gen_totp_provide_code_here' => 'Introduce aquí tu código generado por la aplicación', 'mfa_verify_access' => 'Verificar Acceso', - 'mfa_verify_access_desc' => 'Tu cuenta de usuario requiere que confirmes tu identidad a través de un nivel adicional de verificación antes de que te conceda el acceso. Verifica tu identidad usando uno de los métodos configurados para continuar.', + 'mfa_verify_access_desc' => 'Su cuenta de usuario requiere que confirme su identidad a través de un nivel adicional de verificación antes de que se le conceda el acceso. Verifique su identidad usando uno de los métodos configurados para continuar.', 'mfa_verify_no_methods' => 'No hay Métodos Configurados', - 'mfa_verify_no_methods_desc' => 'No se han encontrado métodos de autenticación de dos pasos para tu cuenta. Tendrás que configurar al menos un método antes de obtener acceso.', + 'mfa_verify_no_methods_desc' => 'No se han encontrado métodos de autenticación de múltiples factores para su cuenta. Tendrá que configurar al menos un método antes de obtener acceso.', 'mfa_verify_use_totp' => 'Verificar usando una aplicación móvil', 'mfa_verify_use_backup_codes' => 'Verificar usando un código de respaldo', - 'mfa_verify_backup_code' => 'Códigos de Respaldo', + 'mfa_verify_backup_code' => 'Código de Respaldo', 'mfa_verify_backup_code_desc' => 'Introduzca uno de sus códigos de respaldo restantes a continuación:', - 'mfa_verify_backup_code_enter_here' => 'Introduce el código de respaldo aquí', - 'mfa_verify_totp_desc' => 'Introduzca el código, generado con tu aplicación móvil, a continuación:', - 'mfa_setup_login_notification' => 'Método de dos factores configurado. Por favor, inicia sesión de nuevo utilizando el método configurado.', + 'mfa_verify_backup_code_enter_here' => 'Introduzca el código de respaldo aquí', + 'mfa_verify_totp_desc' => 'A continuación, introduzca el código generado con su aplicación móvil:', + 'mfa_setup_login_notification' => 'Método de dos factores configurado. Por favor, inicie sesión nuevamente utilizando el método configurado.', ]; \ No newline at end of file diff --git a/resources/lang/es_AR/entities.php b/resources/lang/es_AR/entities.php index 854680e02..bf08bdb51 100644 --- a/resources/lang/es_AR/entities.php +++ b/resources/lang/es_AR/entities.php @@ -234,7 +234,7 @@ return [ 'pages_initial_name' => 'Página nueva', 'pages_editing_draft_notification' => 'Usted está actualmente editando un borrador que fue guardado por última vez el :timeDiff.', 'pages_draft_edited_notification' => 'Esta página ha sido actualizada desde aquel momento. Se recomienda que cancele este borrador.', - 'pages_draft_page_changed_since_creation' => 'This page has been updated since this draft was created. It is recommended that you discard this draft or take care not to overwrite any page changes.', + 'pages_draft_page_changed_since_creation' => 'Esta página fue actualizada desde que se creó este borrador. Se recomienda descartar este borrador o tener cuidado de no sobrescribir ningún cambio en la página.', 'pages_draft_edit_active' => [ 'start_a' => ':count usuarios han comenzado a editar esta página', 'start_b' => ':userName ha comenzado a editar esta página', diff --git a/resources/lang/es_AR/settings.php b/resources/lang/es_AR/settings.php index 99ec4c219..027f22421 100644 --- a/resources/lang/es_AR/settings.php +++ b/resources/lang/es_AR/settings.php @@ -92,7 +92,7 @@ return [ 'recycle_bin' => 'Papelera de Reciclaje', 'recycle_bin_desc' => 'Aquí puede restaurar elementos que hayan sido eliminados o elegir eliminarlos permanentemente del sistema. Esta lista no está filtrada a diferencia de las listas de actividad similares en el sistema donde se aplican los filtros de permisos.', 'recycle_bin_deleted_item' => 'Elemento Eliminado', - 'recycle_bin_deleted_parent' => 'Superior', + 'recycle_bin_deleted_parent' => 'Padre', 'recycle_bin_deleted_by' => 'Eliminado por', 'recycle_bin_deleted_at' => 'Fecha de eliminación', 'recycle_bin_permanently_delete' => 'Eliminar permanentemente', @@ -105,7 +105,7 @@ return [ 'recycle_bin_restore_list' => 'Elementos a restaurar', 'recycle_bin_restore_confirm' => 'Esta acción restaurará el elemento eliminado, incluyendo cualquier elemento secundario, a su ubicación original. Si la ubicación original ha sido eliminada, y ahora está en la papelera de reciclaje, el elemento padre también tendrá que ser restaurado.', 'recycle_bin_restore_deleted_parent' => 'El padre de este elemento también ha sido eliminado. Estos permanecerán eliminados hasta que el padre también sea restaurado.', - 'recycle_bin_restore_parent' => 'Restaurar Superior', + 'recycle_bin_restore_parent' => 'Restaurar Padre', 'recycle_bin_destroy_notification' => 'Eliminados :count elementos de la papelera de reciclaje.', 'recycle_bin_restore_notification' => 'Restaurados :count elementos desde la papelera de reciclaje.', @@ -119,7 +119,7 @@ return [ 'audit_table_user' => 'Usuario', 'audit_table_event' => 'Evento', 'audit_table_related' => 'Elemento o detalle relacionados', - 'audit_table_ip' => 'IP Address', + 'audit_table_ip' => 'Dirección IP', 'audit_table_date' => 'Fecha de la Actividad', 'audit_date_from' => 'Inicio del Rango de Fecha', 'audit_date_to' => 'Final del Rango de Fecha', @@ -139,7 +139,7 @@ return [ 'role_details' => 'Detalles de rol', 'role_name' => 'Nombre de rol', 'role_desc' => 'Descripción corta de rol', - 'role_mfa_enforced' => 'Requiere Autenticación en Dos Pasos', + 'role_mfa_enforced' => 'Requiere autenticación de múltiples factores', 'role_external_auth_id' => 'IDs de Autenticación Externa', 'role_system' => 'Permisos de sistema', 'role_manage_users' => 'Gestionar usuarios', @@ -208,8 +208,8 @@ return [ 'users_api_tokens_create' => 'Crear token', 'users_api_tokens_expires' => 'Expira', 'users_api_tokens_docs' => 'Documentación API', - 'users_mfa' => 'Autenticación en Dos Pasos', - 'users_mfa_desc' => 'La autenticación en dos pasos añade una capa de seguridad adicional a tu cuenta.', + 'users_mfa' => 'Autenticación de múltiples factores', + 'users_mfa_desc' => 'Configure la autenticación de múltiples factores como una capa extra de seguridad para su cuenta de usuario.', 'users_mfa_x_methods' => ':count método configurado|:count métodos configurados', 'users_mfa_configure' => 'Configurar Métodos', diff --git a/resources/lang/es_AR/validation.php b/resources/lang/es_AR/validation.php index 2cc8ed9bf..6b72a6549 100644 --- a/resources/lang/es_AR/validation.php +++ b/resources/lang/es_AR/validation.php @@ -15,7 +15,7 @@ return [ 'alpha_dash' => 'El :attribute solo puede contener letras, números y guiones.', 'alpha_num' => 'El :attribute solo puede contener letras y número.', 'array' => 'El :attribute debe de ser un array.', - 'backup_codes' => 'El código suministrado no es válido o ya ha sido utilizado.', + 'backup_codes' => 'El código suministrado no es válido o ya fue utilizado.', 'before' => 'El :attribute debe ser una fecha anterior a :date.', 'between' => [ 'numeric' => 'El :attribute debe estar entre :min y :max.', @@ -99,7 +99,7 @@ return [ ], 'string' => 'El atributo :attribute debe ser una cadena.', 'timezone' => 'El atributo :attribute debe ser una zona válida.', - 'totp' => 'El código suministrado no es válido o ya ha expirado.', + 'totp' => 'El código suministrado no es válido o ya expiró.', 'unique' => 'El atributo :attribute ya ha sido tomado.', 'url' => 'El atributo :attribute tiene un formato inválido.', 'uploaded' => 'El archivo no se pudo subir. Puede ser que el servidor no acepte archivos de este tamaño.', From 5ba964b677ff3a41e6d60dd1dff434dd0066dcd5 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 15 Oct 2021 14:30:49 +0100 Subject: [PATCH 9/9] Updated readme with latest version info Also updated version file to be current --- readme.md | 17 ++++++++++++----- version | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index cb17a1aae..45b40cdb7 100644 --- a/readme.md +++ b/readme.md @@ -14,17 +14,18 @@ A platform for storing and organising information and documentation. Details for * [Documentation](https://www.bookstackapp.com/docs) * [Demo Instance](https://demo.bookstackapp.com) * [Admin Login](https://demo.bookstackapp.com/login?email=admin@example.com&password=password) +* [Screenshots](https://www.bookstackapp.com/#screenshots) * [BookStack Blog](https://www.bookstackapp.com/blog) * [Issue List](https://github.com/BookStackApp/BookStack/issues) * [Discord Chat](https://discord.gg/ztkBqR2) ## 📚 Project Definition -BookStack is an opinionated wiki system that provides a pleasant and simple out of the box experience. New users to an instance should find the experience intuitive and only basic word-processing skills should be required to get involved in creating content on BookStack. The platform should provide advanced power features to those that desire it but they should not interfere with the core simple user experience. +BookStack is an opinionated wiki system that provides a pleasant and simple out-of-the-box experience. New users to an instance should find the experience intuitive and only basic word-processing skills should be required to get involved in creating content on BookStack. The platform should provide advanced power features to those that desire it but they should not interfere with the core simple user experience. BookStack is not designed as an extensible platform to be used for purposes that differ to the statement above. -In regards to development philosophy, BookStack has a relaxed, open & positive approach. At the end of the day this is free software developed and maintained by people donating their own free time. +In regard to development philosophy, BookStack has a relaxed, open & positive approach. At the end of the day this is free software developed and maintained by people donating their own free time. ## 🛣️ Road Map @@ -41,17 +42,23 @@ Below is a high-level road map view for BookStack to provide a sense of directio ## 🚀 Release Versioning & Process -BookStack releases are each assigned a version number, such as "v0.25.2", in the format `v..`. A change only in the `patch` number indicates a fairly minor release that mainly contains fixes and therefore is very unlikely to cause breakages upon update. A change in the `feature` number indicates a release which will generally bring new features in addition to fixes and enhancements. These releases have a small chance of introducing breaking changes upon update so it's worth checking for any notes in the [update guide](https://www.bookstackapp.com/docs/admin/updates/). A change in the `phase` indicates a much large change in BookStack that will likely incur breakages requiring manual intervention. +BookStack releases are each assigned a date-based version number in the format `v.[.]`. For example: + +- `v20.12` - New feature released launched during December 2020. +- `v21.06.2` - Second patch release upon the June 2021 feature release. + +Patch releases are generally fairly minor, primarily intended for fixes and therefore is fairly unlikely to cause breakages upon update. +Feature releases are generally larger, bringing new features in addition to fixes and enhancements. These releases have a greater chance of introducing breaking changes upon update, so it's worth checking for any notes in the [update guide](https://www.bookstackapp.com/docs/admin/updates/). Each BookStack release will have a [milestone](https://github.com/BookStackApp/BookStack/milestones) created with issues & pull requests assigned to it to define what will be in that release. Milestones are built up then worked through until complete at which point, after some testing and documentation updates, the release will be deployed. -For feature releases, and some patch releases, the release will be accompanied by a post on the [BookStack blog](https://www.bookstackapp.com/blog/) which will provide additional detail on features, changes & updates otherwise the [GitHub release page](https://github.com/BookStackApp/BookStack/releases) will show a list of changes. You can sign up to be alerted to new BookStack blogs posts (once per week maximum) [at this link](https://updates.bookstackapp.com/signup/bookstack-news-and-updates). +Feature releases, and some patch releases, will be accompanied by a post on the [BookStack blog](https://www.bookstackapp.com/blog/) which will provide additional detail on features, changes & updates otherwise the [GitHub release page](https://github.com/BookStackApp/BookStack/releases) will show a list of changes. You can sign up to be alerted to new BookStack blogs posts (once per week maximum) [at this link](https://updates.bookstackapp.com/signup/bookstack-news-and-updates). ## 🛠️ Development & Testing All development on BookStack is currently done on the master branch. When it's time for a release the master branch is merged into release with built & minified CSS & JS then tagged at its version. Here are the current development requirements: -* [Node.js](https://nodejs.org/en/) v12.0+ +* [Node.js](https://nodejs.org/en/) v14.0+ This project uses SASS for CSS development and this is built, along with the JavaScript, using a range of npm scripts. The below npm commands can be used to install the dependencies & run the build tasks: diff --git a/version b/version index 0d86fac78..4a22367ef 100644 --- a/version +++ b/version @@ -1 +1 @@ -v21.06-dev +v21.10-dev