From c26bf5c112a40f77055056607c557a0d70e1c264 Mon Sep 17 00:00:00 2001
From: Cory McWilliams <cory@unprompted.com>
Date: Mon, 14 Apr 2025 12:41:00 -0400
Subject: [PATCH] core: Setting and resetting user app permissions was all
 sorts of broken.

---
 src/ssb.js.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/src/ssb.js.c b/src/ssb.js.c
index c1ccda008..ed9981a71 100644
--- a/src/ssb.js.c
+++ b/src/ssb.js.c
@@ -2199,6 +2199,7 @@ typedef struct _set_user_permission_t
 	const char* package_name;
 	const char* permission;
 	bool allow;
+	bool reset;
 	bool result;
 	JSValue promise[2];
 } set_user_permission_t;
@@ -2239,22 +2240,31 @@ static void _tf_ssb_set_user_permission_work(tf_ssb_t* ssb, void* user_data)
 		if (JS_IsUndefined(package_name))
 		{
 			package_name = JS_NewObject(context);
-			JS_SetPropertyStr(context, package_owner, work->package_name, package_name);
+			JS_SetPropertyStr(context, package_owner, work->package_name, JS_DupValue(context, package_name));
 		}
 		JSValue permission = JS_GetPropertyStr(context, package_name, work->permission);
-		if (JS_ToBool(context, permission) != work->allow)
+		if (work->reset)
 		{
-			JS_SetPropertyStr(context, package_name, work->permission, JS_NewBool(context, work->allow));
-			JSValue settings_json = JS_JSONStringify(context, settings_value, JS_NULL, JS_NULL);
-			const char* settings_string = JS_ToCString(context, settings_json);
-			work->result = tf_ssb_db_set_property(ssb, "core", "settings", settings_string);
-			JS_FreeCString(context, settings_string);
-			JS_FreeValue(context, settings_json);
+			JSAtom atom = JS_NewAtom(context, work->permission);
+			JS_DeleteProperty(context, package_name, atom, 0);
+			JS_FreeAtom(context, atom);
 		}
 		else
 		{
-			work->result = true;
+			JS_SetPropertyStr(context, package_name, work->permission, JS_NewBool(context, work->allow));
 		}
+		JSValue settings_json = JS_JSONStringify(context, settings_value, JS_NULL, JS_NULL);
+		const char* settings_string = JS_ToCString(context, settings_json);
+		work->result = tf_ssb_db_set_property(ssb, "core", "settings", settings_string);
+		JS_FreeCString(context, settings_string);
+		JS_FreeValue(context, settings_json);
+		JS_FreeValue(context, permission);
+		JS_FreeValue(context, package_owner);
+		JS_FreeValue(context, package_name);
+		JS_FreeValue(context, user);
+		JS_FreeValue(context, user_permissions);
+		JS_FreeValue(context, settings_value);
+		tf_free((void*)settings);
 	}
 
 	JS_FreeContext(context);
@@ -2288,6 +2298,7 @@ static JSValue _tf_ssb_set_user_permission(JSContext* context, JSValueConst this
 		.package_name = JS_ToCString(context, argv[2]),
 		.permission = JS_ToCString(context, argv[3]),
 		.allow = JS_ToBool(context, argv[4]),
+		.reset = JS_IsUndefined(argv[4]),
 	};
 	JSValue result = JS_NewPromiseCapability(context, set->promise);
 	tf_ssb_run_work(set->ssb, _tf_ssb_set_user_permission_work, _tf_ssb_set_user_permission_after_work, set);