WebhookTriggerProviders can by async
What changed, and why it matters
This commit is a routine code refactor that lets webhook event providers run their lookup logic asynchronously. It changes a synchronous method to an async one and updates callers to await it. There is no security issue visible in the diff.
No security action needed. Review as normal async refactor if desired.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch converts WebhookTriggerProvider.GetWebhookEvent(object) into GetWebhookEventAsync(object) returning Task
Changed components
BTCPayServer.Plugins.Webhooks.WebhookTriggerProviderBTCPayServer.Plugins.Webhooks.HostedServices.WebhookProviderHostedServiceInspect captured patch +21 / −7
diff --git a/BTCPayServer/Plugins/Webhooks/HostedServices/WebhookProviderHostedService.cs b/BTCPayServer/Plugins/Webhooks/HostedServices/WebhookProviderHostedService.cs
index 6f94b4b..ff81b0f 100644
--- a/BTCPayServer/Plugins/Webhooks/HostedServices/WebhookProviderHostedService.cs
+++ b/BTCPayServer/Plugins/Webhooks/HostedServices/WebhookProviderHostedService.cs
@@ -38,9 +38,7 @@ public class WebhookProviderHostedService(
protected override async Task ProcessEvent(object evt, CancellationToken cancellationToken)
{
- var (provider, webhookEvent) = webhookTriggerProviders
- .Select(o => (o, o.GetWebhookEvent(evt)))
- .FirstOrDefault(o => o.Item2 is not null);
+ var (provider, webhookEvent) = await GetWebhookEvent(evt);
if (webhookEvent is null || provider is null)
return;
@@ -66,6 +64,17 @@ public class WebhookProviderHostedService(
}
}
+ private async Task<(WebhookTriggerProvider?, StoreWebhookEvent?)> GetWebhookEvent(object evt)
+ {
+ foreach (var provider in webhookTriggerProviders)
+ {
+ var webhookEvent = await provider.GetWebhookEventAsync(evt);
+ if (webhookEvent is not null)
+ return (provider, webhookEvent);
+ }
+ return (null, null);
+ }
+
private StoreWebhookEvent Clone(StoreWebhookEvent webhookEvent)
=> (StoreWebhookEvent)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(webhookEvent), webhookEvent.GetType(), WebhookSender.DefaultSerializerSettings)!;
diff --git a/BTCPayServer/Plugins/Webhooks/WebhookTriggerProvider.cs b/BTCPayServer/Plugins/Webhooks/WebhookTriggerProvider.cs
index 559f290..7de4880 100644
--- a/BTCPayServer/Plugins/Webhooks/WebhookTriggerProvider.cs
+++ b/BTCPayServer/Plugins/Webhooks/WebhookTriggerProvider.cs
@@ -12,7 +12,7 @@ namespace BTCPayServer.Plugins.Webhooks;
public abstract class WebhookTriggerProvider
{
- public abstract StoreWebhookEvent? GetWebhookEvent(object evt);
+ public abstract Task<StoreWebhookEvent?> GetWebhookEventAsync(object evt);
public virtual Task<JObject> GetEmailModel(WebhookTriggerContext webhookTriggerContext)
{
@@ -36,9 +36,14 @@ public abstract class WebhookTriggerProvider
public abstract class WebhookTriggerProvider<T> : WebhookTriggerProvider where T : class
{
- public sealed override StoreWebhookEvent? GetWebhookEvent(object evt)
- => evt is T t ? GetWebhookEvent(t) : null;
- protected abstract StoreWebhookEvent? GetWebhookEvent(T evt);
+ public sealed override async Task<StoreWebhookEvent?> GetWebhookEventAsync(object evt)
+ => evt is T t ? await GetWebhookEventAsync(t) : null;
+
+ protected virtual Task<StoreWebhookEvent?> GetWebhookEventAsync(T evt)
+ => Task.FromResult<StoreWebhookEvent?>(GetWebhookEvent(evt));
+
+ protected virtual StoreWebhookEvent? GetWebhookEvent(T evt) => null;
+
public sealed override Task<JObject> GetEmailModel(WebhookTriggerContext webhookTriggerContext)
=> GetEmailModel((WebhookTriggerContext<T>)webhookTriggerContext);
protected virtual Task<JObject> GetEmailModel(WebhookTriggerContext<T> webhookTriggerContext)
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.