1# frozen_string_literal: true
2
3require "erb"
4require "ruby-bandwidth-iris"
5require "securerandom"
6
7require_relative "./alt_top_up_form"
8require_relative "./bandwidth_tn_order"
9require_relative "./bandwidth_tn_reservation_repo"
10require_relative "./command"
11require_relative "./em"
12require_relative "./invites_repo"
13require_relative "./oob"
14require_relative "./parent_code_repo"
15require_relative "./proxied_jid"
16require_relative "./tel_selections"
17require_relative "./welcome_message"
18
19class Registration
20 def self.for(customer, google_play_userid, tel_selections)
21 if (reg = customer.registered?)
22 Registered.for(customer, reg.phone)
23 else
24 tel_selections[customer.jid].then(&:choose_tel).then do |tel|
25 reserve_and_continue(tel_selections, customer, tel).then do
26 FinishOrStartActivation.for(customer, google_play_userid, tel)
27 end
28 end
29 end
30 end
31
32 def self.reserve_and_continue(tel_selections, customer, tel)
33 tel.reserve(customer).catch do
34 tel_selections.delete(customer.jid).then {
35 tel_selections[customer.jid]
36 }.then { |choose|
37 choose.choose_tel(
38 error: "The JMP number #{tel} is no longer available."
39 )
40 }.then { |n_tel| reserve_and_continue(tel_selections, customer, n_tel) }
41 end
42 end
43
44 class Registered
45 def self.for(customer, tel)
46 jid = ProxiedJID.new(customer.jid).unproxied
47 if jid.domain == CONFIG[:onboarding_domain]
48 FinishOnboarding.for(customer, tel)
49 else
50 new(tel)
51 end
52 end
53
54 def initialize(tel)
55 @tel = tel
56 end
57
58 def write
59 Command.finish("You are already registered with JMP number #{@tel}")
60 end
61 end
62
63 class FinishOrStartActivation
64 def self.for(customer, google_play_userid, tel)
65 if customer.active?
66 Finish.new(customer, tel)
67 elsif customer.balance >= CONFIG[:activation_amount_accept]
68 BillPlan.new(customer, tel)
69 else
70 new(customer, google_play_userid, tel)
71 end
72 end
73
74 def initialize(customer, google_play_userid, tel)
75 @customer = customer
76 @tel = tel
77 @google_play_userid = google_play_userid
78 end
79
80 def write
81 Command.reply { |reply|
82 reply.allowed_actions = [:next]
83 reply.note_type = :info
84 reply.note_text = File.read("#{__dir__}/../fup.txt")
85 }.then { Activation.for(@customer, @google_play_userid, @tel).write }
86 end
87 end
88
89 class Activation
90 def self.for(customer, google_play_userid, tel)
91 jid = ProxiedJID.new(customer.jid).unproxied
92 if CONFIG[:approved_domains].key?(jid.domain.to_sym)
93 Allow.for(customer, tel, jid)
94 elsif google_play_userid
95 GooglePlay.new(customer, google_play_userid, tel)
96 else
97 new(customer, tel)
98 end
99 end
100
101 def initialize(customer, tel)
102 @customer = customer
103 @tel = tel
104 @invites = InvitesRepo.new(DB, REDIS)
105 end
106
107 attr_reader :customer, :tel
108
109 def form
110 FormTemplate.render("registration/activate", tel: tel)
111 end
112
113 def write
114 Command.reply { |reply|
115 reply.allowed_actions = [:next]
116 reply.command << form
117 }.then(&method(:next_step))
118 end
119
120 def next_step(iq)
121 code = iq.form.field("code")&.value&.to_s
122 save_customer_plan(iq, code).then {
123 finish_if_valid_invite(code)
124 }.catch_only(InvitesRepo::Invalid) do
125 @invites.stash_code(customer.customer_id, code).then do
126 Payment.for(iq, @customer, @tel).then(&:write)
127 end
128 end
129 end
130
131 protected
132
133 def finish_if_valid_invite(code)
134 @invites.claim_code(@customer.customer_id, code) {
135 @customer.activate_plan_starting_now
136 }.then do
137 Finish.new(@customer, @tel).write
138 end
139 end
140
141 def save_customer_plan(iq, code)
142 ParentCodeRepo.new(redis: REDIS, db: DB).find(code).then do |parent|
143 plan = Plan.for_registration(iq.form.field("plan_name").value.to_s)
144 @customer = @customer.with_plan(plan.name, parent_customer_id: parent)
145 @customer.save_plan!
146 end
147 end
148
149 class GooglePlay
150 def initialize(customer, google_play_userid, tel)
151 @customer = customer
152 @google_play_userid = google_play_userid
153 @tel = tel
154 @invites = InvitesRepo.new(DB, REDIS)
155 @parent_code_repo = ParentCodeRepo.new(redis: REDIS, db: DB)
156 end
157
158 def used
159 REDIS.sismember("google_play_userids", @google_play_userid)
160 end
161
162 def form
163 FormTemplate.render(
164 "registration/google_play",
165 tel: @tel
166 )
167 end
168
169 def write
170 used.then do |u|
171 next Activation.for(@customer, nil, @tel).write if u.to_s == "1"
172
173 Command.reply { |reply|
174 reply.allowed_actions = [:next]
175 reply.command << form
176 }.then(&method(:activate)).then do
177 Finish.new(@customer, @tel).write
178 end
179 end
180 end
181
182 def activate(iq)
183 plan = Plan.for_registration(iq.form.field("plan_name").value)
184 code = iq.form.field("code")&.value
185 EMPromise.all([
186 @parent_code_repo.find(code),
187 REDIS.sadd("google_play_userids", @google_play_userid)
188 ]).then { |(parent, _)|
189 save_active_plan(plan, parent)
190 }.then do
191 use_referral_code(code)
192 end
193 end
194
195 protected
196
197 def save_bogus_transaction
198 Transaction.new(
199 customer_id: @customer.customer_id,
200 transaction_id: "google_play_#{@customer.customer_id}",
201 amount: 0,
202 note: "Activated via Google Play",
203 bonus_eligible?: false
204 ).insert
205 end
206
207 def save_active_plan(plan, parent)
208 @customer = @customer.with_plan(plan.name, parent_customer_id: parent)
209 save_bogus_transaction.then do
210 @customer.activate_plan_starting_now
211 end
212 end
213
214 def use_referral_code(code)
215 EMPromise.resolve(nil).then {
216 @invites.claim_code(@customer.customer_id, code) {
217 @customer.extend_plan
218 }
219 }.catch_only(InvitesRepo::Invalid) do
220 @invites.stash_code(@customer.customer_id, code)
221 end
222 end
223 end
224
225 class Allow < Activation
226 def self.for(customer, tel, jid)
227 credit_to = CONFIG[:approved_domains][jid.domain.to_sym]
228 new(customer, tel, credit_to)
229 end
230
231 def initialize(customer, tel, credit_to)
232 super(customer, tel)
233 @credit_to = credit_to
234 end
235
236 def form
237 FormTemplate.render(
238 "registration/allow",
239 tel: tel,
240 domain: customer.jid.domain
241 )
242 end
243
244 def next_step(iq)
245 plan = Plan.for_registration(iq.form.field("plan_name").value.to_s)
246 @customer = customer.with_plan(plan.name)
247 EMPromise.resolve(nil).then { activate }.then do
248 Finish.new(customer, tel).write
249 end
250 end
251
252 protected
253
254 def activate
255 DB.transaction do
256 if @credit_to
257 InvitesRepo.new(DB, REDIS).create_claimed_code(
258 @credit_to,
259 customer.customer_id
260 )
261 end
262 @customer.activate_plan_starting_now
263 end
264 end
265 end
266 end
267
268 module Payment
269 def self.kinds
270 @kinds ||= {}
271 end
272
273 def self.for(iq, customer, tel, final_message: nil, finish: Finish)
274 kinds.fetch(iq.form.field("activation_method")&.value&.to_s&.to_sym) {
275 raise "Invalid activation method"
276 }.call(customer, tel, final_message: final_message, finish: finish)
277 end
278
279 class CryptoPaymentMethod
280 def crypto_addrs
281 raise NotImplementedError, "Subclass must implement"
282 end
283
284 def reg_form_name
285 raise NotImplementedError, "Subclass must implement"
286 end
287
288 def sell_prices
289 raise NotImplementedError, "Subclass must implement"
290 end
291
292 def initialize(customer, tel, final_message: nil, **)
293 @customer = customer
294 @customer_id = customer.customer_id
295 @tel = tel
296 @final_message = final_message
297 end
298
299 def save
300 TEL_SELECTIONS.set(@customer.jid, @tel)
301 end
302
303 attr_reader :customer_id, :tel
304
305 def form(rate, addr)
306 amount = CONFIG[:activation_amount] / rate
307
308 FormTemplate.render(
309 reg_form_name,
310 amount: amount,
311 addr: addr,
312 final_message: @final_message
313 )
314 end
315
316 def write
317 EMPromise.all([addr_and_rate, save]).then do |((addr, rate), _)|
318 Command.reply { |reply|
319 reply.allowed_actions = [:prev]
320 reply.status = :canceled
321 reply.command << form(rate, addr)
322 }.then(&method(:handle_possible_prev))
323 end
324 end
325 protected
326 def handle_possible_prev(iq)
327 raise "Action not allowed" unless iq.prev?
328
329 Activation.for(@customer, nil, @tel).then(&:write)
330 end
331
332 def addr_and_rate
333 EMPromise.all([
334 self.crypto_addrs.then { |addrs|
335 addrs.first || self.add_crypto_addr
336 },
337
338 sell_prices.public_send(@customer.currency.to_s.downcase)
339 ])
340 end
341 end
342
343 class Bitcoin < CryptoPaymentMethod
344 Payment.kinds[:bitcoin] = method(:new)
345
346 def reg_form_name
347 "registration/btc"
348 end
349
350 def sell_prices
351 BTC_SELL_PRICES
352 end
353
354 def crypto_addrs
355 @customer.btc_addresses
356 end
357
358 def add_crypto_addr
359 @customer.add_btc_address
360 end
361 end
362
363 ## Like Bitcoin
364 class BCH < CryptoPaymentMethod
365 Payment.kinds[:bch] = method(:new)
366
367 def reg_form_name
368 "registration/bch"
369 end
370
371 def sell_prices
372 BCH_SELL_PRICES
373 end
374
375 def crypto_addrs
376 @customer.bch_addresses
377 end
378
379 def add_crypto_addr
380 @customer.add_bch_address
381 end
382 end
383
384
385 class CreditCard
386 Payment.kinds[:credit_card] = ->(*args, **kw) { self.for(*args, **kw) }
387
388 def self.for(in_customer, tel, finish: Finish, **)
389 reload_customer(in_customer).then do |(customer, payment_methods)|
390 if customer.balance >= CONFIG[:activation_amount_accept]
391 next BillPlan.new(customer, tel, finish: finish)
392 end
393
394 if (method = payment_methods.default_payment_method)
395 next Activate.new(customer, method, tel, finish: finish)
396 end
397
398 new(customer, tel, finish: finish)
399 end
400 end
401
402 def self.reload_customer(customer)
403 EMPromise.all([
404 Command.execution.customer_repo.find(customer.customer_id),
405 customer.payment_methods
406 ])
407 end
408
409 def initialize(customer, tel, finish: Finish)
410 @customer = customer
411 @tel = tel
412 @finish = finish
413 end
414
415 def oob(reply)
416 oob = OOB.find_or_create(reply.command)
417 oob.url = CONFIG[:credit_card_url].call(
418 reply.to.stripped.to_s.gsub("\\", "%5C"),
419 @customer.customer_id
420 ) + "&amount=#{CONFIG[:activation_amount]}"
421 oob.desc = "Add credit card, save, then next here to continue"
422 oob
423 end
424
425 def write
426 Command.reply { |reply|
427 reply.allowed_actions = [:next, :prev]
428 toob = oob(reply)
429 reply.note_type = :info
430 reply.note_text = "#{toob.desc}: #{toob.url}"
431 }.then do |iq|
432 next Activation.for(@customer, nil, @tel).then(&:write) if iq.prev?
433
434 CreditCard.for(@customer, @tel, finish: @finish).then(&:write)
435 end
436 end
437
438 class Activate
439 def initialize(customer, payment_method, tel, finish: Finish)
440 @customer = customer
441 @payment_method = payment_method
442 @tel = tel
443 @finish = finish
444 end
445
446 def write
447 CreditCardSale.create(
448 @customer,
449 amount: CONFIG[:activation_amount],
450 payment_method: @payment_method
451 ).then(
452 ->(_) { sold },
453 ->(_) { declined }
454 )
455 end
456
457 protected
458
459 def sold
460 BillPlan.new(@customer, @tel, finish: @finish).write
461 end
462
463 DECLINE_MESSAGE =
464 "Your bank declined the transaction. " \
465 "Often this happens when a person's credit card " \
466 "is a US card that does not support international " \
467 "transactions, as JMP is not based in the USA, though " \
468 "we do support transactions in USD.\n\n" \
469 "You may add another card"
470
471 def decline_oob(reply)
472 oob = OOB.find_or_create(reply.command)
473 oob.url = CONFIG[:credit_card_url].call(
474 reply.to.stripped.to_s.gsub("\\", "%5C"),
475 @customer.customer_id
476 ) + "&amount=#{CONFIG[:activation_amount]}"
477 oob.desc = DECLINE_MESSAGE
478 oob
479 end
480
481 def declined
482 Command.reply { |reply|
483 reply_oob = decline_oob(reply)
484 reply.allowed_actions = [:next]
485 reply.note_type = :error
486 reply.note_text = "#{reply_oob.desc}: #{reply_oob.url}"
487 }.then do
488 CreditCard.for(@customer, @tel, finish: @finish).then(&:write)
489 end
490 end
491 end
492 end
493
494 class InviteCode
495 Payment.kinds[:code] = ->(*args, **kw) { self.for(*args, **kw) }
496
497 def self.for(in_customer, tel, finish: Finish, **)
498 reload_customer(in_customer).then do |customer|
499 if customer.balance >= CONFIG[:activation_amount_accept]
500 next BillPlan.new(customer, tel, finish: finish)
501 end
502
503 msg = if customer.balance.positive?
504 "Account balance not enough to cover the activation"
505 end
506 new(customer, tel, error: msg, finish: Finish)
507 end
508 end
509
510 def self.reload_customer(customer)
511 Command.execution.customer_repo.find(customer.customer_id)
512 end
513
514 FIELDS = [{
515 var: "code",
516 type: "text-single",
517 label: "Your referral code",
518 required: true
519 }].freeze
520
521 def initialize(customer, tel, error: nil, finish: Finish, **)
522 @customer = customer
523 @tel = tel
524 @error = error
525 @finish = finish
526 @parent_code_repo = ParentCodeRepo.new(redis: REDIS, db: DB)
527 end
528
529 def add_form(reply)
530 form = reply.form
531 form.type = :form
532 form.title = "Enter Referral Code"
533 form.instructions = @error if @error
534 form.fields = FIELDS
535 end
536
537 def write
538 Command.reply { |reply|
539 reply.allowed_actions = [:next, :prev]
540 add_form(reply)
541 }.then(&method(:parse))
542 end
543
544 def parse(iq)
545 return Activation.for(@customer, nil, @tel).then(&:write) if iq.prev?
546
547 verify(iq.form.field("code")&.value&.to_s)
548 .catch_only(InvitesRepo::Invalid, &method(:invalid_code))
549 .then(&:write)
550 end
551
552 protected
553
554 def invalid_code(e)
555 InviteCode.new(@customer, @tel, error: e.message)
556 end
557
558 def customer_id
559 @customer.customer_id
560 end
561
562 def verify(code)
563 @parent_code_repo.find(code).then do |parent_customer_id|
564 if parent_customer_id
565 set_parent(parent_customer_id)
566 else
567 InvitesRepo.new(DB, REDIS).claim_code(customer_id, code) {
568 @customer.activate_plan_starting_now
569 }.then { Finish.new(@customer, @tel) }
570 end
571 end
572 end
573
574 def set_parent(parent_customer_id)
575 @customer = @customer.with_plan(
576 @customer.plan_name,
577 parent_customer_id: parent_customer_id
578 )
579 @customer.save_plan!.then do
580 self.class.for(@customer, @tel, finish: @finish)
581 end
582 end
583 end
584
585 class Mail
586 Payment.kinds[:mail] = method(:new)
587
588 def initialize(customer, tel, final_message: nil, **)
589 @customer = customer
590 @tel = tel
591 @final_message = final_message
592 end
593
594 def form
595 FormTemplate.render(
596 "registration/mail",
597 currency: @customer.currency,
598 final_message: @final_message,
599 **onboarding_extras
600 )
601 end
602
603 def onboarding_extras
604 jid = ProxiedJID.new(@customer.jid).unproxied
605 return {} unless jid.domain == CONFIG[:onboarding_domain]
606
607 {
608 customer_id: @customer.customer_id,
609 in_note: "Customer ID"
610 }
611 end
612
613 def write
614 Command.reply { |reply|
615 reply.allowed_actions = [:prev]
616 reply.status = :canceled
617 reply.command << form
618 }.then { |iq|
619 raise "Action not allowed" unless iq.prev?
620
621 Activation.for(@customer, nil, @tel).then(&:write)
622 }
623 end
624 end
625 end
626
627 class BillPlan
628 def initialize(customer, tel, finish: Finish)
629 @customer = customer
630 @tel = tel
631 @finish = finish
632 end
633
634 def write
635 @customer.bill_plan(note: "Bill #{@tel} for first month").then do
636 @finish.new(@customer, @tel).write
637 end
638 end
639 end
640
641 class Finish
642 def initialize(customer, tel)
643 @customer = customer
644 @tel = tel
645 @invites = InvitesRepo.new(DB, REDIS)
646 end
647
648 def write
649 @tel.order(DB, @customer).then(
650 ->(_) { customer_active_tel_purchased },
651 method(:number_purchase_error)
652 )
653 end
654
655 protected
656
657 def number_purchase_error(e)
658 Command.log.error "number_purchase_error", e
659 TEL_SELECTIONS.delete(@customer.jid).then {
660 TEL_SELECTIONS[@customer.jid]
661 }.then { |choose|
662 choose.choose_tel(
663 error: "The JMP number #{@tel} is no longer available."
664 )
665 }.then { |tel| Finish.new(@customer, tel).write }
666 end
667
668 def raise_setup_error(e)
669 Command.log.error "@customer.register! failed", e
670 Command.finish(
671 "There was an error setting up your number, " \
672 "please contact JMP support.",
673 type: :error
674 )
675 end
676
677 def put_default_fwd
678 Bwmsgsv2Repo.new.put_fwd(@customer.customer_id, @tel.tel, CustomerFwd.for(
679 uri: "xmpp:#{@customer.jid}",
680 voicemail_enabled: true
681 ))
682 end
683
684 def use_referral_code
685 @invites.use_pending_group_code(@customer.customer_id).then do |credit_to|
686 next unless credit_to
687
688 Transaction.new(
689 customer_id: @customer.customer_id,
690 transaction_id: "referral_#{@customer.customer_id}_#{credit_to}",
691 amount: @customer.monthly_price,
692 note: "Referral Bonus",
693 bonus_eligible?: false
694 ).insert
695 end
696 end
697
698 def customer_active_tel_purchased
699 @customer.register!(@tel.tel).catch(&method(:raise_setup_error)).then {
700 EMPromise.all([
701 TEL_SELECTIONS.delete(@customer.jid),
702 put_default_fwd,
703 use_referral_code
704 ])
705 }.then do
706 FinishOnboarding.for(@customer, @tel).then(&:write)
707 end
708 end
709 end
710
711 module FinishOnboarding
712 def self.for(customer, tel, db: LazyObject.new { DB })
713 jid = ProxiedJID.new(customer.jid).unproxied
714 if jid.domain == CONFIG[:onboarding_domain]
715 Snikket.for(customer, tel, db: db)
716 else
717 NotOnboarding.new(customer, tel)
718 end
719 end
720
721 class Snikket
722 def self.for(customer, tel, db:)
723 ::Snikket::Repo.new(db: db).find_by_customer(customer).then do |is|
724 if is.empty?
725 new(customer, tel, db: db)
726 elsif is[0].bootstrap_token.empty?
727 # This is a need_dns one, try the launch again
728 new(customer, tel, db: db).launch(is[0].domain)
729 else
730 GetInvite.for(customer, is[0], tel, db: db)
731 end
732 end
733 end
734
735 def initialize(customer, tel, error: nil, old: nil, db:)
736 @customer = customer
737 @tel = tel
738 @error = error
739 @db = db
740 @old = old
741 end
742
743 ACTION_VAR = "http://jabber.org/protocol/commands#actions"
744
745 def form
746 FormTemplate.render(
747 "registration/snikket",
748 tel: @tel,
749 error: @error
750 )
751 end
752
753 def write
754 Command.reply { |reply|
755 reply.allowed_actions = [:next]
756 reply.command << form
757 }.then(&method(:next_step))
758 end
759
760 def next_step(iq)
761 subdomain = empty_nil(iq.form.field("subdomain")&.value)
762 domain = "#{subdomain}.snikket.chat"
763 if iq.form.field(ACTION_VAR)&.value == "custom_domain"
764 CustomDomain.new(@customer, @tel, old: @old).write
765 elsif @old && (!subdomain || domain == @old.domain)
766 GetInvite.for(@customer, @old, @tel, db: @db).then(&:write)
767 else
768 launch(domain)
769 end
770 end
771
772 def launch(domain)
773 IQ_MANAGER.write(::Snikket::Launch.new(
774 nil, CONFIG[:snikket_hosting_api], domain: domain
775 )).then { |launched|
776 save_instance_and_wait(domain, launched)
777 }.catch { |e|
778 next EMPromise.reject(e) unless e.respond_to?(:text)
779
780 Snikket.new(@customer, @tel, old: @old, error: e.text, db: @db).write
781 }
782 end
783
784 def save_instance_and_wait(domain, launched)
785 instance = ::Snikket::CustomerInstance.for(@customer, domain, launched)
786 repo = ::Snikket::Repo.new(db: @db)
787 (@old&.domain == domain ? EMPromise.resolve(nil) : repo.del(@old))
788 .then { repo.put(instance) }.then do
789 if launched.status == :needs_dns
790 NeedsDNS.new(@customer, instance, @tel, launched.records).write
791 else
792 GetInvite.for(@customer, instance, @tel, db: @db).then(&:write)
793 end
794 end
795 end
796
797 def empty_nil(s)
798 s.nil? || s.empty? ? nil : s
799 end
800
801 class NeedsDNS < Snikket
802 def initialize(customer, instance, tel, records, db: DB)
803 @customer = customer
804 @instance = instance
805 @tel = tel
806 @records = records
807 @db = db
808 end
809
810 def form
811 FormTemplate.render(
812 "registration/snikket_needs_dns",
813 records: @records
814 )
815 end
816
817 def write
818 Command.reply { |reply|
819 reply.allowed_actions = [:prev, :next]
820 reply.command << form
821 }.then do |iq|
822 if iq.prev?
823 CustomDomain.new(@customer, @tel, old: @instance).write
824 else
825 launch(@instance.domain)
826 end
827 end
828 end
829 end
830
831 class GetInvite
832 def self.for(customer, instance, tel, db: DB)
833 instance.fetch_invite.then do |xmpp_uri|
834 if xmpp_uri
835 GoToInvite.new(xmpp_uri)
836 else
837 new(customer, instance, tel, db: db)
838 end
839 end
840 end
841
842 def initialize(customer, instance, tel, db: DB)
843 @customer = customer
844 @instance = instance
845 @tel = tel
846 @db = db
847 end
848
849 def form
850 FormTemplate.render(
851 "registration/snikket_wait",
852 domain: @instance.domain
853 )
854 end
855
856 def write
857 Command.reply { |reply|
858 reply.allowed_actions = [:prev, :next]
859 reply.command << form
860 }.then do |iq|
861 if iq.prev?
862 Snikket.new(@customer, @tel, old: @instance, db: @db).write
863 else
864 GetInvite.for(@customer, @instance, @tel, db: @db).then(&:write)
865 end
866 end
867 end
868 end
869
870 class GoToInvite
871 def initialize(xmpp_uri)
872 @xmpp_uri = xmpp_uri
873 end
874
875 def write
876 Command.finish do |reply|
877 oob = OOB.find_or_create(reply.command)
878 oob.url = @xmpp_uri
879 end
880 end
881 end
882 end
883
884 class CustomDomain < Snikket
885 def initialize(customer, tel, old: nil, error: nil, db: DB)
886 @customer = customer
887 @tel = tel
888 @error = error
889 @old = old
890 @db = db
891 end
892
893 def form
894 FormTemplate.render(
895 "registration/snikket_custom",
896 tel: @tel,
897 error: @error
898 )
899 end
900
901 def write
902 Command.reply { |reply|
903 reply.allowed_actions = [:prev, :next]
904 reply.command << form
905 }.then do |iq|
906 if iq.prev?
907 Snikket.new(@customer, @tel, db: @db, old: @old).write
908 else
909 launch(empty_nil(iq.form.field("domain")&.value) || @old&.domain)
910 end
911 end
912 end
913 end
914
915 class NotOnboarding
916 def initialize(customer, tel)
917 @customer = customer
918 @tel = tel
919 end
920
921 def write
922 WelcomeMessage.new(@customer, @tel).welcome
923 Command.finish("Your JMP account has been activated as #{@tel}")
924 end
925 end
926 end
927end