flow_chat 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.cliff.toml +74 -0
  3. data/.github/workflows/ci.yml +2 -3
  4. data/.github/workflows/release.yml +56 -0
  5. data/.standard.yml +4 -0
  6. data/CHANGELOG.md +22 -0
  7. data/CLAUDE.md +327 -0
  8. data/CONTRIBUTING.md +134 -0
  9. data/Gemfile +1 -0
  10. data/README.md +290 -105
  11. data/Rakefile +5 -1
  12. data/SECURITY.md +42 -349
  13. data/docs/architecture.md +510 -0
  14. data/docs/async-background-processing.md +298 -0
  15. data/docs/configuration.md +556 -226
  16. data/docs/factory-pattern.md +355 -0
  17. data/docs/gateway-context-variables.md +171 -0
  18. data/docs/gateway-development.md +723 -0
  19. data/docs/getting-started.md +429 -0
  20. data/docs/instrumentation.md +264 -153
  21. data/docs/platforms/telegram.md +1013 -0
  22. data/docs/platforms/ussd.md +693 -0
  23. data/docs/platforms/whatsapp.md +1395 -0
  24. data/docs/testing.md +243 -365
  25. data/examples/custom_session_id_example.rb +119 -0
  26. data/examples/http_controller.rb +11 -11
  27. data/examples/intercom_configuration_example.rb +118 -0
  28. data/examples/intercom_controller.rb +194 -0
  29. data/examples/multi_tenant_whatsapp_controller.rb +4 -4
  30. data/examples/ussd_controller.rb +9 -9
  31. data/examples/whatsapp_controller.rb +2 -2
  32. data/flow_chat.gemspec +4 -0
  33. data/lib/flow_chat/{base_app.rb → app.rb} +16 -9
  34. data/lib/flow_chat/async_job.rb +176 -0
  35. data/lib/flow_chat/config.rb +10 -30
  36. data/lib/flow_chat/{base_executor.rb → executor.rb} +6 -11
  37. data/lib/flow_chat/factory.rb +94 -0
  38. data/lib/flow_chat/gateway_async_support.rb +106 -0
  39. data/lib/flow_chat/generic_async_job.rb +30 -0
  40. data/lib/flow_chat/http/gateway/simple.rb +81 -33
  41. data/lib/flow_chat/http/renderer.rb +3 -3
  42. data/lib/flow_chat/instrumentation/setup.rb +1 -1
  43. data/lib/flow_chat/instrumentation.rb +23 -0
  44. data/lib/flow_chat/intercom/client.rb +155 -0
  45. data/lib/flow_chat/intercom/configuration.rb +149 -0
  46. data/lib/flow_chat/intercom/gateway/intercom_api.rb +396 -0
  47. data/lib/flow_chat/intercom/renderer.rb +71 -0
  48. data/lib/flow_chat/phone_number_util.rb +37 -35
  49. data/lib/flow_chat/processor.rb +188 -0
  50. data/lib/flow_chat/renderers/markdown_support.rb +58 -0
  51. data/lib/flow_chat/session/middleware.rb +25 -9
  52. data/lib/flow_chat/telegram/client.rb +240 -0
  53. data/lib/flow_chat/telegram/configuration.rb +118 -0
  54. data/lib/flow_chat/telegram/gateway/bot_api.rb +300 -0
  55. data/lib/flow_chat/telegram/middleware/choice_mapper.rb +35 -0
  56. data/lib/flow_chat/telegram/renderer.rb +125 -0
  57. data/lib/flow_chat/telegram.rb +7 -0
  58. data/lib/flow_chat/ussd/gateway/nalo.rb +24 -4
  59. data/lib/flow_chat/ussd/middleware/pagination.rb +9 -5
  60. data/lib/flow_chat/ussd/renderer.rb +1 -1
  61. data/lib/flow_chat/version.rb +1 -1
  62. data/lib/flow_chat/whatsapp/client.rb +144 -13
  63. data/lib/flow_chat/whatsapp/configuration.rb +1 -1
  64. data/lib/flow_chat/whatsapp/gateway/cloud_api.rb +132 -96
  65. data/lib/flow_chat/whatsapp/id_generator.rb +124 -0
  66. data/lib/flow_chat/whatsapp/middleware/choice_mapper.rb +147 -0
  67. data/lib/flow_chat/whatsapp/renderer.rb +145 -11
  68. data/lib/flow_chat.rb +11 -1
  69. data/lib/tasks/release.rake +165 -0
  70. metadata +84 -25
  71. data/docs/flows.md +0 -320
  72. data/docs/http-gateway-protocol.md +0 -432
  73. data/docs/images/simulator.png +0 -0
  74. data/docs/media.md +0 -153
  75. data/docs/sessions.md +0 -433
  76. data/docs/ussd-setup.md +0 -322
  77. data/docs/whatsapp-setup.md +0 -162
  78. data/examples/whatsapp_message_job.rb +0 -113
  79. data/lib/flow_chat/base_processor.rb +0 -146
  80. data/lib/flow_chat/http/app.rb +0 -6
  81. data/lib/flow_chat/http/middleware/executor.rb +0 -24
  82. data/lib/flow_chat/http/processor.rb +0 -33
  83. data/lib/flow_chat/session/rails_session_store.rb +0 -68
  84. data/lib/flow_chat/ussd/app.rb +0 -6
  85. data/lib/flow_chat/ussd/gateway/nsano.rb +0 -96
  86. data/lib/flow_chat/ussd/middleware/executor.rb +0 -24
  87. data/lib/flow_chat/ussd/processor.rb +0 -39
  88. data/lib/flow_chat/whatsapp/app.rb +0 -29
  89. data/lib/flow_chat/whatsapp/middleware/executor.rb +0 -24
  90. data/lib/flow_chat/whatsapp/processor.rb +0 -32
  91. data/lib/flow_chat/whatsapp/send_job_support.rb +0 -79
