mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	using now session cookies to store protectedSessionId
This commit is contained in:
		
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -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": { | ||||||
|   | |||||||
| @@ -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(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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 { | ||||||
|   | |||||||
| @@ -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 { | ||||||
|   | |||||||
| @@ -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, | ||||||
|   | |||||||
| @@ -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 | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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 | ||||||
| }; | }; | ||||||
| @@ -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() { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user