mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-12-12 13:33:46 +08:00
Attachments: Hid edit/delete controls where lacking permission
Some checks are pending
analyse-php / build (push) Waiting to run
lint-js / build (push) Waiting to run
lint-php / build (push) Waiting to run
test-js / build (push) Waiting to run
test-migrations / build (8.1) (push) Waiting to run
test-migrations / build (8.2) (push) Waiting to run
test-migrations / build (8.3) (push) Waiting to run
test-migrations / build (8.4) (push) Waiting to run
test-php / build (8.1) (push) Waiting to run
test-php / build (8.2) (push) Waiting to run
test-php / build (8.3) (push) Waiting to run
test-php / build (8.4) (push) Waiting to run
Some checks are pending
analyse-php / build (push) Waiting to run
lint-js / build (push) Waiting to run
lint-php / build (push) Waiting to run
test-js / build (push) Waiting to run
test-migrations / build (8.1) (push) Waiting to run
test-migrations / build (8.2) (push) Waiting to run
test-migrations / build (8.3) (push) Waiting to run
test-migrations / build (8.4) (push) Waiting to run
test-php / build (8.1) (push) Waiting to run
test-php / build (8.2) (push) Waiting to run
test-php / build (8.3) (push) Waiting to run
test-php / build (8.4) (push) Waiting to run
Added test to cover. Also migrated related ajax-delete-row component to ts. For #5323
This commit is contained in:
parent
0ece664475
commit
fcf0bf79a9
|
@ -1,12 +1,16 @@
|
||||||
import {onSelect} from '../services/dom.ts';
|
import {onSelect} from '../services/dom';
|
||||||
import {Component} from './component';
|
import {Component} from './component';
|
||||||
|
|
||||||
export class AjaxDeleteRow extends Component {
|
export class AjaxDeleteRow extends Component {
|
||||||
|
|
||||||
|
protected row!: HTMLElement;
|
||||||
|
protected url!: string;
|
||||||
|
protected deleteButtons: HTMLElement[] = [];
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
this.row = this.$el;
|
this.row = this.$el;
|
||||||
this.url = this.$opts.url;
|
this.url = this.$opts.url;
|
||||||
this.deleteButtons = this.$manyRefs.delete;
|
this.deleteButtons = this.$manyRefs.delete || [];
|
||||||
|
|
||||||
onSelect(this.deleteButtons, this.runDelete.bind(this));
|
onSelect(this.deleteButtons, this.runDelete.bind(this));
|
||||||
}
|
}
|
||||||
|
@ -21,8 +25,8 @@ export class AjaxDeleteRow extends Component {
|
||||||
}
|
}
|
||||||
this.row.remove();
|
this.row.remove();
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.row.style.opacity = null;
|
this.row.style.removeProperty('opacity');
|
||||||
this.row.style.pointerEvents = null;
|
this.row.style.removeProperty('pointer-events');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,20 +8,20 @@ export class Component {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The element that the component is registered upon.
|
* The element that the component is registered upon.
|
||||||
* @type {Element}
|
* @type {HTMLElement}
|
||||||
*/
|
*/
|
||||||
$el = null;
|
$el = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapping of referenced elements within the component.
|
* Mapping of referenced elements within the component.
|
||||||
* @type {Object<string, Element>}
|
* @type {Object<string, HTMLElement>}
|
||||||
*/
|
*/
|
||||||
$refs = {};
|
$refs = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapping of arrays of referenced elements within the component so multiple
|
* Mapping of arrays of referenced elements within the component so multiple
|
||||||
* references, sharing the same name, can be fetched.
|
* references, sharing the same name, can be fetched.
|
||||||
* @type {Object<string, Element[]>}
|
* @type {Object<string, HTMLElement[]>}
|
||||||
*/
|
*/
|
||||||
$manyRefs = {};
|
$manyRefs = {};
|
||||||
|
|
||||||
|
|
|
@ -15,23 +15,27 @@
|
||||||
option:event-emit-select:name="insert"
|
option:event-emit-select:name="insert"
|
||||||
type="button"
|
type="button"
|
||||||
title="{{ trans('entities.attachments_insert_link') }}"
|
title="{{ trans('entities.attachments_insert_link') }}"
|
||||||
class="drag-card-action text-center text-link">@icon('link') </button>
|
class="drag-card-action text-center text-link">@icon('link')</button>
|
||||||
<button component="event-emit-select"
|
@if(userCan('attachment-update', $attachment))
|
||||||
option:event-emit-select:name="edit"
|
<button component="event-emit-select"
|
||||||
option:event-emit-select:id="{{ $attachment->id }}"
|
option:event-emit-select:name="edit"
|
||||||
type="button"
|
option:event-emit-select:id="{{ $attachment->id }}"
|
||||||
title="{{ trans('common.edit') }}"
|
|
||||||
class="drag-card-action text-center text-link">@icon('edit')</button>
|
|
||||||
<div component="dropdown" class="flex-fill relative">
|
|
||||||
<button refs="dropdown@toggle"
|
|
||||||
type="button"
|
type="button"
|
||||||
title="{{ trans('common.delete') }}"
|
title="{{ trans('common.edit') }}"
|
||||||
class="drag-card-action text-center text-neg">@icon('close')</button>
|
class="drag-card-action text-center text-link">@icon('edit')</button>
|
||||||
<div refs="dropdown@menu" class="dropdown-menu">
|
@endif
|
||||||
<p class="text-neg small px-m mb-xs">{{ trans('entities.attachments_delete') }}</p>
|
@if(userCan('attachment-delete', $attachment))
|
||||||
<button refs="ajax-delete-row@delete" type="button" class="text-link small delete text-item">{{ trans('common.confirm') }}</button>
|
<div component="dropdown" class="flex-fill relative">
|
||||||
|
<button refs="dropdown@toggle"
|
||||||
|
type="button"
|
||||||
|
title="{{ trans('common.delete') }}"
|
||||||
|
class="drag-card-action text-center text-neg">@icon('close')</button>
|
||||||
|
<div refs="dropdown@menu" class="dropdown-menu">
|
||||||
|
<p class="text-neg small px-m mb-xs">{{ trans('entities.attachments_delete') }}</p>
|
||||||
|
<button refs="ajax-delete-row@delete" type="button" class="text-link small delete text-item">{{ trans('common.confirm') }}</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
|
@ -267,6 +267,50 @@ class AttachmentTest extends TestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_attachment_delete_only_shows_with_permission()
|
||||||
|
{
|
||||||
|
$this->asAdmin();
|
||||||
|
$page = $this->entities->page();
|
||||||
|
$this->files->uploadAttachmentFile($this, 'upload_test.txt', $page->id);
|
||||||
|
$attachment = $page->attachments()->first();
|
||||||
|
$viewer = $this->users->viewer();
|
||||||
|
|
||||||
|
$this->permissions->grantUserRolePermissions($viewer, ['page-update-all', 'attachment-create-all']);
|
||||||
|
|
||||||
|
$resp = $this->actingAs($viewer)->get($page->getUrl('/edit'));
|
||||||
|
$html = $this->withHtml($resp);
|
||||||
|
$html->assertElementExists(".card[data-id=\"{$attachment->id}\"]");
|
||||||
|
$html->assertElementNotExists(".card[data-id=\"{$attachment->id}\"] button[title=\"Delete\"]");
|
||||||
|
|
||||||
|
$this->permissions->grantUserRolePermissions($viewer, ['attachment-delete-all']);
|
||||||
|
|
||||||
|
$resp = $this->actingAs($viewer)->get($page->getUrl('/edit'));
|
||||||
|
$html = $this->withHtml($resp);
|
||||||
|
$html->assertElementExists(".card[data-id=\"{$attachment->id}\"] button[title=\"Delete\"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_attachment_edit_only_shows_with_permission()
|
||||||
|
{
|
||||||
|
$this->asAdmin();
|
||||||
|
$page = $this->entities->page();
|
||||||
|
$this->files->uploadAttachmentFile($this, 'upload_test.txt', $page->id);
|
||||||
|
$attachment = $page->attachments()->first();
|
||||||
|
$viewer = $this->users->viewer();
|
||||||
|
|
||||||
|
$this->permissions->grantUserRolePermissions($viewer, ['page-update-all', 'attachment-create-all']);
|
||||||
|
|
||||||
|
$resp = $this->actingAs($viewer)->get($page->getUrl('/edit'));
|
||||||
|
$html = $this->withHtml($resp);
|
||||||
|
$html->assertElementExists(".card[data-id=\"{$attachment->id}\"]");
|
||||||
|
$html->assertElementNotExists(".card[data-id=\"{$attachment->id}\"] button[title=\"Edit\"]");
|
||||||
|
|
||||||
|
$this->permissions->grantUserRolePermissions($viewer, ['attachment-update-all']);
|
||||||
|
|
||||||
|
$resp = $this->actingAs($viewer)->get($page->getUrl('/edit'));
|
||||||
|
$html = $this->withHtml($resp);
|
||||||
|
$html->assertElementExists(".card[data-id=\"{$attachment->id}\"] button[title=\"Edit\"]");
|
||||||
|
}
|
||||||
|
|
||||||
public function test_file_access_with_open_query_param_provides_inline_response_with_correct_content_type()
|
public function test_file_access_with_open_query_param_provides_inline_response_with_correct_content_type()
|
||||||
{
|
{
|
||||||
$page = $this->entities->page();
|
$page = $this->entities->page();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user