ssb.createIdentity without hitting the database from the main thread.

This commit is contained in:
Cory McWilliams 2024-06-12 20:47:48 -04:00
parent 248b258413
commit 7997a739ab
3 changed files with 69 additions and 24 deletions

View File

@ -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) {

View File

@ -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,

View File

@ -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;
}