* Add tagging of outgoing emails
* Detect SES configured via well-known service key
The isSES check only matched "amazonaws" in the host, so SES configured
through SMTP_SERVICE (e.g. "SES" or "SES-US-EAST-1") was not detected and
tagging headers were not applied.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* perf: Lazy import mailparser, @fast-csv, and franc deps
Moves heavy dependencies off the startup path into the narrow async code
paths that actually use them, mirroring the mammoth lazy-import change:
- mailparser: only needed for Confluence Word imports (confluenceToHtml)
- @fast-csv/parse: only needed for CSV imports (csvToMarkdown)
- franc / iso-639-3: only needed by the DocumentUpdateText worker task
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* perf: Lazy import jsdom dep
jsdom is one of the heaviest server dependencies but is only needed for
HTML export (ProsemirrorHelper.toHTML) and HTML import
(DocumentConverter.htmlToProsemirror). Move it to a lazy `await import`
inside those methods so its dependency tree stays off the startup path.
Both methods become async; all callers were already in async contexts.
The type-only usage in patchGlobalEnv is now an `import type`.
* feat: Request document access
Allow users without permission to a document to request access. Notifies
document managers via in-app notification and email; managers can grant
or dismiss the request.
- Adds AccessRequest model, migration, policy, presenter
- Adds accessRequests.create/info/approve/dismiss endpoints
- Adds DocumentAccessRequestNotificationsTask + email
- Adds Error403 request flow with loading state and pending indicator
- Auto-opens notifications popover via ?notifications=true (used in email)
- Adds SplitButton primitive for permission selection in notifications
- Refactors useConsumeQueryParam hook
* refactor
* fix: Make approve/dismiss idempotent on access requests
Return success when the access request has already been dismissed, or
when the user already has document membership at approve time, instead
of throwing 400. Avoids racy double-clicks on notification actions
producing user-visible errors.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Minor fixes
---------
Co-authored-by: Tom Moor <tom@getoutline.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* wip
* Remove obsolete snapshots
* simplify
* chore(test): Convert mocks to TypeScript and tighten fetch mock types
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Remove unneccessary patches
* Migrate to msw instead of custom fetch mock
* Address PR review comments
- Split chained vi.useFakeTimers().setSystemTime() into separate calls.
- Switch test setup to dynamic imports so EventEmitter.defaultMaxListeners
assignment runs before module init (static imports were hoisted above it).
- Drop redundant NODE_ENV guard in monkeyPatchSequelizeErrorsForJest; its
sole caller already gates on env.isTest.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* chore: Replace lodash with es-toolkit
Migrate all direct lodash imports to es-toolkit/compat for a smaller,
faster, lodash-compatible utility library. Transitive lodash usage from
other packages remains unchanged.
* fix: Restore isPlainObject semantics in CanCan policy
The lodash migration aliased `isObject` to `lodash/isPlainObject` and
the codemod incorrectly mapped the local name to es-toolkit's `isObject`,
which also returns true for arrays and functions. This caused condition
objects in policy definitions to be skipped, breaking authorization
checks across the codebase.
* fix: Restore unicode-aware length counting in validators
es-toolkit/compat's size() returns string.length, while lodash's _.size()
counts unicode code points. Switch to [...value].length to preserve the
previous behavior so multi-byte characters like emoji count as one.
* chore: Reduce no-explicit-any warnings in server directory
Tightens types across test response bodies, decorator signatures, the
TestServer wrapper, base class generics, and presenter Record types.
Where any is genuinely load-bearing (Sequelize model generics,
PropertyDescriptor decorator returns, plugin-registered template
classes, Fix mixin), keeps any with a targeted eslint-disable plus
reason rather than masking the constraint. Cuts server-only
no-explicit-any warnings from 162 to 70.
* fix: groups test asserts on first response instead of second
Caught by Copilot review on the no-explicit-any cleanup. Also fixes
the pre-existing getChangsetSkipped → getChangesetSkipped typo
surfaced while reviewing nearby decorator code.
Move key props before spreads, add missing keys to iterator fragments,
and replace this-destructuring with direct property access.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* wip
* Implementation complete
* tidying
* test
* Address feedback
* Remove duplicative retry logic from UpdateDocumentsPopularityScoreTask.
Now that we're split across many runs this is not neccessary
* Refactor to subclass, config to instance
* Refactor BaseTask to named export
* fix: Missing partition
* tsc
* Feedback
* add group mentions
* group mention functionality
* add notification test
* fix: Group icon in mention menu
* language
* toast message
* fix: Group icon in mention menu light mode color
---------
Co-authored-by: Tom Moor <tom@getoutline.com>
* Add ReactionsCreate notification event type
- Add ReactionsCreate to NotificationEventType enum and defaults
- Add notification settings UI with SmileyIcon and proper labels
- Create ReactionsCreateNotificationsTask to handle comment reactions
- Update NotificationsProcessor to handle comments.add_reaction events
- Add eventText and path handling in client Notification model
- Notifications are enabled by default but never send emails
* Applied automatic fixes
* Show the actual emoji in the notification
* Cleanup notifications if reaction is removed
* PR feedback
---------
Co-authored-by: codegen-sh[bot] <131295404+codegen-sh[bot]@users.noreply.github.com>
Co-authored-by: Tom Moor <tom@getoutline.com>
* Improve webhook disabling heuristic with time-based analysis
- Add WEBHOOK_FAILURE_TIME_WINDOW environment variable (default: 24 hours)
- Add WEBHOOK_FAILURE_RATE_THRESHOLD environment variable (default: 80%)
- Replace simple count-based logic with time-window failure rate analysis
- Require minimum 5 deliveries in time window before disabling
- Add comprehensive logging for webhook failure analysis
- Update email template to reflect new time-based approach
Addresses GitHub issue #9788 by making webhook disabling smarter and
considering time factors instead of just consecutive failure counts.
* Fix Logger.warn type error
Remove extra 'task' parameter from Logger.warn call to match the correct
signature: Logger.warn(message: string, extra?: Extra)
* Update WEBHOOK_FAILURE_TIME_WINDOW to use seconds instead of hours
- Change default value from 24 (hours) to 86400 (seconds)
- Update time conversion logic from hours*60*60*1000 to seconds*1000
- Rename timeWindowHours variable to timeWindowSeconds for clarity
- Update documentation comments to reflect seconds-based configuration
This provides more granular control while maintaining the same default
behavior (24 hours = 86400 seconds).
* Improve webhook failure logging and analysis threshold
- Only log webhook failure analysis when failedDeliveries.length > 0
- Extract hardcoded minimum deliveries threshold to constant
- Update minimum deliveries threshold from 5 to 10 for more reliable analysis
This reduces log noise when there are no failures and requires more data
points before considering webhook disabling.
---------
Co-authored-by: codegen-sh[bot] <131295404+codegen-sh[bot]@users.noreply.github.com>
* Upgrade Prettier to v3.6.2 and eslint-plugin-prettier to v5.5.1
- Upgraded prettier from ^2.8.8 to ^3.6.2 (latest version)
- Upgraded eslint-plugin-prettier from ^4.2.1 to ^5.5.1 for compatibility
- Applied automatic formatting changes from new Prettier version
- All existing ESLint and Prettier configurations remain compatible
* Applied automatic fixes
* Trigger CI
---------
Co-authored-by: codegen-sh[bot] <131295404+codegen-sh[bot]@users.noreply.github.com>
Co-authored-by: Tom Moor <tom@getoutline.com>
* Upgrade @typescript-eslint dependencies from v6.21.0 to v8.33.0
- Updated @typescript-eslint/eslint-plugin from ^6.21.0 to ^8.33.0
- Updated @typescript-eslint/parser from ^6.21.0 to ^8.33.0
- Tested linting functionality to ensure compatibility
- This brings the latest TypeScript ESLint features and bug fixes
* lint
* tsc
---------
Co-authored-by: codegen-sh[bot] <131295404+codegen-sh[bot]@users.noreply.github.com>
Co-authored-by: Tom Moor <tom@getoutline.com>
* Fix various linting errors
This commit addresses several linting warnings reported by ESLint:
- @typescript-eslint/no-shadow:
- I renamed variables in inner scopes to avoid conflicts with variables in outer scopes in the following files:
- server/commands/accountProvisioner.ts
- server/commands/documentDuplicator.ts
- server/commands/documentMover.ts
- server/commands/teamProvisioner.test.ts
- server/commands/teamProvisioner.ts
- server/commands/userInviter.ts
- server/commands/userProvisioner.ts
- server/emails/templates/BaseEmail.tsx
- @typescript-eslint/no-explicit-any:
- I replaced `any` with more specific types (Record<string, unknown> or void) in the following files:
- server/emails/templates/BaseEmail.tsx
- server/emails/templates/InviteEmail.tsx
- server/emails/templates/SigninEmail.tsx
- server/logging/Logger.ts
These changes improve code clarity and type safety without altering functionality.
* Update BaseEmail.tsx
* lint
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* Fix misalignment between email and comment mentions
* Add test
* Update ProsemirrorHelper.tsx
* Optimize user mention processing with batch loading
* Add test for multiple mentions
---------
Co-authored-by: codegen-sh[bot] <131295404+codegen-sh[bot]@users.noreply.github.com>
Co-authored-by: Tom Moor <tom@getoutline.com>
* Add SMTP_SERVICE environment variable for well-known services
* Fix PR #8777: Restore code in teams.ts and users.ts
* The rest of the work
* fix validation
---------
Co-authored-by: codegen-sh[bot] <131295404+codegen-sh[bot]@users.noreply.github.com>
Co-authored-by: Tom Moor <tom.moor@gmail.com>