Merge branch 'contact-support-directly'

Stephen Paul Weber created

* contact-support-directly:
  Switch from unbilled to direct targets
  Allow SGX with a node

Change summary

config-schema.dhall |  2 +-
config.dhall.sample |  4 +++-
lib/backend_sgx.rb  |  5 ++++-
sgx_jmp.rb          | 32 +++++++++++++++++++++++++++++---
4 files changed, 37 insertions(+), 6 deletions(-)

Detailed changes

config-schema.dhall 🔗

@@ -15,6 +15,7 @@
 , component : { jid : Text, secret : Text }
 , credit_card_url : forall (jid : Text) -> forall (customer_id : Text) -> Text
 , creds : { account : Text, password : Text, username : Text }
+, direct_targets : List { mapKey : Text, mapValue : Text }
 , electrum : { rpc_password : Text, rpc_uri : Text, rpc_username : Text }
 , electrum_notify_url :
     forall (address : Text) -> forall (customer_id : Text) -> Text
@@ -45,7 +46,6 @@
 , sip : { app : Text, realm : Text }
 , sip_host : Text
 , snikket_hosting_api : Text
-, unbilled_targets : List Text
 , upstream_domain : Text
 , web : < Inet : { interface : Text, port : Natural } | Unix : Text >
 , web_register : { from : Text, to : Text }

config.dhall.sample 🔗

@@ -76,7 +76,9 @@ in
 	payable = "",
 	notify_from = "+15551234567@example.net",
 	admins = ["test\\40example.com@example.net"],
-	unbilled_targets = ["+14169938000"],
+	direct_targets = toMap {
+		`+15551234567` = "support@example.com"
+	},
 	keep_area_codes = ["555"],
 	keep_area_codes_in = { account = "", site_id = "", sip_peer_id = "" },
 	snikket_hosting_api = "",

lib/backend_sgx.rb 🔗

@@ -36,7 +36,10 @@ class BackendSgx
 
 	def stanza(s)
 		s.dup.tap do |stanza|
-			stanza.to = stanza.to.with(domain: jid.domain)
+			stanza.to = stanza.to.with(
+				domain: jid.domain,
+				node: jid.node || stanza.to.node
+			)
 			stanza.from = from_jid.with(resource: stanza.from.resource)
 		end
 	end

sgx_jmp.rb 🔗

@@ -310,11 +310,9 @@ end
 # Especially if we have the component join MUC for notifications
 message(type: :groupchat) { true }
 
-UNBILLED_TARGETS = Set.new(CONFIG[:unbilled_targets])
 def billable_message(m)
 	b = m.body
-	!UNBILLED_TARGETS.member?(m.to.node) && \
-		(b && !b.empty? || m.find("ns:x", ns: OOB.registered_ns).first)
+	b && !b.empty? || m.find("ns:x", ns: OOB.registered_ns).first
 end
 
 class OverLimit < StandardError
@@ -337,6 +335,34 @@ end
 
 class CustomerExpired < StandardError; end
 
+CONFIG[:direct_targets].each do |(tel, jid)|
+	customer_repo = CustomerRepo.new(
+		sgx_repo: TrivialBackendSgxRepo.new(jid: jid),
+		set_user: Sentry.method(:set_user)
+	)
+
+	message to: /\A#{Regexp.escape(tel)}@#{CONFIG[:component][:jid]}\/?/ do |m|
+		customer_repo.find_by_jid(m.from.stripped).then { |customer|
+			customer.stanza_from(m)
+		}.catch_only(CustomerRepo::NotFound) {
+			# This should not happen, but let's still get the message
+			# to support at least if it does
+			m.from = ProxiedJID.proxy(m.from, CONFIG[:component][:jid])
+			m.to = jid
+			BLATHER << m
+		}
+	end
+
+	message to: /\Acustomer_/, from: /\A#{Regexp.escape(jid)}\/?/ do |m|
+		customer_repo.find(m.to.node.delete_prefix("customer_")).then { |customer|
+			m.from = "#{tel}@sgx-jmp" # stanza_to will fix domain
+			customer.stanza_to(m)
+		}.catch_only(CustomerRepo::NotFound) { |e|
+			BLATHER << m.as_error("item-not-found", :cancel, e.message)
+		}
+	end
+end
+
 message do |m|
 	StatsD.increment("message")