pinakes-ui: enforce plugin endpoint allowlist; replace inline styles with CSS custom properties
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I751e5c7ec66f045ee1f0bad6c72759416a6a6964
This commit is contained in:
parent
ada1c07f66
commit
9389af9fda
11 changed files with 1880 additions and 772 deletions
|
|
@ -1617,14 +1617,16 @@ impl ApiClient {
|
|||
|
||||
/// List all UI pages provided by loaded plugins.
|
||||
///
|
||||
/// Returns a vector of `(plugin_id, page)` tuples.
|
||||
/// Returns a vector of `(plugin_id, page, allowed_endpoints)` tuples.
|
||||
pub async fn get_plugin_ui_pages(
|
||||
&self,
|
||||
) -> Result<Vec<(String, pinakes_plugin_api::UiPage)>> {
|
||||
) -> Result<Vec<(String, pinakes_plugin_api::UiPage, Vec<String>)>> {
|
||||
#[derive(Deserialize)]
|
||||
struct PageEntry {
|
||||
plugin_id: String,
|
||||
page: pinakes_plugin_api::UiPage,
|
||||
plugin_id: String,
|
||||
page: pinakes_plugin_api::UiPage,
|
||||
#[serde(default)]
|
||||
allowed_endpoints: Vec<String>,
|
||||
}
|
||||
|
||||
let entries: Vec<PageEntry> = self
|
||||
|
|
@ -1636,7 +1638,80 @@ impl ApiClient {
|
|||
.json()
|
||||
.await?;
|
||||
|
||||
Ok(entries.into_iter().map(|e| (e.plugin_id, e.page)).collect())
|
||||
Ok(
|
||||
entries
|
||||
.into_iter()
|
||||
.map(|e| (e.plugin_id, e.page, e.allowed_endpoints))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
/// List all UI widgets provided by loaded plugins.
|
||||
///
|
||||
/// Returns a vector of `(plugin_id, widget)` tuples.
|
||||
pub async fn get_plugin_ui_widgets(
|
||||
&self,
|
||||
) -> Result<Vec<(String, pinakes_plugin_api::UiWidget)>> {
|
||||
#[derive(Deserialize)]
|
||||
struct WidgetEntry {
|
||||
plugin_id: String,
|
||||
widget: pinakes_plugin_api::UiWidget,
|
||||
}
|
||||
|
||||
let entries: Vec<WidgetEntry> = self
|
||||
.client
|
||||
.get(self.url("/plugins/ui-widgets"))
|
||||
.send()
|
||||
.await?
|
||||
.error_for_status()?
|
||||
.json()
|
||||
.await?;
|
||||
|
||||
Ok(
|
||||
entries
|
||||
.into_iter()
|
||||
.map(|e| (e.plugin_id, e.widget))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Fetch merged CSS custom property overrides from all enabled plugins.
|
||||
///
|
||||
/// Returns a map of CSS property names to values.
|
||||
pub async fn get_plugin_ui_theme_extensions(
|
||||
&self,
|
||||
) -> Result<HashMap<String, String>> {
|
||||
Ok(
|
||||
self
|
||||
.client
|
||||
.get(self.url("/plugins/ui-theme-extensions"))
|
||||
.send()
|
||||
.await?
|
||||
.error_for_status()?
|
||||
.json()
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
|
||||
/// Emit a plugin event to the server-side event bus.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the request fails or the server returns an error
|
||||
/// status.
|
||||
pub async fn post_plugin_event(
|
||||
&self,
|
||||
event: &str,
|
||||
payload: &serde_json::Value,
|
||||
) -> Result<()> {
|
||||
self
|
||||
.client
|
||||
.post(self.url("/plugins/events"))
|
||||
.json(&serde_json::json!({ "event": event, "payload": payload }))
|
||||
.send()
|
||||
.await?
|
||||
.error_for_status()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Make a raw HTTP request to an API path.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue