This is a sketch of a setup that allows apps to produce sandboxed dynamic content without all the iframe/websocket business.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4305 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										45
									
								
								core/core.js
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								core/core.js
									
									
									
									
									
								
							| @@ -343,8 +343,13 @@ async function getProcessBlob(blobId, key, options) { | |||||||
| 					imports.app[api[0]] = process.app.makeFunction(api); | 					imports.app[api[0]] = process.app.makeFunction(api); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | 			for (let [name, f] of Object.entries(options?.imports || {})) { | ||||||
|  | 				imports[name] = f; | ||||||
|  | 			} | ||||||
| 			process.task.onPrint = function(args) { | 			process.task.onPrint = function(args) { | ||||||
|  | 				if (imports.app) { | ||||||
| 					imports.app.print(...args); | 					imports.app.print(...args); | ||||||
|  | 				} | ||||||
| 			}; | 			}; | ||||||
| 			process.task.onError = function(error) { | 			process.task.onError = function(error) { | ||||||
| 				try { | 				try { | ||||||
| @@ -429,7 +434,7 @@ async function getProcessBlob(blobId, key, options) { | |||||||
| 			try { | 			try { | ||||||
| 				let appObject = JSON.parse(appSource); | 				let appObject = JSON.parse(appSource); | ||||||
| 				if (appObject.type == "tildefriends-app") { | 				if (appObject.type == "tildefriends-app") { | ||||||
| 					appSourceName = 'app.js'; | 					appSourceName = options?.script ?? 'app.js'; | ||||||
| 					let id = appObject.files[appSourceName]; | 					let id = appObject.files[appSourceName]; | ||||||
| 					let blob = await getBlobOrContent(id); | 					let blob = await getBlobOrContent(id); | ||||||
| 					appSource = utf8Decode(blob); | 					appSource = utf8Decode(blob); | ||||||
| @@ -586,6 +591,23 @@ async function getBlobOrContent(id) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | let g_handler_index = 0; | ||||||
|  | async function useAppHandler(response, handler_blob_id, path) { | ||||||
|  | 	let do_resolve; | ||||||
|  | 	let promise = new Promise(async function(resolve, reject) { | ||||||
|  | 		do_resolve = resolve; | ||||||
|  | 	}); | ||||||
|  | 	let process = await getProcessBlob(handler_blob_id, 'handler_' + g_handler_index++, { | ||||||
|  | 		script: 'handler.js', | ||||||
|  | 		imports: { | ||||||
|  | 			respond: do_resolve, | ||||||
|  | 		}, | ||||||
|  | 	}); | ||||||
|  | 	let result = await promise; | ||||||
|  | 	await process.task.kill(); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  |  | ||||||
| async function blobHandler(request, response, blobId, uri) { | async function blobHandler(request, response, blobId, uri) { | ||||||
| 	for (let i in k_static_files) { | 	for (let i in k_static_files) { | ||||||
| 		if (uri === k_static_files[i].uri && k_static_files[i].path) { | 		if (uri === k_static_files[i].uri && k_static_files[i].path) { | ||||||
| @@ -732,17 +754,24 @@ async function blobHandler(request, response, blobId, uri) { | |||||||
| 		let data; | 		let data; | ||||||
| 		let match; | 		let match; | ||||||
| 		let id; | 		let id; | ||||||
|  | 		let app_id = blobId; | ||||||
| 		if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { | 		if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { | ||||||
| 			let db = new Database(match[1]); | 			let db = new Database(match[1]); | ||||||
| 			let app_id = await db.get('path:' + match[2]); | 			app_id = await db.get('path:' + match[2]); | ||||||
| 			let app_object = JSON.parse(utf8Decode(await getBlobOrContent(app_id))); |  | ||||||
| 			id = app_object.files[uri.substring(1)]; |  | ||||||
| 		} else { |  | ||||||
| 			let app_object = JSON.parse(utf8Decode(await getBlobOrContent(blobId))); |  | ||||||
| 			id = app_object.files[uri.substring(1)]; |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (id) { | 		let app_object = JSON.parse(utf8Decode(await getBlobOrContent(app_id))); | ||||||
|  | 		id = app_object.files[uri.substring(1)]; | ||||||
|  | 		if (!id && app_object.files['handler.js']) { | ||||||
|  | 			let answer = await useAppHandler(response, app_id, uri.substring(1)); | ||||||
|  | 			if (typeof answer.data == 'string') { | ||||||
|  | 				answer.data = utf8Encode(answer.data); | ||||||
|  | 			} | ||||||
|  | 			sendData(response, answer?.data, answer?.content_type, { | ||||||
|  | 				'Access-Control-Allow-Origin': '*', | ||||||
|  | 				'Content-Security-Policy': 'sandbox', | ||||||
|  | 			}); | ||||||
|  | 		} else if (id) { | ||||||
| 			if (request.headers['if-none-match'] && request.headers['if-none-match'] == '"' + id + '"') { | 			if (request.headers['if-none-match'] && request.headers['if-none-match'] == '"' + id + '"') { | ||||||
| 				let headers = { | 				let headers = { | ||||||
| 					'Access-Control-Allow-Origin': '*', | 					'Access-Control-Allow-Origin': '*', | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user