29 Commits

Author SHA1 Message Date
Sojan Jose
38f16ba677 feat: Secure external credentials with database encryption (#12648)
## Changelog

- Added conditional Active Record encryption to every external
credential we store (SMTP/IMAP passwords, Twilio tokens,
Slack/OpenAI hook tokens, Facebook/Instagram tokens, LINE/Telegram keys,
Twitter secrets) so new writes are encrypted
whenever Chatwoot.encryption_configured? is true; legacy installs still
receive plaintext until their secrets are
    updated.
- Tuned encryption settings in config/application.rb to allow legacy
reads (support_unencrypted_data) and to extend
deterministic queries so lookups continue to match plaintext rows during
the rollout; added TODOs to retire the
    fallback once encryption becomes mandatory.
- Introduced an MFA-pipeline test suite
(spec/models/external_credentials_encryption_spec.rb) plus shared
examples to
verify each attribute encrypts at rest and that plaintext records
re-encrypt on update, with a dedicated Telegram case.
The existing MFA GitHub workflow now runs these tests using the
preconfigured encryption keys.

fixes:
https://linear.app/chatwoot/issue/CW-5453/encrypt-sensitive-credentials-stored-in-plain-text-in-database

## Testing Instructions

 1. Instance without encryption keys
- Unset ACTIVE_RECORD_ENCRYPTION_* vars (or run in an environment where
they’re absent).
      - Create at least one credentialed channel (e.g., Email SMTP).
- Confirm workflows still function (send/receive mail or a similar
sanity check).
- In the DB you should still see plaintext values—this confirms the
guard prevents encryption when keys are missing.
  2. Instance with encryption keys
      - Configure the three encryption env vars and restart.
- Pick a couple of representative integrations (e.g., Email SMTP +
Twilio SMS).
      - Legacy channel check:
- Use existing records created before enabling keys. Trigger their
workflow (send an email / SMS, or hit the
            webhook) to ensure they still authenticate.
- Inspect the raw column—value remains plaintext until changed.
      - Update legacy channel:
- Edit one legacy channel’s credential (e.g., change SMTP password).
- Verify the operation still works and the stored value is now encrypted
(raw column differs, accessor returns
            original).
      - New channel creation:
- Create a new channel of the same type; confirm functionality and that
the stored credential is encrypted from
            the start.

---------

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-10-13 18:05:12 +05:30
Tanmay Deep Sharma
239c4dcb91 feat: MFA (#12290)
## Linear:
- https://github.com/chatwoot/chatwoot/issues/486

## Description
This PR implements Multi-Factor Authentication (MFA) support for user
accounts, enhancing security by requiring a second form of verification
during login. The feature adds TOTP (Time-based One-Time Password)
authentication with QR code generation and backup codes for account
recovery.

## Type of change

- [ ] New feature (non-breaking change which adds functionality)

## How Has This Been Tested?

- Added comprehensive RSpec tests for MFA controller functionality
- Tested MFA setup flow with QR code generation
- Verified OTP validation and backup code generation
- Tested login flow with MFA enabled/disabled

## 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: Pranav <pranav@chatwoot.com>
Co-authored-by: Sojan Jose <sojan@pepalo.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-09-18 20:19:24 +05:30
Shivam Mishra
79b93bed77 feat: SAML authentication controllers [CW-2958] (#12319) 2025-09-10 20:02:27 +05:30
Vishnu Narayanan
75119d4a08 fix: switch to datadog v2 gem (#12214)
# Pull Request Template

## Description
- The `0.48` version of the `ddtrace` gem was out of date, which was
causing the application to crash if `DD_AGENT_URL` was configured
- Switch to `datadog` gem, which is the currently maintained gem from DD


Ref: https://github.com/DataDog/dd-trace-rb/releases/tag/v2.0.0
2025-08-18 21:54:27 +05:30
Vishnu Narayanan
6cab741392 fix: handle active storage preview error for password protected pdfs (#11888)
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-08-11 12:41:37 +05:30
Sojan Jose
c63b583f90 chore: improve plan-based feature handling with plan hierarchy (#11335)
- Refactor HandleStripeEventService to better manage features by plan
- Add constants for features available in each plan tier (Startup,
Business, Enterprise)
- Add channel_instagram to Startup plan features
- Improve downgrade handling to properly disable higher-tier features
- Clean up and optimize tests for maintainability
- Add comprehensive test coverage for plan upgrades and downgrades

---------

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-04-28 14:13:56 -07:00
Pranav
d070743383 feat(ee): Add Captain features (#10665)
Migration Guide: https://chwt.app/v4/migration

This PR imports all the work related to Captain into the EE codebase. Captain represents the AI-based features in Chatwoot and includes the following key components:

- Assistant: An assistant has a persona, the product it would be trained on. At the moment, the data at which it is trained is from websites. Future integrations on Notion documents, PDF etc. This PR enables connecting an assistant to an inbox. The assistant would run the conversation every time before transferring it to an agent.
- Copilot for Agents: When an agent is supporting a customer, we will be able to offer additional help to lookup some data or fetch information from integrations etc via copilot.
- Conversation FAQ generator: When a conversation is resolved, the Captain integration would identify questions which were not in the knowledge base.
- CRM memory: Learns from the conversations and identifies important information about the contact.

---------

Co-authored-by: Vishnu Narayanan <vishnu@chatwoot.com>
Co-authored-by: Sojan <sojan@pepalo.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
2025-01-14 16:15:47 -08:00
Nguyễn Trần Chung
96ae298464 fix: Dotenv::Railtie is deprecated (#10515)
https://github.com/bkeepers/dotenv/pull/468

Renames Dotenv::Railtie => Dotenv::Rails

Co-authored-by: Sojan Jose <sojan@pepalo.com>
2024-12-17 17:20:44 +05:30
Vishnu Narayanan
54afed9fb4 feat: add judoscaler gem for heroku autoscaling (#10419)
- add judoscaler gem to allow judoscale use in heroku environments
- This will allow auto scaling for both web and worker dynos across both
standard-1x/2x and performance dynos
- This will scaling in response to queue time rather than response
time(heroku default)
- This also allows you to scale multiple dynos in and out at once,
rather than scaling them one at a time, as is the default.

Ref
----
1. https://judoscale.com/
2. https://devcenter.heroku.com/articles/judoscale
2024-11-18 12:36:27 +05:30
Sojan Jose
022383d942 chore: Upgrade to Rails 7 (#6719)
fixes: #6736
2023-05-06 10:44:52 +05:30
Sojan Jose
e8a174f689 chore: Add sidekiq metrics to newrelic (#6659)
* chore: Add sidekiq stats to newrelic

* chore: add gemlock
2023-03-14 20:50:28 +05:30
Sojan Jose
c9c3ac4b44 chore: Load only required APMs (#6497)
- Disable requiring the gems for all the APMs 
- Switch to selectively requiring them.
2023-03-01 14:31:51 +05:30
Sojan Jose
4187428729 chore: Update dependencies to the latest versions (#5033) 2022-07-15 09:51:59 +07:00
Sojan Jose
8e153d6350 fix: Redis 6 on Heroku breaks ActionCable config (#4269)
Heroku made some SSL/TLS changes with Redis 6, which is breaking the ActionCable configuration.
Hence providing an environment variable configuration `REDIS_OPENSSL_VERIFY_MODE` to fix that.

set the value `none` for this environment variable in your Heroku installations where breakage occurs.

fixes: #2420
2022-03-24 19:25:07 +05:30
Sojan Jose
b1eea7f7d1 chore: Introduce enterprise edition license (#3209)
- Initialize an "enterprise" folder that is copyrighted.
- You can remove this folder and the system will continue functioning normally, in case you want a purely MIT licensed product.
- Enable limit on the number of user accounts in enterprise code.
- Use enterprise edition injector methods (inspired from Gitlab).
- SaaS software would run enterprise edition software always.

Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
2021-12-09 12:07:48 +05:30
Sojan Jose
ab54d9c629 chore: Upgrade rails and ruby versions (#2400)
ruby version: 3.0.2
rails version: 6.1.4
2021-08-03 20:11:52 +05:30
Pranav Raj S
d0f2ed38c1 fix: Add lib/azure to autoload ignore list (#1368) 2020-10-27 18:48:23 +05:30
Sojan Jose
4f83d5451e Chore: Routine Bugfixes and enhancements (#979)
- Fix slack scopes
- Docs for authentication
Fixes: #704 , #973
2020-06-25 23:35:16 +05:30
Pranav Raj S
3f5ce2ddbf Bug: Fix autoload_paths for facebook bot (#877)
* Fix autoload_paths for facebook bot
2020-05-18 15:32:26 +05:30
Sojan Jose
743bddc065 Chore: Housekeeping tasks (#721)
- End point to return api version
- Move agent bot listener to sync dispatcher
- gem update
2020-04-16 15:05:01 +05:30
Sojan
6c0076665a Bugfix: Production autoload issue for bot.rb
- add app/bot to auto load path
2020-01-09 14:36:20 +05:30
Sojan
8e6b735299 Bugfix: Sidekiq queues getting stuck [#411]
ref: https://github.com/rails/rails/issues/36810
closes: #411
2020-01-09 11:59:31 +05:30
Pranav Raj S
16fe912fbd [Feature] Website live chat (#187)
Co-authored-by: Nithin David Thomas <webofnithin@gmail.com>
Co-authored-by: Sojan Jose <sojan@pepalo.com>
2019-10-29 12:50:54 +05:30
Nursoltan Saipolda
c0354364ff removed app/stylesheets & set stylesheet generator to false (#177) 2019-10-24 17:08:38 +05:30
Nursoltan Saipolda
73d433b591 deleted coffee files & coffee-rails gem. disable js generation on application.rb (#173) 2019-10-23 15:59:45 +05:30
Pranav Raj S
af20e61604 [Feature] Add PWA support (#157)
* Add icons, manifest

* Add workbox config
2019-10-18 12:37:09 +05:30
Sojan Jose
3988777718 Refactoring the code for pub sub (#155)
- We were using the attribute name 'channel' to store pubsub tokens, which was confusing.
- switched to faker from ffaker
- spec for contact.rb
2019-10-17 03:18:07 +05:30
Sojan Jose
52194116b3 Upgrade to rails 6 💎 (#11)
- upgraded to rails 6
- fixes various issues
2019-08-19 13:49:57 +05:30
Pranav Raj Sreepuram
2a34255e0b Initial Commit
Co-authored-by: Subin <subinthattaparambil@gmail.com>
Co-authored-by: Manoj <manojmj92@gmail.com>
Co-authored-by: Nithin <webofnithin@gmail.com>
2019-08-14 15:18:44 +05:30