mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
commit
5c5e5603d8
17
db/migrations/0228__fix_blobIds.sql
Normal file
17
db/migrations/0228__fix_blobIds.sql
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
-- + is normally replaced by X and / by Y, but this can temporarily cause UNIQUE key exception
|
||||||
|
-- this might create blob duplicates, but cleanup will eventually take care of it
|
||||||
|
|
||||||
|
UPDATE blobs SET blobId = REPLACE(blobId, '+', 'A');
|
||||||
|
UPDATE blobs SET blobId = REPLACE(blobId, '/', 'B');
|
||||||
|
|
||||||
|
UPDATE notes SET blobId = REPLACE(blobId, '+', 'A');
|
||||||
|
UPDATE notes SET blobId = REPLACE(blobId, '/', 'B');
|
||||||
|
|
||||||
|
UPDATE attachments SET blobId = REPLACE(blobId, '+', 'A');
|
||||||
|
UPDATE attachments SET blobId = REPLACE(blobId, '/', 'B');
|
||||||
|
|
||||||
|
UPDATE revisions SET blobId = REPLACE(blobId, '+', 'A');
|
||||||
|
UPDATE revisions SET blobId = REPLACE(blobId, '/', 'B');
|
||||||
|
|
||||||
|
UPDATE entity_changes SET entityId = REPLACE(entityId, '+', 'A') WHERE entityName = 'blobs';
|
||||||
|
UPDATE entity_changes SET entityId = REPLACE(entityId, '/', 'B') WHERE entityName = 'blobs';
|
1761
package-lock.json
generated
1761
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
32
package.json
32
package.json
@ -2,7 +2,7 @@
|
|||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"productName": "Trilium Notes",
|
"productName": "Trilium Notes",
|
||||||
"description": "Trilium Notes",
|
"description": "Trilium Notes",
|
||||||
"version": "0.62.4",
|
"version": "0.63.0-beta",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"main": "electron.js",
|
"main": "electron.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -37,11 +37,11 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@braintree/sanitize-url": "6.0.4",
|
"@braintree/sanitize-url": "6.0.4",
|
||||||
"@electron/remote": "2.1.0",
|
"@electron/remote": "2.1.1",
|
||||||
"@excalidraw/excalidraw": "0.16.1",
|
"@excalidraw/excalidraw": "0.16.1",
|
||||||
"archiver": "6.0.1",
|
"archiver": "6.0.1",
|
||||||
"async-mutex": "0.4.0",
|
"async-mutex": "0.4.0",
|
||||||
"axios": "1.6.2",
|
"axios": "1.6.3",
|
||||||
"better-sqlite3": "8.4.0",
|
"better-sqlite3": "8.4.0",
|
||||||
"boxicons": "2.1.4",
|
"boxicons": "2.1.4",
|
||||||
"chokidar": "3.5.3",
|
"chokidar": "3.5.3",
|
||||||
@ -59,10 +59,10 @@
|
|||||||
"escape-html": "1.0.3",
|
"escape-html": "1.0.3",
|
||||||
"express": "4.18.2",
|
"express": "4.18.2",
|
||||||
"express-partial-content": "1.0.2",
|
"express-partial-content": "1.0.2",
|
||||||
"express-rate-limit": "7.1.4",
|
"express-rate-limit": "7.1.5",
|
||||||
"express-session": "1.17.3",
|
"express-session": "1.17.3",
|
||||||
"force-graph": "1.43.4",
|
"force-graph": "1.43.4",
|
||||||
"fs-extra": "11.1.1",
|
"fs-extra": "11.2.0",
|
||||||
"helmet": "7.1.0",
|
"helmet": "7.1.0",
|
||||||
"html": "1.0.0",
|
"html": "1.0.0",
|
||||||
"html2plaintext": "2.1.4",
|
"html2plaintext": "2.1.4",
|
||||||
@ -76,13 +76,13 @@
|
|||||||
"joplin-turndown-plugin-gfm": "1.0.12",
|
"joplin-turndown-plugin-gfm": "1.0.12",
|
||||||
"jquery": "3.7.1",
|
"jquery": "3.7.1",
|
||||||
"jquery-hotkeys": "0.2.2",
|
"jquery-hotkeys": "0.2.2",
|
||||||
"jsdom": "22.1.0",
|
"jsdom": "23.0.1",
|
||||||
"katex": "0.16.9",
|
"katex": "0.16.9",
|
||||||
"marked": "9.1.6",
|
"marked": "9.1.6",
|
||||||
"mermaid": "10.6.1",
|
"mermaid": "10.6.1",
|
||||||
"mime-types": "2.1.35",
|
"mime-types": "2.1.35",
|
||||||
"multer": "1.4.5-lts.1",
|
"multer": "1.4.5-lts.1",
|
||||||
"node-abi": "3.51.0",
|
"node-abi": "3.52.0",
|
||||||
"normalize-strings": "1.1.1",
|
"normalize-strings": "1.1.1",
|
||||||
"open": "8.4.1",
|
"open": "8.4.1",
|
||||||
"panzoom": "9.4.3",
|
"panzoom": "9.4.3",
|
||||||
@ -106,31 +106,31 @@
|
|||||||
"tree-kill": "1.2.2",
|
"tree-kill": "1.2.2",
|
||||||
"turndown": "7.1.2",
|
"turndown": "7.1.2",
|
||||||
"unescape": "1.0.1",
|
"unescape": "1.0.1",
|
||||||
"ws": "8.14.2",
|
"ws": "8.16.0",
|
||||||
"xml2js": "0.6.2",
|
"xml2js": "0.6.2",
|
||||||
"yauzl": "2.10.0"
|
"yauzl": "2.10.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"electron": "25.9.8",
|
"electron": "25.9.8",
|
||||||
"electron-builder": "24.6.4",
|
"electron-builder": "24.9.1",
|
||||||
"electron-packager": "17.1.2",
|
"electron-packager": "17.1.2",
|
||||||
"electron-rebuild": "3.2.9",
|
"electron-rebuild": "3.2.9",
|
||||||
"eslint": "8.54.0",
|
"eslint": "8.56.0",
|
||||||
"eslint-config-airbnb-base": "15.0.0",
|
"eslint-config-airbnb-base": "15.0.0",
|
||||||
"eslint-config-prettier": "9.0.0",
|
"eslint-config-prettier": "9.1.0",
|
||||||
"eslint-plugin-import": "2.29.0",
|
"eslint-plugin-import": "2.29.1",
|
||||||
"eslint-plugin-jsonc": "2.10.0",
|
"eslint-plugin-jsonc": "2.11.2",
|
||||||
"eslint-plugin-prettier": "5.0.1",
|
"eslint-plugin-prettier": "5.0.1",
|
||||||
"esm": "3.2.25",
|
"esm": "3.2.25",
|
||||||
"husky": "8.0.3",
|
"husky": "8.0.3",
|
||||||
"jasmine": "5.1.0",
|
"jasmine": "5.1.0",
|
||||||
"jsdoc": "4.0.2",
|
"jsdoc": "4.0.2",
|
||||||
"jsonc-eslint-parser": "2.4.0",
|
"jsonc-eslint-parser": "2.4.0",
|
||||||
"lint-staged": "15.1.0",
|
"lint-staged": "15.2.0",
|
||||||
"lorem-ipsum": "2.0.8",
|
"lorem-ipsum": "2.0.8",
|
||||||
"nodemon": "3.0.1",
|
"nodemon": "3.0.2",
|
||||||
"prettier": "3.1.0",
|
"prettier": "3.1.1",
|
||||||
"rcedit": "4.0.1",
|
"rcedit": "4.0.1",
|
||||||
"webpack": "5.89.0",
|
"webpack": "5.89.0",
|
||||||
"webpack-cli": "5.1.4"
|
"webpack-cli": "5.1.4"
|
||||||
|
44
src/public/app/menus/image_context_menu.js
Normal file
44
src/public/app/menus/image_context_menu.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import utils from "../services/utils.js";
|
||||||
|
import contextMenu from "./context_menu.js";
|
||||||
|
import imageService from "../services/image.js";
|
||||||
|
|
||||||
|
const PROP_NAME = "imageContextMenuInstalled";
|
||||||
|
|
||||||
|
function setupContextMenu($image) {
|
||||||
|
if (!utils.isElectron() || $image.prop(PROP_NAME)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$image.prop(PROP_NAME, true);
|
||||||
|
$image.on('contextmenu', e => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
contextMenu.show({
|
||||||
|
x: e.pageX,
|
||||||
|
y: e.pageY,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: "Copy reference to clipboard",
|
||||||
|
command: "copyImageReferenceToClipboard",
|
||||||
|
uiIcon: "bx bx-empty"
|
||||||
|
},
|
||||||
|
{title: "Copy image to clipboard", command: "copyImageToClipboard", uiIcon: "bx bx-empty"},
|
||||||
|
],
|
||||||
|
selectMenuItemHandler: ({command}) => {
|
||||||
|
if (command === 'copyImageReferenceToClipboard') {
|
||||||
|
imageService.copyImageReferenceToClipboard($image);
|
||||||
|
} else if (command === 'copyImageToClipboard') {
|
||||||
|
const webContents = utils.dynamicRequire('@electron/remote').getCurrentWebContents();
|
||||||
|
utils.dynamicRequire('electron');
|
||||||
|
webContents.copyImageAt(e.pageX, e.pageY);
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unrecognized command '${command}'`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setupContextMenu
|
||||||
|
};
|
@ -9,6 +9,7 @@ import linkService from "./link.js";
|
|||||||
import treeService from "./tree.js";
|
import treeService from "./tree.js";
|
||||||
import FNote from "../entities/fnote.js";
|
import FNote from "../entities/fnote.js";
|
||||||
import FAttachment from "../entities/fattachment.js";
|
import FAttachment from "../entities/fattachment.js";
|
||||||
|
import imageContextMenuService from "../menus/image_context_menu.js";
|
||||||
|
|
||||||
let idCounter = 1;
|
let idCounter = 1;
|
||||||
|
|
||||||
@ -148,6 +149,8 @@ function renderImage(entity, $renderedContent, options = {}) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imageContextMenuService.setupContextMenu($img);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderFile(entity, type, $renderedContent) {
|
function renderFile(entity, type, $renderedContent) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import utils from "../../services/utils.js";
|
import utils from "../../services/utils.js";
|
||||||
import TypeWidget from "./type_widget.js";
|
import TypeWidget from "./type_widget.js";
|
||||||
import libraryLoader from "../../services/library_loader.js";
|
import libraryLoader from "../../services/library_loader.js";
|
||||||
import contextMenu from "../../menus/context_menu.js";
|
import imageContextMenuService from "../../menus/image_context_menu.js";
|
||||||
import imageService from "../../services/image.js";
|
import imageService from "../../services/image.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
@ -55,36 +55,7 @@ class ImageTypeWidget extends TypeWidget {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (utils.isElectron()) {
|
imageContextMenuService.setupContextMenu(this.$imageView);
|
||||||
// for browser, we want to let the native menu
|
|
||||||
this.$imageView.on('contextmenu', e => {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
contextMenu.show({
|
|
||||||
x: e.pageX,
|
|
||||||
y: e.pageY,
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
title: "Copy reference to clipboard",
|
|
||||||
command: "copyImageReferenceToClipboard",
|
|
||||||
uiIcon: "bx bx-empty"
|
|
||||||
},
|
|
||||||
{title: "Copy image to clipboard", command: "copyImageToClipboard", uiIcon: "bx bx-empty"},
|
|
||||||
],
|
|
||||||
selectMenuItemHandler: ({command}) => {
|
|
||||||
if (command === 'copyImageReferenceToClipboard') {
|
|
||||||
imageService.copyImageReferenceToClipboard(this.$imageWrapper);
|
|
||||||
} else if (command === 'copyImageToClipboard') {
|
|
||||||
const webContents = utils.dynamicRequire('@electron/remote').getCurrentWebContents();
|
|
||||||
utils.dynamicRequire('electron');
|
|
||||||
webContents.copyImageAt(e.pageX, e.pageY);
|
|
||||||
} else {
|
|
||||||
throw new Error(`Unrecognized command '${command}'`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
super.doRender();
|
super.doRender();
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,9 @@ function register(app) {
|
|||||||
|
|
||||||
// excalidraw-view mode in shared notes
|
// excalidraw-view mode in shared notes
|
||||||
app.use(`/${assetPath}/node_modules/react/umd/react.production.min.js`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/react/umd/react.production.min.js')));
|
app.use(`/${assetPath}/node_modules/react/umd/react.production.min.js`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/react/umd/react.production.min.js')));
|
||||||
|
app.use(`/${assetPath}/node_modules/react/umd/react.development.js`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/react/umd/react.development.js')));
|
||||||
app.use(`/${assetPath}/node_modules/react-dom/umd/react-dom.production.min.js`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/react-dom/umd/react-dom.production.min.js')));
|
app.use(`/${assetPath}/node_modules/react-dom/umd/react-dom.production.min.js`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/react-dom/umd/react-dom.production.min.js')));
|
||||||
|
app.use(`/${assetPath}/node_modules/react-dom/umd/react-dom.development.js`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/react-dom/umd/react-dom.development.js')));
|
||||||
// expose the whole dist folder since complete assets are needed in edit and share
|
// expose the whole dist folder since complete assets are needed in edit and share
|
||||||
app.use(`/node_modules/@excalidraw/excalidraw/dist/`, express.static(path.join(srcRoot, '..', 'node_modules/@excalidraw/excalidraw/dist/')));
|
app.use(`/node_modules/@excalidraw/excalidraw/dist/`, express.static(path.join(srcRoot, '..', 'node_modules/@excalidraw/excalidraw/dist/')));
|
||||||
app.use(`/${assetPath}/node_modules/@excalidraw/excalidraw/dist/`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/@excalidraw/excalidraw/dist/')));
|
app.use(`/${assetPath}/node_modules/@excalidraw/excalidraw/dist/`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/@excalidraw/excalidraw/dist/')));
|
||||||
|
@ -39,7 +39,13 @@ function getLightAnonymizationScript() {
|
|||||||
SELECT blobId FROM notes WHERE mime IN ('application/javascript;env=backend', 'application/javascript;env=frontend')
|
SELECT blobId FROM notes WHERE mime IN ('application/javascript;env=backend', 'application/javascript;env=frontend')
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT blobId FROM revisions WHERE mime IN ('application/javascript;env=backend', 'application/javascript;env=frontend')
|
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) {
|
async function createAnonymizedCopy(type) {
|
||||||
|
@ -4,8 +4,8 @@ const build = require('./build.js');
|
|||||||
const packageJson = require('../../package.json');
|
const packageJson = require('../../package.json');
|
||||||
const {TRILIUM_DATA_DIR} = require('./data_dir.js');
|
const {TRILIUM_DATA_DIR} = require('./data_dir.js');
|
||||||
|
|
||||||
const APP_DB_VERSION = 227;
|
const APP_DB_VERSION = 228;
|
||||||
const SYNC_VERSION = 31;
|
const SYNC_VERSION = 32;
|
||||||
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -5,12 +5,14 @@ const utils = require('./utils.js');
|
|||||||
|
|
||||||
function getBlobPojo(entityName, entityId) {
|
function getBlobPojo(entityName, entityId) {
|
||||||
const entity = becca.getEntity(entityName, entityId);
|
const entity = becca.getEntity(entityName, entityId);
|
||||||
|
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
throw new NotFoundError(`Entity ${entityName} '${entityId}' was not found.`);
|
throw new NotFoundError(`Entity ${entityName} '${entityId}' was not found.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const blob = becca.getBlob(entity);
|
const blob = becca.getBlob(entity);
|
||||||
|
if (!blob) {
|
||||||
|
throw new NotFoundError(`Blob ${entity.blobId} for ${entityName} '${entityId}' was not found.`);
|
||||||
|
}
|
||||||
|
|
||||||
const pojo = blob.getPojo();
|
const pojo = blob.getPojo();
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
module.exports = { buildDate:"2023-12-07T00:03:59+01:00", buildRevision: "2e23c521c356c2305124f5df0f474532fa5f34ce" };
|
module.exports = { buildDate:"2024-01-04T00:49:06+01:00", buildRevision: "394530921e3f7ddd852fa4ceb1ac4585447df35e" };
|
||||||
|
@ -17,6 +17,9 @@ const {sanitizeAttributeName} = require('./sanitize_attribute_name.js');
|
|||||||
const noteTypes = require('../services/note_types.js').getNoteTypeNames();
|
const noteTypes = require('../services/note_types.js').getNoteTypeNames();
|
||||||
|
|
||||||
class ConsistencyChecks {
|
class ConsistencyChecks {
|
||||||
|
/**
|
||||||
|
* @param autoFix - automatically fix all encountered problems. False is only for debugging during development (fail fast)
|
||||||
|
*/
|
||||||
constructor(autoFix) {
|
constructor(autoFix) {
|
||||||
this.autoFix = autoFix;
|
this.autoFix = autoFix;
|
||||||
this.unrecoveredConsistencyErrors = false;
|
this.unrecoveredConsistencyErrors = false;
|
||||||
|
@ -37,6 +37,8 @@ function eraseNotes(noteIdsToErase) {
|
|||||||
function setEntityChangesAsErased(entityChanges) {
|
function setEntityChangesAsErased(entityChanges) {
|
||||||
for (const ec of entityChanges) {
|
for (const ec of entityChanges) {
|
||||||
ec.isErased = true;
|
ec.isErased = true;
|
||||||
|
// we're not changing hash here, not sure if good or not
|
||||||
|
// content hash check takes isErased flag into account, though
|
||||||
ec.utcDateChanged = dateUtils.utcNowDateTime();
|
ec.utcDateChanged = dateUtils.utcNowDateTime();
|
||||||
|
|
||||||
entityChangesService.putEntityChangeWithForcedChange(ec);
|
entityChangesService.putEntityChangeWithForcedChange(ec);
|
||||||
|
@ -73,8 +73,11 @@ async function migrate() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (currentDbVersion === 214) {
|
||||||
|
// special VACUUM after the big migration
|
||||||
log.info("VACUUMing database, this might take a while ...");
|
log.info("VACUUMing database, this might take a while ...");
|
||||||
sql.execute("VACUUM");
|
sql.execute("VACUUM");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function executeMigration(mig) {
|
function executeMigration(mig) {
|
||||||
|
@ -63,10 +63,15 @@ function exec(opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let responseStr = '';
|
let responseStr = '';
|
||||||
|
let chunks = [];
|
||||||
|
|
||||||
response.on('data', chunk => responseStr += chunk);
|
response.on('data', chunk => chunks.push(chunk));
|
||||||
|
|
||||||
response.on('end', () => {
|
response.on('end', () => {
|
||||||
|
// use Buffer instead of string concatenation to avoid implicit decoding for each chunk
|
||||||
|
// decode the entire data chunks explicitly as utf-8
|
||||||
|
responseStr = Buffer.concat(chunks).toString('utf-8')
|
||||||
|
|
||||||
if ([200, 201, 204].includes(response.statusCode)) {
|
if ([200, 201, 204].includes(response.statusCode)) {
|
||||||
try {
|
try {
|
||||||
const jsonObj = responseStr.trim() ? JSON.parse(responseStr) : null;
|
const jsonObj = responseStr.trim() ? JSON.parse(responseStr) : null;
|
||||||
|
@ -91,12 +91,16 @@ function updateNormalEntity(remoteEC, remoteEntityRow, instanceId, updateContext
|
|||||||
updateContext.updated[remoteEC.entityName].push(remoteEC.entityId);
|
updateContext.updated[remoteEC.entityName].push(remoteEC.entityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!localEC || localEC.utcDateChanged < remoteEC.utcDateChanged || localEC.hash !== remoteEC.hash) {
|
if (!localEC || localEC.utcDateChanged < remoteEC.utcDateChanged
|
||||||
|
|| localEC.hash !== remoteEC.hash
|
||||||
|
|| localEC.isErased !== remoteEC.isErased
|
||||||
|
) {
|
||||||
entityChangesService.putEntityChangeWithInstanceId(remoteEC, instanceId);
|
entityChangesService.putEntityChangeWithInstanceId(remoteEC, instanceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (localEC.hash !== remoteEC.hash && localEC.utcDateChanged > remoteEC.utcDateChanged) {
|
} else if ((localEC.hash !== remoteEC.hash || localEC.isErased !== remoteEC.isErased)
|
||||||
|
&& localEC.utcDateChanged > remoteEC.utcDateChanged) {
|
||||||
// the change on our side is newer than on the other side, so the other side should update
|
// the change on our side is newer than on the other side, so the other side should update
|
||||||
entityChangesService.putEntityChangeForOtherInstances(localEC);
|
entityChangesService.putEntityChangeForOtherInstances(localEC);
|
||||||
|
|
||||||
@ -148,7 +152,7 @@ function eraseEntity(entityChange) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
if (!entityNames.includes(entityName)) {
|
if (!entityNames.includes(entityName)) {
|
||||||
log.error(`Cannot erase entity '${entityName}', id '${entityId}'.`);
|
log.error(`Cannot erase ${entityName} '${entityId}'.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ function hashedBlobId(content) {
|
|||||||
|
|
||||||
// we don't want such + and / in the IDs
|
// we don't want such + and / in the IDs
|
||||||
const kindaBase62Hash = base64Hash
|
const kindaBase62Hash = base64Hash
|
||||||
.replace('+', 'X')
|
.replaceAll('+', 'X')
|
||||||
.replace('/', 'Y');
|
.replaceAll('/', 'Y');
|
||||||
|
|
||||||
// 20 characters of base62 gives us ~120 bit of entropy which is plenty enough
|
// 20 characters of base62 gives us ~120 bit of entropy which is plenty enough
|
||||||
return kindaBase62Hash.substr(0, 20);
|
return kindaBase62Hash.substr(0, 20);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user