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:
parent
9b2d4b393d
commit
00bdf1df4a
14
core/app.js
14
core/app.js
@ -1,5 +1,14 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var auth = require('auth');
|
||||||
|
var core = require('core');
|
||||||
|
|
||||||
|
var gSessionIndex = 0;
|
||||||
|
|
||||||
|
function makeSessionId() {
|
||||||
|
return (gSessionIndex++).toString();
|
||||||
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
this._on_output = null;
|
this._on_output = null;
|
||||||
this._send_queue = [];
|
this._send_queue = [];
|
||||||
@ -96,7 +105,7 @@ function socket(request, response, client) {
|
|||||||
options.packageName = packageName;
|
options.packageName = packageName;
|
||||||
var sessionId = makeSessionId();
|
var sessionId = makeSessionId();
|
||||||
if (blobId) {
|
if (blobId) {
|
||||||
process = await getSessionProcessBlob(blobId, sessionId, options);
|
process = await core.getSessionProcessBlob(blobId, sessionId, options);
|
||||||
}
|
}
|
||||||
if (process) {
|
if (process) {
|
||||||
process.app.readOutput(function(message) {
|
process.app.readOutput(function(message) {
|
||||||
@ -140,7 +149,7 @@ function socket(request, response, client) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (process && process.eventHandlers['message']) {
|
if (process && process.eventHandlers['message']) {
|
||||||
await invoke(process.eventHandlers['message'], [message]);
|
await core.invoke(process.eventHandlers['message'], [message]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event.opCode == 0x8) {
|
} else if (event.opCode == 0x8) {
|
||||||
@ -160,3 +169,4 @@ function socket(request, response, client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
exports.socket = socket;
|
exports.socket = socket;
|
||||||
|
exports.App = App;
|
||||||
|
41
core/auth.js
41
core/auth.js
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
var gTokens = {};
|
var gTokens = {};
|
||||||
|
|
||||||
|
var core = require('core');
|
||||||
var form = require('form');
|
var form = require('form');
|
||||||
var http = require('http');
|
var http = require('http');
|
||||||
|
|
||||||
@ -51,22 +52,38 @@ function hashPassword(password) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function noAdministrator() {
|
function noAdministrator() {
|
||||||
return !gGlobalSettings || !gGlobalSettings.permissions || !Object.keys(gGlobalSettings.permissions).some(function(name) {
|
return !core.globalSettings || !core.globalSettings.permissions || !Object.keys(core.globalSettings.permissions).some(function(name) {
|
||||||
return gGlobalSettings.permissions[name].indexOf("administration") != -1;
|
return core.globalSettings.permissions[name].indexOf("administration") != -1;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeAdministrator(name) {
|
function makeAdministrator(name) {
|
||||||
if (!gGlobalSettings.permissions) {
|
if (!core.globalSettings.permissions) {
|
||||||
gGlobalSettings.permissions = {};
|
core.globalSettings.permissions = {};
|
||||||
}
|
}
|
||||||
if (!gGlobalSettings.permissions[name]) {
|
if (!core.globalSettings.permissions[name]) {
|
||||||
gGlobalSettings.permissions[name] = [];
|
core.globalSettings.permissions[name] = [];
|
||||||
}
|
}
|
||||||
if (gGlobalSettings.permissions[name].indexOf("administration") == -1) {
|
if (core.globalSettings.permissions[name].indexOf("administration") == -1) {
|
||||||
gGlobalSettings.permissions[name].push("administration");
|
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) {
|
function authHandler(request, response) {
|
||||||
@ -185,9 +202,9 @@ function getPermissions(session) {
|
|||||||
|
|
||||||
function getPermissionsForUser(userName) {
|
function getPermissionsForUser(userName) {
|
||||||
var permissions = {};
|
var permissions = {};
|
||||||
if (gGlobalSettings && gGlobalSettings.permissions && gGlobalSettings.permissions[userName]) {
|
if (core.globalSettings && core.globalSettings.permissions && core.globalSettings.permissions[userName]) {
|
||||||
for (var i in gGlobalSettings.permissions[userName]) {
|
for (var i in core.globalSettings.permissions[userName]) {
|
||||||
permissions[gGlobalSettings.permissions[userName][i]] = true;
|
permissions[core.globalSettings.permissions[userName][i]] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return permissions;
|
return permissions;
|
||||||
|
58
core/core.js
58
core/core.js
@ -5,7 +5,6 @@ var app = require("app");
|
|||||||
|
|
||||||
var gProcessIndex = 0;
|
var gProcessIndex = 0;
|
||||||
var gProcesses = {};
|
var gProcesses = {};
|
||||||
var gSessionIndex = 0;
|
|
||||||
var gStatsTimer = false;
|
var gStatsTimer = false;
|
||||||
|
|
||||||
var gGlobalSettings = {
|
var gGlobalSettings = {
|
||||||
@ -16,26 +15,6 @@ var kGlobalSettingsFile = "data/global/settings.json";
|
|||||||
|
|
||||||
var kPingInterval = 60 * 1000;
|
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) {
|
function printError(out, error) {
|
||||||
if (error.stackTrace) {
|
if (error.stackTrace) {
|
||||||
out.print(error.fileName + ":" + error.lineNumber + ": " + error.message);
|
out.print(error.fileName + ":" + error.lineNumber + ": " + error.message);
|
||||||
@ -154,7 +133,7 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
process.credentials = options.credentials || {};
|
process.credentials = options.credentials || {};
|
||||||
process.task = new Task();
|
process.task = new Task();
|
||||||
process.eventHandlers = {};
|
process.eventHandlers = {};
|
||||||
process.app = new App();
|
process.app = new app.App();
|
||||||
process.lastActive = Date.now();
|
process.lastActive = Date.now();
|
||||||
process.lastPing = null;
|
process.lastPing = null;
|
||||||
process.timeout = options.timeout;
|
process.timeout = options.timeout;
|
||||||
@ -233,14 +212,14 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
var appSourceName = blobId;
|
var appSourceName = blobId;
|
||||||
var appSource = utf8Decode(source);
|
var appSource = utf8Decode(source);
|
||||||
try {
|
try {
|
||||||
var app = JSON.parse(appSource);
|
var appObject = JSON.parse(appSource);
|
||||||
if (app.type == "tildefriends-app") {
|
if (appObject.type == "tildefriends-app") {
|
||||||
appSourceName = 'app.js';
|
appSourceName = 'app.js';
|
||||||
var id = app.files[appSourceName];
|
var id = appObject.files[appSourceName];
|
||||||
var blob = await getBlobOrContent(id);
|
var blob = await getBlobOrContent(id);
|
||||||
appSource = utf8Decode(blob);
|
appSource = utf8Decode(blob);
|
||||||
await Promise.all(Object.keys(app.files).map(async function(f) {
|
await Promise.all(Object.keys(appObject.files).map(async function(f) {
|
||||||
await process.task.loadFile([f, await getBlobOrContent(app.files[f])]);
|
await process.task.loadFile([f, await getBlobOrContent(appObject.files[f])]);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -444,8 +423,8 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
} else {
|
} else {
|
||||||
data = await getBlobOrContent(id);
|
data = await getBlobOrContent(id);
|
||||||
if (match[3]) {
|
if (match[3]) {
|
||||||
var app = JSON.parse(data);
|
var appObject = JSON.parse(data);
|
||||||
data = app.files[match[3]];
|
data = appObject.files[match[3]];
|
||||||
}
|
}
|
||||||
sendData(response, data, undefined, {etag: '"' + id + '"'});
|
sendData(response, data, undefined, {etag: '"' + id + '"'});
|
||||||
}
|
}
|
||||||
@ -462,7 +441,7 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
var match;
|
var match;
|
||||||
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
||||||
var user = match[1];
|
var user = match[1];
|
||||||
var app = match[2];
|
var appName = match[2];
|
||||||
var credentials = auth.query(request.headers);
|
var credentials = auth.query(request.headers);
|
||||||
if (credentials && credentials.session &&
|
if (credentials && credentials.session &&
|
||||||
(credentials.session.name == user ||
|
(credentials.session.name == user ||
|
||||||
@ -473,11 +452,11 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
apps = new Set(JSON.parse(database.get('apps')));
|
apps = new Set(JSON.parse(database.get('apps')));
|
||||||
} catch {
|
} catch {
|
||||||
}
|
}
|
||||||
if (!apps.has(app)) {
|
if (!apps.has(appName)) {
|
||||||
apps.add(app);
|
apps.add(appName);
|
||||||
database.set('apps', JSON.stringify([...apps]));
|
database.set('apps', JSON.stringify([...apps]));
|
||||||
}
|
}
|
||||||
database.set('path:' + app, newBlobId);
|
database.set('path:' + appName, newBlobId);
|
||||||
} else {
|
} else {
|
||||||
response.writeHead(401, {"Content-Type": "text/plain; charset=utf-8"});
|
response.writeHead(401, {"Content-Type": "text/plain; charset=utf-8"});
|
||||||
response.end("401 Unauthorized");
|
response.end("401 Unauthorized");
|
||||||
@ -500,8 +479,8 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
response.end();
|
response.end();
|
||||||
} else {
|
} else {
|
||||||
data = utf8Decode(await getBlobOrContent(id));
|
data = utf8Decode(await getBlobOrContent(id));
|
||||||
var app = JSON.parse(data);
|
var appObject = JSON.parse(data);
|
||||||
data = app.files[uri.substring(1)];
|
data = appObject.files[uri.substring(1)];
|
||||||
data = await getBlobOrContent(data);
|
data = await getBlobOrContent(data);
|
||||||
type = guessType(uri);
|
type = guessType(uri);
|
||||||
headers = {'ETag': '"' + id + '"'};
|
headers = {'ETag': '"' + id + '"'};
|
||||||
@ -512,8 +491,8 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
data = utf8Decode(await getBlobOrContent(blobId));
|
data = utf8Decode(await getBlobOrContent(blobId));
|
||||||
var app = JSON.parse(data);
|
var appObject = JSON.parse(data);
|
||||||
data = app.files[uri.substring(1)];
|
data = appObject.files[uri.substring(1)];
|
||||||
data = await getBlobOrContent(data);
|
data = await getBlobOrContent(data);
|
||||||
sendData(response, data, type, headers);
|
sendData(response, data, type, headers);
|
||||||
}
|
}
|
||||||
@ -608,3 +587,8 @@ loadSettings().then(function() {
|
|||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
print('Failed to load settings.');
|
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)
|
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);
|
tf_util_report_error(task->_context, result);
|
||||||
if (!JS_IsError(task->_context, result) && !JS_IsException(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);
|
JSValue result = _tf_task_executeSource(to, source_str, name);
|
||||||
if (JS_IsException(result))
|
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
|
else
|
||||||
{
|
{
|
||||||
_tf_task_sendPromiseResolve(to, from, promise, result);
|
_tf_task_sendPromiseResolve(to, from, promise, result);
|
||||||
}
|
}
|
||||||
|
JS_FreeValue(to->_context, result);
|
||||||
JS_FreeCString(to->_context, source_str);
|
JS_FreeCString(to->_context, source_str);
|
||||||
JS_FreeCString(to->_context, name);
|
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 global = JS_GetGlobalObject(task->_context);
|
||||||
JSValue oldExports = JS_GetPropertyStr(task->_context, global, "exports");
|
JSValue oldExports = JS_GetPropertyStr(task->_context, global, "exports");
|
||||||
JS_SetPropertyStr(task->_context, global, "exports", JS_DupValue(task->_context, 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);
|
tf_util_report_error(task->_context, eval);
|
||||||
if (JS_IsError(task->_context, eval) ||
|
if (JS_IsError(task->_context, eval) ||
|
||||||
JS_IsException(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)
|
static JSValue _tf_task_executeSource(tf_task_t* task, const char* source, const char* name)
|
||||||
{
|
{
|
||||||
tf_trace_begin(task->_trace, "_tf_task_executeSource");
|
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)
|
if (!*task->_scriptName)
|
||||||
{
|
{
|
||||||
snprintf(task->_scriptName, sizeof(task->_scriptName), "%s", name);
|
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 global = JS_GetGlobalObject(context);
|
||||||
JSValue oldExports = JS_GetPropertyStr(context, global, "exports");
|
JSValue oldExports = JS_GetPropertyStr(context, global, "exports");
|
||||||
JS_SetPropertyStr(context, global, "exports", JS_DupValue(context, 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);
|
tf_util_report_error(context, result);
|
||||||
JS_SetPropertyStr(context, global, "exports", oldExports);
|
JS_SetPropertyStr(context, global, "exports", oldExports);
|
||||||
JS_FreeValue(context, global);
|
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 global = JS_GetGlobalObject(context);
|
||||||
JSValue oldExports = JS_GetPropertyStr(context, global, "exports");
|
JSValue oldExports = JS_GetPropertyStr(context, global, "exports");
|
||||||
JS_SetPropertyStr(context, global, "exports", JS_DupValue(context, 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);
|
tf_util_report_error(context, result);
|
||||||
JS_SetPropertyStr(context, global, "exports", oldExports);
|
JS_SetPropertyStr(context, global, "exports", oldExports);
|
||||||
JS_FreeValue(context, global);
|
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* tf_task_create()
|
||||||
{
|
{
|
||||||
tf_task_t* task = malloc(sizeof(tf_task_t));
|
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_SetHostPromiseRejectionTracker(task->_runtime, _tf_task_promise_rejection_tracker, task);
|
||||||
|
|
||||||
|
JS_SetModuleLoaderFunc(task->_runtime, NULL, _tf_task_module_loader, task);
|
||||||
|
|
||||||
JS_NewClassID(&_import_class_id);
|
JS_NewClassID(&_import_class_id);
|
||||||
JSClassDef def =
|
JSClassDef def =
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user