mirror of
https://github.com/zadam/trilium.git
synced 2025-11-03 03:46:37 +01:00
server-ts: Port anonymization service
This commit is contained in:
97
src/services/anonymization.ts
Normal file
97
src/services/anonymization.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import BUILTIN_ATTRIBUTES = require('./builtin_attributes');
|
||||
import fs = require("fs-extra");
|
||||
import dataDir = require('./data_dir');
|
||||
import dateUtils = require('./date_utils');
|
||||
import Database = require("better-sqlite3");
|
||||
import sql = require('./sql');
|
||||
import path = require("path");
|
||||
|
||||
function getFullAnonymizationScript() {
|
||||
// we want to delete all non-builtin attributes because they can contain sensitive names and values
|
||||
// on the other hand builtin/system attrs should not contain any sensitive info
|
||||
const builtinAttrNames = BUILTIN_ATTRIBUTES
|
||||
.filter(attr => !["shareCredentials", "shareAlias"].includes(attr.name))
|
||||
.map(attr => `'${attr.name}'`).join(', ');
|
||||
|
||||
const anonymizeScript = `
|
||||
UPDATE etapi_tokens SET tokenHash = 'API token hash value';
|
||||
UPDATE notes SET title = 'title' WHERE title NOT IN ('root', '_hidden', '_share');
|
||||
UPDATE blobs SET content = 'text' WHERE content IS NOT NULL;
|
||||
UPDATE revisions SET title = 'title';
|
||||
|
||||
UPDATE attributes SET name = 'name', value = 'value' WHERE type = 'label' AND name NOT IN(${builtinAttrNames});
|
||||
UPDATE attributes SET name = 'name' WHERE type = 'relation' AND name NOT IN (${builtinAttrNames});
|
||||
UPDATE branches SET prefix = 'prefix' WHERE prefix IS NOT NULL AND prefix != 'recovered';
|
||||
UPDATE options SET value = 'anonymized' WHERE name IN
|
||||
('documentId', 'documentSecret', 'encryptedDataKey',
|
||||
'passwordVerificationHash', 'passwordVerificationSalt',
|
||||
'passwordDerivedKeySalt', 'username', 'syncServerHost', 'syncProxy')
|
||||
AND value != '';
|
||||
|
||||
VACUUM;
|
||||
`;
|
||||
|
||||
return anonymizeScript;
|
||||
}
|
||||
|
||||
function getLightAnonymizationScript() {
|
||||
return `UPDATE blobs SET content = 'text' WHERE content IS NOT NULL AND blobId NOT IN (
|
||||
SELECT blobId FROM notes WHERE mime IN ('application/javascript;env=backend', 'application/javascript;env=frontend')
|
||||
UNION ALL
|
||||
SELECT blobId FROM revisions WHERE mime IN ('application/javascript;env=backend', 'application/javascript;env=frontend')
|
||||
);
|
||||
|
||||
UPDATE options SET value = 'anonymized' WHERE name IN
|
||||
('documentId', 'documentSecret', 'encryptedDataKey',
|
||||
'passwordVerificationHash', 'passwordVerificationSalt',
|
||||
'passwordDerivedKeySalt', 'username', 'syncServerHost', 'syncProxy')
|
||||
AND value != '';`;
|
||||
}
|
||||
|
||||
async function createAnonymizedCopy(type: "full" | "light") {
|
||||
if (!['full', 'light'].includes(type)) {
|
||||
throw new Error(`Unrecognized anonymization type '${type}'`);
|
||||
}
|
||||
|
||||
if (!fs.existsSync(dataDir.ANONYMIZED_DB_DIR)) {
|
||||
fs.mkdirSync(dataDir.ANONYMIZED_DB_DIR, 0o700);
|
||||
}
|
||||
|
||||
const anonymizedFile = `${dataDir.ANONYMIZED_DB_DIR}/anonymized-${type}-${dateUtils.getDateTimeForFile()}.db`;
|
||||
|
||||
await sql.copyDatabase(anonymizedFile);
|
||||
|
||||
const db = new Database(anonymizedFile);
|
||||
|
||||
const anonymizationScript = type === 'light'
|
||||
? getLightAnonymizationScript()
|
||||
: getFullAnonymizationScript();
|
||||
|
||||
db.exec(anonymizationScript);
|
||||
|
||||
db.close();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
anonymizedFilePath: anonymizedFile
|
||||
};
|
||||
}
|
||||
|
||||
function getExistingAnonymizedDatabases() {
|
||||
if (!fs.existsSync(dataDir.ANONYMIZED_DB_DIR)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return fs.readdirSync(dataDir.ANONYMIZED_DB_DIR)
|
||||
.filter(fileName => fileName.includes("anonymized"))
|
||||
.map(fileName => ({
|
||||
fileName: fileName,
|
||||
filePath: path.resolve(dataDir.ANONYMIZED_DB_DIR, fileName)
|
||||
}));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getFullAnonymizationScript,
|
||||
createAnonymizedCopy,
|
||||
getExistingAnonymizedDatabases
|
||||
}
|
||||
Reference in New Issue
Block a user