71 lines
2.3 KiB
Ruby
71 lines
2.3 KiB
Ruby
module UserSubscriptions
|
|
# When creating a UserSubscription from a controller/user interaction on the
|
|
# frontend, we need to do some extra validations and logic.
|
|
class CreateFromControllerParams
|
|
attr_reader :user, :source_type, :source_id, :subscriber_email, :response
|
|
|
|
Response = Struct.new(:success, :data, :error, keyword_init: true)
|
|
|
|
def self.call(...)
|
|
new(...).call
|
|
end
|
|
|
|
def initialize(user, user_subscription_params)
|
|
@user = user
|
|
@source_type = user_subscription_params[:source_type]
|
|
@source_id = user_subscription_params[:source_id]
|
|
@response = Response.new(success: false)
|
|
|
|
# TODO: [@forem/delightful]: uncomment this once email confirmation is re-enabled
|
|
# @subscriber_email = user_subscription_params[:subscriber_email]
|
|
end
|
|
|
|
def call
|
|
return response if invalid_source_type?
|
|
|
|
source = source_type.constantize.find_by(id: source_id)
|
|
return response if invalid_source?(source)
|
|
|
|
# TODO: [@forem/delightful]: uncomment this once email confirmation is re-enabled
|
|
# return response if subscriber_email_mismatch?
|
|
|
|
user_subscription = source.build_user_subscription(user)
|
|
if user_subscription.save
|
|
response.success = true
|
|
response.data = user_subscription
|
|
else
|
|
response.error = user_subscription.errors_as_sentence
|
|
end
|
|
|
|
response
|
|
end
|
|
|
|
private
|
|
|
|
def invalid_source_type?
|
|
return false if UserSubscription::ALLOWED_TYPES.include?(source_type)
|
|
|
|
response.error = "Invalid source_type."
|
|
true
|
|
end
|
|
|
|
def invalid_source?(source)
|
|
return false if source
|
|
|
|
response.error = I18n.t("services.user_subscriptions.create_from_controller_params.source_not_found")
|
|
true
|
|
end
|
|
|
|
def subscriber_email_mismatch?
|
|
# This checks if the email address the user saw/consented to share is the
|
|
# same as their current email address. A mismatch occurs if a user updates
|
|
# their email address in a new/separate tab and then tries to subscribe on
|
|
# the old/stale tab without refreshing. In that case, the user would have
|
|
# consented to share their old email address instead of the current one.
|
|
return false if user.email == subscriber_email
|
|
|
|
response.error = I18n.t("services.user_subscriptions.create_from_controller_params.email_mismatch")
|
|
true
|
|
end
|
|
end
|
|
end
|