fix: add user_id support and OAuth shell permission (v0.2.6)
Some checks failed
Release / build-linux-arm64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Release / build-macos-arm64 (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled

Fixes:
- Added shell:allow-open permission to fix OAuth integration flows
- Added user_id field to ProviderConfig for Custom REST provider CORE ID
- Added UI field for user_id when api_format is custom_rest
- Made userId optional in Custom REST provider requests (only sent if provided)
- Added X-msi-genai-client header to Custom REST provider requests
- Updated CSP to include Custom REST provider domains
- Bumped version to 0.2.6

This fixes:
- OAuth error: 'Command plugin:shell|open not allowed by ACL'
- Missing User ID field in Custom REST provider configuration UI
This commit is contained in:
Shaun Arman 2026-04-03 16:34:00 -05:00
parent dd06566375
commit a42745b791
6 changed files with 29 additions and 3 deletions

View File

@ -25,6 +25,7 @@
"fs:scope-app-recursive",
"fs:scope-temp-recursive",
"shell:allow-execute",
"shell:allow-open",
"http:default"
]
}

View File

@ -132,9 +132,13 @@ impl OpenAiProvider {
let mut body = serde_json::json!({
"model": config.model,
"prompt": prompt,
"userId": "user@motorolasolutions.com", // Default user ID
});
// Add userId if provided (CORE ID email)
if let Some(user_id) = &config.user_id {
body["userId"] = serde_json::Value::String(user_id.clone());
}
// Add optional system message
if let Some(system) = system_message {
body["system"] = serde_json::Value::String(system);
@ -157,6 +161,7 @@ impl OpenAiProvider {
.post(&url)
.header(auth_header, auth_value)
.header("Content-Type", "application/json")
.header("X-msi-genai-client", "tftsr-devops-investigation")
.json(&body)
.send()
.await?;

View File

@ -29,6 +29,9 @@ pub struct ProviderConfig {
/// Optional: Session ID for stateful APIs like MSI GenAI
#[serde(skip_serializing_if = "Option::is_none")]
pub session_id: Option<String>,
/// Optional: User ID for MSI GenAI (CORE ID email)
#[serde(skip_serializing_if = "Option::is_none")]
pub user_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]

View File

@ -1,6 +1,6 @@
{
"productName": "TFTSR",
"version": "0.2.2",
"version": "0.2.6",
"identifier": "com.tftsr.devops",
"build": {
"frontendDist": "../dist",
@ -10,7 +10,7 @@
},
"app": {
"security": {
"csp": "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: asset: https:; connect-src 'self' http://localhost:11434 http://localhost:8765 https://api.openai.com https://api.anthropic.com https://api.mistral.ai https://generativelanguage.googleapis.com https://auth.atlassian.com https://*.atlassian.net https://login.microsoftonline.com https://dev.azure.com"
"csp": "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: asset: https:; connect-src 'self' http://localhost:11434 http://localhost:8765 https://api.openai.com https://api.anthropic.com https://api.mistral.ai https://generativelanguage.googleapis.com https://auth.atlassian.com https://*.atlassian.net https://login.microsoftonline.com https://dev.azure.com https://genai-service.stage.commandcentral.com https://genai-service.commandcentral.com"
},
"windows": [
{

View File

@ -15,6 +15,7 @@ export interface ProviderConfig {
custom_auth_prefix?: string;
api_format?: string;
session_id?: string;
user_id?: string;
}
export interface Message {

View File

@ -32,6 +32,7 @@ const emptyProvider: ProviderConfig = {
custom_auth_prefix: undefined,
api_format: undefined,
session_id: undefined,
user_id: undefined,
};
export default function AIProviders() {
@ -351,6 +352,21 @@ export default function AIProviders() {
Prefix added before API key (e.g., "Bearer " for OpenAI, empty for MSI GenAI)
</p>
</div>
{/* MSI GenAI specific: User ID field */}
{form.api_format === "msi_genai" && (
<div className="space-y-2">
<Label>User ID (CORE ID)</Label>
<Input
value={form.user_id ?? ""}
onChange={(e) => setForm({ ...form, user_id: e.target.value })}
placeholder="your.name@motorolasolutions.com"
/>
<p className="text-xs text-muted-foreground">
Optional: Your Motorola CORE ID email. If omitted, costs are tracked to API key owner.
</p>
</div>
)}
</div>
</>
)}