data/SECURITY.md CHANGED
@@ -1,365 +1,58 @@
1
- # FlowChat Security Guide
1
+ # Security Policy
2
2
 
3
- This guide covers the security features and best practices for FlowChat, including webhook signature validation and simulator authentication.
3
+ We take the security of FlowChat seriously. Because FlowChat is a framework for
4
+ building conversational interfaces that other applications are built on, a
5
+ vulnerability here can affect many downstream apps. We appreciate your help in
6
+ disclosing issues responsibly.
4
7
 
5
- ## Overview
8
+ ## Supported Versions
6
9
 
7
- FlowChat includes comprehensive security features to protect your WhatsApp and USSD applications:
10
+ FlowChat is pre-1.0 and evolving quickly. Security fixes are released against
11
+ the **latest published version** only. If you are running an older release,
12
+ please upgrade before reporting an issue to confirm it still reproduces.
8
13
 
9
- - **Webhook Signature Validation**: Verify that WhatsApp webhooks are authentic
10
- - **Simulator Authentication**: Secure access to the testing simulator
11
- - **Configuration Validation**: Prevent insecure configurations
12
- - **Environment-Specific Security**: Different security levels per environment
14
+ | Version | Supported |
15
+ | ------- | ------------------ |
16
+ | Latest release (`0.9.x`) | :white_check_mark: |
17
+ | Older releases | :x: |
13
18
 
14
- ## WhatsApp Webhook Security
19
+ ## Reporting a Vulnerability
15
20
 
16
- ### Signature Validation
21
+ **Please do not report security vulnerabilities through public GitHub issues,
22
+ discussions, or pull requests.**
17
23
 
18
- FlowChat automatically validates WhatsApp webhook signatures using HMAC-SHA256 to ensure requests come from WhatsApp.
24
+ Instead, use one of the following private channels:
19
25
 
