Matthew Meszaros
|
d4ead05456
|
feat: persist campaign sequence canvas coordinates with x/y columns (migration 000053) plus a bulk sequence-layout service/repo path that scopes by campaign owner and never bumps updated_at
|
2026-06-30 10:06:20 +02:00 |
|
Matthew Meszaros
|
73838cecf5
|
feat: add an unaudited automation node-layout endpoint handler/service/repo backed by an atomic jsonb x/y merge that leaves edges, config, and updated_at untouched
|
2026-06-30 10:06:19 +02:00 |
|
Matthew Meszaros
|
9dd37b0d62
|
Merge pull request #52 from warmbly/referral-credits
feat: implement referral program with credit-based rewards
|
2026-06-28 09:12:57 +02:00 |
|
Matthew Meszaros
|
22b75c9165
|
feat: implement ListByOrganization on the discount service test's fake redemption repo so the package typechecks under golangci-lint in CI
|
2026-06-28 06:35:42 +00:00 |
|
Matthew Meszaros
|
0d22e546a9
|
feat: update the discount service test's fake redemption repo to the new offset-based ListByCode signature
|
2026-06-28 05:58:25 +00:00 |
|
Matthew Meszaros
|
22bce66503
|
feat: thread an offset instead of a UUID cursor through the discount service ListRedemptions to match the offset-paged repository
|
2026-06-28 05:58:25 +00:00 |
|
Matthew Meszaros
|
233dee8766
|
feat: move danger-zone deletion emails onto the shared templates package and delete the off-brand standalone emails.go wrapper
|
2026-06-28 05:27:28 +00:00 |
|
Matthew Meszaros
|
57adf4f9b2
|
feat: route notification.deliverEmail through GenerateNotificationHTML and drop the hand-rolled htmlEscape/inline-fragment email body
|
2026-06-28 05:27:28 +00:00 |
|
Matthew Meszaros
|
b1f26e24f9
|
feat: list an organization's promo redemption history through the discount service and repository for the billing page
|
2026-06-28 05:09:50 +00:00 |
|
Matthew Meszaros
|
a21f4d0d0e
|
feat: capture the signup referral code through the auth registration flow and the WireReferral attributor hook
|
2026-06-28 05:09:50 +00:00 |
|
Matthew Meszaros
|
234e624fdc
|
feat: add the Stripe customer-balance applier and wire referral reward, qualify, and clawback hooks into the Stripe webhook handlers
|
2026-06-28 05:09:50 +00:00 |
|
Matthew Meszaros
|
8b05f381f7
|
feat: add the referral service covering code minting, signup attribution, the reward and clawback lifecycle, and Stripe customer-balance sync in internal/app/referral
|
2026-06-28 05:09:50 +00:00 |
|
Matthew Meszaros
|
2c910dcdeb
|
feat: make a campaign step's Original a first-class weighted A/B arm driven by a single draggable traffic-split bar, persisting the control share as an is_control variant row
|
2026-06-15 08:11:53 +02:00 |
|
Matthew Meszaros
|
03acdb87e3
|
fix: thread organization_id through contact, CRM, and unibox reads and writes so non-owner org members see and edit their workspace data, and backfill contacts.organization_id for single-membership users (migration 000049)
|
2026-06-15 08:11:53 +02:00 |
|
Matthew Meszaros
|
c5dfa5e4e7
|
feat: remove the HTTP-request action from campaign steps and automations in favor of signed webhooks, keep fire_event for custom payloads, and drop the now-unused outbound quota plumbing
|
2026-06-15 08:11:35 +02:00 |
|
Matthew Meszaros
|
9d0c432be7
|
feat: let OAuth apps subscribe to webhooks by declaring a url/events/secret and materializing per-org endpoints gated by each grant's scopes, with secret rotation and delivery observability (migration 000050)
|
2026-06-15 08:11:20 +02:00 |
|
Matthew Meszaros
|
173736a004
|
feat: add a Stripe-grade webhook platform with a typed event catalog, HMAC-signed delivery, retries with backoff, endpoint ownership verification, per-endpoint throttling, an audit-spine event bridge, and firehose emit sites (migration 000048)
|
2026-06-15 08:11:20 +02:00 |
|
Matthew Meszaros
|
fcafac4195
|
refactor: remove the campaign 'notify (webhook)' step type now that the HTTP request step covers outbound calls and there is no webhook setup surface
|
2026-06-14 10:48:06 +02:00 |
|
Matthew Meszaros
|
ab24d8bbc8
|
feat: add a 'Fire event' action and campaign step that publish custom events to the realtime gateway (no public URL), an HTTP-request campaign step, a configurable automation dry-run test with per-step toggles, and fix the false 'updated by a teammate' toast on your own save
|
2026-06-14 09:52:49 +02:00 |
|
Matthew Meszaros
|
fcdb31cda7
|
feat: OAuth apps always issue a client secret (drop the public/PKCE-only client type, secret required for the token exchange), add an app-logo upload endpoint, and align the docs to OAuth2 with optional PKCE
|
2026-06-14 09:52:49 +02:00 |
|
Matthew Meszaros
|
8c175d4221
|
feat: add an OAuth 2.1 authorization server (migration 000047 apps/codes/grants, app registration CRUD, authorization-code-with-PKCE authorize+token+refresh-rotation+revoke endpoints, RFC 8414 discovery, bearer-token validation wired into the auth middleware reusing the API-permission gates, scopes mapped to API permission bits)
|
2026-06-13 13:56:39 +02:00 |
|
Matthew Meszaros
|
20935ef061
|
feat: add a nil-safe per-org daily outbound-action quota (Redis daily counter, anti-abuse ceiling on the HTTP-request automation node, wired in both backend and consumer, fail-open) to bound webhook relay abuse
|
2026-06-13 13:41:20 +02:00 |
|
Matthew Meszaros
|
1fa9c65ada
|
fix: harden every user-supplied-URL outbound path against SSRF with a shared dial-time guard (resolves the host, blocks private/loopback/link-local/metadata IPs, pins the validated IP to defeat DNS rebinding, re-validates redirects) and log automation HTTP requests + blocked attempts with org attribution
|
2026-06-13 13:34:19 +02:00 |
|
Matthew Meszaros
|
501b5009b4
|
feat: add an on-error branch to automation action nodes (try/catch routing, rose on-error handle, executor follows the error edge and treats the failure as handled instead of failing the run)
|
2026-06-13 13:15:41 +02:00 |
|
Matthew Meszaros
|
9aa3300f46
|
feat: capture per-action output in automation run history (HTTP status/ok, set-variables values, rendered channel/url/message) and render it under each action in the builder History panel
|
2026-06-13 13:11:58 +02:00 |
|
Matthew Meszaros
|
331745ecc5
|
feat: add a generic per-automation inbound webhook trigger (inbound.webhook event, token-gated POST /api/v1/integrations/inbound/automation/:token, migration 000046 inbound_token, background graph run with the JSON body as event payload)
|
2026-06-13 13:04:10 +02:00 |
|
Matthew Meszaros
|
f1cf470121
|
feat: render Discord notifications as sky-themed rich embeds and Slack notifications as sky-accented attachment cards with contact and subject fields instead of plain text lines
|
2026-06-13 12:41:26 +02:00 |
|
Matthew Meszaros
|
534928cfdd
|
feat: add a safe Set-variables (transform) automation node — computes named values from Go templates against the event + prior step output and writes them back for later steps to reuse, running the same sandboxed text/template engine as every other action value (no I/O, no arbitrary code execution)
|
2026-06-13 12:18:45 +02:00 |
|
Matthew Meszaros
|
f4a2b87c50
|
feat: add a configurable warmbly.http_request automation action (the generic send-a-webhook/call-any-API node) — templated method/url/headers/query/body, SSRF-guarded + bounded retry, captures the response back into the event data under an output key so downstream nodes use {{.response.body...}} and conditions branch on {{.response.ok}}
|
2026-06-13 12:02:11 +02:00 |
|
Matthew Meszaros
|
57e8705a82
|
feat: make public API list cursors opaque base64 tokens (internal/utils/paging) instead of raw record UUIDs, decoding on input with a 400 on a bad cursor; admin endpoints keep transparent UUID cursors
|
2026-06-13 07:18:23 +02:00 |
|
Matthew Meszaros
|
c5911fe37a
|
feat: fire run_automation on campaign instant branches (reply/open/click) through a wired AutomationRunner instead of stamping the action node sent without ever running the flow
|
2026-06-13 06:26:48 +02:00 |
|
Matthew Meszaros
|
ba89a932cd
|
feat: run the label_email action on reply — campaign instant and scheduled paths via advanced LabelThread/LabelLatestThreadForContact, automations via execNativeAction reading thread_id and _user_id from the reply payload — and move the native-actions adapter to a shared package wired into the consumer too so reply/bounce/warmup automation actions stop silently failing
|
2026-06-12 16:44:16 +02:00 |
|
Matthew Meszaros
|
8de7e32857
|
feat: treat a campaign step's own email as the A/B control arm so contacts split across the original plus active variants by weight, and redesign the step variants editor to show the original and variants as one weighted set with live split percentages
|
2026-06-12 08:04:03 +02:00 |
|
Matthew Meszaros
|
0fd3d03f55
|
feat: add org-wide team presence privacy columns (presence_show_online, presence_show_activity) with update plumbing and a PRESENCE_POLICY_UPDATED realtime event so a settings change re-gates connected sockets live
|
2026-06-12 05:59:01 +02:00 |
|
Matthew Meszaros
|
8547fe97eb
|
feat: scope unibox MarkSeenBulk by organization so a non-owner member opening a thread clears the shared org-wide unread state instead of updating zero rows
|
2026-06-12 05:14:50 +02:00 |
|
Matthew Meszaros
|
4db027a342
|
feat: scope unibox GetByThread by organization instead of user_id so non-owner members see the full conversation they already see in the org-scoped inbox list, not an empty thread
|
2026-06-12 05:10:00 +02:00 |
|
Matthew Meszaros
|
6a3b8ac0eb
|
fix: scope the unibox unread-count endpoint by organization_id so the sidebar Inbox badge counts the workspace's unread mail instead of always showing 0 for non-owner members
|
2026-06-11 18:05:18 +02:00 |
|
Matthew Meszaros
|
594c696bf6
|
fix: scope the unibox inbox list and overview by organization_id (via the workspace's email accounts) instead of the logged-in user_id, so every member sees the org's incoming mail; per-user thread labels and snoozes stay personal
|
2026-06-11 17:57:52 +02:00 |
|
Matthew Meszaros
|
21032a8fce
|
fix: scope the contacts list by organization_id instead of user_id so all members see the workspace's contacts (and per-contact campaign badges); categories badge still user-scoped pending an organization_id column on categories
|
2026-06-11 17:52:36 +02:00 |
|
Matthew Meszaros
|
88e241d536
|
fix: scope the analytics dashboard (overall stats, recent activity, top campaigns, daily trend, account health) by organization_id instead of user_id, so every workspace member sees the org's analytics rather than an empty dashboard
|
2026-06-11 17:49:39 +02:00 |
|
Matthew Meszaros
|
a21dc57e07
|
fix: scope campaign list/detail/count queries by organization_id instead of user_id, so all workspace members see the org's campaigns rather than only the creator
|
2026-06-11 17:47:04 +02:00 |
|
Matthew Meszaros
|
6ae5e52c4e
|
fix: scope email-account list/detail queries by organization_id instead of the logged-in user_id, so every member of a workspace sees the org's mailboxes (not just the owner who connected them)
|
2026-06-11 17:43:56 +02:00 |
|
Matthew Meszaros
|
709b77cdc6
|
fix: notification email links use the configured APP_URL instead of a hardcoded app.warmbly.com, so dev and self-hosted deployments link to the right host
|
2026-06-11 12:43:17 +02:00 |
|
Matthew Meszaros
|
3c6de16321
|
fix: forgotten-password reset now revokes all existing sessions, so a reset done because access was lost or compromised fully cuts off prior devices
|
2026-06-11 12:41:55 +02:00 |
|
Matthew Meszaros
|
f209eca9ad
|
fix: Slack notification delivery now resolves a real channel (connection config, then the org's configured Slack automation channel) instead of an always-empty connect-time field that silently dropped every message; docs and UI corrected to match
|
2026-06-11 12:40:31 +02:00 |
|
Matthew Meszaros
|
3c040649c0
|
fix: changing your password now revokes every other session (keeping the current device), matching the security promise in the sign-in alert and docs
|
2026-06-11 12:39:24 +02:00 |
|
Matthew Meszaros
|
5bcc2baaa8
|
feat: implement the coming-soon security features — logged-in change-password (verify current, policy-checked, POST /me/password) with a real dialog, and new-device sign-in alerts (security notification category fired from the token service on an unrecognized OS+browser, delivered in-app and by email), removing the comingSoon stub helper and updating docs
|
2026-06-11 12:30:44 +02:00 |
|
Matthew Meszaros
|
160dc0bc76
|
feat: implement the coming-soon notification delivery channels — Email (SES/SMTP to the account email) and Slack (posts to the org's connected workspace via a new integration NotifySlack), wired in both backend and consumer with per-channel gating, real toggles replacing the coming-soon labels, and updated docs
|
2026-06-11 12:21:48 +02:00 |
|
Matthew Meszaros
|
39a9752d63
|
feat: real tokenized invite-accept link — public /invite landing page with safe preview (org, inviter, roles), accept-by-token plus the previously-broken accept-by-invitation-id, public preview + admin copy-link endpoints, login next-param redirect, and a Copy button that yields a working /invite?token link
|
2026-06-11 11:57:45 +02:00 |
|
Matthew Meszaros
|
19f66507b4
|
feat: fix multi-role review findings — atomic member+roles insert on invite accept (no partial-failure stranding), gate role deletion on the actor holding the role's permissions (blocks team-managers de-privileging admins), and hydrate+chip pending-invitation role sets
|
2026-06-11 11:32:57 +02:00 |
|