forked from cory/tildefriends
getIdentityInfo => C.
This commit is contained in:
parent
a28f6985ed
commit
421955f2a0
@ -149,7 +149,7 @@ function socket(request, response, client) {
|
|||||||
parentApp: parentApp,
|
parentApp: parentApp,
|
||||||
id: blobId,
|
id: blobId,
|
||||||
},
|
},
|
||||||
await core.getIdentityInfo(
|
await ssb.getIdentityInfo(
|
||||||
credentials?.session?.name,
|
credentials?.session?.name,
|
||||||
packageOwner,
|
packageOwner,
|
||||||
packageName
|
packageName
|
||||||
|
36
core/core.js
36
core/core.js
@ -545,7 +545,7 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
{
|
{
|
||||||
action: 'identities',
|
action: 'identities',
|
||||||
},
|
},
|
||||||
await getIdentityInfo(
|
await ssb.getIdentityInfo(
|
||||||
process?.credentials?.session?.name,
|
process?.credentials?.session?.name,
|
||||||
options?.packageOwner,
|
options?.packageOwner,
|
||||||
options?.packageName
|
options?.packageName
|
||||||
@ -785,6 +785,7 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
imports.ssb.getIdentityInfo = undefined;
|
||||||
imports.fetch = function (url, options) {
|
imports.fetch = function (url, options) {
|
||||||
return http.fetch(url, options, gGlobalSettings.fetch_hosts);
|
return http.fetch(url, options, gGlobalSettings.fetch_hosts);
|
||||||
};
|
};
|
||||||
@ -1553,43 +1554,10 @@ function storePermission(user, packageOwner, packageName, permission, allow) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getIdentityInfo(user, packageOwner, packageName) {
|
|
||||||
let identities = await ssb.getIdentities(user);
|
|
||||||
let names = new Object();
|
|
||||||
for (let identity of identities) {
|
|
||||||
names[identity] = identity;
|
|
||||||
}
|
|
||||||
await ssb.sqlAsync(
|
|
||||||
`
|
|
||||||
SELECT author, name FROM (
|
|
||||||
SELECT
|
|
||||||
messages.author,
|
|
||||||
RANK() OVER (PARTITION BY messages.author ORDER BY messages.sequence DESC) AS author_rank,
|
|
||||||
messages.content ->> 'name' AS name
|
|
||||||
FROM messages
|
|
||||||
JOIN json_each(?) AS ids
|
|
||||||
ON messages.author = ids.value
|
|
||||||
WHERE json_extract(messages.content, '$.type') = 'about' AND content ->> 'about' = messages.author AND name IS NOT NULL)
|
|
||||||
WHERE author_rank = 1
|
|
||||||
`,
|
|
||||||
[JSON.stringify(identities)],
|
|
||||||
function (row) {
|
|
||||||
names[row.author] = row.name;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
identities: identities,
|
|
||||||
identity: await ssb.getActiveIdentity(user, packageOwner, packageName),
|
|
||||||
names: names,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
gGlobalSettings as globalSettings,
|
gGlobalSettings as globalSettings,
|
||||||
setGlobalSettings,
|
setGlobalSettings,
|
||||||
enableStats,
|
enableStats,
|
||||||
invoke,
|
invoke,
|
||||||
getSessionProcessBlob,
|
getSessionProcessBlob,
|
||||||
getIdentityInfo,
|
|
||||||
};
|
};
|
||||||
|
19
src/ssb.db.c
19
src/ssb.db.c
@ -1735,3 +1735,22 @@ bool tf_ssb_db_set_property(tf_ssb_t* ssb, const char* id, const char* key, cons
|
|||||||
tf_ssb_release_db_writer(ssb, db);
|
tf_ssb_release_db_writer(ssb, db);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tf_ssb_db_identity_get_active(sqlite3* db, const char* user, const char* package_owner, const char* package_name, char* out_identity, size_t out_identity_size)
|
||||||
|
{
|
||||||
|
sqlite3_stmt* statement = NULL;
|
||||||
|
bool found = false;
|
||||||
|
if (sqlite3_prepare(db, "SELECT value FROM properties WHERE id = ? AND key = 'id:' || ? || ':' || ?", -1, &statement, NULL) == SQLITE_OK)
|
||||||
|
{
|
||||||
|
if (sqlite3_bind_text(statement, 1, user, -1, NULL) == SQLITE_OK &&
|
||||||
|
sqlite3_bind_text(statement, 2, package_owner, -1, NULL) == SQLITE_OK &&
|
||||||
|
sqlite3_bind_text(statement, 3, package_name, -1, NULL) == SQLITE_OK &&
|
||||||
|
sqlite3_step(statement) == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
snprintf(out_identity, out_identity_size, "%s", (const char*)sqlite3_column_text(statement, 0));
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
12
src/ssb.db.h
12
src/ssb.db.h
@ -195,6 +195,18 @@ bool tf_ssb_db_identity_delete(tf_ssb_t* ssb, const char* user, const char* publ
|
|||||||
*/
|
*/
|
||||||
bool tf_ssb_db_identity_add(tf_ssb_t* ssb, const char* user, const char* public_key, const char* private_key);
|
bool tf_ssb_db_identity_add(tf_ssb_t* ssb, const char* user, const char* public_key, const char* private_key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Get the active identity for a user for a given package.
|
||||||
|
** @param db An sqlite3 database.
|
||||||
|
** @param user The username.
|
||||||
|
** @param package_owner The username of the package owner.
|
||||||
|
** @param package_name The name of the package.
|
||||||
|
** @param[out] out_identity Populated with the identity.
|
||||||
|
** @param out_identity_size The size of the out_identity buffer.
|
||||||
|
** @return true If the identity was retrieved.
|
||||||
|
*/
|
||||||
|
bool tf_ssb_db_identity_get_active(sqlite3* db, const char* user, const char* package_owner, const char* package_name, char* out_identity, size_t out_identity_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Call a function for each identity owned by a user.
|
** Call a function for each identity owned by a user.
|
||||||
** @param ssb The SSB instance.
|
** @param ssb The SSB instance.
|
||||||
|
158
src/ssb.js.c
158
src/ssb.js.c
@ -330,19 +330,7 @@ static void _tf_ssb_getActiveIdentity_work(uv_work_t* work)
|
|||||||
tf_trace_begin(trace, "_tf_ssb_getActiveIdentity_work");
|
tf_trace_begin(trace, "_tf_ssb_getActiveIdentity_work");
|
||||||
|
|
||||||
sqlite3* db = tf_ssb_acquire_db_reader(request->ssb);
|
sqlite3* db = tf_ssb_acquire_db_reader(request->ssb);
|
||||||
sqlite3_stmt* statement = NULL;
|
tf_ssb_db_identity_get_active(db, request->name, request->package_owner, request->package_name, request->identity, sizeof(request->identity));
|
||||||
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);
|
tf_ssb_release_db_reader(request->ssb, db);
|
||||||
|
|
||||||
if (!*request->identity)
|
if (!*request->identity)
|
||||||
@ -408,6 +396,149 @@ static JSValue _tf_ssb_getActiveIdentity(JSContext* context, JSValueConst this_v
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _identity_info_work_t
|
||||||
|
{
|
||||||
|
uv_work_t request;
|
||||||
|
tf_ssb_t* ssb;
|
||||||
|
JSContext* context;
|
||||||
|
const char* name;
|
||||||
|
const char* package_owner;
|
||||||
|
const char* package_name;
|
||||||
|
int count;
|
||||||
|
char** identities;
|
||||||
|
char** names;
|
||||||
|
int result;
|
||||||
|
char active_identity[k_id_base64_len];
|
||||||
|
JSValue promise[2];
|
||||||
|
} identity_info_work_t;
|
||||||
|
|
||||||
|
static void _tf_ssb_getIdentityInfo_visit(const char* identity, void* data)
|
||||||
|
{
|
||||||
|
identity_info_work_t* request = data;
|
||||||
|
request->identities = tf_resize_vec(request->identities, (request->count + 1) * sizeof(char*));
|
||||||
|
request->names = tf_resize_vec(request->names, (request->count + 1) * sizeof(char*));
|
||||||
|
request->identities[request->count] = tf_strdup(identity);
|
||||||
|
request->names[request->count] = NULL;
|
||||||
|
request->count++;;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _tf_ssb_getIdentityInfo_work(uv_work_t* work)
|
||||||
|
{
|
||||||
|
identity_info_work_t* request = work->data;
|
||||||
|
tf_ssb_db_identity_visit(request->ssb, request->name, _tf_ssb_getIdentityInfo_visit, request);
|
||||||
|
|
||||||
|
sqlite3* db = tf_ssb_acquire_db_reader(request->ssb);
|
||||||
|
sqlite3_stmt* statement = NULL;
|
||||||
|
request->result = sqlite3_prepare(db,
|
||||||
|
"SELECT author, name FROM ( "
|
||||||
|
" SELECT "
|
||||||
|
" messages.author, "
|
||||||
|
" RANK() OVER (PARTITION BY messages.author ORDER BY messages.sequence DESC) AS author_rank, "
|
||||||
|
" messages.content ->> 'name' AS name "
|
||||||
|
" FROM messages "
|
||||||
|
" JOIN identities ON messages.author = ids.value "
|
||||||
|
" WHERE WHERE identities.user = ? AND json_extract(messages.content, '$.type') = 'about' AND content ->> 'about' = messages.author AND name IS NOT NULL) "
|
||||||
|
"WHERE author_rank = 1 ", -1, &statement, NULL);
|
||||||
|
if (request->result == SQLITE_OK)
|
||||||
|
{
|
||||||
|
if (sqlite3_bind_text(statement, 1, request->name, -1, NULL) == SQLITE_OK)
|
||||||
|
{
|
||||||
|
int r = SQLITE_OK;
|
||||||
|
while ((r = sqlite3_step(statement)) == SQLITE_OK)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < request->count; i++)
|
||||||
|
{
|
||||||
|
const char* identity = (const char*)sqlite3_column_text(statement, 0);
|
||||||
|
const char* name = (const char*)sqlite3_column_text(statement, 1);
|
||||||
|
if (strcmp(request->identities[i], identity) == 0 && !request->names[i])
|
||||||
|
{
|
||||||
|
request->names[i] = tf_strdup(name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
}
|
||||||
|
|
||||||
|
tf_ssb_db_identity_get_active(db, request->name, request->package_owner, request->package_name, request->active_identity, sizeof(request->active_identity));
|
||||||
|
if (!*request->active_identity && request->count)
|
||||||
|
{
|
||||||
|
snprintf(request->active_identity, sizeof(request->active_identity), "%s", request->identities[0]);
|
||||||
|
}
|
||||||
|
tf_ssb_release_db_reader(request->ssb, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _tf_ssb_getIdentityInfo_after_work(uv_work_t* work, int status)
|
||||||
|
{
|
||||||
|
identity_info_work_t* request = work->data;
|
||||||
|
JSContext* context = request->context;
|
||||||
|
JSValue result = JS_NewObject(context);
|
||||||
|
|
||||||
|
JSValue identities = JS_NewArray(context);
|
||||||
|
for (int i = 0; i < request->count; i++)
|
||||||
|
{
|
||||||
|
JS_SetPropertyUint32(context, identities, i, JS_NewString(context, request->identities[i]));
|
||||||
|
}
|
||||||
|
JS_SetPropertyStr(context, result, "identities", identities);
|
||||||
|
|
||||||
|
JSValue names = JS_NewObject(context);
|
||||||
|
for (int i = 0; i < request->count; i++)
|
||||||
|
{
|
||||||
|
JS_SetPropertyStr(context, names, request->identities[i], JS_NewString(context, request->names[i] ? request->names[i] : request->identities[i]));
|
||||||
|
}
|
||||||
|
JS_SetPropertyStr(context, result, "names", names);
|
||||||
|
|
||||||
|
JS_SetPropertyStr(context, result, "identity", JS_NewString(context, request->active_identity));
|
||||||
|
|
||||||
|
JSValue error = JS_Call(context, request->promise[0], JS_UNDEFINED, 1, &result);
|
||||||
|
tf_util_report_error(context, error);
|
||||||
|
JS_FreeValue(context, error);
|
||||||
|
JS_FreeValue(context, result);
|
||||||
|
JS_FreeValue(context, request->promise[0]);
|
||||||
|
JS_FreeValue(context, request->promise[1]);
|
||||||
|
|
||||||
|
for (int i = 0; i < request->count; i++)
|
||||||
|
{
|
||||||
|
tf_free(request->identities[i]);
|
||||||
|
tf_free(request->names[i]);
|
||||||
|
}
|
||||||
|
tf_free(request->identities);
|
||||||
|
tf_free(request->names);
|
||||||
|
tf_free((void*)request->name);
|
||||||
|
tf_free((void*)request->package_owner);
|
||||||
|
tf_free((void*)request->package_name);
|
||||||
|
tf_free(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue _tf_ssb_getIdentityInfo(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]);
|
||||||
|
identity_info_work_t* work = tf_malloc(sizeof(identity_info_work_t));
|
||||||
|
*work = (identity_info_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_getIdentityInfo_work, _tf_ssb_getIdentityInfo_after_work);
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
_tf_ssb_getIdentityInfo_after_work(&work->request, r);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct _append_message_t
|
typedef struct _append_message_t
|
||||||
{
|
{
|
||||||
JSContext* context;
|
JSContext* context;
|
||||||
@ -1812,6 +1943,7 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
|
|||||||
JS_SetPropertyStr(context, object, "getServerIdentity", JS_NewCFunction(context, _tf_ssb_getServerIdentity, "getServerIdentity", 0));
|
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, "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, "getActiveIdentity", JS_NewCFunction(context, _tf_ssb_getActiveIdentity, "getActiveIdentity", 3));
|
||||||
|
JS_SetPropertyStr(context, object, "getIdentityInfo", JS_NewCFunction(context, _tf_ssb_getIdentityInfo, "getIdentityInfo", 3));
|
||||||
JS_SetPropertyStr(context, object, "getMessage", JS_NewCFunction(context, _tf_ssb_getMessage, "getMessage", 2));
|
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, "blobGet", JS_NewCFunction(context, _tf_ssb_blobGet, "blobGet", 1));
|
||||||
JS_SetPropertyStr(context, object, "messageContentGet", JS_NewCFunction(context, _tf_ssb_messageContentGet, "messageContentGet", 1));
|
JS_SetPropertyStr(context, object, "messageContentGet", JS_NewCFunction(context, _tf_ssb_messageContentGet, "messageContentGet", 1));
|
||||||
|
Loading…
Reference in New Issue
Block a user