* UX (view, style, JS) progress * base_data updates * More JS updates * Remove unnecessary param of author_id * Remove author_id from controller * Restrict email to admins * Introduce profile images * Remove base_data and update tag for source * Use .key? * I gotchu Codeclimate, don't worry :) * Add click event listeners to modal buttons * Refactor * More refactor * Refactor subscriber * Use userData() for subscriber * Reorganize * Code cleanup * Add subscription API call and favor textContent * Fix API call and showSubscribed * Add Apple Auth logic and change links to buttons * Update success message * Add Apple email check and spec * Fix default sign in state * Remove email from async_info :( * Refactor markdown classes * Single quote consistency * Modal bug attempt & subscriber image on success * Refactor passing source to tags and fix preview
90 lines
3.1 KiB
Ruby
90 lines
3.1 KiB
Ruby
class UserSubscriptionsController < ApplicationController
|
|
before_action :authenticate_user!
|
|
|
|
USER_SUBSCRIPTION_PARAMS = %i[source_type source_id subscriber_email].freeze
|
|
|
|
def subscribed
|
|
params.require(%i[source_type source_id])
|
|
source_type = params[:source_type]
|
|
source_id = params[:source_id]
|
|
|
|
is_subscribed = UserSubscriptions::SubscriptionCacheChecker.call(current_user, source_type, source_id)
|
|
|
|
render json: { is_subscribed: is_subscribed, success: true }, status: :ok
|
|
end
|
|
|
|
def create
|
|
rate_limit!(:user_subscription_creation)
|
|
|
|
source_type = user_subscription_params[:source_type]
|
|
return error_response("invalid source_type") unless UserSubscription::ALLOWED_TYPES.include?(source_type)
|
|
|
|
source_id = user_subscription_params[:source_id]
|
|
user_subscription_source = source_type.constantize.find_by(id: source_id)
|
|
return error_response("source not found") unless active_source?(source_type, user_subscription_source)
|
|
|
|
unless user_subscription_tag_enabled?(source_type, user_subscription_source)
|
|
return error_response("user subscriptions are not enabled for the requested source")
|
|
end
|
|
|
|
return error_response("subscriber email mismatch") if subscriber_email_stale?
|
|
return error_response("cannot subscribe with Apple private relay email") if subscriber_authed_with_apple?
|
|
|
|
@user_subscription = user_subscription_source.build_user_subscription(current_user)
|
|
|
|
if @user_subscription.save
|
|
rate_limiter.track_limit_by_action(:user_subscription_creation)
|
|
render json: { message: "success", success: true }, status: :ok
|
|
else
|
|
error_response(@user_subscription.errors.full_messages.to_sentence)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def subscriber_authed_with_apple?
|
|
current_user.email.end_with?("@privaterelay.appleid.com")
|
|
end
|
|
|
|
def user_subscription_tag_enabled?(source_type, user_subscription_source)
|
|
liquid_tags =
|
|
case source_type
|
|
when "Article"
|
|
user_subscription_source.liquid_tags_used(:body)
|
|
else
|
|
user_subscription_source.liquid_tags_used
|
|
end
|
|
|
|
liquid_tags.include?(UserSubscriptionTag)
|
|
end
|
|
|
|
def active_source?(source_type, user_subscription_source)
|
|
return false unless user_subscription_source
|
|
|
|
# Don't create new user subscriptions for inactive sources
|
|
# (i.e. unpublished Articles, deleted Comments, etc.)
|
|
case source_type
|
|
when "Article"
|
|
user_subscription_source.published?
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
def error_response(msg)
|
|
render json: { error: msg, success: false }, status: :unprocessable_entity
|
|
end
|
|
|
|
# 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.
|
|
def subscriber_email_stale?
|
|
current_user&.email != user_subscription_params[:subscriber_email]
|
|
end
|
|
|
|
def user_subscription_params
|
|
params.require(:user_subscription).permit(USER_SUBSCRIPTION_PARAMS)
|
|
end
|
|
end
|