diff --git a/core/app.js b/core/app.js index c59737be..9f9f520d 100644 --- a/core/app.js +++ b/core/app.js @@ -79,7 +79,6 @@ App.prototype.send = function (message) { */ exports.app_socket = async function socket(request, response) { let process; - let options = {}; let credentials = await httpd.auth_query(request.headers); response.onClose = async function () { @@ -150,12 +149,6 @@ exports.app_socket = async function socket(request, response) { 0x1 ); - options.api = message.api || []; - options.credentials = credentials; - options.packageOwner = packageOwner; - options.packageName = packageName; - options.url = message.url; - let sessionId = 'session_' + (g_session_index++).toString(); if (blobId) { if (message.edit_only) { response.send( @@ -167,6 +160,14 @@ exports.app_socket = async function socket(request, response) { 0x1 ); } else { + let sessionId = 'session_' + (g_session_index++).toString(); + let options = { + api: message.api || [], + credentials: credentials, + packageOwner: packageOwner, + packageName: packageName, + url: message.url, + }; process = await core.getProcessBlob(blobId, sessionId, options); } } diff --git a/src/httpd.app.c b/src/httpd.app.c index 76e08d86..d9a6cbc3 100644 --- a/src/httpd.app.c +++ b/src/httpd.app.c @@ -250,19 +250,20 @@ typedef struct _app_hello_t const char* path; char blob_id[k_id_base64_len]; tf_ssb_identity_info_t* identity_info; + tf_httpd_user_app_t* user_app; } app_hello_t; static void _httpd_app_hello_work(tf_ssb_t* ssb, void* user_data) { app_hello_t* work = user_data; - tf_httpd_user_app_t* user_app = tf_httpd_parse_user_app_from_path(work->path, NULL); - if (user_app) + work->user_app = tf_httpd_parse_user_app_from_path(work->path, NULL); + if (work->user_app) { - size_t length = strlen("path:") + strlen(user_app->app) + 1; + size_t length = strlen("path:") + strlen(work->user_app->app) + 1; char* key = alloca(length); - snprintf(key, length, "path:%s", user_app->app); - const char* value = tf_ssb_db_get_property(ssb, user_app->user, key); + snprintf(key, length, "path:%s", work->user_app->app); + const char* value = tf_ssb_db_get_property(ssb, work->user_app->user, key); tf_string_set(work->blob_id, sizeof(work->blob_id), value); tf_free((void*)value); } @@ -273,9 +274,8 @@ static void _httpd_app_hello_work(tf_ssb_t* ssb, void* user_data) if (*work->blob_id) { - work->identity_info = tf_ssb_db_get_identity_info(ssb, work->user, user_app ? user_app->user : NULL, user_app ? user_app->app : NULL); + work->identity_info = tf_ssb_db_get_identity_info(ssb, work->user, work->user_app ? work->user_app->user : NULL, work->user_app ? work->user_app->app : NULL); } - tf_free(user_app); } static void _http_json_send(tf_http_request_t* request, JSContext* context, JSValue value) @@ -335,6 +335,61 @@ static void _httpd_app_hello_after_work(tf_ssb_t* ssb, int status, void* user_da } _http_json_send(work->app->request, context, object); JS_FreeValue(context, object); + + JSValue edit_only = JS_GetPropertyStr(context, work->message, "edit_only"); + bool is_edit_only = JS_ToBool(context, edit_only) > 0; + JS_FreeValue(context, edit_only); + + if (is_edit_only) + { + JSValue global = JS_GetGlobalObject(context); + JSValue version = JS_GetPropertyStr(context, global, "version"); + JS_FreeValue(context, global); + + JSValue ready = JS_NewObject(context); + JS_SetPropertyStr(context, ready, "action", JS_NewString(context, "ready")); + JS_SetPropertyStr(context, ready, "version", JS_Call(context, version, JS_NULL, 0, NULL)); + JS_SetPropertyStr(context, ready, "edit_only", JS_TRUE); + _http_json_send(work->app->request, context, ready); + JS_FreeValue(context, ready); + JS_FreeValue(context, version); + } + else + { + JSValue options = JS_NewObject(context); + JSValue api = JS_GetPropertyStr(context, work->message, "api"); + JS_SetPropertyStr(context, options, "api", JS_IsUndefined(api) ? JS_NewArray(context) : api); + JS_SetPropertyStr(context, options, "credentials", JS_DupValue(context, work->app->credentials)); + JS_SetPropertyStr(context, options, "packageOwner", work->user_app ? JS_NewString(context, work->user_app->user) : JS_UNDEFINED); + JS_SetPropertyStr(context, options, "packageName", work->user_app ? JS_NewString(context, work->user_app->app) : JS_UNDEFINED); + JS_SetPropertyStr(context, options, "url", JS_GetPropertyStr(context, work->message, "url")); + + JSValue global = JS_GetGlobalObject(context); + JSValue exports = JS_GetPropertyStr(context, global, "exports"); + JSValue get_process_blob = JS_GetPropertyStr(context, exports, "getProcessBlob"); + + static int64_t s_session_id; + char session_id[64]; + snprintf(session_id, sizeof(session_id), "app_%" PRId64, ++s_session_id); + + JSValue args[] = { + JS_NewString(context, work->blob_id), + JS_NewString(context, session_id), + options, + }; + JSValue result = JS_Call(context, get_process_blob, JS_UNDEFINED, tf_countof(args), args); + tf_util_report_error(context, result); + JS_FreeValue(context, result); + + JS_FreeValue(context, get_process_blob); + JS_FreeValue(context, exports); + JS_FreeValue(context, global); + + for (int i = 0; i < tf_countof(args); i++) + { + JS_FreeValue(context, args[i]); + } + } } tf_http_request_unref(work->app->request); @@ -342,6 +397,7 @@ static void _httpd_app_hello_after_work(tf_ssb_t* ssb, int status, void* user_da JS_FreeCString(context, work->path); JS_FreeValue(context, work->message); tf_free(work->identity_info); + tf_free(work->user_app); tf_free(work); } @@ -370,8 +426,8 @@ static bool _httpd_app_message_call_client_api(app_t* work, JSValue message, con { bool called = false; JSContext* context = work->request->context; - JSValue client_api = JS_GetPropertyStr(context, work->process, "client_api"); - JSValue callback = JS_GetPropertyStr(context, client_api, action_string); + JSValue client_api = JS_IsObject(work->process) ? JS_GetPropertyStr(context, work->process, "client_api") : JS_UNDEFINED; + JSValue callback = JS_IsObject(client_api) ? JS_GetPropertyStr(context, client_api, action_string) : JS_UNDEFINED; if (!JS_IsUndefined(callback)) { JSValue result = JS_Call(context, callback, JS_NULL, 1, &message);