12c830be0a7d83df94f809be030a66a2ceabc8ef
5928
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
12c830be0a |
fix: handoff only if conversation pending (#13882)
# Pull Request Template ## Description - Skip handoff when the conversation is no longer pending. - Fetch conversation status with Conversation.uncached to avoid stale query cache when checking pending state. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Difficult to reproduce locally, but seen a couple of conversations where bot hands off an extra time or Captain re-generates usually due to a retry on FaradayTimeoutError but at perform time, the conversation status is stale so it appears as if Captain responded in an open conversation. ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules |
||
|
|
f2a126f162 |
fix: conversation completion prompt to auto-resolve gibberish/no-intent messages after inactivity (#13875)
# Pull Request Template ## Description For our account, the conversation completion evaluator was proving to be too conservative. This resulted in queue noise. This PR adds a line to handle gibberish/single worded messages with no further context. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. <img width="3012" height="978" alt="CleanShot 2026-03-23 at 11 44 55@2x" src="https://github.com/user-attachments/assets/328195e8-6ea0-4c3a-9049-ee80196eecad" /> <img width="2202" height="866" alt="CleanShot 2026-03-23 at 11 47 15@2x" src="https://github.com/user-attachments/assets/8d51cff4-b18f-4582-9455-8119ec7eff3a" /> ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules |
||
|
|
0c4551e6ff |
chore: Update translations (#13845)
Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
ad8e1ff151 |
chore(deps): bump bcrypt from 3.1.20 to 3.1.22 (#13852)
Bumps [bcrypt](https://github.com/bcrypt-ruby/bcrypt-ruby) from 3.1.20 to 3.1.22. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/bcrypt-ruby/bcrypt-ruby/releases">bcrypt's releases</a>.</em></p> <blockquote> <h2>v3.1.22</h2> <h2>What's Changed</h2> <ul> <li>Move compilation after bundle install by <a href="https://github.com/tenderlove"><code>@tenderlove</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/291">bcrypt-ruby/bcrypt-ruby#291</a></li> <li>Add TruffleRuby in CI by <a href="https://github.com/tjschuck"><code>@tjschuck</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/293">bcrypt-ruby/bcrypt-ruby#293</a></li> <li>fix env url by <a href="https://github.com/tenderlove"><code>@tenderlove</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/294">bcrypt-ruby/bcrypt-ruby#294</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/bcrypt-ruby/bcrypt-ruby/compare/v3.1.21...v3.1.22">https://github.com/bcrypt-ruby/bcrypt-ruby/compare/v3.1.21...v3.1.22</a></p> <h2>v3.1.21</h2> <h2>What's Changed</h2> <ul> <li>Provide a 'Changelog' link on rubygems.org/gems/bcrypt by <a href="https://github.com/mark-young-atg"><code>@mark-young-atg</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/274">bcrypt-ruby/bcrypt-ruby#274</a></li> <li>Support ruby 3.3 and 3.4.0-preview1 by <a href="https://github.com/m-nakamura145"><code>@m-nakamura145</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/276">bcrypt-ruby/bcrypt-ruby#276</a></li> <li>Mark as ractor-safe by <a href="https://github.com/mohamedhafez"><code>@mohamedhafez</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/280">bcrypt-ruby/bcrypt-ruby#280</a></li> <li>Add == gotcha that can be unintuitive at first by <a href="https://github.com/federicoaldunate"><code>@federicoaldunate</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/279">bcrypt-ruby/bcrypt-ruby#279</a></li> <li>Constant compare by <a href="https://github.com/tenderlove"><code>@tenderlove</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/282">bcrypt-ruby/bcrypt-ruby#282</a></li> <li>try to modernize CI by <a href="https://github.com/tenderlove"><code>@tenderlove</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/287">bcrypt-ruby/bcrypt-ruby#287</a></li> <li>Try to deal with flaky tests by <a href="https://github.com/tenderlove"><code>@tenderlove</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/288">bcrypt-ruby/bcrypt-ruby#288</a></li> <li>Configure trusted publishing by <a href="https://github.com/tenderlove"><code>@tenderlove</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/289">bcrypt-ruby/bcrypt-ruby#289</a></li> <li>bump version by <a href="https://github.com/tenderlove"><code>@tenderlove</code></a> in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/290">bcrypt-ruby/bcrypt-ruby#290</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/mark-young-atg"><code>@mark-young-atg</code></a> made their first contribution in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/274">bcrypt-ruby/bcrypt-ruby#274</a></li> <li><a href="https://github.com/m-nakamura145"><code>@m-nakamura145</code></a> made their first contribution in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/276">bcrypt-ruby/bcrypt-ruby#276</a></li> <li><a href="https://github.com/mohamedhafez"><code>@mohamedhafez</code></a> made their first contribution in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/280">bcrypt-ruby/bcrypt-ruby#280</a></li> <li><a href="https://github.com/federicoaldunate"><code>@federicoaldunate</code></a> made their first contribution in <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/pull/279">bcrypt-ruby/bcrypt-ruby#279</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/bcrypt-ruby/bcrypt-ruby/compare/v3.1.20...v3.1.21">https://github.com/bcrypt-ruby/bcrypt-ruby/compare/v3.1.20...v3.1.21</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/bcrypt-ruby/bcrypt-ruby/blob/master/CHANGELOG">bcrypt's changelog</a>.</em></p> <blockquote> <p>3.1.22 Mar 18 2026</p> <ul> <li>[CVE-2026-33306] Fix integer overflow in Java extension</li> </ul> <p>3.1.21 Dec 31 2025</p> <ul> <li>Use constant time comparisons</li> <li>Mark as Ractor safe</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/bcrypt-ruby/bcrypt-ruby/commit/831ce64cb0a9502130fa93a28bfd9527a5fa45c4"><code>831ce64</code></a> Merge commit from fork</li> <li><a href="https://github.com/bcrypt-ruby/bcrypt-ruby/commit/32e687ec5f62baad01a62e4634e41d97f8432a61"><code>32e687e</code></a> bump version update changelog</li> <li><a href="https://github.com/bcrypt-ruby/bcrypt-ruby/commit/5faa2748331d3edc661c127ef2fbb3afcb6b02a4"><code>5faa274</code></a> Fix integer overflow in JRuby BCrypt rounds calculation</li> <li><a href="https://github.com/bcrypt-ruby/bcrypt-ruby/commit/aafc0332ac1aa0d774f2c864439596436f92d18d"><code>aafc033</code></a> Merge pull request <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/issues/294">#294</a> from bcrypt-ruby/fix-publishing</li> <li><a href="https://github.com/bcrypt-ruby/bcrypt-ruby/commit/01f947a66ad8c5e20d8c89d9adbc7e3bd49afb70"><code>01f947a</code></a> fix env url</li> <li><a href="https://github.com/bcrypt-ruby/bcrypt-ruby/commit/92ca1d67deeb8e64dbe779396c52b177e307bc43"><code>92ca1d6</code></a> Merge pull request <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/issues/293">#293</a> from bcrypt-ruby/truffleruby-ci-alt-implementation</li> <li><a href="https://github.com/bcrypt-ruby/bcrypt-ruby/commit/4d1d95b8ec624d0cf8ed1099402a7edd2f308da2"><code>4d1d95b</code></a> Add TruffleRuby in CI</li> <li><a href="https://github.com/bcrypt-ruby/bcrypt-ruby/commit/36a04a2278fae3b38100912ff489b86cd0984b8a"><code>36a04a2</code></a> Merge pull request <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/issues/291">#291</a> from tenderlove/fix-publishing</li> <li><a href="https://github.com/bcrypt-ruby/bcrypt-ruby/commit/01cc68835f0bcdd7ef16de477471c112adb417da"><code>01cc688</code></a> Move compilation after bundle install</li> <li><a href="https://github.com/bcrypt-ruby/bcrypt-ruby/commit/82e6c4c6cf81912768c68d721372e78330ff2c92"><code>82e6c4c</code></a> Merge pull request <a href="https://redirect.github.com/bcrypt-ruby/bcrypt-ruby/issues/290">#290</a> from tenderlove/bump</li> <li>Additional commits viewable in <a href="https://github.com/bcrypt-ruby/bcrypt-ruby/compare/v3.1.20...v3.1.22">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/chatwoot/chatwoot/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
4ec7697f04 |
chore(deps): bump json from 2.18.1 to 2.19.2 (#13849)
Bumps [json](https://github.com/ruby/json) from 2.18.1 to 2.19.2. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/ruby/json/releases">json's releases</a>.</em></p> <blockquote> <h2>v2.19.2</h2> <h2>What's Changed</h2> <ul> <li>Fix a format string injection vulnerability in <code>JSON.parse(doc, allow_duplicate_key: false)</code>. <code>CVE-2026-33210</code></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/ruby/json/compare/v2.19.1...v2.19.2">https://github.com/ruby/json/compare/v2.19.1...v2.19.2</a></p> <h2>v2.19.1</h2> <h2>What's Changed</h2> <ul> <li>Fix a compiler dependent GC bug introduced in <code>2.18.0</code>.</li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/ruby/json/compare/v2.19.0...v2.19.1">https://github.com/ruby/json/compare/v2.19.0...v2.19.1</a></p> <h2>v2.19.0</h2> <h2>What's Changed</h2> <ul> <li>Fix <code>allow_blank</code> parsing option to no longer allow invalid types (e.g. <code>load([], allow_blank: true)</code> now raise a type error).</li> <li>Add <code>allow_invalid_escape</code> parsing option to ignore backslashes that aren't followed by one of the valid escape characters.</li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/ruby/json/compare/v2.18.1...v2.19.0">https://github.com/ruby/json/compare/v2.18.1...v2.19.0</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/ruby/json/blob/master/CHANGES.md">json's changelog</a>.</em></p> <blockquote> <h3>2026-03-18 (2.19.2)</h3> <ul> <li>Fix a format string injection vulnerability in <code>JSON.parse(doc, allow_duplicate_key: false)</code>. <code>CVE-2026-33210</code>.</li> </ul> <h3>2026-03-08 (2.19.1)</h3> <ul> <li>Fix a compiler dependent GC bug introduced in <code>2.18.0</code>.</li> </ul> <h3>2026-03-06 (2.19.0)</h3> <ul> <li>Fix <code>allow_blank</code> parsing option to no longer allow invalid types (e.g. <code>load([], allow_blank: true)</code> now raise a type error).</li> <li>Add <code>allow_invalid_escape</code> parsing option to ignore backslashes that aren't followed by one of the valid escape characters.</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/ruby/json/commit/54f8a878aebee090476a53c851c943128894be62"><code>54f8a87</code></a> Release 2.19.2</li> <li><a href="https://github.com/ruby/json/commit/393b41c3e5f87491e1e34fa59fa78ff6fa179a74"><code>393b41c</code></a> Fix a format string injection vulnerability</li> <li><a href="https://github.com/ruby/json/commit/dbf6bb12aac85db939df1180028aea06c8d3b762"><code>dbf6bb1</code></a> Merge pull request <a href="https://redirect.github.com/ruby/json/issues/953">#953</a> from ruby/dependabot/github_actions/actions/create-gi...</li> <li><a href="https://github.com/ruby/json/commit/7187315b4571ade59d68a1fad84be2794cda744d"><code>7187315</code></a> Bump actions/create-github-app-token from 2 to 3</li> <li><a href="https://github.com/ruby/json/commit/4a42a04280d96d8dd94558078c16f1c078c38e1b"><code>4a42a04</code></a> Release 2.19.1</li> <li><a href="https://github.com/ruby/json/commit/13689c269970f18316952541f8544830ec2dc5c4"><code>13689c2</code></a> Add missing GC_GUARD in <code>fbuffer_append_str</code></li> <li><a href="https://github.com/ruby/json/commit/a11acc1ff496627e5d72c71d6d1229e8c8ffeaa1"><code>a11acc1</code></a> Release 2.19.0</li> <li><a href="https://github.com/ruby/json/commit/0a4fb79cd97f535701cc2240ac736d76b9af5025"><code>0a4fb79</code></a> fbuffer.h: Use size_t over unsigned long</li> <li><a href="https://github.com/ruby/json/commit/a29fcdcb4a78164daa14f6af05812690dd3ac939"><code>a29fcdc</code></a> Add depth validation to Jruby and TruffleRuby implementations</li> <li><a href="https://github.com/ruby/json/commit/de993aa76639078da891f46351a36f77d51ad3d3"><code>de993aa</code></a> Reject negative depth; add overflow guards to prevent hang/crash</li> <li>Additional commits viewable in <a href="https://github.com/ruby/json/compare/v2.18.1...v2.19.2">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/chatwoot/chatwoot/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
02b89f3f20 |
chore: Auto-focus editor when replying to a message (#13857)
# Pull Request Template ## Description This PR adds support to auto-focus the editor when clicking reply to this message, the editor now automatically receives focus so users can start typing immediately. Fixes https://linear.app/chatwoot/issue/CW-6661/typing-box-not-focused-after-clicking-reply-to-message ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? ### Screencast https://github.com/user-attachments/assets/c5e77055-3f68-4ad8-934e-cfc465166e8a ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules |
||
|
|
a761185653 |
fix: use last_activity_at for orphan conversation cleanup timeframe (#13859)
## Description The RemoveOrphanConversationsService filters orphan conversations by a time window before deleting them. Previously it used created_at, which could miss old conversations that still had recent activity. Switching to last_activity_at ensures the cleanup window reflects actual conversation activity rather than creation time. ## Type of change Please delete options that are not relevant. - [ ] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - By running Rake task - Run the job from console ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules |
||
|
|
e2843e9bb9 |
feat: allow captain to access contact attributes (#13850)
# Pull Request Template ## Description Captain v1 does not have access to contact attributes. Added a toggle to let user choose if they want contact information available to Captain. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Specs and locally <img width="1924" height="740" alt="CleanShot 2026-03-19 at 18 48 19@2x" src="https://github.com/user-attachments/assets/353cfeaa-cd58-40eb-89e7-d660a1dc1185" /> ![Uploading CleanShot 2026-03-19 at 18.53.26@2x.png…]() ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules |
||
|
|
e32debe0b9 |
chore(i18n): add missing pt_BR locale imports for companies, mfa, snooze, webhooks and more (#13844)
## Description Add missing JSON imports and spread exports for `companies`, `contentTemplates`, `mfa`, `snooze`, `webhooks`, and `yearInReview` so these translations are properly loaded in the pt_BR locale. Without these imports, those sections of the UI were falling back to English for Brazilian Portuguese users. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] My changes generate no new warnings Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
e74d1d75be |
feat(rollup): add models and write path [1/3] (#13796)
## PR#1: Reporting events rollup — model and write path Reporting queries currently hit the `reporting_events` table directly. This works, but the table grows linearly with event volume, and aggregation queries (counts, averages over date ranges) get progressively slower as accounts age. This PR introduces a pre-aggregated `reporting_events_rollups` table that stores daily per-metric, per-dimension (account/agent/inbox) totals. The write path is intentionally decoupled from the read path — rollup rows are written inline from the event listener via upsert, and a backfill service exists to rebuild historical data from raw events. Nothing reads from this table yet. The write path activates when an account has a `reporting_timezone` set (new account setting). The `reporting_events_rollup` feature flag controls only the future read path, not writes — so rollup data accumulates silently once timezone is configured. A `MetricRegistry` maps raw event names to rollup column semantics in one place, keeping the write and (future) read paths aligned. ### What changed - Migration for `reporting_events_rollups` with a unique composite index for upsert - `ReportingEventsRollup` model - `reporting_timezone` account setting with IANA timezone validation - `MetricRegistry` — single source of truth for event-to-metric mappings - `RollupService` — real-time upsert from event listener - `BackfillService` — rebuilds rollups for a given account + date from raw events - Rake tasks for interactive backfill and timezone setup - `reporting_events_rollup` feature flag (disabled by default) ### How to test 1. Set a `reporting_timezone` on an account (`Account.first.update!(reporting_timezone: 'Asia/Kolkata')`) 2. Resolve a conversation or trigger a first response 3. Check `ReportingEventsRollup.where(account_id: ...)` — rows should appear 4. Run backfill: `bundle exec rake reporting_events_rollup:backfill` and verify historical data populates --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> |
||
|
|
a532c79d98 |
docs(swagger): fix public API schema definitions to match jbuilder responses (#13693)
## Description This PR updates the OpenAPI schema definitions for Public API resources (`public_conversation`, `public_message`, `public_contact`) so they match the actual API responses produced by the jbuilder views. These definitions were introduced in #2417 (2021-06) with a minimal set of fields. The jbuilder views have since been updated (e.g. `uuid` in #7255, `agent_last_seen_at` in #4377), but the Swagger definitions were never updated. As a result, generated API clients get incorrect or missing types. This change fixes that by aligning the schemas with the implementation. **Fixes #13692** ## Type of change Please delete options that are not relevant. - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality not to work as expected) - [x] This change requires a documentation update ## How Has This Been Tested? - Compared each jbuilder view (`app/views/public/api/v1/models/_conversation.json.jbuilder`, `_message.json.jbuilder`, `_contact.json.jbuilder`) field-by-field against the Swagger YAML definitions. - Cross-referenced Ruby model enums (`Conversation.status`, `Attachment.file_type`, `Message.message_type`) for enum values. - Ran the swagger build (via the project’s `rake swagger:build` logic / `json_refs` resolution) to regenerate `swagger.json` and tag group files; confirmed the generated schemas contain the correct fields and types. - No runtime tests were run; this is a documentation/schema-only change. ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas *(N/A: schema definitions)* - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works *(N/A: documentation/schema only)* - [ ] New and existing unit tests pass locally with my changes *(N/A: no code under test)* - [x] Any dependent changes have been merged and published in downstream modules *(N/A: none)* --- ## Change summary (for reference) ### `public_conversation` - Added missing fields: `uuid`, `status`, `contact_last_seen_at`, `agent_last_seen_at` - Fixed `inbox_id` type from `string` to `integer` - Fixed `messages` items `$ref` from `message` to `public_message` - Added property details for embedded `contact` object (`id`, `name`, `email`, `phone_number`) - Added `status` enum: `open`, `resolved`, `pending`, `snoozed` ### `public_message` - Fixed `id`, `message_type`, `created_at`, `conversation_id` types (string → integer where applicable) - Fixed `content_attributes` type from `string` to `object` - Added property details for `attachments` items and `sender` object - Added `file_type` and `sender.type` enums ### `public_contact` - Added missing `phone_number` field --------- Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
3af52abfc3 |
fix: patch Devise confirmable race condition vulnerability (#13843)
Devise 4.9.x has a race condition in the reconfirmable flow where concurrent email change requests can desynchronize the confirmation token from `unconfirmed_email`, letting an attacker confirm an email they don't own. We use `:confirmable` with `reconfirmable = true`, so we're directly exposed. The upstream fix is in Devise 5.0.3, but we can't upgrade — `devise-two-factor` only supports Devise 5 from v6.4.0, which also raised its Rails minimum to 7.2+. No released version supports both Devise 5 and Rails 7.1. This PR ports the Devise 5.0.3 fix locally by overriding `postpone_email_change_until_confirmation_and_regenerate_confirmation_token` on the User model to persist the record before regenerating the token. This is a stopgap — remove it once the dependency chain allows upgrading to Devise 5. ### How to test Sign in as a confirmed user and change your email. The app should send a confirmation to the new address while keeping the current email unchanged until confirmed. |
||
|
|
103160a939 | Bump version to 4.12.0 | ||
|
|
7121425ed0 |
chore: Update translations (#13832)
Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
15d0cdbf75 |
fix: return correct outgoing_url in Platform agent bot API responses (#13827)
The Platform API was returning the bot's `name` value for the `outgoing_url` field across all agent bot endpoints (index, show, create, update). A typo in the `_agent_bot.json.jbuilder` partial used `resource.name` instead of `resource.outgoing_url`. Closes #13787 ## What changed - `app/views/platform/api/v1/models/_agent_bot.json.jbuilder`: corrected `resource.name` → `resource.outgoing_url` on the `outgoing_url` field. ## How to reproduce 1. Create an agent bot via `POST /platform/api/v1/agent_bots` with a distinct `outgoing_url`. 2. Call `GET /platform/api/v1/agent_bots/:id`. 3. Before this fix the `outgoing_url` in the response equals the bot's `name`; after the fix it equals the value set at creation. ## Tests Added `outgoing_url` assertions to the existing GET index and GET show request specs so the regression is covered. |
||
|
|
270c7b893a | chore(tds-1): rake task for assignment v2 migration (#13828) | ||
|
|
286e6b6ba1 |
fix: reverse order of api_key for bg task (#13826)
# Pull Request Template ## Description we were getting 403, 401 errors on `translate_query` on langfuse and sentry This happened because, we use the customer's openai key if they have BYOK But translation is something they never opt in so we should not use their quota for it. This PR addresses the issue. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. locally ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules |
||
|
|
96db77c236 |
feat(widget): Allow widget loading in mobile app WebViews when domain restrictions are set (#13763)
When `allowed_domains` is configured on a web widget inbox, the server responds with Content-Security-Policy: frame-ancestors <domains>, which blocks the widget iframe in mobile app WebViews. This happens because WebViews load content from file:// or null origins, which cannot match any domain in the frame-ancestors directive. This adds a per-inbox toggle — "Enable widget in mobile apps" — that skips the frame-ancestors header when the request has no valid Origin (i.e., it comes from a mobile WebView). Web browsers with a real origin still get domain restrictions enforced as usual. <img width="2330" height="1490" alt="CleanShot 2026-03-11 at 10 13 01@2x" src="https://github.com/user-attachments/assets/d9326fac-020d-4ce7-9ced-0c185468c8fc" /> Fixes https://linear.app/chatwoot/issue/CW-6560/widget-is-not-loading-from-iosandroid-widgets How to test 1. Go to Settings → Inboxes → (Web Widget) → Configuration 2. Set allowed_domains to a specific domain (e.g., *.example.com) 3. Try loading the widget in a mobile app WebView — it should be blocked 4. Enable "Enable widget in mobile apps" checkbox 5. Reload the widget in the WebView — it should now load successfully 6. Verify the widget on a website not in the allowed domains list is still blocked --------- Co-authored-by: iamsivin <iamsivin@gmail.com> |
||
|
|
2255758f9b |
feat: distributed scheduling for version check job (#13042)
This change spreads Chatwoot Hub version checks across the day by scheduling each installation at a stable minute derived from its installation identifier, instead of having all instances check at the same fixed time. Closes - https://linear.app/chatwoot/issue/CW-6107/handle-the-spike-at-12-utc-on-chatwoot-hub What changed - Added `Internal::TriggerDailyScheduledItemsJob` to act as the daily trigger for deferred internal jobs. - Updated the version check cron entry to run once daily at `00:00 UTC` and enqueue the actual version check for that installation’s assigned minute of the day. - Used a deterministic minute-of-day derived from `ChatwootHub.installation_identifier` so the check time stays stable across deploys and restarts. - Kept the existing cron schedule key while switching it to the new orchestrator job. How to test - Run `bundle exec rspec spec/jobs/internal/check_new_versions_job_spec.rb spec/jobs/internal/trigger_daily_scheduled_items_job_spec.rb spec/configs/schedule_spec.rb` - In a Rails console, run `Internal::TriggerDailyScheduledItemsJob.perform_now` and verify `Internal::CheckNewVersionsJob` is enqueued with a `wait_until` later the same UTC day. - In Super Admin settings, use Refresh and verify the version check still runs immediately. --------- Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
d7cfa2f7a9 |
feat(linear): Support refresh tokens and migrate legacy OAuth tokens (#13721)
Linear is deprecating long-lived OAuth2 access tokens (valid for 10 years) in favor of short-lived access tokens with refresh tokens. Starting October 1, 2025, all new OAuth2 apps will default to refresh tokens. Linear will no longer issue long-lived access tokens. Please read more details [here](https://linear.app/developers/oauth-2-0-authentication#migrate-to-using-refresh-tokens) We currently use long-lived tokens in our Linear integration (valid for up to 10 years). To remain compatible, this PR ensures compatibility by supporting refresh-token-based auth and migrating existing legacy tokens. Fixes https://linear.app/chatwoot/issue/CW-5541/migrate-linear-oauth2-integration-to-support-refresh-tokens |
||
|
|
7a69acb19c |
feat: Add draft status for help center locales (#13768)
This adds a draft status for Help Center locales so teams can prepare localized content in the dashboard without exposing those locales in the public portal switcher until they are ready to publish. Fixes: https://github.com/chatwoot/chatwoot/issues/10412 Closes: https://github.com/chatwoot/chatwoot/issues/10412 ## Why Teams need a way to work on locale-specific Help Center content ahead of launch. The public portal should only show ready locales, while the admin dashboard should continue to expose every allowed locale for ongoing article and category work. ## What this change does - Adds `draft_locales` to portal config as a subset of `allowed_locales` - Hides drafted locales from the public portal language switchers while keeping direct locale URLs working - Keeps drafted locales fully visible in the admin dashboard for article and category management - Adds locale actions to move an existing locale to draft, publish a drafted locale, and keep the default locale protected from drafting - Adds a status dropdown when creating a locale so new locales can be created as `Published` or `Draft` - Returns each admin locale with a `draft` flag so the locale UI can reflect the public visibility state ## Validation - Seed a portal with multiple locales, draft one locale, and confirm the public portal switcher hides it while `/hc/:slug/:locale` still loads directly - In the admin dashboard, confirm drafted locales still appear in the locale list and remain selectable for articles and categories - Create a new locale with `Draft` status and confirm it stays out of the public switcher until published - Move an existing locale back and forth between `Published` and `Draft` and confirm the public switcher updates accordingly ## Demo https://github.com/user-attachments/assets/ba22dc26-c2e7-463a-b1f5-adf1fda1f9be --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> |
||
|
|
6cd67734fc |
fix: slim help center search results (#13761)
Fixes help center public article search so query responses stay compact and locale-scoped. Whitespace-only queries are now treated as empty in both the portal UI and the server-side search path, and search suggestions stay aligned with the trimmed query. Fixes: https://github.com/chatwoot/chatwoot/issues/10402 Closes: https://github.com/chatwoot/chatwoot/issues/10402 ## Why The public help center search endpoint reused the full article serializer for query responses, which returned much more data than the search suggestions UI needed. That made responses heavier than necessary and also surfaced nested portal and category data that made the results look cross-locale. Whitespace-only searches could also still reach the backend search path, and in Enterprise that meant embedding search could be invoked for a blank query. ## What changed - return a compact search-specific payload for article query responses - keep the existing full article serializer for normal article listing responses - preserve current-locale search behavior for the portal search flow - trim whitespace-only search terms on the client so they do not open suggestions or trigger a request - reuse the normalized query on the backend so whitespace-only requests are treated as empty searches in both OSS and Enterprise paths - pass the trimmed search term into suggestions so highlighting matches the actual query being sent - add request and frontend regression coverage for compact payloads, locale scoping, and whitespace-only search behavior ## Validation 1. Open `/hc/:portal/:locale` in the public help center. 2. Enter only spaces in the search box and confirm suggestions do not open. 3. Search for a real term and confirm suggestions appear. 4. Verify the results are limited to the active locale. 5. Click a suggestion and confirm it opens the correct article page. 6. Inspect the query response and confirm it returns the compact search payload instead of the full article serializer. --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> |
||
|
|
4a055d2c6b |
fix(email): Allow inbox OAuth replies without global SMTP (#13820)
Email inbox replies now work for Google and Microsoft OAuth inboxes even when the self-hosted instance does not have global SMTP configured. This keeps agent replies working for email channels that already have valid inbox-level delivery settings. fixes: chatwoot/chatwoot#13118 closes: chatwoot/chatwoot#13118 ## Why Self-hosted email inbox replies were blocked by a global SMTP guard in the `email_reply` path. For OAuth-backed email inboxes, outbound delivery is configured at the inbox level, so the mailer returned early and the reply flow failed before sending. ## What this change does - Allows the `email_reply` path to proceed when the inbox has SMTP configured - Allows the `email_reply` path to proceed when the inbox has Google or Microsoft OAuth delivery configured - Renames the touched mailer helper predicates to `?` methods for clarity ## Validation - Configure a Google email inbox on a self-hosted instance without global `SMTP_ADDRESS` - Reply from Chatwoot to an existing email conversation - Confirm the reply is sent through the inbox OAuth SMTP configuration - Run `bundle exec rspec spec/mailers/conversation_reply_mailer_spec.rb:595` --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> |
||
|
|
1b5744c2ba |
fix: upgrade rollup to 4.59.0 to remediate CVE-2026-27606 (#13781)
https://linear.app/chatwoot/issue/CW-6595/vanta-remediate-high-vulnerabilities-identified-in-packages-are ## Description - Added "rollup": ">=4.59.0" to pnpm.overrides in package.json - This bumps rollup from 4.52.5 to 4.59.0 (the transitive dep via vite) ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - Overall Sanity via UI. ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> |
||
|
|
ec9d00dd08 |
fix(i18n): improve Ukrainian widget translation (#13819)
## Description
This PR improves the Ukrainian translation for the Chatwoot widget
(`app/javascript/widget/i18n/locale/uk.json`).
Key changes:
- Fixed typo: `Звантажити` → `Завантажити`
- Translated missing English strings
- Improved reply time messages
- Updated day names to match `{day}` usage in `BACK_ON_DAY`
- Improved UX wording in form placeholders
- Fixed typography in `ім’я`
- Improved consistency with other Chatwoot translations
These updates improve readability and correctness of the Ukrainian
widget interface.
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
## How Has This Been Tested?
Reviewed the updated translations and verified that:
- Ukrainian translations render correctly
- Reply time messages display properly
- `{day}` values work correctly with the `BACK_ON_DAY` message
- Form placeholders appear correctly
- No untranslated English strings remain
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] My changes generate no new warnings
---------
Co-authored-by: Sojan Jose <sojan@pepalo.com>
|
||
|
|
401e407daf |
chore(deps): bump dompurify from 3.2.4 to 3.3.2 (#13738)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.2.4 to 3.3.2. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/cure53/DOMPurify/releases">dompurify's releases</a>.</em></p> <blockquote> <h2>DOMPurify 3.3.2</h2> <ul> <li>Fixed a possible bypass caused by jsdom's faulty raw-text tag parsing, thanks multiple reporters</li> <li>Fixed a prototype pollution issue when working with custom elements, thanks <a href="https://github.com/christos-eth"><code>@christos-eth</code></a></li> <li>Fixed a lenient config parsing in <code>_isValidAttribute</code>, thanks <a href="https://github.com/christos-eth"><code>@christos-eth</code></a></li> <li>Bumped and removed several dependencies, thanks <a href="https://github.com/Rotzbua"><code>@Rotzbua</code></a></li> <li>Fixed the test suite after bumping dependencies, thanks <a href="https://github.com/Rotzbua"><code>@Rotzbua</code></a></li> </ul> <h2>DOMPurify 3.3.1</h2> <ul> <li>Updated <code>ADD_FORBID_CONTENTS</code> setting to extend default list, thanks <a href="https://github.com/MariusRumpf"><code>@MariusRumpf</code></a></li> <li>Updated the ESM import syntax to be more correct, thanks <a href="https://github.com/binhpv"><code>@binhpv</code></a></li> </ul> <h2>DOMPurify 3.3.0</h2> <ul> <li>Added the SVG <code>mask-type</code> attribute to default allow-list, thanks <a href="https://github.com/prasadrajandran"><code>@prasadrajandran</code></a></li> <li>Added support for <code>ADD_ATTR</code> and <code>ADD_TAGS</code> to accept functions, thanks <a href="https://github.com/nelstrom"><code>@nelstrom</code></a></li> <li>Fixed an issue with the <code>slot</code> element being in both SVG and HTML allow-list, thanks <a href="https://github.com/Wim-Valgaeren"><code>@Wim-Valgaeren</code></a></li> </ul> <h2>DOMPurify 3.2.7</h2> <ul> <li>Added new attributes and elements to default allow-list, thanks <a href="https://github.com/elrion018"><code>@elrion018</code></a></li> <li>Added <code>tagName</code> parameter to custom element <code>attributeNameCheck</code>, thanks <a href="https://github.com/nelstrom"><code>@nelstrom</code></a></li> <li>Added better check for animated <code>href</code> attributes, thanks <a href="https://github.com/llamakko"><code>@llamakko</code></a></li> <li>Updated and improved the bundled types, thanks <a href="https://github.com/ssi02014"><code>@ssi02014</code></a></li> <li>Updated several tests to better align with new browser encoding behaviors</li> <li>Improved the handling of potentially risky content inside CDATA elements, thanks <a href="https://github.com/securityMB"><code>@securityMB</code></a> & <a href="https://github.com/terjanq"><code>@terjanq</code></a></li> <li>Improved the regular expression for raw-text elements to cover textareas, thanks <a href="https://github.com/securityMB"><code>@securityMB</code></a> & <a href="https://github.com/terjanq"><code>@terjanq</code></a></li> </ul> <h2>DOMPurify 3.2.6</h2> <ul> <li>Fixed several typos and removed clutter from our documentation, thanks <a href="https://github.com/Rotzbua"><code>@Rotzbua</code></a></li> <li>Added <code>matrix:</code> as an allowed URI scheme, thanks <a href="https://github.com/kleinesfilmroellchen"><code>@kleinesfilmroellchen</code></a></li> <li>Added better config hardening against prototype pollution, thanks <a href="https://github.com/EffectRenan"><code>@EffectRenan</code></a></li> <li>Added better handling of attribute removal, thanks <a href="https://github.com/michalnieruchalski-tiugo"><code>@michalnieruchalski-tiugo</code></a></li> <li>Added better configuration for aggressive mXSS scrubbing behavior, thanks <a href="https://github.com/BryanValverdeU"><code>@BryanValverdeU</code></a></li> <li>Removed the script that caused the fake entry <a href="https://security.snyk.io/vuln/SNYK-JS-DOMPURIFY-10176060">CVE-2025-48050</a></li> </ul> <h2>DOMPurify 3.2.5</h2> <ul> <li>Added a check to the mXSS detection regex to be more strict, thanks <a href="https://github.com/masatokinugawa"><code>@masatokinugawa</code></a></li> <li>Added ESM type imports in source, removes patch function, thanks <a href="https://github.com/donmccurdy"><code>@donmccurdy</code></a></li> <li>Added script to verify various TypeScript configurations, thanks <a href="https://github.com/reduckted"><code>@reduckted</code></a></li> <li>Added more modern browsers to the Karma launchers list</li> <li>Added Node 23.x to tested runtimes, removed Node 17.x</li> <li>Fixed the generation of source maps, thanks <a href="https://github.com/reduckted"><code>@reduckted</code></a></li> <li>Fixed an unexpected behavior with <code>ALLOWED_URI_REGEXP</code> using the 'g' flag, thanks <a href="https://github.com/hhk-png"><code>@hhk-png</code></a></li> <li>Fixed a few typos in the README file</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/cure53/DOMPurify/commit/5e56114cb24079ce52dbc51f76e494b77afa5153"><code>5e56114</code></a> Getting 3.x branch ready for 3.3.2 release (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1208">#1208</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/e8c95f4a27aa8b041f92b59ab7685a94f7be6208"><code>e8c95f4</code></a> fix: Fixed the broken package-lock.json</li> <li><a href="https://github.com/cure53/DOMPurify/commit/9636037c145b769dad0b52da8313301cbf867f46"><code>9636037</code></a> Update package-lock.json</li> <li><a href="https://github.com/cure53/DOMPurify/commit/5cad4cecf2e647ac66eed25bc02a2415f00dbc8b"><code>5cad4ce</code></a> Getting 3.x branch ready for 3.3.2 releas (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1205">#1205</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/6fc446a589ab3d1d72ae2a5b71167ba38dbd3096"><code>6fc446a</code></a> Merge pull request <a href="https://redirect.github.com/cure53/DOMPurify/issues/1175">#1175</a> from cure53/main</li> <li><a href="https://github.com/cure53/DOMPurify/commit/3b3bf917d2b39460de6d130acebdc9243cf3e6ae"><code>3b3bf91</code></a> Merge branch 'main' of github.com:cure53/DOMPurify</li> <li><a href="https://github.com/cure53/DOMPurify/commit/9863f4195bae6048de9eb2802219218c6904066c"><code>9863f41</code></a> chore: Preparing 3.3.1 release</li> <li><a href="https://github.com/cure53/DOMPurify/commit/b4e02954dc4172c3944a755f3e99fbb76be64f7b"><code>b4e0295</code></a> chore: Preparing 3.3.0 release</li> <li><a href="https://github.com/cure53/DOMPurify/commit/077746bb2cfb77836dfb628dca7ffc7ced8a5356"><code>077746b</code></a> build(deps-dev): bump js-yaml from 4.1.0 to 4.1.1 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1170">#1170</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/4de68bba9aba43dc3bba9348df603b64fc06d591"><code>4de68bb</code></a> build(deps): bump actions/checkout from 5 to 6 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1171">#1171</a>)</li> <li>Additional commits viewable in <a href="https://github.com/cure53/DOMPurify/compare/3.2.4...3.3.2">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/chatwoot/chatwoot/network/alerts). </details> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Shivam Mishra <scm.mymail@gmail.com> Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
18340ad6b2 |
fix(i18n): complete zh_TW locale coverage (#13792)
This updates the Traditional Chinese (`zh_TW`) locale coverage across Chatwoot so the app no longer falls back to English for missing backend, dashboard, widget, and survey strings. ## How to test 1. Start Chatwoot locally and switch the UI locale to Traditional Chinese (`zh_TW`). 2. Walk through the main product areas: dashboard, settings, inbox management, help center, automations, reports, widget, and survey flows. 3. Confirm the UI surfaces translated Traditional Chinese copy instead of English fallbacks. 4. Spot-check newly added locale surfaces such as secure password messaging and snooze UI copy. --------- Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
9947efa881 |
feat: Bulgarian locale updates(#13635)
Bulgarian locale updates |
||
|
|
ea6331d73e |
feat(i18n): complete Korean (ko) translations to 100% coverage (#13583)
Translate all English strings to Korean across 41 frontend locale files and 2 backend locale files. Add structurally missing keys and translate existing keys that were left in English. # Pull Request Template ## Description Please include a summary of the change and issue(s) fixed. Also, mention relevant motivation, context, and any dependencies that this change requires. Fixes # (issue) ## Type of change Please delete options that are not relevant. - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality not to work as expected) - [ ] This change requires a documentation update ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
92e8e8e90f |
chore(i18n): update Russian translations (#13405)
# Pull Request Template ## Description Updated few i18n files to: 1. fix typos / grammar / punctuation 2. translate strings that were still in english 3. add missing keys ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? i18n change, the format remained the same. ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
c37ed53bb9 |
chore: Update translations (#13227)
Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
95490d089e |
fix: skip captain auto-open for templates (#13802)
# Pull Request Template ## Description WhatsApp template messages are treated as outgoing human messages so conversations are automatically marked Open, preventing Captain from responding. #13673 This PR fixes the behaviour for template messages, so that captain can respond to them. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules |
||
|
|
7071abfe3f |
fix: Correct reversed message status indicators for API channel (#13594)
## Description Fixes the reversed message delivery status indicators for the API channel. The API inbox was grouped with the web widget inbox in the `isDelivered` computed property, causing both to treat a `sent` status as `delivered`. Since the API channel provides real `sent`/`delivered`/`read` status values from external systems (unlike the web widget which has no separate delivery confirmation), the API inbox needs its own handling. **Before this fix:** - Status `sent` (0) → incorrectly showed delivered checkmarks - Status `delivered` (1) → incorrectly showed "Sending" spinner **After this fix:** - Status `sent` → correctly shows sent indicator (single checkmark) - Status `delivered` → correctly shows delivered indicator (double checkmarks) - Status `read` → unchanged (already worked correctly) The web widget inbox behavior is unchanged — it still treats `sent` as `delivered` since it lacks a separate delivery confirmation mechanism. Fixes #13576 ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? Verified by code review that the computed properties now correctly map API channel message statuses: - `isSent` returns `true` when `status === 'sent'` for API inbox - `isDelivered` returns `true` when `status === 'delivered'` for API inbox - `isRead` unchanged — already checks `status === 'read'` for API inbox - Web widget inbox logic is unchanged ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [x] My changes generate no new warnings *This PR was created with the assistance of Claude Opus 4.6 by Anthropic. Happy to make any adjustments! Reviewed and submitted by a human.* Co-authored-by: Your Name <your-email@example.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> |
||
|
|
23e44d73c1 |
feat: trigger assignment on resolve (#13780)
## Description When an agent resolves or snoozes a conversation, their capacity frees up — but under Assignment V2, no new conversation was assigned until the next event triggered the assignment job. This meant agents could sit idle despite having queued conversations waiting. This change triggers the AssignmentJob immediately on resolve/snooze so freed capacity is utilized right away. ## Type of change - [ ] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? - Enable auto assignment v2 on an inbox - Create a conversation (gets auto-assigned to an available agent) - Resolve the conversation - Verify that another unassigned conversation in the inbox gets assigned to the freed-up agent ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: tds-1 <tds-1@users.noreply.github.com> |
||
|
|
32b41024b5 |
feat(whatsapp): add webhook registration and status endpoints (#13551)
## Description Adds webhook configuration management for WhatsApp Cloud API channels, allowing administrators to check webhook status and register webhooks directly from Chatwoot without accessing Meta Business Manager. ## Type of change - [ ] New feature (non-breaking change which adds functionality) ## Screenshots <img width="1130" height="676" alt="Screenshot 2026-03-05 at 7 04 18 PM" src="https://github.com/user-attachments/assets/f5dcd9dd-8827-42c5-a52b-1024012703c2" /> <img width="1101" height="651" alt="Screenshot 2026-03-05 at 7 04 29 PM" src="https://github.com/user-attachments/assets/e0bd59f9-2a90-4f24-87c0-b79f21e721ee" /> ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> |
||
|
|
5004cf86dc |
fix: upgrade markdown-it to 14.1.1 to remediate CVE-2026-2327 (#13782)
## Linear tickets - https://linear.app/chatwoot/issue/CW-6607/vanta-remediate-medium-vulnerabilities-identified-in-packages-are - https://linear.app/chatwoot/issue/CW-6612/vanta-remediate-medium-vulnerabilities-identified-in-packages-are ## Description Upgrades markdown-it from 13.0.2 to 14.1.1 to remediate CVE-2026-2327 ## Type of change Please delete options that are not relevant. - [ ] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - Sanity testing of golden flows via UI ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules |
||
|
|
91b1e59cb2 |
feat: update bunny video support in HC (#13815)
Bunny Video has added a new URL player.mediadelivery.net, this PR adds support for the new URL |
||
|
|
0c28413fc0 |
feat: Add force legacy auto-resolve flag (#13804)
# Pull Request Template ## Description Add account setting and store_accessor for `captain_force_legacy_auto_resolve`. Enterprise job now skips LLM evaluation when this flag is true and falls back to legacy time-based resolution. Add spec to cover the fallback. ## Type of change We recently rolled out Captain deciding if a conversation is resolved or not. While it is an improvement for majority of customers, some still prefer the old way of auto-resolving based on inactivity. This PR adds a check. ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. legacy_auto_resolve = true <img width="1282" height="848" alt="CleanShot 2026-03-13 at 19 55 55@2x" src="https://github.com/user-attachments/assets/dfdcc5d5-6d21-462b-87a6-a5e1b1290a8b" /> legacy_auto_resolve = false <img width="1268" height="864" alt="CleanShot 2026-03-13 at 20 00 50@2x" src="https://github.com/user-attachments/assets/f4719ec6-922a-4c3b-bc45-7b29eaced565" /> ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules |
||
|
|
1f043cd6c1 |
fix: Delete double hmac check (#12464)
## Description When hmac identity check is enabled according to [this](https://www.chatwoot.com/hc/user-guide/articles/1677587479-how-to-enable-identity-validation-in-chatwoot) I found out, that it checked twice. If `should_verify_hmac? -> true` then hmac checked in `before_action` and we don't need to do it again later. This perfomance related and PR fixes this. |
||
|
|
040a456113 |
fix: prefer system API key for completion service (#13799)
# Pull Request Template ## Description Add an api_key override so internal conversation completions prefers using the system API key and do not consume customer OpenAI credits. ## Type of change Please delete options that are not relevant. - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. specs and locally ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules |
||
|
|
ed8bd83a44 |
fix: restrict existing user sign-in to account members (#13793)
SAML sign-in now only links an existing user when that user already belongs to the account that initiated SSO. New users can still be created for SAML-enabled accounts, and invited members can continue to sign in through their IdP, but SAML will no longer auto-attach an unrelated existing user record during login. **What changed** - Added an account-membership check before SAML reuses an existing user by email. - Kept first-time SAML user creation unchanged for valid new users. - Added builder and request specs covering the allowed and rejected login paths. |
||
|
|
cfcbb396c4 |
fix: skip Enter key submission during IME composition in AI inputs (#13779)
# Pull Request Template ## Description CJK language users (Chinese, Japanese, Korean, etc.) use IME where Enter confirms character selection. AI input components were intercepting Enter unconditionally, making them unusable for IME users. Add `event.isComposing` check to CopilotEditor, CopilotInput, and AssistantPlayground so Enter during active IME composition is ignored. ## Type of change Please delete options that are not relevant. - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Before: Add a Japenese keyboard, then go to AI follow-ups, type some word, selecting it with enter submits the follow up. So CJK users cannot use follow-ups. https://github.com/user-attachments/assets/53517432-d97b-47fc-a802-81675e31d5c9 After: Type a word, press enter to choose it, press enter again to unselect it and enter again to send https://github.com/user-attachments/assets/6c2a420b-7ee6-4c71-82a6-d9f1d7bbf31a ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
b179082342 |
feat: captain decides if conversation should be resolved or kept open (#13336)
# Pull Request Template ## Description captain decides if conversation should be resolved or open Fixes https://linear.app/chatwoot/issue/AI-91/make-captain-resolution-time-configurable Update: Added 2 entries in reporting events: `conversation_captain_handoff` and `conversation_captain_resolved` ## Type of change Please delete options that are not relevant. - [x] New feature (non-breaking change which adds functionality) - [x] This change requires a documentation update ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. LLM call decides that conversation is resolved, drops a private note <img width="1228" height="438" alt="image" src="https://github.com/user-attachments/assets/fb2cf1e9-4b2b-458b-a1e2-45c53d6a0158" /> LLM call decides conversation is still open as query was not resolved <img width="1215" height="573" alt="image" src="https://github.com/user-attachments/assets/2d1d5322-f567-487e-954e-11ab0798d11c" /> ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
1d5a51bf82 |
fix: Skip redundant contact saves in ContactIdentifyAction (#13778)
When the SDK sends identify calls with identical payloads (common on every page load), `save!` fires even though no attributes changed. While Rails skips the actual UPDATE SQL, it still opens a transaction, runs all callbacks (including validation queries like `Contact Exists?`), and triggers `after_commit` hooks — all for a no-op. This adds a `changed?` guard before `save!` to skip it entirely when no attributes have actually changed. **How to test** - Trigger an identify call via the SDK with a contact's existing attributes (same name, email, custom_attributes, etc.) - The contact should not fire a save (no transaction, no callbacks) - Trigger an identify call with a changed attribute — save should work normally **What changed** - `ContactIdentifyAction#update_contact`: guard `save!` with `changed?` check - Added specs to verify `save!` is skipped for unchanged params and avatar job still enqueues independently |
||
|
|
73cb559f23 |
chore: Remove message touch:true, use combined update query (#13770)
Removes touch: true from the belongs_to :conversation association on Message and consolidates the conversation timestamp update into the existing set_conversation_activity callback. Previously, every message save triggered two separate UPDATE queries on the conversation — one from Rails' touch (updating updated_at) and another from set_conversation_activity (updating last_activity_at). This combines both into a single update_columns call, reducing write load on the conversations table on every message creation. ### What changed - Removed touch: true from belongs_to :conversation in Message - Added updated_at: created_at to the existing update_columns call in set_conversation_activity |
||
|
|
21e32e384d |
fix: override minimatch to patch ReDoS vulnerability (#13769)
## Description Remediates high severity ReDoS vulnerability in minimatch (CVE-2026-27903) flagged by Vanta/Dependabot. minimatch is a transitive dev-only dependency (via eslint and tailwindcss build tooling) — not shipped to production. Added pnpm overrides to force patched versions: - minimatch@<4 → 3.1.5 - minimatch@>=9.0.0 <9.0.7 → 9.0.9 Closes: https://linear.app/chatwoot/issue/CW-6595/vanta-remediate-high-vulnerabilities-identified-in-packages-are ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - No production impact — minimatch is only used in dev tooling, not at runtime - pnpm install completes successfully ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules |
||
|
|
8d21c7f2a5 |
fix: Add fix to only allow confirmed agents to used in Agent Assingments at Macros/Automations (#13225)
# Pull Request Template ## Description Unconfirmed agents (pending email verification) were incorrectly appearing in the "assign agent" dropdown for macros and automations. This fix filters out unconfirmed agents from these dropdowns and adds backend validation to prevent assignment of unconfirmed agents. Fixes #13223 ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? **Backend tests:** ```bash docker compose run --rm rails bundle exec rspec spec/services/action_service_spec.rb ``` - Added tests for confirmed agent assignment (should succeed) - Added tests for unconfirmed agent assignment (should be skipped) **Frontend tests:** ```bash docker compose run --rm rails pnpm test app/javascript/dashboard/composables/spec/useMacros.spec.js ``` - Updated mocks to use `getVerifiedAgents` getter **Manual testing:** 1. Create an unconfirmed agent via platform 2. Navigate to Settings → Macros → New Macro → Add "Assign Agent" action 3. Verify unconfirmed agent does NOT appear in dropdown 4. Navigate to Settings → Automations → New Automation → Add "Assign Agent" action 5. Verify unconfirmed agent does NOT appear in dropdown ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
e0dc14899e |
fix: playground captain v2 scenarios (#13747)
# Pull Request Template ## Description Playground now uses v2. It was only wired to use v1. Traces get `source: playground` on langfuse when playground has been used. ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. locally and specs <img width="1806" height="1276" alt="image" src="https://github.com/user-attachments/assets/41ef4eb3-52b1-4b8e-9a4f-e8510c90cb39" /> ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules |
||
|
|
90eb12ef31 |
fix: Use handoff_key for scenarios (#13755)
# Pull Request Template
## Description
Ensure agent function names stay within OpenAI's 64-char limit
(ai-agents prepends "handoff_to_").
Add HANDOFF_TITLE_SLUG_MAX_LENGTH and
handoff_key generation: persisted records use `scenario_{id}_agent`; new
records use a truncated title slug.
Assistant scenario keys and agent_name now reference the generated
handoff key.
fixes :
`Invalid 'messages[9].tool_calls[0].function.name': string too long.
Expected a string with maximum length 64, but got a string with length
95 instead.`
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
## How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide
instructions so we can reproduce. Please also list any relevant details
for your test configuration.
Tested locally
<img width="1806" height="1044" alt="image"
src="https://github.com/user-attachments/assets/40cd7a3d-3d97-43a8-bd56-d3f5d63abbda"
/>
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules
---------
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
|
||
|
|
77b17ff3e7 |
feat: make assignment_v2 feature available to all accounts (#13764)
## Description Makes the assignment_v2 feature flag available to all installations by removing the chatwoot_internal restriction. Previously this feature was hidden from self-hosted installations; this change surfaces it in the feature flags UI so any Chatwoot instance can enable it. ## Type of change - [ ] New feature (non-breaking change which adds functionality) ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules |