mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
db anonymization implementation
This commit is contained in:
parent
fab69f411e
commit
5b08dfefd3
@ -17,7 +17,7 @@ const settings = (function() {
|
|||||||
|
|
||||||
dialogEl.dialog({
|
dialogEl.dialog({
|
||||||
modal: true,
|
modal: true,
|
||||||
width: 800
|
width: 900
|
||||||
});
|
});
|
||||||
|
|
||||||
tabsEl.tabs();
|
tabsEl.tabs();
|
||||||
@ -161,5 +161,17 @@ settings.addModule((async function () {
|
|||||||
showMessage("Full sync triggered");
|
showMessage("Full sync triggered");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return {};
|
||||||
|
})());
|
||||||
|
|
||||||
|
settings.addModule((async function () {
|
||||||
|
const anonymizeButton = $("#anonymize-button");
|
||||||
|
|
||||||
|
anonymizeButton.click(async () => {
|
||||||
|
await server.post('anonymization/anonymize');
|
||||||
|
|
||||||
|
showMessage("Created anonymized database");
|
||||||
|
});
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
})());
|
})());
|
13
routes/api/anonymization.js
Normal file
13
routes/api/anonymization.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
const anonymization = require('../../services/anonymization');
|
||||||
|
|
||||||
|
router.post('/anonymize', async (req, res, next) => {
|
||||||
|
await anonymization.anonymize();
|
||||||
|
|
||||||
|
res.send({});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
@ -22,6 +22,7 @@ const exportRoute = require('./api/export');
|
|||||||
const importRoute = require('./api/import');
|
const importRoute = require('./api/import');
|
||||||
const setupApiRoute = require('./api/setup');
|
const setupApiRoute = require('./api/setup');
|
||||||
const sqlRoute = require('./api/sql');
|
const sqlRoute = require('./api/sql');
|
||||||
|
const anonymizationRoute = require('./api/anonymization');
|
||||||
|
|
||||||
function register(app) {
|
function register(app) {
|
||||||
app.use('/', indexRoute);
|
app.use('/', indexRoute);
|
||||||
@ -47,6 +48,7 @@ function register(app) {
|
|||||||
app.use('/api/import', importRoute);
|
app.use('/api/import', importRoute);
|
||||||
app.use('/api/setup', setupApiRoute);
|
app.use('/api/setup', setupApiRoute);
|
||||||
app.use('/api/sql', sqlRoute);
|
app.use('/api/sql', sqlRoute);
|
||||||
|
app.use('/api/anonymization', anonymizationRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
32
services/anonymization.js
Normal file
32
services/anonymization.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const data_dir = require('./data_dir');
|
||||||
|
const utils = require('./utils');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
const sqlite = require('sqlite');
|
||||||
|
|
||||||
|
async function anonymize() {
|
||||||
|
if (!fs.existsSync(data_dir.ANONYMIZED_DB_DIR)) {
|
||||||
|
fs.mkdirSync(data_dir.ANONYMIZED_DB_DIR, 0o700);
|
||||||
|
}
|
||||||
|
|
||||||
|
const anonymizedFile = data_dir.ANONYMIZED_DB_DIR + "/" + "backup-" + utils.getDateTimeForFile() + ".db";
|
||||||
|
|
||||||
|
fs.copySync(data_dir.DOCUMENT_PATH, anonymizedFile);
|
||||||
|
|
||||||
|
const db = await sqlite.open(anonymizedFile, {Promise});
|
||||||
|
|
||||||
|
await db.run("UPDATE notes SET note_title = 'title', note_text = 'text'");
|
||||||
|
await db.run("UPDATE notes_history SET note_title = 'title', note_text = 'text'");
|
||||||
|
await db.run("UPDATE notes_tree SET prefix = 'prefix' WHERE prefix IS NOT NULL");
|
||||||
|
await db.run(`UPDATE options SET opt_value = 'anonymized' WHERE opt_name IN
|
||||||
|
('document_secret', 'encrypted_data_key', 'password_verification_hash',
|
||||||
|
'password_verification_salt', 'password_derived_key_salt')`);
|
||||||
|
await db.run("VACUUM");
|
||||||
|
|
||||||
|
await db.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
anonymize
|
||||||
|
};
|
@ -23,9 +23,7 @@ async function regularBackup() {
|
|||||||
async function backupNow() {
|
async function backupNow() {
|
||||||
const now = utils.nowDate();
|
const now = utils.nowDate();
|
||||||
|
|
||||||
const date_str = new Date().toISOString().substr(0, 19).replace(/:/g, '');
|
const backupFile = dataDir.BACKUP_DIR + "/" + "backup-" + utils.getDateTimeForFile() + ".db";
|
||||||
|
|
||||||
const backupFile = dataDir.BACKUP_DIR + "/" + "backup-" + date_str + ".db";
|
|
||||||
|
|
||||||
fs.copySync(dataDir.DOCUMENT_PATH, backupFile);
|
fs.copySync(dataDir.DOCUMENT_PATH, backupFile);
|
||||||
|
|
||||||
|
@ -13,11 +13,13 @@ const DOCUMENT_PATH = TRILIUM_DATA_DIR + "/document.db";
|
|||||||
const BACKUP_DIR = TRILIUM_DATA_DIR + "/backup";
|
const BACKUP_DIR = TRILIUM_DATA_DIR + "/backup";
|
||||||
const LOG_DIR = TRILIUM_DATA_DIR + "/log";
|
const LOG_DIR = TRILIUM_DATA_DIR + "/log";
|
||||||
const EXPORT_DIR = TRILIUM_DATA_DIR + "/export";
|
const EXPORT_DIR = TRILIUM_DATA_DIR + "/export";
|
||||||
|
const ANONYMIZED_DB_DIR = TRILIUM_DATA_DIR + "/anonymized-db";
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
TRILIUM_DATA_DIR,
|
TRILIUM_DATA_DIR,
|
||||||
DOCUMENT_PATH,
|
DOCUMENT_PATH,
|
||||||
BACKUP_DIR,
|
BACKUP_DIR,
|
||||||
LOG_DIR,
|
LOG_DIR,
|
||||||
EXPORT_DIR
|
EXPORT_DIR,
|
||||||
|
ANONYMIZED_DB_DIR
|
||||||
};
|
};
|
@ -118,7 +118,7 @@ async function pullSync(syncContext) {
|
|||||||
|
|
||||||
for (const sync of syncRows) {
|
for (const sync of syncRows) {
|
||||||
if (source_id.isLocalSourceId(sync.source_id)) {
|
if (source_id.isLocalSourceId(sync.source_id)) {
|
||||||
log.info(`Skipping pull #${sync.id} ${sync.entity_name} ${sync.entity_id} because it has local source id.`);
|
log.info(`Skipping pull #${sync.id} ${sync.entity_name} ${sync.entity_id} because ${sync.source_id} is a local source id.`);
|
||||||
|
|
||||||
await setLastSyncedPull(sync.id);
|
await setLastSyncedPull(sync.id);
|
||||||
|
|
||||||
|
@ -70,6 +70,9 @@ function isEmptyOrWhitespace(str) {
|
|||||||
return str === null || str.match(/^ *$/) !== null;
|
return str === null || str.match(/^ *$/) !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDateTimeForFile() {
|
||||||
|
return new Date().toISOString().substr(0, 19).replace(/:/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
randomSecureToken,
|
randomSecureToken,
|
||||||
@ -85,5 +88,6 @@ module.exports = {
|
|||||||
hmac,
|
hmac,
|
||||||
isElectron,
|
isElectron,
|
||||||
hash,
|
hash,
|
||||||
isEmptyOrWhitespace
|
isEmptyOrWhitespace,
|
||||||
|
getDateTimeForFile
|
||||||
};
|
};
|
@ -166,6 +166,7 @@
|
|||||||
<li><a href="#protected-session-timeout">Protected session</a></li>
|
<li><a href="#protected-session-timeout">Protected session</a></li>
|
||||||
<li><a href="#history-snapshot-time-interval">History snapshots</a></li>
|
<li><a href="#history-snapshot-time-interval">History snapshots</a></li>
|
||||||
<li><a href="#sync">Sync</a></li>
|
<li><a href="#sync">Sync</a></li>
|
||||||
|
<li><a href="#debugging">Debugging</a></li>
|
||||||
<li><a href="#about">About Trilium</a></li>
|
<li><a href="#about">About Trilium</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div id="change-password">
|
<div id="change-password">
|
||||||
@ -216,6 +217,9 @@
|
|||||||
<div id="sync">
|
<div id="sync">
|
||||||
<button id="force-full-sync-button" class="btn btn-sm">Force full sync</button>
|
<button id="force-full-sync-button" class="btn btn-sm">Force full sync</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="debugging">
|
||||||
|
<button id="anonymize-button" class="btn btn-sm">Save anonymized database</button>
|
||||||
|
</div>
|
||||||
<div id="about">
|
<div id="about">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<tr>
|
<tr>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user