| 
									
										
										
										
											2019-07-20 12:19:47 +02:00
										 |  |  | const PROTOCOL_VERSION_MAJOR = 1; | 
					
						
							| 
									
										
										
										
											2019-07-20 12:17:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | function isDevEnv() { | 
					
						
							|  |  |  | 	const manifest = browser.runtime.getManifest(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-19 23:34:54 +02:00
										 |  |  | 	return manifest.name.endsWith('(dev)'); | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TriliumServerFacade { | 
					
						
							|  |  |  | 	constructor() { | 
					
						
							|  |  |  | 		this.triggerSearchForTrilium(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// continually scan for changes (if e.g. desktop app is started after browser)
 | 
					
						
							|  |  |  | 		setInterval(() => this.triggerSearchForTrilium(), 60 * 1000); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	async sendTriliumSearchStatusToPopup() { | 
					
						
							|  |  |  | 		try { | 
					
						
							|  |  |  | 			await browser.runtime.sendMessage({ | 
					
						
							|  |  |  | 				name: "trilium-search-status", | 
					
						
							|  |  |  | 				triliumSearch: this.triliumSearch | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		catch (e) {} // nothing might be listening
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	setTriliumSearch(ts) { | 
					
						
							|  |  |  | 		this.triliumSearch = ts; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.sendTriliumSearchStatusToPopup(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 12:17:59 +02:00
										 |  |  | 	setTriliumSearchWithVersionCheck(json, resp) { | 
					
						
							|  |  |  | 		const [major, minor] = json.protocolVersion | 
					
						
							|  |  |  | 			.split(".") | 
					
						
							|  |  |  | 			.map(chunk => parseInt(chunk)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// minor version is intended to be used to dynamically limit features provided by extension
 | 
					
						
							|  |  |  | 		// if some specific Trilium API is not supported. So far not needed.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (major !== PROTOCOL_VERSION_MAJOR) { | 
					
						
							|  |  |  | 			this.setTriliumSearch({ | 
					
						
							|  |  |  | 				status: 'version-mismatch', | 
					
						
							|  |  |  | 				extensionMajor: PROTOCOL_VERSION_MAJOR, | 
					
						
							|  |  |  | 				triliumMajor: major | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			this.setTriliumSearch(resp); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 	async triggerSearchForTrilium() { | 
					
						
							|  |  |  | 		this.setTriliumSearch({ status: 'searching' }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-31 00:48:23 +01:00
										 |  |  | 		try { | 
					
						
							|  |  |  | 			const port = await this.getPort(); | 
					
						
							| 
									
										
										
										
											2020-05-29 20:27:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-31 00:48:23 +01:00
										 |  |  | 			console.debug('Trying port ' + port); | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-31 00:48:23 +01:00
										 |  |  | 			const resp = await fetch(`http://127.0.0.1:${port}/api/clipper/handshake`); | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-31 00:48:23 +01:00
										 |  |  | 			const text = await resp.text(); | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-31 00:48:23 +01:00
										 |  |  | 			console.log("Received response:", text); | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-31 00:48:23 +01:00
										 |  |  | 			const json = JSON.parse(text); | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-31 00:48:23 +01:00
										 |  |  | 			if (json.appName === 'trilium') { | 
					
						
							|  |  |  | 				this.setTriliumSearchWithVersionCheck(json, { | 
					
						
							|  |  |  | 					status: 'found-desktop', | 
					
						
							|  |  |  | 					port: port, | 
					
						
							|  |  |  | 					url: 'http://127.0.0.1:' + port | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-31 00:48:23 +01:00
										 |  |  | 				return; | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-12-31 00:48:23 +01:00
										 |  |  | 		catch (error) { | 
					
						
							|  |  |  | 			// continue
 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		const {triliumServerUrl} = await browser.storage.sync.get("triliumServerUrl"); | 
					
						
							|  |  |  | 		const {authToken} = await browser.storage.sync.get("authToken"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (triliumServerUrl && authToken) { | 
					
						
							|  |  |  | 			try { | 
					
						
							|  |  |  | 				const resp = await fetch(triliumServerUrl + '/api/clipper/handshake', { | 
					
						
							|  |  |  | 					headers: { | 
					
						
							|  |  |  | 						Authorization: authToken | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				const text = await resp.text(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				console.log("Received response:", text); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				const json = JSON.parse(text); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (json.appName === 'trilium') { | 
					
						
							| 
									
										
										
										
											2019-07-20 12:17:59 +02:00
										 |  |  | 					this.setTriliumSearchWithVersionCheck(json, { | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 						status: 'found-server', | 
					
						
							|  |  |  | 						url: triliumServerUrl, | 
					
						
							|  |  |  | 						token: authToken | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2019-07-20 12:17:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			catch (e) { | 
					
						
							|  |  |  | 				console.log("Request to the configured server instance failed with:", e); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// if all above fails it's not found
 | 
					
						
							|  |  |  | 		this.setTriliumSearch({ status: 'not-found' }); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	async waitForTriliumSearch() { | 
					
						
							|  |  |  | 		return new Promise((res, rej) => { | 
					
						
							|  |  |  | 			const checkStatus = () => { | 
					
						
							|  |  |  | 				if (this.triliumSearch.status === "searching") { | 
					
						
							|  |  |  | 					setTimeout(checkStatus, 500); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else if (this.triliumSearch.status === 'not-found') { | 
					
						
							|  |  |  | 					rej(new Error("Trilium instance has not been found.")); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					res(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			checkStatus(); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-31 00:48:23 +01:00
										 |  |  | 	async getPort() { | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 		const {triliumDesktopPort} = await browser.storage.sync.get("triliumDesktopPort"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (triliumDesktopPort) { | 
					
						
							|  |  |  | 			return parseInt(triliumDesktopPort); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			return isDevEnv() ? 37740 : 37840; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	async callService(method, path, body) { | 
					
						
							|  |  |  | 		const fetchOptions = { | 
					
						
							|  |  |  | 			method: method, | 
					
						
							|  |  |  | 			headers: { | 
					
						
							|  |  |  | 				'Content-Type': 'application/json' | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (body) { | 
					
						
							|  |  |  | 			fetchOptions.body = typeof body === 'string' ? body : JSON.stringify(body); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		try { | 
					
						
							|  |  |  | 			await this.waitForTriliumSearch(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			fetchOptions.headers.Authorization = this.triliumSearch.token || ""; | 
					
						
							| 
									
										
										
										
											2020-05-29 20:27:17 +02:00
										 |  |  | 			fetchOptions.headers['trilium-local-now-datetime'] = this.localNowDateTime(); | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			const url = this.triliumSearch.url + "/api/clipper/" + path; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			console.log(`Sending ${method} request to ${url}`); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const response = await fetch(url, fetchOptions); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!response.ok) { | 
					
						
							|  |  |  | 				throw new Error(await response.text()); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return await response.json(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		catch (e) { | 
					
						
							|  |  |  | 			console.log("Sending request to trilium failed", e); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			toast('Your request failed because we could not contact Trilium instance. Please make sure Trilium is running and is accessible.'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return null; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-05-29 20:27:17 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	localNowDateTime() { | 
					
						
							|  |  |  | 		const date = new Date(); | 
					
						
							|  |  |  | 		const off = date.getTimezoneOffset(); | 
					
						
							|  |  |  | 		const absoff = Math.abs(off); | 
					
						
							|  |  |  | 		return (new Date(date.getTime() - off * 60 * 1000).toISOString().substr(0,23).replace("T",  " ") + | 
					
						
							|  |  |  | 			(off > 0 ? '-' : '+') + | 
					
						
							|  |  |  | 			(absoff / 60).toFixed(0).padStart(2,'0') + ':' + | 
					
						
							|  |  |  | 			(absoff % 60).toString().padStart(2,'0')); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-07-19 20:35:53 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-29 20:27:17 +02:00
										 |  |  | window.triliumServerFacade = new TriliumServerFacade(); |