-
Notifications
You must be signed in to change notification settings - Fork 224
Comparing changes
Open a pull request
base repository: postalsys/emailengine
base: v2.69.0
head repository: postalsys/emailengine
compare: v2.70.0
- 15 commits
- 80 files changed
- 2 contributors
Commits on Jun 10, 2026
-
fix: do not crash at startup when a feature flag env variable is set …
…to a falsy value EENGINE_FEATURE_* variables with values like "false" or "0" called the nonexistent Set.remove() and threw a TypeError while loading the module. Use Set.delete() and anchor the truthy value pattern so that values like "latest" no longer enable a flag by accident.
Configuration menu - View commit details
-
Copy full SHA for 98ad979 - Browse repository at this point
Copy the full SHA 98ad979View commit details -
fix: report correct nextAttempt time for queued messages
The outbox API doubled the actual BullMQ retry delay by using 2^attemptsMade instead of 2^(attemptsMade-1) for jobs whose attempt counter already includes the failed attempt. The submit worker had the correct multiplier but advertised a retry time on the final attempt and serialized exhausted retries as the 1970 epoch. Also removed a dead exhaustion re-check in handleSubmitError that referenced a nonexistent jobData.opts field and prevented the feedbackKey failure update.
Configuration menu - View commit details
-
Copy full SHA for d5ebdfb - Browse repository at this point
Copy the full SHA d5ebdfbView commit details -
fix: assign unassigned accounts after license activation
Accounts added while no license was active stayed in the initializing state forever because account assignment was only triggered by the worker crash recovery path, not when suspended IMAP workers were respawned after a license became active.
Configuration menu - View commit details
-
Copy full SHA for 5677977 - Browse repository at this point
Copy the full SHA 5677977View commit details -
ci: make Docker :latest track releases and harden build scripts [skip…
… ci] - release.yaml: also tag releases as :latest on GHCR, matching Docker Hub - deploy.yml: publish per-push dev images as :edge instead of :latest, so :latest is owned solely by the release workflow - deploy.yml: pass EE_COMMIT_HASH=$GITHUB_SHA to update-info.sh - getswagger.sh: refuse to start if the port is already in use, bound curl requests with --max-time, wait for the server to exit during cleanup - update-info.sh: only trust git rev-parse when the repository toplevel is the working directory, so a source export nested inside an unrelated git repository does not record the parent repository's commit hash
Configuration menu - View commit details
-
Copy full SHA for 44fd5e1 - Browse repository at this point
Copy the full SHA 44fd5e1View commit details -
fix: align API response schemas with actual responses and fix uncover…
…ed API bugs Audit of the Joi response schemas across all API route modules so the generated OpenAPI spec matches what the handlers actually return, plus fixes for bugs the audit uncovered: - return 404 (MessageNotFound/FolderNotFound) instead of a false response body when a message or folder is not found (Account#assertFound) - resolve special-use folder aliases (\Sent, \Trash, ...) for IMAP bulk update, move, and delete operations - Gmail API: support flags.set, reject unsupported labels.set with 400 before any API calls, return 404 for unknown folder paths in bulk updates - flags.set now takes precedence over flags.add/delete on Gmail and Outlook accounts, matching the IMAP backend behavior - Outlook: only force-delete messages in bulk delete when the source folder is the Trash folder; report a missing Trash folder as 404 - oauth-token endpoint returns the provider name and the OAuth2 app ID as separate fields instead of the app ID in the provider field - encrypt mailRuClientSecret, imapProxyServerPassword, and serviceKey settings at rest and mask them in GET /v1/settings responses - OAuth2 app updates only map the deprecated tenant field into authority when explicitly selected via authority='tenant' - accounts can be filtered by state 'paused' (API and admin UI) - enforce the documented force=true query parameter on the template flush endpoint (DELETE /v1/templates/account/{account} without it now fails with 400 ForceRequired) - assorted fixes: trackOpens flag, custom submit headers, outbox created timestamps, token listing IDs, delivery-test SPF comment cleanup, search size filters, OAuth2 app listing pagination totals, gateway delete response, queue stats resilience, chat success flag semantics Known gaps left for follow-up: IMAP move target paths do not resolve special-use aliases, Gmail bulk label updates do not map special-use names, and the OAuth2 create route still accepts the inert tenant field.Configuration menu - View commit details
-
Copy full SHA for abacbf6 - Browse repository at this point
Copy the full SHA abacbf6View commit details -
chore: replace jsxgettext with a modern gettext string extractor [ski…
…p ci] jsxgettext bundled acorn 5 and crashed with a SyntaxError on any file using post-ES2018 syntax (optional chaining etc.), which forced a hardcoded list of scanned files and a ban on modern syntax in them. The new gettext-extract.js parses with acorn 8 (ecmaVersion latest), walks the AST for gettext()/ngettext() calls, and merges the strings into translations/messages.pot via gettext-parser. Files are discovered dynamically under bin/, lib/, and workers/, so new modules with translatable strings are picked up automatically - no list to maintain when routes are refactored. The extracted msgid set is identical to the previous output, the views half of the pipeline (xgettext-template) is unchanged, and the "no newer syntax" restriction comments were removed from the previously scanned files since the constraint no longer applies.
Configuration menu - View commit details
-
Copy full SHA for 4c30b69 - Browse repository at this point
Copy the full SHA 4c30b69View commit details -
fix: align remaining API response schemas with actual responses
Continues the response schema audit: adds response schemas with failAction 'log' to the remaining API routes (blocklist, chat, delivery-test, export, gateway, license, mailbox, message, oauth2-app, outbox, pubsub, settings, stats, submit, template, token, webhook-route), extends lib/schemas.js with the shared error response helper usage, and simplifies the gettext coverage test.
Configuration menu - View commit details
-
Copy full SHA for 06136ab - Browse repository at this point
Copy the full SHA 06136abView commit details
Commits on Jun 11, 2026
-
chore: quote eslint globs so the whole lib/ tree is linted [skip ci]
The unquoted lib/**/*.js globs in the lint script and Gruntfile were expanded by sh (no globstar) to depth-2 files only, so the 48 root-level lib files and everything three or more levels deep were never linted by npm test or CI. Quoting the globs lets eslint expand them itself. Fixes the issues this surfaced (all behavior-neutral): - lib/account.js: drop a dead initializer (no-useless-assignment) - lib/autodetect-imap-settings.js: remove a leftover dead filter statement - lib/email-client/imap/subconnection.js: remove a no-op null assignment - lib/email-client/imap/sync-operations.js, lib/stream-encrypt.js: attach the caught error as cause when rethrowing (preserve-caught-error) - lib/imapproxy/imap-core/lib/imap-connection.js: remove a dead assignment - lib/imapproxy/imap-core/test/imap-indexer-test.js: keep the smoke parse without the unused assignment - lib/metrics-collector.js, lib/redis-operations.js: drop unused variables The tenth surfaced error (lib/webhooks.js:401) was a real bug and is fixed separately.
Configuration menu - View commit details
-
Copy full SHA for 1813f08 - Browse repository at this point
Copy the full SHA 1813f08View commit details -
fix: resolve code review findings in Gmail bulk ops, exports, webhook…
…s, and schemas Bugs: - Gmail API: resolve add/remove label conflicts in favor of the add in updateMessage/updateMessages, so bulk deletes from the Trash folder (add TRASH + remove TRASH) and moves within the current folder no longer fail with 400, and map IMAP special-use labels to Gmail label IDs in bulk updates via a shared toGmailLabelId helper (single-message updates already mapped them) - export worker: isSkippableError now reads the machine-readable code from Boom output payloads (like its sibling isFolderMissingError), so a message expunged mid-export is skipped instead of failing the whole export job; the error classifiers moved to lib/export.js for reuse and test coverage - webhooks: the handler cache version marker was assigned backwards and the per-route version compared a number to the string from Redis, so the cache was rebuilt from Redis on every webhook event once a custom route existed; the cache now refreshes only when routes change - settings: enabling generateEmailSummary or openAiGenerateEmbeddings now really enables notifyText - the old 'key in [array]' condition never matched - while still storing the key itself and bumping the OpenAI settings version - schemas: token access.ip and the short mailbox listing delimiter allow null, remoteAddress is documented as the IP of the client that created the token (not a restriction), and search responses document the documentStoreQuery debug field - gettext-extract: skip empty msgids that would corrupt the POT header entry Cleanup: shared mailbox base fields and a verify-result factory in the response schemas, shared OAuth2 scope-array schema, hoisted template account field, single schemas require in oauth2-app-routes, dropped the serviceUrl normalization from the settings route (settings.set already normalizes via formatSettingValue), removed unused schema exports and the dead module.exports block in workers/export.js. Tests: new regression coverage for the export error classifiers, the webhook handler cache, the settings AI/notifyText coupling, and gettext extraction (interpolated template literal tripwire, ngettext-only module coverage, empty msgid guard). translations/messages.pot regenerated for the final line references.
Configuration menu - View commit details
-
Copy full SHA for f0ddb46 - Browse repository at this point
Copy the full SHA f0ddb46View commit details -
feat: replace Bugsnag with self-hosted Sentry for error tracking
Error tracking now uses @sentry/node gated on the SENTRY_DSN env var, replacing @bugsnag/js and BUGSNAG_API_KEY. The nine duplicated init blocks in server.js and the worker entry points are consolidated into lib/sentry.js. Sentry is configured for error capture only: the SDK is required lazily so disabled installs pay no startup cost, and default integrations plus OpenTelemetry setup are skipped to keep http/fetch hot paths unpatched. The global uncaughtException/unhandledRejection handlers in lib/logger.js now always terminate the process, reporting the error and waiting for a short delivery flush first when tracking is enabled. Previously exit was delegated to the tracking SDK, which Sentry does not guarantee in worker threads.
Configuration menu - View commit details
-
Copy full SHA for 62de831 - Browse repository at this point
Copy the full SHA 62de831View commit details -
feat: allow enabling Sentry error reporting from the admin UI
Adds sentryEnabled and sentryDsn settings, exposed on the Config -> Logging page and through /v1/settings. When enabled without a custom DSN, reports go to the shared community Sentry instance run by the EmailEngine developers, so error reporting can be switched on temporarily during a support case without setting up a Sentry server. The settings are applied at runtime: lib/sentry.js polls them once a minute in every thread and starts or stops the SDK on change, so no restart is needed. The SENTRY_DSN environment variable still pins the configuration and disables the runtime settings.
Configuration menu - View commit details
-
Copy full SHA for a4076a4 - Browse repository at this point
Copy the full SHA a4076a4View commit details -
feat: tag Sentry error reports with instance id and license key
Events from different EmailEngine installations sharing the community Sentry DSN are now attributable: every report carries an 'instance' tag (the unique serviceId of the installation) and a 'license' tag (the license key id, read from the cached license metadata). Identity values are read once per SDK start, so a license swapped at runtime shows up after the next restart. A failed identity lookup only means untagged events, it never breaks error reporting.
Configuration menu - View commit details
-
Copy full SHA for 2e9683f - Browse repository at this point
Copy the full SHA 2e9683fView commit details -
Configuration menu - View commit details
-
Copy full SHA for 36cbdb8 - Browse repository at this point
Copy the full SHA 36cbdb8View commit details -
Configuration menu - View commit details
-
Copy full SHA for 76e2a80 - Browse repository at this point
Copy the full SHA 76e2a80View commit details -
Merge pull request #606 from postalsys/release-please--branches--mast…
…er--components--emailengine-app chore(master): release 2.70.0
Configuration menu - View commit details
-
Copy full SHA for 303496c - Browse repository at this point
Copy the full SHA 303496cView commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff v2.69.0...v2.70.0