web-agent-bridge 3.3.0 → 3.4.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.
- package/LICENSE +12 -0
- package/README.ar.md +18 -0
- package/README.md +198 -1664
- package/bin/wab-init.js +223 -0
- package/examples/azure-dns-wab.js +83 -0
- package/examples/cloudflare-wab-dns.js +121 -0
- package/examples/cpanel-wab-dns.js +114 -0
- package/examples/dns-discovery-agent.js +166 -0
- package/examples/gcp-dns-wab.js +76 -0
- package/examples/governance-agent.js +169 -0
- package/examples/plesk-wab-dns.js +103 -0
- package/examples/route53-wab-dns.js +144 -0
- package/examples/safe-mode-agent.js +96 -0
- package/examples/wab-sign.js +74 -0
- package/examples/wab-verify.js +60 -0
- package/package.json +5 -5
- package/public/.well-known/wab.json +28 -0
- package/public/activate.html +368 -0
- package/public/adoption-metrics.html +188 -0
- package/public/api.html +1 -1
- package/public/azure-dns-integration.html +289 -0
- package/public/cloudflare-integration.html +380 -0
- package/public/cpanel-integration.html +398 -0
- package/public/css/styles.css +28 -0
- package/public/dashboard.html +1 -0
- package/public/dns.html +101 -172
- package/public/docs.html +1 -0
- package/public/gcp-dns-integration.html +318 -0
- package/public/growth.html +4 -2
- package/public/index.html +227 -31
- package/public/integrations.html +1 -1
- package/public/js/activate.js +145 -0
- package/public/js/auth-nav.js +34 -0
- package/public/js/dns.js +438 -0
- package/public/openapi.json +89 -0
- package/public/plesk-integration.html +375 -0
- package/public/premium.html +1 -1
- package/public/provider-onboarding.html +172 -0
- package/public/provider-sandbox.html +134 -0
- package/public/providers.html +359 -0
- package/public/registrar-integrations.html +141 -0
- package/public/robots.txt +12 -0
- package/public/route53-integration.html +531 -0
- package/public/shieldqr.html +231 -0
- package/public/sitemap.xml +6 -0
- package/public/wab-trust.html +200 -0
- package/public/wab-vs-protocols.html +210 -0
- package/public/whitepaper.html +449 -0
- package/sdk/auto-discovery.js +288 -0
- package/sdk/governance.js +262 -0
- package/sdk/index.js +13 -0
- package/sdk/package.json +2 -2
- package/sdk/safe-mode.js +221 -0
- package/server/index.js +144 -5
- package/server/migrations/007_governance.sql +106 -0
- package/server/migrations/008_plans.sql +144 -0
- package/server/migrations/009_shieldqr.sql +30 -0
- package/server/migrations/010_extended_trust.sql +33 -0
- package/server/models/adapters/mysql.js +1 -1
- package/server/models/adapters/postgresql.js +1 -1
- package/server/models/db.js +60 -1
- package/server/routes/admin-plans.js +76 -0
- package/server/routes/admin-premium.js +4 -2
- package/server/routes/admin-shieldqr.js +90 -0
- package/server/routes/admin-trust-monitor.js +83 -0
- package/server/routes/admin.js +289 -1
- package/server/routes/billing.js +16 -4
- package/server/routes/discovery.js +1933 -2
- package/server/routes/governance.js +208 -0
- package/server/routes/plans.js +33 -0
- package/server/routes/providers.js +650 -0
- package/server/routes/shieldqr.js +88 -0
- package/server/services/email.js +29 -0
- package/server/services/governance.js +466 -0
- package/server/services/plans.js +214 -0
- package/server/services/premium.js +1 -1
- package/server/services/provider-clients.js +740 -0
- package/server/services/shieldqr.js +322 -0
- package/server/services/ssl-inspector.js +42 -0
- package/server/services/ssl-monitor.js +167 -0
- package/server/services/stripe.js +18 -5
- package/server/services/vision.js +1 -1
- package/server/services/wab-crypto.js +178 -0
package/public/index.html
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
<meta name="description" content="The open AI↔Web protocol & agent platform: standardized command interface, sovereign browser, phone shield, DNS discovery, agent mesh, and unified API gateway.">
|
|
8
8
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
9
9
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
10
|
-
<style>body{background:#0a0e1a;color:#f0f4ff;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;margin:0;min-height:100vh}
|
|
10
|
+
<style>body{background:#0a0e1a;color:#f0f4ff;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;margin:0;min-height:100vh}
|
|
11
|
+
|
|
12
|
+
</style>
|
|
11
13
|
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
|
12
14
|
<noscript><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet"></noscript>
|
|
13
15
|
<link rel="stylesheet" href="/css/styles.css?v=3.0.1">
|
|
@@ -23,6 +25,7 @@
|
|
|
23
25
|
</a>
|
|
24
26
|
<ul class="navbar-links">
|
|
25
27
|
<li><a href="#features">Features</a></li>
|
|
28
|
+
<li><a href="#governance">Governance</a></li>
|
|
26
29
|
<li><a href="#packages">Packages</a></li>
|
|
27
30
|
<li><a href="#integrations">Integrations</a></li>
|
|
28
31
|
<li><a href="#how-it-works">How It Works</a></li>
|
|
@@ -38,13 +41,14 @@
|
|
|
38
41
|
<li><a href="/growth">Growth Suite</a></li>
|
|
39
42
|
<li><a href="/api">API</a></li>
|
|
40
43
|
<li><a href="/docs">Docs</a></li>
|
|
44
|
+
<li><a href="/whitepaper">Whitepaper</a></li>
|
|
41
45
|
</ul>
|
|
42
46
|
<div class="navbar-actions">
|
|
43
47
|
<a href="/login" class="btn btn-ghost" data-wab-auth="guest">Sign In</a>
|
|
44
48
|
<a href="/dashboard" class="btn btn-ghost" data-wab-auth="signed-in" style="display:none">Dashboard</a>
|
|
45
49
|
<a href="/register" class="btn btn-primary btn-sm" data-wab-auth="guest">Get Started</a>
|
|
46
50
|
</div>
|
|
47
|
-
<button class="mobile-menu-btn"
|
|
51
|
+
<button class="mobile-menu-btn" >☰</button>
|
|
48
52
|
</div>
|
|
49
53
|
</nav>
|
|
50
54
|
|
|
@@ -67,6 +71,7 @@
|
|
|
67
71
|
<div class="hero-actions">
|
|
68
72
|
<a href="/register" class="btn btn-primary btn-lg">Start Free</a>
|
|
69
73
|
<a href="/docs" class="btn btn-secondary btn-lg">Read the Docs</a>
|
|
74
|
+
<a href="/whitepaper" class="btn btn-secondary btn-lg" style="background:linear-gradient(135deg,#4ea3ff,#8b5cf6);color:#fff;border:none">📄 Read the Whitepaper</a>
|
|
70
75
|
<a href="/browser" class="btn btn-secondary btn-lg" style="background:linear-gradient(135deg,#0ea5e9,#10b981);color:#fff;border:none">🌐 Download WAB Browser</a>
|
|
71
76
|
<a href="/pwa/" class="btn btn-secondary btn-lg" style="background:linear-gradient(135deg,#8b5cf6,#0ea5e9);color:#fff;border:none">📱 Mobile PWA</a>
|
|
72
77
|
<a href="/workspace" class="btn btn-secondary btn-lg" style="background:linear-gradient(135deg,#f59e0b,#ef4444);color:#fff;border:none">🤖 Agent Workspace</a>
|
|
@@ -164,6 +169,74 @@
|
|
|
164
169
|
</div>
|
|
165
170
|
</section>
|
|
166
171
|
|
|
172
|
+
<!-- ═══════════ GOVERNANCE LAYER ═══════════ -->
|
|
173
|
+
<section class="section" id="governance" style="background: linear-gradient(180deg, var(--bg-primary) 0%, #f1f5f9 100%);">
|
|
174
|
+
<div class="container">
|
|
175
|
+
<div class="section-header">
|
|
176
|
+
<span class="label" style="background:#0ea5e9; color:#fff;">Enterprise Security & Compliance</span>
|
|
177
|
+
<h2>Governance Layer — for agents that touch real money</h2>
|
|
178
|
+
<p>The missing layer above the protocol: per-agent permissions, human-in-the-loop approvals, tamper-evident audit, kill-switch and spend caps — all server-enforced, all open-source, all one SDK call away.</p>
|
|
179
|
+
<div style="display:flex; gap:10px; flex-wrap:wrap; justify-content:center; margin-top:18px;">
|
|
180
|
+
<img alt="Tamper-Evident Audit" src="https://img.shields.io/badge/Audit-Tamper--Evident_HMAC_Chain-0ea5e9?style=for-the-badge&logo=keybase&logoColor=white" />
|
|
181
|
+
<img alt="Human-in-the-Loop Approvals" src="https://img.shields.io/badge/Approvals-Human--in--the--Loop-22c55e?style=for-the-badge&logo=checkmarx&logoColor=white" />
|
|
182
|
+
<img alt="Kill Switch" src="https://img.shields.io/badge/Kill_Switch-Per--Agent-ef4444?style=for-the-badge&logo=stopsign&logoColor=white" />
|
|
183
|
+
<img alt="Tests" src="https://img.shields.io/badge/Governance_Tests-26%2F26-22c55e?style=for-the-badge&logo=jest&logoColor=white" />
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
<div class="grid-3" style="margin-top:32px;">
|
|
188
|
+
<div class="card fade-in">
|
|
189
|
+
<div class="card-icon blue">🔐</div>
|
|
190
|
+
<h3>Permission Boundaries</h3>
|
|
191
|
+
<p>Per-agent <code>resource × action × scope</code> policies with <code>allow</code> or <code>deny</code> effect. Most-specific scope wins. Deny-by-default.</p>
|
|
192
|
+
</div>
|
|
193
|
+
<div class="card fade-in fade-in-delay-1">
|
|
194
|
+
<div class="card-icon green">🙋</div>
|
|
195
|
+
<h3>Human-in-the-Loop Approvals</h3>
|
|
196
|
+
<p>Mark any policy <code>requires_approval: true</code>. Sensitive actions wait for an explicit human <em>approve</em> or <em>reject</em> with TTL. SDK <code>onApprovalRequired</code> hook routes to Slack, email or webhook.</p>
|
|
197
|
+
</div>
|
|
198
|
+
<div class="card fade-in fade-in-delay-2">
|
|
199
|
+
<div class="card-icon cyan">🧾</div>
|
|
200
|
+
<h3>Tamper-Evident Audit</h3>
|
|
201
|
+
<p>Every event hash-chained with HMAC: <code>hash<sub>n</sub> = HMAC(secret, prev_hash ‖ row)</code>. <code>verifyAuditChain()</code> rebuilds the chain and reports the first divergence — a single altered byte breaks every subsequent hash.</p>
|
|
202
|
+
</div>
|
|
203
|
+
<div class="card fade-in fade-in-delay-1">
|
|
204
|
+
<div class="card-icon" style="background:#fee2e2; color:#dc2626;">🛑</div>
|
|
205
|
+
<h3>Kill Switch</h3>
|
|
206
|
+
<p>One <code>POST /agents/:id/kill</code> disables the agent globally. All pending approvals are auto-cancelled — no resurrection via stale approval requests.</p>
|
|
207
|
+
</div>
|
|
208
|
+
<div class="card fade-in fade-in-delay-2">
|
|
209
|
+
<div class="card-icon orange">💰</div>
|
|
210
|
+
<h3>Spend & Rate Limits</h3>
|
|
211
|
+
<p>Per-call <code>max_amount</code>, rolling 24-hour <code>daily_cap</code>, per-minute <code>per_call_rate</code>. Runaway loops can't drain your Stripe balance.</p>
|
|
212
|
+
</div>
|
|
213
|
+
<div class="card fade-in fade-in-delay-3">
|
|
214
|
+
<div class="card-icon purple">🕵️</div>
|
|
215
|
+
<h3>Auto-Redaction</h3>
|
|
216
|
+
<p>Fields named <code>password</code>, <code>api_key</code>, <code>token</code>, <code>cookie</code>, <code>cvv</code>, <code>ssn</code> are automatically replaced with <code>[redacted]</code> before audit storage. Token itself is sha256-hashed at rest.</p>
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
|
|
220
|
+
<div class="card fade-in" style="margin-top:32px; max-width:880px; margin-left:auto; margin-right:auto; background:#0f172a; color:#e2e8f0;">
|
|
221
|
+
<div style="font-family: 'JetBrains Mono', Menlo, monospace; font-size:13px; line-height:1.6; overflow-x:auto;">
|
|
222
|
+
<pre style="margin:0; color:#e2e8f0; background:transparent;"><span style="color:#64748b;">// One call wraps permission check + approval gate + execute + audit</span>
|
|
223
|
+
<span style="color:#7dd3fc;">await</span> gov.<span style="color:#fbbf24;">guard</span>(
|
|
224
|
+
{ resource: <span style="color:#86efac;">'stripe'</span>, action: <span style="color:#86efac;">'write'</span>, scope: <span style="color:#86efac;">'refunds'</span>, amount: <span style="color:#fda4af;">49.99</span> },
|
|
225
|
+
<span style="color:#7dd3fc;">async</span> () => stripe.refunds.<span style="color:#fbbf24;">create</span>({ charge: <span style="color:#86efac;">'ch_x'</span> }),
|
|
226
|
+
);</pre>
|
|
227
|
+
</div>
|
|
228
|
+
<p style="margin-top:18px; color:#cbd5e1; font-size:14px;">
|
|
229
|
+
▶ Run the full 9-step demo:
|
|
230
|
+
<code style="background:#1e293b; padding:4px 10px; border-radius:4px; color:#86efac;">node examples/governance-agent.js</code>
|
|
231
|
+
</p>
|
|
232
|
+
</div>
|
|
233
|
+
|
|
234
|
+
<p style="text-align:center; margin-top:24px; color:#64748b;">
|
|
235
|
+
Verified by <a href="https://github.com/abokenan444/web-agent-bridge/blob/master/tests/governance.test.js" style="color:#0ea5e9; font-weight:600;">26 automated tests</a> covering security (10), operational (10), and SDK (6) scenarios.
|
|
236
|
+
</p>
|
|
237
|
+
</div>
|
|
238
|
+
</section>
|
|
239
|
+
|
|
167
240
|
<!-- ═══════════ V2 FEATURES ═══════════ -->
|
|
168
241
|
<section class="section" id="v2-features" style="background: var(--bg-secondary);">
|
|
169
242
|
<div class="container">
|
|
@@ -465,58 +538,116 @@ console.<span class="fn">log</span>(actions);
|
|
|
465
538
|
<p>Start free, upgrade when you need advanced features. Open source forever.</p>
|
|
466
539
|
</div>
|
|
467
540
|
|
|
468
|
-
<div class="grid-3">
|
|
541
|
+
<div class="grid-3" id="pricing-grid" data-pricing-grid>
|
|
542
|
+
<!-- Server-rendered fallback. Replaced live by /api/plans on page load. -->
|
|
469
543
|
<div class="pricing-card">
|
|
470
544
|
<div class="pricing-tier">Free</div>
|
|
471
|
-
<div class="pricing-price"
|
|
472
|
-
<div class="pricing-desc">
|
|
545
|
+
<div class="pricing-price">€0 <span>/mo</span></div>
|
|
546
|
+
<div class="pricing-desc">Open-source core, free forever.</div>
|
|
473
547
|
<ul class="pricing-features">
|
|
474
|
-
<li>
|
|
475
|
-
<li>
|
|
476
|
-
<li>
|
|
477
|
-
<li>
|
|
478
|
-
<li>
|
|
479
|
-
<li class="disabled">Form filling</li>
|
|
480
|
-
<li class="disabled">API access</li>
|
|
481
|
-
<li class="disabled">Analytics dashboard</li>
|
|
548
|
+
<li>WAP protocol & SDK</li>
|
|
549
|
+
<li>DNS / .well-known discovery</li>
|
|
550
|
+
<li>Browser execution layer</li>
|
|
551
|
+
<li>MCP / REST adapters</li>
|
|
552
|
+
<li>Basic agent registration</li>
|
|
482
553
|
</ul>
|
|
483
554
|
<a href="/register" class="btn btn-secondary" style="width:100%;">Get Started Free</a>
|
|
484
555
|
</div>
|
|
485
556
|
|
|
486
557
|
<div class="pricing-card featured">
|
|
487
558
|
<div class="pricing-tier">Pro</div>
|
|
488
|
-
<div class="pricing-price"
|
|
489
|
-
<div class="pricing-desc">For
|
|
559
|
+
<div class="pricing-price">€10 <span>/mo</span></div>
|
|
560
|
+
<div class="pricing-desc">For developers shipping production agents.</div>
|
|
490
561
|
<ul class="pricing-features">
|
|
491
562
|
<li>Everything in Free</li>
|
|
492
|
-
<li>
|
|
493
|
-
<li>
|
|
494
|
-
<li>Advanced
|
|
495
|
-
<li>
|
|
496
|
-
<li>Automated login support</li>
|
|
497
|
-
<li>Data extraction</li>
|
|
498
|
-
<li>Priority support</li>
|
|
563
|
+
<li>Workspace & observability</li>
|
|
564
|
+
<li>Replay engine</li>
|
|
565
|
+
<li>Advanced orchestration</li>
|
|
566
|
+
<li>Advanced analytics & data extraction</li>
|
|
499
567
|
</ul>
|
|
500
|
-
<a href="/register" class="btn btn-primary" style="width:100%;">Start Pro
|
|
568
|
+
<a href="/register" class="btn btn-primary" style="width:100%;">Start Pro</a>
|
|
569
|
+
</div>
|
|
570
|
+
|
|
571
|
+
<div class="pricing-card">
|
|
572
|
+
<div class="pricing-tier">Business</div>
|
|
573
|
+
<div class="pricing-price">€29 <span>/mo</span></div>
|
|
574
|
+
<div class="pricing-desc">All paid features, ready for scale.</div>
|
|
575
|
+
<ul class="pricing-features">
|
|
576
|
+
<li>Everything in Pro</li>
|
|
577
|
+
<li>Hosted runtime & marketplace</li>
|
|
578
|
+
<li>Vision, swarm, traffic intel</li>
|
|
579
|
+
<li>Audit logs & custom domain</li>
|
|
580
|
+
<li>Agent governance layer</li>
|
|
581
|
+
</ul>
|
|
582
|
+
<a href="/register" class="btn btn-secondary" style="width:100%;">Start Business</a>
|
|
501
583
|
</div>
|
|
502
584
|
|
|
503
585
|
<div class="pricing-card">
|
|
504
586
|
<div class="pricing-tier">Enterprise</div>
|
|
505
587
|
<div class="pricing-price">Custom</div>
|
|
506
|
-
<div class="pricing-desc">Custom
|
|
588
|
+
<div class="pricing-desc">Custom-built for organisations.</div>
|
|
507
589
|
<ul class="pricing-features">
|
|
508
|
-
<li>Everything in
|
|
509
|
-
<li>
|
|
510
|
-
<li>
|
|
511
|
-
<li>
|
|
512
|
-
<li>SSO / SAML</li>
|
|
513
|
-
<li>Dedicated support</li>
|
|
514
|
-
<li>SLA guarantee</li>
|
|
590
|
+
<li>Everything in Business</li>
|
|
591
|
+
<li>Enterprise security & SSO</li>
|
|
592
|
+
<li>Dedicated infrastructure</li>
|
|
593
|
+
<li>Priority support & SLA</li>
|
|
515
594
|
<li>Custom development</li>
|
|
516
595
|
</ul>
|
|
517
596
|
<a href="mailto:sales@webagentbridge.com" class="btn btn-secondary" style="width:100%;">Contact Sales</a>
|
|
518
597
|
</div>
|
|
519
598
|
</div>
|
|
599
|
+
<script>
|
|
600
|
+
(function () {
|
|
601
|
+
var GRID = document.getElementById('pricing-grid');
|
|
602
|
+
if (!GRID) return;
|
|
603
|
+
var FEATURED_ID = 'pro';
|
|
604
|
+
function esc(s){return String(s==null?'':s).replace(/[&<>"']/g,function(c){return ({'&':'&','<':'<','>':'>','"':'"',"'":'''})[c];});}
|
|
605
|
+
function fmtPrice(p){
|
|
606
|
+
if (p.billing_period === 'custom' || p.cta_type === 'contact') return 'Custom';
|
|
607
|
+
if (!p.price_cents) return (p.currency==='EUR'?'€':p.currency==='USD'?'$':p.currency+' ') + '0 <span>/' + esc(p.billing_period) + '</span>';
|
|
608
|
+
var sym = p.currency === 'EUR' ? '€' : (p.currency === 'USD' ? '$' : p.currency + ' ');
|
|
609
|
+
return sym + (p.price_cents/100).toFixed(p.price_cents % 100 === 0 ? 0 : 2) + ' <span>/' + esc(p.billing_period) + '</span>';
|
|
610
|
+
}
|
|
611
|
+
function ctaHref(p){
|
|
612
|
+
if (p.cta_type === 'contact') return p.cta_url || 'mailto:sales@webagentbridge.com';
|
|
613
|
+
if (p.cta_type === 'external') return p.cta_url || '/register';
|
|
614
|
+
if (p.cta_type === 'register') return p.cta_url || '/register';
|
|
615
|
+
// checkout — send authenticated users straight to dashboard?plan=…, anonymous to register first.
|
|
616
|
+
return '/register?plan=' + encodeURIComponent(p.id);
|
|
617
|
+
}
|
|
618
|
+
function topFeatures(plan, catalog, max){
|
|
619
|
+
var labels = catalog.reduce(function(m,f){m[f.key]=f.label;return m;},{});
|
|
620
|
+
var keys = Object.keys(plan.features||{}).filter(function(k){return plan.features[k];});
|
|
621
|
+
// Prefer non-open-source labels (the differentiators) when listing.
|
|
622
|
+
var nonOpen = keys.filter(function(k){var f=catalog.find(function(x){return x.key===k;});return f && !f.is_open_source;});
|
|
623
|
+
var pick = nonOpen.length ? nonOpen : keys;
|
|
624
|
+
return pick.slice(0, max).map(function(k){return labels[k] || k;});
|
|
625
|
+
}
|
|
626
|
+
function render(plans, catalog){
|
|
627
|
+
if (!plans || !plans.length) return;
|
|
628
|
+
var html = plans.map(function(p){
|
|
629
|
+
var feats = topFeatures(p, catalog, 6);
|
|
630
|
+
var ctaCls = p.highlight ? 'btn-primary' : 'btn-secondary';
|
|
631
|
+
return ''
|
|
632
|
+
+ '<div class="pricing-card' + (p.highlight ? ' featured' : '') + '">'
|
|
633
|
+
+ '<div class="pricing-tier">' + esc(p.name) + '</div>'
|
|
634
|
+
+ '<div class="pricing-price">' + fmtPrice(p) + '</div>'
|
|
635
|
+
+ '<div class="pricing-desc">' + esc(p.tagline || p.description || '') + '</div>'
|
|
636
|
+
+ '<ul class="pricing-features">'
|
|
637
|
+
+ feats.map(function(f){return '<li>' + esc(f) + '</li>';}).join('')
|
|
638
|
+
+ '</ul>'
|
|
639
|
+
+ '<a href="' + esc(ctaHref(p)) + '" class="btn ' + ctaCls + '" style="width:100%;">' + esc(p.cta_label || 'Get started') + '</a>'
|
|
640
|
+
+ '</div>';
|
|
641
|
+
}).join('');
|
|
642
|
+
GRID.innerHTML = html;
|
|
643
|
+
GRID.style.gridTemplateColumns = 'repeat(' + Math.min(4, plans.length) + ', 1fr)';
|
|
644
|
+
}
|
|
645
|
+
fetch('/api/plans', { credentials: 'omit' })
|
|
646
|
+
.then(function(r){ return r.ok ? r.json() : null; })
|
|
647
|
+
.then(function(d){ if (d && d.plans) render(d.plans, d.features || []); })
|
|
648
|
+
.catch(function(){ /* keep server fallback */ });
|
|
649
|
+
})();
|
|
650
|
+
</script>
|
|
520
651
|
</div>
|
|
521
652
|
</section>
|
|
522
653
|
|
|
@@ -988,6 +1119,20 @@ console.<span class="fn">log</span>(actions);
|
|
|
988
1119
|
</div>
|
|
989
1120
|
</section>
|
|
990
1121
|
|
|
1122
|
+
<!-- ═══════════ LIVE DNS ADOPTION ═══════════ -->
|
|
1123
|
+
<section class="section" id="live-dns-adoption">
|
|
1124
|
+
<div class="container">
|
|
1125
|
+
<div class="section-header">
|
|
1126
|
+
<span class="label">Live Adoption</span>
|
|
1127
|
+
<h2>Businesses Using WAB DNS Discovery</h2>
|
|
1128
|
+
<p>This list is auto-generated from real registry registrations only. No static seeded entries.</p>
|
|
1129
|
+
</div>
|
|
1130
|
+
<div id="indexLiveAdoptionStatus" style="margin-bottom:14px;color:var(--text-secondary);">Loading live registry…</div>
|
|
1131
|
+
<div id="indexLiveAdoptionList" class="grid-3" style="display:none;"></div>
|
|
1132
|
+
</div>
|
|
1133
|
+
</section>
|
|
1134
|
+
|
|
1135
|
+
|
|
991
1136
|
<!-- ═══════════ CTA ═══════════ -->
|
|
992
1137
|
<section class="section" style="text-align:center;">
|
|
993
1138
|
<div class="container">
|
|
@@ -1064,6 +1209,57 @@ console.<span class="fn">log</span>(actions);
|
|
|
1064
1209
|
? 'rgba(10, 14, 26, 0.95)'
|
|
1065
1210
|
: 'rgba(10, 14, 26, 0.8)';
|
|
1066
1211
|
});
|
|
1212
|
+
|
|
1213
|
+
function escapeHtml(v) {
|
|
1214
|
+
return String(v)
|
|
1215
|
+
.replace(/&/g, '&')
|
|
1216
|
+
.replace(/</g, '<')
|
|
1217
|
+
.replace(/>/g, '>')
|
|
1218
|
+
.replace(/\"/g, '"')
|
|
1219
|
+
.replace(/'/g, ''');
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
async function loadIndexLiveAdoption() {
|
|
1223
|
+
const status = document.getElementById('indexLiveAdoptionStatus');
|
|
1224
|
+
const list = document.getElementById('indexLiveAdoptionList');
|
|
1225
|
+
if (!status || !list) return;
|
|
1226
|
+
|
|
1227
|
+
status.textContent = 'Loading live registry…';
|
|
1228
|
+
list.style.display = 'none';
|
|
1229
|
+
list.innerHTML = '';
|
|
1230
|
+
|
|
1231
|
+
try {
|
|
1232
|
+
const res = await fetch('/api/discovery/registry?limit=12');
|
|
1233
|
+
const data = await res.json();
|
|
1234
|
+
const entries = Array.isArray(data && data.listings) ? data.listings : [];
|
|
1235
|
+
|
|
1236
|
+
if (!entries.length) {
|
|
1237
|
+
status.textContent = 'No businesses are currently listed. New real registrations will appear here automatically.';
|
|
1238
|
+
return;
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
list.innerHTML = entries.map((entry) => {
|
|
1242
|
+
const name = escapeHtml(entry.name || entry.domain || 'Unnamed site');
|
|
1243
|
+
const domain = escapeHtml(entry.domain || '');
|
|
1244
|
+
const category = escapeHtml(entry.category || 'general');
|
|
1245
|
+
const desc = escapeHtml(entry.description || 'WAB-enabled website');
|
|
1246
|
+
const score = Number.isFinite(Number(entry.neutrality_score)) ? Number(entry.neutrality_score) : 0;
|
|
1247
|
+
return '<div class="card fade-in" style="border-left:3px solid #10b981;">' +
|
|
1248
|
+
'<h3 style="margin-bottom:8px">' + name + '</h3>' +
|
|
1249
|
+
'<p style="margin-bottom:10px">' + desc + '</p>' +
|
|
1250
|
+
'<p style="color:var(--text-secondary);font-size:.88rem;margin:0">' + domain + '</p>' +
|
|
1251
|
+
'<p style="color:var(--text-secondary);font-size:.82rem;margin-top:6px">' + category + ' · neutrality ' + score + '</p>' +
|
|
1252
|
+
'</div>';
|
|
1253
|
+
}).join('');
|
|
1254
|
+
|
|
1255
|
+
list.style.display = 'grid';
|
|
1256
|
+
status.textContent = 'Live list loaded from registry.';
|
|
1257
|
+
} catch (err) {
|
|
1258
|
+
status.textContent = 'Failed to load live registry: ' + ((err && err.message) || err);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
loadIndexLiveAdoption();
|
|
1067
1263
|
</script>
|
|
1068
1264
|
<script src="/js/cookie-consent.js?v=3.0.1"></script>
|
|
1069
1265
|
</body>
|
package/public/integrations.html
CHANGED
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
<a href="/dashboard" class="btn btn-ghost" data-wab-auth="signed-in" style="display:none">Dashboard</a>
|
|
117
117
|
<a href="/register" class="btn btn-primary btn-sm" data-wab-auth="guest">Get Started</a>
|
|
118
118
|
</div>
|
|
119
|
-
<button class="mobile-menu-btn"
|
|
119
|
+
<button class="mobile-menu-btn" >☰</button>
|
|
120
120
|
</div>
|
|
121
121
|
</nav>
|
|
122
122
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/* activate.js — WAB DNS Discovery Activation Page */
|
|
2
|
+
(function () {
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
/* ── Translations ── */
|
|
6
|
+
var i18n = {
|
|
7
|
+
en: {
|
|
8
|
+
nav_home: 'Home', nav_integrations: 'Integrations', nav_dns: 'DNS Discovery',
|
|
9
|
+
nav_phone: 'Phone Shield', nav_sovereign: 'Sovereign', nav_docs: 'Docs',
|
|
10
|
+
hero_title: 'Activate WAB Discovery<br><span class="gradient-text">in One Click</span>',
|
|
11
|
+
hero_sub: 'Add a single DNS TXT record and make your website instantly discoverable by AI agents — no code changes required.',
|
|
12
|
+
cta_guide: 'View Setup Guide', cta_verify: 'Live Verifier',
|
|
13
|
+
video_title: 'Watch: Full Setup in 40 Seconds',
|
|
14
|
+
video_fallback: 'Your browser does not support the video tag.',
|
|
15
|
+
steps_title: 'Step-by-Step Setup Guide',
|
|
16
|
+
step1_title: 'Log In to Your DNS Provider',
|
|
17
|
+
step1_desc: 'Sign in to your domain registrar or DNS hosting dashboard. Common providers include Cloudflare, cPanel, GoDaddy, and Namecheap. Navigate to the DNS Management or DNS Records section.',
|
|
18
|
+
prov_cloudflare: 'Go to <strong>dash.cloudflare.com</strong> → Select your domain → Click <strong>DNS</strong> in the top navigation → Click <strong>+ Add record</strong>.',
|
|
19
|
+
prov_cpanel: 'Log in to cPanel → Scroll to <strong>Domains</strong> section → Click <strong>Zone Editor</strong> → Click <strong>Manage</strong> next to your domain → Click <strong>+ Add Record</strong>.',
|
|
20
|
+
prov_godaddy: 'Log in to <strong>godaddy.com</strong> → My Products → Click <strong>DNS</strong> next to your domain → Click <strong>Add New Record</strong>.',
|
|
21
|
+
prov_namecheap: 'Log in to <strong>namecheap.com</strong> → Domain List → Click <strong>Manage</strong> → Click <strong>Advanced DNS</strong> tab → Click <strong>Add New Record</strong>.',
|
|
22
|
+
step2_title: 'Add the TXT Record',
|
|
23
|
+
step2_desc: 'Create a new DNS TXT record with exactly these values. Replace <code style="color:#a5f3fc">yourdomain.com</code> with your actual domain.',
|
|
24
|
+
step3_title: 'Create the wab.json Capabilities File',
|
|
25
|
+
step3_desc: 'Create the file <code style="color:#a5f3fc">/.well-known/wab.json</code> on your web server. This file describes your site\'s capabilities to AI agents.',
|
|
26
|
+
step4_title: 'Verify Your Setup',
|
|
27
|
+
step4_desc: 'DNS propagation takes a few minutes. Use the Live Verifier to confirm your record is active. The verifier queries DNS over HTTPS (DoH) — no data is sent to our servers.',
|
|
28
|
+
verify_btn: 'Verify Now',
|
|
29
|
+
cta_title: 'Your Domain is Now AI-Ready',
|
|
30
|
+
cta_desc: 'Once verified, AI agents using the WAB protocol can discover your site\'s capabilities automatically — no manual configuration needed on their end.',
|
|
31
|
+
cta_full_guide: 'Full DNS Guide', cta_docs: 'Read the Docs'
|
|
32
|
+
},
|
|
33
|
+
ar: {
|
|
34
|
+
nav_home: 'الرئيسية', nav_integrations: 'التكاملات', nav_dns: 'اكتشاف DNS',
|
|
35
|
+
nav_phone: 'درع الهاتف', nav_sovereign: 'سيادي', nav_docs: 'التوثيق',
|
|
36
|
+
hero_title: 'فعّل اكتشاف WAB<br><span class="gradient-text">بنقرة واحدة</span>',
|
|
37
|
+
hero_sub: 'أضف سجل DNS TXT واحداً واجعل موقعك قابلاً للاكتشاف فوراً من قِبَل وكلاء الذكاء الاصطناعي — دون أي تغييرات في الكود.',
|
|
38
|
+
cta_guide: 'عرض دليل الإعداد', cta_verify: 'المدقق المباشر',
|
|
39
|
+
video_title: 'شاهد: الإعداد الكامل في 40 ثانية',
|
|
40
|
+
video_fallback: 'متصفحك لا يدعم تشغيل الفيديو.',
|
|
41
|
+
steps_title: 'دليل الإعداد خطوة بخطوة',
|
|
42
|
+
step1_title: 'سجّل الدخول إلى مزود DNS',
|
|
43
|
+
step1_desc: 'سجّل الدخول إلى مسجّل نطاقك أو لوحة تحكم استضافة DNS. المزودون الشائعون: Cloudflare وcPanel وGoDaddy وNamecheap. انتقل إلى قسم إدارة DNS أو سجلات DNS.',
|
|
44
|
+
prov_cloudflare: 'اذهب إلى <strong>dash.cloudflare.com</strong> → اختر نطاقك → انقر على <strong>DNS</strong> في التنقل العلوي → انقر على <strong>+ إضافة سجل</strong>.',
|
|
45
|
+
prov_cpanel: 'سجّل الدخول إلى cPanel → مرّر إلى قسم <strong>النطاقات</strong> → انقر على <strong>محرر المنطقة</strong> → انقر على <strong>إدارة</strong> بجانب نطاقك → انقر على <strong>+ إضافة سجل</strong>.',
|
|
46
|
+
prov_godaddy: 'سجّل الدخول إلى <strong>godaddy.com</strong> → منتجاتي → انقر على <strong>DNS</strong> بجانب نطاقك → انقر على <strong>إضافة سجل جديد</strong>.',
|
|
47
|
+
prov_namecheap: 'سجّل الدخول إلى <strong>namecheap.com</strong> → قائمة النطاقات → انقر على <strong>إدارة</strong> → انقر على تبويب <strong>Advanced DNS</strong> → انقر على <strong>إضافة سجل جديد</strong>.',
|
|
48
|
+
step2_title: 'أضف سجل TXT',
|
|
49
|
+
step2_desc: 'أنشئ سجل DNS TXT جديداً بهذه القيم بالضبط. استبدل <code style="color:#a5f3fc">yourdomain.com</code> بنطاقك الفعلي.',
|
|
50
|
+
step3_title: 'أنشئ ملف قدرات wab.json',
|
|
51
|
+
step3_desc: 'أنشئ الملف <code style="color:#a5f3fc">/.well-known/wab.json</code> على خادم الويب الخاص بك. يصف هذا الملف قدرات موقعك لوكلاء الذكاء الاصطناعي.',
|
|
52
|
+
step4_title: 'تحقق من إعدادك',
|
|
53
|
+
step4_desc: 'قد يستغرق انتشار DNS بضع دقائق. استخدم المدقق المباشر للتأكد من أن سجلك نشط. يستعلم المدقق عبر DNS over HTTPS (DoH) — لا يُرسَل أي بيانات إلى خوادمنا.',
|
|
54
|
+
verify_btn: 'تحقق الآن',
|
|
55
|
+
cta_title: 'نطاقك جاهز للذكاء الاصطناعي',
|
|
56
|
+
cta_desc: 'بمجرد التحقق، يمكن لوكلاء الذكاء الاصطناعي الذين يستخدمون بروتوكول WAB اكتشاف قدرات موقعك تلقائياً — دون الحاجة إلى أي إعداد يدوي من جانبهم.',
|
|
57
|
+
cta_full_guide: 'الدليل الكامل لـ DNS', cta_docs: 'اقرأ التوثيق'
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
var currentLang = 'en';
|
|
62
|
+
|
|
63
|
+
window.setActivateLang = function (lang) {
|
|
64
|
+
currentLang = lang;
|
|
65
|
+
var t = i18n[lang];
|
|
66
|
+
var html = document.documentElement;
|
|
67
|
+
html.setAttribute('lang', lang);
|
|
68
|
+
html.setAttribute('dir', lang === 'ar' ? 'rtl' : 'ltr');
|
|
69
|
+
|
|
70
|
+
document.querySelectorAll('[data-i18n]').forEach(function (el) {
|
|
71
|
+
var key = el.getAttribute('data-i18n');
|
|
72
|
+
if (t[key] !== undefined) el.innerHTML = t[key];
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
var btnEn = document.getElementById('btnEn');
|
|
76
|
+
var btnAr = document.getElementById('btnAr');
|
|
77
|
+
if (btnEn && btnAr) {
|
|
78
|
+
btnEn.classList.toggle('active', lang === 'en');
|
|
79
|
+
btnAr.classList.toggle('active', lang === 'ar');
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/* ── Provider tabs ── */
|
|
84
|
+
window.showProvider = function (name, btn) {
|
|
85
|
+
document.querySelectorAll('.provider-content').forEach(function (el) { el.classList.remove('active'); });
|
|
86
|
+
document.querySelectorAll('.provider-tab').forEach(function (el) { el.classList.remove('active'); });
|
|
87
|
+
var content = document.getElementById('prov-' + name);
|
|
88
|
+
if (content) content.classList.add('active');
|
|
89
|
+
if (btn) btn.classList.add('active');
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/* ── Live Verifier ── */
|
|
93
|
+
function verifyDomain() {
|
|
94
|
+
var input = document.getElementById('activateDomain');
|
|
95
|
+
var result = document.getElementById('activateResult');
|
|
96
|
+
if (!input || !result) return;
|
|
97
|
+
var domain = input.value.trim().replace(/^https?:\/\//, '').replace(/\/.*$/, '');
|
|
98
|
+
if (!domain) { input.focus(); return; }
|
|
99
|
+
|
|
100
|
+
result.style.display = 'block';
|
|
101
|
+
result.style.color = '#94a3b8';
|
|
102
|
+
result.innerHTML = currentLang === 'ar' ? '⏳ جارٍ التحقق...' : '⏳ Verifying...';
|
|
103
|
+
|
|
104
|
+
var url = 'https://cloudflare-dns.com/dns-query?name=_wab.' + encodeURIComponent(domain) + '&type=TXT';
|
|
105
|
+
fetch(url, { headers: { 'Accept': 'application/dns-json' } })
|
|
106
|
+
.then(function (r) { return r.json(); })
|
|
107
|
+
.then(function (data) {
|
|
108
|
+
var answers = (data.Answer || []).filter(function (a) { return a.type === 16; });
|
|
109
|
+
if (answers.length === 0) {
|
|
110
|
+
result.style.color = '#f87171';
|
|
111
|
+
result.innerHTML = currentLang === 'ar'
|
|
112
|
+
? '✗ لم يُعثر على سجل _wab. تأكد من إضافة السجل وانتظر انتشار DNS.'
|
|
113
|
+
: '✗ No _wab record found. Make sure you added the record and wait for DNS propagation.';
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
var raw = answers[0].data.replace(/^"|"$/g, '');
|
|
117
|
+
if (raw.indexOf('v=wab1') !== -1) {
|
|
118
|
+
result.style.color = '#34d399';
|
|
119
|
+
result.innerHTML = (currentLang === 'ar' ? '✓ سجل WAB صالح. ' : '✓ Valid WAB record found. ') +
|
|
120
|
+
'<br><span style="color:#a5f3fc">' + raw + '</span>';
|
|
121
|
+
} else {
|
|
122
|
+
result.style.color = '#fbbf24';
|
|
123
|
+
result.innerHTML = (currentLang === 'ar' ? '⚠ سجل TXT موجود لكن ليس سجل WAB صالحاً: ' : '⚠ TXT record found but not a valid WAB record: ') +
|
|
124
|
+
'<br><span style="color:#a5f3fc">' + raw + '</span>';
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
.catch(function () {
|
|
128
|
+
result.style.color = '#f87171';
|
|
129
|
+
result.innerHTML = currentLang === 'ar' ? '✗ خطأ في الاتصال. حاول مجدداً.' : '✗ Connection error. Please try again.';
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
134
|
+
var btn = document.getElementById('activateVerifyBtn');
|
|
135
|
+
if (btn) btn.addEventListener('click', verifyDomain);
|
|
136
|
+
var inp = document.getElementById('activateDomain');
|
|
137
|
+
if (inp) inp.addEventListener('keydown', function (e) { if (e.key === 'Enter') verifyDomain(); });
|
|
138
|
+
|
|
139
|
+
/* Lang buttons */
|
|
140
|
+
var btnEn = document.getElementById('btnEn');
|
|
141
|
+
var btnAr = document.getElementById('btnAr');
|
|
142
|
+
if (btnEn) btnEn.addEventListener('click', function () { setActivateLang('en'); });
|
|
143
|
+
if (btnAr) btnAr.addEventListener('click', function () { setActivateLang('ar'); });
|
|
144
|
+
});
|
|
145
|
+
})();
|
package/public/js/auth-nav.js
CHANGED
|
@@ -29,3 +29,37 @@
|
|
|
29
29
|
apply();
|
|
30
30
|
}
|
|
31
31
|
})();
|
|
32
|
+
|
|
33
|
+
// ─── Mobile hamburger menu (CSP-safe, no onclick attributes) ───
|
|
34
|
+
(function () {
|
|
35
|
+
function initMobileMenu() {
|
|
36
|
+
var btn = document.querySelector('.mobile-menu-btn');
|
|
37
|
+
var links = document.querySelector('.navbar-links');
|
|
38
|
+
if (!btn || !links) return;
|
|
39
|
+
btn.addEventListener('click', function (e) {
|
|
40
|
+
e.stopPropagation();
|
|
41
|
+
links.classList.toggle('active');
|
|
42
|
+
// Toggle icon ☰ ↔ ✕
|
|
43
|
+
btn.textContent = links.classList.contains('active') ? '✕' : '☰';
|
|
44
|
+
});
|
|
45
|
+
// Close menu when clicking outside
|
|
46
|
+
document.addEventListener('click', function (e) {
|
|
47
|
+
if (!e.target.closest('nav') && links.classList.contains('active')) {
|
|
48
|
+
links.classList.remove('active');
|
|
49
|
+
btn.textContent = '☰';
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
// Close menu when a nav link is clicked
|
|
53
|
+
links.querySelectorAll('a').forEach(function (a) {
|
|
54
|
+
a.addEventListener('click', function () {
|
|
55
|
+
links.classList.remove('active');
|
|
56
|
+
btn.textContent = '☰';
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (document.readyState === 'loading') {
|
|
61
|
+
document.addEventListener('DOMContentLoaded', initMobileMenu);
|
|
62
|
+
} else {
|
|
63
|
+
initMobileMenu();
|
|
64
|
+
}
|
|
65
|
+
})();
|