Matthew Meszaros
|
3bf8d4bdfa
|
Merge remote-tracking branch 'origin/main' into feature/mailbox-fair-use-allowance
|
2026-09-04 21:25:53 -07:00 |
|
Matthew Meszaros
|
aac8fd3f6b
|
Merge pull request #329 from warmbly/feature/warmbly-cli
A warmbly CLI: sign in from your terminal and drive the product, installable in one command
|
2026-09-04 21:20:23 -07:00 |
|
Matthew Meszaros
|
70baaac636
|
feat: describe a paid plan's mailbox capacity in the free-workspace panel of the allowance dialog as one mailbox for every daily send it includes rather than promising unlimited, and name the upgrade feature More mailboxes to match
|
2026-09-04 21:17:58 -07:00 |
|
Matthew Meszaros
|
c7da25d126
|
fix: never leave a per-IP rate-limit counter without a TTL, which would block that address forever once it passed the limit, by dropping the key and failing open when EXPIRE fails and repairing a missing expiry on the reject path, and assert the exit status as well as the message when the CLI installer rejects a flag
|
2026-09-04 21:12:27 -07:00 |
|
Matthew Meszaros
|
bf46839fb7
|
feat: address the CodeRabbit review on the mailbox allowance work by reserving the mailbox slot inside the account insert transaction under a per-organization lock so concurrent connects cannot both take the last one, resolving the storage limit under the quota lock so a plan change cannot be raced past, deleting refused attachment objects on a context that outlives the request, settling already-connected rows before the bulk batch spends allowance, leaving password columns out of the failed-rows CSV, stopping click propagation from the portalled allowance dialog, and counting bulk progress once
|
2026-09-04 21:11:25 -07:00 |
|
Matthew Meszaros
|
b35e111705
|
fix: address the review on the CLI PR: give the sign-in handshake its own per-IP budget so a 200-poll login cannot lock the address out of the browser login, keep https for a remote host that names a port instead of sending a bearer token in cleartext, report truncation when a paginated walk stops at max-pages, accept a piped secret with no trailing newline, normalise WEBSOCKET_URL on its suffix so a bare /socket becomes a real endpoint, destroy a minted secret the moment its code expires, gate cli-installer-ci on the required status check, print a rejected flag instead of an unbound-variable error, and use a portable sha256 so the packaging runs on macOS
|
2026-09-04 21:03:58 -07:00 |
|
Matthew Meszaros
|
3596a9770f
|
feat: make mailboxes truly unlimited under a fair-use allowance of one mailbox per daily send the plan includes (15,000 on Business), drop the 200 hard cap and the 5-per-day connect throttle, open a request-more dialog with inline limit requests and plan upgrade when the allowance is reached, add bulk CSV mailbox import with live progress and a downloadable failed-rows file, reserve attachment storage atomically under a per-org lock so concurrent uploads cannot pass the quota (#326), report storage and the allowance on the billing usage meters, and honor approved daily-send overrides in the sender
|
2026-09-04 21:00:26 -07:00 |
|
Matthew Meszaros
|
d80816efa1
|
feat: make a successful warmbly auth login always the active host instead of deciding it from three overlapping conditions, and say why the CLI state file tolerates an unwritable home
|
2026-09-04 20:16:56 -07:00 |
|
Matthew Meszaros
|
f68918d7f6
|
Merge remote-tracking branch 'origin/main' into feature/warmbly-cli
|
2026-09-04 20:14:46 -07:00 |
|
Matthew Meszaros
|
23f88293c8
|
feat: document the warmbly CLI at docs.warmbly.com/api/cli with every install channel, the device flow in api/authentication, the new auth/cli and api-keys/self routes in the endpoint scope map, a warmbly-cli agent skill, and a note on warmblyctl saying which of the two CLIs a reader wants
|
2026-09-04 20:14:43 -07:00 |
|
Matthew Meszaros
|
4e94d2b47b
|
feat: install the CLI in one command from warmbly.com/cli.sh or cli.ps1, with checksum-verified archives, a Homebrew formula and Scoop manifest generated alongside them, a ghcr cli image, and a make cli-check that installs from a local mirror and proves a tampered checksum stops the install
|
2026-09-04 20:14:38 -07:00 |
|
Matthew Meszaros
|
f46fc86a7c
|
feat: add the warmbly CLI at cmd/cli, a signed-in multi-host client of the public REST API with 30 command families over one spec table, gh-shaped api passthrough, live event tailing, tables on a terminal and JSON in a pipe, and a confirmation gate in front of everything that puts real mail on the wire
|
2026-09-04 20:14:33 -07:00 |
|
Matthew Meszaros
|
028689fd2e
|
feat: device-code sign-in for the CLI, with a browser approval page at /cli that mints a scoped API key, self-revocation at DELETE /api-keys/self so a read-only credential can always end itself, and app_url plus websocket_url on /auth/config so a client can find the dashboard and the realtime gateway on a self-hosted layout
|
2026-09-04 20:14:27 -07:00 |
|
Matthew Meszaros
|
a9f68656dc
|
Merge pull request #321 from warmbly/feature/plan-upgrade-paywall-modal
Full-screen upgrade dialog with plan cards, interval toggle and one-click checkout for plan-locked features
|
2026-09-04 09:27:44 -07:00 |
|
Matthew Meszaros
|
aba176f8aa
|
fix: never highlight a plan at or below the workspace's current one, so an Enterprise customer is no longer shown Business as the best value, and stop the agencies page promising each client its own machine and IP now that the FAQ states we do not sell or manage IPs as a product
|
2026-09-04 09:20:33 -07:00 |
|
Matthew Meszaros
|
5fd9aedb80
|
Merge remote-tracking branch 'origin/main' into feature/plan-upgrade-paywall-modal
|
2026-09-04 09:11:51 -07:00 |
|
Matthew Meszaros
|
32d2bdfb81
|
Merge pull request #324 from warmbly/feature/install-script-setup-wizard
feat: one-command self-host installer with an interactive data-control wizard
|
2026-09-04 07:12:38 -07:00 |
|
Matthew Meszaros
|
e5360713e7
|
Merge remote-tracking branch 'origin/main' into feature/install-script-setup-wizard
|
2026-09-04 06:43:12 -07:00 |
|
Matthew Meszaros
|
a7d2381120
|
Merge pull request #327 from warmbly/feat/step-composer-campaign-wide-attachments
Show the campaign's every-step attachments in the step composer
|
2026-09-04 06:42:48 -07:00 |
|
Matthew Meszaros
|
5c4f87c1aa
|
feat: list the campaign's unscoped attachments under a Sent with every step group in the step composer, so files the step really carries stop being invisible in the panel that claims to show them, and say in the confirm that removing one takes it off every step
|
2026-09-04 06:40:48 -07:00 |
|
Matthew Meszaros
|
6869676001
|
Merge pull request #323 from Skylinerffm97/fix/step-attachments-mount
Mount StepAttachments in the step composer (#307 item 3)
|
2026-09-04 06:39:51 -07:00 |
|
Matthew Meszaros
|
b0db8cc02b
|
feat: chain the backup bundle cleanup behind a successful docker compose cp so a failed copy cannot delete the only backup, and tell a pinned image install to set WARMBLY_TAG before pulling by hand
|
2026-09-04 06:35:04 -07:00 |
|
Matthew Meszaros
|
af9e852314
|
Merge branch 'main' into fix/step-attachments-mount
|
2026-09-04 06:34:53 -07:00 |
|
Matthew Meszaros
|
3156758c9f
|
Merge pull request #325 from warmbly/fix/step-scoped-attachments
Send only the attachments a step actually carries, and org-scope the attachment routes
|
2026-09-04 06:34:45 -07:00 |
|
Matthew Meszaros
|
d78e4423e4
|
fix: address the review of the notifications work — bound detached alert delivery to a fixed pool that drops and logs rather than spawning a goroutine per event, never echo a transport error that embeds the webhook URL, treat an emptied channel target as cleared so switching transport cannot post Slack payloads to a Discord URL, emit user.registered for invited signups and the worker alert after a successful reassignment, format Stripe amounts by currency exponent, refuse an upgrade while the plan list is still loading instead of silently opening the portal, apply a fixed discount to the annual invoice rather than to each month, convert proration from minor units, contain focus in the nested enterprise dialog, hide the odometer wheels from assistive tech, and drop the last dedicated-IP row from the pricing matrix
|
2026-09-04 06:33:20 -07:00 |
|
Matthew Meszaros
|
9a2184fda7
|
Merge remote-tracking branch 'origin/main' into fix/step-scoped-attachments
|
2026-09-04 06:28:26 -07:00 |
|
Matthew Meszaros
|
04689a8bfc
|
feat: mark step_id required on the CampaignAttachment schema, since the attachment response always carries the key and serialises a campaign-wide file's as null, so a generated client that treats it as optional loses the difference between an unscoped file and one it forgot to read
|
2026-09-04 06:28:26 -07:00 |
|
Matthew Meszaros
|
77058a2cb4
|
feat: address the review on the installer branch by keeping the database password out of pg_dump's argv, excluding backup bundles from the blob root they are written into, tolerating blobs that change or vanish mid-archive, making the instance-settings bootstrap a single atomic insert, and validating the release tag before it is written into .env
|
2026-09-04 06:24:05 -07:00 |
|
Matthew Meszaros
|
2a820ed9f9
|
Merge pull request #322 from Skylinerffm97/fix/create-schedule-windows
Persist schedule_windows on POST /campaigns (#307 item 5)
|
2026-09-04 06:23:17 -07:00 |
|
Matthew Meszaros
|
fb868dfe40
|
feat: delete the storage objects of a step's attachments when the step is deleted, since the attachment rows cascade away with the sequence and left their bytes counted against the organization's storage quota with no row left to reach them
|
2026-09-04 06:20:26 -07:00 |
|
Matthew Meszaros
|
a54774c0a5
|
feat: install the attachment upload's body cap before the first form field is read, since reading step_id parses the whole multipart body and left the MaxBytesReader that followed it with nothing to limit
|
2026-09-04 06:19:29 -07:00 |
|
Matthew Meszaros
|
85f3dad215
|
feat: send the files a step actually carries by honouring campaign_attachments.sequence_id in the send, test-send and preview paths instead of attaching every campaign file to every step, count them per step in the preflight content score, and refuse an upload naming another campaign's step
|
2026-09-04 06:16:16 -07:00 |
|
Matthew Meszaros
|
05e19ffb69
|
feat: scope the campaign attachment routes to the caller's organization, so listing, uploading to or deleting from a campaign id belonging to another workspace is a 404 instead of leaking presigned download URLs, adding a file that workspace then sends, or deleting their stored objects
|
2026-09-04 06:16:16 -07:00 |
|
Matthew Meszaros
|
81d6ba4520
|
Merge remote-tracking branch 'origin/main' into feature/plan-upgrade-paywall-modal
|
2026-09-04 06:09:14 -07:00 |
|
Matthew Meszaros
|
c089cdfa75
|
fix: address review findings on the upgrade surfaces — resolve a catalog plan to the server plan by exact name before falling back to an unambiguous prefix so an operator-added 'Starter Legacy' cannot capture Starter's checkout, stop a plan that does not unlock the requested feature from offering to buy it, honour the dialog's aria-modal by moving and containing focus and restoring it on close, and pin the odometer digit geometry against flex shrink
|
2026-09-04 06:09:09 -07:00 |
|
Matthew Meszaros
|
7314e85dfe
|
Merge branch 'main' into fix/create-schedule-windows
|
2026-09-04 06:08:05 -07:00 |
|
Matthew Meszaros
|
a0c9d5a5b0
|
feat: add operator notification channels an admin configures in the panel (Discord, Slack, HMAC-signed webhook, or email) with per-channel event subscriptions, a synchronous test probe, SSRF-guarded URLs and credentials redacted on read, wire nine instance events including the enterprise inquiry that previously wrote a row nobody was told about, and reword the plan-specific limits copy so it reads correctly without billing
|
2026-09-04 06:02:40 -07:00 |
|
Matthew Meszaros
|
42c3000383
|
feat: verify the backup bundle's recorded dump digest before warmblyctl restore empties the target schema, so a truncated bundle is refused instead of leaving the instance with neither its own data nor the bundle's
|
2026-09-04 05:56:12 -07:00 |
|
Matthew Meszaros
|
f042e307e5
|
feat: rewrite the installer's three A && B || C constructs as guard clauses so shellcheck's SC2015 is satisfied on the CI runner's version, and print the shellcheck version in check-installer.sh
|
2026-09-04 05:53:16 -07:00 |
|
Matthew Meszaros
|
d68bbcd2ab
|
feat: add a one-command self-host installer at warmbly.com/install.sh with an interactive data-control wizard, give docker-compose.yml image keys and per-store volume variables, add an image-mode updater, move engagement/form/audit retention into instance settings, and add warmblyctl backup/restore
|
2026-09-04 05:49:54 -07:00 |
|
Matthew Meszaros
|
7d8bb08fa0
|
fix: Talk to sales now opens an enterprise inquiry form instead of a Stripe portal session a free-tier prospect has no customer for, and correct two clients that could never succeed: the portal sent no body against a required return_url and read a url key the endpoint never returns, and the enterprise inquiry sent name/email/company/message against a handler binding company_name/contact_name/contact_email
|
2026-09-04 05:20:31 -07:00 |
|
Matthew Meszaros
|
b3e5394bb5
|
feat: drop the plan card hover lift and the large hover drop-shadow, leaving the same border-darkens-on-hover the rest of the settings controls use
|
2026-09-04 05:16:02 -07:00 |
|
Matthew Meszaros
|
87ada2c99f
|
feat: drop the purple gradient and indigo plan accents for the app's own slate and sky palette (Business wears sky, Enterprise solid ink, no gradients anywhere), highlight the best-value plan instead of whatever sits one rung up, remove the duplicated capability matrix from Overview and the comparison table from Plans, and stop calling dedicated workers 'dedicated IPs' across the dashboard, docs, pricing page, FAQ and agencies page
|
2026-09-04 05:11:47 -07:00 |
|
Matthew Meszaros
|
01dd6e3450
|
feat: rebuild Billing > Plans on the same large plan cards the upgrade dialog uses (extracted to a shared component with rolling prices, interval sheen and a highlighted next-step-up plan), add a side-by-side comparison table of every limit and capability sourced from the server plan records with the current plan column highlighted, and show the proration preview per card
|
2026-09-04 05:03:28 -07:00 |
|
Matthew Meszaros
|
19f8dfbc20
|
feat: rebuild Billing > Overview as a real control panel with cancel and resume, live usage meters against server-enforced limits, a capability matrix, trial and past-due and pending-cancellation banners; price plan switches with a proration preview on the Plans tab; fix the cancel client that sent no body and always 400'd; stop the Payment tab claiming no card is on file
|
2026-09-04 04:48:59 -07:00 |
|
Matthew Meszaros
|
3cca2390be
|
feat: replace the upgrade dialog's count-up prices with a per-digit odometer that rolls each wheel to its new digit, and choreograph the plan section on an interval flip with a staggered sheen sweep across each card, a scale pulse on the price, sliding billing-note and section-description crossfades, and an annual savings pill
|
2026-09-04 04:36:03 -07:00 |
|
Matthew Meszaros
|
2f3693f5b2
|
Merge pull request #320 from warmbly/fix/issue-316-stale-list-when-socket-down
Stop the dashboard showing stale campaign counts and a permanent "Slow connection" (#316, #319)
|
2026-09-04 04:11:06 -07:00 |
|
Matthew Meszaros
|
7fe7b7c8e9
|
feat: scope the collaboration guide's offline claim to the data that is actually refetched, since live events are never replayed and presence and cursors resume from current state rather than backfilling what was missed
|
2026-09-04 04:07:44 -07:00 |
|
Matthew Meszaros
|
1533b83c16
|
feat: open a full-screen upgrade dialog from every plan lock (sidebar rows, the unified inbox frosted overlay, the free-workspace screen) with the four plan cards, a monthly/annual toggle with animated prices, the unlocking plan highlighted, promo codes and one-click Stripe checkout or in-place plan change through a shared useUpgradeFlow hook that the billing page now uses too, return the Stripe redirect to the originating page and settle it in place, and add a plans and billing guide
|
2026-09-04 04:03:44 -07:00 |
|
Matthew Meszaros
|
ebc6de1f81
|
feat: refetch the campaigns list on a slow cycle while the realtime socket is not connected, so send counts kept current by live invalidation cannot sit on their five-minute cache with no event coming to refresh them, and document what the header's connection dot means and what still refreshes while it is down
|
2026-09-04 04:03:01 -07:00 |
|