JWT auth plugin and necessary updates

This commit is contained in:
Gregory Schier
2025-01-17 08:02:55 -08:00
parent bd322162c8
commit 07ff709429
24 changed files with 327 additions and 104 deletions

View File

@@ -29,6 +29,8 @@ export type Color = "custom" | "default" | "primary" | "secondary" | "info" | "s
export type CopyTextRequest = { text: string, };
export type EditorLanguage = "text" | "javascript" | "json" | "html" | "xml" | "graphql" | "markdown";
export type EmptyPayload = {};
export type ExportHttpRequestRequest = { httpRequest: HttpRequest, };
@@ -49,7 +51,7 @@ export type FindHttpResponsesRequest = { requestId: string, limit?: number, };
export type FindHttpResponsesResponse = { httpResponses: Array<HttpResponse>, };
export type FormInput = { "type": "text" } & FormInputText | { "type": "select" } & FormInputSelect | { "type": "checkbox" } & FormInputCheckbox | { "type": "file" } & FormInputFile | { "type": "http_request" } & FormInputHttpRequest;
export type FormInput = { "type": "text" } & FormInputText | { "type": "editor" } & FormInputEditor | { "type": "select" } & FormInputSelect | { "type": "checkbox" } & FormInputCheckbox | { "type": "file" } & FormInputFile | { "type": "http_request" } & FormInputHttpRequest;
export type FormInputBase = { name: string,
/**
@@ -79,6 +81,24 @@ label?: string,
*/
defaultValue?: string, };
export type FormInputEditor = {
/**
* Placeholder for the text input
*/
placeholder?: string | null, language: EditorLanguage, name: string,
/**
* Whether the user must fill in the argument
*/
optional?: boolean,
/**
* The label of the input
*/
label?: string,
/**
* The default value
*/
defaultValue?: string, };
export type FormInputFile = {
/**
* The title of the file selection window
@@ -139,7 +159,11 @@ export type FormInputText = {
/**
* Placeholder for the text input
*/
placeholder?: string | null, name: string,
placeholder?: string | null,
/**
* Placeholder for the text input
*/
password?: boolean, name: string,
/**
* Whether the user must fill in the argument
*/
@@ -153,7 +177,7 @@ label?: string,
*/
defaultValue?: string, };
export type GetHttpAuthenticationResponse = { name: string, pluginName: string, config: Array<FormInput>, };
export type GetHttpAuthenticationResponse = { name: string, label: string, shortLabel: string, config: Array<FormInput>, };
export type GetHttpRequestActionsRequest = Record<string, never>;

View File

@@ -25,6 +25,9 @@ pub enum Error {
#[error("Plugin not found: {0}")]
PluginNotFoundErr(String),
#[error("Auth plugin not found: {0}")]
AuthPluginNotFound(String),
#[error("Plugin error: {0}")]
PluginErr(String),

View File

@@ -298,7 +298,8 @@ pub enum Icon {
#[ts(export, export_to = "events.ts")]
pub struct GetHttpAuthenticationResponse {
pub name: String,
pub plugin_name: String,
pub label: String,
pub short_label: String,
pub config: Vec<FormInput>,
}
@@ -356,6 +357,7 @@ pub struct TemplateFunction {
#[ts(export, export_to = "events.ts")]
pub enum FormInput {
Text(FormInputText),
Editor(FormInputEditor),
Select(FormInputSelect),
Checkbox(FormInputCheckbox),
File(FormInputFile),
@@ -391,6 +393,43 @@ pub struct FormInputText {
/// Placeholder for the text input
#[ts(optional = nullable)]
pub placeholder: Option<String>,
/// Placeholder for the text input
#[ts(optional)]
pub password: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(rename_all = "snake_case")]
#[ts(export, export_to = "events.ts")]
pub enum EditorLanguage {
Text,
Javascript,
Json,
Html,
Xml,
Graphql,
Markdown,
}
impl Default for EditorLanguage {
fn default() -> Self {
Self::Text
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
#[serde(default, rename_all = "camelCase")]
#[ts(export, export_to = "events.ts")]
pub struct FormInputEditor {
#[serde(flatten)]
pub base: FormInputBase,
/// Placeholder for the text input
#[ts(optional = nullable)]
pub placeholder: Option<String>,
pub language: EditorLanguage,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]

View File

@@ -1,9 +1,11 @@
use crate::error::Error::{ClientNotInitializedErr, PluginErr, PluginNotFoundErr, UnknownEventErr};
use crate::error::Error::{
AuthPluginNotFound, ClientNotInitializedErr, PluginErr, PluginNotFoundErr, UnknownEventErr,
};
use crate::error::Result;
use crate::events::{
BootRequest, CallHttpAuthenticationRequest, CallHttpAuthenticationResponse,
CallHttpRequestActionRequest, CallTemplateFunctionArgs, CallTemplateFunctionRequest,
CallTemplateFunctionResponse, EmptyPayload, FilterRequest, FilterResponse,
CallTemplateFunctionResponse, EmptyPayload, FilterRequest, FilterResponse, FormInput,
GetHttpAuthenticationResponse, GetHttpRequestActionsResponse, GetTemplateFunctionsResponse,
ImportRequest, ImportResponse, InternalEvent, InternalEventPayload, RenderPurpose,
WindowContext,
@@ -462,7 +464,7 @@ impl PluginManager {
pub async fn get_http_authentication<R: Runtime>(
&self,
window: &WebviewWindow<R>,
) -> Result<Vec<GetHttpAuthenticationResponse>> {
) -> Result<Vec<(PluginHandle, GetHttpAuthenticationResponse)>> {
let window_context = WindowContext::from_window(window);
let reply_events = self
.send_and_wait(
@@ -474,7 +476,11 @@ impl PluginManager {
let mut results = Vec::new();
for event in reply_events {
if let InternalEventPayload::GetHttpAuthenticationResponse(resp) = event.payload {
results.push(resp.clone());
let plugin = self
.get_plugin_by_ref_id(&event.plugin_ref_id)
.await
.ok_or(PluginNotFoundErr(event.plugin_ref_id))?;
results.push((plugin, resp.clone()));
}
}
@@ -484,13 +490,37 @@ impl PluginManager {
pub async fn call_http_authentication<R: Runtime>(
&self,
window: &WebviewWindow<R>,
plugin_name: &str,
auth_name: &str,
req: CallHttpAuthenticationRequest,
) -> Result<CallHttpAuthenticationResponse> {
let plugin = self
.get_plugin_by_name(plugin_name)
.await
.ok_or(PluginNotFoundErr(plugin_name.to_string()))?;
let handlers = self.get_http_authentication(window).await?;
let (plugin, authentication) = handlers
.iter()
.find(|(_, a)| a.name == auth_name)
.ok_or(AuthPluginNotFound(auth_name.to_string()))?;
// Clone for mutability
let mut req = req.clone();
// Fill in default values
for arg in authentication.config.clone() {
let base = match arg {
FormInput::Text(a) => a.base,
FormInput::Editor(a) => a.base,
FormInput::Select(a) => a.base,
FormInput::Checkbox(a) => a.base,
FormInput::File(a) => a.base,
FormInput::HttpRequest(a) => a.base,
};
if let None = req.config.get(base.name.as_str()) {
let default = match base.default_value {
None => serde_json::Value::Null,
Some(s) => serde_json::Value::String(s),
};
req.config.insert(base.name, default);
}
}
let event = self
.send_to_plugin_and_wait(
WindowContext::from_window(window),