From 0233d45874ba9667c3b99801a9fedc29ec7433a0 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Mon, 11 May 2020 20:45:32 -0500 Subject: [PATCH] fix double bass, reduce emails --- .../jam_ruby/constants/validation_messages.rb | 5 ++ ruby/lib/jam_ruby/models/instrument.rb | 1 + ruby/lib/jam_ruby/models/invited_user.rb | 26 +++++++ ruby/lib/jam_ruby/models/user.rb | 52 +++++++++++++ .../spec/jam_ruby/models/invited_user_spec.rb | 73 ++++++++++++++++++ ruby/spec/jam_ruby/models/user_spec.rb | 63 +++++++++++++++ ruby/spec/support/utilities.rb | 12 +++ .../content/icon_instrument_double_bass24.png | Bin 0 -> 961 bytes .../icon_instrument_double_bass256.png | Bin 0 -> 14033 bytes .../content/icon_instrument_double_bass45.png | Bin 0 -> 1990 bytes web/app/assets/javascripts/globals.js | 2 +- web/app/assets/javascripts/utils.js | 1 + .../api_live_streams_controller.rb | 12 ++- web/app/views/users/_user_dropdown.html.erb | 2 +- web/config/application.rb | 5 ++ web/spec/support/app_config.rb | 12 +++ 16 files changed, 262 insertions(+), 4 deletions(-) create mode 100644 web/app/assets/images/content/icon_instrument_double_bass24.png create mode 100644 web/app/assets/images/content/icon_instrument_double_bass256.png create mode 100644 web/app/assets/images/content/icon_instrument_double_bass45.png diff --git a/ruby/lib/jam_ruby/constants/validation_messages.rb b/ruby/lib/jam_ruby/constants/validation_messages.rb index a3a51621a..da90d06cd 100644 --- a/ruby/lib/jam_ruby/constants/validation_messages.rb +++ b/ruby/lib/jam_ruby/constants/validation_messages.rb @@ -43,6 +43,11 @@ module ValidationMessages INVALID_FPFILE = "is not valid" VERIFY_EMAIL = "You need to verify your email." + CHINESE_CANT_BE_MIXED = "must be all Chinese or Japanese" + CHINESE_NAME_TOO_LONG = "must be 4 characters or less when Chinese or Japanese" + NO_SPECIAL_CHARACTERS = "must not have special characters" + INVALID_NAME = "not valid" + # recurly RECURLY_ERROR = "Error occurred during Recurly transaction." RECURLY_ACCOUNT_ERROR = "You don't have Recurly account yet." diff --git a/ruby/lib/jam_ruby/models/instrument.rb b/ruby/lib/jam_ruby/models/instrument.rb index e8b407135..16b907301 100644 --- a/ruby/lib/jam_ruby/models/instrument.rb +++ b/ruby/lib/jam_ruby/models/instrument.rb @@ -27,6 +27,7 @@ module JamRuby "tuba" => "tuba", "ukulele" => "ukelele", "upright bass" => "upright_bass", + "double bass" => "double_bass", "viola" => "viola", "violin" => "violin", "voice" => "voice" diff --git a/ruby/lib/jam_ruby/models/invited_user.rb b/ruby/lib/jam_ruby/models/invited_user.rb index 16be90d84..ae93bf76b 100644 --- a/ruby/lib/jam_ruby/models/invited_user.rb +++ b/ruby/lib/jam_ruby/models/invited_user.rb @@ -26,6 +26,7 @@ module JamRuby validate :valid_personalized_invitation # validate :not_accepted_twice validate :not_accepted_twice, :if => lambda { |iu| iu.email_required? } + validate :spammer validate :can_invite? after_save :track_user_progression @@ -102,6 +103,31 @@ module JamRuby errors.add(:accepted, "you can only accept an invitation once") if accepted_twice end + # the same account should not receive emails within the same day + def spammer + max_invites_ever_per_sender + max_invites_per_day_per_sender + max_invites_to_receiver_per_day + end + + def max_invites_ever_per_sender + if InvitedUser.where(:sender => self.sender).count > APP_CONFIG.max_invites_ever_per_sender + errors.add(:base, "max invites sent by this account") + end + end + + def max_invites_per_day_per_sender + if InvitedUser.where(:sender => self.sender).where("created_at > ?", Time.now - 1.days).count > APP_CONFIG.max_invites_per_day_per_sender + errors.add(:base, "maximum number of invites sent in past 24 hours") + end + end + + def max_invites_to_receiver_per_day + if InvitedUser.where(:email => self.email).where("created_at > ?", Time.now - 1.days).count > APP_CONFIG.max_invites_to_receiver_per_day - 1 + errors.add(:base, "someone has already sent to #{self.email} in past 24 hours") + end + end + def one_facebook_invite_per_user rel = InvitedUser.where(:invite_medium => FB_MEDIUM, :sender_id => self.sender_id) rel = rel.where(['id != ?',self.id]) if self.id diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index a3942e9dc..e76563b35 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -291,9 +291,11 @@ module JamRuby validate :validate_update_email validate :validate_avatar_info validate :email_case_insensitive_uniqueness + validate :validate_spammy_names validate :update_email_case_insensitive_uniqueness, :if => :updating_email validate :validate_mods validate :presence_gift_card, :if => :expecting_gift_card + validate :validate_special_chars_names, :on => :create scope :musicians, -> { where(:musician => true) } scope :fans, -> { where(:musician => false) } @@ -529,6 +531,56 @@ module JamRuby end end + + def validate_special_chars_names + if name.include?("www") + errors.add(:first_name, ValidationMessages::INVALID_NAME) + elsif name.include?("http") + errors.add(:first_name, ValidationMessages::INVALID_NAME) + end + + if !first_name.nil? && first_name =~ /[\\*\\.\\&\\:\\%]/ + errors.add(:first_name, ValidationMessages::NO_SPECIAL_CHARACTERS) + elsif !last_name.nil? && last_name =~ /[\*\.\\&]/ + errors.add(:last_name, ValidationMessages::NO_SPECIAL_CHARACTERS) + end + end + + def validate_spammy_names + + test = "" + test += first_name if !first_name.nil? + test += last_name if !last_name.nil? + + if test == "" + return + end + + some_chinese = test !~ /\p{Han}/ + + any_chinese = (test =~ /\p{Han}/) != nil + + all_chinese = (test =~ /\p{^Han}/) == nil + + any_non_chinese = (test =~ /\p{^Han}/) != nil + + if any_chinese + # must be ALL chinese + if !all_chinese + errors.add(:first_name, ValidationMessages::CHINESE_CANT_BE_MIXED) + errors.add(:last_name, ValidationMessages::CHINESE_CANT_BE_MIXED) + elsif !first_name.nil? && first_name.length > 4 + errors.add(:first_name, ValidationMessages::CHINESE_NAME_TOO_LONG) + elsif !last_name.nil? && last_name.length > 4 + errors.add(:last_name, ValidationMessages::CHINESE_NAME_TOO_LONG) + end + end + + + + + end + def validate_avatar_info if updating_avatar # we want to mak sure that original_fpfile and cropped_fpfile seems like real fpfile info objects (i.e, json objects from filepicker.io) diff --git a/ruby/spec/jam_ruby/models/invited_user_spec.rb b/ruby/spec/jam_ruby/models/invited_user_spec.rb index a00db8a20..a9a6777e4 100644 --- a/ruby/spec/jam_ruby/models/invited_user_spec.rb +++ b/ruby/spec/jam_ruby/models/invited_user_spec.rb @@ -6,6 +6,79 @@ describe InvitedUser do UserMailer.deliveries.clear end + describe 'spammer' do + + after {Timecop.return} + + + let(:user1) { FactoryGirl.create(:user) } + + it 'max_invites_ever_per_sender' do + + Timecop.travel(Date.new(2016, 3, 20)) + + APP_CONFIG.max_invites_ever_per_sender.times do + invited_user = FactoryGirl.create(:invited_user, :sender => user1) + end + + invited_user = FactoryGirl.build(:invited_user, :sender => user1) + invited_user.save + invited_user.should_not be_valid + + # but move time forward... + + Timecop.travel(Date.new(2016, 3, 22)) + + # this should never 'heal'; once you hit max, you are done for good + invited_user = FactoryGirl.build(:invited_user, :sender => user1) + invited_user.save + invited_user.should_not be_valid + end + + it 'max_invites_per_day_per_sender' do + + Timecop.travel(Date.new(2016, 3, 20)) + + APP_CONFIG.max_invites_per_day_per_sender.times do + invited_user = FactoryGirl.create(:invited_user, :sender => user1) + end + + invited_user = FactoryGirl.build(:invited_user, :sender => user1) + invited_user.save + invited_user.should_not be_valid + + # but move time forward... + + Timecop.travel(Date.new(2016, 3, 22)) + + # this should work because we moved forward by 2 days + invited_user = FactoryGirl.create(:invited_user, :sender => user1) + end + + + it 'max_invites_to_receiver_per_day' do + + Timecop.travel(Date.new(2016, 3, 20)) + + APP_CONFIG.max_invites_to_receiver_per_day.times do + invited_user = FactoryGirl.create(:invited_user, :email => 'seth@jamkazam.com') + end + + invited_user = FactoryGirl.build(:invited_user, :email => 'seth@jamkazam.com') + invited_user.save + invited_user.should_not be_valid + + # but move time forward... + + Timecop.travel(Date.new(2016, 3, 22)) + + # this should work because we moved forward by 2 days + invited_user = FactoryGirl.create(:invited_user, :email => 'seth@jamkazam.com') + end + + + end + it 'create an invitation from end-user' do # create an end user diff --git a/ruby/spec/jam_ruby/models/user_spec.rb b/ruby/spec/jam_ruby/models/user_spec.rb index 0b8729dd9..ae6f1a3ed 100644 --- a/ruby/spec/jam_ruby/models/user_spec.rb +++ b/ruby/spec/jam_ruby/models/user_spec.rb @@ -98,6 +98,69 @@ describe User do it { should be_admin } end + describe "namespam" do + + describe "no hostnames" do + before {@user.first_name = "bleh www.something.com"} + it { should_not be_valid } + end + + describe "first name can't be mixed chinese" do + before {@user.first_name = "注冊ww"} + it { should_not be_valid } + end + + describe "long chinese names" do + before {@user.first_name = "注冊注冊注冊"; @user.last_name = "注冊"} + it { should_not be_valid } + end + + describe "if chinese first name, must be chinese last name" do + before {@user.first_name = "注冊"; @user.last_name = "abc"} + it { should_not be_valid } + end + + describe "chinese names can be allchinese" do + before {@user.first_name = "注冊"; @user.last_name = "注冊"} + it { puts @user.errors.inspect; should be_valid } + end + + describe "no hostname-looking stuff - first name" do + before {@user.first_name = "www server com"} + it { should_not be_valid } + end + + describe "no hostname-looking stuff - last name" do + before {@user.first_name = "www server com"} + it { should_not be_valid } + end + + describe "no junk characters" do + before {@user.first_name = "name.come"} + it { should_not be_valid } + end + + describe "no junk characters - period" do + before {@user.first_name = "name.come"} + it { should_not be_valid } + end + + describe "no junk characters - percent" do + before {@user.first_name = "name%"} + it { should_not be_valid } + end + + describe "no junk characters - amp" do + before {@user.first_name = "name&"} + it { should_not be_valid } + end + + describe "no junk characters - asterisk" do + before {@user.first_name = "name*"} + it { should_not be_valid } + end + end + describe "when first name is not present" do before { @user.first_name = " " } diff --git a/ruby/spec/support/utilities.rb b/ruby/spec/support/utilities.rb index 9e17eb029..91858a0db 100644 --- a/ruby/spec/support/utilities.rb +++ b/ruby/spec/support/utilities.rb @@ -318,6 +318,18 @@ def app_config 1 end + def max_invites_ever_per_sender + 4 + end + + def max_invites_per_day_per_sender + 3 + end + + def max_invites_to_receiver_per_day + 1 + end + def check_bounced_emails false end diff --git a/web/app/assets/images/content/icon_instrument_double_bass24.png b/web/app/assets/images/content/icon_instrument_double_bass24.png new file mode 100644 index 0000000000000000000000000000000000000000..c054f32adae3dd7c5463ec23ffd4fdbbd746a076 GIT binary patch literal 961 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1rX+877l!}s{b%+Ad7K3vkswhI zFm^kcZ3k3w&(p;*#Nu@Bl(YFEsUpYf-|sD7_Vz)~MhA``g0f4QoEG(lX?7awb%i@wvUXW)L^=g_0(akRf|(XwO@7bU+QLlL2=%jAu7cNV{| zJ^#4L$XImV+1(ZO&*!K=pYy$R%hbfcEpr98ck{Y57#^N-ZpE`G$Js^Z{nB3+os}tR z-t|N+wET02P->gx6aTpvSVhW;j_a^|Tc!492k(-`_p2nW@2*c?b*s^2e(8tT=k_Ot zR$Fo!|6AXZnX`QE=H$$C%qD_i8&{QeUd#Pqe#GQ+_xB&$-)@o>(Ead({cZGZ<)pmp z;wd`zvt+-||Iy|9OTAa&z}x3ZMOKTy^D*iR?3$OGH#au!*QE1zqwV^0w|)M{d48_R z@p#9ukM5WLEqQSA-R8n-v!dOly1OMx5;cngZ`v-(UNt=~G27}{T6M?EovY^G<@j}m zul)CX#~*=z7rKO(UOINkSCX57L;B+P6sOe$(xbN5?JV+7 z*euUXF#eS(6udWMJ6{WVhf2K!vlvcs%4bF$JY+$s0Uv6S{=)fdJN0Z759~cw@{PGo|91JlNp@-J zf0xhNY1#Ot^y1154Ij=&Ty5it;*j2Y^3BmDNzYY0KP`XO-5a`jJEQb=XKm?=izHw8 z?tb9@=kPCwk@T z><9aYdb27{@9~}oO!BHFt`Q|Ei6yC4$wjF^iowXh&{)^NOxMsX#K6+Z$jHjT2*|ZE zFxcun^*D-#-29Zxv`VN3Bd7*LGbgTe~DWM4f`-Zc! literal 0 HcmV?d00001 diff --git a/web/app/assets/images/content/icon_instrument_double_bass256.png b/web/app/assets/images/content/icon_instrument_double_bass256.png new file mode 100644 index 0000000000000000000000000000000000000000..c5373a2156c71f73d2e0495347015f70117908af GIT binary patch literal 14033 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 e AdminMailer.ugly({to:'david@jamkazam.com', cc:'seth@jamkazam.com,peter@jamkazam.com', body: params.to_s + "\n\n" + e.to_s, subject: 'Live Stream Started!'}).deliver_now @@ -117,7 +125,7 @@ class ApiLiveStreamsController < ApiController end def stream_started - email_stream_event("Live Stream Started!", false) + #email_stream_event("Live Stream Started!", false) diff --git a/web/app/views/users/_user_dropdown.html.erb b/web/app/views/users/_user_dropdown.html.erb index 55c761ac5..11f3935fc 100644 --- a/web/app/views/users/_user_dropdown.html.erb +++ b/web/app/views/users/_user_dropdown.html.erb @@ -61,7 +61,7 @@
  • <%= link_to "Download App", downloads_path, :rel => "external" %>
  • - <% if @nativeClient %> + <% if false #@nativeClient %>
  • <%= link_to "Test Network", '#' %>
  • <% end %>
  • <%= link_to "Get Help", 'https://forum.jamkazam.com/', :rel => "external" %>
  • diff --git a/web/config/application.rb b/web/config/application.rb index 14bca627d..a39ab2d23 100644 --- a/web/config/application.rb +++ b/web/config/application.rb @@ -385,6 +385,11 @@ if defined?(Bundler) config.jamtrack_landing_bubbles_enabled = true config.jamtrack_browser_bubbles_enabled = true + # spam for invited users + config.max_invites_ever_per_sender = 70 + config.max_invites_per_day_per_sender = 20 + config.max_invites_to_receiver_per_day = 1 + config.react.variant = :production config.react.addons = true diff --git a/web/spec/support/app_config.rb b/web/spec/support/app_config.rb index a9e69058c..7962415d1 100644 --- a/web/spec/support/app_config.rb +++ b/web/spec/support/app_config.rb @@ -168,6 +168,18 @@ def web_config def rating_dialog_min_num 1 end + + def max_invites_ever_per_sender + 3 + end + + def max_invites_per_day_per_sender + 4 + end + + def max_invites_to_receiver_per_day + 1 + end end klass.new end