cdp-edge 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/README.md +153 -306
  2. package/bin/cdp-edge.js +71 -61
  3. package/contracts/agent-versions.json +682 -0
  4. package/contracts/api-versions.json +372 -368
  5. package/contracts/types.ts +81 -0
  6. package/dist/commands/analyze.js +52 -52
  7. package/dist/commands/infra.js +54 -54
  8. package/dist/commands/install.js +26 -3
  9. package/dist/commands/server.js +174 -174
  10. package/dist/commands/setup.js +332 -100
  11. package/dist/commands/validate.js +248 -84
  12. package/dist/index.js +12 -12
  13. package/dist/sdk/cdpTrack.js +2095 -0
  14. package/dist/sdk/cdpTrack.min.js +64 -0
  15. package/dist/sdk/install-snippet.html +10 -0
  16. package/docs/whatsapp-ctwa.md +5 -4
  17. package/extracted-skill/tracking-events-generator/INTEGRACAO-COMPLETA.md +89 -0
  18. package/extracted-skill/tracking-events-generator/MELHORIAS-IMPLEMENTADAS.md +101 -0
  19. package/extracted-skill/tracking-events-generator/advanced-matching.js +364 -364
  20. package/extracted-skill/tracking-events-generator/agents/ab-ltv-agent.md +196 -0
  21. package/extracted-skill/tracking-events-generator/agents/ab-testing-agent.md +1 -1
  22. package/extracted-skill/tracking-events-generator/agents/attribution-agent.md +41 -41
  23. package/extracted-skill/tracking-events-generator/agents/bidding-agent.md +347 -0
  24. package/extracted-skill/tracking-events-generator/agents/bing-agent.md +40 -50
  25. package/extracted-skill/tracking-events-generator/agents/browser-tracking.md +174 -74
  26. package/extracted-skill/tracking-events-generator/agents/code-guardian-agent.md +1 -1
  27. package/extracted-skill/tracking-events-generator/agents/compliance-agent.md +25 -5
  28. package/extracted-skill/tracking-events-generator/agents/dashboard-agent.md +10 -10
  29. package/extracted-skill/tracking-events-generator/agents/database-agent.md +43 -42
  30. package/extracted-skill/tracking-events-generator/agents/debug-agent.md +22 -22
  31. package/extracted-skill/tracking-events-generator/agents/devops-agent.md +232 -0
  32. package/extracted-skill/tracking-events-generator/agents/domain-setup-agent.md +23 -9
  33. package/extracted-skill/tracking-events-generator/agents/email-agent.md +28 -1
  34. package/extracted-skill/tracking-events-generator/agents/evo-crm-agent.md +244 -0
  35. package/extracted-skill/tracking-events-generator/agents/fingerprint-agent.md +206 -1
  36. package/extracted-skill/tracking-events-generator/agents/fraud-detection-agent.md +143 -0
  37. package/extracted-skill/tracking-events-generator/agents/google-agent.md +128 -2
  38. package/extracted-skill/tracking-events-generator/agents/intelligence-agent.md +191 -31
  39. package/extracted-skill/tracking-events-generator/agents/lead-scoring-agent.md +282 -0
  40. package/extracted-skill/tracking-events-generator/agents/linkedin-agent.md +145 -34
  41. package/extracted-skill/tracking-events-generator/agents/localization-agent.md +1 -1
  42. package/extracted-skill/tracking-events-generator/agents/ltv-predictor-agent.md +5 -5
  43. package/extracted-skill/tracking-events-generator/agents/master-feedback-loop.md +81 -21
  44. package/extracted-skill/tracking-events-generator/agents/master-orchestrator.md +428 -190
  45. package/extracted-skill/tracking-events-generator/agents/match-quality-agent.md +304 -0
  46. package/extracted-skill/tracking-events-generator/agents/memory-agent.json +25 -109
  47. package/extracted-skill/tracking-events-generator/agents/memory-agent.md +190 -15
  48. package/extracted-skill/tracking-events-generator/agents/meta-agent.md +10 -2
  49. package/extracted-skill/tracking-events-generator/agents/ml-clustering-agent.md +749 -0
  50. package/extracted-skill/tracking-events-generator/agents/page-analyzer.md +21 -4
  51. package/extracted-skill/tracking-events-generator/agents/performance-agent.md +41 -31
  52. package/extracted-skill/tracking-events-generator/agents/performance-optimization-agent.md +18 -8
  53. package/extracted-skill/tracking-events-generator/agents/pinterest-agent.md +14 -6
  54. package/extracted-skill/tracking-events-generator/agents/premium-tracking-intelligence-agent.md +7 -7
  55. package/extracted-skill/tracking-events-generator/agents/r2-setup-agent.md +16 -8
  56. package/extracted-skill/tracking-events-generator/agents/reddit-agent.md +15 -7
  57. package/extracted-skill/tracking-events-generator/agents/security-enterprise-agent.md +157 -48
  58. package/extracted-skill/tracking-events-generator/agents/server-tracking.md +35 -35
  59. package/extracted-skill/tracking-events-generator/agents/spotify-agent.md +15 -7
  60. package/extracted-skill/tracking-events-generator/agents/tiktok-agent.md +73 -2
  61. package/extracted-skill/tracking-events-generator/agents/tracking-plan-agent.md +104 -9
  62. package/extracted-skill/tracking-events-generator/agents/utm-agent.md +322 -0
  63. package/extracted-skill/tracking-events-generator/agents/validator-agent.md +13 -9
  64. package/extracted-skill/tracking-events-generator/agents/webhook-agent.md +112 -4
  65. package/extracted-skill/tracking-events-generator/agents/whatsapp-agent.md +58 -5
  66. package/extracted-skill/tracking-events-generator/agents/whatsapp-ctwa-setup-agent.md +26 -18
  67. package/extracted-skill/tracking-events-generator/agents/youtube-agent.md +152 -37
  68. package/extracted-skill/tracking-events-generator/anti-blocking.js +285 -285
  69. package/extracted-skill/tracking-events-generator/cdpTrack.js +642 -641
  70. package/extracted-skill/tracking-events-generator/contracts/api-versions.json +14 -10
  71. package/extracted-skill/tracking-events-generator/engagement-scoring.js +226 -226
  72. package/extracted-skill/tracking-events-generator/evals/evals.json +235 -235
  73. package/extracted-skill/tracking-events-generator/integration-test.js +497 -497
  74. package/extracted-skill/tracking-events-generator/knowledge-base.md +172 -0
  75. package/extracted-skill/tracking-events-generator/micro-events.js +992 -992
  76. package/extracted-skill/tracking-events-generator/models/lancamento-imobiliario.md +344 -0
  77. package/extracted-skill/tracking-events-generator/models/pinterest/conversions-api-template.js +144 -144
  78. package/extracted-skill/tracking-events-generator/models/pinterest/event-mappings.json +48 -48
  79. package/extracted-skill/tracking-events-generator/models/pinterest/tag-template.js +28 -28
  80. package/extracted-skill/tracking-events-generator/models/quiz-funnel.md +83 -19
  81. package/extracted-skill/tracking-events-generator/models/reddit/conversions-api-template.js +205 -205
  82. package/extracted-skill/tracking-events-generator/models/reddit/event-mappings.json +56 -56
  83. package/extracted-skill/tracking-events-generator/models/reddit/pixel-template.js +19 -19
  84. package/extracted-skill/tracking-events-generator/models/scenarios/behavior-engine.js +425 -425
  85. package/extracted-skill/tracking-events-generator/route-intent-capture.js +222 -0
  86. package/extracted-skill/tracking-events-generator/tracking.config.js +3 -3
  87. package/package.json +89 -75
  88. package/scripts/build-sdk.js +106 -0
  89. package/server-edge-tracker/.client.env.example +14 -0
  90. package/server-edge-tracker/INSTALAR.md +222 -23
  91. package/server-edge-tracker/SEGMENTATION-DOCS.md +513 -0
  92. package/server-edge-tracker/config/utm-mapping.json +64 -0
  93. package/server-edge-tracker/deploy-client.cjs +76 -0
  94. package/server-edge-tracker/index.ts +1230 -0
  95. package/server-edge-tracker/migrate-v7.sql +64 -0
  96. package/server-edge-tracker/modules/db.ts +710 -0
  97. package/server-edge-tracker/modules/dispatch/crm.ts +382 -0
  98. package/server-edge-tracker/modules/dispatch/ga4.ts +72 -0
  99. package/server-edge-tracker/modules/dispatch/meta.ts +143 -0
  100. package/server-edge-tracker/modules/dispatch/platforms.ts +255 -0
  101. package/server-edge-tracker/modules/dispatch/tiktok.ts +107 -0
  102. package/server-edge-tracker/modules/dispatch/whatsapp.ts +296 -0
  103. package/server-edge-tracker/modules/intelligence.ts +589 -0
  104. package/server-edge-tracker/modules/ml/bidding.ts +247 -0
  105. package/server-edge-tracker/modules/ml/fraud.ts +302 -0
  106. package/server-edge-tracker/modules/ml/logistic.ts +226 -0
  107. package/server-edge-tracker/modules/ml/ltv.ts +531 -0
  108. package/server-edge-tracker/modules/ml/matchquality.ts +232 -0
  109. package/server-edge-tracker/modules/ml/quiz.ts +343 -0
  110. package/server-edge-tracker/modules/ml/roas.ts +255 -0
  111. package/server-edge-tracker/modules/ml/segmentation.ts +407 -0
  112. package/server-edge-tracker/modules/nurture.ts +257 -0
  113. package/server-edge-tracker/modules/utils.ts +311 -0
  114. package/server-edge-tracker/modules/utm/utm-enricher.ts +231 -0
  115. package/server-edge-tracker/schema-ab-ltv.sql +97 -0
  116. package/server-edge-tracker/schema-bidding.sql +86 -0
  117. package/server-edge-tracker/schema-fraud.sql +90 -0
  118. package/server-edge-tracker/schema-indexes.sql +67 -0
  119. package/server-edge-tracker/schema-ltv-feedback.sql +11 -0
  120. package/server-edge-tracker/schema-quiz.sql +52 -0
  121. package/server-edge-tracker/schema-sales-engine.sql +113 -0
  122. package/server-edge-tracker/schema-segmentation.sql +219 -0
  123. package/server-edge-tracker/schema-utm.sql +82 -0
  124. package/server-edge-tracker/schema.sql +281 -265
  125. package/server-edge-tracker/types.ts +275 -0
  126. package/server-edge-tracker/wrangler.toml +140 -85
  127. package/templates/lancamento-imobiliario.md +344 -0
  128. package/templates/multi-step-checkout.md +3 -4
  129. package/templates/pinterest/conversions-api-template.js +144 -144
  130. package/templates/pinterest/event-mappings.json +48 -48
  131. package/templates/pinterest/tag-template.js +28 -28
  132. package/templates/quiz-funnel.md +83 -19
  133. package/templates/reddit/conversions-api-template.js +205 -205
  134. package/templates/reddit/event-mappings.json +56 -56
  135. package/templates/reddit/pixel-template.js +12 -39
  136. package/templates/scenarios/behavior-engine.js +45 -22
  137. package/docs/PixelBuilder-Documentacao-Completa (2).docx +0 -0
  138. package/docs/installation.md +0 -155
  139. package/docs/quick-start.md +0 -185
  140. package/extracted-skill/tracking-events-generator/agents/crm-integration-agent.md +0 -1419
  141. package/extracted-skill/tracking-events-generator/agents/intelligence-scheduling.md +0 -643
  142. package/server-edge-tracker/worker.js +0 -2574
