From 1e1051fd36f39b4ec34692b592310363831b3be5 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Thu, 11 Jul 2013 23:33:10 -0400 Subject: [PATCH] what's this? is this password reset??? --- Gemfile | 3 +- Gemfile.lock | 9 ++++ app.rb | 51 ++++++++++++++++++++++ environment.rb | 1 + migrations/014_add_password_reset_token.rb | 11 +++++ views/password_reset.slim | 15 +++++++ views/signin.slim | 5 ++- workers/email_worker.rb | 11 +++++ 8 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 migrations/014_add_password_reset_token.rb create mode 100644 views/password_reset.slim create mode 100644 workers/email_worker.rb diff --git a/Gemfile b/Gemfile index 929b097d..7d8fa8f1 100644 --- a/Gemfile +++ b/Gemfile @@ -14,6 +14,7 @@ gem 'rmagick', require: nil gem 'selenium-webdriver', require: nil gem 'sidekiq' gem 'ago' +gem 'mail' platform :mri do gem 'magic' # sudo apt-get install file, For OSX: brew install libmagic @@ -55,4 +56,4 @@ group :test do platform :mri do gem 'simplecov', require: nil end -end \ No newline at end of file +end diff --git a/Gemfile.lock b/Gemfile.lock index e6b4d32c..aa032786 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -34,8 +34,12 @@ GEM kgio (2.8.0) magic (0.2.6) ffi (>= 0.6.3) + mail (2.5.4) + mime-types (~> 1.16) + treetop (~> 1.4.8) metaclass (0.0.1) method_source (0.8.1) + mime-types (1.23) minitest (4.7.4) minitest-reporters (0.14.19) ansi @@ -46,6 +50,7 @@ GEM metaclass (~> 0.0.1) multi_json (1.7.3) pg (0.15.1) + polyglot (0.3.3) powerbar (1.0.11) ansi (~> 1.4.0) hashie (>= 1.1.0) @@ -112,6 +117,9 @@ GEM temple (0.6.5) tilt (1.4.1) timers (1.1.0) + treetop (1.4.14) + polyglot + polyglot (>= 0.3.1) unicorn (4.6.2) kgio (~> 2.6) rack @@ -134,6 +142,7 @@ DEPENDENCIES jruby-openssl json magic + mail minitest minitest-reporters mocha diff --git a/app.rb b/app.rb index c57b0d16..eb5060f5 100644 --- a/app.rb +++ b/app.rb @@ -367,6 +367,57 @@ post '/admin/mark_nsfw' do redirect '/admin' end +get '/password_reset' do + slim :'password_reset' +end + +post '/send_password_reset' do + site = Site[email: params[:email]] + + if site + site.update password_reset_token: token + + token = SecureRandom.uuid.gsub('-', '') + + body = <<-EOT +Hello! This is the NeoCities cat, and I have received a password reset request for your e-mail address. Purrrr. + +Go to this URL to reset your password: http://neocities.org/password_reset_confirm?code=#{token} + +If you didn't request this reset, you can ignore it. Or hide under a bed. Or take a nap. Your call. + +Meow, +the NeoCities Cat + EOT + + body.strip! + + EmailWorker.perform_async({ + to: params[:email], + subject: '[NeoCities] Password Reset', + body: body + }) + end + + flash[:success] = 'If your email was valid (and used by a site), the NeoCities Cat will send an e-mail to your account with password reset instructions.' + redirect '/' +end + +get '/password_reset_confirm' do + site = Site[password_reset_token: params[:token]] + + if site + site.password = params[:token] + site.save + + flash[:success] = 'Your password has been changed to the token sent in your e-mail. Please login and change your password in the settings page as soon as possible.' + else + flash[:error] = 'Could not find a site with this token.' + end + + redirect '/' +end + def require_admin redirect '/' unless signed_in? && current_site.is_admin end diff --git a/environment.rb b/environment.rb index 4d1ce945..05333193 100644 --- a/environment.rb +++ b/environment.rb @@ -34,6 +34,7 @@ Sidekiq.configure_client do |config| end require File.join(DIR_ROOT, 'workers', 'screenshot_worker.rb') +require File.join(DIR_ROOT, 'workers', 'email_worker.rb') Sequel.datetime_class = Time Sequel.extension :pagination diff --git a/migrations/014_add_password_reset_token.rb b/migrations/014_add_password_reset_token.rb new file mode 100644 index 00000000..544ca287 --- /dev/null +++ b/migrations/014_add_password_reset_token.rb @@ -0,0 +1,11 @@ +Sequel.migration do + up { + DB.add_column :sites, :password_reset_token, :text + DB.add_index :sites, :password_reset_token + } + + down { + DB.add_column :sites, :password_reset_token + DB.drop_index :sites, :password_reset_token + } +end \ No newline at end of file diff --git a/views/password_reset.slim b/views/password_reset.slim new file mode 100644 index 00000000..91def705 --- /dev/null +++ b/views/password_reset.slim @@ -0,0 +1,15 @@ +.text-center + .row + .span12 + h1 Reset Password + .row + .span6.offset3.text-center + h5 If you provided your e-mail you can reset your password. If you didn't, you will not be able to reset your password, you will need to create a new site. We will not change a password without an email entered, no exceptions. + .row + .span12 + form method="POST" action="/send_password_reset" + input name="csrf_token" type="hidden" value="#{csrf_token}" + + fieldset + div: input name="email" type="email" placeholder="Your email" + div: button class="btn btn-large btn-success" href="#" style="margin-top: 10px" Send Password Reset \ No newline at end of file diff --git a/views/signin.slim b/views/signin.slim index cb395b2d..4c5cea6d 100644 --- a/views/signin.slim +++ b/views/signin.slim @@ -13,4 +13,7 @@ div: button class="btn btn-large btn-success" href="#" style="margin-top: 10px" Sign in .row .span12 - a href="/new" I don't have an account yet. + div + a href="/new" I don't have an account yet. + div + a href="/password_reset" I forgot my password. \ No newline at end of file diff --git a/workers/email_worker.rb b/workers/email_worker.rb new file mode 100644 index 00000000..a215349c --- /dev/null +++ b/workers/email_worker.rb @@ -0,0 +1,11 @@ +class EmailWorker + include Sidekiq::Worker + + def perform(args={}) + Mail.deliver do + to args[:to] + subject args[:subject] + body args[:body] + end + end +end