X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/a6633642232efd164d4708967ab59e498fbff896..refs/heads/ldap_host_failover:/tests/Entity/ExportTest.php
diff --git a/tests/Entity/ExportTest.php b/tests/Entity/ExportTest.php
index 1e44f015a..0f80bdd49 100644
--- a/tests/Entity/ExportTest.php
+++ b/tests/Entity/ExportTest.php
@@ -1,18 +1,21 @@
-entities->page();
$this->asEditor();
$resp = $this->get($page->getUrl('/export/plaintext'));
@@ -23,7 +26,7 @@ class ExportTest extends TestCase
public function test_page_pdf_export()
{
- $page = Page::first();
+ $page = $this->entities->page();
$this->asEditor();
$resp = $this->get($page->getUrl('/export/pdf'));
@@ -33,7 +36,7 @@ class ExportTest extends TestCase
public function test_page_html_export()
{
- $page = Page::first();
+ $page = $this->entities->page();
$this->asEditor();
$resp = $this->get($page->getUrl('/export/html'));
@@ -44,7 +47,7 @@ class ExportTest extends TestCase
public function test_book_text_export()
{
- $page = Page::first();
+ $page = $this->entities->page();
$book = $page->book;
$this->asEditor();
@@ -57,7 +60,7 @@ class ExportTest extends TestCase
public function test_book_pdf_export()
{
- $page = Page::first();
+ $page = $this->entities->page();
$book = $page->book;
$this->asEditor();
@@ -68,7 +71,7 @@ class ExportTest extends TestCase
public function test_book_html_export()
{
- $page = Page::first();
+ $page = $this->entities->page();
$book = $page->book;
$this->asEditor();
@@ -82,7 +85,7 @@ class ExportTest extends TestCase
public function test_book_html_export_shows_chapter_descriptions()
{
$chapterDesc = 'My custom test chapter description ' . Str::random(12);
- $chapter = Chapter::query()->first();
+ $chapter = $this->entities->chapter();
$chapter->description = $chapterDesc;
$chapter->save();
@@ -95,7 +98,7 @@ class ExportTest extends TestCase
public function test_chapter_text_export()
{
- $chapter = Chapter::first();
+ $chapter = $this->entities->chapter();
$page = $chapter->pages[0];
$this->asEditor();
@@ -108,7 +111,7 @@ class ExportTest extends TestCase
public function test_chapter_pdf_export()
{
- $chapter = Chapter::first();
+ $chapter = $this->entities->chapter();
$this->asEditor();
$resp = $this->get($chapter->getUrl('/export/pdf'));
@@ -118,7 +121,7 @@ class ExportTest extends TestCase
public function test_chapter_html_export()
{
- $chapter = Chapter::first();
+ $chapter = $this->entities->chapter();
$page = $chapter->pages[0];
$this->asEditor();
@@ -131,29 +134,51 @@ class ExportTest extends TestCase
public function test_page_html_export_contains_custom_head_if_set()
{
- $page = Page::first();
+ $page = $this->entities->page();
- $customHeadContent = "";
+ $customHeadContent = '';
$this->setSettings(['app-custom-head' => $customHeadContent]);
$resp = $this->asEditor()->get($page->getUrl('/export/html'));
- $resp->assertSee($customHeadContent);
+ $resp->assertSee($customHeadContent, false);
+ }
+
+ public function test_page_html_export_does_not_break_with_only_comments_in_custom_head()
+ {
+ $page = $this->entities->page();
+
+ $customHeadContent = '';
+ $this->setSettings(['app-custom-head' => $customHeadContent]);
+
+ $resp = $this->asEditor()->get($page->getUrl('/export/html'));
+ $resp->assertStatus(200);
+ $resp->assertSee($customHeadContent, false);
}
public function test_page_html_export_use_absolute_dates()
{
- $page = Page::first();
+ $page = $this->entities->page();
$resp = $this->asEditor()->get($page->getUrl('/export/html'));
- $resp->assertSee($page->created_at->toDayDateTimeString());
+ $resp->assertSee($page->created_at->formatLocalized('%e %B %Y %H:%M:%S'));
$resp->assertDontSee($page->created_at->diffForHumans());
- $resp->assertSee($page->updated_at->toDayDateTimeString());
+ $resp->assertSee($page->updated_at->formatLocalized('%e %B %Y %H:%M:%S'));
$resp->assertDontSee($page->updated_at->diffForHumans());
}
+ public function test_page_export_does_not_include_user_or_revision_links()
+ {
+ $page = $this->entities->page();
+
+ $resp = $this->asEditor()->get($page->getUrl('/export/html'));
+ $resp->assertDontSee($page->getUrl('/revisions'));
+ $resp->assertDontSee($page->createdBy->getProfileUrl());
+ $resp->assertSee($page->createdBy->name);
+ }
+
public function test_page_export_sets_right_data_type_for_svg_embeds()
{
- $page = Page::first();
+ $page = $this->entities->page();
Storage::disk('local')->makeDirectory('uploads/images/gallery');
Storage::disk('local')->put('uploads/images/gallery/svg_test.svg', '');
$page->html = '
';
@@ -164,12 +189,12 @@ class ExportTest extends TestCase
Storage::disk('local')->delete('uploads/images/gallery/svg_test.svg');
$resp->assertStatus(200);
- $resp->assertSee('
entities->page();
Storage::disk('local')->makeDirectory('uploads/images/gallery');
Storage::disk('local')->put('uploads/images/gallery/svg_test.svg', '');
Storage::disk('local')->put('uploads/images/gallery/svg_test2.svg', '');
@@ -185,10 +210,10 @@ class ExportTest extends TestCase
public function test_page_export_contained_html_image_fetches_only_run_when_url_points_to_image_upload_folder()
{
- $page = Page::first();
+ $page = $this->entities->page();
$page->html = '
'
- .'
'
- .'
';
+ . '
'
+ . '
';
$storageDisk = Storage::disk('local');
$storageDisk->makeDirectory('uploads/images/gallery');
$storageDisk->put('uploads/images/gallery/svg_test.svg', '');
@@ -200,9 +225,243 @@ class ExportTest extends TestCase
$storageDisk->delete('uploads/images/gallery/svg_test.svg');
$storageDisk->delete('uploads/svg_test.svg');
- $resp->assertDontSee('http://localhost/uploads/images/gallery/svg_test.svg');
+ $resp->assertDontSee('http://localhost/uploads/images/gallery/svg_test.svg', false);
$resp->assertSee('http://localhost/uploads/svg_test.svg');
- $resp->assertSee('src="/uploads/svg_test.svg"');
+ $resp->assertSee('src="/uploads/svg_test.svg"', false);
+ }
+
+ public function test_page_export_contained_html_does_not_allow_upward_traversal_with_local()
+ {
+ $contents = file_get_contents(public_path('.htaccess'));
+ config()->set('filesystems.images', 'local');
+
+ $page = $this->entities->page();
+ $page->html = '
';
+ $page->save();
+
+ $resp = $this->asEditor()->get($page->getUrl('/export/html'));
+ $resp->assertDontSee(base64_encode($contents));
+ }
+
+ public function test_page_export_contained_html_does_not_allow_upward_traversal_with_local_secure()
+ {
+ $testFilePath = storage_path('logs/test.txt');
+ config()->set('filesystems.images', 'local_secure');
+ file_put_contents($testFilePath, 'I am a cat');
+
+ $page = $this->entities->page();
+ $page->html = '
';
+ $page->save();
+
+ $resp = $this->asEditor()->get($page->getUrl('/export/html'));
+ $resp->assertDontSee(base64_encode('I am a cat'));
+ unlink($testFilePath);
+ }
+
+ public function test_exports_removes_scripts_from_custom_head()
+ {
+ $entities = [
+ Page::query()->first(), Chapter::query()->first(), Book::query()->first(),
+ ];
+ setting()->put('app-custom-head', '');
+
+ foreach ($entities as $entity) {
+ $resp = $this->asEditor()->get($entity->getUrl('/export/html'));
+ $resp->assertDontSee('window.donkey');
+ $resp->assertDontSee('