hookarmor 1.0.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.
@@ -0,0 +1,549 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>HookArmor - Never Lose a Stripe or Shopify Webhook Again</title>
7
+ <meta name="description" content="Zero-loss Webhook Dead-Letter Queue (DLQ), Ingress Proxy, and 1-Click Replay Gateway for Stripe, Shopify, Clerk, and modern B2B SaaS.">
8
+ <link rel="canonical" href="https://hookarmour.dev/">
9
+
10
+ <!-- OpenGraph / Facebook / LinkedIn / Slack -->
11
+ <meta property="og:type" content="website">
12
+ <meta property="og:url" content="https://hookarmour.dev/">
13
+ <meta property="og:title" content="HookArmor - Never Lose a Stripe or Shopify Webhook Again">
14
+ <meta property="og:description" content="Zero-loss Webhook Dead-Letter Queue (DLQ), instant buffer, and 1-click replay gateway for Stripe, Shopify, and B2B SaaS.">
15
+ <meta property="og:site_name" content="HookArmor">
16
+ <meta property="og:image" content="https://hookarmour.dev/og-preview.png">
17
+ <meta property="og:image:width" content="1200">
18
+ <meta property="og:image:height" content="630">
19
+
20
+ <!-- Twitter / X -->
21
+ <meta name="twitter:card" content="summary_large_image">
22
+ <meta name="twitter:url" content="https://hookarmour.dev/">
23
+ <meta name="twitter:title" content="HookArmor - Never Lose a Stripe or Shopify Webhook Again">
24
+ <meta name="twitter:description" content="Zero-loss Webhook Dead-Letter Queue (DLQ), instant buffer, and 1-click replay gateway for Stripe, Shopify, and B2B SaaS.">
25
+ <meta name="twitter:image" content="https://hookarmour.dev/og-preview.png">
26
+
27
+ <!-- JSON-LD Structured Data for Google Rich Snippets -->
28
+ <script type="application/ld+json">
29
+ {
30
+ "@context": "https://schema.org",
31
+ "@type": "SoftwareApplication",
32
+ "name": "HookArmor",
33
+ "url": "https://hookarmour.dev",
34
+ "applicationCategory": "DeveloperApplication",
35
+ "operatingSystem": "Cloud / Docker / Node.js",
36
+ "description": "Zero-loss Webhook Dead-Letter Queue (DLQ), sub-10ms ingress buffer, and 1-click replay gateway for Stripe, Shopify, and B2B SaaS.",
37
+ "offers": {
38
+ "@type": "Offer",
39
+ "price": "0",
40
+ "priceCurrency": "USD"
41
+ }
42
+ }
43
+ </script>
44
+
45
+ <link rel="preconnect" href="https://fonts.googleapis.com">
46
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
47
+ <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
48
+ <style>
49
+ :root {
50
+ --bg: #070a12;
51
+ --bg-card: #0d1322;
52
+ --border: #1e293b;
53
+ --accent: #3b82f6;
54
+ --accent-glow: rgba(59, 130, 246, 0.25);
55
+ --text: #f8fafc;
56
+ --text-muted: #94a3b8;
57
+ --emerald: #10b981;
58
+ --rose: #f43f5e;
59
+ --font-sans: 'Plus Jakarta Sans', sans-serif;
60
+ --font-mono: 'JetBrains Mono', monospace;
61
+ }
62
+ * { box-sizing: border-box; margin: 0; padding: 0; }
63
+ body {
64
+ background: var(--bg);
65
+ color: var(--text);
66
+ font-family: var(--font-sans);
67
+ line-height: 1.6;
68
+ overflow-x: hidden;
69
+ }
70
+ nav {
71
+ max-width: 1200px;
72
+ margin: 0 auto;
73
+ padding: 1.5rem 2rem;
74
+ display: flex;
75
+ justify-content: space-between;
76
+ align-items: center;
77
+ }
78
+ .logo {
79
+ display: flex;
80
+ align-items: center;
81
+ gap: 0.75rem;
82
+ font-weight: 800;
83
+ font-size: 1.25rem;
84
+ color: white;
85
+ text-decoration: none;
86
+ }
87
+ .badge-v1 {
88
+ font-size: 0.65rem;
89
+ background: rgba(59, 130, 246, 0.15);
90
+ color: var(--accent);
91
+ border: 1px solid rgba(59, 130, 246, 0.3);
92
+ padding: 0.15rem 0.5rem;
93
+ border-radius: 9999px;
94
+ font-weight: 700;
95
+ }
96
+ .nav-cta {
97
+ display: flex;
98
+ gap: 1rem;
99
+ align-items: center;
100
+ }
101
+ .btn {
102
+ display: inline-flex;
103
+ align-items: center;
104
+ gap: 0.5rem;
105
+ padding: 0.65rem 1.25rem;
106
+ border-radius: 8px;
107
+ font-weight: 700;
108
+ font-size: 0.9rem;
109
+ text-decoration: none;
110
+ transition: all 0.2s;
111
+ cursor: pointer;
112
+ }
113
+ .btn-primary {
114
+ background: #2563eb;
115
+ color: white;
116
+ box-shadow: 0 4px 20px rgba(37, 99, 235, 0.4);
117
+ }
118
+ .btn-primary:hover { background: #1d4ed8; transform: translateY(-1px); }
119
+ .btn-outline {
120
+ background: transparent;
121
+ border: 1px solid var(--border);
122
+ color: var(--text);
123
+ }
124
+ .btn-outline:hover { background: var(--bg-card); border-color: #475569; }
125
+
126
+ /* Hero */
127
+ .hero {
128
+ max-width: 1100px;
129
+ margin: 4rem auto 2rem;
130
+ padding: 0 2rem;
131
+ text-align: center;
132
+ display: flex;
133
+ flex-direction: column;
134
+ align-items: center;
135
+ gap: 1.5rem;
136
+ }
137
+ .pill {
138
+ display: inline-flex;
139
+ align-items: center;
140
+ gap: 0.5rem;
141
+ background: rgba(16, 185, 129, 0.1);
142
+ color: var(--emerald);
143
+ border: 1px solid rgba(16, 185, 129, 0.25);
144
+ padding: 0.35rem 0.85rem;
145
+ border-radius: 9999px;
146
+ font-size: 0.8rem;
147
+ font-weight: 700;
148
+ }
149
+ h1 {
150
+ font-size: clamp(2.5rem, 5vw, 4.2rem);
151
+ font-weight: 800;
152
+ line-height: 1.15;
153
+ letter-spacing: -0.03em;
154
+ }
155
+ .gradient-text {
156
+ background: linear-gradient(135deg, #60a5fa 0%, #a855f7 100%);
157
+ -webkit-background-clip: text;
158
+ -webkit-text-fill-color: transparent;
159
+ }
160
+ .hero p {
161
+ font-size: 1.2rem;
162
+ color: var(--text-muted);
163
+ max-width: 720px;
164
+ }
165
+ .hero-actions {
166
+ display: flex;
167
+ gap: 1rem;
168
+ margin-top: 1rem;
169
+ flex-wrap: wrap;
170
+ justify-content: center;
171
+ }
172
+
173
+ /* Terminal Quickstart */
174
+ .terminal-box {
175
+ background: #00040a;
176
+ border: 1px solid var(--border);
177
+ border-radius: 12px;
178
+ padding: 1.25rem 1.75rem;
179
+ display: flex;
180
+ align-items: center;
181
+ gap: 1.25rem;
182
+ font-family: var(--font-mono);
183
+ font-size: 0.95rem;
184
+ color: #38bdf8;
185
+ margin-top: 1.5rem;
186
+ box-shadow: 0 20px 40px rgba(0,0,0,0.6);
187
+ }
188
+ .copy-btn {
189
+ background: #1e293b;
190
+ border: none;
191
+ color: #94a3b8;
192
+ padding: 0.35rem 0.75rem;
193
+ border-radius: 6px;
194
+ cursor: pointer;
195
+ font-size: 0.8rem;
196
+ }
197
+ .copy-btn:hover { color: white; background: #334155; }
198
+
199
+ /* Pain & Feature Section */
200
+ .section {
201
+ max-width: 1200px;
202
+ margin: 6rem auto;
203
+ padding: 0 2rem;
204
+ }
205
+ .section-title {
206
+ text-align: center;
207
+ margin-bottom: 3.5rem;
208
+ }
209
+ .section-title h2 {
210
+ font-size: 2.2rem;
211
+ font-weight: 800;
212
+ letter-spacing: -0.02em;
213
+ }
214
+ .section-title p {
215
+ color: var(--text-muted);
216
+ margin-top: 0.5rem;
217
+ }
218
+
219
+ .grid-3 {
220
+ display: grid;
221
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
222
+ gap: 1.5rem;
223
+ }
224
+ .card {
225
+ background: var(--bg-card);
226
+ border: 1px solid var(--border);
227
+ border-radius: 16px;
228
+ padding: 2rem;
229
+ display: flex;
230
+ flex-direction: column;
231
+ gap: 1rem;
232
+ }
233
+ .card-icon {
234
+ width: 48px;
235
+ height: 48px;
236
+ border-radius: 12px;
237
+ display: flex;
238
+ align-items: center;
239
+ justify-content: center;
240
+ font-size: 1.5rem;
241
+ }
242
+ .card h3 {
243
+ font-size: 1.2rem;
244
+ font-weight: 700;
245
+ }
246
+ .card p {
247
+ color: var(--text-muted);
248
+ font-size: 0.95rem;
249
+ }
250
+
251
+ /* Comparison Table */
252
+ .comparison-table {
253
+ width: 100%;
254
+ border-collapse: collapse;
255
+ margin-top: 2rem;
256
+ font-size: 0.9rem;
257
+ }
258
+ .comparison-table th, .comparison-table td {
259
+ padding: 1rem 1.25rem;
260
+ border-bottom: 1px solid var(--border);
261
+ text-align: left;
262
+ }
263
+ .comparison-table th {
264
+ background: #090e1a;
265
+ color: var(--text-muted);
266
+ font-weight: 700;
267
+ }
268
+
269
+ /* Pricing Section */
270
+ .pricing-grid {
271
+ display: grid;
272
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
273
+ gap: 1.5rem;
274
+ margin-top: 3rem;
275
+ }
276
+ .pricing-card {
277
+ background: var(--bg-card);
278
+ border: 1px solid var(--border);
279
+ border-radius: 16px;
280
+ padding: 2rem;
281
+ display: flex;
282
+ flex-direction: column;
283
+ gap: 1.25rem;
284
+ position: relative;
285
+ }
286
+ .pricing-card.featured {
287
+ border-color: var(--accent);
288
+ box-shadow: 0 0 30px rgba(59, 130, 246, 0.2);
289
+ }
290
+ .featured-badge {
291
+ position: absolute;
292
+ top: -12px;
293
+ left: 50%;
294
+ transform: translateX(-50%);
295
+ background: #2563eb;
296
+ color: white;
297
+ padding: 0.2rem 0.75rem;
298
+ border-radius: 9999px;
299
+ font-size: 0.75rem;
300
+ font-weight: 700;
301
+ }
302
+ .price {
303
+ font-size: 2.5rem;
304
+ font-weight: 800;
305
+ }
306
+ .price span {
307
+ font-size: 1rem;
308
+ color: var(--text-muted);
309
+ font-weight: 500;
310
+ }
311
+ .feature-list {
312
+ list-style: none;
313
+ display: flex;
314
+ flex-direction: column;
315
+ gap: 0.6rem;
316
+ font-size: 0.9rem;
317
+ }
318
+ .feature-list li {
319
+ display: flex;
320
+ align-items: center;
321
+ gap: 0.5rem;
322
+ color: #cbd5e1;
323
+ }
324
+
325
+ footer {
326
+ border-top: 1px solid var(--border);
327
+ padding: 3rem 2rem;
328
+ text-align: center;
329
+ color: var(--text-muted);
330
+ font-size: 0.85rem;
331
+ margin-top: 6rem;
332
+ }
333
+ </style>
334
+ </head>
335
+ <body>
336
+
337
+ <nav>
338
+ <a href="#" class="logo">
339
+ <span>🛡️</span> HookArmor <span class="badge-v1">Open Source Beta</span>
340
+ </a>
341
+ <div class="nav-cta">
342
+ <a href="/blog" class="btn btn-outline">Blog</a>
343
+ <a href="/dashboard" class="btn btn-outline">Live Demo</a>
344
+ <a href="#pricing" class="btn btn-outline">Pricing</a>
345
+ <a href="https://github.com/pkdoddamani/hookarmor" class="btn btn-primary" target="_blank">Star on GitHub ⭐</a>
346
+ </div>
347
+ </nav>
348
+
349
+ <header class="hero">
350
+ <div class="pill">⚡ Tested & Verified Across 5 Failover Scenarios</div>
351
+ <h1>Never Lose a <span class="gradient-text">Stripe or Shopify</span> Webhook Again.</h1>
352
+ <p>
353
+ Zero-downtime deploys and serverless cold starts silently drop webhooks. Stripe retries days later. HookArmor acts as your zero-loss Dead-Letter Queue (DLQ), fast ingress buffer, and 1-click replay engine.
354
+ </p>
355
+
356
+ <!-- Waitlist Capture Form -->
357
+ <div style="margin-top: 1.5rem; width: 100%; max-width: 480px;">
358
+ <form id="waitlist-form" onsubmit="handleWaitlist(event)" style="display: flex; gap: 0.5rem; background: #0d1322; border: 1px solid var(--border); padding: 0.4rem; border-radius: 10px;">
359
+ <input type="email" id="waitlist-email" placeholder="Enter your work email for Cloud Beta..." required style="flex: 1; background: transparent; border: none; padding: 0.6rem 0.8rem; color: white; outline: none; font-size: 0.9rem;">
360
+ <button type="submit" class="btn btn-primary" style="padding: 0.6rem 1.2rem; font-size: 0.85rem;">Join Cloud Beta</button>
361
+ </form>
362
+ <div id="waitlist-msg" style="font-size: 0.85rem; margin-top: 0.75rem; display: none; background: rgba(16, 185, 129, 0.08); border: 1px solid rgba(16, 185, 129, 0.3); padding: 1rem; border-radius: 10px; text-align: left;">
363
+ <div style="font-weight: 700; color: #10b981; font-size: 0.95rem; margin-bottom: 0.35rem;">🎉 You're on the HookArmor Cloud Beta waitlist!</div>
364
+ <p style="color: #94a3b8; font-size: 0.82rem; margin-bottom: 0.75rem; line-height: 1.5;">
365
+ Your invite has been recorded. While your cloud cluster is being queued, jump straight into the live interactive demo to test 1-click dead-letter replays right now.
366
+ </p>
367
+ <div style="display: flex; gap: 0.6rem; flex-wrap: wrap;">
368
+ <a href="/dashboard" class="btn btn-primary" style="padding: 0.45rem 0.9rem; font-size: 0.8rem;">🚀 Launch Live Demo Now</a>
369
+ <a href="https://github.com/pkdoddamani/hookarmor" target="_blank" class="btn btn-outline" style="padding: 0.45rem 0.9rem; font-size: 0.8rem;">⭐ Star on GitHub</a>
370
+ </div>
371
+ </div>
372
+ </div>
373
+
374
+ <div class="terminal-box" style="flex-direction: column; align-items: flex-start; gap: 0.5rem; width: 100%; max-width: 620px;">
375
+ <div style="display: flex; justify-content: space-between; width: 100%; align-items: center;">
376
+ <span style="font-size: 0.75rem; color: #64748b; text-transform: uppercase; letter-spacing: 0.05em; font-family: var(--font-sans); font-weight: 600;">Self-Host Quickstart (Zero Dependencies)</span>
377
+ <button class="copy-btn" onclick="navigator.clipboard.writeText('git clone https://github.com/pkdoddamani/hookarmor.git && cd hookarmor && npm install && npm start')">Copy</button>
378
+ </div>
379
+ <div style="color: #38bdf8; font-size: 0.85rem; word-break: break-all;">
380
+ $ git clone https://github.com/pkdoddamani/hookarmor.git && cd hookarmor && npm start
381
+ </div>
382
+ </div>
383
+
384
+ <div class="hero-actions">
385
+ <a href="https://github.com/pkdoddamani/hookarmor" target="_blank" class="btn btn-primary">Download Free on GitHub</a>
386
+ <a href="#features" class="btn btn-outline">How HookArmor Works</a>
387
+ </div>
388
+ </header>
389
+
390
+ <script>
391
+ async function handleWaitlist(e) {
392
+ e.preventDefault();
393
+ const input = document.getElementById('waitlist-email');
394
+ const email = input.value.trim();
395
+ const form = document.getElementById('waitlist-form');
396
+ const msg = document.getElementById('waitlist-msg');
397
+ if (!email) return;
398
+ try {
399
+ const res = await fetch('/api/waitlist', {
400
+ method: 'POST',
401
+ headers: { 'Content-Type': 'application/json' },
402
+ body: JSON.stringify({ email, source: 'hero_landing' })
403
+ });
404
+ const data = await res.json();
405
+ form.style.display = 'none';
406
+ msg.style.display = 'block';
407
+ } catch (err) {
408
+ msg.style.display = 'block';
409
+ msg.style.background = 'rgba(244, 63, 94, 0.1)';
410
+ msg.style.borderColor = 'rgba(244, 63, 94, 0.3)';
411
+ msg.innerHTML = '<span style="color: #f43f5e;">⚠️ Could not join waitlist right now. Please try again.</span>';
412
+ }
413
+ }
414
+ </script>
415
+
416
+ <section class="section" id="features">
417
+ <div class="section-title">
418
+ <h2>Built for Developers Tired of Silent Revenue Loss</h2>
419
+ <p>A drop-in proxy that protects your business from the harsh realities of production infrastructure.</p>
420
+ </div>
421
+
422
+ <div class="grid-3">
423
+ <div class="card">
424
+ <div class="card-icon" style="background: rgba(59, 130, 246, 0.1); color: #60a5fa;">⚡</div>
425
+ <h3>Fast Ingress Buffer (&lt;15ms)</h3>
426
+ <p>
427
+ Returns an instant <code>200 OK</code> to Stripe, Shopify, or Clerk immediately upon receipt. Payment gateways never enter backoff retry purgatory or mark endpoints dead.
428
+ </p>
429
+ </div>
430
+
431
+ <div class="card">
432
+ <div class="card-icon" style="background: rgba(244, 63, 94, 0.1); color: #f43f5e;">💀</div>
433
+ <h3>Durable Dead-Letter Queue</h3>
434
+ <p>
435
+ If your backend responds 500, 502, 504, 429, or times out, the exact raw body and headers are safely quarantined in SQLite with complete error diagnostic traces.
436
+ </p>
437
+ </div>
438
+
439
+ <div class="card">
440
+ <div class="card-icon" style="background: rgba(16, 185, 129, 0.1); color: #34d399;">🔄</div>
441
+ <h3>1-Click Bulk Replay</h3>
442
+ <p>
443
+ Deploy your fix, then click <strong>"Replay All Dead-Letter"</strong> in the dashboard or run <code>node bin/hookarmor.js replay --failed</code> to restore customer subscriptions in 2 seconds.
444
+ </p>
445
+ </div>
446
+
447
+ <div class="card">
448
+ <div class="card-icon" style="background: rgba(168, 85, 247, 0.1); color: #c084fc;">🔐</div>
449
+ <h3>HMAC Signature Passthrough</h3>
450
+ <p>
451
+ Preserves exact raw bytes and cryptographic signature headers (<code>stripe-signature</code>, <code>x-shopify-hmac-sha256</code>) so downstream security checks never break.
452
+ </p>
453
+ </div>
454
+
455
+ <div class="card">
456
+ <div class="card-icon" style="background: rgba(245, 158, 11, 0.1); color: #fbbf24;">🚨</div>
457
+ <h3>Discord & Slack Webhooks</h3>
458
+ <p>
459
+ Get notified within 1 second of an endpoint failure with the event ID, HTTP status code, and error body delivered directly to your engineering channel.
460
+ </p>
461
+ </div>
462
+
463
+ <div class="card">
464
+ <div class="card-icon" style="background: rgba(56, 189, 248, 0.1); color: #38bdf8;">💻</div>
465
+ <h3>Zero-Friction Local Tunnel</h3>
466
+ <p>
467
+ Run <code>node bin/hookarmor.js listen http://localhost:3000/api/webhook</code> to test production events against your local IDE with hot reloading and zero ngrok hassles.
468
+ </p>
469
+ </div>
470
+ </div>
471
+ </section>
472
+
473
+ <section class="section" id="pricing">
474
+ <div class="section-title">
475
+ <h2>Simple, Predictable Developer Pricing</h2>
476
+ <p>No usage shock. No complex JSON configuration bills. Open core forever.</p>
477
+ </div>
478
+
479
+ <div class="pricing-grid">
480
+ <div class="pricing-card">
481
+ <h3>Self-Hosted</h3>
482
+ <div class="price">$0 <span>/ forever</span></div>
483
+ <p style="color: var(--text-muted); font-size: 0.85rem;">Open source engine & dashboard for local dev and self-hosting.</p>
484
+ <ul class="feature-list">
485
+ <li>✓ Full SQLite DLQ & Ingress Engine</li>
486
+ <li>✓ Web Dashboard & Inspector</li>
487
+ <li>✓ Terminal CLI runner</li>
488
+ <li>✓ Local Dev Tunneling</li>
489
+ <li>✓ Community Support</li>
490
+ </ul>
491
+ <a href="https://github.com/pkdoddamani/hookarmor" class="btn btn-outline" style="margin-top: auto;" target="_blank">Download on GitHub</a>
492
+ </div>
493
+
494
+ <div class="pricing-card featured">
495
+ <div class="featured-badge">MOST POPULAR</div>
496
+ <h3>Starter Cloud</h3>
497
+ <div class="price">$29 <span>/ month</span></div>
498
+ <p style="color: var(--text-muted); font-size: 0.85rem;">For growing B2B SaaS apps and indie founders.</p>
499
+ <ul class="feature-list">
500
+ <li>✓ <strong>50,000 events / month</strong></li>
501
+ <li>✓ <strong>30-day retention</strong> in DLQ</li>
502
+ <li>✓ 5 Webhook Endpoints</li>
503
+ <li>✓ Instant Discord & Slack Alerts</li>
504
+ <li>✓ Automatic Exponential Retries</li>
505
+ <li>✓ 1-Click UI & API Replay</li>
506
+ </ul>
507
+ <a href="#waitlist-form" onclick="focusWaitlist();" class="btn btn-primary" style="margin-top: auto;">Get Started</a>
508
+ </div>
509
+
510
+ <div class="pricing-card">
511
+ <h3>Scale Cloud</h3>
512
+ <div class="price">$79 <span>/ month</span></div>
513
+ <p style="color: var(--text-muted); font-size: 0.85rem;">For high-volume e-commerce and scale-ups.</p>
514
+ <ul class="feature-list">
515
+ <li>✓ <strong>250,000 events / month</strong></li>
516
+ <li>✓ <strong>90-day retention</strong> in DLQ</li>
517
+ <li>✓ Unlimited Endpoints</li>
518
+ <li>✓ Automated Circuit Breakers</li>
519
+ <li>✓ Team Workspaces (Beta Roadmap)</li>
520
+ <li>✓ High-Concurrency Queue Worker</li>
521
+ </ul>
522
+ <a href="#waitlist-form" onclick="focusWaitlist();" class="btn btn-outline" style="margin-top: auto;">Upgrade to Scale</a>
523
+ </div>
524
+ </div>
525
+ </section>
526
+
527
+ <script>
528
+ function focusWaitlist() {
529
+ const form = document.getElementById('waitlist-form');
530
+ const input = document.getElementById('waitlist-email');
531
+ if (form) form.style.display = 'flex';
532
+ if (input) {
533
+ input.focus();
534
+ input.scrollIntoView({ behavior: 'smooth', block: 'center' });
535
+ }
536
+ }
537
+ </script>
538
+
539
+ <footer>
540
+ <div style="max-width: 600px; margin: 0 auto 1.5rem; display: flex; justify-content: center; gap: 2rem;">
541
+ <a href="/blog" style="color: #94a3b8; text-decoration: none;">Engineering Blog</a>
542
+ <a href="/dashboard" style="color: #94a3b8; text-decoration: none;">Live Demo Dashboard</a>
543
+ <a href="https://github.com/pkdoddamani/hookarmor" target="_blank" style="color: #94a3b8; text-decoration: none;">GitHub Repository</a>
544
+ </div>
545
+ <p>© 2026 HookArmor. MIT Licensed Open Source Core. Built for developers who refuse to lose payments.</p>
546
+ </footer>
547
+
548
+ </body>
549
+ </html>
Binary file
@@ -0,0 +1,5 @@
1
+ User-agent: *
2
+ Allow: /
3
+ Disallow: /api/
4
+
5
+ Sitemap: https://hookarmour.dev/sitemap.xml
@@ -0,0 +1,27 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3
+ <url>
4
+ <loc>https://hookarmour.dev/</loc>
5
+ <lastmod>2026-09-24</lastmod>
6
+ <changefreq>daily</changefreq>
7
+ <priority>1.0</priority>
8
+ </url>
9
+ <url>
10
+ <loc>https://hookarmour.dev/blog</loc>
11
+ <lastmod>2026-09-24</lastmod>
12
+ <changefreq>weekly</changefreq>
13
+ <priority>0.8</priority>
14
+ </url>
15
+ <url>
16
+ <loc>https://hookarmour.dev/blog/stripe-webhook-signature-verification-failed.html</loc>
17
+ <lastmod>2026-09-24</lastmod>
18
+ <changefreq>monthly</changefreq>
19
+ <priority>0.9</priority>
20
+ </url>
21
+ <url>
22
+ <loc>https://hookarmour.dev/blog/sqs-webhook-deduplication-trap.html</loc>
23
+ <lastmod>2026-09-24</lastmod>
24
+ <changefreq>monthly</changefreq>
25
+ <priority>0.9</priority>
26
+ </url>
27
+ </urlset>