feat: add Resend inbound webhook endpoint and client (refs #155)
- ResendInboundClient: webhook signature verification via Svix, email fetch/download/parse with mailparser - POST /api/webhooks/resend/inbound endpoint with rawBody, signature verification, idempotency check, queue insertion, async processing - Config: resend_webhook_secret (optional) in secrets schema - Route registration in app.ts following Stripe webhook pattern Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -126,6 +126,7 @@ const secretsSchema = z.object({
|
||||
auth0_management_client_secret: z.string(),
|
||||
google_maps_api_key: z.string(),
|
||||
resend_api_key: z.string(),
|
||||
resend_webhook_secret: z.string().optional(),
|
||||
// Stripe secrets (API keys only - price IDs are config, not secrets)
|
||||
stripe_secret_key: z.string(),
|
||||
stripe_webhook_secret: z.string(),
|
||||
@@ -143,6 +144,10 @@ export interface AppConfiguration {
|
||||
getRedisUrl(): string;
|
||||
getAuth0Config(): { domain: string; audience: string; clientSecret: string };
|
||||
getAuth0ManagementConfig(): { domain: string; clientId: string; clientSecret: string };
|
||||
getResendConfig(): {
|
||||
apiKey: string;
|
||||
webhookSecret: string | undefined;
|
||||
};
|
||||
getStripeConfig(): {
|
||||
secretKey: string;
|
||||
webhookSecret: string;
|
||||
@@ -185,6 +190,7 @@ class ConfigurationLoader {
|
||||
'auth0-management-client-secret',
|
||||
'google-maps-api-key',
|
||||
'resend-api-key',
|
||||
'resend-webhook-secret',
|
||||
'stripe-secret-key',
|
||||
'stripe-webhook-secret',
|
||||
];
|
||||
@@ -250,6 +256,13 @@ class ConfigurationLoader {
|
||||
};
|
||||
},
|
||||
|
||||
getResendConfig() {
|
||||
return {
|
||||
apiKey: secrets.resend_api_key,
|
||||
webhookSecret: secrets.resend_webhook_secret,
|
||||
};
|
||||
},
|
||||
|
||||
getStripeConfig() {
|
||||
return {
|
||||
secretKey: secrets.stripe_secret_key,
|
||||
@@ -258,8 +271,11 @@ class ConfigurationLoader {
|
||||
},
|
||||
};
|
||||
|
||||
// Set RESEND_API_KEY in environment for EmailService
|
||||
// Set Resend environment variables for EmailService and webhook verification
|
||||
process.env['RESEND_API_KEY'] = secrets.resend_api_key;
|
||||
if (secrets.resend_webhook_secret) {
|
||||
process.env['RESEND_WEBHOOK_SECRET'] = secrets.resend_webhook_secret;
|
||||
}
|
||||
|
||||
logger.info('Configuration loaded successfully', {
|
||||
configSource: 'yaml',
|
||||
|
||||
Reference in New Issue
Block a user