@@ -43,7 +43,7 @@ Browser (Cliente) Worker (Server-Side) APIs (Meta/Google/TikT
43
43
 
44
44
  ### 1.1 Token Bucket Algorithm
45
45
 
46
- ```javascript
46
+ ```typescript
47
47
  // Rate limiting com token bucket
48
48
  const RATE_LIMIT_CONFIG = {
49
49
  // Limites por IP
@@ -127,7 +127,7 @@ const rateLimiters = {
127
127
 
128
128
  ### 1.2 Rate Limiting Middleware
129
129
 
130
- ```javascript
130
+ ```typescript
131
131
  // Middleware de rate limiting
132
132
  export async function applyRateLimiting(request, env) {
133
133
  const ip = request.headers.get('CF-Connecting-IP') || 'unknown';
@@ -260,7 +260,7 @@ export async function applyRateLimiting(request, env) {
260
260
 
261
261
  ### 1.3 Response Headers de Rate Limiting
262
262
 
263
- ```javascript
263
+ ```typescript
264
264
  // Headers de resposta com informações de rate limiting
265
265
  export function getRateLimitHeaders(checkResult) {
266
266
  const headers = {
@@ -285,7 +285,7 @@ export function getRateLimitHeaders(checkResult) {
285
285
 
286
286
  ### 2.1 Blacklist e Whitelist de IPs
287
287
 
288
- ```javascript
288
+ ```typescript
289
289
  // Configuração de IP blocking
290
290
  const IP_BLOCKING_CONFIG = {
291
291
  // Blacklist: IPs explicitamente bloqueados
@@ -396,13 +396,13 @@ CREATE INDEX IF NOT EXISTS idx_ip_violations_blocked ON ip_violations(blocked);
396
396
 
397
397
  ### 2.3 IP Blocking Middleware
398
398
 
399
- ```javascript
399
+ ```typescript
400
400
  // Middleware de IP blocking
401
401
  export async function checkIPBlocking(request, env) {
402
402
  const ip = request.headers.get('CF-Connecting-IP') || 'unknown';
403
403
 
404
404
  // 1. Verificar whitelist (primeiro - bypass rate limiting)
405
- const isWhitelisted = await checkIPWhitelist(ip);
405
+ const isWhitelisted = await checkIPWhitelist(ip, env);
406
406
  if (isWhitelisted) {
407
407
  return {
408
408
  allowed: true,
@@ -412,7 +412,7 @@ export async function checkIPBlocking(request, env) {
412
412
  }
413
413
 
414
414
  // 2. Verificar blacklist manual
415
- const isManuallyBlocked = await checkIPBlacklist(ip);
415
+ const isManuallyBlocked = await checkIPBlacklist(ip, env);
416
416
  if (isManuallyBlocked) {
417
417
  await logSecurityEvent({
418
418
  type: 'IP_BLACKLISTED',
@@ -430,7 +430,7 @@ export async function checkIPBlocking(request, env) {
430
430
  }
431
431
 
432
432
  // 3. Verificar geoblocking
433
- const isGeoBlocked = await checkGeoBlocking(request);
433
+ const isGeoBlocked = await checkGeoBlocking(request, env);
434
434
  if (isGeoBlocked) {
435
435
  await logSecurityEvent({
436
436
  type: 'IP_GEO_BLOCKED',
@@ -447,7 +447,7 @@ export async function checkIPBlocking(request, env) {
447
447
  }
448
448
 
449
449
  // 4. Verificar bloqueio automático (comportamento malicioso)
450
- const isAutoBlocked = await checkAutoIPBlocking(ip);
450
+ const isAutoBlocked = await checkAutoIPBlocking(ip, env);
451
451
  if (isAutoBlocked) {
452
452
  await logSecurityEvent({
453
453
  type: 'IP_AUTO_BLOCKED',
@@ -470,13 +470,13 @@ export async function checkIPBlocking(request, env) {
470
470
  }
471
471
 
472
472
  // Verificar se IP está na whitelist
473
- async function checkIPWhitelist(ip) {
473
+ async function checkIPWhitelist(ip, env) {
474
474
  if (!IP_BLOCKING_CONFIG.whitelist.enabled) {
475
475
  return false;
476
476
  }
477
477
 
478
478
  // 1. Verificar whitelist manual (IP exato)
479
- const manualWhitelist = await DB.prepare(`
479
+ const manualWhitelist = await env.DB.prepare(`
480
480
  SELECT ip, cidr_range
481
481
  FROM ip_whitelist
482
482
  WHERE ip = ?
@@ -497,8 +497,8 @@ async function checkIPWhitelist(ip) {
497
497
  }
498
498
 
499
499
  // Verificar se IP está na blacklist
500
- async function checkIPBlacklist(ip) {
501
- const blocked = await DB.prepare(`
500
+ async function checkIPBlacklist(ip, env) {
501
+ const blocked = await env.DB.prepare(`
502
502
  SELECT block_reason, blocked_at, unblocked_at, blocking_type, violation_count
503
503
  FROM ip_blacklist
504
504
  WHERE ip = ? AND unblocked_at IS NULL
@@ -508,7 +508,7 @@ async function checkIPBlacklist(ip) {
508
508
  }
509
509
 
510
510
  // Verificar geoblocking
511
- async function checkGeoBlocking(request) {
511
+ async function checkGeoBlocking(request, env) {
512
512
  if (!IP_BLOCKING_CONFIG.blacklist.geo_blocking.enabled) {
513
513
  return null;
514
514
  }
@@ -527,7 +527,7 @@ async function checkGeoBlocking(request) {
527
527
  }
528
528
 
529
529
  // Verificar bloqueio automático por comportamento
530
- async function checkAutoIPBlocking(ip) {
530
+ async function checkAutoIPBlocking(ip, env) {
531
531
  if (!IP_BLOCKING_CONFIG.blacklist.automatic.enabled) {
532
532
  return null;
533
533
  }
@@ -535,7 +535,7 @@ async function checkAutoIPBlocking(ip) {
535
535
  const config = IP_BLOCKING_CONFIG.blacklist.automatic;
536
536
 
537
537
  // 1. Verificar falhas por hora
538
- const failuresPerHour = await DB.prepare(`
538
+ const failuresPerHour = await env.DB.prepare(`
539
539
  SELECT COUNT(*) as failures
540
540
  FROM ip_violations
541
541
  WHERE ip = ?
@@ -544,7 +544,7 @@ async function checkAutoIPBlocking(ip) {
544
544
 
545
545
  if (failuresPerHour.failures >= config.threshold_failures_per_hour) {
546
546
  // Bloquear IP automaticamente
547
- await blockIPAutomatically(ip, 'EXCEEDED_FAILURES_PER_HOUR', failuresPerHour.failures);
547
+ await blockIPAutomatically(ip, 'EXCEEDED_FAILURES_PER_HOUR', failuresPerHour.failures, env);
548
548
  return {
549
549
  blocked: true,
550
550
  reason: 'EXCEEDED_FAILURES_PER_HOUR',
@@ -554,7 +554,7 @@ async function checkAutoIPBlocking(ip) {
554
554
  }
555
555
 
556
556
  // 2. Verificar falhas por dia
557
- const failuresPerDay = await DB.prepare(`
557
+ const failuresPerDay = await env.DB.prepare(`
558
558
  SELECT COUNT(*) as failures
559
559
  FROM ip_violations
560
560
  WHERE ip = ?
@@ -562,7 +562,7 @@ async function checkAutoIPBlocking(ip) {
562
562
  `).bind(ip).get();
563
563
 
564
564
  if (failuresPerDay.failures >= config.threshold_failures_per_day) {
565
- await blockIPAutomatically(ip, 'EXCEEDED_FAILURES_PER_DAY', failuresPerDay.failures);
565
+ await blockIPAutomatically(ip, 'EXCEEDED_FAILURES_PER_DAY', failuresPerDay.failures, env);
566
566
  return {
567
567
  blocked: true,
568
568
  reason: 'EXCEEDED_FAILURES_PER_DAY',
@@ -572,7 +572,7 @@ async function checkAutoIPBlocking(ip) {
572
572
  }
573
573
 
574
574
  // 3. Verificar erros 429 por hora
575
- const rateLimitErrorsPerHour = await DB.prepare(`
575
+ const rateLimitErrorsPerHour = await env.DB.prepare(`
576
576
  SELECT COUNT(*) as errors
577
577
  FROM ip_violations
578
578
  WHERE ip = ?
@@ -581,7 +581,7 @@ async function checkAutoIPBlocking(ip) {
581
581
  `).bind(ip).get();
582
582
 
583
583
  if (rateLimitErrorsPerHour.errors >= config.threshold_429_per_hour) {
584
- await blockIPAutomatically(ip, 'EXCEEDED_RATE_LIMITS_PER_HOUR', rateLimitErrorsPerHour.errors);
584
+ await blockIPAutomatically(ip, 'EXCEEDED_RATE_LIMITS_PER_HOUR', rateLimitErrorsPerHour.errors, env);
585
585
  return {
586
586
  blocked: true,
587
587
  reason: 'EXCEEDED_RATE_LIMITS_PER_HOUR',
@@ -594,10 +594,10 @@ async function checkAutoIPBlocking(ip) {
594
594
  }
595
595
 
596
596
  // Bloquear IP automaticamente
597
- async function blockIPAutomatically(ip, reason, count) {
597
+ async function blockIPAutomatically(ip, reason, count, env) {
598
598
  const now = new Date().toISOString();
599
599
 
600
- await DB.prepare(`
600
+ await env.DB.prepare(`
601
601
  INSERT OR REPLACE INTO ip_blacklist
602
602
  (ip, block_reason, blocked_at, blocking_type, violation_count, last_violation_type, last_violation_at)
603
603
  VALUES (?, ?, ?, ?, ?, ?, ?)
@@ -621,7 +621,7 @@ async function blockIPAutomatically(ip, reason, count) {
621
621
 
622
622
  ### 3.1 Schema Validation (Joi)
623
623
 
624
- ```javascript
624
+ ```typescript
625
625
  // Joi schema validation (via npm package)
626
626
  import Joi from 'joi';
627
627
 
@@ -740,7 +740,7 @@ export async function validateEvent(eventData, eventName) {
740
740
 
741
741
  ### 3.2 Sanitização de Dados (Anti-XSS, Anti-Injection)
742
742
 
743
- ```javascript
743
+ ```typescript
744
744
  // Sanitização de strings (anti-XSS)
745
745
  export function sanitizeString(input) {
746
746
  if (!input || typeof input !== 'string') {
@@ -925,9 +925,108 @@ export function sanitizePayload(eventData, eventName) {
925
925
  }
926
926
  ```
927
927
 
928
- ### 3.3 Middleware de Validação e Sanitização
928
+ ### 3.3 CSRF Protection (Anti-Cross-Site Request Forgery)
929
+
930
+ CSRF é relevante nos **endpoints de webhook** (Hotmart, Kiwify, Ticto) onde um atacante pode forjar requisições. A proteção é HMAC-SHA256 por assinatura — cada plataforma assina o payload com um secret compartilhado.
931
+
932
+ ```typescript
933
+ /**
934
+ * Verificação CSRF via HMAC-SHA256 para webhooks de plataformas de pagamento.
935
+ * Cada plataforma tem seu próprio header e algoritmo.
936
+ *
937
+ * @param {Request} request
938
+ * @param {Object} env
939
+ * @param {string} gateway - 'hotmart' | 'kiwify' | 'ticto' | 'stripe'
940
+ * @returns {Promise<boolean>} true se assinatura válida
941
+ */
942
+ export async function validateWebhookSignature(request, env, gateway) {
943
+ const body = await request.text(); // Ler como texto para HMAC exato
944
+
945
+ switch (gateway) {
946
+ case 'hotmart': {
947
+ // Hotmart: header X-Hotmart-Hottok (token fixo, não HMAC)
948
+ const token = request.headers.get('X-Hotmart-Hottok');
949
+ return token === env.WEBHOOK_SECRET_HOTMART;
950
+ }
951
+
952
+ case 'kiwify': {
953
+ // Kiwify: query param ?signature=HMAC_SHA256(body, secret)
954
+ const url = new URL(request.url);
955
+ const receivedSig = url.searchParams.get('signature') || '';
956
+ const expectedSig = await hmacSHA256(body, env.WEBHOOK_SECRET_KIWIFY);
957
+ return timingSafeEqual(receivedSig, expectedSig);
958
+ }
959
+
960
+ case 'ticto': {
961
+ // Ticto: header X-Ticto-Signature = HMAC_SHA256(body, secret)
962
+ const receivedSig = request.headers.get('X-Ticto-Signature') || '';
963
+ const expectedSig = await hmacSHA256(body, env.WEBHOOK_SECRET_TICTO);
964
+ return timingSafeEqual(receivedSig, expectedSig);
965
+ }
966
+
967
+ case 'stripe': {
968
+ // Stripe: header Stripe-Signature = t={ts},v1={HMAC}
969
+ const sigHeader = request.headers.get('Stripe-Signature') || '';
970
+ const parts = Object.fromEntries(sigHeader.split(',').map(p => p.split('=')));
971
+ const signedPayload = `${parts.t}.${body}`;
972
+ const expectedSig = await hmacSHA256(signedPayload, env.STRIPE_WEBHOOK_SECRET);
973
+ return timingSafeEqual(parts.v1, expectedSig);
974
+ }
975
+
976
+ default:
977
+ return false; // Gateway desconhecido = rejeitar
978
+ }
979
+ }
980
+
981
+ // HMAC-SHA256 usando WebCrypto (disponível em Cloudflare Workers)
982
+ async function hmacSHA256(message, secret) {
983
+ const encoder = new TextEncoder();
984
+ const key = await crypto.subtle.importKey(
985
+ 'raw', encoder.encode(secret),
986
+ { name: 'HMAC', hash: 'SHA-256' },
987
+ false, ['sign']
988
+ );
989
+ const sig = await crypto.subtle.sign('HMAC', key, encoder.encode(message));
990
+ return Array.from(new Uint8Array(sig)).map(b => b.toString(16).padStart(2, '0')).join('');
991
+ }
992
+
993
+ // Comparação em tempo constante — previne timing attacks
994
+ function timingSafeEqual(a, b) {
995
+ if (a.length !== b.length) return false;
996
+ let diff = 0;
997
+ for (let i = 0; i < a.length; i++) {
998
+ diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
999
+ }
1000
+ return diff === 0;
1001
+ }
1002
+
1003
+ /**
1004
+ * Uso no handler de webhook:
1005
+ *
1006
+ * const isValid = await validateWebhookSignature(request, env, 'hotmart');
1007
+ * if (!isValid) return new Response('Unauthorized', { status: 401 });
1008
+ *
1009
+ * REGRA: Validar assinatura ANTES de parsear o body JSON.
1010
+ * Re-clonar o request se precisar ler o body depois:
1011
+ * const clonedRequest = request.clone();
1012
+ * const valid = await validateWebhookSignature(clonedRequest, env, gateway);
1013
+ * const body = await request.json(); // original ainda disponível
1014
+ */
1015
+ ```
1016
+
1017
+ ### Checklist CSRF
929
1018
 
930
- ```javascript
1019
+ - [ ] HMAC validado para Hotmart, Kiwify, Ticto antes de processar
1020
+ - [ ] Rejeição 401 imediata se assinatura inválida
1021
+ - [ ] Uso de `timingSafeEqual` para prevenir timing attacks
1022
+ - [ ] Body lido como texto para HMAC (não como JSON — evita parsing antes da validação)
1023
+ - [ ] Secrets via `wrangler secret put WEBHOOK_SECRET_HOTMART` etc.
1024
+
1025
+ ---
1026
+
1027
+ ### 3.4 Middleware de Validação e Sanitização
1028
+
1029
+ ```typescript
931
1030
  // Middleware de segurança completo
932
1031
  export async function applySecurityMiddleware(request, env) {
933
1032
  const ip = request.headers.get('CF-Connecting-IP') || 'unknown';
@@ -1049,7 +1148,7 @@ export async function applySecurityMiddleware(request, env) {
1049
1148
 
1050
1149
  ### 4.1 Configuração de Encryption
1051
1150
 
1052
- ```javascript
1151
+ ```typescript
1053
1152
  // Configuração de encryption
1054
1153
  const ENCRYPTION_CONFIG = {
1055
1154
  // Algoritmos de hash (para enviar às plataformas)
@@ -1087,7 +1186,7 @@ const ENCRYPTION_CONFIG = {
1087
1186
 
1088
1187
  ### 4.2 Hashing Functions (SHA256 - Web Crypto API)
1089
1188
 
1090
- ```javascript
1189
+ ```typescript
1091
1190
  // Hashing de email
1092
1191
  export async function hashEmail(email) {
1093
1192
  if (!email) return null;
@@ -1204,7 +1303,7 @@ export async function hashCEP(cep) {
1204
1303
 
1205
1304
  ### 4.3 Encryption Functions (AES-256-GCM)
1206
1305
 
1207
- ```javascript
1306
+ ```typescript
1208
1307
  // Encriptação de dados sensíveis
1209
1308
  const encryptionKeys = new Map();
1210
1309
 
@@ -1348,7 +1447,7 @@ CREATE INDEX IF NOT EXISTS idx_audit_blocked ON audit_logs(blocked);
1348
1447
 
1349
1448
  ### 5.2 Tipos de Audit Log
1350
1449
 
1351
- ```javascript
1450
+ ```typescript
1352
1451
  // Tipos de log de segurança
1353
1452
  const AUDIT_LOG_TYPES = {
1354
1453
  // Rate Limiting
@@ -1399,9 +1498,9 @@ const SEVERITY_LEVELS = {
1399
1498
 
1400
1499
  ### 5.3 Funções de Audit Logging
1401
1500
 
1402
- ```javascript
1501
+ ```typescript
1403
1502
  // Log de evento de segurança
1404
- export async function logSecurityEvent(eventData) {
1503
+ export async function logSecurityEvent(eventData, env) {
1405
1504
  const {
1406
1505
  type,
1407
1506
  severity,
@@ -1419,7 +1518,7 @@ export async function logSecurityEvent(eventData) {
1419
1518
 
1420
1519
  const timestamp = new Date().toISOString();
1421
1520
 
1422
- await DB.prepare(`
1521
+ await env.DB.prepare(`
1423
1522
  INSERT INTO audit_logs
1424
1523
  (timestamp, ip, user_id, session_id, user_agent, event_name, event_id,
1425
1524
  log_type, severity, action, outcome, details, blocked)
@@ -1453,7 +1552,7 @@ export async function logSecurityEvent(eventData) {
1453
1552
  }
1454
1553
 
1455
1554
  // Query de audit logs
1456
- export async function queryAuditLogs(filters = {}) {
1555
+ export async function queryAuditLogs(filters = {}, env) {
1457
1556
  const {
1458
1557
  ip,
1459
1558
  user_id,
@@ -1509,7 +1608,7 @@ export async function queryAuditLogs(filters = {}) {
1509
1608
 
1510
1609
  query += ' ORDER BY timestamp DESC LIMIT ?';
1511
1610
 
1512
- const results = await DB.prepare(query).bind(...params).all();
1611
+ const results = await env.DB.prepare(query).bind(...params).all();
1513
1612
 
1514
1613
  return results;
1515
1614
  }
@@ -1521,7 +1620,7 @@ export async function queryAuditLogs(filters = {}) {
1521
1620
 
1522
1621
  ### 6.1 Endpoint: `/api/security/rate-limit-status`
1523
1622
 
1524
- ```javascript
1623
+ ```typescript
1525
1624
  export async function getRateLimitStatus(request, env) {
1526
1625
  const ip = request.headers.get('CF-Connecting-IP') || 'unknown';
1527
1626
 
@@ -1539,7 +1638,7 @@ export async function getRateLimitStatus(request, env) {
1539
1638
  refill_rate: rateLimiters.event.get('global').refillRate
1540
1639
  }
1541
1640
  },
1542
- recent_violations: await DB.prepare(`
1641
+ recent_violations: await env.DB.prepare(`
1543
1642
  SELECT
1544
1643
  log_type,
1545
1644
  severity,
@@ -1561,14 +1660,14 @@ export async function getRateLimitStatus(request, env) {
1561
1660
 
1562
1661
  ### 6.2 Endpoint: `/api/security/ip-status`
1563
1662
 
1564
- ```javascript
1663
+ ```typescript
1565
1664
  export async function getIPStatus(request, env) {
1566
1665
  const ip = request.headers.get('CF-Connecting-IP') || 'unknown';
1567
1666
 
1568
1667
  // Verificar status do IP
1569
- const blacklist = await checkIPBlacklist(ip);
1570
- const whitelist = await checkIPWhitelist(ip);
1571
- const geoBlock = await checkGeoBlocking(request);
1668
+ const blacklist = await checkIPBlacklist(ip, env);
1669
+ const whitelist = await checkIPWhitelist(ip, env);
1670
+ const geoBlock = await checkGeoBlocking(request, env);
1572
1671
 
1573
1672
  const status = {
1574
1673
  ip,
@@ -1577,7 +1676,7 @@ export async function getIPStatus(request, env) {
1577
1676
  blacklist_reason: blacklist ? blacklist.block_reason : null,
1578
1677
  is_geo_blocked: !!geoBlock,
1579
1678
  geo_details: geoBlock || null,
1580
- recent_violations: await DB.prepare(`
1679
+ recent_violations: await env.DB.prepare(`
1581
1680
  SELECT
1582
1681
  COUNT(*) as violations,
1583
1682
  MAX(violation_count) as max_violation_count
@@ -1597,7 +1696,7 @@ export async function getIPStatus(request, env) {
1597
1696
 
1598
1697
  ### 6.3 Endpoint: `/api/security/audit-logs`
1599
1698
 
1600
- ```javascript
1699
+ ```typescript
1601
1700
  export async function getAuditLogs(request, env) {
1602
1701
  const url = new URL(request.url);
1603
1702
  const filters = {
@@ -1630,10 +1729,10 @@ export async function getAuditLogs(request, env) {
1630
1729
 
1631
1730
  ## 🎯 FORMATO DE SAÍDA
1632
1731
 
1633
- ### DELIVERABLE 1: `security-middleware.js`
1732
+ ### DELIVERABLE 1: `modules/security-middleware.ts`
1634
1733
 
1635
- ```javascript
1636
- // security-middleware.js - Middleware de segurança completo
1734
+ ```typescript
1735
+ // modules/security-middleware.ts - Middleware de segurança completo
1637
1736
  export {
1638
1737
  applyRateLimiting,
1639
1738
  checkIPBlocking,
@@ -1666,7 +1765,7 @@ CREATE TABLE IF NOT EXISTS audit_logs (...);
1666
1765
 
1667
1766
  ### DELIVERABLE 3: `security-config.js`
1668
1767
 
1669
- ```javascript
1768
+ ```typescript
1670
1769
  // security-config.js - Configuração de segurança
1671
1770
  export const RATE_LIMIT_CONFIG = { ... };
1672
1771
  export const IP_BLOCKING_CONFIG = { ... };
@@ -1699,6 +1798,16 @@ export const SEVERITY_LEVELS = { ... };
1699
1798
  - [ ] CIDR ranges implementados
1700
1799
  - [ ] Auto-unblock implementado
1701
1800
 
1801
+ ### CSRF Protection (Webhooks)
1802
+
1803
+ - [ ] HMAC-SHA256 validado para Hotmart
1804
+ - [ ] HMAC-SHA256 validado para Kiwify
1805
+ - [ ] HMAC-SHA256 validado para Ticto
1806
+ - [ ] HMAC-SHA256 validado para Stripe
1807
+ - [ ] `timingSafeEqual` implementado (sem timing attacks)
1808
+ - [ ] Body lido como text antes do JSON.parse para validação HMAC
1809
+ - [ ] Secrets via `wrangler secret put` (nunca hardcode)
1810
+
1702
1811
  ### Input Validation
1703
1812
 
1704
1813
  - [ ] Joi schemas criados (Lead, Purchase, Contact)