From a28f6985edb9c4409d466e567548115398877aae Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sun, 5 May 2024 12:55:32 -0400 Subject: [PATCH] getActiveIdentity => C. --- core/core.js | 20 ++-------- src/ssb.js.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 17 deletions(-) diff --git a/core/core.js b/core/core.js index 234605d8..7a49fbd3 100644 --- a/core/core.js +++ b/core/core.js @@ -587,7 +587,7 @@ async function getProcessBlob(blobId, key, options) { options.packageName, 'setActiveIdentity', [ - await getActiveIdentity( + await ssb.getActiveIdentity( process.credentials?.session?.name, options.packageOwner, options.packageName @@ -696,7 +696,7 @@ async function getProcessBlob(blobId, key, options) { }; imports.ssb.setActiveIdentity = (id) => process.setActiveIdentity(id); imports.ssb.getActiveIdentity = () => - getActiveIdentity( + ssb.getActiveIdentity( process.credentials?.session?.name, options.packageOwner, options.packageName @@ -1553,19 +1553,6 @@ function storePermission(user, packageOwner, packageName, permission, allow) { } } -async function getActiveIdentity(user, packageOwner, packageName) { - if (user && packageOwner && packageName) { - let id = await new Database(user).get(`id:${packageOwner}:${packageName}`); - if (!id) { - let ids = await ssb.getIdentities(user); - if (ids) { - id = ids[0]; - } - } - return id; - } -} - async function getIdentityInfo(user, packageOwner, packageName) { let identities = await ssb.getIdentities(user); let names = new Object(); @@ -1593,7 +1580,7 @@ async function getIdentityInfo(user, packageOwner, packageName) { return { identities: identities, - identity: await getActiveIdentity(user, packageOwner, packageName), + identity: await ssb.getActiveIdentity(user, packageOwner, packageName), names: names, }; } @@ -1604,6 +1591,5 @@ export { enableStats, invoke, getSessionProcessBlob, - getActiveIdentity, getIdentityInfo, }; diff --git a/src/ssb.js.c b/src/ssb.js.c index 774345ba..6a0e219d 100644 --- a/src/ssb.js.c +++ b/src/ssb.js.c @@ -300,6 +300,114 @@ static JSValue _tf_ssb_getAllIdentities(JSContext* context, JSValueConst this_va return result; } +typedef struct _active_identity_work_t +{ + uv_work_t request; + tf_ssb_t* ssb; + JSContext* context; + const char* name; + const char* package_owner; + const char* package_name; + char identity[k_id_base64_len]; + int result; + JSValue promise[2]; +} active_identity_work_t; + +static void _tf_ssb_getActiveIdentity_visit(const char* identity, void* user_data) +{ + active_identity_work_t* request = user_data; + if (!*request->identity) + { + snprintf(request->identity, sizeof(request->identity), "%s", identity); + } +} + +static void _tf_ssb_getActiveIdentity_work(uv_work_t* work) +{ + active_identity_work_t* request = work->data; + tf_ssb_record_thread_busy(request->ssb, true); + tf_trace_t* trace = tf_ssb_get_trace(request->ssb); + tf_trace_begin(trace, "_tf_ssb_getActiveIdentity_work"); + + sqlite3* db = tf_ssb_acquire_db_reader(request->ssb); + sqlite3_stmt* statement = NULL; + request->result = sqlite3_prepare(db, "SELECT value FROM properties WHERE id = ? AND key = 'id:' || ? || ':' || ?", -1, &statement, NULL); + if (request->result == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 1, request->name, -1, NULL) == SQLITE_OK && + sqlite3_bind_text(statement, 2, request->package_owner, -1, NULL) == SQLITE_OK && + sqlite3_bind_text(statement, 3, request->package_name, -1, NULL) == SQLITE_OK && + sqlite3_step(statement) == SQLITE_ROW) + { + snprintf(request->identity, sizeof(request->identity), "%s", (const char*)sqlite3_column_text(statement, 0)); + } + sqlite3_finalize(statement); + } + tf_ssb_release_db_reader(request->ssb, db); + + if (!*request->identity) + { + tf_ssb_db_identity_visit(request->ssb, request->name, _tf_ssb_getActiveIdentity_visit, request); + } + + tf_trace_end(trace); + tf_ssb_record_thread_busy(request->ssb, false); +} + +static void _tf_ssb_getActiveIdentity_after_work(uv_work_t* work, int status) +{ + active_identity_work_t* request = work->data; + JSContext* context = request->context; + if (request->result == 0) + { + JSValue identity = JS_NewString(context, request->identity); + JSValue error = JS_Call(context, request->promise[0], JS_UNDEFINED, 1, &identity); + JS_FreeValue(context, identity); + tf_util_report_error(context, error); + JS_FreeValue(context, error); + } + else + { + JSValue error = JS_Call(context, request->promise[1], JS_UNDEFINED, 0, NULL); + tf_util_report_error(context, error); + JS_FreeValue(context, error); + } + JS_FreeValue(context, request->promise[0]); + JS_FreeValue(context, request->promise[1]); + tf_free((void*)request->name); + tf_free((void*)request->package_owner); + tf_free((void*)request->package_name); + tf_free(request); +} + +static JSValue _tf_ssb_getActiveIdentity(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ + const char* name = JS_ToCString(context, argv[0]); + const char* package_owner = JS_ToCString(context, argv[1]); + const char* package_name = JS_ToCString(context, argv[2]); + active_identity_work_t* work = tf_malloc(sizeof(active_identity_work_t)); + *work = (active_identity_work_t) + { + .request = { .data = work }, + .ssb = JS_GetOpaque(this_val, _tf_ssb_classId), + .context = context, + .name = tf_strdup(name), + .package_owner = tf_strdup(package_owner), + .package_name = tf_strdup(package_name), + }; + JSValue result = JS_NewPromiseCapability(context, work->promise); + JS_FreeCString(context, name); + JS_FreeCString(context, package_owner); + JS_FreeCString(context, package_name); + + int r = uv_queue_work(tf_ssb_get_loop(work->ssb), &work->request, _tf_ssb_getActiveIdentity_work, _tf_ssb_getActiveIdentity_after_work); + if (r) + { + _tf_ssb_getActiveIdentity_after_work(&work->request, r); + } + return result; +} + typedef struct _append_message_t { JSContext* context; @@ -1703,6 +1811,7 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb) /* Does not require an identity. */ JS_SetPropertyStr(context, object, "getServerIdentity", JS_NewCFunction(context, _tf_ssb_getServerIdentity, "getServerIdentity", 0)); JS_SetPropertyStr(context, object, "getAllIdentities", JS_NewCFunction(context, _tf_ssb_getAllIdentities, "getAllIdentities", 0)); + JS_SetPropertyStr(context, object, "getActiveIdentity", JS_NewCFunction(context, _tf_ssb_getActiveIdentity, "getActiveIdentity", 3)); JS_SetPropertyStr(context, object, "getMessage", JS_NewCFunction(context, _tf_ssb_getMessage, "getMessage", 2)); JS_SetPropertyStr(context, object, "blobGet", JS_NewCFunction(context, _tf_ssb_blobGet, "blobGet", 1)); JS_SetPropertyStr(context, object, "messageContentGet", JS_NewCFunction(context, _tf_ssb_messageContentGet, "messageContentGet", 1));