Integrating letter_opener with Devise - ruby-on-rails-4

I am currently using the Devise gem for authentication with my rails app and I am having trouble using the letter_opener gem with it. I can get it to work with a the standard mailer but I'm not sure how to configure the Devise mailer to work with letter_opener.
How do I configure letter_opener so that it will work with the emails sent with Devise?

Don`t know how it was in Rails 4.x but in Rails 5.1 I did it like so:
1) Install
gem 'letter_opener_web', group: :development
2) Make your devise model
confirmable
here`s the link https://github.com/plataformatec/devise/wiki/How-To:-Add-:confirmable-to-Users
3) Add this config
config.action_mailer.perform_deliveries = true
config.action_mailer.default_url_options = { host: 'localhost:3000' }
config.action_mailer.delivery_method = :letter_opener
to
config/environments/development.rb
in your devise initializer(config/initializers/devise.rb)
config.mailer_sender = 'foo#bar.com'
config.mailer = Devise.mailer
4) Do not forget to mount your letter_opener web interface to routes.rb
mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?
This works pretty nice. Your mails will be available at
localhost:3000/letter_opener

Related

rails4 deployment logs out all users

got some strange behavior since quite a while. After deployment (with capistarano) all users need to sign in again!
happens in several apps, since Rails 4.x .. here some versions:
Rails: 4.2.5 / 4.2.6
Devise: 3.5.3 / 3.5.6 / 4.2.0
Capistrano: 3.4.0
Ruby: 2.2.1 / 2.3.0
Web-Server: nginx
App-Server: thin (1.6.4 / 1.7.0)
this is really annoying, especially because zero-downtime-deployment makes no sence anymore and remember-me doesn't work at all
models/user
class User < ActiveRecord::Base
..
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable,
:validatable, :confirmable, :lockable, :timeoutable, :omniauthable, :invitable,
:omniauth_providers => CONFIG[:devise_provider]
..
end
initializers/devise
Devise.setup do |config|
config.secret_key = 'xxx-key-xxx'
config.mailer_sender = CONFIG[:mail_system]
config.mailer = 'AccountMailer'
require 'devise/orm/active_record'
config.case_insensitive_keys = [:email]
config.strip_whitespace_keys = [:email]
config.skip_session_storage = [:http_auth]
config.stretches = Rails.env.test? ? 1 : 10
config.invite_for = 0
config.reconfirmable = true
config.expire_all_remember_me_on_sign_out = true
config.password_length = CONFIG[:password_min_length]..CONFIG[:password_max_length]
config.timeout_in = 6.hours
config.reset_password_within = 6.hours
config.sign_out_via = :delete
config.omniauth :facebook, CONFIG[:facebook_id], CONFIG[:facebook_secret], {info_fields: 'email, first_name, last_name, gender', image_size: "large"}
config.omniauth :google_oauth2, CONFIG[:google_id], CONFIG[:google_secret], {
skip_jwt: true,
scope: "email, profile, plus.me",
# prompt: "select_account",
image_aspect_ratio: "square",
image_size: 200
}
end
Most of the apps are running in production, so I don't touch the database while deployment (except for migrations).
Also happens in apps without devise_invitable, so this also don't causes it.
.. thanks for any help! ..
also posted as devise #4277
solved it!
The problem was caused by the only thing I didn't mention: rvmor better rvm1-capistrano3which completely ignores ~/.bachrc, ~/.profile and so on.
I had to put secret_key_base in /etc/environment now it works as expected.
Till now secret_key_base was just a huge pain in the ass for me, because all documented usage didn't work and I had to put secret_key_base in :default_env and also inject it in some monit scripts. ie: to restart sidekiq or thin (therefore it was hardcoded in deploy.rb)
Thanks to surendar, his answer on capistrano 3 + rvm1-capistrano3 rails 4.1 secrets.yml environmental variables issue was the solution.
It still don't seems to be the best solution (but it works), so I'll stay open for better solutions.

Capybara::Poltergeist Status error, failed to reach server

