feat: add LibreTranslate message auto-translation provider - #40900
dionisio-bot[bot] merged 3 commits into
Conversation
Adds LibreTranslate as a fourth message auto-translation provider alongside Google, DeepL and Microsoft. Unlike the existing providers, LibreTranslate is open-source and can be self-hosted, enabling fully on-premise / offline message auto-translation with no third-party API dependency. - New provider `libre-translate` registered in TranslationProviderRegistry - Configurable instance URL (AutoTranslate_LibreTranslateAPIURL) and optional API key (AutoTranslate_LibreTranslateAPIKey) under the Auto-Translate section - Added to the Service Provider dropdown and i18n labels
|
Looks like this PR is not ready to merge, because of the following issues:
Please fix the issues and try again If you have any trouble, please check the PR guidelines |
🦋 Changeset detectedLatest commit: 781eb8d The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughThis pull request introduces LibreTranslate as a new auto-translation provider for Rocket.Chat messages and attachments. The implementation includes a provider class that communicates with LibreTranslate HTTP APIs, admin settings to configure the API endpoint and optional authentication key, and localization strings for the UI. ChangesLibreTranslate Provider Implementation
🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
apps/meteor/app/autotranslate/server/libreTranslate.ts (1)
16-25: ⚡ Quick winRemove implementation comments in this TS file to match repository guideline.
As per coding guidelines, "Avoid code comments in the implementation."
Also applies to: 31-34, 41-47, 52-56, 65-69, 77-83, 110-118, 149-156, 177-183, 204-204
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/meteor/app/autotranslate/server/libreTranslate.ts` around lines 16 - 25, Remove all implementation-style comments inside the LibreTranslate class so the file follows the "no implementation comments" guideline: delete the inline/block comment blocks that describe implementation details (not JSDoc) around the LibreTranslate class and its methods (e.g., constructor, getLanguages, translate, detectLanguage, and any helper functions) and leave only necessary JSDoc/type comments if present; ensure no commented-out code remains and run a quick build/tests to confirm no functional code was accidentally removed.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/meteor/app/autotranslate/server/libreTranslate.ts`:
- Line 160: The call to getSupportedLanguages('en') can reject and abort the
entire translation flow; wrap both calls to getSupportedLanguages('en') in a
try/catch inside the LibreTranslate class method that drives per-language
translations (where getSupportedLanguages is invoked), log the error via the
existing logger, and fall back to a safe default (e.g., an empty array or a
minimal hardcoded list) so the per-target-language loop still runs and each
individual translate call can handle its own failures; ensure you reference
getSupportedLanguages('en') and the surrounding translate/processing method when
making the change so you catch both bootstrap sites.
- Around line 94-96: The two outbound fetch calls to
`${this.apiEndPointUrl}/languages` and the POST to
`${this.apiEndPointUrl}/translate` lack a timeout/abort mechanism; update both
fetches in apps/meteor/app/autotranslate/server/libreTranslate.ts to supply a
timeout-supported option via the `@rocket.chat/server-fetch` helper or attach an
AbortSignal from an AbortController (e.g., create an AbortController, set a
reasonable timeout like 5–15s to call controller.abort(), and pass
controller.signal to fetch). Also ensure the code that calls these fetches (the
methods referencing this.apiEndPointUrl and the response handling) catches
abort/timeout errors and returns/logs an appropriate failure rather than leaving
the worker hanging.
- Around line 93-96: The fetch call in the LibreTranslate client is bypassing
SSRF protection by setting ignoreSsrfValidation: true; update the code in the
method that calls fetch (the languages request in LibreTranslate client) to
remove ignoreSsrfValidation and instead perform proper SSRF validation — either
rely on the built-in checkForSsrfWithIp flow by omitting the ignore flag, or
validate the configured AutoTranslate_LibreTranslateAPIURL against the SSRF
allowlist (SSRF_Allowlist) before calling fetch; ensure the same change is
applied to the other fetch usage in the same file (lines 130-134 equivalent) so
runtime-configured API URLs are validated rather than unconditionally bypassing
SSRF checks.
In `@apps/meteor/server/settings/message.ts`:
- Around line 401-417: The setting registration for
'AutoTranslate_LibreTranslateAPIKey' uses this.add(...) but is missing the
secret flag, so the API key can be exposed; update the options object passed to
this.add for the 'AutoTranslate_LibreTranslateAPIKey' setting to include secret:
true (alongside existing properties like type, group, section, public,
i18nLabel, and enableQuery) so the value is treated as a secret in admin
surfaces and logs.
In `@packages/i18n/src/locales/en.i18n.json`:
- Line 869: The i18n key "AutoTranslate_LibreTranslate_API_URL" does not match
the configured setting ID "AutoTranslate_LibreTranslateAPIURL", causing label
resolution to fail; rename the JSON key to "AutoTranslate_LibreTranslateAPIURL"
(replacing the underscored variant) so it exactly matches the setting ID used by
the admin settings resolver, and run a quick search to update any other locale
files or references that use the old key.
---
Nitpick comments:
In `@apps/meteor/app/autotranslate/server/libreTranslate.ts`:
- Around line 16-25: Remove all implementation-style comments inside the
LibreTranslate class so the file follows the "no implementation comments"
guideline: delete the inline/block comment blocks that describe implementation
details (not JSDoc) around the LibreTranslate class and its methods (e.g.,
constructor, getLanguages, translate, detectLanguage, and any helper functions)
and leave only necessary JSDoc/type comments if present; ensure no commented-out
code remains and run a quick build/tests to confirm no functional code was
accidentally removed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5bdc6f1c-a9fd-438a-ab9e-c83b7536e550
📒 Files selected for processing (5)
.changeset/libretranslate-autotranslate-provider.mdapps/meteor/app/autotranslate/server/index.tsapps/meteor/app/autotranslate/server/libreTranslate.tsapps/meteor/server/settings/message.tspackages/i18n/src/locales/en.i18n.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: 📦 Build Packages
- GitHub Check: CodeQL-Build
- GitHub Check: cubic · AI code reviewer
- GitHub Check: Hacktron Security Check
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)
**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation
Files:
apps/meteor/app/autotranslate/server/index.tsapps/meteor/server/settings/message.tsapps/meteor/app/autotranslate/server/libreTranslate.ts
🧠 Learnings (4)
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.
Applied to files:
apps/meteor/app/autotranslate/server/index.tsapps/meteor/server/settings/message.tsapps/meteor/app/autotranslate/server/libreTranslate.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.
Applied to files:
apps/meteor/app/autotranslate/server/index.tsapps/meteor/server/settings/message.tsapps/meteor/app/autotranslate/server/libreTranslate.ts
📚 Learning: 2026-05-06T12:21:44.083Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 40256
File: apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx:121-149
Timestamp: 2026-05-06T12:21:44.083Z
Learning: Field wrappers in rocket.chat/fuselage-forms (Field, FieldLabel, FieldRow, FieldError, FieldHint) auto-create htmlFor/id associations, aria-describedby, and role="alert" for errors. Do not manually set htmlFor, id, aria-describedby, or role attributes when using these wrappers. This automatic wiring does not apply to plain rocket.chat/fuselage components, which require explicit ID wiring per the accessibility docs. In code reviews, prefer using fuselage-forms wrappers for form fields and verify there is no unnecessary manual ID/aria wiring in files that use these wrappers. If a component uses plain fuselage components, ensure proper id wiring as per docs.
Applied to files:
apps/meteor/app/autotranslate/server/index.tsapps/meteor/server/settings/message.tsapps/meteor/app/autotranslate/server/libreTranslate.ts
📚 Learning: 2026-03-16T21:50:37.589Z
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39676
File: .changeset/migrate-users-register-openapi.md:3-3
Timestamp: 2026-03-16T21:50:37.589Z
Learning: For changes related to OpenAPI migrations in Rocket.Chat/OpenAPI, when removing endpoint types and validators from rocket.chat/rest-typings (e.g., UserRegisterParamsPOST, /v1/users.register) document this as a minor changeset (not breaking) per RocketChat/Rocket.Chat-Open-API#150 Rule 7. Note that the endpoint type is re-exposed via a module augmentation .d.ts in the consuming package (e.g., packages/web-ui-registration/src/users-register.d.ts). In reviews, ensure the changeset clearly states: this is a non-breaking change, the major version should not be bumped, and the changeset reflects a minor version bump. Do not treat this as a breaking change during OpenAPI migrations.
Applied to files:
.changeset/libretranslate-autotranslate-provider.md
🔇 Additional comments (3)
.changeset/libretranslate-autotranslate-provider.md (1)
1-7: LGTM!apps/meteor/server/settings/message.ts (1)
319-322: LGTM!Also applies to: 383-399
apps/meteor/app/autotranslate/server/index.ts (1)
13-13: LGTM!
There was a problem hiding this comment.
3 issues found across 5 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #40900 +/- ##
===========================================
+ Coverage 70.02% 70.11% +0.08%
===========================================
Files 3355 3358 +3
Lines 129162 129565 +403
Branches 22337 22490 +153
===========================================
+ Hits 90443 90839 +396
+ Misses 35421 35409 -12
- Partials 3298 3317 +19
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
Warning These are security findings reported by the security scanners configured in Layne. Findings may contain false positives - review them and fix what makes sense. Layne found 2 high issues in this PR. View 2 finding(s)
|
…ovider - Replace underscore (`_.findWhere`) with a native `Array.find` - Wrap `new Intl.Locale(code)` so an unsupported language code can't throw - Guard `getSupportedLanguages`/translation when the instance URL is unset - Isolate supported-language fetch failures so one error no longer aborts all target translations for a message - Set an explicit request timeout on the outbound LibreTranslate calls - Mark `AutoTranslate_LibreTranslateAPIKey` as `secret`
- Move error handling inside getSupportedLanguages (drop the wrapper helper) - Use a dedicated AutoTranslate `LibreTranslate` logger section instead of SystemLogger - Use Array.includes and object spread for the API key - Keep request timeouts and admin-only URL handling
|
/layne exception-approve LAYNE-66b4c90a9bc8b034 LAYNE-66573dc98a53d745 reason: URL is not user-controlled and is admin-only |
|
✅ Exception recorded for LAYNE-66b4c90a9bc8b034, LAYNE-66573dc98a53d745 by @yasnagat: "URL is not user-controlled and is admin-only". Re-running scan... |
25722db
Proposed changes
Adds LibreTranslate as a message auto-translation provider, alongside the existing Google, DeepL and Microsoft providers.
Unlike the current providers, LibreTranslate is open-source and can be self-hosted, which enables fully on-premise / offline message auto-translation with no third-party API dependency or per-character cost. This is useful for air-gapped, privacy-sensitive, or cost-constrained deployments.
It integrates through the existing
AutoTranslateprovider abstraction, so it populates the nativetranslationsmessage metadata and works with the standard per-user translate toggle — no client changes.Implementation
libre-translate(apps/meteor/app/autotranslate/server/libreTranslate.ts) extendingAutoTranslate, registered viaTranslationProviderRegistry.AutoTranslate_LibreTranslateAPIURL— base URL of the LibreTranslate instance (e.g.http://libretranslate.internal:5000)AutoTranslate_LibreTranslateAPIKey— optional, only when the instance enforces API keyslibre-translateto theAutoTranslate_ServiceProviderdropdown and the corresponding i18n labels./languagesendpoint; translation uses/translate.How to test
docker run -p 5000:5000 libretranslate/libretranslate).Validated end-to-end against a self-hosted LibreTranslate instance (message translated and stored in
message.translations).Types of changes
Further comments
A changeset is included (
@rocket.chat/meteor: minor,@rocket.chat/i18n: patch).CORE-2301
Summary by CodeRabbit