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