From 94858e2371d0c5fe02eae535b2036f91fe7eb271 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Wed, 8 Oct 2025 19:13:54 -0400 Subject: [PATCH] core: ssb.getIdentities() + ssb.getOwnerIdentities() JS => C. --- core/core.js | 14 ----- src/api.js.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++---- src/ssb.js.c | 98 -------------------------------- 3 files changed, 147 insertions(+), 123 deletions(-) diff --git a/core/core.js b/core/core.js index d1bc75d3..10536451 100644 --- a/core/core.js +++ b/core/core.js @@ -446,20 +446,6 @@ async function getProcessBlob(blobId, key, options) { } }; imports.ssb.setActiveIdentity = (id) => process.setActiveIdentity(id); - imports.ssb.getOwnerIdentities = function () { - if (options.packageOwner) { - return ssb.getIdentities(options.packageOwner); - } - }; - imports.ssb.getIdentities = function () { - if ( - process.credentials && - process.credentials.session && - process.credentials.session.name - ) { - return ssb.getIdentities(process.credentials.session.name); - } - }; imports.ssb.getPrivateKey = function (id) { if ( process.credentials && diff --git a/src/api.js.c b/src/api.js.c index 44396382..f434116a 100644 --- a/src/api.js.c +++ b/src/api.js.c @@ -385,18 +385,29 @@ static void _tf_ssb_getActiveIdentity_after_work(tf_ssb_t* ssb, int status, void tf_free(request); } +static const char* _tf_ssb_get_process_credentials_session_name(JSContext* context, JSValue process) +{ + JSValue credentials = JS_IsObject(process) ? JS_GetPropertyStr(context, process, "credentials") : JS_UNDEFINED; + JSValue session = JS_IsObject(credentials) ? JS_GetPropertyStr(context, credentials, "session") : JS_UNDEFINED; + JSValue name_value = JS_IsObject(session) ? JS_GetPropertyStr(context, session, "name") : JS_UNDEFINED; + const char* name = JS_ToCString(context, name_value); + const char* result = tf_strdup(name); + JS_FreeCString(context, name); + JS_FreeValue(context, name_value); + JS_FreeValue(context, session); + JS_FreeValue(context, credentials); + return result; +} + static JSValue _tf_ssb_getActiveIdentity(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* data) { tf_task_t* task = tf_task_get(context); tf_ssb_t* ssb = tf_task_get_ssb(task); JSValue process = data[0]; - JSValue credentials = JS_IsObject(process) ? JS_GetPropertyStr(context, process, "credentials") : JS_UNDEFINED; - JSValue session = JS_IsObject(credentials) ? JS_GetPropertyStr(context, credentials, "session") : JS_UNDEFINED; - JSValue name_value = JS_IsObject(session) ? JS_GetPropertyStr(context, session, "name") : JS_UNDEFINED; JSValue package_owner_value = JS_GetPropertyStr(context, process, "packageOwner"); JSValue package_name_value = JS_GetPropertyStr(context, process, "packageName"); - const char* name = JS_ToCString(context, name_value); + const char* name = _tf_ssb_get_process_credentials_session_name(context, process); const char* package_owner = JS_ToCString(context, package_owner_value); const char* package_name = JS_ToCString(context, package_name_value); active_identity_work_t* work = tf_malloc(sizeof(active_identity_work_t)); @@ -407,20 +418,143 @@ static JSValue _tf_ssb_getActiveIdentity(JSContext* context, JSValueConst this_v .package_name = tf_strdup(package_name), }; JSValue result = JS_NewPromiseCapability(context, work->promise); - JS_FreeCString(context, name); + tf_free((void*)name); JS_FreeCString(context, package_owner); JS_FreeCString(context, package_name); JS_FreeValue(context, package_owner_value); JS_FreeValue(context, package_name_value); - JS_FreeValue(context, name_value); - JS_FreeValue(context, session); - JS_FreeValue(context, credentials); - tf_ssb_run_work(ssb, _tf_ssb_getActiveIdentity_work, _tf_ssb_getActiveIdentity_after_work, work); return result; } +typedef struct _identities_visit_t +{ + JSContext* context; + JSValue promise[2]; + const char** identities; + int count; + char user[]; +} identities_visit_t; + +static void _tf_ssb_getIdentities_visit(const char* identity, void* user_data) +{ + identities_visit_t* work = user_data; + work->identities = tf_resize_vec(work->identities, (work->count + 1) * sizeof(const char*)); + char id[k_id_base64_len]; + snprintf(id, sizeof(id), "@%s", identity); + work->identities[work->count++] = tf_strdup(id); +} + +static void _tf_ssb_get_all_identities_work(tf_ssb_t* ssb, void* user_data) +{ + tf_ssb_db_identity_visit_all(ssb, _tf_ssb_getIdentities_visit, user_data); +} + +static void _tf_ssb_get_identities_after_work(tf_ssb_t* ssb, int status, void* user_data) +{ + identities_visit_t* work = user_data; + JSContext* context = tf_ssb_get_context(ssb); + JSValue result = JS_NewArray(context); + for (int i = 0; i < work->count; i++) + { + JS_SetPropertyUint32(context, result, i, JS_NewString(context, work->identities[i])); + tf_free((void*)work->identities[i]); + } + tf_free(work->identities); + + JSValue error = JS_Call(context, work->promise[0], JS_UNDEFINED, 1, &result); + JS_FreeValue(context, result); + tf_util_report_error(context, error); + JS_FreeValue(context, error); + JS_FreeValue(context, work->promise[0]); + JS_FreeValue(context, work->promise[1]); + tf_free(work); +} + +static JSValue _tf_ssb_getAllIdentities(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ + JSValue result = JS_UNDEFINED; + tf_task_t* task = tf_task_get(context); + tf_ssb_t* ssb = tf_task_get_ssb(task); + if (ssb) + { + identities_visit_t* work = tf_malloc(sizeof(identities_visit_t)); + *work = (identities_visit_t) { + .context = context, + }; + + result = JS_NewPromiseCapability(context, work->promise); + tf_ssb_run_work(ssb, _tf_ssb_get_all_identities_work, _tf_ssb_get_identities_after_work, work); + } + return result; +} + +static void _tf_ssb_get_identities_work(tf_ssb_t* ssb, void* user_data) +{ + identities_visit_t* work = user_data; + if (tf_ssb_db_user_has_permission(ssb, NULL, work->user, "administration")) + { + char id[k_id_base64_len] = ""; + if (tf_ssb_whoami(ssb, id, sizeof(id))) + { + _tf_ssb_getIdentities_visit(*id == '@' ? id + 1 : id, work); + } + } + tf_ssb_db_identity_visit(ssb, work->user, _tf_ssb_getIdentities_visit, user_data); +} + +static JSValue _tf_ssb_getIdentities(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* data) +{ + JSValue result = JS_UNDEFINED; + tf_task_t* task = tf_task_get(context); + tf_ssb_t* ssb = tf_task_get_ssb(task); + JSValue process = data[0]; + if (ssb) + { + const char* user = _tf_ssb_get_process_credentials_session_name(context, process); + if (user) + { + size_t user_length = user ? strlen(user) : 0; + identities_visit_t* work = tf_malloc(sizeof(identities_visit_t) + user_length + 1); + *work = (identities_visit_t) { + .context = context, + }; + memcpy(work->user, user, user_length + 1); + tf_free((void*)user); + + result = JS_NewPromiseCapability(context, work->promise); + tf_ssb_run_work(ssb, _tf_ssb_get_identities_work, _tf_ssb_get_identities_after_work, work); + } + } + return result; +} + +static JSValue _tf_ssb_getOwnerIdentities(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* data) +{ + JSValue result = JS_UNDEFINED; + tf_task_t* task = tf_task_get(context); + tf_ssb_t* ssb = tf_task_get_ssb(task); + JSValue process = data[0]; + if (ssb) + { + JSValue value = JS_GetPropertyStr(context, process, "packageOwner"); + const char* user = JS_ToCString(context, value); + size_t user_length = user ? strlen(user) : 0; + identities_visit_t* work = tf_malloc(sizeof(identities_visit_t) + user_length + 1); + *work = (identities_visit_t) { + .context = context, + }; + memcpy(work->user, user, user_length + 1); + JS_FreeCString(context, user); + JS_FreeValue(context, value); + + result = JS_NewPromiseCapability(context, work->promise); + tf_ssb_run_work(ssb, _tf_ssb_get_identities_work, _tf_ssb_get_identities_after_work, work); + } + return result; +} + static JSValue _tf_api_register_imports(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { JSValue imports = argv[0]; @@ -442,8 +576,10 @@ static JSValue _tf_api_register_imports(JSContext* context, JSValueConst this_va JS_SetPropertyStr(context, core, "url", JS_GetPropertyStr(context, process, "url")); JSValue ssb = JS_GetPropertyStr(context, imports, "ssb"); - ; - JS_SetPropertyStr(context, ssb, "getActiveIdentity", JS_NewCFunctionData(context, _tf_ssb_getActiveIdentity, 3, 0, 1, &process)); + JS_SetPropertyStr(context, ssb, "getAllIdentities", JS_NewCFunction(context, _tf_ssb_getAllIdentities, "getAllIdentities", 0)); + JS_SetPropertyStr(context, ssb, "getActiveIdentity", JS_NewCFunctionData(context, _tf_ssb_getActiveIdentity, 0, 0, 1, &process)); + JS_SetPropertyStr(context, ssb, "getIdentities", JS_NewCFunctionData(context, _tf_ssb_getIdentities, 0, 0, 1, &process)); + JS_SetPropertyStr(context, ssb, "getOwnerIdentities", JS_NewCFunctionData(context, _tf_ssb_getOwnerIdentities, 0, 0, 1, &process)); JS_FreeValue(context, ssb); JS_FreeValue(context, core); diff --git a/src/ssb.js.c b/src/ssb.js.c index 229425f3..eb192729 100644 --- a/src/ssb.js.c +++ b/src/ssb.js.c @@ -363,85 +363,6 @@ static JSValue _tf_ssb_swap_with_server_identity(JSContext* context, JSValueCons return result; } -typedef struct _identities_visit_t -{ - JSContext* context; - JSValue promise[2]; - const char** identities; - int count; - char user[]; -} identities_visit_t; - -static void _tf_ssb_getIdentities_visit(const char* identity, void* user_data) -{ - identities_visit_t* work = user_data; - work->identities = tf_resize_vec(work->identities, (work->count + 1) * sizeof(const char*)); - char id[k_id_base64_len]; - snprintf(id, sizeof(id), "@%s", identity); - work->identities[work->count++] = tf_strdup(id); -} - -static void _tf_ssb_get_identities_work(tf_ssb_t* ssb, void* user_data) -{ - identities_visit_t* work = user_data; - if (tf_ssb_db_user_has_permission(ssb, NULL, work->user, "administration")) - { - char id[k_id_base64_len] = ""; - if (tf_ssb_whoami(ssb, id, sizeof(id))) - { - _tf_ssb_getIdentities_visit(*id == '@' ? id + 1 : id, work); - } - } - tf_ssb_db_identity_visit(ssb, work->user, _tf_ssb_getIdentities_visit, user_data); -} - -static void _tf_ssb_get_all_identities_work(tf_ssb_t* ssb, void* user_data) -{ - tf_ssb_db_identity_visit_all(ssb, _tf_ssb_getIdentities_visit, user_data); -} - -static void _tf_ssb_get_identities_after_work(tf_ssb_t* ssb, int status, void* user_data) -{ - identities_visit_t* work = user_data; - JSContext* context = tf_ssb_get_context(ssb); - JSValue result = JS_NewArray(context); - for (int i = 0; i < work->count; i++) - { - JS_SetPropertyUint32(context, result, i, JS_NewString(context, work->identities[i])); - tf_free((void*)work->identities[i]); - } - tf_free(work->identities); - - JSValue error = JS_Call(context, work->promise[0], JS_UNDEFINED, 1, &result); - JS_FreeValue(context, result); - tf_util_report_error(context, error); - JS_FreeValue(context, error); - JS_FreeValue(context, work->promise[0]); - JS_FreeValue(context, work->promise[1]); - tf_free(work); -} - -static JSValue _tf_ssb_getIdentities(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) -{ - JSValue result = JS_UNDEFINED; - tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) - { - size_t user_length = 0; - const char* user = JS_ToCStringLen(context, &user_length, argv[0]); - identities_visit_t* work = tf_malloc(sizeof(identities_visit_t) + user_length + 1); - *work = (identities_visit_t) { - .context = context, - }; - memcpy(work->user, user, user_length + 1); - JS_FreeCString(context, user); - - result = JS_NewPromiseCapability(context, work->promise); - tf_ssb_run_work(ssb, _tf_ssb_get_identities_work, _tf_ssb_get_identities_after_work, work); - } - return result; -} - typedef struct _get_private_key_t { JSContext* context; @@ -513,23 +434,6 @@ static JSValue _tf_ssb_getServerIdentity(JSContext* context, JSValueConst this_v return result; } -static JSValue _tf_ssb_getAllIdentities(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) -{ - JSValue result = JS_UNDEFINED; - tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); - if (ssb) - { - identities_visit_t* work = tf_malloc(sizeof(identities_visit_t)); - *work = (identities_visit_t) { - .context = context, - }; - - result = JS_NewPromiseCapability(context, work->promise); - tf_ssb_run_work(ssb, _tf_ssb_get_all_identities_work, _tf_ssb_get_identities_after_work, work); - } - return result; -} - typedef struct _identity_info_work_t { JSContext* context; @@ -2293,7 +2197,6 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb) JS_SetPropertyStr(context, object, "addIdentity", JS_NewCFunction(context, _tf_ssb_addIdentity, "addIdentity", 2)); JS_SetPropertyStr(context, object, "deleteIdentity", JS_NewCFunction(context, _tf_ssb_deleteIdentity, "deleteIdentity", 2)); JS_SetPropertyStr(context, object, "swapWithServerIdentity", JS_NewCFunction(context, _tf_ssb_swap_with_server_identity, "swapWithServerIdentity", 2)); - JS_SetPropertyStr(context, object, "getIdentities", JS_NewCFunction(context, _tf_ssb_getIdentities, "getIdentities", 1)); JS_SetPropertyStr(context, object, "getPrivateKey", JS_NewCFunction(context, _tf_ssb_getPrivateKey, "getPrivateKey", 2)); JS_SetPropertyStr(context, object, "privateMessageEncrypt", JS_NewCFunction(context, _tf_ssb_private_message_encrypt, "privateMessageEncrypt", 4)); JS_SetPropertyStr(context, object, "privateMessageDecrypt", JS_NewCFunction(context, _tf_ssb_private_message_decrypt, "privateMessageDecrypt", 3)); @@ -2303,7 +2206,6 @@ 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, "blobGet", JS_NewCFunction(context, _tf_ssb_blobGet, "blobGet", 1)); JS_SetPropertyStr(context, object, "connections", JS_NewCFunction(context, _tf_ssb_connections, "connections", 0)); JS_SetPropertyStr(context, object, "storedConnections", JS_NewCFunction(context, _tf_ssb_storedConnections, "storedConnections", 0));