mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
becca entities enriched with functionality from repository entities
This commit is contained in:
parent
7494491560
commit
8d8d654fe8
5
.idea/dataSources.xml
generated
5
.idea/dataSources.xml
generated
@ -1,11 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||||
<data-source source="LOCAL" name="document.db" uuid="4e69c96a-8a2b-43f5-9b40-d1608f75f7a4">
|
<data-source source="LOCAL" name="SQLite - document.db" uuid="30cef30d-e704-484d-a4ca-5d3bfc2ece63">
|
||||||
<driver-ref>sqlite.xerial</driver-ref>
|
<driver-ref>sqlite.xerial</driver-ref>
|
||||||
<synchronize>true</synchronize>
|
<synchronize>true</synchronize>
|
||||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||||
<jdbc-url>jdbc:sqlite:$USER_HOME$/trilium-data/document.db</jdbc-url>
|
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/../trilium-data/document.db</jdbc-url>
|
||||||
|
<working-dir>$ProjectFileDir$</working-dir>
|
||||||
</data-source>
|
</data-source>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
2
db/TODO.txt
Normal file
2
db/TODO.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
- drop branches.utcDateCreated - not used for anything
|
||||||
|
- drop options.utcDateCreated - not used for anything
|
@ -17,7 +17,7 @@ function load() {
|
|||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
becca.reset();
|
becca.reset();
|
||||||
|
|
||||||
for (const row of sql.iterateRows(`SELECT noteId, title, type, mime, isProtected, dateCreated, dateModified, utcDateCreated, utcDateModified FROM notes WHERE isDeleted = 0`, [])) {
|
for (const row of sql.iterateRows(`SELECT noteId, title, type, mime, isProtected, dateCreated, dateModified, utcDateCreated, utcDateModified FROM notes`, [])) {
|
||||||
new Note(becca, row);
|
new Note(becca, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
src/services/becca/entities/abstract_entity.js
Normal file
43
src/services/becca/entities/abstract_entity.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
class AbstractEntity {
|
||||||
|
beforeSaving() {
|
||||||
|
this.generateIdIfNecessary();
|
||||||
|
}
|
||||||
|
|
||||||
|
generateIdIfNecessary() {
|
||||||
|
if (!this[this.constructor.primaryKeyName]) {
|
||||||
|
this[this.constructor.primaryKeyName] = utils.newEntityId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
generateHash() {
|
||||||
|
let contentToHash = "";
|
||||||
|
|
||||||
|
for (const propertyName of this.constructor.hashedProperties) {
|
||||||
|
contentToHash += "|" + this[propertyName];
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.hash(contentToHash).substr(0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUtcDateChanged() {
|
||||||
|
return this.utcDateModified || this.utcDateCreated;
|
||||||
|
}
|
||||||
|
|
||||||
|
get repository() {
|
||||||
|
if (!repo) {
|
||||||
|
repo = require('../services/repository');
|
||||||
|
}
|
||||||
|
|
||||||
|
return repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {
|
||||||
|
this.repository.updateEntity(this);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = AbstractEntity;
|
@ -1,9 +1,19 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const Note = require('./note.js');
|
const Note = require('./note.js');
|
||||||
|
const AbstractEntity = require("./abstract_entity.js");
|
||||||
|
const sql = require("../../sql.js");
|
||||||
|
const dateUtils = require("../../date_utils.js");
|
||||||
|
const promotedAttributeDefinitionParser = require("../../promoted_attribute_definition_parser");
|
||||||
|
|
||||||
|
class Attribute extends AbstractEntity {
|
||||||
|
static get entityName() { return "attributes"; }
|
||||||
|
static get primaryKeyName() { return "attributeId"; }
|
||||||
|
static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable"]; }
|
||||||
|
|
||||||
class Attribute {
|
|
||||||
constructor(becca, row) {
|
constructor(becca, row) {
|
||||||
|
super();
|
||||||
|
|
||||||
/** @param {Becca} */
|
/** @param {Becca} */
|
||||||
this.becca = becca;
|
this.becca = becca;
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
@ -60,13 +70,99 @@ class Attribute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for logging etc
|
/**
|
||||||
|
* @returns {Note|null}
|
||||||
|
*/
|
||||||
|
getNote() {
|
||||||
|
return this.repository.getNote(this.noteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Note|null}
|
||||||
|
*/
|
||||||
|
getTargetNote() {
|
||||||
|
if (this.type !== 'relation') {
|
||||||
|
throw new Error(`Attribute ${this.attributeId} is not relation`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.repository.getNote(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
isDefinition() {
|
||||||
|
return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:'));
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefinition() {
|
||||||
|
return promotedAttributeDefinitionParser.parse(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefinedName() {
|
||||||
|
if (this.type === 'label' && this.name.startsWith('label:')) {
|
||||||
|
return this.name.substr(6);
|
||||||
|
} else if (this.type === 'label' && this.name.startsWith('relation:')) {
|
||||||
|
return this.name.substr(9);
|
||||||
|
} else {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get pojo() {
|
get pojo() {
|
||||||
const pojo = {...this};
|
return {
|
||||||
|
attributeId: this.attributeId,
|
||||||
|
noteId: this.noteId,
|
||||||
|
type: this.type,
|
||||||
|
name: this.name,
|
||||||
|
position: this.position,
|
||||||
|
value: this.value,
|
||||||
|
isInheritable: this.isInheritable
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
delete pojo.becca;
|
beforeSaving() {
|
||||||
|
if (!this.value) {
|
||||||
|
if (this.type === 'relation') {
|
||||||
|
throw new Error(`Cannot save relation ${this.name} since it does not target any note.`);
|
||||||
|
}
|
||||||
|
|
||||||
return pojo;
|
// null value isn't allowed
|
||||||
|
this.value = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.position === undefined) {
|
||||||
|
this.position = 1 + sql.getValue(`SELECT COALESCE(MAX(position), 0) FROM attributes WHERE noteId = ?`, [this.noteId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isInheritable) {
|
||||||
|
this.isInheritable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isDeleted) {
|
||||||
|
this.isDeleted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.beforeSaving();
|
||||||
|
|
||||||
|
this.utcDateModified = dateUtils.utcNowDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
createClone(type, name, value, isInheritable) {
|
||||||
|
return new Attribute({
|
||||||
|
noteId: this.noteId,
|
||||||
|
type: type,
|
||||||
|
name: name,
|
||||||
|
value: value,
|
||||||
|
position: this.position,
|
||||||
|
isInheritable: isInheritable,
|
||||||
|
isDeleted: false,
|
||||||
|
utcDateModified: this.utcDateModified
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,19 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const Note = require('./note.js');
|
const Note = require('./note.js');
|
||||||
|
const AbstractEntity = require("./abstract_entity.js");
|
||||||
|
const sql = require("../../sql.js");
|
||||||
|
const dateUtils = require("../../date_utils.js");
|
||||||
|
|
||||||
|
class Branch extends AbstractEntity {
|
||||||
|
static get entityName() { return "branches"; }
|
||||||
|
static get primaryKeyName() { return "branchId"; }
|
||||||
|
// notePosition is not part of hash because it would produce a lot of updates in case of reordering
|
||||||
|
static get hashedProperties() { return ["branchId", "noteId", "parentNoteId", "prefix"]; }
|
||||||
|
|
||||||
class Branch {
|
|
||||||
constructor(becca, row) {
|
constructor(becca, row) {
|
||||||
|
super();
|
||||||
|
|
||||||
/** @param {Becca} */
|
/** @param {Becca} */
|
||||||
this.becca = becca;
|
this.becca = becca;
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
@ -55,13 +65,44 @@ class Branch {
|
|||||||
return this.becca.notes[this.parentNoteId];
|
return this.becca.notes[this.parentNoteId];
|
||||||
}
|
}
|
||||||
|
|
||||||
// for logging etc
|
|
||||||
get pojo() {
|
get pojo() {
|
||||||
const pojo = {...this};
|
return {
|
||||||
|
branchId: this.branchId,
|
||||||
|
noteId: this.noteId,
|
||||||
|
parentNoteId: this.parentNoteId,
|
||||||
|
prefix: this.prefix,
|
||||||
|
notePosition: this.notePosition,
|
||||||
|
isExpanded: this.isExpanded
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
delete pojo.becca;
|
createClone(parentNoteId, notePosition) {
|
||||||
|
return new Branch({
|
||||||
|
noteId: this.noteId,
|
||||||
|
parentNoteId: parentNoteId,
|
||||||
|
notePosition: notePosition,
|
||||||
|
prefix: this.prefix,
|
||||||
|
isExpanded: this.isExpanded
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return pojo;
|
beforeSaving() {
|
||||||
|
if (this.notePosition === undefined || this.notePosition === null) {
|
||||||
|
const maxNotePos = sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [this.parentNoteId]);
|
||||||
|
this.notePosition = maxNotePos === null ? 0 : maxNotePos + 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isExpanded) {
|
||||||
|
this.isExpanded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.branchId) {
|
||||||
|
this.utcDateCreated = dateUtils.utcNowDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
super.beforeSaving();
|
||||||
|
|
||||||
|
this.utcDateModified = dateUtils.utcNowDateTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,12 +2,23 @@
|
|||||||
|
|
||||||
const protectedSessionService = require('../../protected_session');
|
const protectedSessionService = require('../../protected_session');
|
||||||
const log = require('../../log');
|
const log = require('../../log');
|
||||||
|
const sql = require('../../sql');
|
||||||
|
const utils = require('../../utils');
|
||||||
|
const dateUtils = require('../../date_utils');
|
||||||
|
const entityChangesService = require('../../entity_changes.js');
|
||||||
|
const AbstractEntity = require("./abstract_entity.js");
|
||||||
|
|
||||||
const LABEL = 'label';
|
const LABEL = 'label';
|
||||||
const RELATION = 'relation';
|
const RELATION = 'relation';
|
||||||
|
|
||||||
class Note {
|
class Note extends AbstractEntity {
|
||||||
|
static get entityName() { return "notes"; }
|
||||||
|
static get primaryKeyName() { return "noteId"; }
|
||||||
|
static get hashedProperties() { return ["noteId", "title", "isProtected", "type", "mime"]; }
|
||||||
|
|
||||||
constructor(becca, row) {
|
constructor(becca, row) {
|
||||||
|
super();
|
||||||
|
|
||||||
/** @param {Becca} */
|
/** @param {Becca} */
|
||||||
this.becca = becca;
|
this.becca = becca;
|
||||||
|
|
||||||
@ -46,10 +57,14 @@ class Note {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(row) {
|
update(row) {
|
||||||
|
// ------ Database persisted attributes ------
|
||||||
|
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
this.noteId = row.noteId;
|
this.noteId = row.noteId;
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
this.title = row.title;
|
this.title = row.title;
|
||||||
|
/** @param {boolean} */
|
||||||
|
this.isProtected = !!row.isProtected;
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
this.type = row.type;
|
this.type = row.type;
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
@ -62,8 +77,9 @@ class Note {
|
|||||||
this.utcDateCreated = row.utcDateCreated;
|
this.utcDateCreated = row.utcDateCreated;
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
this.utcDateModified = row.utcDateModified;
|
this.utcDateModified = row.utcDateModified;
|
||||||
/** @param {boolean} */
|
|
||||||
this.isProtected = !!row.isProtected;
|
// ------ Derived attributes ------
|
||||||
|
|
||||||
/** @param {boolean} */
|
/** @param {boolean} */
|
||||||
this.isDecrypted = !row.isProtected || !!row.isContentAvailable;
|
this.isDecrypted = !row.isProtected || !!row.isContentAvailable;
|
||||||
|
|
||||||
@ -73,6 +89,162 @@ class Note {
|
|||||||
this.flatTextCache = null;
|
this.flatTextCache = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note content has quite special handling - it's not a separate entity, but a lazily loaded
|
||||||
|
* part of Note entity with it's own sync. Reasons behind this hybrid design has been:
|
||||||
|
*
|
||||||
|
* - content can be quite large and it's not necessary to load it / fill memory for any note access even if we don't need a content, especially for bulk operations like search
|
||||||
|
* - changes in the note metadata or title should not trigger note content sync (so we keep separate utcDateModified and entity changes records)
|
||||||
|
* - but to the user note content and title changes are one and the same - single dateModified (so all changes must go through Note and content is not a separate entity)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @returns {*} */
|
||||||
|
getContent(silentNotFoundError = false) {
|
||||||
|
const row = sql.getRow(`SELECT content FROM note_contents WHERE noteId = ?`, [this.noteId]);
|
||||||
|
|
||||||
|
if (!row) {
|
||||||
|
if (silentNotFoundError) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Error("Cannot find note content for noteId=" + this.noteId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = row.content;
|
||||||
|
|
||||||
|
if (this.isProtected) {
|
||||||
|
if (protectedSessionService.isProtectedSessionAvailable()) {
|
||||||
|
content = content === null ? null : protectedSessionService.decrypt(content);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
content = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isStringNote()) {
|
||||||
|
return content === null
|
||||||
|
? ""
|
||||||
|
: content.toString("UTF-8");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {{contentLength, dateModified, utcDateModified}} */
|
||||||
|
getContentMetadata() {
|
||||||
|
return sql.getRow(`
|
||||||
|
SELECT
|
||||||
|
LENGTH(content) AS contentLength,
|
||||||
|
dateModified,
|
||||||
|
utcDateModified
|
||||||
|
FROM note_contents
|
||||||
|
WHERE noteId = ?`, [this.noteId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {*} */
|
||||||
|
getJsonContent() {
|
||||||
|
const content = this.getContent();
|
||||||
|
|
||||||
|
if (!content || !content.trim()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
setContent(content) {
|
||||||
|
if (content === null || content === undefined) {
|
||||||
|
throw new Error(`Cannot set null content to note ${this.noteId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isStringNote()) {
|
||||||
|
content = content.toString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
content = Buffer.isBuffer(content) ? content : Buffer.from(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pojo = {
|
||||||
|
noteId: this.noteId,
|
||||||
|
content: content,
|
||||||
|
dateModified: dateUtils.localNowDateTime(),
|
||||||
|
utcDateModified: dateUtils.utcNowDateTime()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.isProtected) {
|
||||||
|
if (protectedSessionService.isProtectedSessionAvailable()) {
|
||||||
|
pojo.content = protectedSessionService.encrypt(pojo.content);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Error(`Cannot update content of noteId=${this.noteId} since we're out of protected session.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sql.upsert("note_contents", "noteId", pojo);
|
||||||
|
|
||||||
|
const hash = utils.hash(this.noteId + "|" + pojo.content.toString());
|
||||||
|
|
||||||
|
entityChangesService.addEntityChange({
|
||||||
|
entityName: 'note_contents',
|
||||||
|
entityId: this.noteId,
|
||||||
|
hash: hash,
|
||||||
|
isErased: false,
|
||||||
|
utcDateChanged: pojo.utcDateModified
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
setJsonContent(content) {
|
||||||
|
this.setContent(JSON.stringify(content, null, '\t'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {boolean} true if this note is the root of the note tree. Root note has "root" noteId */
|
||||||
|
isRoot() {
|
||||||
|
return this.noteId === 'root';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {boolean} true if this note is of application/json content type */
|
||||||
|
isJson() {
|
||||||
|
return this.mime === "application/json";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {boolean} true if this note is JavaScript (code or attachment) */
|
||||||
|
isJavaScript() {
|
||||||
|
return (this.type === "code" || this.type === "file")
|
||||||
|
&& (this.mime.startsWith("application/javascript")
|
||||||
|
|| this.mime === "application/x-javascript"
|
||||||
|
|| this.mime === "text/javascript");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {boolean} true if this note is HTML */
|
||||||
|
isHtml() {
|
||||||
|
return ["code", "file", "render"].includes(this.type)
|
||||||
|
&& this.mime === "text/html";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {boolean} true if the note has string content (not binary) */
|
||||||
|
isStringNote() {
|
||||||
|
return utils.isStringNote(this.type, this.mime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {string|null} JS script environment - either "frontend" or "backend" */
|
||||||
|
getScriptEnv() {
|
||||||
|
if (this.isHtml() || (this.isJavaScript() && this.mime.endsWith('env=frontend'))) {
|
||||||
|
return "frontend";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.type === 'render') {
|
||||||
|
return "frontend";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isJavaScript() && this.mime.endsWith('env=backend')) {
|
||||||
|
return "backend";
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {Attribute[]} */
|
/** @return {Attribute[]} */
|
||||||
get attributes() {
|
get attributes() {
|
||||||
return this.__getAttributes([]);
|
return this.__getAttributes([]);
|
||||||
@ -543,19 +715,45 @@ class Note {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for logging etc
|
|
||||||
get pojo() {
|
get pojo() {
|
||||||
const pojo = {...this};
|
return {
|
||||||
|
noteId: this.noteId,
|
||||||
|
title: this.title,
|
||||||
|
isProtected: this.isProtected,
|
||||||
|
type: this.type,
|
||||||
|
mime: this.mime,
|
||||||
|
dateCreated: this.dateCreated,
|
||||||
|
dateModified: this.dateModified,
|
||||||
|
utcDateCreated: this.utcDateCreated,
|
||||||
|
utcDateModified: this.utcDateModified
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
delete pojo.becca;
|
beforeSaving() {
|
||||||
delete pojo.ancestorCache;
|
if (!this.dateCreated) {
|
||||||
delete pojo.attributeCache;
|
this.dateCreated = dateUtils.localNowDateTime();
|
||||||
delete pojo.flatTextCache;
|
}
|
||||||
delete pojo.children;
|
|
||||||
delete pojo.parents;
|
|
||||||
delete pojo.parentBranches;
|
|
||||||
|
|
||||||
return pojo;
|
if (!this.utcDateCreated) {
|
||||||
|
this.utcDateCreated = dateUtils.utcNowDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
super.beforeSaving();
|
||||||
|
|
||||||
|
this.dateModified = dateUtils.localNowDateTime();
|
||||||
|
this.utcDateModified = dateUtils.utcNowDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePojo(pojo) {
|
||||||
|
if (pojo.isProtected) {
|
||||||
|
if (this.isDecrypted) {
|
||||||
|
pojo.title = protectedSessionService.encrypt(pojo.title);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// updating protected note outside of protected session means we will keep original ciphertexts
|
||||||
|
delete pojo.title;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user