This website requires JavaScript.
Explore
Help
Sign In
starred
/
warmbly
Watch
1
Star
0
Fork
0
mirror of
https://github.com/warmbly/warmbly.git
synced
2026-09-05 16:02:48 +00:00
Code
Issues
Packages
Projects
Releases
Wiki
Activity
Files
6da2c3dfaade7f8d0dc81ba87459f165a6cdcd97
warmbly
/
internal
T
History
Matthew Meszaros
6da2c3dfaa
feat: fix the three mailbox Settings bugs from
#247
: patch both cache shapes under ["emails", "list"] (paginated pages and the flat directory array) through one patchEmailLists helper so saving, removing, warmup lifecycle and tracking-domain writes no longer crash on undefined.map, stop rewriting the signature editor's contentEditable innerHTML on every keystroke so the caret stays where the user is typing, and scope the auth-check GET/POST handlers by organization instead of user id so the SPF/DKIM/DMARC check stops returning 404
2026-08-28 22:05:41 -07:00
..
api
feat: fix the three mailbox Settings bugs from
#247
: patch both cache shapes under ["emails", "list"] (paginated pages and the flat directory array) through one patchEmailLists helper so saving, removing, warmup lifecycle and tracking-domain writes no longer crash on undefined.map, stop rewriting the signature editor's contentEditable innerHTML on every keystroke so the caret stays where the user is typing, and scope the auth-check GET/POST handlers by organization instead of user id so the SPF/DKIM/DMARC check stops returning 404
2026-08-28 22:05:41 -07:00
app
feat: fix the three mailbox Settings bugs from
#247
: patch both cache shapes under ["emails", "list"] (paginated pages and the flat directory array) through one patchEmailLists helper so saving, removing, warmup lifecycle and tracking-domain writes no longer crash on undefined.map, stop rewriting the signature editor's contentEditable innerHTML on every keystroke so the caret stays where the user is typing, and scope the auth-check GET/POST handlers by organization instead of user id so the SPF/DKIM/DMARC check stops returning 404
2026-08-28 22:05:41 -07:00
bitmask
New Repository: Add Backend Code
2026-01-17 14:11:14 +00:00
client
feat: read spam complaints and domain-auth refusals, the last two open delivery signals (
#232
)
2026-08-28 11:02:45 -07:00
config
feat: build the browser half of social sign-in, which was never wired: GOOGLE_CLIENT_ID was read at boot and made the login screen render a Google button, but the button opened a popup at /auth/google/login which no route served, and authService.GoogleAuth/AppleAuth had no caller anywhere in the codebase; internal/app/socialauth now runs Google and Apple through the flow generic OIDC already used (one-time state, PKCE, nonce, id_token verified against the provider JWKS, identity keyed on issuer and subject, JIT provisioning, the ban and 2FA gates), the redirect URI defaults to API_PUBLIC_URL/v1/auth/<provider>/callback and is logged at boot because registering the dashboard origin instead is the mistake that produces a valid OAuth client and a dead button, /auth/config advertises only providers the backend can actually complete, the SSO landing page no longer swallows a two_fa_required response, and OIDC_PROVIDER_NAME finally reaches the button it documents
2026-08-28 01:33:08 -07:00
email
feat: make the inbound mail pipeline work end to end by never publishing the eventbus partition key as Nats-Msg-Id (JetStream deduped every event after the first per mailbox), fetching IMAP message bodies after the outer FETCH closes instead of nesting one inside it (which deadlocked sync on the first message), wrapping NEW_EMAIL in JobEventNewEmail across all three providers so the consumer stops nil-derefing, coalescing nil arrays before the NOT NULL unibox columns, sealing validation credentials on a copy so stored SMTP/IMAP passwords are not double encrypted, routing the email task type to the user email handler, and returning false instead of closing a nil conn in VerifySMTP (
#88
)
2026-07-31 09:41:36 +02:00
errx
feat: read spam complaints and domain-auth refusals, the last two open delivery signals (
#232
)
2026-08-28 11:02:45 -07:00
events
feat: never hand a send to a worker that is not heartbeating (registry row plus the Redis heartbeat key, which the worker now sets at boot instead of 90 seconds later), because a command queued for a dead worker is neither executed nor answered; reload a worker's mailboxes the moment its boot heartbeat arrives instead of waiting for the reconciler's republish window, make the publisher fail instead of silently succeeding when no bus or object storage is configured, and log a send that could not reach a worker to the campaign feed as a red, retrying entry
2026-08-23 10:18:50 -07:00
infrastructure
feat: give a cold mailbox a rotation lifecycle so a tired one can rest (
#237
)
2026-08-28 12:08:52 -07:00
jobs
feat: organization data export and import for moving a workspace between instances (
#132
)
2026-08-18 07:53:39 -07:00
models
feat: record the verdict that issued the login challenge instead of re-judging at confirm, and stop a mailbox in no warmup pool reading as healthy: the emailed code is confirmed by a second request that can carry a different address and sees history the first one did not, so re-assessing there could file a challenged sign-in as clean and drop it from the repeat count that reaches the workspace posture; the verdict now travels in the login session and every completion path takes it, while ListLifecycleCandidates returns a NULL health as unknown so leaving the pool is no longer evidence of recovery and a resting mailbox neither resumes nor accrues probation on it
2026-08-28 12:20:11 -07:00
notify
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
observability
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
pkg
feat: count only readable messages in the warmup batch failure suffix, so a blank provider error entry no longer renders "(+1 more)" and sends the operator hunting for a second reason that does not exist, and condense the new BatchState, batchFailureReason and failed-batch comments to the one-line form the repo convention asks for
2026-08-28 20:03:07 -07:00
repository
Merge remote-tracking branch 'origin/main' into feat/149-ato-signals
2026-08-28 12:26:55 -07:00
sandbox
feat: make a custom tracking domain verifiable instead of permanently "Pending DNS": the CNAME target is now this install's TRACKING_DOMAIN rather than a hardcoded t.warmbly.com that resolves nowhere, matching is exact on the label boundary (or on shared addresses, so a provider-flattened CNAME stops reading as no record at all) instead of strings.Contains, and every outcome carries the reason plus what DNS actually returned, including when the tracking host the customer is told to point at has no record of its own; a pasted URL is normalized to its host and a malformed one is rejected up front instead of saved and left pending forever; only a VERIFIED mailbox domain is used at send time with the shared host as the fallback and a campaign-feed entry saying why; pixels and click tickets are built from the configured host, and with none configured mail ships untracked rather than carrying links to another deployment's tracking service; adds GET /emails/:id/track and POST /emails/:id/track/verify plus an hourly re-resolution sweep so a record that propagates later starts being used and one that breaks stops routing links; and scopes the tracking-domain write by organization like the read, which also fixes GET /emails/:id passing a user id to an org-scoped query and 404ing for every caller
2026-08-24 09:02:29 -07:00
scheduler
feat: give a cold mailbox a rotation lifecycle so a tired one can rest (
#237
)
2026-08-28 12:08:52 -07:00
seed
feat: make a custom tracking domain verifiable instead of permanently "Pending DNS": the CNAME target is now this install's TRACKING_DOMAIN rather than a hardcoded t.warmbly.com that resolves nowhere, matching is exact on the label boundary (or on shared addresses, so a provider-flattened CNAME stops reading as no record at all) instead of strings.Contains, and every outcome carries the reason plus what DNS actually returned, including when the tracking host the customer is told to point at has no record of its own; a pasted URL is normalized to its host and a malformed one is rejected up front instead of saved and left pending forever; only a VERIFIED mailbox domain is used at send time with the shared host as the fallback and a campaign-feed entry saying why; pixels and click tickets are built from the configured host, and with none configured mail ships untracked rather than carrying links to another deployment's tracking service; adds GET /emails/:id/track and POST /emails/:id/track/verify plus an hourly re-resolution sweep so a record that propagates later starts being used and one that breaks stops routing links; and scopes the tracking-domain write by organization like the read, which also fixes GET /emails/:id passing a user id to an org-scoped query and 404ing for every caller
2026-08-24 09:02:29 -07:00
tasks
feat: give an organization one fused abuse posture (
#233
)
2026-08-28 11:20:19 -07:00
tasksched
feat: add an in-process postgres task scheduler so delayed sends need no cloud tasks
2026-07-20 09:56:02 +02:00
utils
feat: widen the contact custom-field key rule in internal/utils/json.go from ^[a-zA-Z0-9_]+$ to identifier segments joined by spaces or dashes, the exact set tasks.rewriteSpacedFieldRefs already resolves, so a spreadsheet column named "Company Mobile" is storable as well as addressable as {{.Company Mobile}}, and add NormalizeJSONKey plus an exported JSONKeyRules string so every caller trims and whitespace-collapses a key identically and reports the same rule back to the user
2026-08-27 03:42:47 -07:00