allow configuring the time period before deleted notes are erased (and changed the default to 7 days)

This commit is contained in:
zadam 2020-01-03 22:32:49 +01:00
parent 1699646b39
commit 54d89a9f47
4 changed files with 46 additions and 5 deletions

View file

@ -37,6 +37,20 @@ const TPL = `
</div> </div>
</div> </div>
<div>
<h4>Note erasure timeout</h4>
<p>Deleted notes are at first only marked as deleted and it is possible to recover them
from Recent Notes dialog. After period of time, deleted notes are "erased" which means
their content is not recoverable anymore. This setting allows you to configure the length
of the period between deleting and erasing the note.</p>
<div class="form-group">
<label for="erase-notes-after-time-in-seconds">Erase notes after X seconds</label>
<input class="form-control" id="erase-notes-after-time-in-seconds" type="number" min="0">
</div>
</div>
<div> <div>
<h4>Protected session timeout</h4> <h4>Protected session timeout</h4>
@ -81,6 +95,20 @@ export default class ProtectedSessionOptions {
return false; return false;
}); });
this.$eraseNotesAfterTimeInSeconds = $("#erase-notes-after-time-in-seconds");
this.$eraseNotesAfterTimeInSeconds.on('change', () => {
const eraseNotesAfterTimeInSeconds = this.$eraseNotesAfterTimeInSeconds.val();
server.put('options', { 'eraseNotesAfterTimeInSeconds': eraseNotesAfterTimeInSeconds }).then(() => {
optionsService.reloadOptions();
toastService.showMessage("Options change have been saved.");
});
return false;
});
this.$protectedSessionTimeout = $("#protected-session-timeout-in-seconds"); this.$protectedSessionTimeout = $("#protected-session-timeout-in-seconds");
this.$protectedSessionTimeout.on('change', () => { this.$protectedSessionTimeout.on('change', () => {
@ -126,6 +154,7 @@ export default class ProtectedSessionOptions {
this.$spellCheckEnabled.prop("checked", options['spellCheckEnabled'] === 'true'); this.$spellCheckEnabled.prop("checked", options['spellCheckEnabled'] === 'true');
this.$spellCheckLanguageCode.val(options['spellCheckLanguageCode']); this.$spellCheckLanguageCode.val(options['spellCheckLanguageCode']);
this.$eraseNotesAfterTimeInSeconds.val(options['eraseNotesAfterTimeInSeconds']);
this.$protectedSessionTimeout.val(options['protectedSessionTimeout']); this.$protectedSessionTimeout.val(options['protectedSessionTimeout']);
this.$noteRevisionsTimeInterval.val(options['noteRevisionSnapshotTimeInterval']); this.$noteRevisionsTimeInterval.val(options['noteRevisionSnapshotTimeInterval']);

View file

@ -6,6 +6,7 @@ const attributes = require('../../services/attributes');
// options allowed to be updated directly in options dialog // options allowed to be updated directly in options dialog
const ALLOWED_OPTIONS = new Set([ const ALLOWED_OPTIONS = new Set([
'eraseNotesAfterTimeInSeconds',
'protectedSessionTimeout', 'protectedSessionTimeout',
'noteRevisionSnapshotTimeInterval', 'noteRevisionSnapshotTimeInterval',
'zoomFactor', 'zoomFactor',

View file

@ -547,7 +547,9 @@ async function scanForLinks(noteId) {
} }
async function eraseDeletedNotes() { async function eraseDeletedNotes() {
const cutoffDate = new Date(Date.now() - 48 * 3600 * 1000); const eraseNotesAfterTimeInSeconds = await optionService.getOptionInt('eraseNotesAfterTimeInSeconds');
const cutoffDate = new Date(Date.now() - eraseNotesAfterTimeInSeconds * 1000);
const noteIdsToErase = await sql.getColumn("SELECT noteId FROM notes WHERE isDeleted = 1 AND isErased = 0 AND notes.utcDateModified <= ?", [dateUtils.utcDateStr(cutoffDate)]); const noteIdsToErase = await sql.getColumn("SELECT noteId FROM notes WHERE isDeleted = 1 AND isErased = 0 AND notes.utcDateModified <= ?", [dateUtils.utcDateStr(cutoffDate)]);
@ -561,10 +563,11 @@ async function eraseDeletedNotes() {
// - we don't want change the hash since this erasing happens on each instance separately // - we don't want change the hash since this erasing happens on each instance separately
// and changing the hash would fire up the sync errors temporarily // and changing the hash would fire up the sync errors temporarily
// setting contentLength to zero would serve no benefit and it leaves potentially useful trail
await sql.executeMany(` await sql.executeMany(`
UPDATE notes UPDATE notes
SET isErased = 1 SET title = '[deleted]',
contentLength = 0,
isErased = 1
WHERE noteId IN (???)`, noteIdsToErase); WHERE noteId IN (???)`, noteIdsToErase);
await sql.executeMany(` await sql.executeMany(`
@ -582,8 +585,15 @@ async function eraseDeletedNotes() {
await sql.executeMany(` await sql.executeMany(`
UPDATE note_revisions UPDATE note_revisions
SET isErased = 1, SET isErased = 1,
title = NULL title = NULL,
contentLength = 0
WHERE isErased = 0 AND noteId IN (???)`, noteIdsToErase); WHERE isErased = 0 AND noteId IN (???)`, noteIdsToErase);
await sql.executeMany(`
UPDATE attributes
SET name = 'deleted',
value = ''
WHERE noteId IN (???)`, noteIdsToErase);
} }
async function duplicateNote(noteId, parentNoteId) { async function duplicateNote(noteId, parentNoteId) {

View file

@ -80,7 +80,8 @@ const defaultOptions = [
{ name: 'leftPaneWidth', value: '25', isSynced: false }, { name: 'leftPaneWidth', value: '25', isSynced: false },
{ name: 'rightPaneWidth', value: '25', isSynced: false }, { name: 'rightPaneWidth', value: '25', isSynced: false },
{ name: 'rightPaneVisible', value: 'true', isSynced: false }, { name: 'rightPaneVisible', value: 'true', isSynced: false },
{ name: 'nativeTitleBarVisible', value: 'false', isSynced: false } { name: 'nativeTitleBarVisible', value: 'false', isSynced: false },
{ name: 'eraseNotesAfterTimeInSeconds', value: '604800', isSynced: true } // default is 7 days
]; ];
async function initStartupOptions() { async function initStartupOptions() {