web-agent-bridge 3.4.0 → 3.8.1

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 (310) hide show
  1. package/LICENSE +84 -84
  2. package/README.ar.md +1563 -1304
  3. package/README.md +137 -298
  4. package/bin/agent-runner.js +474 -474
  5. package/bin/cli.js +237 -237
  6. package/bin/wab-init.js +244 -223
  7. package/bin/wab.js +80 -80
  8. package/examples/azure-dns-wab.js +83 -83
  9. package/examples/bidi-agent.js +119 -119
  10. package/examples/cloudflare-wab-dns.js +121 -121
  11. package/examples/cpanel-wab-dns.js +114 -114
  12. package/examples/cross-site-agent.js +91 -91
  13. package/examples/dns-discovery-agent.js +166 -166
  14. package/examples/gcp-dns-wab.js +76 -76
  15. package/examples/governance-agent.js +169 -169
  16. package/examples/mcp-agent.js +94 -94
  17. package/examples/next-app-router/README.md +44 -44
  18. package/examples/plesk-wab-dns.js +103 -103
  19. package/examples/puppeteer-agent.js +108 -108
  20. package/examples/route53-wab-dns.js +144 -144
  21. package/examples/saas-dashboard/README.md +55 -55
  22. package/examples/safe-mode-agent.js +96 -96
  23. package/examples/self-discovery.js +106 -0
  24. package/examples/shopify-hydrogen/README.md +74 -74
  25. package/examples/vision-agent.js +171 -171
  26. package/examples/wab-sign.js +74 -74
  27. package/examples/wab-verify.js +60 -60
  28. package/examples/wordpress-elementor/README.md +77 -77
  29. package/package.json +93 -93
  30. package/public/.well-known/agent-tools.json +180 -180
  31. package/public/.well-known/ai-assets.json +59 -59
  32. package/public/.well-known/security.txt +8 -8
  33. package/public/.well-known/wab.json +28 -28
  34. package/public/activate.html +448 -368
  35. package/public/adopt.html +236 -0
  36. package/public/adoption-metrics.html +188 -188
  37. package/public/agent-workspace.html +359 -349
  38. package/public/ai.html +198 -198
  39. package/public/api.html +397 -413
  40. package/public/azure-dns-integration.html +289 -289
  41. package/public/browser.html +486 -486
  42. package/public/cloudflare-integration.html +380 -380
  43. package/public/commander-dashboard.html +243 -243
  44. package/public/cookies.html +210 -210
  45. package/public/cpanel-integration.html +398 -398
  46. package/public/css/agent-workspace.css +1713 -1713
  47. package/public/css/premium.css +317 -317
  48. package/public/css/styles.css +1401 -1263
  49. package/public/dashboard-shieldlink.html +295 -0
  50. package/public/dashboard.html +711 -707
  51. package/public/dns.html +436 -436
  52. package/public/docs.html +588 -588
  53. package/public/enterprise-mesh.ar.html +80 -0
  54. package/public/enterprise-mesh.html +81 -0
  55. package/public/feed.xml +89 -89
  56. package/public/gcp-dns-integration.html +318 -318
  57. package/public/governance.ar.html +70 -0
  58. package/public/governance.html +69 -0
  59. package/public/growth.html +465 -465
  60. package/public/index.html +1372 -1266
  61. package/public/integrations.html +556 -556
  62. package/public/js/activate.js +449 -145
  63. package/public/js/agent-workspace.js +1740 -1740
  64. package/public/js/auth-nav.js +117 -65
  65. package/public/js/auth-redirect.js +12 -12
  66. package/public/js/cookie-consent.js +56 -56
  67. package/public/js/dns.js +438 -438
  68. package/public/js/wab-demo-page.js +721 -721
  69. package/public/js/ws-client.js +74 -74
  70. package/public/l-preview.html +242 -0
  71. package/public/llms-full.txt +360 -360
  72. package/public/llms.txt +125 -125
  73. package/public/login.html +85 -85
  74. package/public/mesh-dashboard.html +328 -328
  75. package/public/milestones.html +346 -0
  76. package/public/one-click.html +779 -0
  77. package/public/openapi.json +669 -669
  78. package/public/partners.ar.html +145 -0
  79. package/public/partners.html +143 -0
  80. package/public/phone-shield.html +281 -281
  81. package/public/plesk-integration.html +375 -375
  82. package/public/premium-dashboard.html +2489 -2489
  83. package/public/premium.html +793 -793
  84. package/public/privacy.html +297 -297
  85. package/public/provider-onboarding.html +172 -172
  86. package/public/provider-sandbox.html +134 -134
  87. package/public/providers.html +359 -359
  88. package/public/refusals.html +172 -0
  89. package/public/register.html +105 -105
  90. package/public/registrar-integrations.html +141 -141
  91. package/public/ring4.html +292 -0
  92. package/public/robots.txt +99 -99
  93. package/public/route53-integration.html +531 -531
  94. package/public/score.html +263 -0
  95. package/public/script/wab-consent.d.ts +36 -36
  96. package/public/script/wab-consent.js +104 -104
  97. package/public/script/wab-schema.js +131 -131
  98. package/public/script/wab.d.ts +108 -108
  99. package/public/script/wab.min.js +580 -580
  100. package/public/security.txt +8 -8
  101. package/public/shieldlink.html +244 -0
  102. package/public/shieldqr.html +231 -231
  103. package/public/sitemap.xml +13 -1
  104. package/public/terms.html +256 -256
  105. package/public/trust-graph-api.ar.html +92 -0
  106. package/public/trust-graph-api.html +91 -0
  107. package/public/wab-features.html +560 -0
  108. package/public/wab-trust.html +200 -200
  109. package/public/wab-truth.html +375 -0
  110. package/public/wab-vs-protocols.html +210 -210
  111. package/public/whitepaper.html +449 -449
  112. package/script/ai-agent-bridge.js +1754 -1754
  113. package/sdk/README.md +99 -99
  114. package/sdk/agent-mesh.js +449 -449
  115. package/sdk/auto-discovery.js +301 -288
  116. package/sdk/commander.js +262 -262
  117. package/sdk/governance.js +262 -262
  118. package/sdk/index.d.ts +464 -464
  119. package/sdk/index.js +649 -649
  120. package/sdk/multi-agent.js +318 -318
  121. package/sdk/safe-mode.js +221 -221
  122. package/sdk/safety-shield.js +219 -219
  123. package/sdk/schema-discovery.js +83 -83
  124. package/server/adapters/index.js +520 -520
  125. package/server/config/plans.js +412 -367
  126. package/server/config/secrets.js +102 -102
  127. package/server/control-plane/index.js +301 -301
  128. package/server/data-plane/index.js +354 -354
  129. package/server/index.js +790 -670
  130. package/server/llm/index.js +404 -404
  131. package/server/middleware/adminAuth.js +35 -35
  132. package/server/middleware/api-tier.js +170 -0
  133. package/server/middleware/auth.js +50 -50
  134. package/server/middleware/featureGate.js +88 -88
  135. package/server/middleware/rateLimits.js +100 -100
  136. package/server/middleware/sensitiveAction.js +157 -157
  137. package/server/middleware/wab-trust.js +141 -0
  138. package/server/migrations/001_add_analytics_indexes.sql +7 -7
  139. package/server/migrations/002_premium_features.sql +418 -418
  140. package/server/migrations/003_ads_integer_cents.sql +33 -33
  141. package/server/migrations/004_agent_os.sql +158 -158
  142. package/server/migrations/005_marketplace_metering.sql +126 -126
  143. package/server/migrations/006_growth_suite.sql +138 -0
  144. package/server/migrations/007_governance.sql +106 -106
  145. package/server/migrations/008_plans.sql +144 -144
  146. package/server/migrations/009_shieldqr.sql +30 -30
  147. package/server/migrations/010_extended_trust.sql +33 -33
  148. package/server/migrations/011_outreach.sql +47 -0
  149. package/server/migrations/012_shieldlink.sql +116 -0
  150. package/server/migrations/013_ct_monitor.sql +13 -0
  151. package/server/migrations/014_wab_advanced_features.sql +128 -0
  152. package/server/migrations/015_wab_truth_layer.sql +101 -0
  153. package/server/migrations/016_ring4_external_trust.sql +84 -0
  154. package/server/migrations/017_ring4_extensions.sql +69 -0
  155. package/server/migrations/018_commercial_foundations.sql +167 -0
  156. package/server/migrations/019_unify_tier_constraints.sql +133 -0
  157. package/server/models/adapters/index.js +33 -33
  158. package/server/models/adapters/mysql.js +183 -183
  159. package/server/models/adapters/postgresql.js +172 -172
  160. package/server/models/adapters/sqlite.js +7 -7
  161. package/server/models/db.js +740 -740
  162. package/server/observability/failure-analysis.js +337 -337
  163. package/server/observability/index.js +394 -394
  164. package/server/protocol/capabilities.js +223 -223
  165. package/server/protocol/index.js +243 -243
  166. package/server/protocol/schema.js +584 -584
  167. package/server/registry/certification.js +271 -271
  168. package/server/registry/index.js +326 -326
  169. package/server/routes/activate.js +478 -0
  170. package/server/routes/admin-outreach.js +239 -0
  171. package/server/routes/admin-plans.js +76 -76
  172. package/server/routes/admin-premium.js +674 -673
  173. package/server/routes/admin-shieldlink.js +137 -0
  174. package/server/routes/admin-shieldqr.js +90 -90
  175. package/server/routes/admin-trust-monitor.js +139 -83
  176. package/server/routes/admin.js +550 -549
  177. package/server/routes/adopt.js +61 -0
  178. package/server/routes/ads.js +130 -130
  179. package/server/routes/agent-workspace.js +540 -540
  180. package/server/routes/api-keys.js +127 -0
  181. package/server/routes/api.js +150 -150
  182. package/server/routes/auth.js +71 -71
  183. package/server/routes/billing.js +57 -57
  184. package/server/routes/commander.js +316 -316
  185. package/server/routes/customer-shieldlink.js +133 -0
  186. package/server/routes/demo-showcase.js +332 -332
  187. package/server/routes/demo-store.js +154 -154
  188. package/server/routes/diagnose.js +373 -0
  189. package/server/routes/discovery.js +2348 -2348
  190. package/server/routes/enterprise-mesh.js +170 -0
  191. package/server/routes/gateway.js +173 -173
  192. package/server/routes/governance-saas.js +203 -0
  193. package/server/routes/governance.js +208 -208
  194. package/server/routes/growth.js +1048 -0
  195. package/server/routes/intent.js +328 -0
  196. package/server/routes/license.js +251 -251
  197. package/server/routes/mesh.js +469 -469
  198. package/server/routes/noscript.js +543 -543
  199. package/server/routes/partners.js +201 -0
  200. package/server/routes/plans.js +33 -33
  201. package/server/routes/premium-v2.js +686 -686
  202. package/server/routes/premium.js +724 -724
  203. package/server/routes/providers.js +650 -650
  204. package/server/routes/reputation.js +411 -0
  205. package/server/routes/ring4.js +885 -0
  206. package/server/routes/runtime.js +2148 -2148
  207. package/server/routes/shieldlink.js +70 -0
  208. package/server/routes/shieldqr.js +88 -88
  209. package/server/routes/sovereign.js +465 -465
  210. package/server/routes/truth-layer.js +670 -0
  211. package/server/routes/universal.js +200 -200
  212. package/server/routes/unsubscribe.js +51 -0
  213. package/server/routes/wab-api.js +850 -850
  214. package/server/routes/wab-cache.js +282 -0
  215. package/server/runtime/container-worker.js +111 -111
  216. package/server/runtime/container.js +448 -448
  217. package/server/runtime/distributed-worker.js +362 -362
  218. package/server/runtime/event-bus.js +210 -210
  219. package/server/runtime/index.js +253 -253
  220. package/server/runtime/queue.js +599 -599
  221. package/server/runtime/replay.js +666 -666
  222. package/server/runtime/sandbox.js +266 -266
  223. package/server/runtime/scheduler.js +534 -534
  224. package/server/runtime/session-engine.js +293 -293
  225. package/server/runtime/state-manager.js +188 -188
  226. package/server/secrets/wab-signing-key.pem +3 -0
  227. package/server/secrets/wab-signing-pub.pem +3 -0
  228. package/server/security/cross-site-redactor.js +196 -196
  229. package/server/security/dry-run.js +180 -180
  230. package/server/security/human-gate-rate-limit.js +147 -147
  231. package/server/security/human-gate-transports.js +178 -178
  232. package/server/security/human-gate.js +281 -281
  233. package/server/security/index.js +368 -368
  234. package/server/security/intent-engine.js +245 -245
  235. package/server/security/reward-guard.js +171 -171
  236. package/server/security/rollback-store.js +239 -239
  237. package/server/security/token-scope.js +404 -404
  238. package/server/security/url-policy.js +139 -139
  239. package/server/services/adoption-agent.js +182 -0
  240. package/server/services/agent-chat.js +506 -506
  241. package/server/services/agent-learning.js +601 -601
  242. package/server/services/agent-memory.js +625 -625
  243. package/server/services/agent-mesh.js +555 -555
  244. package/server/services/agent-symphony.js +717 -717
  245. package/server/services/agent-tasks.js +1807 -1807
  246. package/server/services/api-key-engine.js +292 -292
  247. package/server/services/cluster.js +894 -894
  248. package/server/services/commander.js +738 -738
  249. package/server/services/edge-compute.js +440 -440
  250. package/server/services/email.js +233 -233
  251. package/server/services/fairness-engine.js +409 -0
  252. package/server/services/fairness.js +420 -0
  253. package/server/services/governance.js +466 -466
  254. package/server/services/hosted-runtime.js +205 -205
  255. package/server/services/lfd.js +635 -635
  256. package/server/services/local-ai.js +389 -389
  257. package/server/services/marketplace.js +270 -270
  258. package/server/services/metering.js +182 -182
  259. package/server/services/modules/affiliate-intelligence.js +93 -93
  260. package/server/services/modules/agent-firewall.js +90 -90
  261. package/server/services/modules/bounty.js +89 -89
  262. package/server/services/modules/collective-bargaining.js +92 -92
  263. package/server/services/modules/dark-pattern.js +66 -66
  264. package/server/services/modules/gov-intelligence.js +45 -45
  265. package/server/services/modules/neural.js +55 -55
  266. package/server/services/modules/notary.js +49 -49
  267. package/server/services/modules/price-time-machine.js +86 -86
  268. package/server/services/modules/protocol.js +104 -104
  269. package/server/services/negotiation.js +439 -439
  270. package/server/services/outreach-agent.js +312 -0
  271. package/server/services/plans.js +214 -214
  272. package/server/services/plugins.js +771 -771
  273. package/server/services/price-intelligence.js +566 -566
  274. package/server/services/price-shield.js +1137 -1137
  275. package/server/services/provider-clients.js +740 -740
  276. package/server/services/reputation.js +465 -465
  277. package/server/services/search-engine.js +357 -357
  278. package/server/services/security.js +513 -513
  279. package/server/services/self-healing.js +843 -843
  280. package/server/services/shieldlink.js +492 -0
  281. package/server/services/shieldqr.js +322 -322
  282. package/server/services/sovereign-shield.js +542 -542
  283. package/server/services/ssl-ct-monitor.js +224 -0
  284. package/server/services/ssl-inspector.js +42 -42
  285. package/server/services/ssl-monitor.js +167 -167
  286. package/server/services/stripe.js +206 -205
  287. package/server/services/swarm.js +788 -788
  288. package/server/services/universal-scraper.js +662 -662
  289. package/server/services/verification.js +481 -481
  290. package/server/services/vision.js +1163 -1163
  291. package/server/services/wab-crypto.js +178 -178
  292. package/server/utils/cache.js +125 -125
  293. package/server/utils/migrate.js +81 -81
  294. package/server/utils/safe-fetch.js +228 -228
  295. package/server/utils/secureFields.js +50 -50
  296. package/server/ws.js +161 -161
  297. package/templates/artisan-marketplace.yaml +104 -104
  298. package/templates/book-price-scout.yaml +98 -98
  299. package/templates/electronics-price-tracker.yaml +108 -108
  300. package/templates/flight-deal-hunter.yaml +113 -113
  301. package/templates/freelancer-direct.yaml +116 -116
  302. package/templates/grocery-price-compare.yaml +93 -93
  303. package/templates/hotel-direct-booking.yaml +113 -113
  304. package/templates/local-services.yaml +98 -98
  305. package/templates/olive-oil-tunisia.yaml +88 -88
  306. package/templates/organic-farm-fresh.yaml +101 -101
  307. package/templates/restaurant-direct.yaml +97 -97
  308. package/templates/ring4/banking-sovereign.yaml +55 -0
  309. package/templates/ring4/ecommerce-sovereign.yaml +58 -0
  310. package/templates/ring4/healthcare-sovereign.yaml +60 -0
