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,
|
||||
id: blobId,
|
||||
},
|
||||
await core.getIdentityInfo(
|
||||
await ssb.getIdentityInfo(
|
||||
credentials?.session?.name,
|
||||
packageOwner,
|
||||
packageName
|
||||
|
36
core/core.js
36
core/core.js
@ -545,7 +545,7 @@ async function getProcessBlob(blobId, key, options) {
|
||||
{
|
||||
action: 'identities',
|
||||
},
|
||||
await getIdentityInfo(
|
||||
await ssb.getIdentityInfo(
|
||||
process?.credentials?.session?.name,
|
||||
options?.packageOwner,
|
||||
options?.packageName
|
||||
@ -785,6 +785,7 @@ async function getProcessBlob(blobId, key, options) {
|
||||
);
|
||||
}
|
||||
};
|
||||
imports.ssb.getIdentityInfo = undefined;
|
||||
imports.fetch = function (url, options) {
|
||||
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 {
|
||||
gGlobalSettings as globalSettings,
|
||||
setGlobalSettings,
|
||||
enableStats,
|
||||
invoke,
|
||||
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);
|
||||
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);
|
||||
|
||||
/**
|
||||
** 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.
|
||||
** @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");
|
||||
|
||||
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_db_identity_get_active(db, request->name, request->package_owner, request->package_name, request->identity, sizeof(request->identity));
|
||||
tf_ssb_release_db_reader(request->ssb, db);
|
||||
|
||||
if (!*request->identity)
|
||||
@ -408,6 +396,149 @@ static JSValue _tf_ssb_getActiveIdentity(JSContext* context, JSValueConst this_v
|
||||
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
|
||||
{
|
||||
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, "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, "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, "blobGet", JS_NewCFunction(context, _tf_ssb_blobGet, "blobGet", 1));
|
||||
JS_SetPropertyStr(context, object, "messageContentGet", JS_NewCFunction(context, _tf_ssb_messageContentGet, "messageContentGet", 1));
|
||||
|
Loading…
Reference in New Issue
Block a user