diff --git a/plugin/src/App/StatusPages/Permissions/init.lua b/plugin/src/App/StatusPages/Permissions/init.lua index 5d10736f..2a553d9f 100644 --- a/plugin/src/App/StatusPages/Permissions/init.lua +++ b/plugin/src/App/StatusPages/Permissions/init.lua @@ -64,6 +64,20 @@ local PermissionsPage = Roact.Component:extend("PermissionsPage") function PermissionsPage:init() self.contentSize, self.setContentSize = Roact.createBinding(Vector2.new(0, 0)) + + self:setState({ + permissions = self.props.headlessAPI._permissions, + }) + + self.changedListener = self.props.headlessAPI._permissionsChanged:Connect(function() + self:setState({ + permissions = self.props.headlessAPI._permissions, + }) + end) +end + +function PermissionsPage:willUnmount() + self.changedListener:Disconnect() end function PermissionsPage:render() @@ -71,7 +85,7 @@ function PermissionsPage:render() theme = theme.Settings local sources = {} - if next(self.props.headlessAPI._permissions) == nil then + if next(self.state.permissions) == nil then sources.noSources = e("TextLabel", { Text = "No third-party plugins have been granted permissions.", Font = Enum.Font.Gotham, @@ -86,7 +100,11 @@ function PermissionsPage:render() BackgroundTransparency = 1, }) else - for source in self.props.headlessAPI._permissions do + for source, permissions in self.state.permissions do + if next(permissions) == nil then + continue + end + local meta = self.props.headlessAPI:_getMetaFromSource(source) sources[source] = e(Listing, { layoutOrder = string.byte(source), diff --git a/plugin/src/App/init.lua b/plugin/src/App/init.lua index 5774733c..e5635de4 100644 --- a/plugin/src/App/init.lua +++ b/plugin/src/App/init.lua @@ -851,17 +851,19 @@ function App:render() end, onEdit = function(plugin, source, meta, apiMap) + local name = meta.Name .. if meta.Creator then " by " .. meta.Creator else "" local apiList = {} for api in apiMap do table.insert(apiList, api) end - self:requestPermission( + local response = self:requestPermission( plugin, source, - meta.Name .. if meta.Creator then " by " .. meta.Creator else "", + name, apiList, apiMap ) + self.headlessAPI:_setPermissions(source, name, response) end, }), diff --git a/plugin/src/HeadlessAPI.lua b/plugin/src/HeadlessAPI.lua index 1221be7e..bf661739 100644 --- a/plugin/src/HeadlessAPI.lua +++ b/plugin/src/HeadlessAPI.lua @@ -152,17 +152,6 @@ function API.new(app) return "CommandBar" end - function Rojo:_permissionCheck(key: string): boolean - if apiPermissionAllowlist[key] then return true end - - local source = Rojo:_getCallerSource() - if Rojo._permissions[source] == nil then - Rojo._permissions[source] = {} - end - - return not not Rojo._permissions[source][key] - end - local BUCKET, LIMIT = 10, 15 function Rojo:_checkRateLimit(api: string): boolean local source = Rojo:_getCallerSource() @@ -189,6 +178,54 @@ function API.new(app) return false end + Rojo._permissionsChangedEvent = Instance.new("BindableEvent") + Rojo._permissionsChanged = Rojo._permissionsChangedEvent.Event + + function Rojo:_permissionCheck(key: string): boolean + if apiPermissionAllowlist[key] then return true end + + local source = Rojo:_getCallerSource() + if Rojo._permissions[source] == nil then + Rojo._permissions[source] = {} + end + + return not not Rojo._permissions[source][key] + end + + function Rojo:_setPermissions(source, name, permissions) + -- Ensure permissions exist for this source + if Rojo._permissions[source] == nil then + Rojo._permissions[source] = {} + end + + -- Set permissions + for api, granted in permissions do + Log.warn(string.format( + "%s Rojo.%s for '%s'", + granted and "Granting permission to" or "Denying permission to", api, name + )) + Rojo._permissions[source][api] = granted + end + + -- Clear out source if no permissions are granted + local hasAnyPermissions = false + for _, granted in Rojo._permissions[source] do + if granted then + hasAnyPermissions = true + break + end + end + if not hasAnyPermissions then + Rojo._permissions[source] = nil + end + + -- Update stored permissions + Settings:set("apiPermissions", Rojo._permissions) + + -- Share changes + Rojo._permissionsChangedEvent:Fire(source, Rojo._permissions[source]) + end + Rojo._apiDescriptions.RequestAccess = "Used to gain access to Rojo API members" function Rojo:RequestAccess(plugin: Plugin, apis: {string}): {[string]: boolean} assert(type(apis) == "table", "Rojo:RequestAccess expects an array of valid API names as the second argument") @@ -245,14 +282,7 @@ function API.new(app) local response = app:requestPermission(plugin, source, name, sanitizedApis, Rojo._permissions[source]) - for api, granted in response do - Log.warn(string.format( - "%s Rojo.%s for '%s'", - granted and "Granting permission to" or "Denying permission to", api, name - )) - Rojo._permissions[source][api] = granted - end - Settings:set("apiPermissions", Rojo._permissions) + Rojo:_setPermissions(source, name, response) Rojo._activePermissionRequests[source] = nil return response