diff --git a/app.rb b/app.rb index 9bde856e..f769ef29 100644 --- a/app.rb +++ b/app.rb @@ -407,11 +407,46 @@ post '/create' do plan: params[:selected_plan] ) @site.stripe_customer_id = customer.id + + plan_name = customer.subscriptions.first['plan']['name'] + + EmailWorker.perform_async({ + from: 'web@neocities.org', + reply_to: 'contact@neocities.org', + to: @site.email, + subject: "[Neocities] You've become a supporter!", + body: Tilt.new('./views/templates/email_subscription.erb', pretty: true).render(self, plan_name: plan_name) + }) + end @site.save end + EmailWorker.perform_async({ + from: 'web@neocities.org', + reply_to: 'contact@neocities.org', + to: @site.email, + subject: "[Neocities] Welcome to Neocities!", + body: Tilt.new('./views/templates/email_welcome.erb', pretty: true).render(self) + }) + + EmailWorker.perform_async({ + from: 'web@neocities.org', + reply_to: 'contact@neocities.org', + to: @site.email, + subject: "[Neocities] Welcome to Neocities!", + body: Tilt.new('./views/templates/email_welcome.erb', pretty: true).render(self) + }) + + EmailWorker.perform_async({ + from: 'web@neocities.org', + reply_to: 'contact@neocities.org', + to: @site.email, + subject: "[Neocities] Confirm your email address", + body: Tilt.new('./views/templates/email_confirm.erb', pretty: true).render(self) + }) + session[:id] = @site.id redirect '/' else @@ -1041,6 +1076,18 @@ post '/comment/:comment_id/delete' do |comment_id| return {result: 'error'}.to_json end +get '/site/:username/confirm_email/:token' do + site = Site[username: params[:username]] + if site.email_confirmation_token == params[:token] + site.email_confirmed = true + site.save + + erb :'site_email_confirmed' + else + erb :'site_email_not_confirmed' + end +end + post '/site/:username/report' do |username| site = Site[username: username] diff --git a/migrations/037_email_confirmation.rb b/migrations/037_email_confirmation.rb new file mode 100644 index 00000000..aeb7c0bc --- /dev/null +++ b/migrations/037_email_confirmation.rb @@ -0,0 +1,11 @@ +Sequel.migration do + up { + DB.add_column :sites, :email_confirmation_token, :text + DB.add_column :sites, :email_confirmed, :boolean, default: false + } + + down { + DB.drop_column :sites, :email_confirmation_token + DB.drop_column :sites, :email_confirmed + } +end \ No newline at end of file diff --git a/models/site.rb b/models/site.rb index 0620ae72..f3d9a0d0 100644 --- a/models/site.rb +++ b/models/site.rb @@ -358,6 +358,10 @@ class Site < Sequel::Model super end + def before_create + self.email_confirmation_token = SecureRandom.hex 3 + end + # def after_destroy # FileUtils.rm_rf file_path # super @@ -379,6 +383,17 @@ class Site < Sequel::Model errors.add :username, 'User/site name cannot exceed 32 characters.' end + + # Check that email has been provided + if new? && values[:email].empty? + errors.add :email, 'An email address is required.' + end + + # Check for existing email + if new? && self.class.select(:id).filter(email: values[:email]).first + errors.add :email, 'This email address already exists on Neocities, please use your existing account.' + end + # Check for existing user user = self.class.select(:id, :username).filter(username: values[:username]).first @@ -522,7 +537,7 @@ class Site < Sequel::Model end def host - domain ? domain : "#{username}.neocities.org" + !domain.empty? ? domain : "#{username}.neocities.org" end def title diff --git a/tests/acceptance_tests.rb b/tests/acceptance_tests.rb index bc89d063..29a1071e 100644 --- a/tests/acceptance_tests.rb +++ b/tests/acceptance_tests.rb @@ -23,6 +23,7 @@ describe 'signup' do @site = Fabricate.attributes_for(:site) fill_in 'username', with: @site[:username] fill_in 'password', with: @site[:password] + fill_in 'email', with: @site[:email] end def visit_signup @@ -137,6 +138,20 @@ describe 'signup' do site.tags.first.name.must_equal 'one' end + it 'fails with existing email' do + email = Fabricate.attributes_for(:site)[:email] + fill_in_valid + fill_in 'email', with: email + click_button 'Create Home Page' + page.must_have_content 'Your Feed' + Capybara.reset_sessions! + visit_signup + fill_in_valid + fill_in 'email', with: email + click_button 'Create Home Page' + page.must_have_content /email.+exists/ + end + it 'succeeds with no tags' do fill_in_valid fill_in 'tags', with: '' @@ -165,9 +180,14 @@ describe 'signin' do include Capybara::DSL def fill_in_valid - site = Fabricate.attributes_for :site - fill_in 'username', with: site[:username] - fill_in 'password', with: site[:password] + @site = Fabricate.attributes_for :site + fill_in 'username', with: @site[:username] + fill_in 'password', with: @site[:password] + end + + def fill_in_valid_signup + fill_in_valid + fill_in 'email', with: @site[:email] end before do @@ -196,15 +216,13 @@ describe 'signin' do it 'logs in with proper credentials' do visit '/' click_button 'Create My Website' - site = Fabricate.attributes_for(:site) - fill_in 'username', with: site[:username] - fill_in 'password', with: site[:password] + fill_in_valid_signup click_button 'Create Home Page' Capybara.reset_sessions! visit '/' click_link 'Sign In' - fill_in 'username', with: site[:username] - fill_in 'password', with: site[:password] + fill_in 'username', with: @site[:username] + fill_in 'password', with: @site[:password] click_button 'Sign In' page.must_have_content 'Your Feed' end diff --git a/tests/fabricators/site_fabricator.rb b/tests/fabricators/site_fabricator.rb index 6f70e455..9a16c9a9 100644 --- a/tests/fabricators/site_fabricator.rb +++ b/tests/fabricators/site_fabricator.rb @@ -1,4 +1,5 @@ Fabricator(:site) do username { SecureRandom.hex } password { 'abcde' } + email { SecureRandom.uuid.gsub('-', '')+'@example.com' } end \ No newline at end of file diff --git a/views/new.erb b/views/new.erb index 78d236b9..60839a34 100644 --- a/views/new.erb +++ b/views/new.erb @@ -47,7 +47,7 @@
- Now you can enter an e-mail address. Your e-mail address is private and we will not show it to anyone for any reason. You don't have to provide one, but we will not be able to reset your password without it, so don't lose your username and password if you leave this blank! + Now you need to enter your e-mail address. Your e-mail address is private, we will not display it or give it to third-parties.