@@ -0,0 +1,133 @@
1
+ -- ─────────────────────────────────────────────────────────────────────
2
+ -- Migration 019: Unify tier CHECK constraints with canonical plans table
3
+ --
4
+ -- Background:
5
+ -- plans table (008_plans.sql) seeds: free / pro / business / enterprise
6
+ -- Legacy CHECK constraints accepted: free / starter / pro / enterprise
7
+ -- ⇒ Cannot purchase the canonical 'business' tier because the row would
8
+ -- violate the CHECK constraint on sites.tier, subscriptions.tier,
9
+ -- stripe_subscriptions.tier, free_grants.granted_tier and
10
+ -- workspace_subscriptions.plan.
11
+ --
12
+ -- This migration accepts BOTH 'starter' (legacy / kept for back-compat
13
+ -- with any existing rows or external scripts) AND 'business' (canonical
14
+ -- new tier name).
15
+ --
16
+ -- SQLite-recommended pattern: create new table, copy rows, drop old,
17
+ -- rename new, recreate indexes. defer_foreign_keys lets us do it inside
18
+ -- a single transaction.
19
+ -- ─────────────────────────────────────────────────────────────────────
20
+
21
+ PRAGMA defer_foreign_keys = ON;
22
+
23
+ -- ── 1) sites ─────────────────────────────────────────────────────────
24
+ CREATE TABLE sites_new (
25
+ id TEXT PRIMARY KEY,
26
+ user_id TEXT NOT NULL,
27
+ domain TEXT NOT NULL,
28
+ name TEXT NOT NULL,
29
+ description TEXT,
30
+ tier TEXT DEFAULT 'free' CHECK(tier IN ('free','starter','pro','business','enterprise')),
31
+ license_key TEXT UNIQUE NOT NULL,
32
+ api_key TEXT UNIQUE,
33
+ config TEXT DEFAULT '{}',
34
+ active INTEGER DEFAULT 1,
35
+ created_at TEXT DEFAULT (datetime('now')),
36
+ updated_at TEXT DEFAULT (datetime('now')),
37
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
38
+ );
39
+ INSERT INTO sites_new SELECT * FROM sites;
40
+ DROP TABLE sites;
41
+ ALTER TABLE sites_new RENAME TO sites;
42
+ CREATE INDEX IF NOT EXISTS idx_sites_domain ON sites(domain);
43
+ CREATE INDEX IF NOT EXISTS idx_sites_license ON sites(license_key);
44
+
45
+ -- ── 2) subscriptions ────────────────────────────────────────────────
46
+ CREATE TABLE subscriptions_new (
47
+ id TEXT PRIMARY KEY,
48
+ user_id TEXT NOT NULL,
49
+ site_id TEXT NOT NULL,
50
+ tier TEXT NOT NULL CHECK(tier IN ('free','starter','pro','business','enterprise')),
51
+ status TEXT DEFAULT 'active' CHECK(status IN ('active','cancelled','expired','trial')),
52
+ started_at TEXT DEFAULT (datetime('now')),
53
+ expires_at TEXT,
54
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
55
+ FOREIGN KEY (site_id) REFERENCES sites(id) ON DELETE CASCADE
56
+ );
57
+ INSERT INTO subscriptions_new SELECT * FROM subscriptions;
58
+ DROP TABLE subscriptions;
59
+ ALTER TABLE subscriptions_new RENAME TO subscriptions;
60
+
61
+ -- ── 3) free_grants ──────────────────────────────────────────────────
62
+ CREATE TABLE free_grants_new (
63
+ id TEXT PRIMARY KEY,
64
+ user_id TEXT NOT NULL,
65
+ site_id TEXT,
66
+ granted_tier TEXT NOT NULL CHECK(granted_tier IN ('starter','pro','business','enterprise')),
67
+ reason TEXT,
68
+ granted_by TEXT NOT NULL,
69
+ granted_at TEXT DEFAULT (datetime('now')),
70
+ expires_at TEXT,
71
+ active INTEGER DEFAULT 1,
72
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
73
+ FOREIGN KEY (granted_by) REFERENCES admins(id)
74
+ );
75
+ INSERT INTO free_grants_new SELECT * FROM free_grants;
76
+ DROP TABLE free_grants;
77
+ ALTER TABLE free_grants_new RENAME TO free_grants;
78
+
79
+ -- ── 4) stripe_subscriptions ─────────────────────────────────────────
80
+ CREATE TABLE stripe_subscriptions_new (
81
+ id TEXT PRIMARY KEY,
82
+ user_id TEXT NOT NULL,
83
+ site_id TEXT NOT NULL,
84
+ stripe_subscription_id TEXT UNIQUE,
85
+ stripe_price_id TEXT,
86
+ tier TEXT NOT NULL CHECK(tier IN ('starter','pro','business','enterprise')),
87
+ status TEXT DEFAULT 'active' CHECK(status IN ('active','cancelled','past_due','trialing','incomplete')),
88
+ current_period_start TEXT,
89
+ current_period_end TEXT,
90
+ created_at TEXT DEFAULT (datetime('now')),
91
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
92
+ FOREIGN KEY (site_id) REFERENCES sites(id) ON DELETE CASCADE
93
+ );
94
+ INSERT INTO stripe_subscriptions_new SELECT * FROM stripe_subscriptions;
95
+ DROP TABLE stripe_subscriptions;
96
+ ALTER TABLE stripe_subscriptions_new RENAME TO stripe_subscriptions;
97
+
98
+ -- ── 5) workspace_subscriptions (agent-workspace.js dynamic table) ────
99
+ -- Created on first import of routes/agent-workspace.js. May not exist
100
+ -- in fresh installs that have not loaded that route yet; guard with
101
+ -- a defensive recreate.
102
+ CREATE TABLE IF NOT EXISTS workspace_subscriptions (
103
+ id TEXT PRIMARY KEY,
104
+ user_id TEXT NOT NULL,
105
+ plan TEXT NOT NULL DEFAULT 'free',
106
+ status TEXT NOT NULL DEFAULT 'active',
107
+ tasks_today INTEGER DEFAULT 0,
108
+ tasks_total INTEGER DEFAULT 0,
109
+ deals_completed INTEGER DEFAULT 0,
110
+ total_savings REAL DEFAULT 0,
111
+ last_task_date TEXT,
112
+ created_at TEXT DEFAULT (datetime('now')),
113
+ expires_at TEXT,
114
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
115
+ );
116
+
117
+ CREATE TABLE workspace_subscriptions_new (
118
+ id TEXT PRIMARY KEY,
119
+ user_id TEXT NOT NULL,
120
+ plan TEXT NOT NULL DEFAULT 'free' CHECK(plan IN ('free','starter','pro','business','enterprise')),
121
+ status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active','cancelled','expired','suspended')),
122
+ tasks_today INTEGER DEFAULT 0,
123
+ tasks_total INTEGER DEFAULT 0,
124
+ deals_completed INTEGER DEFAULT 0,
125
+ total_savings REAL DEFAULT 0,
126
+ last_task_date TEXT,
127
+ created_at TEXT DEFAULT (datetime('now')),
128
+ expires_at TEXT,
129
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
130
+ );
131
+ INSERT INTO workspace_subscriptions_new SELECT * FROM workspace_subscriptions;
132
+ DROP TABLE workspace_subscriptions;
133
+ ALTER TABLE workspace_subscriptions_new RENAME TO workspace_subscriptions;
@@ -1,33 +1,33 @@
1
- /**
2
- * Database Adapter Interface
3
- *
4
- * WAB supports multiple database backends via adapters.
5
- * Set DB_ADAPTER environment variable to choose: sqlite (default), postgresql, mysql
6
- *
7
- * For PostgreSQL:
8
- * npm install pg
9
- * DB_ADAPTER=postgresql DATABASE_URL=postgres://user:pass@host:5432/wab
10
- *
11
- * For MySQL:
12
- * npm install mysql2
13
- * DB_ADAPTER=mysql DATABASE_URL=mysql://user:pass@host:3306/wab
14
- */
15
-
16
- const adapter = process.env.DB_ADAPTER || 'sqlite';
17
-
18
- let db;
19
- switch (adapter) {
20
- case 'postgresql':
21
- case 'postgres':
22
- db = require('./postgresql');
23
- break;
24
- case 'mysql':
25
- db = require('./mysql');
26
- break;
27
- case 'sqlite':
28
- default:
29
- db = require('./sqlite');
30
- break;
31
- }
32
-
33
- module.exports = db;
1
+ /**
2
+ * Database Adapter Interface
3
+ *
4
+ * WAB supports multiple database backends via adapters.
5
+ * Set DB_ADAPTER environment variable to choose: sqlite (default), postgresql, mysql
6
+ *
7
+ * For PostgreSQL:
8
+ * npm install pg
9
+ * DB_ADAPTER=postgresql DATABASE_URL=postgres://user:pass@host:5432/wab
10
+ *
11
+ * For MySQL:
12
+ * npm install mysql2
13
+ * DB_ADAPTER=mysql DATABASE_URL=mysql://user:pass@host:3306/wab
14
+ */
15
+
16
+ const adapter = process.env.DB_ADAPTER || 'sqlite';
17
+
18
+ let db;
19
+ switch (adapter) {
20
+ case 'postgresql':
21
+ case 'postgres':
22
+ db = require('./postgresql');
23
+ break;
24
+ case 'mysql':
25
+ db = require('./mysql');
26
+ break;
27
+ case 'sqlite':
28
+ default:
29
+ db = require('./sqlite');
30
+ break;
31
+ }
32
+
33
+ module.exports = db;
@@ -1,183 +1,183 @@
1
- /**
2
- * MySQL Adapter for WAB
3
- *
4
- * Prerequisites: npm install mysql2
5
- * Set DATABASE_URL=mysql://user:pass@host:3306/wab
6
- *
7
- * This adapter implements the same interface as the SQLite adapter
8
- * so it can be used as a drop-in replacement.
9
- */
10
-
11
- const mysql = require('mysql2/promise');
12
- const bcrypt = require('bcryptjs');
13
- const { randomUUID: uuidv4 } = require('crypto');
14
-
15
- const pool = mysql.createPool(process.env.DATABASE_URL);
16
-
17
- // Initialize tables
18
- async function initDB() {
19
- const conn = await pool.getConnection();
20
- try {
21
- await conn.query(`
22
- CREATE TABLE IF NOT EXISTS users (
23
- id VARCHAR(36) PRIMARY KEY,
24
- email VARCHAR(255) UNIQUE NOT NULL,
25
- password VARCHAR(255) NOT NULL,
26
- name VARCHAR(255) NOT NULL,
27
- company VARCHAR(255),
28
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
29
- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
30
- )
31
- `);
32
- await conn.query(`
33
- CREATE TABLE IF NOT EXISTS sites (
34
- id VARCHAR(36) PRIMARY KEY,
35
- user_id VARCHAR(36) NOT NULL,
36
- domain VARCHAR(255) NOT NULL,
37
- name VARCHAR(255) NOT NULL,
38
- description TEXT,
39
- tier ENUM('free','starter','pro','enterprise') DEFAULT 'free',
40
- license_key VARCHAR(30) UNIQUE NOT NULL,
41
- api_key VARCHAR(50) UNIQUE,
42
- config JSON,
43
- active BOOLEAN DEFAULT TRUE,
44
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
45
- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
46
- FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
47
- INDEX idx_sites_domain (domain),
48
- INDEX idx_sites_license (license_key)
49
- )
50
- `);
51
- await conn.query(`
52
- CREATE TABLE IF NOT EXISTS analytics (
53
- id INT AUTO_INCREMENT PRIMARY KEY,
54
- site_id VARCHAR(36) NOT NULL,
55
- action_name VARCHAR(255) NOT NULL,
56
- agent_id VARCHAR(255),
57
- trigger_type VARCHAR(50),
58
- success BOOLEAN,
59
- metadata JSON,
60
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
61
- FOREIGN KEY (site_id) REFERENCES sites(id) ON DELETE CASCADE,
62
- INDEX idx_analytics_site (site_id),
63
- INDEX idx_analytics_created (created_at)
64
- )
65
- `);
66
- await conn.query(`
67
- CREATE TABLE IF NOT EXISTS subscriptions (
68
- id VARCHAR(36) PRIMARY KEY,
69
- user_id VARCHAR(36) NOT NULL,
70
- site_id VARCHAR(36) NOT NULL,
71
- tier ENUM('free','starter','pro','enterprise') NOT NULL,
72
- status ENUM('active','cancelled','expired','trial') DEFAULT 'active',
73
- started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
74
- expires_at TIMESTAMP NULL,
75
- FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
76
- FOREIGN KEY (site_id) REFERENCES sites(id) ON DELETE CASCADE
77
- )
78
- `);
79
- } finally {
80
- conn.release();
81
- }
82
- }
83
-
84
- initDB().catch(console.error);
85
-
86
- function generateLicenseKey() {
87
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
88
- const segments = [];
89
- for (let s = 0; s < 4; s++) {
90
- let seg = '';
91
- for (let i = 0; i < 5; i++) seg += chars[Math.floor(Math.random() * chars.length)];
92
- segments.push(seg);
93
- }
94
- return `WAB-${segments.join('-')}`;
95
- }
96
-
97
- function generateApiKey() {
98
- return `wab_${uuidv4().replace(/-/g, '')}`;
99
- }
100
-
101
- // ─── User Operations ──────────────────────────────────────────────────
102
- async function registerUser({ email, password, name, company }) {
103
- const id = uuidv4();
104
- const hashed = bcrypt.hashSync(password, 12);
105
- await pool.execute(
106
- 'INSERT INTO users (id, email, password, name, company) VALUES (?, ?, ?, ?, ?)',
107
- [id, email, hashed, name, company || null]
108
- );
109
- return { id, email, name, company };
110
- }
111
-
112
- async function loginUser({ email, password }) {
113
- const [rows] = await pool.execute('SELECT * FROM users WHERE email = ?', [email]);
114
- const user = rows[0];
115
- if (!user) return null;
116
- if (!bcrypt.compareSync(password, user.password)) return null;
117
- return { id: user.id, email: user.email, name: user.name, company: user.company };
118
- }
119
-
120
- // ─── Site Operations ──────────────────────────────────────────────────
121
- async function addSite({ userId, domain, name, description, tier }) {
122
- const id = uuidv4();
123
- const licenseKey = generateLicenseKey();
124
- const apiKey = generateApiKey();
125
- const config = JSON.stringify({
126
- agentPermissions: { readContent: true, click: true, fillForms: false, scroll: true, navigate: false, apiAccess: false, automatedLogin: false, extractData: false },
127
- features: { advancedAnalytics: false, realTimeUpdates: false },
128
- restrictions: { allowedSelectors: [], blockedSelectors: ['.private', '[data-private]'], rateLimit: { maxCallsPerMinute: 60 } },
129
- logging: { enabled: false, level: 'basic' }
130
- });
131
- await pool.execute(
132
- 'INSERT INTO sites (id, user_id, domain, name, description, tier, license_key, api_key, config) VALUES (?,?,?,?,?,?,?,?,?)',
133
- [id, userId, domain, name, description || '', tier || 'free', licenseKey, apiKey, config]
134
- );
135
- return { id, domain, name, licenseKey, apiKey, tier: tier || 'free' };
136
- }
137
-
138
- // ─── Analytics ────────────────────────────────────────────────────────
139
- async function recordAnalytic({ siteId, actionName, agentId, triggerType, success, metadata }) {
140
- await pool.execute(
141
- 'INSERT INTO analytics (site_id, action_name, agent_id, trigger_type, success, metadata) VALUES (?,?,?,?,?,?)',
142
- [siteId, actionName, agentId || null, triggerType || null, success ? 1 : 0, JSON.stringify(metadata || {})]
143
- );
144
- }
145
-
146
- // ─── License Verification ─────────────────────────────────────────────
147
- async function verifyLicense(domain, licenseKey) {
148
- const [rows] = await pool.execute(
149
- 'SELECT * FROM sites WHERE domain = ? AND license_key = ? AND active = TRUE', [domain, licenseKey]
150
- );
151
- const site = rows[0];
152
- if (!site) {
153
- const [byKey] = await pool.execute('SELECT * FROM sites WHERE license_key = ? AND active = TRUE', [licenseKey]);
154
- if (byKey[0]) return { valid: false, error: 'Domain mismatch', tier: 'free' };
155
- return { valid: false, error: 'Invalid license key', tier: 'free' };
156
- }
157
-
158
- const tierPermissions = {
159
- free: { apiAccess: false, automatedLogin: false, extractData: false, advancedAnalytics: false },
160
- starter: { apiAccess: false, automatedLogin: true, extractData: false, advancedAnalytics: true },
161
- pro: { apiAccess: true, automatedLogin: true, extractData: true, advancedAnalytics: true },
162
- enterprise: { apiAccess: true, automatedLogin: true, extractData: true, advancedAnalytics: true }
163
- };
164
-
165
- const config = typeof site.config === 'string' ? JSON.parse(site.config) : site.config;
166
- return {
167
- valid: true,
168
- tier: site.tier,
169
- permissions: { ...config.agentPermissions, ...tierPermissions[site.tier] },
170
- restrictions: config.restrictions,
171
- features: config.features,
172
- siteId: site.id
173
- };
174
- }
175
-
176
- module.exports = {
177
- registerUser,
178
- loginUser,
179
- addSite,
180
- recordAnalytic,
181
- verifyLicense,
182
- pool
183
- };
1
+ /**
2
+ * MySQL Adapter for WAB
3
+ *
4
+ * Prerequisites: npm install mysql2
5
+ * Set DATABASE_URL=mysql://user:pass@host:3306/wab
6
+ *
7
+ * This adapter implements the same interface as the SQLite adapter
8
+ * so it can be used as a drop-in replacement.
9
+ */
10
+
11
+ const mysql = require('mysql2/promise');
12
+ const bcrypt = require('bcryptjs');
13
+ const { randomUUID: uuidv4 } = require('crypto');
14
+
15
+ const pool = mysql.createPool(process.env.DATABASE_URL);
16
+
17
+ // Initialize tables
18
+ async function initDB() {
19
+ const conn = await pool.getConnection();
20
+ try {
21
+ await conn.query(`
22
+ CREATE TABLE IF NOT EXISTS users (
23
+ id VARCHAR(36) PRIMARY KEY,
24
+ email VARCHAR(255) UNIQUE NOT NULL,
25
+ password VARCHAR(255) NOT NULL,
26
+ name VARCHAR(255) NOT NULL,
27
+ company VARCHAR(255),
28
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
29
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
30
+ )
31
+ `);
32
+ await conn.query(`
33
+ CREATE TABLE IF NOT EXISTS sites (
34
+ id VARCHAR(36) PRIMARY KEY,
35
+ user_id VARCHAR(36) NOT NULL,
36
+ domain VARCHAR(255) NOT NULL,
37
+ name VARCHAR(255) NOT NULL,
38
+ description TEXT,
39
+ tier ENUM('free','starter','pro','business','enterprise') DEFAULT 'free',
40
+ license_key VARCHAR(30) UNIQUE NOT NULL,
41
+ api_key VARCHAR(50) UNIQUE,
42
+ config JSON,
43
+ active BOOLEAN DEFAULT TRUE,
44
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
45
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
46
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
47
+ INDEX idx_sites_domain (domain),
48
+ INDEX idx_sites_license (license_key)
49
+ )
50
+ `);
51
+ await conn.query(`
52
+ CREATE TABLE IF NOT EXISTS analytics (
53
+ id INT AUTO_INCREMENT PRIMARY KEY,
54
+ site_id VARCHAR(36) NOT NULL,
55
+ action_name VARCHAR(255) NOT NULL,
56
+ agent_id VARCHAR(255),
57
+ trigger_type VARCHAR(50),
58
+ success BOOLEAN,
59
+ metadata JSON,
60
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
61
+ FOREIGN KEY (site_id) REFERENCES sites(id) ON DELETE CASCADE,
62
+ INDEX idx_analytics_site (site_id),
63
+ INDEX idx_analytics_created (created_at)
64
+ )
65
+ `);
66
+ await conn.query(`
67
+ CREATE TABLE IF NOT EXISTS subscriptions (
68
+ id VARCHAR(36) PRIMARY KEY,
69
+ user_id VARCHAR(36) NOT NULL,
70
+ site_id VARCHAR(36) NOT NULL,
71
+ tier ENUM('free','starter','pro','business','enterprise') NOT NULL,
72
+ status ENUM('active','cancelled','expired','trial') DEFAULT 'active',
73
+ started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
74
+ expires_at TIMESTAMP NULL,
75
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
76
+ FOREIGN KEY (site_id) REFERENCES sites(id) ON DELETE CASCADE
77
+ )
78
+ `);
79
+ } finally {
80
+ conn.release();
81
+ }
82
+ }
83
+
84
+ initDB().catch(console.error);
85
+
86
+ function generateLicenseKey() {
87
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
88
+ const segments = [];
89
+ for (let s = 0; s < 4; s++) {
90
+ let seg = '';
91
+ for (let i = 0; i < 5; i++) seg += chars[Math.floor(Math.random() * chars.length)];
92
+ segments.push(seg);
93
+ }
94
+ return `WAB-${segments.join('-')}`;
95
+ }
96
+
97
+ function generateApiKey() {
98
+ return `wab_${uuidv4().replace(/-/g, '')}`;
99
+ }
100
+
101
+ // ─── User Operations ──────────────────────────────────────────────────
102
+ async function registerUser({ email, password, name, company }) {
103
+ const id = uuidv4();
104
+ const hashed = bcrypt.hashSync(password, 12);
105
+ await pool.execute(
106
+ 'INSERT INTO users (id, email, password, name, company) VALUES (?, ?, ?, ?, ?)',
107
+ [id, email, hashed, name, company || null]
108
+ );
109
+ return { id, email, name, company };
110
+ }
111
+
112
+ async function loginUser({ email, password }) {
113
+ const [rows] = await pool.execute('SELECT * FROM users WHERE email = ?', [email]);
114
+ const user = rows[0];
115
+ if (!user) return null;
116
+ if (!bcrypt.compareSync(password, user.password)) return null;
117
+ return { id: user.id, email: user.email, name: user.name, company: user.company };
118
+ }
119
+
120
+ // ─── Site Operations ──────────────────────────────────────────────────
121
+ async function addSite({ userId, domain, name, description, tier }) {
122
+ const id = uuidv4();
123
+ const licenseKey = generateLicenseKey();
124
+ const apiKey = generateApiKey();
125
+ const config = JSON.stringify({
126
+ agentPermissions: { readContent: true, click: true, fillForms: false, scroll: true, navigate: false, apiAccess: false, automatedLogin: false, extractData: false },
127
+ features: { advancedAnalytics: false, realTimeUpdates: false },
128
+ restrictions: { allowedSelectors: [], blockedSelectors: ['.private', '[data-private]'], rateLimit: { maxCallsPerMinute: 60 } },
129
+ logging: { enabled: false, level: 'basic' }
130
+ });
131
+ await pool.execute(
132
+ 'INSERT INTO sites (id, user_id, domain, name, description, tier, license_key, api_key, config) VALUES (?,?,?,?,?,?,?,?,?)',
133
+ [id, userId, domain, name, description || '', tier || 'free', licenseKey, apiKey, config]
134
+ );
135
+ return { id, domain, name, licenseKey, apiKey, tier: tier || 'free' };
136
+ }
137
+
138
+ // ─── Analytics ────────────────────────────────────────────────────────
139
+ async function recordAnalytic({ siteId, actionName, agentId, triggerType, success, metadata }) {
140
+ await pool.execute(
141
+ 'INSERT INTO analytics (site_id, action_name, agent_id, trigger_type, success, metadata) VALUES (?,?,?,?,?,?)',
142
+ [siteId, actionName, agentId || null, triggerType || null, success ? 1 : 0, JSON.stringify(metadata || {})]
143
+ );
144
+ }
145
+
146
+ // ─── License Verification ─────────────────────────────────────────────
147
+ async function verifyLicense(domain, licenseKey) {
148
+ const [rows] = await pool.execute(
149
+ 'SELECT * FROM sites WHERE domain = ? AND license_key = ? AND active = TRUE', [domain, licenseKey]
150
+ );
151
+ const site = rows[0];
152
+ if (!site) {
153
+ const [byKey] = await pool.execute('SELECT * FROM sites WHERE license_key = ? AND active = TRUE', [licenseKey]);
154
+ if (byKey[0]) return { valid: false, error: 'Domain mismatch', tier: 'free' };
155
+ return { valid: false, error: 'Invalid license key', tier: 'free' };
156
+ }
157
+
158
+ const tierPermissions = {
159
+ free: { apiAccess: false, automatedLogin: false, extractData: false, advancedAnalytics: false },
160
+ starter: { apiAccess: false, automatedLogin: true, extractData: false, advancedAnalytics: true },
161
+ pro: { apiAccess: true, automatedLogin: true, extractData: true, advancedAnalytics: true },
162
+ enterprise: { apiAccess: true, automatedLogin: true, extractData: true, advancedAnalytics: true }
163
+ };
164
+
165
+ const config = typeof site.config === 'string' ? JSON.parse(site.config) : site.config;
166
+ return {
167
+ valid: true,
168
+ tier: site.tier,
169
+ permissions: { ...config.agentPermissions, ...tierPermissions[site.tier] },
170
+ restrictions: config.restrictions,
171
+ features: config.features,
172
+ siteId: site.id
173
+ };
174
+ }
175
+
176
+ module.exports = {
177
+ registerUser,
178
+ loginUser,
179
+ addSite,
180
+ recordAnalytic,
181
+ verifyLicense,
182
+ pool
183
+ };