[privacy] remove Community Chatwoot Hub egress

Remove Community Chatwoot Hub URL/push relay/sync/registration/event/changelog
egress. changelog.js becomes a local empty-feed adapter (no axios/fetch/network)
exporting the default ChangelogApi; links.js drops the Hub changelog URL.
lib/chatwoot_hub.rb removes base_url/push_notification_url/billing_base_url/
instance_config/send_push/send_push_with_response; billing_url reads only an
explicit CHATWOOT_BILLING_URL env, HTTPS-only with host and no userinfo, and
never falls back to a Hub URL. Enterprise proprietary base_url override is
preserved (spec uses singleton_class.instance_methods(false) for edition-safety).
privacy_audit uses a narrow per-file/per-rule Enterprise exception (hub-url
only) and privacy_audit_test.sh proves forbidden Enterprise runtime lines are
still detected; deployment privacy guard unchanged. Approved by independent
five-key review deleg_49d6ee2e (passed=true, blocking arrays empty).
This commit is contained in:
Kunthawat Greethong
2026-08-16 07:37:52 +07:00
parent 2ef6fa554b
commit 8101395608
10 changed files with 146 additions and 73 deletions

View File

@@ -1,28 +1,12 @@
require 'uri'
class ChatwootHub
DEFAULT_BASE_URL = 'https://hub.2.chatwoot.com'.freeze
def self.base_url
DEFAULT_BASE_URL
end
def self.push_notification_url
"#{base_url}/send_push"
end
def self.billing_base_url
"#{base_url}/billing"
end
def self.installation_identifier
identifier = InstallationConfig.find_by(name: 'INSTALLATION_IDENTIFIER')&.value
identifier ||= InstallationConfig.create!(name: 'INSTALLATION_IDENTIFIER', value: SecureRandom.uuid).value
identifier
end
def self.billing_url
"#{billing_base_url}?installation_identifier=#{installation_identifier}"
end
def self.pricing_plan
return 'community' unless ChatwootApp.enterprise?
@@ -35,6 +19,18 @@ class ChatwootHub
InstallationConfig.find_by(name: 'INSTALLATION_PRICING_PLAN_QUANTITY')&.value || 0
end
def self.billing_url
configured_url = ENV['CHATWOOT_BILLING_URL'].to_s
return if configured_url.empty?
uri = URI.parse(configured_url)
return unless uri.scheme == 'https' && uri.host.present? && uri.user.nil? && uri.password.nil?
configured_url
rescue URI::InvalidURIError
nil
end
def self.support_config
{
support_website_token: InstallationConfig.find_by(name: 'CHATWOOT_SUPPORT_WEBSITE_TOKEN')&.value,
@@ -43,28 +39,6 @@ class ChatwootHub
}
end
def self.instance_config
{
installation_identifier: installation_identifier,
installation_version: Chatwoot.config[:version],
installation_host: URI.parse(ENV.fetch('FRONTEND_URL', '')).host,
installation_env: ENV.fetch('INSTALLATION_ENV', ''),
edition: ENV.fetch('CW_EDITION', '')
}
end
def self.send_push(fcm_options)
send_push_with_response(fcm_options)
rescue *ExceptionList::REST_CLIENT_EXCEPTIONS => e
Rails.logger.error "Exception: #{e.message}"
rescue StandardError => e
ChatwootExceptionTracker.new(e).capture_exception
end
def self.send_push_with_response(fcm_options)
info = { fcm_options: fcm_options }
RestClient.post(push_notification_url, info.merge(instance_config).to_json, { content_type: :json, accept: :json })
end
end
ChatwootHub.singleton_class.prepend_mod_with('ChatwootHub')