diff --git a/core/core.js b/core/core.js index 87de6c650..9ef7351a2 100644 --- a/core/core.js +++ b/core/core.js @@ -198,13 +198,6 @@ async function getProcessBlob(blobId, key, options) { core: { broadcast: broadcast.bind(process), user: getUser(process, process), - users: async function () { - try { - return JSON.parse(await new Database('auth').get('users')); - } catch { - return []; - } - }, permissionsGranted: async function () { let user = process?.credentials?.session?.name; let settings = await loadSettings(); @@ -234,10 +227,6 @@ async function getProcessBlob(blobId, key, options) { return settings.userPermissions[user]; } }, - permissionsForUser: async function (user) { - let settings = await loadSettings(); - return settings?.permissions?.[user] ?? []; - }, permissionTest: async function (permission) { let user = process?.credentials?.session?.name; let settings = await loadSettings(); diff --git a/src/api.js.c b/src/api.js.c index 5334651fc..3ad3ad346 100644 --- a/src/api.js.c +++ b/src/api.js.c @@ -147,6 +147,55 @@ static JSValue _tf_api_core_apps(JSContext* context, JSValueConst this_val, int return result; } +typedef struct _users_t +{ + const char* users; + JSContext* context; + JSValue promise[2]; +} users_t; + +static void _tf_api_core_users_work(tf_ssb_t* ssb, void* user_data) +{ + users_t* work = user_data; + work->users = tf_ssb_db_get_property(ssb, "auth", "users"); +} + +static void _tf_api_core_users_after_work(tf_ssb_t* ssb, int status, void* user_data) +{ + users_t* work = user_data; + JSContext* context = work->context; + JSValue result = JS_UNDEFINED; + if (work->users) + { + result = JS_ParseJSON(context, work->users, strlen(work->users), NULL); + tf_free((void*)work->users); + } + if (JS_IsUndefined(result)) + { + result = JS_NewArray(context); + } + JSValue error = JS_Call(context, JS_IsArray(context, result) ? work->promise[0] : work->promise[1], JS_UNDEFINED, 1, &result); + tf_util_report_error(context, error); + JS_FreeValue(context, error); + JS_FreeValue(context, result); + JS_FreeValue(context, work->promise[0]); + JS_FreeValue(context, work->promise[1]); + tf_free(work); +} + +static JSValue _tf_api_core_users(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); + users_t* work = tf_malloc(sizeof(users_t)); + *work = (users_t) { + .context = context, + }; + JSValue result = JS_NewPromiseCapability(context, work->promise); + tf_ssb_run_work(ssb, _tf_api_core_users_work, _tf_api_core_users_after_work, work); + return result; +} + static JSValue _tf_api_core_register(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* data) { JSValue event_name = argv[0]; @@ -210,6 +259,68 @@ static JSValue _tf_api_core_unregister(JSContext* context, JSValueConst this_val return JS_UNDEFINED; } +typedef struct _permissions_for_user_t +{ + const char* user; + const char* settings; + JSContext* context; + JSValue promise[2]; +} permissions_for_user_t; + +static void _tf_api_core_permissions_for_user_work(tf_ssb_t* ssb, void* user_data) +{ + permissions_for_user_t* work = user_data; + work->settings = tf_ssb_db_get_property(ssb, "core", "settings"); +} + +static void _tf_api_core_permissions_for_user_after_work(tf_ssb_t* ssb, int status, void* user_data) +{ + permissions_for_user_t* work = user_data; + JSContext* context = work->context; + JSValue result = JS_UNDEFINED; + if (work->settings) + { + JSValue json = JS_ParseJSON(context, work->settings, strlen(work->settings), NULL); + if (JS_IsObject(json)) + { + JSValue permissions = JS_GetPropertyStr(context, json, "permissions"); + if (JS_IsObject(permissions)) + { + result = JS_GetPropertyStr(context, permissions, work->user); + } + JS_FreeValue(context, permissions); + } + JS_FreeValue(context, json); + tf_free((void*)work->settings); + } + if (JS_IsUndefined(result)) + { + result = JS_NewArray(context); + } + JSValue error = JS_Call(context, JS_IsArray(context, result) ? work->promise[0] : work->promise[1], JS_UNDEFINED, 1, &result); + tf_util_report_error(context, error); + JS_FreeValue(context, error); + JS_FreeValue(context, result); + JS_FreeValue(context, work->promise[0]); + JS_FreeValue(context, work->promise[1]); + JS_FreeCString(context, work->user); + tf_free(work); +} + +static JSValue _tf_api_core_permissionsForUser(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); + permissions_for_user_t* work = tf_malloc(sizeof(permissions_for_user_t)); + *work = (permissions_for_user_t) { + .context = context, + .user = JS_ToCString(context, argv[0]), + }; + JSValue result = JS_NewPromiseCapability(context, work->promise); + tf_ssb_run_work(ssb, _tf_api_core_permissions_for_user_work, _tf_api_core_permissions_for_user_after_work, work); + return result; +} + static JSValue _tf_api_register_imports(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { JSValue imports = argv[0]; @@ -218,6 +329,10 @@ static JSValue _tf_api_register_imports(JSContext* context, JSValueConst this_va JS_SetPropertyStr(context, core, "apps", JS_NewCFunctionData(context, _tf_api_core_apps, 1, 0, 1, &process)); JS_SetPropertyStr(context, core, "register", JS_NewCFunctionData(context, _tf_api_core_register, 2, 0, 1, &process)); JS_SetPropertyStr(context, core, "unregister", JS_NewCFunctionData(context, _tf_api_core_unregister, 2, 0, 1, &process)); + + JS_SetPropertyStr(context, core, "users", JS_NewCFunctionData(context, _tf_api_core_users, 0, 0, 1, &process)); + + JS_SetPropertyStr(context, core, "permissionsForUser", JS_NewCFunctionData(context, _tf_api_core_permissionsForUser, 1, 0, 1, &process)); JS_FreeValue(context, core); return JS_UNDEFINED; }