fix: resolve clippy format-args failures and OpenSSL vendoring issue
Inline format arguments across Rust modules to satisfy clippy -D warnings, and configure Cargo to prefer system OpenSSL so clippy builds do not fail on missing vendored Perl modules. Made-with: Cursor
This commit is contained in:
parent
bdb63f3aee
commit
85a8d0a4c0
3
.cargo/config.toml
Normal file
3
.cargo/config.toml
Normal file
@ -0,0 +1,3 @@
|
||||
[env]
|
||||
# Force use of system OpenSSL instead of vendored OpenSSL source builds.
|
||||
OPENSSL_NO_VENDOR = "1"
|
||||
@ -4,3 +4,8 @@
|
||||
# error. The desktop binary links against rlib (static), so cdylib exports
|
||||
# are unused at runtime.
|
||||
rustflags = ["-C", "link-arg=-Wl,--exclude-all-symbols"]
|
||||
|
||||
[env]
|
||||
# Use system OpenSSL instead of vendoring from source (which requires Perl modules
|
||||
# unavailable on some environments and breaks clippy/check).
|
||||
OPENSSL_NO_VENDOR = "1"
|
||||
|
||||
@ -47,7 +47,10 @@ impl Provider for MistralProvider {
|
||||
|
||||
let resp = client
|
||||
.post(&url)
|
||||
.header("Authorization", format!("Bearer {}", config.api_key))
|
||||
.header(
|
||||
"Authorization",
|
||||
format!("Bearer {api_key}", api_key = config.api_key),
|
||||
)
|
||||
.header("Content-Type", "application/json")
|
||||
.json(&body)
|
||||
.send()
|
||||
|
||||
@ -54,7 +54,8 @@ impl OpenAiProvider {
|
||||
.custom_endpoint_path
|
||||
.as_deref()
|
||||
.unwrap_or("/chat/completions");
|
||||
let url = format!("{}{}", config.api_url.trim_end_matches('/'), endpoint_path);
|
||||
let api_url = config.api_url.trim_end_matches('/');
|
||||
let url = format!("{api_url}{endpoint_path}");
|
||||
|
||||
let mut body = serde_json::json!({
|
||||
"model": config.model,
|
||||
@ -75,7 +76,7 @@ impl OpenAiProvider {
|
||||
.as_deref()
|
||||
.unwrap_or("Authorization");
|
||||
let auth_prefix = config.custom_auth_prefix.as_deref().unwrap_or("Bearer ");
|
||||
let auth_value = format!("{}{}", auth_prefix, config.api_key);
|
||||
let auth_value = format!("{auth_prefix}{api_key}", api_key = config.api_key);
|
||||
|
||||
let resp = client
|
||||
.post(&url)
|
||||
@ -122,7 +123,8 @@ impl OpenAiProvider {
|
||||
|
||||
// Use custom endpoint path, default to empty (API URL already includes /api/v2/chat)
|
||||
let endpoint_path = config.custom_endpoint_path.as_deref().unwrap_or("");
|
||||
let url = format!("{}{}", config.api_url.trim_end_matches('/'), endpoint_path);
|
||||
let api_url = config.api_url.trim_end_matches('/');
|
||||
let url = format!("{api_url}{endpoint_path}");
|
||||
|
||||
// Extract system message if present
|
||||
let system_message = messages
|
||||
@ -177,7 +179,7 @@ impl OpenAiProvider {
|
||||
.as_deref()
|
||||
.unwrap_or("x-msi-genai-api-key");
|
||||
let auth_prefix = config.custom_auth_prefix.as_deref().unwrap_or("");
|
||||
let auth_value = format!("{}{}", auth_prefix, config.api_key);
|
||||
let auth_value = format!("{auth_prefix}{api_key}", api_key = config.api_key);
|
||||
|
||||
let resp = client
|
||||
.post(&url)
|
||||
|
||||
@ -246,7 +246,7 @@ pub async fn chat_message(
|
||||
"api_url": provider_config.api_url,
|
||||
"user_message": user_msg.content,
|
||||
"response_preview": if response.content.len() > 200 {
|
||||
format!("{}...", &response.content[..200])
|
||||
format!("{preview}...", preview = &response.content[..200])
|
||||
} else {
|
||||
response.content.clone()
|
||||
},
|
||||
|
||||
@ -295,19 +295,19 @@ pub async fn list_issues(
|
||||
let mut params: Vec<Box<dyn rusqlite::types::ToSql>> = vec![];
|
||||
|
||||
if let Some(ref status) = filter.status {
|
||||
sql.push_str(&format!(" AND i.status = ?{}", params.len() + 1));
|
||||
sql.push_str(&format!(" AND i.status = ?{index}", index = params.len() + 1));
|
||||
params.push(Box::new(status.clone()));
|
||||
}
|
||||
if let Some(ref severity) = filter.severity {
|
||||
sql.push_str(&format!(" AND i.severity = ?{}", params.len() + 1));
|
||||
sql.push_str(&format!(" AND i.severity = ?{index}", index = params.len() + 1));
|
||||
params.push(Box::new(severity.clone()));
|
||||
}
|
||||
if let Some(ref category) = filter.category {
|
||||
sql.push_str(&format!(" AND i.category = ?{}", params.len() + 1));
|
||||
sql.push_str(&format!(" AND i.category = ?{index}", index = params.len() + 1));
|
||||
params.push(Box::new(category.clone()));
|
||||
}
|
||||
if let Some(ref domain) = filter.domain {
|
||||
sql.push_str(&format!(" AND i.category = ?{}", params.len() + 1));
|
||||
sql.push_str(&format!(" AND i.category = ?{index}", index = params.len() + 1));
|
||||
params.push(Box::new(domain.clone()));
|
||||
}
|
||||
if let Some(ref search) = filter.search {
|
||||
@ -321,9 +321,9 @@ pub async fn list_issues(
|
||||
|
||||
sql.push_str(" ORDER BY i.updated_at DESC");
|
||||
sql.push_str(&format!(
|
||||
" LIMIT ?{} OFFSET ?{}",
|
||||
params.len() + 1,
|
||||
params.len() + 2
|
||||
" LIMIT ?{limit_index} OFFSET ?{offset_index}",
|
||||
limit_index = params.len() + 1,
|
||||
offset_index = params.len() + 2
|
||||
));
|
||||
params.push(Box::new(limit));
|
||||
params.push(Box::new(offset));
|
||||
|
||||
@ -34,7 +34,7 @@ pub async fn generate_rca(
|
||||
id: doc_id.clone(),
|
||||
issue_id: issue_id.clone(),
|
||||
doc_type: "rca".to_string(),
|
||||
title: format!("RCA: {}", issue_detail.issue.title),
|
||||
title: format!("RCA: {title}", title = issue_detail.issue.title),
|
||||
content_md: content_md.clone(),
|
||||
created_at: now.clone(),
|
||||
updated_at: now,
|
||||
@ -49,7 +49,7 @@ pub async fn generate_rca(
|
||||
"doc_title": document.title,
|
||||
"content_length": content_md.len(),
|
||||
"content_preview": if content_md.len() > 300 {
|
||||
format!("{}...", &content_md[..300])
|
||||
format!("{preview}...", preview = &content_md[..300])
|
||||
} else {
|
||||
content_md.clone()
|
||||
},
|
||||
@ -93,7 +93,7 @@ pub async fn generate_postmortem(
|
||||
id: doc_id.clone(),
|
||||
issue_id: issue_id.clone(),
|
||||
doc_type: "postmortem".to_string(),
|
||||
title: format!("Post-Mortem: {}", issue_detail.issue.title),
|
||||
title: format!("Post-Mortem: {title}", title = issue_detail.issue.title),
|
||||
content_md: content_md.clone(),
|
||||
created_at: now.clone(),
|
||||
updated_at: now,
|
||||
@ -108,7 +108,7 @@ pub async fn generate_postmortem(
|
||||
"doc_title": document.title,
|
||||
"content_length": content_md.len(),
|
||||
"content_preview": if content_md.len() > 300 {
|
||||
format!("{}...", &content_md[..300])
|
||||
format!("{preview}...", preview = &content_md[..300])
|
||||
} else {
|
||||
content_md.clone()
|
||||
},
|
||||
|
||||
@ -514,7 +514,7 @@ pub async fn authenticate_with_webview(
|
||||
app_handle: tauri::AppHandle,
|
||||
app_state: State<'_, AppState>,
|
||||
) -> Result<WebviewAuthResponse, String> {
|
||||
let webview_id = format!("{}-auth", service);
|
||||
let webview_id = format!("{service}-auth");
|
||||
|
||||
// Check if window already exists
|
||||
if let Some(existing_label) = app_state
|
||||
@ -526,10 +526,7 @@ pub async fn authenticate_with_webview(
|
||||
if app_handle.get_webview_window(existing_label).is_some() {
|
||||
return Ok(WebviewAuthResponse {
|
||||
success: true,
|
||||
message: format!(
|
||||
"{} browser window is already open. Switch to it to log in.",
|
||||
service
|
||||
),
|
||||
message: format!("{service} browser window is already open. Switch to it to log in."),
|
||||
webview_id: existing_label.clone(),
|
||||
});
|
||||
}
|
||||
@ -551,8 +548,7 @@ pub async fn authenticate_with_webview(
|
||||
Ok(WebviewAuthResponse {
|
||||
success: true,
|
||||
message: format!(
|
||||
"{} browser window opened. This window will stay open - use it to browse and authenticate. Cookies will be extracted automatically for API calls.",
|
||||
service
|
||||
"{service} browser window opened. This window will stay open - use it to browse and authenticate. Cookies will be extracted automatically for API calls."
|
||||
),
|
||||
webview_id,
|
||||
})
|
||||
@ -622,7 +618,7 @@ pub async fn extract_cookies_from_webview(
|
||||
|
||||
Ok(ConnectionResult {
|
||||
success: true,
|
||||
message: format!("{} authentication saved successfully", service),
|
||||
message: format!("{service} authentication saved successfully"),
|
||||
})
|
||||
}
|
||||
|
||||
@ -669,7 +665,7 @@ pub async fn save_manual_token(
|
||||
};
|
||||
crate::integrations::servicenow::test_connection(&config).await
|
||||
}
|
||||
_ => return Err(format!("Unknown service: {}", request.service)),
|
||||
_ => return Err(format!("Unknown service: {service}", service = request.service)),
|
||||
};
|
||||
|
||||
// If test fails, don't save the token
|
||||
@ -736,7 +732,10 @@ pub async fn save_manual_token(
|
||||
|
||||
Ok(ConnectionResult {
|
||||
success: true,
|
||||
message: format!("{} token saved and validated successfully", request.service),
|
||||
message: format!(
|
||||
"{service} token saved and validated successfully",
|
||||
service = request.service
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -98,20 +98,23 @@ pub async fn get_audit_log(
|
||||
let mut params: Vec<Box<dyn rusqlite::types::ToSql>> = vec![];
|
||||
|
||||
if let Some(ref action) = filter.action {
|
||||
sql.push_str(&format!(" AND action = ?{}", params.len() + 1));
|
||||
sql.push_str(&format!(" AND action = ?{index}", index = params.len() + 1));
|
||||
params.push(Box::new(action.clone()));
|
||||
}
|
||||
if let Some(ref entity_type) = filter.entity_type {
|
||||
sql.push_str(&format!(" AND entity_type = ?{}", params.len() + 1));
|
||||
sql.push_str(&format!(
|
||||
" AND entity_type = ?{index}",
|
||||
index = params.len() + 1
|
||||
));
|
||||
params.push(Box::new(entity_type.clone()));
|
||||
}
|
||||
if let Some(ref entity_id) = filter.entity_id {
|
||||
sql.push_str(&format!(" AND entity_id = ?{}", params.len() + 1));
|
||||
sql.push_str(&format!(" AND entity_id = ?{index}", index = params.len() + 1));
|
||||
params.push(Box::new(entity_id.clone()));
|
||||
}
|
||||
|
||||
sql.push_str(" ORDER BY timestamp DESC");
|
||||
sql.push_str(&format!(" LIMIT ?{}", params.len() + 1));
|
||||
sql.push_str(&format!(" LIMIT ?{index}", index = params.len() + 1));
|
||||
params.push(Box::new(limit));
|
||||
|
||||
let param_refs: Vec<&dyn rusqlite::types::ToSql> = params.iter().map(|p| p.as_ref()).collect();
|
||||
|
||||
@ -5,15 +5,21 @@ pub fn generate_postmortem_markdown(detail: &IssueDetail) -> String {
|
||||
|
||||
let mut md = String::new();
|
||||
|
||||
md.push_str(&format!("# Blameless Post-Mortem: {}\n\n", issue.title));
|
||||
md.push_str(&format!(
|
||||
"# Blameless Post-Mortem: {title}\n\n",
|
||||
title = issue.title
|
||||
));
|
||||
|
||||
// Header metadata
|
||||
md.push_str("## Metadata\n\n");
|
||||
md.push_str(&format!("- **Date:** {}\n", issue.created_at));
|
||||
md.push_str(&format!("- **Severity:** {}\n", issue.severity));
|
||||
md.push_str(&format!("- **Category:** {}\n", issue.category));
|
||||
md.push_str(&format!("- **Status:** {}\n", issue.status));
|
||||
md.push_str(&format!("- **Last Updated:** {}\n", issue.updated_at));
|
||||
md.push_str(&format!("- **Date:** {created_at}\n", created_at = issue.created_at));
|
||||
md.push_str(&format!("- **Severity:** {severity}\n", severity = issue.severity));
|
||||
md.push_str(&format!("- **Category:** {category}\n", category = issue.category));
|
||||
md.push_str(&format!("- **Status:** {status}\n", status = issue.status));
|
||||
md.push_str(&format!(
|
||||
"- **Last Updated:** {updated_at}\n",
|
||||
updated_at = issue.updated_at
|
||||
));
|
||||
md.push_str(&format!(
|
||||
"- **Assigned To:** {}\n",
|
||||
if issue.assigned_to.is_empty() {
|
||||
@ -45,7 +51,7 @@ pub fn generate_postmortem_markdown(detail: &IssueDetail) -> String {
|
||||
md.push_str("## Timeline\n\n");
|
||||
md.push_str("| Time (UTC) | Event |\n");
|
||||
md.push_str("|------------|-------|\n");
|
||||
md.push_str(&format!("| {} | Issue created |\n", issue.created_at));
|
||||
md.push_str(&format!("| {created_at} | Issue created |\n", created_at = issue.created_at));
|
||||
if let Some(ref resolved) = issue.resolved_at {
|
||||
md.push_str(&format!("| {resolved} | Issue resolved |\n"));
|
||||
}
|
||||
@ -77,7 +83,7 @@ pub fn generate_postmortem_markdown(detail: &IssueDetail) -> String {
|
||||
|
||||
if let Some(last) = detail.resolution_steps.last() {
|
||||
if !last.answer.is_empty() {
|
||||
md.push_str(&format!("**Root Cause:** {}\n\n", last.answer));
|
||||
md.push_str(&format!("**Root Cause:** {answer}\n\n", answer = last.answer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,16 +5,16 @@ pub fn generate_rca_markdown(detail: &IssueDetail) -> String {
|
||||
|
||||
let mut md = String::new();
|
||||
|
||||
md.push_str(&format!("# Root Cause Analysis: {}\n\n", issue.title));
|
||||
md.push_str(&format!("# Root Cause Analysis: {title}\n\n", title = issue.title));
|
||||
|
||||
md.push_str("## Issue Summary\n\n");
|
||||
md.push_str("| Field | Value |\n");
|
||||
md.push_str("|-------|-------|\n");
|
||||
md.push_str(&format!("| **Issue ID** | {} |\n", issue.id));
|
||||
md.push_str(&format!("| **Category** | {} |\n", issue.category));
|
||||
md.push_str(&format!("| **Status** | {} |\n", issue.status));
|
||||
md.push_str(&format!("| **Severity** | {} |\n", issue.severity));
|
||||
md.push_str(&format!("| **Source** | {} |\n", issue.source));
|
||||
md.push_str(&format!("| **Issue ID** | {id} |\n", id = issue.id));
|
||||
md.push_str(&format!("| **Category** | {category} |\n", category = issue.category));
|
||||
md.push_str(&format!("| **Status** | {status} |\n", status = issue.status));
|
||||
md.push_str(&format!("| **Severity** | {severity} |\n", severity = issue.severity));
|
||||
md.push_str(&format!("| **Source** | {source} |\n", source = issue.source));
|
||||
md.push_str(&format!(
|
||||
"| **Assigned To** | {} |\n",
|
||||
if issue.assigned_to.is_empty() {
|
||||
@ -23,8 +23,11 @@ pub fn generate_rca_markdown(detail: &IssueDetail) -> String {
|
||||
&issue.assigned_to
|
||||
}
|
||||
));
|
||||
md.push_str(&format!("| **Created** | {} |\n", issue.created_at));
|
||||
md.push_str(&format!("| **Last Updated** | {} |\n", issue.updated_at));
|
||||
md.push_str(&format!("| **Created** | {created_at} |\n", created_at = issue.created_at));
|
||||
md.push_str(&format!(
|
||||
"| **Last Updated** | {updated_at} |\n",
|
||||
updated_at = issue.updated_at
|
||||
));
|
||||
if let Some(ref resolved) = issue.resolved_at {
|
||||
md.push_str(&format!("| **Resolved** | {resolved} |\n"));
|
||||
}
|
||||
@ -47,12 +50,12 @@ pub fn generate_rca_markdown(detail: &IssueDetail) -> String {
|
||||
step.step_order, step.why_question
|
||||
));
|
||||
if !step.answer.is_empty() {
|
||||
md.push_str(&format!("**Answer:** {}\n\n", step.answer));
|
||||
md.push_str(&format!("**Answer:** {answer}\n\n", answer = step.answer));
|
||||
} else {
|
||||
md.push_str("_Awaiting answer._\n\n");
|
||||
}
|
||||
if !step.evidence.is_empty() {
|
||||
md.push_str(&format!("**Evidence:** {}\n\n", step.evidence));
|
||||
md.push_str(&format!("**Evidence:** {evidence}\n\n", evidence = step.evidence));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -365,7 +365,7 @@ mod tests {
|
||||
.create_async()
|
||||
.await;
|
||||
|
||||
let token_endpoint = format!("{}/oauth/token", server.url());
|
||||
let token_endpoint = format!("{server_url}/oauth/token", server_url = server.url());
|
||||
let result = exchange_code(
|
||||
&token_endpoint,
|
||||
"test-client-id",
|
||||
@ -397,7 +397,7 @@ mod tests {
|
||||
.create_async()
|
||||
.await;
|
||||
|
||||
let token_endpoint = format!("{}/oauth/token", server.url());
|
||||
let token_endpoint = format!("{server_url}/oauth/token", server_url = server.url());
|
||||
let result = exchange_code(
|
||||
&token_endpoint,
|
||||
"test-client-id",
|
||||
@ -421,7 +421,7 @@ mod tests {
|
||||
.create_async()
|
||||
.await;
|
||||
|
||||
let token_endpoint = format!("{}/oauth/token", server.url());
|
||||
let token_endpoint = format!("{server_url}/oauth/token", server_url = server.url());
|
||||
let result = exchange_code(
|
||||
&token_endpoint,
|
||||
"test-client-id",
|
||||
|
||||
@ -40,9 +40,10 @@ pub async fn test_connection(config: &AzureDevOpsConfig) -> Result<ConnectionRes
|
||||
message: "Successfully connected to Azure DevOps".to_string(),
|
||||
})
|
||||
} else {
|
||||
let status = resp.status();
|
||||
Ok(ConnectionResult {
|
||||
success: false,
|
||||
message: format!("Connection failed with status: {}", resp.status()),
|
||||
message: format!("Connection failed with status: {status}"),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -61,8 +62,7 @@ pub async fn search_work_items(
|
||||
|
||||
// Build WIQL query
|
||||
let wiql = format!(
|
||||
"SELECT [System.Id], [System.Title], [System.WorkItemType], [System.State] FROM WorkItems WHERE [System.Title] CONTAINS '{}' ORDER BY [System.CreatedDate] DESC",
|
||||
query
|
||||
"SELECT [System.Id], [System.Title], [System.WorkItemType], [System.State] FROM WorkItems WHERE [System.Title] CONTAINS '{query}' ORDER BY [System.CreatedDate] DESC"
|
||||
);
|
||||
|
||||
let body = serde_json::json!({ "query": wiql });
|
||||
|
||||
@ -269,7 +269,7 @@ mod tests {
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(200)).await;
|
||||
|
||||
// Server should be running
|
||||
let health_url = format!("http://127.0.0.1:{}/health", port);
|
||||
let health_url = format!("http://127.0.0.1:{port}/health");
|
||||
let health_before = reqwest::get(&health_url).await;
|
||||
assert!(health_before.is_ok(), "Server should be running");
|
||||
|
||||
|
||||
@ -43,9 +43,10 @@ pub async fn test_connection(config: &ConfluenceConfig) -> Result<ConnectionResu
|
||||
message: "Successfully connected to Confluence".to_string(),
|
||||
})
|
||||
} else {
|
||||
let status = resp.status();
|
||||
Ok(ConnectionResult {
|
||||
success: false,
|
||||
message: format!("Connection failed with status: {}", resp.status()),
|
||||
message: format!("Connection failed with status: {status}"),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -53,7 +54,8 @@ pub async fn test_connection(config: &ConfluenceConfig) -> Result<ConnectionResu
|
||||
/// List all spaces accessible with the current token
|
||||
pub async fn list_spaces(config: &ConfluenceConfig) -> Result<Vec<Space>, String> {
|
||||
let client = reqwest::Client::new();
|
||||
let url = format!("{}/rest/api/space", config.base_url.trim_end_matches('/'));
|
||||
let base_url = config.base_url.trim_end_matches('/');
|
||||
let url = format!("{base_url}/rest/api/space");
|
||||
|
||||
let resp = client
|
||||
.get(&url)
|
||||
@ -103,9 +105,9 @@ pub async fn search_pages(
|
||||
config.base_url.trim_end_matches('/')
|
||||
);
|
||||
|
||||
let mut cql = format!("text ~ \"{}\"", query);
|
||||
let mut cql = format!("text ~ \"{query}\"");
|
||||
if let Some(space) = space_key {
|
||||
cql = format!("{} AND space = {}", cql, space);
|
||||
cql = format!("{cql} AND space = {space}");
|
||||
}
|
||||
|
||||
let resp = client
|
||||
@ -140,7 +142,7 @@ pub async fn search_pages(
|
||||
id: page_id.to_string(),
|
||||
title: p["title"].as_str()?.to_string(),
|
||||
space_key: p["space"]["key"].as_str()?.to_string(),
|
||||
url: format!("{}/pages/viewpage.action?pageId={}", base_url, page_id),
|
||||
url: format!("{base_url}/pages/viewpage.action?pageId={page_id}"),
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
@ -157,7 +159,8 @@ pub async fn publish_page(
|
||||
parent_page_id: Option<&str>,
|
||||
) -> Result<PublishResult, String> {
|
||||
let client = reqwest::Client::new();
|
||||
let url = format!("{}/rest/api/content", config.base_url.trim_end_matches('/'));
|
||||
let base_url = config.base_url.trim_end_matches('/');
|
||||
let url = format!("{base_url}/rest/api/content");
|
||||
|
||||
let mut body = serde_json::json!({
|
||||
"type": "page",
|
||||
|
||||
@ -42,9 +42,10 @@ pub async fn test_connection(config: &ServiceNowConfig) -> Result<ConnectionResu
|
||||
message: "Successfully connected to ServiceNow".to_string(),
|
||||
})
|
||||
} else {
|
||||
let status = resp.status();
|
||||
Ok(ConnectionResult {
|
||||
success: false,
|
||||
message: format!("Connection failed with status: {}", resp.status()),
|
||||
message: format!("Connection failed with status: {status}"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,13 +25,14 @@ pub async fn authenticate_with_webview(
|
||||
service: &str,
|
||||
base_url: &str,
|
||||
) -> Result<ExtractedCredentials, String> {
|
||||
let trimmed_base_url = base_url.trim_end_matches('/');
|
||||
let login_url = match service {
|
||||
"confluence" => format!("{}/login.action", base_url.trim_end_matches('/')),
|
||||
"confluence" => format!("{trimmed_base_url}/login.action"),
|
||||
"azuredevops" => {
|
||||
// Azure DevOps login - user will be redirected through Microsoft SSO
|
||||
format!("{}/_signin", base_url.trim_end_matches('/'))
|
||||
format!("{trimmed_base_url}/_signin")
|
||||
}
|
||||
"servicenow" => format!("{}/login.do", base_url.trim_end_matches('/')),
|
||||
"servicenow" => format!("{trimmed_base_url}/login.do"),
|
||||
_ => return Err(format!("Unknown service: {service}")),
|
||||
};
|
||||
|
||||
@ -42,13 +43,13 @@ pub async fn authenticate_with_webview(
|
||||
);
|
||||
|
||||
// Create persistent browser window (stays open for browsing and fresh cookie extraction)
|
||||
let webview_label = format!("{}-auth", service);
|
||||
let webview_label = format!("{service}-auth");
|
||||
let webview = WebviewWindowBuilder::new(
|
||||
&app_handle,
|
||||
&webview_label,
|
||||
WebviewUrl::External(login_url.parse().map_err(|e| format!("Invalid URL: {e}"))?),
|
||||
)
|
||||
.title(format!("{} Browser (TFTSR)", service))
|
||||
.title(format!("{service} Browser (TFTSR)"))
|
||||
.inner_size(1000.0, 800.0)
|
||||
.min_inner_size(800.0, 600.0)
|
||||
.resizable(true)
|
||||
@ -195,7 +196,7 @@ pub async fn extract_cookies_via_ipc<R: tauri::Runtime>(
|
||||
pub fn cookies_to_header(cookies: &[Cookie]) -> String {
|
||||
cookies
|
||||
.iter()
|
||||
.map(|c| format!("{}={}", c.name, c.value))
|
||||
.map(|c| format!("{name}={value}", name = c.name.as_str(), value = c.value.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.join("; ")
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user