I am trying to make some tests with Rspec/Capybara/Poltergeist on my Rails 4 application, Phantomjs is installed (version 2.2.1), but I always get this error :
Failure/Error: visit(perfect_landing_page_path)
Capybara::Poltergeist::StatusFailError:
Request to 'http://127.0.0.1:49623/path' failed to reach server, check DNS
and/or server status
The test i'm working on :
require 'rails_helper'
RSpec.feature 'Subscription', :type => :feature do
let!(:plan) { create(:plan) }
let!(:landing_page) { create(:landing_page) }
before(:each) { landing_page.default_plan = plan }
describe 'landing_page#perfect_show' do
scenario 'form display', js: true do
plan_2 = create(:plan)
plan_3 = create(:plan)
landing_page.plans << plan_2
landing_page.plans << plan_3
visit(perfect_landing_page_path)
expect(page).to have_css(".start-now", count: 3)
first(".start-now").click
expect(page).to have_css("#new_user")
end
end
end
My Gemfile looks like this :
gem 'rspec-rails', '~> 3.0'
gem 'factory_girl_rails'
gem 'guard-rspec'
group :test do
gem 'database_cleaner'
gem 'capybara'
gem 'capybara-screenshot'
gem 'poltergeist'
gem 'selenium-webdriver'
gem 'shoulda-matchers', require: false
gem 'show_me_the_cookies'
end
My spec/support/capybara.rb file :
require 'capybara/rails'
require 'capybara/rspec'
require 'capybara-screenshot/rspec'
require "capybara/poltergeist" # Add this line to require poltergeist
require 'selenium-webdriver'
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {:js_errors => false, :default_max_wait_time => 30, :timeout => 30, phantomjs_options: [
'--load-images=no',
'--ignore-ssl-errors=true',
'--ssl-protocol=any']})
end
Capybara.register_driver :poltergeist_debug do |app|
Capybara::Poltergeist::Driver.new(app, :inspector => true)
end
Capybara.configure do |config|
config.javascript_driver = :poltergeist
config.ignore_hidden_elements = true
config.default_max_wait_time = 30
end
My spec_helper.rb file :
require 'capybara/rspec'
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.filter_run :focus
config.run_all_when_everything_filtered = true
Did someone encounter this problem before ? Does anyone have a solution for this ? I have been banging my head for days looking on the web...
Thank you very much.
PS : it works fine on my friend's mac (Yosemite or El Capitan), just not on mine.
I was having this problem in CI (CodeShip).
Adding a call to bundle exec rake assets:precompile at the end of the setup commands seemed to fix it:
CodeShip CI Setup Commands:
rvm use 2.3.4 --install
bundle install
export RAILS_ENV=test
bundle exec rake db:schema:load
bundle exec rake assets:precompile
Also had a whitelist per #agbodike but in the rails_helper.rb
config.before(:each, js: true) do
page.driver.browser.url_whitelist = ["127.0.0.1"]
end
I had the same issue and it was due to a 3rd party script timing out. You can prevent loading of 3rd party scripts with a blacklist. For example:
config.before(:each, js: true) do
page.driver.browser.url_blacklist = ["http://use.typekit.net"]
end
would prevent any URL starting with http://use.typekit.net from being called for each test that uses the js driver. More information can be found at:
https://robots.thoughtbot.com/speed-up-javascript-capybara-specs-by-blacklisting-urls
Alternatively you can use a whitelist:
config.before(:each, js: true) do
page.driver.browser.url_whitelist = ["127.0.0.1"]
end
which will block all requests not to 127.0.0.1
I placed the configuration in spec/feature_helper.rb to ensure it was only set for feature specs.
You can avoid these by precompile the assets before tests.
And the code is:
RSpec.configure do |config|
config.before :all do
ENV['PRECOMPILE_ASSETS'] ||= begin
case self.class.metadata[:type]
when :feature, :view
STDOUT.write "Precompiling assets..."
require 'rake'
Rails.application.load_tasks
Rake::Task['assets:precompile'].invoke
STDOUT.puts " done."
Time.now.to_s
end
end
end
end
more info

With Rails 4 and selenium web driver, use Sauce Labs on Travis CI but not locally

