nxtgauge-ai-assistant/src/services/action_confirmation.rs
Ashwin Kumar Sivakumar 23a707e175
All checks were successful
build-and-release / build (push) Successful in 4m14s
Fix security audit findings: IDOR, rate limiting, action audit trail
- Chat and ticket-creation endpoints now scope lookups/attribution to
  the authenticated JWT identity instead of trusting a client-supplied
  user_id in the request body (IDOR)
- Add per-user in-memory rate limiter on AI-generation endpoints to
  guard against unbounded LLM-cost abuse
- Bind confirm_action to the authenticated user for audit logging
- Bump vulnerable transitive dependencies via cargo update

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 17:32:01 +05:30

67 lines
2 KiB
Rust

use crate::{
actions::get_action,
error::AppError,
handlers::actions::{ConfirmActionRequest, ConfirmActionResponse},
};
#[derive(Clone, Default)]
pub struct ActionConfirmationService;
impl ActionConfirmationService {
pub fn new() -> Self {
Self
}
pub async fn confirm_action(
&self,
request: ConfirmActionRequest,
confirmed_by_user_id: &str,
) -> Result<ConfirmActionResponse, AppError> {
if !request.confirmed {
tracing::info!(
user_id = %confirmed_by_user_id,
action = %request.action,
conversation_id = %request.conversation_id,
"action confirmation cancelled by user"
);
return Ok(ConfirmActionResponse {
success: false,
delegated: false,
message: "Action cancelled by user.".to_string(),
action: request.action.clone(),
backend_handler: None,
record_id: None,
fields: None,
ui_events: None,
});
}
let action = get_action(&request.action);
let backend_handler = action
.as_ref()
.map(|item| item.backend_handler.clone())
.unwrap_or_else(|| request.action.clone());
tracing::info!(
user_id = %confirmed_by_user_id,
action = %request.action,
backend_handler = %backend_handler,
conversation_id = %request.conversation_id,
"action confirmed by user"
);
Ok(ConfirmActionResponse {
success: true,
delegated: true,
message: format!(
"Action approved. Execute '{}' in the product backend.",
backend_handler
),
action: request.action.clone(),
backend_handler: Some(backend_handler),
record_id: None,
fields: Some(request.fields),
ui_events: None,
})
}
}