64 Commits

Author SHA1 Message Date
Matthew Meszaros 734cb5fe08 feat: make self-hosted onboarding survivable by fixing invite_only, which could not onboard anyone (the accept route is JWT-only, so redeeming the invitation that would create your account required already having one, making the self-host default silently identical to fully closed), threading the invitation token through registration so an invited person lands in the inviting organization instead of a stray workspace, gating SSO just-in-time provisioning behind DISABLE_REGISTRATION (it bypassed the gate entirely, so an instance set to true was still open to anyone the IdP would assert) with SSO_AUTO_PROVISION as the opt-out, correcting the OIDC redirect URL that pointed at /api/v1 against a route at /v1 and 404'd every SSO login, scoping the first-launch exemption so it no longer overrides an explicit lockdown, preserving the remaining TTL when restoring a losing setup token so a public endpoint cannot hold the claim window open forever, replacing a generic 403 with typed registration_invite_only, registration_closed, invitation_invalid, setup_token_invalid and setup_already_complete codes that name the next step, logging why no claim link was issued on an already-claimed instance instead of staying silent, adding a warmblyctl operator CLI (status with health checks and a non-zero exit, reissuable setup-link, user create/list/reset-password/grant-admin/revoke-admin/disable-2fa, hash-password) so a locked-out operator no longer needs hand-written psql, adding read-only instance configuration over 104 environment variables with structural secret redaction and fingerprints, 35 health checks, a database-backed settings tier for the three keys no environment variable owns, hiding the signup form when the config already says invite_only rather than failing the whole form with a toast, and documenting first run, accounts and access, configuration, instance health and troubleshooting alongside the root .env.example the README told operators to write but never shipped (#114) 2026-08-16 05:58:11 +02:00
Matthew Meszaros 0ae4db2c41 feat: make self-hosted auth work without a mail relay by rewriting the platform SMTP transport with real AUTH and TLS (it did neither, so SMTP_USERNAME/SMTP_PASSWORD were dead and every documented relay was unreachable), adding MAIL_TRANSPORT=smtp|log|ses with a log transport that prints codes so a fresh install can sign in with no relay, demoting the emailed login code to AUTH_LOGIN_CODE=always|new_device|off (off on self-host, per NIST SP 800-63B and OWASP ASVS), claiming the first owner through a single-use setup link or WARMBLY_BOOTSTRAP_* instead of register-then-psql, deriving every emailed URL from APP_URL rather than a hardcoded app.warmbly.com that leaked live reset tokens to the vendor, fixing the confirm hooks that read path params against paramless routes and broke login, register and reset confirmation in the dashboard everywhere, adding generic OIDC with PKCE, one-time state, verified nonce and (issuer,subject) identity binding, enforcing 2FA on the social paths that skipped it, adding a per-IP limiter and trusted-proxy handling to the unthrottled auth group, refusing boot on the published default secrets, and dropping mailpit from the default stack (#99) 2026-08-14 14:57:09 +02:00
Matthew Meszaros 8f465fdb1c feat: give each mailbox a human sending persona (randomized daily and hourly caps, send spacing, work start/end, lunch break and working weekdays, rolled once per local day in the mailbox's own timezone and applied across the campaign, warmup and smart-send schedulers), add campaign auto-pause guardrails that stop a campaign when its bounce, complaint or reply rate leaves the configured band, make mailbox rotation actually rotate for tag-resolved and all-mailbox campaigns, stop every scheduler from ever returning a slot in the past, and correct the mailbox min-gap field that stored seconds while labelling them minutes 2026-08-13 16:51:29 +02:00
Matthew Meszaros 8bd2c2b57a feat: make self-hosting work end to end and rewrite the guide around what was tested (#97) 2026-08-13 09:47:46 +02:00
Matthew Meszaros a7518a8558 docs: refresh the documentation site, fix inaccurate claims and contact addresses, add SEO primitives (#90)
* feat: rewrite the self-hosting docs against repo ground truth: turn the deployment guide into a full self-host guide (quick start with first-admin bootstrap via make grant-admin, .env secrets with exact key formats, PUBLIC_HOST derivation and HTTPS reverse-proxy vars, provider switches with build-tag caveats, mailbox OAuth, remote worker enrollment via SSH or wmenroll tokens, real CI image tags, upgrades and backups), rewrite the events page around the real NATS/Kafka bus topics and {type,body} envelopes, fix Kafka-era and make-target claims in architecture/local-development/deploy README, add API_PUBLIC_URL and drop the dead LOG_DISCORD_WEBHOOK_URL in env.example, and remove the docker-compose.kafka.yml comment pointing at a file that does not exist

* feat: make the self-hosting docs visual and skimmable by adding a Mermaid MDX component (client-rendered, theme-aware) to the docs site, condensing the self-host guide around a control-plane topology diagram, a worker enrollment sequence diagram, a dashboard screenshot, and symptom/check troubleshooting + optional-subsystem tables, and adding an execution-plane flowchart to the architecture page

* feat: stop the docs root flashing a 'Continue to the Warmbly docs' link before redirecting by navigating with an inline location.replace that runs during HTML parse, and demoting the visible link and meta refresh to no-JS fallbacks inside noscript

* feat: cut docs bulk and duplication by deleting three orphaned API pages that were stale forks of the reference section and were unreachable from the sidebar (porting their unique social sign-in, promo-code, and referral endpoints into api/reference/account-org.mdx as compact tables), condensing the deliverability and warmup guides to roughly half their length around tables instead of prose, replacing prose em dashes across the guides and MCP pages, and adding the required trailing slashes to internal links in 24 files

* feat: condense the sequences guide by about 40 percent, folding the switch-step deciders and branch conditions into tables and cutting restated prose while keeping every rule about threading, instant branches, reply matching, and stop on reply

* feat: condense the automations, unibox, advisor, and expressions guides by roughly 40 percent each, folding trigger lists, action catalogs, sending controls, and advisor checks into tables, adding a trigger-condition-action flow diagram to automations, and cutting restated prose while preserving every threshold, permission boundary, and rule

* feat: condense the mailboxes, campaigns, analytics, and team-roles guides by roughly 45 percent each, replacing prose walks through providers, rotation modes, lead statuses, counting rules, A/B confidence, and the permission matrix with compact tables and collapsing the four-way role grid into one capability table plus a one-line mapping

* feat: condense the AI-steps, security, and contacts-CRM guides by roughly 40 percent, turning sign-in methods, AI step modes, switch deciders, credit and failure behavior, import field mappings, and deal views into tables while keeping every safety boundary and dedupe rule

* feat: condense the meetings, notifications, AI-credits, and AI-assistant guides by roughly 40 percent, merging notification categories and their defaults into one table, collapsing credit costs, spend controls, and plan allowances into tables, and tightening the assistant page around its approval and permission boundaries

* feat: condense the integrations, collaboration, zapier, and make guides by roughly 35 percent, grouping the thirty-row Zapier and Make action lists into eight labelled areas, folding CRM default field mappings and presence indicators into tables, and promoting the destructive-action and unattended-delete warnings into callouts

* fix: correct three factual errors in the development docs: NOTIFICATION_EMAIL_DAILY_CAP=0 means uncapped rather than disabled (overEmailBudget returns false at limit<=0, so documenting it as a kill switch inverted the behavior), and the worker-SSH and warmup-pool migration citations in architecture.mdx pointed at pre-squash filenames that no longer exist or now belong to unrelated migrations, so both now cite the tables in 000001_baseline.up.sql

* feat: add the missing docs SEO primitives: a build-time sitemap.xml covering all 64 pages, a robots.txt that points at it and keeps the llms.mdx and og mirrors out of the index as duplicate content, and per-page canonical plus richer OpenGraph URL/title/description metadata

* fix: use the single real team@warmbly.com address everywhere a human is told to write in, replacing the invented hello/sales/legal/support inboxes across the marketing site, the transactional email footer, and the admin outreach composer default Reply-To (which pointed replies at a mailbox that does not exist), and collapse the contact page's two-inbox framing into one inbox with one published response time
2026-08-05 10:37:27 +02:00
Matthew Meszaros 764500391c fix: clear the trivy security scan by bumping react-router-dom to 7.18.1 in web and admin, postcss to 8.5.23 across web/admin/docs (docs via a pnpm-workspace override since next pins 8.4.31), next and eslint-config-next to 16.2.11, and ignoring the RSC-only react-router CSRF advisory 2026-07-26 19:36:23 +02:00
Matthew Meszaros 664774e1e3 feat: add production nginx Dockerfiles for the web dashboard and admin panel that build the SPA once and render /config.js from WARMBLY_* env at container start 2026-07-22 18:40:06 +02:00
Matthew Meszaros 611ecba1c2 feat: add the same runtime config shim to the admin panel so its built image reads api url, dashboard url, env label, and turnstile key from container env 2026-07-22 18:40:06 +02:00
Matthew Meszaros f768029ec0 feat: automate warmup conversation generation, coherent replies, adaptive rotation, and admin observability 2026-07-22 12:11:19 +02:00
Matthew Meszaros d4b201eef0 fix: bump axios and js-yaml to clear the trivy security scan 2026-07-21 17:59:46 +02:00
Matthew Meszaros b1070ce097 feat: rip the cloud-provisioning and billing pages out of the admin ui 2026-07-20 09:56:29 +02:00
Matthew Meszaros 9f1f511c8b feat: replace the AWS credential dialog's example-key placeholders with descriptive text - the AKIA-prefixed sample matched Trivy's aws-access-key-id secret rule and failed the security scan 2026-07-12 09:04:02 +02:00
Matthew Meszaros 262d25779c feat: realtime admin dashboard + diagnosability - new Elixir admin:platform channel (JWT-only, gated on users.admin_permissions) mirrors every platform event, the admin app connects through a /getaway-tokenized Phoenix socket client with a throttled react-query invalidation spine, a Live Events firehose page streams the platform with filters/pause/JSON expand, a System Status page runs parallel infra probes (postgres/redis/kafka/schema-registry/realtime/tracking via /admin/system/status), and the worker logs viewer gains follow mode, line-count selection, and copy 2026-07-12 09:00:10 +02:00
Matthew Meszaros a26d144b49 feat: continuous warmup-content refresh + full admin control surface - the scheduler now recycles the most-used AI threads each run (refresh_enabled/refresh_per_run) so fresh warmup messages keep generating after the target is reached, the warmup-content overview exposes the whole automation pipeline (AI configured/enabled/scheduled/stocked, per-segment stock vs target, daily budget), state legends explain risk-pool/health/job-status enums, and new settings pages cover worker profiles, releases, provisioning policy, and AWS credentials 2026-07-12 08:59:59 +02:00
Matthew Meszaros 9b948e326c chore(security): sync admin package.json vite range to ^7.3.6 to match the security-patched lockfile 2026-06-28 06:29:18 +00:00
Matthew Meszaros 9eb633414f fix(security): bump admin vite to 7.3.6 and form-data to 4.0.6 to clear CVE-2026-53571 and CVE-2026-12143 2026-06-28 06:29:01 +00:00
Matthew Meszaros 587eae774e feat: serve the entire customer API (auth + resources) only under /v1 with no unversioned alias, and repoint the web and admin clients to the versioned base accordingly 2026-06-13 07:18:23 +02:00
Matthew Meszaros 1afe453eb0 feat: add deliverability controls
Add seed inbox-placement testing with admin management, placement result polling, and seed mailbox persistence.

Add pre-send email verification, invalid-recipient skipping, warmup-health campaign gating, and RFC 8058 one-click unsubscribe headers/endpoints.
2026-06-03 16:47:53 +02:00
Matthew Meszaros b0b712a43f feat: refine warmup content admin
Treat warmup content as a shared library in settings and admin tables, and realign the conversation pick index with segment-based selection.

Add generation job details and fix warmup placement displays so backend percentages and provider counts render correctly.
2026-06-03 11:32:09 +02:00
Matthew Meszaros 0b6dc6ddfd feat: split warmup content admin pages
Replace the monolithic warmup content admin page with routed overview, library, generate, jobs, and settings pages.

Add shared warmup content layout, tab navigation, and reusable presentation helpers for the section.
2026-06-03 11:14:47 +02:00
Matthew Meszaros 2009780beb feat: add warmup batch generation
Add OpenAI Batch API support for warmup content generation, including job metadata, polling, cancellation, and completed-batch ingestion.

Share the generation prompt between sync and batch modes and humanize/lint generated threads before storing them in the warmup content library.
2026-06-03 11:14:33 +02:00
Matthew Meszaros 38cbcd281e feat: add warmup star engagement
Add star-rate settings to warmup content controls and include star actions in generated engagement plans.

Execute Gmail stars via STARRED labels while keeping IMAP behavior a no-op to avoid duplicate flagging.
2026-06-03 06:26:47 +02:00
Matthew Meszaros 47bdf66899 feat: improve warmup health analytics
Record warmup spam placements by recipient provider and surface provider breakdowns in the admin health summary.

Track warmup replies and use stable static conversation ids so warmup analytics can correlate content reliably.
2026-06-03 06:26:39 +02:00
Matthew Meszaros 15ef9d4994 feat: add warmup content controls
Add warmup content generation and admin review surfaces, plus mailbox warmup appeal/status APIs.

Track warmup engagement and tampering signals so unsafe mailboxes can be handled by the warmup flow.
2026-06-03 05:05:53 +02:00
Matthew Meszaros cf5ca0e649 feat: consolidate admin infrastructure settings
Replace separate backend settings pages with a single infrastructure view, remove the egresses route, and update admin navigation/readme copy.
2026-06-02 15:54:47 +02:00
Matthew Meszaros e740aebba8 feat: upgrade admin management explorers
Wire expanded admin API contracts into campaigns, discounts, enterprise, limit request, outreach, plan, worker detail, and provisioning admin views.
2026-06-02 15:54:40 +02:00
Matthew Meszaros 0e31748662 feat: add worker explorer filters
Convert the managed workers page into a faceted explorer with client-side filtering, sorting, CSV metadata, and worker detail navigation.
2026-06-02 05:44:43 +02:00
Matthew Meszaros 6bc6c066fc feat: add faceted admin data browsers
Upgrade users, organizations, and mailboxes admin pages with explorer filters, date and numeric facets, sortable tables, and scoped navigation params.
2026-06-02 05:44:39 +02:00
Matthew Meszaros 3d0b514eb7 feat: add admin explorer filter primitives
Expand the admin explorer control set with select, toggle, date-range, and number-range filters plus shared date-range serialization helpers.
2026-06-02 05:44:35 +02:00
Matthew Meszaros 0b6c394e89 feat: wire admin explorer query params
Add a shared admin search query serializer and expose the expanded user, organization, and mailbox filter contracts to the frontend clients.
2026-06-02 05:44:31 +02:00
Matthew Meszaros 7906363c16 feat: refine the admin data explorer (organized facet rail, result count, icon toolbar, crisp table) 2026-06-01 18:14:10 +02:00
Matthew Meszaros 8be0aa0269 feat: Mailboxes browser + browse-mailboxes-by-org cross-entity filter 2026-06-01 18:01:40 +02:00
Matthew Meszaros 072e7a7b6e feat: data-explorer (filter rail + sortable, cursor-paged table) for Users and Organizations 2026-06-01 17:56:03 +02:00
Matthew Meszaros 412a4c0baa fix: broken admin list endpoints (uuid casts, campaign/plan columns, warmup pools shape) 2026-06-01 17:44:13 +02:00
Matthew Meszaros 86f72b8c53 feat: refine admin dashboard chrome
Align the sidebar header with the topbar, use the Warmbly logo, and let dashboard content use the full available width.
2026-06-01 17:41:13 +02:00
Matthew Meszaros df658ad9a0 feat: harden admin warmup error states
Wire the shared error state through warmup admin queries and guard summary cards against partial API responses.
2026-06-01 17:41:10 +02:00
Matthew Meszaros defe511bd3 feat: show full admin user list errors
Use the shared error state on user and organization admin tables so failed loads expose the real API message and request ID.
2026-06-01 17:41:05 +02:00
Matthew Meszaros 0e3bbcaca0 feat: add admin query error state
Introduce a shared admin error panel that displays full API failure details and offers an inline retry action.
2026-06-01 17:41:01 +02:00
Matthew Meszaros 2c8beefe0d feat: surface admin api error metadata
Capture backend error codes and request IDs in the admin APIError type so failed admin views can show actionable diagnostics.
2026-06-01 17:40:57 +02:00
Matthew Meszaros 910fac9808 feat: declutter the admin login (no dev env pill, flat mail badge, no load animation) 2026-06-01 16:49:46 +02:00
Matthew Meszaros 4944689e57 feat: add a complete admin favicon set (ico, png, apple-touch, manifest) 2026-06-01 16:43:27 +02:00
Matthew Meszaros abb38b0f51 feat: animate the admin login steps and add an OTP code input 2026-06-01 16:20:32 +02:00
Matthew Meszaros f62312d674 feat: optically center the Warmbly mark in the admin favicon 2026-06-01 16:19:29 +02:00
Matthew Meszaros f2913249b4 feat: implement the two-step email-code admin login flow 2026-06-01 13:58:06 +02:00
Matthew Meszaros bcc861ef7e feat: theme the admin favicon with the Warmbly mark in red 2026-06-01 13:19:37 +02:00
Matthew Meszaros d554fdec4a feat: redesign the admin login page 2026-06-01 13:12:32 +02:00
Matthew Meszaros 8b28b86b7f feat: support exposed local dev hosts
Add PUBLIC_HOST wiring for local web, admin, site, realtime, and backend CORS so the native dev stack can be reached over Tailscale or LAN without changing localhost defaults.
2026-06-01 05:51:02 +02:00
Matthew Meszaros 6766031cc5 feat: add discount code support for checkout and plan changes 2026-05-29 05:49:19 +00:00
Matt 3ffa416e40 feat(admin): mailboxes admin (cross-org triage)
Adds GET /admin/mailboxes — paginated platform-wide mailbox list that
joins email_accounts → users → organizations so the table answers
"whose mailbox is this and where does it live" without N+1 fetches.

Search covers mailbox email / owner email / org name; status filter
defaults to active so the active surface shows first ("inactive" /
"all" both available). Provider filter speeds up "show me every Gmail
mailbox" investigations. Cursor pagination matches the rest of the
admin lists.

Frontend page surfaces warmup-on/off, send budget, and last-sync time
with red-when-never / amber-when-stale-over-24h tone so an
investigator can spot dead mailboxes fast. Mailbox email links into
the owning user's detail page; org name links into the workspace
admin so the pivot path stays one click in either direction.

Gated on AdminPermViewUsers since mailbox triage is tightly coupled to
user/org context today; a dedicated bit can be carved later if
mailbox-specific actions land.
2026-05-28 12:38:08 +02:00
Matt 705877f2ff feat(admin/ui): analytics page with daily/hourly/worker charts
Replace the AnalyticsPage stub with the full chart pack over the
existing /admin/analytics/* endpoints. Four-up trend cards on top
(users / emails / campaigns / revenue growth vs. previous period),
then a 30-day stacked bar chart for daily email volume (delivered /
replied / bounced), and a two-up row with hourly-by-today plus a
sorted worker-load list that links into each worker's detail page.

No chart library — bars are CSS divs so the admin bundle doesn't pay
for recharts/d3 for this one screen. Hover tooltips on the bars carry
the per-day breakdown.

User-growth strip lives below the email charts for symmetry with the
Overview's "platform pulse" framing.
2026-05-28 12:33:31 +02:00