#include "httpd.js.h" #include "http.h" #include "mem.h" #include "ssb.db.h" #include "ssb.h" #include "task.h" #include "util.js.h" typedef struct _delete_t { tf_http_request_t* request; const char* session; int response; } delete_t; static void _httpd_endpoint_delete_work(tf_ssb_t* ssb, void* user_data) { delete_t* delete = user_data; tf_http_request_t* request = delete->request; JSMallocFunctions funcs = { 0 }; tf_get_js_malloc_functions(&funcs); JSRuntime* runtime = JS_NewRuntime2(&funcs, NULL); JSContext* context = JS_NewContext(runtime); JSValue jwt = tf_httpd_authenticate_jwt(ssb, context, delete->session); JSValue user = JS_GetPropertyStr(context, jwt, "name"); const char* user_string = JS_ToCString(context, user); if (user_string && tf_httpd_is_name_valid(user_string)) { tf_httpd_user_app_t* user_app = tf_httpd_parse_user_app_from_path(request->path, "/delete"); if (user_app) { if (strcmp(user_string, user_app->user) == 0 || (strcmp(user_app->user, "core") == 0 && tf_ssb_db_user_has_permission(ssb, NULL, user_string, "administration"))) { size_t path_length = strlen("path:") + strlen(user_app->app) + 1; char* app_path = tf_malloc(path_length); snprintf(app_path, path_length, "path:%s", user_app->app); bool changed = false; changed = tf_ssb_db_remove_value_from_array_property(ssb, user_string, "apps", user_app->app) || changed; changed = tf_ssb_db_remove_property(ssb, user_string, app_path) || changed; delete->response = changed ? 200 : 404; tf_free(app_path); } else { delete->response = 401; } } else { delete->response = 404; } tf_free(user_app); } else { delete->response = 401; } JS_FreeCString(context, user_string); JS_FreeValue(context, user); JS_FreeValue(context, jwt); JS_FreeContext(context); JS_FreeRuntime(runtime); } static void _httpd_endpoint_delete_after_work(tf_ssb_t* ssb, int status, void* user_data) { delete_t* delete = user_data; const char* k_payload = tf_http_status_text(delete->response ? delete->response : 404); tf_http_respond(delete->request, delete->response ? delete->response : 404, NULL, 0, k_payload, strlen(k_payload)); tf_http_request_unref(delete->request); tf_free((void*)delete->session); tf_free(delete); } void tf_httpd_endpoint_delete(tf_http_request_t* request) { tf_http_request_ref(request); tf_task_t* task = request->user_data; tf_ssb_t* ssb = tf_task_get_ssb(task); delete_t* delete = tf_malloc(sizeof(delete_t)); *delete = (delete_t) { .request = request, .session = tf_http_get_cookie(tf_http_request_get_header(request, "cookie"), "session"), }; tf_ssb_run_work(ssb, _httpd_endpoint_delete_work, _httpd_endpoint_delete_after_work, delete); }