From 303813890978f240425a69596c20be471d35b84d Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Wed, 17 May 2023 20:22:13 +0000 Subject: [PATCH] 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 --- core/core.js | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/core/core.js b/core/core.js index cf8759ac..fa5da0bf 100644 --- a/core/core.js +++ b/core/core.js @@ -343,8 +343,13 @@ async function getProcessBlob(blobId, key, options) { 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) { - imports.app.print(...args); + if (imports.app) { + imports.app.print(...args); + } }; process.task.onError = function(error) { try { @@ -429,7 +434,7 @@ async function getProcessBlob(blobId, key, options) { try { let appObject = JSON.parse(appSource); if (appObject.type == "tildefriends-app") { - appSourceName = 'app.js'; + appSourceName = options?.script ?? 'app.js'; let id = appObject.files[appSourceName]; let blob = await getBlobOrContent(id); 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) { for (let i in k_static_files) { 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 match; let id; + let app_id = blobId; if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) { let db = new Database(match[1]); - let 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)]; + app_id = await db.get('path:' + match[2]); } - 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 + '"') { let headers = { 'Access-Control-Allow-Origin': '*',