I'm filling out specs for an open source Rails project and need to run the app in a browser for some of my feature specs. I'd like to use Sauce Labs on Travis CI, but without having to rewrite my specs to also use Sauce Labs locally, because:
I don't want to have to be connected to the Internet during development to run my specs.
Making the specs reliant on Sauce Labs would make it impossible for contributors to run the specs themselves without setting up their own Sauce Labs account and env vars.
I couldn't find documentation detailing this scenario. What's the best way of achieving this?
For those with similar needs, this is what I ended up doing:
.travis.yml:
env:
global:
- secure: "encrypted sauce username"
- secure: "encrypted sauce secret key"
addons:
sauce_connect: true
before_install:
# install the ed text editor which we use to append
# file contents to a specific line of another file
- sudo apt-get install -y ed
# appends contents of travis/Gemfile.travis to Gemfile
- cat travis/Gemfile.travis >> Gemfile
# adds contents of travis/rails_helper.rb.travis to line 12 of spec/rails_helper.rb
- ed -s spec/rails_helper.rb <<< '12r travis/rails_helper.rb.travis'$'\nw'
travis/Gemfile.travis:
group :test, :development do
gem 'sauce', '~> 3.1.1'
gem 'sauce-connect'
gem 'parallel_tests'
end
travis/rails_helper.rb.travis:
require 'sauce'
require 'sauce/capybara'
# change to "Capybara.default_driver = :sauce" to use sauce
# for ALL feature specs, not just ones marked with "js: true"
Capybara.javascript_driver = :sauce
Sauce.config do |config|
config[:browsers] = [
['Linux', 'Chrome', nil],
# and other OS/browser combos you want to support...
]
end
UPDATE (2014/11/25):
I ended up using a slightly different configuration in my final solution. I didn't like the brittleness of inserting at a line number. Instead of having special Sauce inclusions in separate files, I just nested special configuration in a conditional, depending on whether an environment variable SAUCY is set to true.
.travis.yml:
env:
global:
- secure: "encrypted sauce username"
- secure: "encrypted sauce secret key"
- SAUCY: true
addons:
sauce_connect: true
Gemfile:
group :development, :test do
# other gems...
if ENV['SAUCY']
# gems for sauce
gem 'sauce', '~> 3.1.1'
gem 'sauce-connect'
gem 'parallel_tests'
end
end
spec/rails_helper.rb:
# after other requires
if ENV['SAUCY']
require 'sauce'
require 'sauce/capybara'
# change to "Capybara.default_driver = :sauce" to use sauce
# for ALL feature specs, not just ones marked with "js: true"
Capybara.javascript_driver = :sauce
Sauce.config do |config|
config[:browsers] = [
['Linux', 'Chrome', nil],
# and other OS/browser combos you want to support...
]
end
end
This way, I can also easily use Sauce locally if I choose to with:
SAUCY=true bundle install
SAUCY=true SAUCE_USERNAME=username SAUCE_ACCESS_KEY=access_key bundle exec rspec

Facebook omniauth rails NoAuthorizationCodeError

Hello guys I am trying to integrate facebook login in my rails application
I included gems in my gem file
gem 'omniauth'
gem 'omniauth-facebook', '~> 1.4.1'
and in my omniauth file
an in my routes.rb file
get 'auth/:provider/callback', to: 'users#screate',:as => :callback
i have added in my omniauth.rb
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, '632837163475474', 'b1db948ee52851623397e66b293ff45a',{provider_ignores_state: true}
end
but when I try to login I get the following error
OmniAuth::Strategies::Facebook::NoAuthorizationCodeError
must pass either a `code` parameter or a signed request (via `signed_request` parameter or a `fbsr_XXX` cookie)
if I remove
{provider_ignores_state: true}
I get following error
csrf_detected | CSRF detected
When you try to login, are you linking to "/auth/facebook"? This URL sets up the signed request that your error is suggesting you don't have...

(Rails) : NoMethodError: undefined method cost' for BCrypt::Engine:Class

When I learn "Ruby on Rails Tutorial", and I want to create a User on console:
irb(main):001:0> User.create(name:"gsky",email:"k#q.com",
irb(main):002:1* password:"aaaaaa",password_confirmation:"aaaaaa")
then, I getting the following error message:
NoMethodError: undefined method cost' for BCrypt::Engine:Class
from D:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activemodel-4.
0.2/lib/active_model/secure_password.rb:104:inpassword='
from D:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4
.0.2/lib/active_record/attribute_assignment.rb:42:in public_send'
This is user model:
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }
end
Add bcrypt-ruby to your Gemfile as specified below:
gem 'bcrypt-ruby', '3.1.2'
then run bundle update from your project root directory and bundle install
When i saw "Ruby On Rails Tutorial" I have met the same problem,
I solved it by set Gemfile from:
gem 'bcrypt-ruby', '3.0.1'
to:
gem 'bcrypt-ruby', '3.1.2'
then run:
bundle install
Also going for the tutorial/book and having the same problems, I used gem 'bcrypt-ruby', '~> 3.0.0' because of problems with bundle install. After going through secure_password.rb, the problem was in BCrypt::Engine.cost, this method actually doesn't exist.
I changed my gem to gem 'bcrypt-ruby', '~> 3.1.0' which installed bcrypt 3.1.7. Saw a warning message about the gem being renamed and changed it to gem 'bcrypt', '~> 3.1.0' (this part shouldn't matter). After doing bundle install, I was able to see the implementation of Bcrypt::Engine.cost through my IDE and I was able to make my user in rails c.
I want to add that adding ActiveModel::SecurePassword.min_cost = true in test.rb was able to let me make new users if I ran rails c in test environment, but when I added the same line in development.rb, it didn't work.
I think you are learning rails from the tutorial. If you just want to continue and not spent much time on doing the right fix, you can just use the cost as say 10, instead of calling the BCrypt::Engine.cost method.
So replace
cost = BCrypt::Engine.cost
with
cost = 10
This value when used will take less than 200ms to compute and that should be okay.
Tested on mac:
Include this in your gemfile:
gem 'bcrypt', '3.1.11'
run:
xcode-select --install
then run: bundle install
That's it.
Best of lucks