Compare commits

...

7 Commits

13 changed files with 53 additions and 11 deletions

View File

@@ -2,7 +2,7 @@
"name": "trilium",
"productName": "Trilium Notes",
"description": "Trilium Notes",
"version": "0.46.6",
"version": "0.46.7",
"license": "AGPL-3.0-only",
"main": "electron.js",
"bin": {

View File

@@ -49,7 +49,12 @@ class Note extends Entity {
this.isContentAvailable = protectedSessionService.isProtectedSessionAvailable();
if (this.isContentAvailable) {
this.title = protectedSessionService.decryptString(this.title);
try {
this.title = protectedSessionService.decryptString(this.title);
}
catch (e) {
throw new Error(`Could not decrypt title of note ${this.noteId}: ${e.message} ${e.stack}`)
}
}
else {
this.title = "[protected]";

View File

@@ -359,7 +359,7 @@ class NoteShort {
const workspaceIconClass = this.getWorkspaceIconClass();
if (iconClassLabels.length > 0) {
return iconClassLabels.map(l => l.value).join(' ');
return iconClassLabels[0].value;
}
else if (workspaceIconClass) {
return workspaceIconClass;

View File

@@ -1,5 +1,6 @@
import utils from "./utils.js";
import options from './options.js';
import server from "./server.js";
const PROTECTED_SESSION_ID_KEY = 'protectedSessionId';
@@ -23,11 +24,11 @@ function resetSessionCookie() {
utils.setSessionCookie(PROTECTED_SESSION_ID_KEY, null);
}
function resetProtectedSession() {
async function resetProtectedSession() {
resetSessionCookie();
// most secure solution - guarantees nothing remained in memory
// since this expires because user doesn't use the app, it shouldn't be disruptive
await server.post("logout/protected");
utils.reloadApp();
}

View File

@@ -14,6 +14,10 @@ const TPL = `
height: 35px;
}
.standard-top-widget > div {
flex-shrink: 0; /* fixes https://github.com/zadam/trilium/issues/1745 */
}
.standard-top-widget button.noborder {
padding: 1px 5px 1px 5px;
font-size: 90%;

View File

@@ -78,6 +78,12 @@ function loginToProtectedSession(req) {
};
}
function logoutFromProtectedSession() {
protectedSessionService.resetDataKey();
eventService.emit(eventService.LEAVE_PROTECTED_SESSION);
}
function token(req) {
const username = req.body.username;
const password = req.body.password;
@@ -101,5 +107,6 @@ function token(req) {
module.exports = {
loginSync,
loginToProtectedSession,
logoutFromProtectedSession,
token
};

View File

@@ -270,6 +270,8 @@ function register(app) {
route(POST, '/api/login/sync', [], loginApiRoute.loginSync, apiResultHandler);
// this is for entering protected mode so user has to be already logged-in (that's the reason we don't require username)
apiRoute(POST, '/api/login/protected', loginApiRoute.loginToProtectedSession);
apiRoute(POST, '/api/logout/protected', loginApiRoute.logoutFromProtectedSession);
route(POST, '/api/login/token', [], loginApiRoute.token, apiResultHandler);
// in case of local electron, local calls are allowed unauthenticated, for server they need auth

View File

@@ -1 +1 @@
module.exports = { buildDate:"2021-03-23T23:57:48+01:00", buildRevision: "1862acd1ff9261536ebc7118d35bbbd8449ba94d" };
module.exports = { buildDate:"2021-04-03T22:37:04+02:00", buildRevision: "ef37a52a06b471e60f9c0f11da704283bbcef6ab" };

View File

@@ -2,6 +2,7 @@ const log = require('./log');
const NOTE_TITLE_CHANGED = "NOTE_TITLE_CHANGED";
const ENTER_PROTECTED_SESSION = "ENTER_PROTECTED_SESSION";
const LEAVE_PROTECTED_SESSION = "LEAVE_PROTECTED_SESSION";
const ENTITY_CREATED = "ENTITY_CREATED";
const ENTITY_CHANGED = "ENTITY_CHANGED";
const ENTITY_DELETED = "ENTITY_DELETED";
@@ -47,6 +48,7 @@ module.exports = {
// event types:
NOTE_TITLE_CHANGED,
ENTER_PROTECTED_SESSION,
LEAVE_PROTECTED_SESSION,
ENTITY_CREATED,
ENTITY_CHANGED,
ENTITY_DELETED,

View File

@@ -1,6 +1,7 @@
"use strict";
const protectedSessionService = require('../../protected_session');
const log = require('../../log');
class Note {
constructor(noteCache, row) {
@@ -416,9 +417,14 @@ class Note {
decrypt() {
if (this.isProtected && !this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) {
this.title = protectedSessionService.decryptString(this.title);
try {
this.title = protectedSessionService.decryptString(this.title);
this.isDecrypted = true;
this.isDecrypted = true;
}
catch (e) {
log.error(`Could not decrypt note ${this.noteId}: ${e.message} ${e.stack}`);
}
}
}

View File

@@ -177,6 +177,10 @@ eventService.subscribe(eventService.ENTER_PROTECTED_SESSION, () => {
}
});
eventService.subscribe(eventService.LEAVE_PROTECTED_SESSION, () => {
load();
});
module.exports = {
load
};

View File

@@ -5,7 +5,7 @@ const log = require('./log');
const dataEncryptionService = require('./data_encryption');
const cls = require('./cls');
const dataKeyMap = {};
let dataKeyMap = {};
function setDataKey(decryptedDataKey) {
const protectedSessionId = utils.randomSecureToken(32);
@@ -29,6 +29,10 @@ function getDataKey() {
return dataKeyMap[protectedSessionId];
}
function resetDataKey() {
dataKeyMap = {};
}
function isProtectedSessionAvailable() {
const protectedSessionId = getProtectedSessionId();
@@ -71,6 +75,7 @@ function decryptString(cipherText) {
module.exports = {
setDataKey,
getDataKey,
resetDataKey,
isProtectedSessionAvailable,
encrypt,
decrypt,

View File

@@ -1,6 +1,7 @@
"use strict";
const sql = require('./sql');
const log = require('./log');
const repository = require('./repository');
const Branch = require('../entities/branch');
const entityChangesService = require('./entity_changes.js');
@@ -139,7 +140,12 @@ function sortNotesByTitle(parentNoteId, foldersFirst = false, reverse = false) {
sql.execute("UPDATE branches SET notePosition = ? WHERE branchId = ?",
[position, note.branchId]);
noteCache.branches[note.branchId].notePosition = position;
if (note.branchId in noteCache.branches) {
noteCache.branches[note.branchId].notePosition = position;
}
else {
log.info(`Branch "${note.branchId}" was not found in note cache.`);
}
position += 10;
}