2026-09-04 21:11:25 -07:00
..
2026-08-05 10:37:27 +02:00
2026-08-05 10:37:27 +02:00
2026-07-16 07:50:24 +02:00
feat: rebuild the new-campaign wizard with animated step transitions, a numbered stepper, the shared Toggle instead of a broken hand-rolled switch, per-step validation that explains itself and a discard guard, register PopoverMenu's click-outside in the capture phase so dropdowns inside dialogs close on click-away, add a Campaigns back link and clickable breadcrumb crumbs, add a From contacts leads picker with category filter and select-all-matching backed by the bulk add_campaigns path whose SQL now scopes campaigns by organization instead of the caller, and stop self-hosted no-billing deployments presenting as a free trial or plan-metered by exposing billing_enabled on GET /auth/config, showing a Self-hosted badge, hiding Billing and Refer & earn, and reporting AI credits as unlimited with the header gauge and cost copy hidden
2026-08-18 07:48:58 -07:00
2026-07-16 07:50:24 +02:00
2026-08-05 10:37:27 +02:00
2026-07-22 17:24:07 +02:00
2026-09-03 04:13:39 -07:00
2026-08-05 10:37:27 +02:00
2026-09-04 21:00:26 -07:00
2026-09-04 02:59:01 -07:00
2026-09-04 04:07:44 -07:00
2026-07-16 07:50:24 +02:00
2026-09-03 05:22:05 -07:00
feat: give every campaign email a working opt-out: a reply-to-opt-out line by default or an unsubscribe link (workspace setting under Settings > Sending with a per-campaign override and a {{.UnsubscribeLink}} variable), signed per-recipient unsubscribe links served on the API origin so the List-Unsubscribe header no longer points at a dead warmbly.com page, a confirm page on GET with RFC 8058 one-click on POST and a resubscribe button, reply opt-out detection through the whole-word compliance lexicon with quoted history stripped, a first-class suppression list (Contacts tab, GET/POST/DELETE /suppressions with address and domain entries, audited removal, contact drawer action), the contact Subscribed flag enforced in campaign routing, migration 000122 with a shared recipient_suppressed() predicate, and docs for all of it
2026-09-03 01:52:40 -07:00
2026-08-05 10:37:27 +02:00
feat: forms v2, a full redesign of the hosted form and its builder: eight one-click themes, card/wide/split layouts with a brand cover panel, classic paged and Typeform-style focus modes split on a new page_break block, logo/cover/background uploads with size, fit and veil controls, an optional header bar that can span the page or sit with the form, a real HSV colour picker and font preview, per-contact personalized links that prefill and attribute without email verification, a render-token gate so the form JSON cannot be scraped without loading the page, funnel analytics with per-page drop-off and identified visitors, a leads-style forms list and responses table, and an organization custom forms domain verified by CNAME with hourly re-checks
2026-09-01 09:27:28 -07:00
2026-08-21 18:45:09 +02:00
feat: address verification overhaul for #264: MillionVerifier as a pay-as-you-go integration plugin with org-sealed key and automatic fallback to the built-in check, built-in prober gains domain cache, Microsoft/Yahoo fingerprinting, MX fallback, disposable/role sub-statuses and a self-check breaker, imports and POST /contacts accept verification results in any known provider vocabulary with auto-detected columns, verdict provenance and expiry columns (migration 000110), campaigns park at paused_undeliverable with re-verify/send-anyway instead of finishing, POST/GET /contacts/verification bulk actions and overview, launch gate override via acknowledge_list_risk, animated verification marks, banner and settings card in the dashboard, and docs
2026-08-29 23:11:22 -07:00
2026-09-04 21:11:25 -07:00
2026-08-05 10:37:27 +02:00
2026-08-05 10:37:27 +02:00
2026-09-04 04:03:44 -07:00
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
2026-08-05 10:37:27 +02:00
2026-08-28 12:26:55 -07:00
2026-09-03 20:38:27 -07:00
2026-08-28 09:46:39 -07:00
2026-09-04 21:00:26 -07:00
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
2026-09-01 03:53:19 -07:00
2026-09-03 02:20:47 -07:00
feat: let a linked self-hosted instance sign Google and Microsoft mailboxes in through Warmbly Cloud's own OAuth apps and send with cloud-brokered access tokens: the cloud runs the consent (pool_link_mailboxes.managed, brokered state in Redis, the existing /addresses/*/callback completes it and redirects to the instance's /cloud-oauth/done), keeps the refresh grant, mints short-lived tokens at /pool-link/instance/mailboxes/:id/token and refuses them for revoked links, removed, inactive or blocked mailboxes; the instance mirrors such mailboxes without a credential (cloud_link_mailboxes.managed), ships them to the worker as brokered so goog/msgraph init on a token source that pulls from /api/v1/internal/cloud-link/token/:id, lets the consumer ignore cloud warmup tokens for enrolled mailboxes, and can adopt mailboxes connected directly on the workspace; Add account shows the cloud path and the adoptable list, and the Warmbly Cloud guide documents the model
2026-08-29 09:50:52 -07:00
2026-08-29 07:09:04 -07:00
2026-07-16 07:50:24 +02:00
2026-08-29 05:11:22 -07:00
2026-09-04 05:49:54 -07:00
2026-08-05 10:37:27 +02:00