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:
Cory McWilliams 2023-05-17 20:22:13 +00:00
parent 2ca08d21e4
commit 3038138909

View File

@ -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': '*',