Matthew Meszaros
d8a3e70450
Merge pull request #609 from warmbly/fix/suppression-add-dialog
...
feat: suppression add dialog, row menu fix, and warmup suppression cleanup
2026-09-19 15:51:20 +00:00
Matthew Meszaros
530b184748
Merge pull request #607 from warmbly/feature/two-factor-setup-flow
...
feat: rebuild two-factor setup in Settings > Security as a three-step wizard with a QR code, manual setup key and TOTP parameters, inline code errors, and recovery codes with download, copy and print; show enable date and remaining recovery codes, add POST /auth/2fa/recovery-codes to regenerate them, return two_fa_invalid_code on a mismatched code, and update the security guide, API reference, error codes and OpenAPI
2026-09-19 15:48:03 +00:00
Matthew Meszaros
6b834b49f6
feat: cap the suppression add dialog's chip preview at 200 with a count of the rest, and refuse a paste over the server's 5000-entry limit before submitting instead of after
2026-09-19 08:46:24 -07:00
Matthew Meszaros
68ec5a016e
feat: delete the reauth attempt counter when a refund leaves it at zero or below so it always carries an expiry, and focus the first field of a 2FA dialog on open
2026-09-19 08:43:11 -07:00
Matthew Meszaros
e9d1a7e734
feat: reserve the per-account reauth attempt atomically before checking a password or 2FA code, keep the 2FA dialogs open while a request is in flight, move and trap focus in them, show a retry row when 2FA status fails to load, and drop Idempotency-Key from the recovery-code route with the reason documented
2026-09-19 08:36:59 -07:00
Matthew Meszaros
b8f47c94f4
Merge pull request #608 from warmbly/feat/unibox-message-details
...
feat: open a message details panel in the unibox from the recipient line, sender and an info icon, with every address, exact times, mailbox, folder, size and identifiers, and add email_id and folder to GET /unibox/:id
2026-09-19 15:31:23 +00:00
Matthew Meszaros
69ddac8c75
feat: replace the inline suppression add form with a modal dialog that previews each pasted address and domain as chips with counts and flags unrecognized values, fix the suppression row menu so Remove from list sits on one line with its icon and the added date no longer wraps, tint danger menu item icons red, and add migration 000186 removing suppression entries and deliverability events that only warmup sends produced
2026-09-19 08:23:10 -07:00
Matthew Meszaros
eceed10d89
feat: invoke the PostHog CLI as pnpm dlx @posthog/cli@<version> sourcemap ... in the web, admin and forms source map scripts, because pnpm dlx --package <pkg> <bin> is only understood by pnpm 10 and later and Cloudflare Pages builds the dashboards with an older pnpm that reads --package as the package name and fails the deploy on a registry 404
2026-09-19 17:23:10 +02:00
Matthew Meszaros
a1d3f3f3f1
feat: open a message details panel in the unibox from the recipient line, sender and an info icon, showing every From, Reply-To, To, Cc and Bcc address, sent and received times in the reader's zone, the mailbox, folder, size, Message-ID and In-Reply-To with one-click copy; summarise all recipients on the header line; add email_id and folder to GET /unibox/:id and document both
2026-09-19 08:22:14 -07:00
Matthew Meszaros
274ff888a5
feat: rebuild two-factor setup in Settings > Security as a three-step wizard with a QR code, manual setup key and TOTP parameters, inline code errors, and recovery codes with download, copy and print; show enable date and remaining recovery codes, add POST /auth/2fa/recovery-codes to regenerate them, return two_fa_invalid_code on a mismatched code, and update the security guide, API reference, error codes and OpenAPI
2026-09-19 08:15:31 -07:00
Matthew Meszaros
464ec521ca
feat: present the $15 pool plan as the Warmup plan everywhere: rename the plan row (migration 000185), add it to the dashboard catalog so the header and billing overview name it, show the cloud tier in a self-hosted instance's header pill and a Plan section under Settings > Warmbly Cloud with upgrade and manage links to the cloud billing page, nudge on the mailboxes page only when the free pool is full, drop the self-host framing from the cloud's checkout dialog, paths panel and locked screen, rebuild the checkout dialog in the plan chooser's style, pitch Premium on deliverability from one shared benefit list, and update the billing and Warmbly Cloud guides and the pricing FAQ
2026-09-19 05:57:41 -07:00
Matthew Meszaros
834da184d9
feat: clear every dependency advisory that has an upstream fix, dropping the AWS SDK's legacy-rustls-ring default feature that was pulling a second hyper 0.14, rustls 0.21 and rustls-webpki 0.101 into the tracking service alongside the current ones, moving async-nats to 0.50 for the last old webpki and reqwest to 0.12, boxing the NATS producer variant the bigger client made oversized, refreshing the node trees with overrides for the esbuild and postcss-selector-parser that fumadocs pins, recording why the two unpatched cowlib advisories cannot be reached from a service that sets no cookie, and deciding the credential-validation timeout from the subscription context's deadline rather than the error's shape
2026-09-19 13:25:33 +02:00
Matthew Meszaros
2c886a3202
feat: decide the credential-validation timeout from the subscription context rather than the error's shape so a Redis socket timeout inside a live deadline stays an internal error, and require a synthetic mechanism and an empty stack as well as a default object string before dropping an exception so a message that stringified an object alongside real text is still reported
2026-09-19 13:00:23 +02:00
Matthew Meszaros
acecd62c88
feat: scope mailbox disconnect and warmup lifecycle to the workspace rather than the member who connected the mailbox so an admin can act on every mailbox the list already shows them, evict a mailbox whose row is gone from every live worker when its provider errors arrive so a deleted mailbox stops calling the provider once a sync interval forever, subscribe before publishing the credential-validation job and classify a socket deadline as the retryable timeout it is, give the worker's validation reply its own budget so a slow mail host no longer loses a finished verdict, guard every global key handler against a keydown carrying no key, drop exceptions whose whole message is an object's default toString, make the Postgres pool size configurable, and record the CASA and security invariants in AGENTS.md
2026-09-19 12:49:46 +02:00
Matthew Meszaros
b09ec39907
Merge pull request #599 from warmbly/chore/casa-al1-security-assessment
...
feat: complete the ADA CASA AL1 control set and ship the assessment evidence pack
2026-09-19 06:39:12 +00:00
Matthew Meszaros
e668a2a36b
feat: complete the ADA CASA v2.1.1 AL1 control set across authentication, sessions, access control, cryptography, input validation and configuration, adding a breached-password denylist and per-account login throttling, enforced multi-factor authentication on the admin panel, step-up confirmation before an action that mints a lasting credential, purpose-scoped session tokens, single-use TOTP steps, tenant verification on every cross-referenced identifier, security headers on every surface, encrypted webhook signing secrets, per-organization idempotency, PKCE and a minimal two-scope Gmail consent on the mailbox OAuth flow, bounded spreadsheet and archive decoding, a patched Go toolchain with govulncheck in CI, and the evidence pack under compliance/casa
2026-09-19 08:18:35 +02:00
Matthew Meszaros
6428e6b3e9
Merge pull request #594 from warmbly/feature/disable-google-oauth-new-mailboxes
...
feat: route new Gmail mailboxes through a guided app-password connect instead of Google sign-in, behind BOX_GOOGLE_OAUTH_CONNECT, leaving existing OAuth mailboxes sending and re-authorizable
2026-09-19 06:11:15 +00:00
Matthew Meszaros
49acd51b64
feat: stop one recurring fault burying error tracking by reporting it once per five minutes with the count it stands for, keep a cache outage from answering every signed-in request with a 500 and from taking realtime down by treating an unreachable Redis as a miss and the websocket handshake nonce nothing reads as best-effort, answer a 5xx with a sentence the reader can act on while the call site's own words go to the log against the same request id, prefer the API's own message over the HTTP class in the admin and dashboard clients, and name the fix on a schema registry refusal, an SES sandbox rejection and a mailbox check that could not be run
2026-09-19 07:39:40 +02:00
Matthew Meszaros
e8f14bb2fd
feat: address the review on the Gmail app-password connect by reading BOX_GOOGLE_OAUTH_CONNECT through config.GoogleOAuthConnect in the instance-settings table so a yes/on value cannot display true against a gate that parses it as false, dropping the coming-soon line from the walkthrough banner on deployments where Google sign-in is actually available, naming the 2-Step Verification app-password control an administrator still has rather than the Less secure apps page Google removed, saying the OAuth client re-authorizes existing mailboxes as well as refreshing them, and marking the marketing send trace as the Google sign-in path
2026-09-18 22:18:56 -07:00
Matthew Meszaros
ee46cb49e8
feat: route new Gmail and Google Workspace mailboxes through a guided three-step app-password connect over smtp.gmail.com and imap.gmail.com instead of Google sign-in, behind BOX_GOOGLE_OAUTH_CONNECT (off by default) and announced to clients as gmail_oauth_connect on /auth/config, refusing a new gmail OAuth start with 403 mailbox_gmail_oauth_disabled in both the direct and Warmbly Cloud broker paths while leaving mailboxes already connected that way sending, syncing and re-authorizable
2026-09-18 22:06:09 -07:00
Matthew Meszaros
f99ee57484
feat: scope mailbox disconnect to the workspace instead of the connecting member, so a teammate with manage_emails no longer gets 404 on a mailbox the list shows them, delete by id in the repository on the strength of that check while the worker removal still names the owner the consumer's unibox cleanup is keyed on, and read the API's own reason off the normalised AppError in the accounts page so a refused disconnect says why instead of "The mailbox couldn't be disconnected" on every failure
2026-09-19 06:01:03 +02:00
Matthew Meszaros
81d46bdcc8
feat: attribute a campaign reply by the thread it answers rather than requiring the From address to equal the contact's, so a person replying from a Gmail send-as alias, a forward or a colleague's desk counts as replied for that lead, stamp replied_at whether or not reply-intent automation is switched on, suppress the mailed address too when an alias reply opts out, and count only a person's opens in every open count and open rate (campaign overview, per step, daily, hourly, dashboard, recent activity) with machine opens shown as a separate not-counted figure, matching how the Leads tab already reads opened
2026-09-18 14:29:16 +02:00
Matthew Meszaros
94482df9d1
Merge pull request #589 from warmbly/fix/campaign-progress-and-daily-budget-visibility
...
Fix campaign progress counts, the stuck Sending card, and explain a spent daily budget per mailbox
2026-09-18 12:08:03 +00:00
Matthew Meszaros
7e6cbd6b1f
feat: count the send in flight on the last-email-of-the-day feed line so a cap-one mailbox is shown at its cap with a budget gate rather than at zero, and put live campaign progress in emails (contacts times steps) with a total_emails field so a six-step campaign no longer reads 100% once every contact has had its first email
2026-09-18 13:54:12 +02:00
Matthew Meszaros
5b96ce903b
feat: count campaign progress from each table on its own so one sent email is no longer multiplied by leads times steps into 378 of 63 contacts at 100%, show the live Sending card only while a named contact's email is in flight and close it on EMAIL_SENT instead of leaving Sending Unknown contact up all day, and write the day's last send and every budget-spent line to the campaign feed with a per-mailbox breakdown of the cap, the clamp that set it, sends today, the gate and warmup health band so a campaign sending one email a morning says why
2026-09-18 13:12:07 +02:00
Matthew Meszaros
cd964aafa8
feat: stop a deleted mailbox living on inside its worker, by returning the worker assignments a scheduled org or user deletion destroys so the erasure path can evict them the way the single-mailbox delete already does, and by treating an assignment lookup that finds no row as the mailbox being gone rather than a failed lookup, which tells every live worker to drop it; and clear the rest of error tracking by retrying a mailbox delete that loses a deadlock to its own cascade instead of failing the person who clicked Disconnect, answering a daily-usage read for a mailbox that no longer exists with 404 rather than a reported 500, and guarding the inner data field on three list reads plus serialising an empty pool-link list as [] rather than null
2026-09-18 12:42:43 +02:00
Matthew Meszaros
0e914ee390
feat: stop the password reset flow reporting success while sending nothing, by answering 200 only for an address with no account rather than for every cache and database fault, folding addresses to one case on every account lookup and write so a typed capital cannot miss the row or split an SSO account in two, refunding the two-per-four-hours budget when the failure was ours, retrying one transient send and quoting the link's real lifetime; and clear the rest of error tracking by grouping the engagement breakdown in a subquery so ORDER BY stops resolving opens against email_opens, dropping unibox_mailboxes and email_sync_state writes whose mailbox was deleted mid-sync instead of redelivering them forever, answering a corrupt argon2 hash with ErrCredentials rather than a 500, never filing a cancelled caller as a database incident, and reporting only the first websocket init failure of a streak
2026-09-18 11:42:49 +02:00
Matthew Meszaros
e37c5053c2
feat: make warmup refunds atomic, count confirmed partner diversity in local and cloud mailbox views, and document cloud-safe mailbox deletion
2026-09-17 21:15:28 -07:00
Matthew Meszaros
177a0817c4
Merge remote-tracking branch 'origin/main' into fix/closiqode-reported-issues
2026-09-17 21:00:48 -07:00
Matthew Meszaros
d739f449e3
feat: make the unibox search persistence regression deterministic by keeping the opened subject inside the debounced result set
2026-09-17 21:00:48 -07:00
Matthew Meszaros
68c3676717
feat: keep warmup out of the customer's own mailbox and off their deliverability record: Gmail foldering now removes INBOX and SENT instead of only labelling, sent copies and reply-backs are filed in both directions, filing is configurable per mailbox (folder/inbox/archive via warmup_placement + warmup_folder, migration 000177), IMAP relocates a moved message by Message-ID so read/important stop no-opping, and a warmup send's bounce notice no longer lands in the unibox or suppresses a pool partner
2026-09-17 20:46:03 -07:00
Matthew Meszaros
d2095a8a70
feat: stop a greylisted RCPT reply from being filed as bounce evidence now that the send carries the server's own words, revoke a cloud enrollment after the worker removal and put the mailbox back when the revocation is refused so a failed delete really changes nothing, drop the unenroll-under-Settings advice that makes the same failing call, and only log a within-workspace pairing when there is a sibling to draw
2026-09-17 20:19:46 -07:00
Matthew Meszaros
8ee1c50a1b
feat: make a failed SMTP send name the step and the cause behind it instead of one bare SERVER_UNREACHABLE sentinel, give a refused warmup send its day back so sent_today can no longer climb past the target while the cap frees the slot, revoke a mailbox's Warmbly Cloud enrollment when it is deleted so the pool stops holding its password, and prefer warmup partners outside the sender's own workspace while showing the partner diversity a mailbox is actually getting ( #574 , #575 )
2026-09-17 20:02:37 -07:00
Matthew Meszaros
fdf7033c70
feat: correct the Gmail app-password instructions in the connect dialog and mailboxes guide, since Google removed the IMAP setting in January 2025 and app passwords are unavailable under Advanced Protection, security-key-only 2SV or an admin policy
2026-09-17 20:02:07 -07:00
Matthew Meszaros
1a73ff4bb3
feat: say in the Gmail connect warning and the mailboxes guide that an app in review is capacity capped, so a mailbox connected through Google sign-in may be disconnected later and need reconnecting
2026-09-17 19:51:23 -07:00
Matthew Meszaros
97e19bcb81
feat: mark Gmail OAuth as not recommended in the connect dialog with a red badge and an explanation dialog that routes to SMTP/IMAP with Gmail app-password steps, and document the same in the mailboxes guide
2026-09-17 19:51:23 -07:00
Matthew Meszaros
6f0314081c
feat: update vulnerable dependencies across Go Phoenix docs site and web
2026-09-17 07:04:40 -07:00
Matthew Meszaros
deeef293e4
feat: render automatic inbox label explanations with themed tooltips
2026-09-17 05:02:58 -07:00
Matthew Meszaros
b733d09f89
feat: make inbox follow-up labels safe for manual labels and automated mail
2026-09-17 04:57:52 -07:00
SUMAN JANA
3b8761d361
feat(inbox): explain every tag on hover, label live mail, and keep follow-ups working with no external service
2026-09-17 04:57:52 -07:00
Matthew Meszaros
dcf26a2361
feat: make automatic inbox tagging atomic live and reviewable in production
2026-09-17 04:57:24 -07:00
SUMAN JANA
260898bf20
feat(inbox): automatic tagging and relevance scoring for inbound mail, optional and off by default
2026-09-17 04:57:24 -07:00
Matthew Meszaros
ae1a324801
Merge pull request #562 from rocker1166/feat/direct-mail-analytics
...
feat: add accurate direct-mail analytics and opt-in engagement tracking
2026-09-17 11:47:50 +00:00
Matthew Meszaros
93a0e39371
Merge pull request #568 from warmbly/fix/reported-issue-resolution
...
feat: preserve binary dashboard API responses so campaign lead exports remain downloadable
2026-09-17 11:28:29 +00:00
Matthew Meszaros
8745dd988d
feat: correct direct-mail analytics attribution and publish live engagement updates
2026-09-17 04:27:00 -07:00
Matthew Meszaros
7402898c0d
feat: preserve binary dashboard API responses so campaign lead exports remain downloadable ( #565 )
2026-09-17 04:24:52 -07:00
Matthew Meszaros
cc5925fe44
feat: preserve web-search operators and escape participant patterns in unibox search
2026-09-17 04:18:08 -07:00
SUMAN JANA
2134c7a143
feat(analytics): report on mail written by hand, with opt-in open and click tracking per mailbox
2026-09-17 10:26:25 +00:00
SUMAN JANA
ebbe432d2c
feat(unibox): search people and partial words, and offer to widen a search that found nothing in the current scope
2026-09-17 10:20:17 +00:00
Matthew Meszaros
0f5ca71155
feat: correct mailbox sending metrics and workspace analytics across dashboard surfaces
2026-09-16 21:44:42 -07:00