Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
795 commits
Select commit Hold shift + click to select a range
430c5cf
fix(whatsapp): refresh inboxes when opening new conversation composer…
tds-1 Aug 6, 2026
696d2a5
fix: add default names to data imports (#15345)
sony-mathew Aug 6, 2026
17d9275
fix: block the unused Active Storage direct-upload route (#15329)
vishnu-narayanan Aug 6, 2026
240aca1
fix: keep bulk action bar on a single line for longer translations (#…
iamsivin Aug 6, 2026
cefb3fe
fix(voice): sync inbound WhatsApp call accept state across tabs (#15326)
tds-1 Aug 6, 2026
473ac39
feat: nudge users with a dashboard banner when backup codes run low (…
tds-1 Aug 6, 2026
e3e35ab
feat: enable data imports for paid plans (#15346)
sony-mathew Aug 6, 2026
0df9508
fix(security): keep inbox access filtering on the participating scope…
tds-1 Aug 6, 2026
834e9a4
fix(whatsapp): correctly sync Twilio template approval status (#15353)
muhsin-k Aug 7, 2026
0f3bb64
feat(captain): Add audience and schedule controls for assistants (#14…
pranavrajs Aug 7, 2026
c8e95ef
fix(whatsapp): return empty template arrays for malformed inbox data …
muhsin-k Aug 7, 2026
f770c58
fix: prevent vertical tab labels from overlapping (#15363)
iamsivin Aug 7, 2026
35a5f33
feat: update status on agent bot assignment (#14870)
sojan-official Aug 7, 2026
f125291
fix: align AgentBot ownership with conversation counts (#15343)
sojan-official Aug 7, 2026
a4eae97
test: Add focused Captain response lifecycle logs (#15364)
aakashb95 Aug 9, 2026
81fc35e
chore: upgrade Rails to 7.2.3.1 (#13437)
sony-mathew Aug 10, 2026
9a9c884
feat(whatsapp): improve template listing controls (#15377)
muhsin-k Aug 10, 2026
bdbbaa3
feat(captain): add inactivity timer backend (2/5) (#15303)
aakashb95 Aug 10, 2026
cce94aa
chore: rework the canned response picker with search and preview (#15…
iamsivin Aug 10, 2026
972b692
refactor(saml): harden multi-account user handling (#15395)
scmmishra Aug 10, 2026
9a9be2f
chore: Update translations (#15355)
chatwoot-bot Aug 10, 2026
c70c87c
fix(widget): correct Hebrew availability card (#15405)
sojan-official Aug 11, 2026
66067a1
fix(inboxes): show facebook inbox creation errors (#15408)
muhsin-k Aug 11, 2026
2fbcc71
fix: conversations hidden when filtering by a date range (#15385)
iamsivin Aug 11, 2026
406eb8f
feat(automation): allow send email transcript action to target the co…
tds-1 Aug 11, 2026
1693525
fix(captain): scope copilot conversation access (#15249)
aakashb95 Aug 11, 2026
0a2293f
feat: record Captain conversation outcome episodes from lifecycle eve…
scmmishra Aug 11, 2026
875ea6e
fix(auth): persist MFA sessions across browser restarts (#15379)
scmmishra Aug 11, 2026
e6f21f7
perf: scale sidekiq worker MemoryMax with host memory (#15412)
vishnu-narayanan Aug 11, 2026
7cba8a0
feat: add search to filter dropdowns and group attributes (#15348)
iamsivin Aug 11, 2026
3f4d28f
feat: add search and preview to the mention, variable and emoji picke…
iamsivin Aug 11, 2026
a4ce4b1
fix(contacts): enqueue avatar sync after commit (#15402)
muhsin-k Aug 12, 2026
eaecc43
fix: search returning 500 when a conversation has no messages (#15328)
marcoazcabral Aug 12, 2026
10ea370
chore(deps): bump dompurify from 3.4.11 to 3.4.13 (#15370)
dependabot[bot] Aug 12, 2026
8842c71
fix: Handle NUL bytes in canned response search (#15397)
sony-mathew Aug 12, 2026
07352f5
chore(deps): bump lettersanitizer from 1.0.6 to 1.0.8 (#14959)
bfontaine Aug 12, 2026
7ed7bdc
fix: close editor pickers when the composer state is rebuilt (#15396)
iamsivin Aug 12, 2026
8397fa7
fix: include account_id in FCM push payload (#15260)
devi-r Aug 12, 2026
5a02616
fix: inline editor in the contact sidebar clips longer values (#15403)
iamsivin Aug 12, 2026
541f91a
fix: allow resizing the reply editor while a Copilot suggestion is ac…
iamsivin Aug 12, 2026
79405f7
feat(whatsapp): display click-to-chat ad referrals (#15424)
muhsin-k Aug 12, 2026
a24f5a3
fix: anchor contact phone number validation (#15415)
scmmishra Aug 12, 2026
1e17cbe
feat(voice): transcribe Twilio call recordings (#15241)
tds-1 Aug 12, 2026
121b743
fix: scope Captain assistant responses to account (#15386)
aakashb95 Aug 12, 2026
a47eb37
feat(captain): add advanced inactivity policy backend (4/5) (#15306)
aakashb95 Aug 12, 2026
f9cdfe0
fix: Use dark text on amber solid buttons so the disabled Add Note bu…
limehawk Aug 12, 2026
d310e2c
chore(deps-dev): bump postcss from 8.4.47 to 8.5.23 (#15380)
dependabot[bot] Aug 12, 2026
958fc37
fix(conversation): refactor layout utilities to logical properties fo…
khushhhhh Aug 12, 2026
42ca090
fix(editor): handle parenthesized ordered list markers (#15362)
rekurt Aug 12, 2026
adef9f2
fix: Alt+E resolve shortcut also opens Chrome's built-in menu on Wind…
vjymisal0 Aug 12, 2026
3453e29
chore: land super admin on dashboard after login (#15411)
vishnu-narayanan Aug 13, 2026
10e9cb5
fix(whatsapp): load health status for regional locales (#15440)
muhsin-k Aug 13, 2026
046c6c7
fix(messages): resend failed messages through provider (#15432)
muhsin-k Aug 13, 2026
590e17d
chore: remove the legacy notifications page (#15426)
iamsivin Aug 13, 2026
2ed68cf
feat: cache canned responses in the browser (#15401)
iamsivin Aug 13, 2026
1d905fb
fix: anchor Label title validation with \z instead of \Z (#15443)
suparikoli Aug 13, 2026
13dfe1a
feat: run macros from the reply editor with `#` (#15416)
iamsivin Aug 13, 2026
416ac86
fix: fit the reply editor to Copilot suggestions (#15428)
iamsivin Aug 13, 2026
4587892
feat: run macros from the command bar (#15422)
iamsivin Aug 13, 2026
b24a970
fix: allow multi-digit values in duration inputs (#15429)
aakashb95 Aug 13, 2026
eff7ce2
fix: consolidate customer message bursts before lookup (#15263)
aakashb95 Aug 13, 2026
13de83d
refactor(captain): route conversation completion by feature (#15317)
aakashb95 Aug 13, 2026
ba1973e
fix: escape formula characters in CSAT CSV export (#15335)
vishnu-narayanan Aug 13, 2026
8a778f4
fix: handle empty round robin queues (#15399)
sony-mathew Aug 13, 2026
dd20343
fix: reject malformed filter payloads (#15398)
sony-mathew Aug 13, 2026
b3a1dbc
fix: oversized message cursors (#15400)
sony-mathew Aug 13, 2026
8864f80
feat(captain): show document conversation usage (#15140)
aakashb95 Aug 13, 2026
a929955
fix: escape formula characters in contact CSV export (#15334)
vishnu-narayanan Aug 13, 2026
40f5381
feat: add Captain outcome reporting builders (#15425)
scmmishra Aug 13, 2026
fefa0a6
perf: add composite index for account-scoped conversation created_at …
vishnu-narayanan Aug 13, 2026
59942e6
fix: inbox contact sidebar overflow (#15470)
scmmishra Aug 13, 2026
9a73c14
feat: add icons to macro and automation dropdowns (#15447)
iamsivin Aug 14, 2026
e52a731
fix(voice): sync Twilio call accept/end state across tabs (#15413)
tds-1 Aug 17, 2026
c6c34ae
feat(whatsapp): show ad referral card for CTWA leads (#14466)
propiter Aug 17, 2026
8ee2c7f
feat(campaigns): track whatsapp campaign delivery analytics (#15276)
muhsin-k Aug 17, 2026
3d3838a
fix: broken previews and empty rows in contact history (#15478)
iamsivin Aug 17, 2026
d7e49c3
fix: prevent duplicate results in paginated search (#15446)
vishnu-narayanan Aug 17, 2026
8d263a0
fix: restore Rails 7.2 schema dumps (#15500)
sony-mathew Aug 17, 2026
4eb3c77
fix(twilio): retry transient whatsapp media downloads (#15499)
muhsin-k Aug 17, 2026
c58d7a6
revert(twilio): restore media downloads after redirect regression (#1…
muhsin-k Aug 17, 2026
89a933f
refactor(reports): migrate charts to `@chatwoot/viz` (#15458)
scmmishra Aug 17, 2026
c8492c1
feat(campaigns): add whatsapp campaign analytics UI (#15369)
muhsin-k Aug 18, 2026
725df66
feat: expose Captain outcome statistics (#15481)
scmmishra Aug 18, 2026
20828cc
feat: add resend confirmation email action in super admin (#15383)
vishnu-narayanan Aug 18, 2026
df9e5c4
fix: treat empty labels as absent in filters (#15510)
scmmishra Aug 18, 2026
90acfa1
fix: Surface inline-marked email images as regular attachments when t…
mvanhorn Aug 18, 2026
7705be5
fix(twilio): safely retry redirected media downloads (#15504)
muhsin-k Aug 18, 2026
61a03ef
feat: publish Sidekiq queue metrics to CloudWatch for autoscaling (#1…
vishnu-narayanan Aug 18, 2026
59442e5
feat: support internal feature model overrides (#15460)
aakashb95 Aug 18, 2026
69f3238
fix(captain): apply V2 assistant behavior to Copilot reply suggestion…
aakashb95 Aug 18, 2026
25da7dc
chore: migrate pico-search package (#15514)
scmmishra Aug 18, 2026
41051ad
fix(campaigns): clarify pending whatsapp campaign statuses (#15518)
muhsin-k Aug 19, 2026
8d93d69
feat: audit log filtering, search and sort (#15479)
vishnu-narayanan Aug 19, 2026
02593b6
chore: bump mail gem to 2.9.1 (#15522)
vishnu-narayanan Aug 19, 2026
2d17397
fix(security): scope conversation source_id lookup to the current acc…
vishnu-narayanan Aug 19, 2026
6ca3423
fix(conversations): emit conversation.opened when legacy auto assignm…
tds-1 Aug 19, 2026
b811878
fix: Read API version from installation config (#14937)
pranavrajs Aug 19, 2026
ac37bbc
fix: keep super admin user action buttons on one row (#15515)
vishnu-narayanan Aug 19, 2026
9849d74
fix: localize friendly email sender names (#15459)
sony-mathew Aug 19, 2026
c11c1b7
fix: dropdown clipping and condition label in automation rules (#15503)
iamsivin Aug 19, 2026
5157407
fix(security): render identity labels as plain text (#15525)
muhsin-k Aug 19, 2026
1780e8f
fix: prevent reopening resolved conversations from widget (#15529)
iamsivin Aug 19, 2026
c2f98d8
Bump version to 4.17.0
sojan-official Aug 19, 2026
b34f5b7
Merge branch 'release/4.17.0'
sojan-official Aug 19, 2026
9486c5d
Merge branch 'release/4.17.0' into develop
sojan-official Aug 19, 2026
3eab288
chore: clean up resolved conversation guard in widget (#15535)
iamsivin Aug 20, 2026
2dce6c0
refactor: generate Captain reasoning before responses (#15532)
aakashb95 Aug 20, 2026
41ce45b
fix: include conversation labels in Captain state (#15531)
aakashb95 Aug 20, 2026
3fe2b43
fix(sdk): refresh users when contact details change (#15538)
scmmishra Aug 20, 2026
b493596
fix(dev): keep tunnel vite watcher running (#15539)
muhsin-k Aug 20, 2026
6b24cf8
refactor: add unified AI assignee association (#15419)
sojan-official Aug 21, 2026
ed230f9
fix: skip self-hosted Captain usage tracking (#15465)
aakashb95 Aug 21, 2026
6154aeb
fix(captain): set cloud mode in reply suggestion specs (#15560)
sojan-official Aug 22, 2026
f3f06b9
feat(perf): reduce sdk.js bundle size (#15381)
scmmishra Aug 24, 2026
a8efc71
feat(captain): redesign assistant overview dashboard (#15516)
scmmishra Aug 24, 2026
02ae3fe
perf: batch sign-in and sign-out audit inserts (#15572)
vishnu-narayanan Aug 24, 2026
389aca3
perf: avoid per-membership queries in user auth payload (#15570)
vishnu-narayanan Aug 24, 2026
eef8f13
fix: reassign calls when merging contacts to prevent orphaned records…
AdityaAudi Aug 24, 2026
6a0bc5b
fix(facebook): compare echo app_id as strings to detect Chatwoot-sent…
jaroenchai-t Aug 24, 2026
f35d2f8
docs: document message read status APIs for API channels (#15469)
vishnu-narayanan Aug 24, 2026
aaf9848
fix(instagram): restore business login authorization (#15575)
muhsin-k Aug 24, 2026
99a25ab
fix: automation rule content filter incorrectly splits on commas (#13…
williambsm9 Aug 25, 2026
4a63be9
feat(whatsapp): make account health easier to understand (#15550)
muhsin-k Aug 27, 2026
edada02
Bump version to 4.17.1
sony-mathew Aug 27, 2026
b354a95
Merge branch 'release/4.17.1'
sony-mathew Aug 27, 2026
b18ddc0
Merge branch 'release/4.17.1' into develop
sony-mathew Aug 27, 2026
4875ddc
feat(inboxes): expose channel identifiers (#15527)
sony-mathew Aug 27, 2026
57f0800
chore: show exact date on timestamp hover (#15410)
iamsivin Aug 27, 2026
4d44847
chore: remove Captain V2 rollout eligibility marker (#15599)
aakashb95 Aug 27, 2026
5726230
feat: add Captain scenario and tool toggles (#15571)
sony-mathew Aug 27, 2026
ac17485
fix: remove extra punctuation from participant copy (#15058)
sojan-official Aug 27, 2026
a4a9508
feat(inboxes): display channel identifiers (#15528)
sony-mathew Aug 27, 2026
50aff71
feat(slack): add alerts only mode for the Slack integration (#15605)
pranavrajs Aug 28, 2026
bdde38b
feat(llm): include conversation created time in LLM text format (#15145)
pranavrajs Aug 28, 2026
7419fa5
fix(conversations): seed message thread by highest id so CSAT survey …
muhsin-k Aug 28, 2026
e7bbc82
fix: prevent greeting messages from firing on activity events (#3657)…
williambsm9 Aug 28, 2026
8b1e08f
fix(security): scope SMS media download credentials to the provider h…
vishnu-narayanan Aug 28, 2026
8e3d510
feat: add conditions to delayed automations (#15472)
aakashb95 Aug 28, 2026
f8e1655
fix(security): fetch non-provider SMS media through the safe fetcher …
vishnu-narayanan Aug 28, 2026
b7d857d
fix(secutiy): verify Slack webhook request signatures (#15480)
vishnu-narayanan Aug 28, 2026
180321a
fix(inboxes): hide opaque social identifiers (#15611)
sony-mathew Aug 28, 2026
7f029b6
fix: render team metadata for agent bot requests (#15612)
sojan-official Aug 28, 2026
642223f
feat: add Captain conversation assignment (#15421)
sojan-official Aug 29, 2026
0c0ab96
fix(whatsapp): remux call recordings to ogg so files carry a duration…
tds-1 Aug 31, 2026
11ecd7a
fix(whatsapp): keep conversations on the active BSUID identity (#15175)
marcoazcabral Aug 31, 2026
186fba5
chore: format hover timestamps in the user's locale (#15600)
iamsivin Aug 31, 2026
56e533c
fix(messages): prevent out-of-order webhook status regressions (#14149)
pedrolis Aug 31, 2026
b938893
fix: Handle Telegram callback queries and acknowledge inline callback…
radaloshara Aug 31, 2026
9d51dae
fix: moved learn more hyperlink below the description (#15627)
iamsivin Aug 31, 2026
c086fe8
feat(whatsapp): add guided manual inbox setup (#15079)
muhsin-k Aug 31, 2026
5ea936e
fix(inboxes): hide Facebook and X identifiers (#15628)
sony-mathew Aug 31, 2026
6595292
fix(whatsapp): preserve phone conversations for mixed BSUID payloads …
muhsin-k Aug 31, 2026
ce76807
fix(help-center): drop leading @ from pt_BR social link placeholder (…
hahuma Aug 31, 2026
dabde9e
fix(conversation): toggle contact and captain sidepanels on repeat cl…
salmonumbrella Aug 31, 2026
e5eaff1
feat(whatsapp): enable embedded signup for paid plans (#15626)
muhsin-k Sep 1, 2026
b3233bb
fix: show team icons in the sidebar (#15634)
iamsivin Sep 1, 2026
646b473
feat(tiktok): add inbox access request (#15637)
sojan-official Sep 1, 2026
07fa9ce
fix(whatsapp): preserve contacts across BSUID lifecycle changes (#15357)
marcoazcabral Sep 1, 2026
a523f65
feat: improve file upload experience in the article editor (#15593)
iamsivin Sep 1, 2026
79e145b
fix(whatsapp): skip phone registration and health check for coexisten…
tds-1 Sep 1, 2026
4e88475
fix(captain): preserve Copilot first messages over 255 characters (#1…
ajuijas Sep 1, 2026
acbab75
fix: show Initiated at in the agent's timezone (#15644)
iamsivin Sep 2, 2026
08b9992
fix(whatsapp): remove reconfigure feature gate (#15650)
muhsin-k Sep 2, 2026
9c71770
fix: prevent team icon picker clipping (#15648)
iamsivin Sep 2, 2026
bfd9d9e
feat: audit log message deletions with original content (#15456)
vishnu-narayanan Sep 2, 2026
9550de8
fix(whatsapp): prevent duplicate brazil contacts in whatsapp co-exist…
muhsin-k Sep 3, 2026
e027da1
fix: preserve spacing between automation conditions (#15662)
scmmishra Sep 3, 2026
16a4c6c
fix: sync embedded app context (#15660)
scmmishra Sep 3, 2026
3fa9555
fix: keyboard shortcuts fire twice after switching conversations (key…
oAllanNascimento Sep 3, 2026
5f9d7a1
feat(contacts): show whatsapp usernames in social links (#15669)
muhsin-k Sep 3, 2026
b18694e
fix: improve Google OAuth signup error feedback (#15655)
scmmishra Sep 3, 2026
6d9b7d7
fix: read FRONTEND_URL from global config for SAML ACS URL (#15643)
scmmishra Sep 3, 2026
31ee54a
fix(line): log invalid webhook signatures (#15671)
muhsin-k Sep 3, 2026
da4898e
fix: automation rules cannot be edited after closing the panel (#15674)
iamsivin Sep 3, 2026
7bd4eca
feat(voice): per-inbox call recording and transcription settings (#15…
tds-1 Sep 4, 2026
8314676
chore(deps-dev): bump @faker-js/faker from 9.9.0 to 10.5.0 in /tests/…
dependabot[bot] Sep 4, 2026
008e7ca
feat: render media previews in the article diff panel (#15640)
iamsivin Sep 7, 2026
97bc9be
fix(twilio): register messaging webhook for voice inboxes and add web…
tds-1 Sep 7, 2026
1b3ae26
fix(automation): load SLA options before editing rules (#15661)
scmmishra Sep 7, 2026
54c731b
fix(whatsapp): classify BSUID contacts as leads (#15670)
muhsin-k Sep 7, 2026
c44a98d
feat(whatsapp): recover phone information for BSUID contacts (#15552)
muhsin-k Sep 7, 2026
8484f96
fix: send Captain resolution message from resolve tool (#15668)
aakashb95 Sep 7, 2026
aa3d5c3
fix: refresh conversation lists safely on reconnect (#15651)
scmmishra Sep 7, 2026
9253468
feat(whatsapp): route campaigns to BSUID recipients (#15614)
muhsin-k Sep 7, 2026
c9f1867
fix: preserve line breaks in Copilot reply suggestions (#14765)
chinatsu1124 Sep 7, 2026
87007a8
fix(instagram): display button postbacks as incoming messages (#14237)
concept254 Sep 8, 2026
f9b7715
feat: improve Captain playground test setup (#15652)
sony-mathew Sep 8, 2026
7f7ae95
fix(auth): show OAuth error toast after snackbar mounts (#15716)
scmmishra Sep 8, 2026
6148b3f
feat: allow rotating the inbox HMAC token (#15715)
scmmishra Sep 8, 2026
89fac89
fix: prevent stale messages when switching conversations (#15699)
scmmishra Sep 8, 2026
6543e47
fix: mirror directional widget icons in RTL locales (#15714)
iamsivin Sep 8, 2026
720ef3f
fix: stray backslash and vanishing signature separator in replies (#1…
iamsivin Sep 8, 2026
8ecae51
fix(widget): preserve spacing after message lists (#15717)
muhsin-k Sep 8, 2026
dc0748b
docs: fix typo in message provider JSDoc (#15616)
vaibhav8a Sep 8, 2026
b227f80
feat(whatsapp): route BSUID calls through the active identity (#15546)
muhsin-k Sep 8, 2026
7e0f38b
feat(billing): cancel subscriptions at period end and show the cancel…
tds-1 Sep 9, 2026
f854ced
feat: mask audit log IP and show geo location behind a flag (#15455)
vishnu-narayanan Sep 9, 2026
545b82f
fix: Brazil whatsapp duplicate contacts (#14264)
AfricanMake Sep 9, 2026
ed42e09
fix(widget): prevent duplicate email-collect messages (#14855)
hahuma Sep 9, 2026
5bd167d
fix: preserve HTML-like outbound message content (#14192)
lucas-langa Sep 9, 2026
961d97e
feat(inboxes): persist social provider names (#15629)
sony-mathew Sep 9, 2026
5a53b16
test: cover WhatsApp HTML-like outbound payload (#15750)
sony-mathew Sep 9, 2026
27c87bf
fix(whatsapp): skip tracking-only webhook jobs (#15706)
muhsin-k Sep 9, 2026
63c0ac7
fix: generate Captain FAQ suggestions in account locale (#15728)
aakashb95 Sep 9, 2026
4a1499f
fix: enable reply suggestion search for self-hosted Premium (#15727)
aakashb95 Sep 9, 2026
2c82030
docs(campaigns): document campaign creation and scheduling APIs (#15748)
muhsin-k Sep 9, 2026
b88b8ab
fix: report filters resetting when opening a team (#15703)
aakashb95 Sep 9, 2026
5dc47d2
feat: support whatsapp input select row descriptions (#14938)
izcoser Sep 9, 2026
4114ff1
feat(whatsapp): grant embedded signup access after use case submissio…
muhsin-k Sep 9, 2026
6efffc8
fix: reject invalid conversation parameters (#15623)
sojan-official Sep 9, 2026
9d8d46a
fix(attachment): resolve inline audio URL via configured Active Stora…
augustocbx Sep 10, 2026
50a812e
feat(inboxes): Improve channel finish setup guidance (#13539)
sojan-official Sep 10, 2026
726af12
feat(shopify): add gated billing infrastructure (#15756)
muhsin-k Sep 10, 2026
6b72216
feat: expose Captain in assignment dropdown (#15437)
sojan-official Sep 10, 2026
840fb5d
refactor: group Captain runner options (#15707)
sony-mathew Sep 10, 2026
cca63c2
fix: simplify Captain eligibility checks for paid self-hosted plans (…
sojan-official Sep 10, 2026
bacb65d
fix(whatsapp): show backend errors when calls fail (#15766)
muhsin-k Sep 10, 2026
2f1ed80
fix(captain): refine overview reporting and design (#15722)
scmmishra Sep 11, 2026
d3e4ff2
fix: load ChatwootHub before stubbing edition in specs (#15785)
scmmishra Sep 14, 2026
f452298
fix(filters): use local calendar dates in saved filters (#15784)
scmmishra Sep 14, 2026
0820f3c
fix(email): prompt reauthorization for IMAP authentication failures (…
scmmishra Sep 14, 2026
6548045
revert: local calendar dates in saved filters (#15815)
vishnu-narayanan Sep 14, 2026
1f49e79
fix(inbox): allow SMTP configuration without IMAP (#15783)
scmmishra Sep 15, 2026
159658c
revert: fix email prompt reauthorization for IMAP authentication fail…
scmmishra Sep 15, 2026
16771f6
fix: prevent stale metadata from overwriting filtered counts (#15808)
scmmishra Sep 15, 2026
a24a498
fix(whatsapp): temporarily disable contact-info action during browsin…
scmmishra Sep 15, 2026
3d7ca0e
fix(contacts): default the contacts list to most recent activity firs…
tds-1 Sep 15, 2026
fc5c734
feat: resolve IP location for sign-in and sign-out audit logs (#15752)
vishnu-narayanan Sep 16, 2026
3effb7e
feat: add sorting to filtered conversations (#15753)
sony-mathew Sep 16, 2026
d0d0339
fix(twilio): preserve incoming quoted replies (#15838)
muhsin-k Sep 16, 2026
e16d8f2
fix(voice): answer WhatsApp calls from the conversation when the call…
tds-1 Sep 16, 2026
e39b5b7
fix: support opening sidebar items in new tabs (#15833)
iamsivin Sep 16, 2026
f61e9c9
fix(ci): document RubyLLM audit exception (#15847)
sony-mathew Sep 16, 2026
a8514e7
fix: Configure increased redis reconnection attempts (#14704)
tejush1998 Sep 16, 2026
eb0d524
fix(whatsapp): upload attachments to the media endpoint and send medi…
tds-1 Sep 16, 2026
a641b0e
fix: Widget DirectUpload CSRF error (#13447)
mazenkhalil Sep 16, 2026
2eabc74
feat: navigate between a contact's conversations from the thread (#15…
iamsivin Sep 16, 2026
4218dc6
fix(security): sanitize XSS-prone HTML rendering and markdown output …
Gurjit-30 Sep 16, 2026
2be8c3a
fix(sessions): read MAX_USER_SESSIONS from ENV dynamically (#15062)
qsebas Sep 16, 2026
5b7038b
fix: return 404 instead of 500 for unknown portal slugs (#15798)
breken-ai Sep 16, 2026
39b9d20
fix(facebook): handle messenger postbacks (#14115)
coolbirdzik Sep 17, 2026
d0ca2d9
chore: Update translations (#15848)
chatwoot-bot Sep 17, 2026
7d9d17a
fix: include widget ET translation files (#14701)
linbaublys Sep 17, 2026
aad2791
Merge commit from fork
sony-mathew Sep 17, 2026
7d581dc
Merge commit from fork
vishnu-narayanan Sep 17, 2026
fcfad2d
fix: limit app, widget, and admin search indexing (#15873)
sony-mathew Sep 17, 2026
a9552e8
Bump version to 4.18.0
sony-mathew Sep 17, 2026
9f920b5
Merge branch 'release/4.18.0'
sony-mathew Sep 17, 2026
a5eb0f3
chore: merge upstream chatwoot v4.18.0
neilLasrado Sep 24, 2026
a050cc2
fix(sdk): remove debug logs and unused import from disconnect helpers
neilLasrado Sep 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
30 changes: 26 additions & 4 deletions .bundler-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,30 @@
ignore:
- CVE-2021-41098 # https://github.com/chatwoot/chatwoot/issues/3097 (update once azure blob storage is updated)
- GHSA-57hq-95w6-v4fc # Devise confirmable race condition — patched locally in User model (remove once on Devise 5+)
# Chatwoot defaults to Active Storage redirect-style URLs, and its recommended
# storage setup uses local/cloud storage with optional direct uploads to the
# storage provider rather than Rails proxy mode. Revisit if we enable
# rails_storage_proxy or other app-served Active Storage proxy routes.
# Devise 5 is currently blocked by devise-secure_password/devise_token_auth/devise-two-factor.
# Chatwoot does not enable Timeoutable, so the timeout redirect path is not reachable.
- GHSA-jp94-3292-c3xv
# Rails 7.1 has no patched release for the Active Storage proxy range
# advisories. Chatwoot limits proxy range requests locally.
- CVE-2026-33658
# Rails 7.1 has no patched release for this Active Storage direct-upload
# advisory. Chatwoot filters internal metadata keys locally.
- CVE-2026-33173
- CVE-2026-33174
# Rails 7.1 has no patched release for these Rails advisories. These are not
# reachable through Chatwoot's current usage patterns and should be removed
# once we upgrade to Rails 7.2.3.1+.
- CVE-2026-33168
- CVE-2026-33169
- CVE-2026-33170
- CVE-2026-33176
- CVE-2026-33195
- CVE-2026-33202
# No Rails 7.1 patch for this Active Storage advisory; mitigated locally.
# Remove once on Rails 7.2.3.1+.
- CVE-2026-66066
# RubyLLM's name-normalization ReDoS is reported on Ruby 3.1; we require Ruby 3.4.4.
# Built-in tool names are fixed; custom tools use bounded slugs and override normalization.
# Patched 2.0 releases need an ai-agents migration (currently constrained to RubyLLM 1.x).
# Remove when a supported patched RubyLLM/ai-agents combination is adopted.
- CVE-2026-67991
9 changes: 6 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ jobs:

- node/install:
node-version: '24.13'
- node/install-pnpm
- node/install-pnpm:
version: '10.2.0'
- node/install-packages:
pkg-manager: pnpm
override-ci-command: pnpm i
Expand Down Expand Up @@ -118,7 +119,8 @@ jobs:
- checkout
- node/install:
node-version: '24.13'
- node/install-pnpm
- node/install-pnpm:
version: '10.2.0'
- node/install-packages:
pkg-manager: pnpm
override-ci-command: pnpm i
Expand Down Expand Up @@ -149,7 +151,8 @@ jobs:
- checkout
- node/install:
node-version: '24.13'
- node/install-pnpm
- node/install-pnpm:
version: '10.2.0'
- node/install-packages:
pkg-manager: pnpm
override-ci-command: pnpm i
Expand Down
58 changes: 55 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ REDIS_SENTINEL_MASTER_NAME=
# ref: https://github.com/chatwoot/chatwoot/issues/2420
# REDIS_OPENSSL_VERIFY_MODE=none

# OpenSearch / Elasticsearch-compatible search config
# Set OPENSEARCH_URL to enable advanced search. Elastic Cloud API keys can be configured with either key name below.
# API key values must be provided without the ApiKey authorization scheme prefix.
# OPENSEARCH_URL=
# OPENSEARCH_API_KEY=
# ELASTICSEARCH_API_KEY=
# OPENSEARCH_AWS_ACCESS_KEY_ID=
# OPENSEARCH_AWS_SECRET_ACCESS_KEY=
# OPENSEARCH_AWS_REGION=us-east-1

# Postgres Database config variables
# You can leave POSTGRES_DATABASE blank. The default name of
# the database in the production environment is chatwoot_production
Expand Down Expand Up @@ -98,6 +108,8 @@ SMTP_OPENSSL_VERIFY_MODE=peer
# Mail Incoming
# This is the domain set for the reply emails when conversation continuity is enabled
MAILER_INBOUND_EMAIL_DOMAIN=
# Maximum time in seconds to process a single IMAP email
# EMAIL_PROCESSING_TIMEOUT_SECONDS=60
# Set this to the appropriate ingress channel with regards to incoming emails
# Possible values are :
# relay for Exim, Postfix, Qmail
Expand Down Expand Up @@ -130,6 +142,11 @@ ACTION_MAILBOX_SES_SNS_TOPIC=
# Storage
ACTIVE_STORAGE_SERVICE=local

# Restrict libvips to its trusted, well-tested image loaders when Active Storage
# generates variants. Hardens image processing against untrusted uploads.
# Requires libvips >= 8.13 (ignored on older versions).
VIPS_BLOCK_UNTRUSTED=1

# Amazon S3
# documentation: https://www.chatwoot.com/docs/configuring-s3-bucket-as-cloud-storage
S3_BUCKET_NAME=
Expand All @@ -149,6 +166,8 @@ LOG_SIZE=500

# Facebook
# documentation: https://www.chatwoot.com/docs/facebook-setup
# Connected Facebook pages are subscribed by Chatwoot to Messenger webhook
# fields, including postbacks used by Get Started and button flows.
FB_VERIFY_TOKEN=
FB_APP_SECRET=
FB_APP_ID=
Expand All @@ -166,6 +185,7 @@ TWITTER_ENVIRONMENT=
#slack integration
SLACK_CLIENT_ID=
SLACK_CLIENT_SECRET=
SLACK_SIGNING_SECRET=

# Google OAuth
GOOGLE_OAUTH_CLIENT_ID=
Expand Down Expand Up @@ -228,10 +248,30 @@ ANDROID_SHA256_CERT_FINGERPRINT=AC:73:8E:DE:EB:56:EA:CC:10:87:02:A7:65:37:7B:38:
## To prevent and throttle abusive requests
# ENABLE_RACK_ATTACK=true
# RACK_ATTACK_LIMIT=300
## Parent switch for all widget throttles; per-endpoint switches below only apply when this is on
# ENABLE_RACK_ATTACK_WIDGET_API=true
## Widget conversation creates, per minute, keyed on (IP, website_token)
# ENABLE_RACK_ATTACK_WIDGET_CONVERSATIONS=true
# RATE_LIMIT_WIDGET_CONVERSATIONS=30
## Widget message creates, per minute, keyed on (IP, website_token)
# ENABLE_RACK_ATTACK_WIDGET_MESSAGES=true
# RATE_LIMIT_WIDGET_MESSAGES=60
## Widget contact updates, per hour, per IP
# ENABLE_RACK_ATTACK_WIDGET_CONTACTS=true
# RATE_LIMIT_WIDGET_CONTACTS=60
## Widget page loads (new session), per hour, per IP
# ENABLE_RACK_ATTACK_WIDGET_LOAD=true
# RATE_LIMIT_WIDGET_LOAD=200
## Widget transcript requests, per hour, per IP
# ENABLE_RACK_ATTACK_WIDGET_TRANSCRIPT=true
# RATE_LIMIT_WIDGET_TRANSCRIPT=5
# Comma-separated list of trusted IPs that bypass Rack Attack throttling rules
# RACK_ATTACK_ALLOWED_IPS=127.0.0.1,::1,192.168.0.10

## SafeFetch private network access
## Keep disabled by default. Self-hosted installations can enable this to allow SafeFetch requests to private network URLs.
# SAFE_FETCH_ALLOW_PRIVATE_NETWORK=false

## Running chatwoot as an API only server
## setting this value to true will disable the frontend dashboard endpoints
# CW_API_ONLY_SERVER=false
Expand Down Expand Up @@ -266,9 +306,9 @@ AZURE_APP_SECRET=
# ENABLE_SIDEKIQ_DEQUEUE_LOGGER=false


# AI powered features
## OpenAI key
# OPENAI_API_KEY=
# AI powered features (Captain)
# The OpenAI API key and endpoint for Captain are not configured via .env.
# Set them at Super Admin > App Configs > Captain (CAPTAIN_OPEN_AI_API_KEY, CAPTAIN_OPEN_AI_ENDPOINT).

# Housekeeping/Performance related configurations
# Set to true if you want to remove stale contact inboxes
Expand All @@ -277,3 +317,15 @@ AZURE_APP_SECRET=

# REDIS_ALFRED_SIZE=10
# REDIS_VELMA_SIZE=10

# Publish Sidekiq queue metrics to AWS CloudWatch for autoscaling. Off by default.
# By default uses the instance role, which must allow cloudwatch:PutMetricData.
# ENABLE_SIDEKIQ_CLOUDWATCH=true
# SIDEKIQ_CLOUDWATCH_NAMESPACE=Chatwoot/Sidekiq
# Publish interval in seconds (default 60; values below 60 work but bill as high-resolution CloudWatch metrics)
# SIDEKIQ_CLOUDWATCH_INTERVAL=60
# Optional: dedicated credentials for CloudWatch only, separate from the S3 (storage) keys.
# Set these to override the instance role when a role is not available.
# SIDEKIQ_CLOUDWATCH_AWS_ACCESS_KEY_ID=
# SIDEKIQ_CLOUDWATCH_AWS_SECRET_ACCESS_KEY=
# SIDEKIQ_CLOUDWATCH_AWS_REGION=us-east-1
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ module.exports = {
},
env: {
browser: true,
es2020: true,
node: true,
},
globals: {
Expand Down
195 changes: 195 additions & 0 deletions .github/scripts/ghsa_linear_sync.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#!/usr/bin/env python3
"""Sync triage GitHub security advisories to Linear issues."""

from __future__ import annotations

import os
import sys
from typing import Any

import requests

GITHUB_API = "https://api.github.com"
LINEAR_API = "https://api.linear.app/graphql"

SEVERITY_PRIORITY = {"critical": 1, "high": 2, "medium": 3, "low": 4}
SEVERITY_COLOR = {
"critical": 15548997,
"high": 15105570,
"medium": 15844367,
"low": 3066993,
}
DEFAULT_COLOR = 9807270


def required_env(name: str) -> str:
value = os.environ.get(name)
if not value:
sys.exit(f"Missing required env var: {name}")
return value


def fetch_triage_advisories(repo: str, token: str) -> list[dict[str, Any]]:
url: str | None = f"{GITHUB_API}/repos/{repo}/security-advisories"
params: dict[str, Any] | None = {"state": "triage", "per_page": 100}
headers = {
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {token}",
"X-GitHub-Api-Version": "2022-11-28",
}
advisories: list[dict[str, Any]] = []
while url:
r = requests.get(url, headers=headers, params=params, timeout=30)
r.raise_for_status()
advisories.extend(r.json())
next_link = r.links.get("next")
url = next_link["url"] if next_link else None
params = None
return advisories


def linear_call(query: str, variables: dict[str, Any], api_key: str) -> dict[str, Any]:
r = requests.post(
LINEAR_API,
headers={"Authorization": api_key},
json={"query": query, "variables": variables},
timeout=30,
)
r.raise_for_status()
return r.json()


def linear_issue_exists(ghsa_id: str, api_key: str) -> bool:
query = (
"query($q: String!) { issues(filter: {title: {contains: $q}}, first: 1) "
"{ nodes { id } } }"
)
resp = linear_call(query, {"q": ghsa_id}, api_key)
return len(resp.get("data", {}).get("issues", {}).get("nodes", [])) > 0


def linear_create_issue(input_data: dict[str, Any], api_key: str) -> dict[str, str] | None:
query = (
"mutation($input: IssueCreateInput!) { issueCreate(input: $input) "
"{ success issue { identifier url } } }"
)
resp = linear_call(query, {"input": input_data}, api_key)
create = resp.get("data", {}).get("issueCreate") or {}
if not create.get("success"):
return None
return create.get("issue")


def reporter_login(advisory: dict[str, Any]) -> str:
for credit in advisory.get("credits") or []:
user = (credit or {}).get("user") or {}
if user.get("login"):
return user["login"]
return "unknown"


def cvss_score(advisory: dict[str, Any]) -> str:
score = (advisory.get("cvss") or {}).get("score")
return str(score) if score is not None else "n/a"


def build_description(adv: dict[str, Any]) -> str:
return (
f"**GHSA:** {adv['ghsa_id']}\n"
f"**CVE:** {adv.get('cve_id') or 'n/a'}\n"
f"**Severity:** {adv.get('severity') or 'unknown'} (CVSS {cvss_score(adv)})\n"
f"**Reporter:** {reporter_login(adv)}\n"
f"**Reported:** {(adv.get('created_at') or '').split('T')[0]}\n"
f"**Advisory:** {adv['html_url']}\n\n"
f"---\n\n"
f"{adv.get('description') or 'No description provided.'}"
)


def post_discord(adv: dict[str, Any], issue: dict[str, str], webhook_url: str) -> None:
severity = adv.get("severity") or "unknown"
title = f"[{adv['ghsa_id']}] {adv['summary']}"[:250]
payload = {
"username": "GHSA Sync",
"embeds": [
{
"title": title,
"url": issue["url"],
"color": SEVERITY_COLOR.get(severity, DEFAULT_COLOR),
"fields": [
{"name": "Linear", "value": issue["identifier"], "inline": True},
{
"name": "Severity",
"value": f"{severity} (CVSS {cvss_score(adv)})",
"inline": True,
},
{
"name": "Advisory",
"value": f"[GitHub]({adv['html_url']})",
"inline": True,
},
],
}
],
}
try:
requests.post(webhook_url, json=payload, timeout=10)
except requests.RequestException:
pass


def main() -> int:
repo = required_env("GITHUB_REPOSITORY")
gh_token = required_env("GHSA_READ_TOKEN")
linear_api_key = required_env("LINEAR_API_KEY")
team_id = required_env("LINEAR_TEAM_ID")
project_id = required_env("LINEAR_PROJECT_ID")
label_id = required_env("LINEAR_LABEL_ID")
discord_webhook = os.environ.get("DISCORD_WEBHOOK_URL") or None

advisories = fetch_triage_advisories(repo, gh_token)
print(f"Fetched {len(advisories)} triage advisories")

created = skipped = failed = 0

for adv in advisories:
ghsa_id = adv.get("ghsa_id")
if not ghsa_id:
failed += 1
continue

try:
if linear_issue_exists(ghsa_id, linear_api_key):
skipped += 1
continue

severity = adv.get("severity") or "unknown"
issue = linear_create_issue(
{
"title": f"[{ghsa_id}] {adv.get('summary', '')}",
"description": build_description(adv),
"teamId": team_id,
"projectId": project_id,
"labelIds": [label_id],
"priority": SEVERITY_PRIORITY.get(severity, 3),
},
linear_api_key,
)
except requests.RequestException:
failed += 1
continue

if not issue:
failed += 1
continue

created += 1
if discord_webhook:
post_discord(adv, issue, discord_webhook)

print(f"Created {created}, skipped {skipped}, failed {failed}")
return 1 if failed > 0 else 0


if __name__ == "__main__":
sys.exit(main())
3 changes: 3 additions & 0 deletions .github/workflows/deploy_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ concurrency:
group: pr-${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
deployment_check:
name: Check Deployment
Expand Down
Loading
Loading