fix(webhooks): add idempotent_event_id generation using URL-safe Base64 (no padding) and SHA256 digest (#9405)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Ayush Anand
2025-09-22 13:15:52 +05:30
committed by GitHub
parent 740f3af643
commit 0c38bc3d0c
7 changed files with 43 additions and 11 deletions

View File

@ -1,6 +1,12 @@
use std::marker::PhantomData;
use common_utils::{errors::CustomResult, ext_traits::ValueExt};
use base64::Engine;
use common_utils::{
consts,
crypto::{self, GenerateDigest},
errors::CustomResult,
ext_traits::ValueExt,
};
use error_stack::{Report, ResultExt};
use redis_interface as redis;
use router_env::tracing;
@ -146,18 +152,28 @@ pub(crate) fn get_idempotent_event_id(
primary_object_id: &str,
event_type: types::storage::enums::EventType,
delivery_attempt: types::storage::enums::WebhookDeliveryAttempt,
) -> String {
) -> Result<String, Report<errors::WebhooksFlowError>> {
use crate::types::storage::enums::WebhookDeliveryAttempt;
const EVENT_ID_SUFFIX_LENGTH: usize = 8;
let common_prefix = format!("{primary_object_id}_{event_type}");
match delivery_attempt {
WebhookDeliveryAttempt::InitialAttempt => common_prefix,
// Hash the common prefix with SHA256 and encode with URL-safe base64 without padding
let digest = crypto::Sha256
.generate_digest(common_prefix.as_bytes())
.change_context(errors::WebhooksFlowError::IdGenerationFailed)
.attach_printable("Failed to generate idempotent event ID")?;
let base_encoded = consts::BASE64_ENGINE_URL_SAFE_NO_PAD.encode(digest);
let result = match delivery_attempt {
WebhookDeliveryAttempt::InitialAttempt => base_encoded,
WebhookDeliveryAttempt::AutomaticRetry | WebhookDeliveryAttempt::ManualRetry => {
common_utils::generate_id(EVENT_ID_SUFFIX_LENGTH, &common_prefix)
common_utils::generate_id(EVENT_ID_SUFFIX_LENGTH, &base_encoded)
}
}
};
Ok(result)
}
#[inline]