forked from cory/tildefriends
		
	Use proper js modules for apps. Kludge enough things to make things seem to work. Need to apply this to core still.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3862 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										14
									
								
								core/app.js
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								core/app.js
									
									
									
									
									
								
							@@ -1,5 +1,14 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
var auth = require('auth');
 | 
			
		||||
var core = require('core');
 | 
			
		||||
 | 
			
		||||
var gSessionIndex = 0;
 | 
			
		||||
 | 
			
		||||
function makeSessionId() {
 | 
			
		||||
	return (gSessionIndex++).toString();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function App() {
 | 
			
		||||
	this._on_output = null;
 | 
			
		||||
	this._send_queue = [];
 | 
			
		||||
@@ -96,7 +105,7 @@ function socket(request, response, client) {
 | 
			
		||||
				options.packageName = packageName;
 | 
			
		||||
				var sessionId = makeSessionId();
 | 
			
		||||
				if (blobId) {
 | 
			
		||||
					process = await getSessionProcessBlob(blobId, sessionId, options);
 | 
			
		||||
					process = await core.getSessionProcessBlob(blobId, sessionId, options);
 | 
			
		||||
				}
 | 
			
		||||
				if (process) {
 | 
			
		||||
					process.app.readOutput(function(message) {
 | 
			
		||||
@@ -140,7 +149,7 @@ function socket(request, response, client) {
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if (process && process.eventHandlers['message']) {
 | 
			
		||||
					await invoke(process.eventHandlers['message'], [message]);
 | 
			
		||||
					await core.invoke(process.eventHandlers['message'], [message]);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (event.opCode == 0x8) {
 | 
			
		||||
@@ -160,3 +169,4 @@ function socket(request, response, client) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.socket = socket;
 | 
			
		||||
exports.App = App;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								core/auth.js
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								core/auth.js
									
									
									
									
									
								
							@@ -2,6 +2,7 @@
 | 
			
		||||
 | 
			
		||||
var gTokens = {};
 | 
			
		||||
 | 
			
		||||
var core = require('core');
 | 
			
		||||
var form = require('form');
 | 
			
		||||
var http = require('http');
 | 
			
		||||
 | 
			
		||||
@@ -51,22 +52,38 @@ function hashPassword(password) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function noAdministrator() {
 | 
			
		||||
	return !gGlobalSettings || !gGlobalSettings.permissions || !Object.keys(gGlobalSettings.permissions).some(function(name) {
 | 
			
		||||
		return gGlobalSettings.permissions[name].indexOf("administration") != -1;
 | 
			
		||||
	return !core.globalSettings || !core.globalSettings.permissions || !Object.keys(core.globalSettings.permissions).some(function(name) {
 | 
			
		||||
		return core.globalSettings.permissions[name].indexOf("administration") != -1;
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function makeAdministrator(name) {
 | 
			
		||||
	if (!gGlobalSettings.permissions) {
 | 
			
		||||
		gGlobalSettings.permissions = {};
 | 
			
		||||
	if (!core.globalSettings.permissions) {
 | 
			
		||||
		core.globalSettings.permissions = {};
 | 
			
		||||
	}
 | 
			
		||||
	if (!gGlobalSettings.permissions[name]) {
 | 
			
		||||
		gGlobalSettings.permissions[name] = [];
 | 
			
		||||
	if (!core.globalSettings.permissions[name]) {
 | 
			
		||||
		core.globalSettings.permissions[name] = [];
 | 
			
		||||
	}
 | 
			
		||||
	if (gGlobalSettings.permissions[name].indexOf("administration") == -1) {
 | 
			
		||||
		gGlobalSettings.permissions[name].push("administration");
 | 
			
		||||
	if (core.globalSettings.permissions[name].indexOf("administration") == -1) {
 | 
			
		||||
		core.globalSettings.permissions[name].push("administration");
 | 
			
		||||
	}
 | 
			
		||||
	setGlobalSettings(gGlobalSettings);
 | 
			
		||||
	core.setGlobalSettings(core.globalSettings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getCookies(headers) {
 | 
			
		||||
	var cookies = {};
 | 
			
		||||
 | 
			
		||||
	if (headers.cookie) {
 | 
			
		||||
		var parts = headers.cookie.split(/,|;/);
 | 
			
		||||
		for (var i in parts) {
 | 
			
		||||
			var equals = parts[i].indexOf("=");
 | 
			
		||||
			var name = parts[i].substring(0, equals).trim();
 | 
			
		||||
			var value = parts[i].substring(equals + 1).trim();
 | 
			
		||||
			cookies[name] = value;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return cookies;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function authHandler(request, response) {
 | 
			
		||||
@@ -185,9 +202,9 @@ function getPermissions(session) {
 | 
			
		||||
 | 
			
		||||
function getPermissionsForUser(userName) {
 | 
			
		||||
	var permissions = {};
 | 
			
		||||
	if (gGlobalSettings && gGlobalSettings.permissions && gGlobalSettings.permissions[userName]) {
 | 
			
		||||
		for (var i in gGlobalSettings.permissions[userName]) {
 | 
			
		||||
			permissions[gGlobalSettings.permissions[userName][i]] = true;
 | 
			
		||||
	if (core.globalSettings && core.globalSettings.permissions && core.globalSettings.permissions[userName]) {
 | 
			
		||||
		for (var i in core.globalSettings.permissions[userName]) {
 | 
			
		||||
			permissions[core.globalSettings.permissions[userName][i]] = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return permissions;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										58
									
								
								core/core.js
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								core/core.js
									
									
									
									
									
								
							@@ -5,7 +5,6 @@ var app = require("app");
 | 
			
		||||
 | 
			
		||||
var gProcessIndex = 0;
 | 
			
		||||
var gProcesses = {};
 | 
			
		||||
var gSessionIndex = 0;
 | 
			
		||||
var gStatsTimer = false;
 | 
			
		||||
 | 
			
		||||
var gGlobalSettings = {
 | 
			
		||||
@@ -16,26 +15,6 @@ var kGlobalSettingsFile = "data/global/settings.json";
 | 
			
		||||
 | 
			
		||||
var kPingInterval = 60 * 1000;
 | 
			
		||||
 | 
			
		||||
function getCookies(headers) {
 | 
			
		||||
	var cookies = {};
 | 
			
		||||
 | 
			
		||||
	if (headers.cookie) {
 | 
			
		||||
		var parts = headers.cookie.split(/,|;/);
 | 
			
		||||
		for (var i in parts) {
 | 
			
		||||
			var equals = parts[i].indexOf("=");
 | 
			
		||||
			var name = parts[i].substring(0, equals).trim();
 | 
			
		||||
			var value = parts[i].substring(equals + 1).trim();
 | 
			
		||||
			cookies[name] = value;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return cookies;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function makeSessionId() {
 | 
			
		||||
	return (gSessionIndex++).toString();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function printError(out, error) {
 | 
			
		||||
	if (error.stackTrace) {
 | 
			
		||||
		out.print(error.fileName + ":" + error.lineNumber + ": " + error.message);
 | 
			
		||||
@@ -154,7 +133,7 @@ async function getProcessBlob(blobId, key, options) {
 | 
			
		||||
			process.credentials = options.credentials || {};
 | 
			
		||||
			process.task = new Task();
 | 
			
		||||
			process.eventHandlers = {};
 | 
			
		||||
			process.app = new App();
 | 
			
		||||
			process.app = new app.App();
 | 
			
		||||
			process.lastActive = Date.now();
 | 
			
		||||
			process.lastPing = null;
 | 
			
		||||
			process.timeout = options.timeout;
 | 
			
		||||
@@ -233,14 +212,14 @@ async function getProcessBlob(blobId, key, options) {
 | 
			
		||||
			var appSourceName = blobId;
 | 
			
		||||
			var appSource = utf8Decode(source);
 | 
			
		||||
			try {
 | 
			
		||||
				var app = JSON.parse(appSource);
 | 
			
		||||
				if (app.type == "tildefriends-app") {
 | 
			
		||||
				var appObject = JSON.parse(appSource);
 | 
			
		||||
				if (appObject.type == "tildefriends-app") {
 | 
			
		||||
					appSourceName = 'app.js';
 | 
			
		||||
					var id = app.files[appSourceName];
 | 
			
		||||
					var id = appObject.files[appSourceName];
 | 
			
		||||
					var blob = await getBlobOrContent(id);
 | 
			
		||||
					appSource = utf8Decode(blob);
 | 
			
		||||
					await Promise.all(Object.keys(app.files).map(async function(f) {
 | 
			
		||||
						await process.task.loadFile([f, await getBlobOrContent(app.files[f])]);
 | 
			
		||||
					await Promise.all(Object.keys(appObject.files).map(async function(f) {
 | 
			
		||||
						await process.task.loadFile([f, await getBlobOrContent(appObject.files[f])]);
 | 
			
		||||
					}));
 | 
			
		||||
				}
 | 
			
		||||
			} catch (e) {
 | 
			
		||||
@@ -444,8 +423,8 @@ async function blobHandler(request, response, blobId, uri) {
 | 
			
		||||
					} else {
 | 
			
		||||
						data = await getBlobOrContent(id);
 | 
			
		||||
						if (match[3]) {
 | 
			
		||||
							var app = JSON.parse(data);
 | 
			
		||||
							data = app.files[match[3]];
 | 
			
		||||
							var appObject = JSON.parse(data);
 | 
			
		||||
							data = appObject.files[match[3]];
 | 
			
		||||
						}
 | 
			
		||||
						sendData(response, data, undefined, {etag: '"' + id + '"'});
 | 
			
		||||
					}
 | 
			
		||||
@@ -462,7 +441,7 @@ async function blobHandler(request, response, blobId, uri) {
 | 
			
		||||
			var match;
 | 
			
		||||
			if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
 | 
			
		||||
				var user = match[1];
 | 
			
		||||
				var app = match[2];
 | 
			
		||||
				var appName = match[2];
 | 
			
		||||
				var credentials = auth.query(request.headers);
 | 
			
		||||
				if (credentials && credentials.session &&
 | 
			
		||||
					(credentials.session.name == user ||
 | 
			
		||||
@@ -473,11 +452,11 @@ async function blobHandler(request, response, blobId, uri) {
 | 
			
		||||
						apps = new Set(JSON.parse(database.get('apps')));
 | 
			
		||||
					} catch {
 | 
			
		||||
					}
 | 
			
		||||
					if (!apps.has(app)) {
 | 
			
		||||
						apps.add(app);
 | 
			
		||||
					if (!apps.has(appName)) {
 | 
			
		||||
						apps.add(appName);
 | 
			
		||||
						database.set('apps', JSON.stringify([...apps]));
 | 
			
		||||
					}
 | 
			
		||||
					database.set('path:' + app, newBlobId);
 | 
			
		||||
					database.set('path:' + appName, newBlobId);
 | 
			
		||||
				} else {
 | 
			
		||||
					response.writeHead(401, {"Content-Type": "text/plain; charset=utf-8"});
 | 
			
		||||
					response.end("401 Unauthorized");
 | 
			
		||||
@@ -500,8 +479,8 @@ async function blobHandler(request, response, blobId, uri) {
 | 
			
		||||
						response.end();
 | 
			
		||||
					} else {
 | 
			
		||||
						data = utf8Decode(await getBlobOrContent(id));
 | 
			
		||||
						var app = JSON.parse(data);
 | 
			
		||||
						data = app.files[uri.substring(1)];
 | 
			
		||||
						var appObject = JSON.parse(data);
 | 
			
		||||
						data = appObject.files[uri.substring(1)];
 | 
			
		||||
						data = await getBlobOrContent(data);
 | 
			
		||||
						type = guessType(uri);
 | 
			
		||||
						headers = {'ETag': '"' + id + '"'};
 | 
			
		||||
@@ -512,8 +491,8 @@ async function blobHandler(request, response, blobId, uri) {
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				data = utf8Decode(await getBlobOrContent(blobId));
 | 
			
		||||
				var app = JSON.parse(data);
 | 
			
		||||
				data = app.files[uri.substring(1)];
 | 
			
		||||
				var appObject = JSON.parse(data);
 | 
			
		||||
				data = appObject.files[uri.substring(1)];
 | 
			
		||||
				data = await getBlobOrContent(data);
 | 
			
		||||
				sendData(response, data, type, headers);
 | 
			
		||||
			}
 | 
			
		||||
@@ -608,3 +587,8 @@ loadSettings().then(function() {
 | 
			
		||||
}).catch(function(error) {
 | 
			
		||||
	print('Failed to load settings.');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
exports.getSessionProcessBlob = getSessionProcessBlob;
 | 
			
		||||
exports.invoke = invoke;
 | 
			
		||||
exports.globalSettings = gGlobalSettings;
 | 
			
		||||
exports.setGlobalSettings = setGlobalSettings;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										51
									
								
								src/task.c
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								src/task.c
									
									
									
									
									
								
							@@ -347,7 +347,7 @@ int tf_task_execute(tf_task_t* task, const char* fileName)
 | 
			
		||||
	}
 | 
			
		||||
	if (source)
 | 
			
		||||
	{
 | 
			
		||||
		JSValue result = JS_Eval(task->_context, source, strlen(source), fileName, 0);
 | 
			
		||||
		JSValue result = JS_Eval(task->_context, source, strlen(source), fileName, JS_EVAL_TYPE_MODULE);
 | 
			
		||||
		tf_util_report_error(task->_context, result);
 | 
			
		||||
		if (!JS_IsError(task->_context, result) && !JS_IsException(result))
 | 
			
		||||
		{
 | 
			
		||||
@@ -891,12 +891,15 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length,
 | 
			
		||||
			JSValue result = _tf_task_executeSource(to, source_str, name);
 | 
			
		||||
			if (JS_IsException(result))
 | 
			
		||||
			{
 | 
			
		||||
				_tf_task_sendPromiseReject(to, from, promise, JS_GetException(to->_context));
 | 
			
		||||
				JSValue exception = JS_GetException(to->_context);
 | 
			
		||||
				_tf_task_sendPromiseReject(to, from, promise, exception);
 | 
			
		||||
				JS_FreeValue(to->_context, exception);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				_tf_task_sendPromiseResolve(to, from, promise, result);
 | 
			
		||||
			}
 | 
			
		||||
			JS_FreeValue(to->_context, result);
 | 
			
		||||
			JS_FreeCString(to->_context, source_str);
 | 
			
		||||
			JS_FreeCString(to->_context, name);
 | 
			
		||||
		}
 | 
			
		||||
@@ -1031,7 +1034,7 @@ JSValue _tf_task_require(JSContext* context, JSValueConst this_val, int argc, JS
 | 
			
		||||
					JSValue global = JS_GetGlobalObject(task->_context);
 | 
			
		||||
					JSValue oldExports = JS_GetPropertyStr(task->_context, global, "exports");
 | 
			
		||||
					JS_SetPropertyStr(task->_context, global, "exports", JS_DupValue(task->_context, exports));
 | 
			
		||||
					JSValue eval = JS_Eval(task->_context, source, strlen(source), path, 0);
 | 
			
		||||
					JSValue eval = JS_Eval(task->_context, source, strlen(source), path, JS_EVAL_TYPE_MODULE);
 | 
			
		||||
					tf_util_report_error(task->_context, eval);
 | 
			
		||||
					if (JS_IsError(task->_context, eval) ||
 | 
			
		||||
						JS_IsException(eval))
 | 
			
		||||
@@ -1067,7 +1070,7 @@ JSValue _tf_task_require(JSContext* context, JSValueConst this_val, int argc, JS
 | 
			
		||||
static JSValue _tf_task_executeSource(tf_task_t* task, const char* source, const char* name)
 | 
			
		||||
{
 | 
			
		||||
	tf_trace_begin(task->_trace, "_tf_task_executeSource");
 | 
			
		||||
	JSValue result = JS_Eval(task->_context, source, strlen(source), name, 0);
 | 
			
		||||
	JSValue result = JS_Eval(task->_context, source, strlen(source), name, JS_EVAL_TYPE_MODULE);
 | 
			
		||||
	if (!*task->_scriptName)
 | 
			
		||||
	{
 | 
			
		||||
		snprintf(task->_scriptName, sizeof(task->_scriptName), "%s", name);
 | 
			
		||||
@@ -1103,7 +1106,7 @@ JSValue _tf_task_sandbox_require(JSContext* context, JSValueConst this_val, int
 | 
			
		||||
				JSValue global = JS_GetGlobalObject(context);
 | 
			
		||||
				JSValue oldExports = JS_GetPropertyStr(context, global, "exports");
 | 
			
		||||
				JS_SetPropertyStr(context, global, "exports", JS_DupValue(context, exports));
 | 
			
		||||
				JSValue result = JS_Eval(context, source, length, name, 0);
 | 
			
		||||
				JSValue result = JS_Eval(context, source, length, name, JS_EVAL_TYPE_MODULE);
 | 
			
		||||
				tf_util_report_error(context, result);
 | 
			
		||||
				JS_SetPropertyStr(context, global, "exports", oldExports);
 | 
			
		||||
				JS_FreeValue(context, global);
 | 
			
		||||
@@ -1117,7 +1120,7 @@ JSValue _tf_task_sandbox_require(JSContext* context, JSValueConst this_val, int
 | 
			
		||||
				JSValue global = JS_GetGlobalObject(context);
 | 
			
		||||
				JSValue oldExports = JS_GetPropertyStr(context, global, "exports");
 | 
			
		||||
				JS_SetPropertyStr(context, global, "exports", JS_DupValue(context, exports));
 | 
			
		||||
				JSValue result = JS_Eval(context, source, length, name, 0);
 | 
			
		||||
				JSValue result = JS_Eval(context, source, length, name, JS_EVAL_TYPE_MODULE);
 | 
			
		||||
				tf_util_report_error(context, result);
 | 
			
		||||
				JS_SetPropertyStr(context, global, "exports", oldExports);
 | 
			
		||||
				JS_FreeValue(context, global);
 | 
			
		||||
@@ -1378,6 +1381,40 @@ static void _tf_task_run_jobs_prepare(uv_prepare_t* prepare)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSModuleDef* _tf_task_module_loader(JSContext* context, const char* module_name, void* opaque)
 | 
			
		||||
{
 | 
			
		||||
	tf_task_t* task = opaque;
 | 
			
		||||
	JSValue source_value = JS_GetPropertyStr(context, task->_loadedFiles, module_name);
 | 
			
		||||
 | 
			
		||||
	char* source = NULL;
 | 
			
		||||
	size_t length = 0;
 | 
			
		||||
	uint8_t* array = tf_util_try_get_array_buffer(context, &length, source_value);
 | 
			
		||||
	if (array)
 | 
			
		||||
	{
 | 
			
		||||
		source = malloc(length + 1);
 | 
			
		||||
		memcpy(source, array, length);
 | 
			
		||||
		source[length] = '\0';
 | 
			
		||||
	}
 | 
			
		||||
	JS_FreeValue(context, source_value);
 | 
			
		||||
 | 
			
		||||
	if (!source)
 | 
			
		||||
	{
 | 
			
		||||
		JS_ThrowReferenceError(context, "Could not load '%s'.", module_name);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	JSValue result = JS_Eval(context, source, length, module_name, JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
 | 
			
		||||
	free(source);
 | 
			
		||||
	if (tf_util_report_error(task->_context, result))
 | 
			
		||||
	{
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	JSModuleDef* module = JS_VALUE_GET_PTR(result);
 | 
			
		||||
	JS_FreeValue(context, result);
 | 
			
		||||
	return module;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tf_task_t* tf_task_create()
 | 
			
		||||
{
 | 
			
		||||
	tf_task_t* task = malloc(sizeof(tf_task_t));
 | 
			
		||||
@@ -1389,6 +1426,8 @@ tf_task_t* tf_task_create()
 | 
			
		||||
 | 
			
		||||
	JS_SetHostPromiseRejectionTracker(task->_runtime, _tf_task_promise_rejection_tracker, task);
 | 
			
		||||
 | 
			
		||||
	JS_SetModuleLoaderFunc(task->_runtime, NULL, _tf_task_module_loader, task);
 | 
			
		||||
 | 
			
		||||
	JS_NewClassID(&_import_class_id);
 | 
			
		||||
	JSClassDef def =
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user