Skip to content

Commit

Permalink
Update live edit feature to protect against overwriting modified content
Browse files Browse the repository at this point in the history
Updates the live edit feature to protect against overwriting content modified in other tabs/editors
  • Loading branch information
caendesilva committed Nov 17, 2023
1 parent 4d94129 commit 8380602
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/realtime-compiler/resources/live-edit.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
</header>
<input type="hidden" name="_token" value="{{ $csrfToken }}">
<input type="hidden" name="page" value="{{ $page->getSourcePath() }}">
<input type="hidden" name="currentContentHash" value="{{ hash_file('sha256', $page->getSourcePath()) }}">
<label for="live-editor" class="sr-only">Edit page contents</label>
<textarea name="markdown" id="live-editor" cols="30" rows="20" class="rounded-lg bg-gray-200 dark:bg-gray-800">{{ $markdown }}</textarea>
</form>
Expand Down
8 changes: 8 additions & 0 deletions packages/realtime-compiler/resources/live-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ function initLiveEdit() {
if (response.ok) {
window.location.reload();
} else {
if (response.status === 409) {
if (confirm('This page has been modified in another window. Do you want to overwrite the changes?')) {
document.getElementById('liveEditForm').insertAdjacentHTML('beforeend', '<input type="hidden" name="force" value="true">');
document.getElementById('liveEditForm').submit();
}
return;
}

alert(`Error saving content: ${response.status} ${response.statusText}\n${JSON.parse(await response.text()).error ?? 'Unknown error'}`);
}
});
Expand Down
6 changes: 6 additions & 0 deletions packages/realtime-compiler/src/Http/LiveEditController.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,19 @@ protected function handleRequest(): Response
{
$pagePath = $this->request->data['page'] ?? $this->abort(400, 'Must provide page path');
$content = $this->request->data['markdown'] ?? $this->abort(400, 'Must provide content');
$currentContentHash = $this->request->data['currentContentHash'] ?? $this->abort(400, 'Must provide content hash');
$force = $this->request->data['force'] ?? false;

$page = Hyde::pages()->getPage($pagePath);

if (! $page instanceof BaseMarkdownPage) {
$this->abort(400, 'Page is not a markdown page');
}

if (! $force && hash_file('sha256', $page->getSourcePath()) !== $currentContentHash) {
$this->abort(409, 'Content has changed in another window');
}

$page->markdown = new Markdown($content);
$page->save();

Expand Down

0 comments on commit 8380602

Please sign in to comment.