diff --git a/core/app.js b/core/app.js index d0a9a625..839e9137 100644 --- a/core/app.js +++ b/core/app.js @@ -222,7 +222,7 @@ async function socket(request, response, client) { } else if (message.action == 'setActiveIdentity') { process.setActiveIdentity(message.identity); } else if (message.action == 'createIdentity') { - process.createIdentity(); + await process.createIdentity(); } else if (message.message == 'tfrpc') { if (message.id && g_calls[message.id]) { if (message.error !== undefined) { diff --git a/core/core.js b/core/core.js index 97d5eb89..90dc246b 100644 --- a/core/core.js +++ b/core/core.js @@ -472,7 +472,7 @@ async function getProcessBlob(blobId, key, options) { process.credentials.session.name && process.credentials.session.name !== 'guest' ) { - let id = ssb.createIdentity(process.credentials.session.name); + let id = await ssb.createIdentity(process.credentials.session.name); await process.sendIdentities(); broadcastAppEventToUser( process?.credentials?.session?.name, diff --git a/src/ssb.js.c b/src/ssb.js.c index f5a97e47..9b306604 100644 --- a/src/ssb.js.c +++ b/src/ssb.js.c @@ -30,35 +30,80 @@ static JSClassID _tf_ssb_classId; static JSValue _tf_ssb_appendMessageWithIdentity(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); +typedef struct _create_identity_t +{ + char id[k_id_base64_len]; + bool error_add; + bool error_too_many; + JSValue promise[2]; + char user[]; +} create_identity_t; + +static void _tf_ssb_create_identity_work(tf_ssb_t* ssb, void* user_data) +{ + create_identity_t* work = user_data; + int count = tf_ssb_db_identity_get_count_for_user(ssb, work->user); + if (count < 16) + { + char public[k_id_base64_len - 1]; + char private[512]; + tf_ssb_generate_keys_buffer(public, sizeof(public), private, sizeof(private)); + if (tf_ssb_db_identity_add(ssb, work->user, public, private)) + { + snprintf(work->id, sizeof(work->id), "@%s", public); + } + else + { + work->error_add = true; + } + } + else + { + work->error_too_many = true; + } +} + +static void _tf_ssb_create_identity_after_work(tf_ssb_t* ssb, int status, void* user_data) +{ + JSContext* context = tf_ssb_get_context(ssb); + JSValue result = JS_UNDEFINED; + create_identity_t* work = user_data; + if (work->error_too_many) + { + result = JS_ThrowInternalError(context, "Too many identities for user."); + } + else if (work->error_add) + { + result = JS_ThrowInternalError(context, "Unable to add identity."); + } + else + { + result = JS_NewString(context, work->id); + } + + 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_createIdentity(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); JSValue result = JS_UNDEFINED; if (ssb) { - const char* user = JS_ToCString(context, argv[0]); - int count = tf_ssb_db_identity_get_count_for_user(ssb, user); - if (count < 16) - { - char public[512]; - char private[512]; - tf_ssb_generate_keys_buffer(public, sizeof(public), private, sizeof(private)); - if (tf_ssb_db_identity_add(ssb, user, public, private)) - { - char id[513]; - snprintf(id, sizeof(id), "@%s", public); - result = JS_NewString(context, id); - } - else - { - result = JS_ThrowInternalError(context, "Unable to add identity."); - } - } - else - { - result = JS_ThrowInternalError(context, "Too many identities for user."); - } + size_t length = 0; + const char* user = JS_ToCStringLen(context, &length, argv[0]); + create_identity_t* work = tf_malloc(sizeof(create_identity_t) + length + 1); + *work = (create_identity_t) { 0 }; + memcpy(work->user, user, length + 1); JS_FreeCString(context, user); + result = JS_NewPromiseCapability(context, work->promise); + tf_ssb_run_work(ssb, _tf_ssb_create_identity_work, _tf_ssb_create_identity_after_work, work); } return result; }