Prevent double-activate

Stephen Paul Weber created

We're seeing trouble in production where users activate more than once, which
results in suboptimal DB contents.  If they're already active, just redirect
them back to complete registration.

Change summary

config.ru | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)

Detailed changes

config.ru 🔗

@@ -53,6 +53,13 @@ class Plan
 		BRAINTREE_CONFIG[:merchant_accounts][currency]
 	end
 
+	def self.active?(customer_id)
+		DB.exec_params(<<~SQL, [customer_id]).first&.[]("count").to_i > 0
+			SELECT count(1) AS count FROM customer_plans
+			WHERE customer_id=$1 AND expires_at > NOW()
+		SQL
+	end
+
 	def activate(customer_id, months)
 		DB.exec_params(
 			"INSERT INTO plan_log VALUES ($1, $2, $3, $4)",
@@ -232,15 +239,21 @@ class JmpPay < Roda
 				end
 
 				r.get do
-					render.call
+					if Plan.active?(gateway.customer_id)
+						r.redirect request.params["return_to"], 303
+					else
+						render.call
+					end
 				end
 
 				r.post do
-					result = gateway.buy_plan(
-						request.params["plan_name"],
-						5,
-						request.params["braintree_nonce"]
-					)
+					result = DB.transaction do
+						Plan.active?(gateway.customer_id) || gateway.buy_plan(
+							request.params["plan_name"],
+							5,
+							request.params["braintree_nonce"]
+						)
+					end
 					if result
 						r.redirect request.params["return_to"], 303
 					else