20
- #### Required Configuration
26
+ - **Preferred:** [Open a private vulnerability report](https://github.com/radioactive-labs/flow_chat/security/advisories/new)
27
+ via GitHub Security Advisories.
28
+ - **Email:** [sfroelich01@gmail.com](mailto:sfroelich01@gmail.com) with the
29
+ subject line `[SECURITY] FlowChat`.
21
30
 
22
- For webhook signature validation, you need to configure your WhatsApp app secret:
31
+ To help us triage quickly, please include as much of the following as you can:
23
32
 
24
- ```ruby
25
- # Using Rails credentials
26
- rails credentials:edit
27
- ```
33
+ - The FlowChat version (and Rails version) affected.
34
+ - A description of the vulnerability and its impact.
35
+ - Steps to reproduce, or a proof-of-concept.
36
+ - Any known workarounds.
28
37
 
29
- ```yaml
30
- whatsapp:
31
- app_secret: "your_whatsapp_app_secret"
32
- # ... other credentials
33
- ```
38
+ ## What to Expect
34
39
 
35
- Or using environment variables:
40
+ - **Acknowledgement:** We aim to acknowledge your report within **3 business days**.
41
+ - **Assessment:** We will investigate and let you know whether the report is
42
+ accepted, along with our expected timeline for a fix.
43
+ - **Disclosure:** We follow a coordinated disclosure process. We will work with
44
+ you to agree on a disclosure date once a fix is available, and we are happy to
45
+ credit you in the advisory unless you prefer to remain anonymous.
36
46
 
37
- ```bash
38
- export WHATSAPP_APP_SECRET="your_whatsapp_app_secret"
39
- ```
47
+ Please give us a reasonable opportunity to address the issue before any public
48
+ disclosure.
40
49
 
41
- #### Security Modes
50
+ ## Scope
42
51
 
43
- FlowChat supports two security modes for webhook validation:
52
+ Security reports about the FlowChat framework code in this repository are in
53
+ scope. Issues in applications *built with* FlowChat, or in third-party
54
+ dependencies, should be reported to their respective maintainers — though if you
55
+ believe a dependency issue is triggered by how FlowChat uses it, we would like
56
+ to hear about it.
44
57
 
45
- **1. Full Security (Recommended for Production)**
46
-
47
- ```ruby
48
- config = FlowChat::Whatsapp::Configuration.new
49
- config.app_secret = "your_whatsapp_app_secret" # Required
50
- config.skip_signature_validation = false # Default: enforce validation
51
- ```
52
-
53
- **2. Development Mode (Testing Only)**
54
-
55
- ```ruby
56
- config = FlowChat::Whatsapp::Configuration.new
57
- config.app_secret = nil # Not required when disabled
58
- config.skip_signature_validation = true # Explicitly disable validation
59
- ```
60
-
61
- ⚠️ **Security Warning**: Never disable signature validation in production environments.
62
-
63
- #### Configuration Error Handling
64
-
65
- When `app_secret` is missing and validation is not explicitly disabled, FlowChat raises a `ConfigurationError`:
66
-
67
- ```ruby
68
- begin
69
- processor.run WelcomeFlow, :main_page
70
- rescue FlowChat::Whatsapp::ConfigurationError => e
71
- Rails.logger.error "Security configuration error: #{e.message}"
72
- head :internal_server_error
73
- end
74
- ```
75
-
76
- The error message provides clear guidance:
77
-
78
- ```
79
- WhatsApp app_secret is required for webhook signature validation.
80
- Either configure app_secret or set skip_signature_validation=true to explicitly disable validation.
81
- ```
82
-
83
- ### Environment-Specific Security
84
-
85
- Configure different security levels per environment:
86
-
87
- ```ruby
88
- # config/initializers/flowchat.rb
89
- case Rails.env
90
- when 'development'
91
- # Relaxed security for easier development
92
- config.skip_signature_validation = true
93
-
94
- when 'test'
95
- # Skip validation for deterministic testing
96
- config.skip_signature_validation = true
97
-
98
- when 'staging', 'production'
99
- # Full security for production-like environments
100
- config.skip_signature_validation = false
101
-
102
- # Ensure app_secret is configured
103
- if ENV['WHATSAPP_APP_SECRET'].blank?
104
- raise "WHATSAPP_APP_SECRET required for #{Rails.env} environment"
105
- end
106
- end
107
- ```
108
-
109
- ## Simulator Security
110
-
111
- ### Authentication System
112
-
113
- The FlowChat simulator uses secure HMAC-SHA256 signed cookies for authentication. This prevents unauthorized access to your simulator endpoints.
114
-
115
- #### Required Configuration
116
-
117
- Configure a simulator secret in your initializer:
118
-
119
- ```ruby
120
- # config/initializers/flowchat.rb
121
- FlowChat::Config.simulator_secret = "your_secure_secret_here"
122
- ```
123
-
124
- #### Environment-Specific Secrets
125
-
126
- Use different secrets per environment:
127
-
128
- ```ruby
129
- case Rails.env
130
- when 'development', 'test'
131
- # Use Rails secret key with environment suffix
132
- FlowChat::Config.simulator_secret = Rails.application.secret_key_base + "_#{Rails.env}"
133
-
134
- when 'staging', 'production'
135
- # Use environment variable for production
136
- FlowChat::Config.simulator_secret = ENV['FLOWCHAT_SIMULATOR_SECRET']
137
-
138
- if FlowChat::Config.simulator_secret.blank?
139
- Rails.logger.warn "FLOWCHAT_SIMULATOR_SECRET not configured. Simulator will be unavailable."
140
- end
141
- end
142
- ```
143
-
144
- #### Cookie Security
145
-
146
- Simulator cookies are automatically configured with security best practices:
147
-
148
- - **HMAC-SHA256 signed**: Prevents tampering
149
- - **24-hour expiration**: Limits exposure window
150
- - **Secure flag**: Only sent over HTTPS in production
151
- - **HttpOnly flag**: Prevents XSS access
152
- - **SameSite=Lax**: CSRF protection
153
-
154
- #### Enabling Simulator Mode
155
-
156
- Enable simulator mode only when needed:
157
-
158
- ```ruby
159
- # Enable simulator only in development/staging
160
- enable_simulator = Rails.env.development? || Rails.env.staging?
161
-
162
- processor = FlowChat::Whatsapp::Processor.new(self, enable_simulator: enable_simulator) do |config|
163
- config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
164
- config.use_session_store FlowChat::Session::CacheSessionStore
165
- end
166
- ```
167
-
168
- ### Simulator Request Flow
169
-
170
- 1. **User visits simulator**: Browser requests `/simulator`
171
- 2. **Cookie generation**: Server generates HMAC-signed cookie
172
- 3. **Simulator requests**: Include valid cookie for authentication
173
- 4. **Cookie validation**: Server validates HMAC signature and timestamp
174
- 5. **Request processing**: Continues if authentication succeeds
175
-
176
- ## Security Best Practices
177
-
178
- ### Production Checklist
179
-
180
- ✅ **WhatsApp Security**
181
- - Configure `app_secret` for webhook validation
182
- - Set `skip_signature_validation = false`
183
- - Use environment variables for secrets
184
- - Handle `ConfigurationError` exceptions
185
-
186
- ✅ **Simulator Security**
187
- - Configure `simulator_secret` using environment variables
188
- - Enable simulator only in development/staging
189
- - Use unique secrets per environment
190
-
191
- ✅ **Environment Configuration**
192
- - Different security levels per environment
193
- - Fail fast on missing required configuration
194
- - Log security warnings appropriately
195
-
196
- ✅ **Error Handling**
197
- - Catch and log `ConfigurationError` exceptions
198
- - Return appropriate HTTP status codes
199
- - Don't expose sensitive information in errors
200
-
201
- ### Development Guidelines
202
-
203
- **DO:**
204
- - Use Rails `secret_key_base` + suffix for development secrets
205
- - Skip webhook validation in development for easier testing
206
- - Enable simulator mode for testing
207
- - Use test-specific credentials in test environment
208
-
209
- **DON'T:**
210
- - Hardcode secrets in source code
211
- - Disable security in production
212
- - Use production secrets in development
213
- - Commit secrets to version control
214
-
215
- ### Example Secure Configuration
216
-
217
- ```ruby
218
- # config/initializers/flowchat.rb
219
- case Rails.env
220
- when 'development'
221
- FlowChat::Config.simulator_secret = Rails.application.secret_key_base + "_dev"
222
- FlowChat::Config.whatsapp.message_handling_mode = :simulator
223
-
224
- when 'test'
225
- FlowChat::Config.simulator_secret = "test_secret_#{Rails.application.secret_key_base}"
226
- FlowChat::Config.whatsapp.message_handling_mode = :simulator
227
-
228
- when 'staging'
229
- FlowChat::Config.simulator_secret = ENV.fetch('FLOWCHAT_SIMULATOR_SECRET')
230
- FlowChat::Config.whatsapp.message_handling_mode = :inline
231
-
232
- when 'production'
233
- FlowChat::Config.simulator_secret = ENV.fetch('FLOWCHAT_SIMULATOR_SECRET')
234
- FlowChat::Config.whatsapp.message_handling_mode = :background
235
- FlowChat::Config.whatsapp.background_job_class = 'WhatsappMessageJob'
236
- end
237
- ```
238
-
239
- ## Testing Security Features
240
-
241
- ### Webhook Signature Validation Tests
242
-
243
- ```ruby
244
- test "webhook accepts valid signature" do
245
- payload = valid_webhook_payload.to_json
246
- signature = OpenSSL::HMAC.hexdigest(
247
- OpenSSL::Digest.new("sha256"),
248
- "your_app_secret",
249
- payload
250
- )
251
-
252
- post "/whatsapp/webhook",
253
- params: payload,
254
- headers: {
255
- "Content-Type" => "application/json",
256
- "X-Hub-Signature-256" => "sha256=#{signature}"
257
- }
258
-
259
- assert_response :success
260
- end
261
-
262
- test "webhook rejects invalid signature" do
263
- post "/whatsapp/webhook",
264
- params: valid_webhook_payload,
265
- headers: { "X-Hub-Signature-256" => "sha256=invalid_signature" }
266
-
267
- assert_response :unauthorized
268
- end
269
-
270
- test "webhook rejects missing signature" do
271
- post "/whatsapp/webhook", params: valid_webhook_payload
272
- assert_response :unauthorized
273
- end
274
- ```
275
-
276
- ### Simulator Authentication Tests
277
-
278
- ```ruby
279
- test "simulator requires valid authentication" do
280
- post "/whatsapp/webhook", params: {
281
- simulator_mode: true,
282
- # ... webhook payload
283
- }
284
-
285
- assert_response :unauthorized # No valid simulator cookie
286
- end
287
-
288
- test "simulator accepts valid authentication" do
289
- # Generate valid simulator cookie
290
- timestamp = Time.now.to_i
291
- message = "simulator:#{timestamp}"
292
- signature = OpenSSL::HMAC.hexdigest(
293
- OpenSSL::Digest.new("sha256"),
294
- FlowChat::Config.simulator_secret,
295
- message
296
- )
297
-
298
- post "/whatsapp/webhook",
299
- params: { simulator_mode: true, /* ... */ },
300
- cookies: { flowchat_simulator: "#{timestamp}:#{signature}" }
301
-
302
- assert_response :success
303
- end
304
- ```
305
-
306
- ## Troubleshooting
307
-
308
- ### Common Issues
309
-
310
- **1. ConfigurationError: app_secret required**
311
-
312
- ```
313
- WhatsApp app_secret is required for webhook signature validation.
314
- ```
315
-
316
- **Solution**: Configure `WHATSAPP_APP_SECRET` environment variable or disable validation explicitly.
317
-
318
- **2. Invalid webhook signature**
319
-
320
- ```
321
- Invalid webhook signature received
322
- ```
323
-
324
- **Solution**: Verify your `app_secret` matches your WhatsApp app configuration.
325
-
326
- **3. Simulator authentication failed**
327
-
328
- ```
329
- Invalid simulator cookie format
330
- ```
331
-
332
- **Solution**: Ensure `FlowChat::Config.simulator_secret` is properly configured.
333
-
334
- **4. Missing simulator secret**
335
-
336
- ```
337
- Simulator secret not configured
338
- ```
339
-
340
- **Solution**: Set `FLOWCHAT_SIMULATOR_SECRET` environment variable or configure in initializer.
341
-
342
- ### Debug Mode
343
-
344
- Enable debug logging for security events:
345
-
346
- ```ruby
347
- # config/initializers/flowchat.rb
348
- if Rails.env.development?
349
- FlowChat::Config.logger.level = Logger::DEBUG
350
- end
351
- ```
352
-
353
- This will log security validation attempts and help troubleshoot configuration issues.
354
-
355
- ## Security Updates
356
-
357
- This security system was introduced in FlowChat v2.0.0 and includes:
358
-
359
- - HMAC-SHA256 webhook signature validation
360
- - Secure simulator authentication with signed cookies
361
- - Environment-specific security configuration
362
- - Comprehensive error handling and logging
363
- - Timing-attack resistant signature comparison
364
-
365
- For the latest security updates and recommendations, check the FlowChat changelog and security advisories.
58
+ Thank you for helping keep FlowChat and its community safe.