using now session cookies to store protectedSessionId

This commit is contained in:
zadam 2019-03-13 21:53:09 +01:00
parent 24c8b39d8e
commit b4c6d9f800
9 changed files with 31 additions and 27 deletions

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "trilium", "name": "trilium",
"version": "0.30.4", "version": "0.30.5",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -17,7 +17,8 @@ import link from './services/link.js';
import messagingService from './services/messaging.js'; import messagingService from './services/messaging.js';
import noteDetailService from './services/note_detail.js'; import noteDetailService from './services/note_detail.js';
import noteType from './services/note_type.js'; import noteType from './services/note_type.js';
import protected_session from './services/protected_session.js'; import protectedSessionService from './services/protected_session.js';
import protectedSessionHolder from './services/protected_session_holder.js';
import searchNotesService from './services/search_notes.js'; import searchNotesService from './services/search_notes.js';
import FrontendScriptApi from './services/frontend_script_api.js'; import FrontendScriptApi from './services/frontend_script_api.js';
import ScriptContext from './services/script_context.js'; import ScriptContext from './services/script_context.js';
@ -52,6 +53,8 @@ window.glob.getCurrentNote = noteDetailService.getCurrentNote;
window.glob.requireLibrary = libraryLoader.requireLibrary; window.glob.requireLibrary = libraryLoader.requireLibrary;
window.glob.ESLINT = libraryLoader.ESLINT; window.glob.ESLINT = libraryLoader.ESLINT;
protectedSessionHolder.setProtectedSessionId(null);
window.onerror = function (msg, url, lineNo, columnNo, error) { window.onerror = function (msg, url, lineNo, columnNo, error) {
const string = msg.toLowerCase(); const string = msg.toLowerCase();

View File

@ -79,7 +79,7 @@ $form.submit(() => {
function exportBranch(branchId, type, format, version) { function exportBranch(branchId, type, format, version) {
exportId = utils.randomString(10); exportId = utils.randomString(10);
const url = utils.getHost() + `/api/notes/${branchId}/export/${type}/${format}/${version}/${exportId}?protectedSessionId=` + encodeURIComponent(protectedSessionHolder.getProtectedSessionId()); const url = utils.getHost() + `/api/notes/${branchId}/export/${type}/${format}/${version}/${exportId}`;
utils.download(url); utils.download(url);
} }

View File

@ -51,8 +51,7 @@ $openButton.click(() => {
function getFileUrl() { function getFileUrl() {
// electron needs absolute URL so we extract current host, port, protocol // electron needs absolute URL so we extract current host, port, protocol
return utils.getHost() + "/api/notes/" + noteDetailService.getCurrentNoteId() return utils.getHost() + "/api/notes/" + noteDetailService.getCurrentNoteId();
+ "/download?protectedSessionId=" + encodeURIComponent(protectedSessionHolder.getProtectedSessionId());
} }
export default { export default {

View File

@ -62,8 +62,7 @@ $copyToClipboardButton.click(() => {
function getFileUrl() { function getFileUrl() {
// electron needs absolute URL so we extract current host, port, protocol // electron needs absolute URL so we extract current host, port, protocol
return utils.getHost() + "/api/notes/" + noteDetailService.getCurrentNoteId() return utils.getHost() + "/api/notes/" + noteDetailService.getCurrentNoteId() + "/download";
+ "/download?protectedSessionId=" + encodeURIComponent(protectedSessionHolder.getProtectedSessionId());
} }
export default { export default {

View File

@ -1,9 +1,10 @@
import utils from "./utils.js"; import utils from "./utils.js";
import optionsInitService from './options_init.js'; import optionsInitService from './options_init.js';
const PROTECTED_SESSION_ID_KEY = 'protectedSessionId';
let lastProtectedSessionOperationDate = null; let lastProtectedSessionOperationDate = null;
let protectedSessionTimeout = null; let protectedSessionTimeout = null;
let protectedSessionId = null;
optionsInitService.optionsReady.then(options => protectedSessionTimeout = options.protectedSessionTimeout); optionsInitService.optionsReady.then(options => protectedSessionTimeout = options.protectedSessionTimeout);
@ -17,16 +18,13 @@ function setProtectedSessionTimeout(encSessTimeout) {
protectedSessionTimeout = encSessTimeout; protectedSessionTimeout = encSessTimeout;
} }
function getProtectedSessionId() {
return protectedSessionId;
}
function setProtectedSessionId(id) { function setProtectedSessionId(id) {
protectedSessionId = id; // using session cookie so that it disappears after browser/tab is closed
utils.setSessionCookie(PROTECTED_SESSION_ID_KEY, id);
} }
function resetProtectedSession() { function resetProtectedSession() {
protectedSessionId = null; utils.setSessionCookie(PROTECTED_SESSION_ID_KEY, null);
// most secure solution - guarantees nothing remained in memory // most secure solution - guarantees nothing remained in memory
// since this expires because user doesn't use the app, it shouldn't be disruptive // since this expires because user doesn't use the app, it shouldn't be disruptive
@ -34,17 +32,16 @@ function resetProtectedSession() {
} }
function isProtectedSessionAvailable() { function isProtectedSessionAvailable() {
return protectedSessionId !== null; return !!utils.getCookie(PROTECTED_SESSION_ID_KEY);
} }
function touchProtectedSession() { function touchProtectedSession() {
if (isProtectedSessionAvailable()) { if (isProtectedSessionAvailable()) {
lastProtectedSessionOperationDate = new Date(); setProtectedSessionId(utils.getCookie(PROTECTED_SESSION_ID_KEY));
} }
} }
export default { export default {
getProtectedSessionId,
setProtectedSessionId, setProtectedSessionId,
resetProtectedSession, resetProtectedSession,
isProtectedSessionAvailable, isProtectedSessionAvailable,

View File

@ -3,18 +3,10 @@ import utils from './utils.js';
import infoService from "./info.js"; import infoService from "./info.js";
function getHeaders() { function getHeaders() {
let protectedSessionId = null;
try { // this is because protected session might not be declared in some cases
protectedSessionId = protectedSessionHolder.getProtectedSessionId();
}
catch(e) {}
// headers need to be lowercase because node.js automatically converts them to lower case // headers need to be lowercase because node.js automatically converts them to lower case
// so hypothetical protectedSessionId becomes protectedsessionid on the backend // so hypothetical protectedSessionId becomes protectedsessionid on the backend
// also avoiding using underscores instead of dashes since nginx filters them out by default // also avoiding using underscores instead of dashes since nginx filters them out by default
return { return {
'trilium-protected-session-id': protectedSessionId,
'trilium-source-id': glob.sourceId 'trilium-source-id': glob.sourceId
}; };
} }

View File

@ -164,11 +164,23 @@ function isDesktop() {
|| (!window.device && !/Mobi/.test(navigator.userAgent)); || (!window.device && !/Mobi/.test(navigator.userAgent));
} }
// cookie code below works for simple use cases only - ASCII only
// not setting path so that cookies do not leak into other websites if multiplexed with reverse proxy
function setCookie(name, value) { function setCookie(name, value) {
const date = new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000); const date = new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000);
const expires = "; expires=" + date.toUTCString(); const expires = "; expires=" + date.toUTCString();
document.cookie = name + "=" + (value || "") + expires + "; path=/"; document.cookie = name + "=" + (value || "") + expires + ";";
}
function setSessionCookie(name, value) {
document.cookie = name + "=" + (value || "") + ";";
}
function getCookie(name) {
const valueMatch = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
return valueMatch ? valueMatch[2] : null;
} }
function getNoteTypeClass(type) { function getNoteTypeClass(type) {
@ -213,6 +225,8 @@ export default {
isMobile, isMobile,
isDesktop, isDesktop,
setCookie, setCookie,
setSessionCookie,
getCookie,
getNoteTypeClass, getNoteTypeClass,
getMimeTypeClass getMimeTypeClass
}; };

View File

@ -15,7 +15,7 @@ function setDataKey(decryptedDataKey) {
} }
function setProtectedSessionId(req) { function setProtectedSessionId(req) {
cls.namespace.set('protectedSessionId', req.headers['trilium-protected-session-id'] || req.query.protectedSessionId); cls.namespace.set('protectedSessionId', req.cookies.protectedSessionId);
} }
function getProtectedSessionId() { function getProtectedSessionId() {