devise 3.2.4 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.travis.yml +12 -5
- data/CHANGELOG.md +28 -1
- data/Gemfile +5 -5
- data/Gemfile.lock +98 -92
- data/README.md +22 -16
- data/app/controllers/devise/confirmations_controller.rb +1 -1
- data/app/controllers/devise/registrations_controller.rb +18 -5
- data/app/controllers/devise/sessions_controller.rb +32 -9
- data/app/controllers/devise_controller.rb +3 -3
- data/app/views/devise/registrations/new.html.erb +1 -1
- data/app/views/devise/sessions/new.html.erb +2 -2
- data/app/views/devise/shared/_links.erb +1 -1
- data/config/locales/en.yml +16 -15
- data/gemfiles/Gemfile.rails-3.2-stable +3 -3
- data/gemfiles/Gemfile.rails-3.2-stable.lock +166 -0
- data/gemfiles/Gemfile.rails-4.0-stable +4 -4
- data/gemfiles/Gemfile.rails-4.0-stable.lock +162 -0
- data/gemfiles/Gemfile.rails-head +7 -4
- data/gemfiles/Gemfile.rails-head.lock +190 -0
- data/lib/devise.rb +8 -4
- data/lib/devise/controllers/helpers.rb +77 -6
- data/lib/devise/controllers/sign_in_out.rb +0 -1
- data/lib/devise/controllers/store_location.rb +8 -2
- data/lib/devise/controllers/url_helpers.rb +3 -1
- data/lib/devise/failure_app.rb +6 -6
- data/lib/devise/hooks/activatable.rb +3 -4
- data/lib/devise/hooks/csrf_cleaner.rb +3 -1
- data/lib/devise/hooks/timeoutable.rb +8 -1
- data/lib/devise/mapping.rb +4 -1
- data/lib/devise/models/confirmable.rb +3 -3
- data/lib/devise/models/database_authenticatable.rb +7 -3
- data/lib/devise/models/lockable.rb +2 -2
- data/lib/devise/models/recoverable.rb +23 -7
- data/lib/devise/models/rememberable.rb +2 -2
- data/lib/devise/models/trackable.rb +4 -1
- data/lib/devise/rails/routes.rb +8 -6
- data/lib/devise/strategies/authenticatable.rb +7 -0
- data/lib/devise/version.rb +1 -1
- data/lib/generators/active_record/devise_generator.rb +19 -2
- data/lib/generators/templates/README +1 -1
- data/lib/generators/templates/devise.rb +3 -0
- data/script/cached-bundle +49 -0
- data/script/s3-put +71 -0
- data/test/controllers/custom_registrations_controller_test.rb +35 -0
- data/test/controllers/helpers_test.rb +35 -0
- data/test/controllers/internal_helpers_test.rb +1 -1
- data/test/controllers/passwords_controller_test.rb +1 -1
- data/test/devise_test.rb +18 -5
- data/test/failure_app_test.rb +40 -4
- data/test/generators/active_record_generator_test.rb +6 -0
- data/test/helpers/devise_helper_test.rb +3 -2
- data/test/integration/authenticatable_test.rb +19 -3
- data/test/integration/confirmable_test.rb +49 -9
- data/test/integration/http_authenticatable_test.rb +1 -1
- data/test/integration/lockable_test.rb +6 -6
- data/test/integration/recoverable_test.rb +5 -5
- data/test/integration/registerable_test.rb +32 -22
- data/test/integration/timeoutable_test.rb +8 -2
- data/test/integration/trackable_test.rb +2 -2
- data/test/mailers/confirmation_instructions_test.rb +3 -3
- data/test/mailers/reset_password_instructions_test.rb +3 -3
- data/test/mailers/unlock_instructions_test.rb +3 -3
- data/test/models/authenticatable_test.rb +1 -1
- data/test/models/lockable_test.rb +6 -0
- data/test/models/recoverable_test.rb +12 -0
- data/test/models/rememberable_test.rb +21 -6
- data/test/models/trackable_test.rb +28 -0
- data/test/models/validatable_test.rb +2 -2
- data/test/rails_app/app/active_record/user_on_engine.rb +7 -0
- data/test/rails_app/app/active_record/user_on_main_app.rb +7 -0
- data/test/rails_app/app/controllers/application_controller.rb +3 -0
- data/test/rails_app/app/controllers/application_with_fake_engine.rb +30 -0
- data/test/rails_app/app/controllers/custom/registrations_controller.rb +21 -0
- data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +1 -1
- data/test/rails_app/app/controllers/users_controller.rb +1 -1
- data/test/rails_app/app/mongoid/user_on_engine.rb +39 -0
- data/test/rails_app/app/mongoid/user_on_main_app.rb +39 -0
- data/test/rails_app/config/application.rb +1 -1
- data/test/rails_app/config/initializers/devise.rb +2 -0
- data/test/rails_app/config/routes.rb +17 -0
- data/test/rails_app/lib/shared_user.rb +1 -1
- data/test/rails_app/lib/shared_user_without_omniauth.rb +13 -0
- data/test/routes_test.rb +5 -3
- data/test/support/assertions.rb +2 -3
- data/test/support/integration.rb +2 -2
- data/test/test_helper.rb +2 -0
- data/test/test_helpers_test.rb +22 -32
- metadata +23 -2
|
@@ -33,14 +33,20 @@ module Devise
|
|
|
33
33
|
#
|
|
34
34
|
def store_location_for(resource_or_scope, location)
|
|
35
35
|
session_key = stored_location_key_for(resource_or_scope)
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
uri = parse_uri(location)
|
|
37
|
+
if uri
|
|
38
38
|
session[session_key] = [uri.path.sub(/\A\/+/, '/'), uri.query].compact.join('?')
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
private
|
|
43
43
|
|
|
44
|
+
def parse_uri(location)
|
|
45
|
+
location && URI.parse(location)
|
|
46
|
+
rescue URI::InvalidURIError
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
49
|
+
|
|
44
50
|
def stored_location_key_for(resource_or_scope)
|
|
45
51
|
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
|
46
52
|
"#{scope}_return_to"
|
|
@@ -47,7 +47,9 @@ module Devise
|
|
|
47
47
|
class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
|
|
48
48
|
def #{method}(resource_or_scope, *args)
|
|
49
49
|
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
|
50
|
-
|
|
50
|
+
router_name = Devise.mappings[scope].router_name
|
|
51
|
+
context = router_name ? send(router_name) : _devise_route_context
|
|
52
|
+
context.send("#{action}\#{scope}_#{module_name}_#{path_or_url}", *args)
|
|
51
53
|
end
|
|
52
54
|
URL_HELPERS
|
|
53
55
|
end
|
data/lib/devise/failure_app.rb
CHANGED
|
@@ -96,15 +96,15 @@ module Devise
|
|
|
96
96
|
request.referrer
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
path ||
|
|
99
|
+
path || scope_url
|
|
100
100
|
else
|
|
101
|
-
|
|
101
|
+
scope_url
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
|
|
105
|
-
def
|
|
105
|
+
def scope_url
|
|
106
106
|
opts = {}
|
|
107
|
-
route = :"new_#{scope}
|
|
107
|
+
route = :"new_#{scope}_session_url"
|
|
108
108
|
opts[:format] = request_format unless skip_format?
|
|
109
109
|
|
|
110
110
|
config = Rails.application.config
|
|
@@ -114,8 +114,8 @@ module Devise
|
|
|
114
114
|
|
|
115
115
|
if context.respond_to?(route)
|
|
116
116
|
context.send(route, opts)
|
|
117
|
-
elsif respond_to?(:
|
|
118
|
-
|
|
117
|
+
elsif respond_to?(:root_url)
|
|
118
|
+
root_url(opts)
|
|
119
119
|
else
|
|
120
120
|
"/"
|
|
121
121
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
# Deny user access whenever their account is not active yet.
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
# in each request and in case the user is using other strategies beside Devise ones.
|
|
1
|
+
# Deny user access whenever their account is not active yet.
|
|
2
|
+
# We need this as hook to validate the user activity on each request
|
|
3
|
+
# and in case the user is using other strategies beside Devise ones.
|
|
5
4
|
Warden::Manager.after_set_user do |record, warden, options|
|
|
6
5
|
if record && record.respond_to?(:active_for_authentication?) && !record.active_for_authentication?
|
|
7
6
|
scope = options[:scope]
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Warden::Manager.after_authentication do |record, warden, options|
|
|
2
|
-
|
|
2
|
+
clean_up_for_winning_strategy = !warden.winning_strategy.respond_to?(:clean_up_csrf?) ||
|
|
3
|
+
warden.winning_strategy.clean_up_csrf?
|
|
4
|
+
if Devise.clean_up_csrf_token_on_authentication && clean_up_for_winning_strategy
|
|
3
5
|
warden.request.session.try(:delete, :_csrf_token)
|
|
4
6
|
end
|
|
5
7
|
end
|
|
@@ -9,6 +9,13 @@ Warden::Manager.after_set_user do |record, warden, options|
|
|
|
9
9
|
|
|
10
10
|
if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) && options[:store] != false
|
|
11
11
|
last_request_at = warden.session(scope)['last_request_at']
|
|
12
|
+
|
|
13
|
+
if last_request_at.is_a? Integer
|
|
14
|
+
last_request_at = Time.at(last_request_at).utc
|
|
15
|
+
elsif last_request_at.is_a? String
|
|
16
|
+
last_request_at = Time.parse(last_request_at)
|
|
17
|
+
end
|
|
18
|
+
|
|
12
19
|
proxy = Devise::Hooks::Proxy.new(warden)
|
|
13
20
|
|
|
14
21
|
if record.timedout?(last_request_at) && !env['devise.skip_timeout']
|
|
@@ -22,7 +29,7 @@ Warden::Manager.after_set_user do |record, warden, options|
|
|
|
22
29
|
end
|
|
23
30
|
|
|
24
31
|
unless env['devise.skip_trackable']
|
|
25
|
-
warden.session(scope)['last_request_at'] = Time.now.utc
|
|
32
|
+
warden.session(scope)['last_request_at'] = Time.now.utc.to_i
|
|
26
33
|
end
|
|
27
34
|
end
|
|
28
35
|
end
|
data/lib/devise/mapping.rb
CHANGED
|
@@ -23,7 +23,8 @@ module Devise
|
|
|
23
23
|
#
|
|
24
24
|
class Mapping #:nodoc:
|
|
25
25
|
attr_reader :singular, :scoped_path, :path, :controllers, :path_names,
|
|
26
|
-
:class_name, :sign_out_via, :format, :used_routes, :used_helpers,
|
|
26
|
+
:class_name, :sign_out_via, :format, :used_routes, :used_helpers,
|
|
27
|
+
:failure_app, :router_name
|
|
27
28
|
|
|
28
29
|
alias :name :singular
|
|
29
30
|
|
|
@@ -60,6 +61,8 @@ module Devise
|
|
|
60
61
|
@sign_out_via = options[:sign_out_via] || Devise.sign_out_via
|
|
61
62
|
@format = options[:format]
|
|
62
63
|
|
|
64
|
+
@router_name = options[:router_name]
|
|
65
|
+
|
|
63
66
|
default_failure_app(options)
|
|
64
67
|
default_controllers(options)
|
|
65
68
|
default_path_names(options)
|
|
@@ -236,17 +236,17 @@ module Devise
|
|
|
236
236
|
end
|
|
237
237
|
|
|
238
238
|
def postpone_email_change?
|
|
239
|
-
postpone = self.class.reconfirmable && email_changed? && !@bypass_confirmation_postpone &&
|
|
239
|
+
postpone = self.class.reconfirmable && email_changed? && !@bypass_confirmation_postpone && self.email.present?
|
|
240
240
|
@bypass_confirmation_postpone = false
|
|
241
241
|
postpone
|
|
242
242
|
end
|
|
243
243
|
|
|
244
244
|
def reconfirmation_required?
|
|
245
|
-
self.class.reconfirmable && @reconfirmation_required &&
|
|
245
|
+
self.class.reconfirmable && @reconfirmation_required && self.email.present?
|
|
246
246
|
end
|
|
247
247
|
|
|
248
248
|
def send_confirmation_notification?
|
|
249
|
-
confirmation_required? && !@skip_confirmation_notification &&
|
|
249
|
+
confirmation_required? && !@skip_confirmation_notification && self.email.present?
|
|
250
250
|
end
|
|
251
251
|
|
|
252
252
|
def after_confirmation
|
|
@@ -55,9 +55,13 @@ module Devise
|
|
|
55
55
|
self.password = self.password_confirmation = nil
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
# Update record attributes when :current_password matches, otherwise
|
|
59
|
-
# error on :current_password.
|
|
60
|
-
#
|
|
58
|
+
# Update record attributes when :current_password matches, otherwise
|
|
59
|
+
# returns error on :current_password.
|
|
60
|
+
#
|
|
61
|
+
# This method also rejects the password field if it is blank (allowing
|
|
62
|
+
# users to change relevant information like the e-mail without changing
|
|
63
|
+
# their password). In case the password field is rejected, the confirmation
|
|
64
|
+
# is also rejected as long as it is also blank.
|
|
61
65
|
def update_with_password(params, *options)
|
|
62
66
|
current_password = params.delete(:current_password)
|
|
63
67
|
|
|
@@ -115,10 +115,10 @@ module Devise
|
|
|
115
115
|
# leaks the existence of an account.
|
|
116
116
|
if Devise.paranoid
|
|
117
117
|
super
|
|
118
|
+
elsif access_locked? || (lock_strategy_enabled?(:failed_attempts) && attempts_exceeded?)
|
|
119
|
+
:locked
|
|
118
120
|
elsif lock_strategy_enabled?(:failed_attempts) && last_attempt?
|
|
119
121
|
:last_attempt
|
|
120
|
-
elsif lock_strategy_enabled?(:failed_attempts) && attempts_exceeded?
|
|
121
|
-
:locked
|
|
122
122
|
else
|
|
123
123
|
super
|
|
124
124
|
end
|
|
@@ -45,14 +45,10 @@ module Devise
|
|
|
45
45
|
# Resets reset password token and send reset password instructions by email.
|
|
46
46
|
# Returns the token sent in the e-mail.
|
|
47
47
|
def send_reset_password_instructions
|
|
48
|
-
|
|
48
|
+
token = set_reset_password_token
|
|
49
|
+
send_reset_password_instructions_notification(token)
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
self.reset_password_sent_at = Time.now.utc
|
|
52
|
-
self.save(validate: false)
|
|
53
|
-
|
|
54
|
-
send_devise_notification(:reset_password_instructions, raw, {})
|
|
55
|
-
raw
|
|
51
|
+
token
|
|
56
52
|
end
|
|
57
53
|
|
|
58
54
|
# Checks if the reset password token sent is within the limit time.
|
|
@@ -90,7 +86,27 @@ module Devise
|
|
|
90
86
|
def after_password_reset
|
|
91
87
|
end
|
|
92
88
|
|
|
89
|
+
def set_reset_password_token
|
|
90
|
+
raw, enc = Devise.token_generator.generate(self.class, :reset_password_token)
|
|
91
|
+
|
|
92
|
+
self.reset_password_token = enc
|
|
93
|
+
self.reset_password_sent_at = Time.now.utc
|
|
94
|
+
self.save(validate: false)
|
|
95
|
+
raw
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def send_reset_password_instructions_notification(token)
|
|
99
|
+
send_devise_notification(:reset_password_instructions, token, {})
|
|
100
|
+
end
|
|
101
|
+
|
|
93
102
|
module ClassMethods
|
|
103
|
+
# Attempt to find a user by password reset token. If a user is found, return it
|
|
104
|
+
# If a user is not found, return nil
|
|
105
|
+
def with_reset_password_token(token)
|
|
106
|
+
reset_password_token = Devise.token_generator.digest(self, :reset_password_token, token)
|
|
107
|
+
to_adapter.find_first(reset_password_token: reset_password_token)
|
|
108
|
+
end
|
|
109
|
+
|
|
94
110
|
# Attempt to find a user by its email. If a record is found, send new
|
|
95
111
|
# password instructions to it. If user is not found, returns a new user
|
|
96
112
|
# with an email not found error.
|
|
@@ -58,7 +58,7 @@ module Devise
|
|
|
58
58
|
def forget_me!
|
|
59
59
|
return unless persisted?
|
|
60
60
|
self.remember_token = nil if respond_to?(:remember_token=)
|
|
61
|
-
self.remember_created_at = nil
|
|
61
|
+
self.remember_created_at = nil if self.class.expire_all_remember_me_on_sign_out
|
|
62
62
|
save(validate: false)
|
|
63
63
|
end
|
|
64
64
|
|
|
@@ -122,7 +122,7 @@ module Devise
|
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
-
Devise::Models.config(self, :remember_for, :extend_remember_period, :rememberable_options)
|
|
125
|
+
Devise::Models.config(self, :remember_for, :extend_remember_period, :rememberable_options, :expire_all_remember_me_on_sign_out)
|
|
126
126
|
end
|
|
127
127
|
end
|
|
128
128
|
end
|
|
@@ -15,7 +15,7 @@ module Devise
|
|
|
15
15
|
[:current_sign_in_at, :current_sign_in_ip, :last_sign_in_at, :last_sign_in_ip, :sign_in_count]
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def update_tracked_fields
|
|
18
|
+
def update_tracked_fields(request)
|
|
19
19
|
old_current, new_current = self.current_sign_in_at, Time.now.utc
|
|
20
20
|
self.last_sign_in_at = old_current || new_current
|
|
21
21
|
self.current_sign_in_at = new_current
|
|
@@ -26,7 +26,10 @@ module Devise
|
|
|
26
26
|
|
|
27
27
|
self.sign_in_count ||= 0
|
|
28
28
|
self.sign_in_count += 1
|
|
29
|
+
end
|
|
29
30
|
|
|
31
|
+
def update_tracked_fields!(request)
|
|
32
|
+
update_tracked_fields(request)
|
|
30
33
|
save(validate: false) or raise "Devise trackable could not save #{inspect}." \
|
|
31
34
|
"Please make sure a model using trackable can be saved at sign in."
|
|
32
35
|
end
|
data/lib/devise/rails/routes.rb
CHANGED
|
@@ -129,7 +129,8 @@ module ActionDispatch::Routing
|
|
|
129
129
|
#
|
|
130
130
|
# devise_for :users, module: "users"
|
|
131
131
|
#
|
|
132
|
-
# * skip: tell which controller you want to skip routes from being created
|
|
132
|
+
# * skip: tell which controller you want to skip routes from being created.
|
|
133
|
+
# It accepts :all as an option, meaning it will not generate any route at all:
|
|
133
134
|
#
|
|
134
135
|
# devise_for :users, skip: :sessions
|
|
135
136
|
#
|
|
@@ -153,6 +154,8 @@ module ActionDispatch::Routing
|
|
|
153
154
|
#
|
|
154
155
|
# * defaults: works the same as Rails' defaults
|
|
155
156
|
#
|
|
157
|
+
# * router_name: allows application level router name to be overwritten for the current scope
|
|
158
|
+
#
|
|
156
159
|
# ==== Scoping
|
|
157
160
|
#
|
|
158
161
|
# Following Rails 3 routes DSL, you can nest devise_for calls inside a scope:
|
|
@@ -224,7 +227,7 @@ module ActionDispatch::Routing
|
|
|
224
227
|
raise_no_devise_method_error!(mapping.class_name) unless mapping.to.respond_to?(:devise)
|
|
225
228
|
rescue NameError => e
|
|
226
229
|
raise unless mapping.class_name == resource.to_s.classify
|
|
227
|
-
warn "[WARNING] You provided devise_for #{resource.inspect} but there is "
|
|
230
|
+
warn "[WARNING] You provided devise_for #{resource.inspect} but there is " \
|
|
228
231
|
"no model #{mapping.class_name} defined in your application"
|
|
229
232
|
next
|
|
230
233
|
rescue NoMethodError => e
|
|
@@ -234,13 +237,12 @@ module ActionDispatch::Routing
|
|
|
234
237
|
|
|
235
238
|
if options[:controllers] && options[:controllers][:omniauth_callbacks]
|
|
236
239
|
unless mapping.omniauthable?
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
raise msg
|
|
240
|
+
raise ArgumentError, "Mapping omniauth_callbacks on a resource that is not omniauthable\n" \
|
|
241
|
+
"Please add `devise :omniauthable` to the `#{mapping.class_name}` model"
|
|
240
242
|
end
|
|
241
243
|
end
|
|
242
244
|
|
|
243
|
-
routes
|
|
245
|
+
routes = mapping.used_routes
|
|
244
246
|
|
|
245
247
|
devise_scope mapping.name do
|
|
246
248
|
with_devise_exclusive_scope mapping.fullpath, mapping.name, options do
|
|
@@ -16,6 +16,13 @@ module Devise
|
|
|
16
16
|
valid_for_params_auth? || valid_for_http_auth?
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
# Override and set to false for things like OmniAuth that technically
|
|
20
|
+
# run through Authentication (user_set) very often, which would normally
|
|
21
|
+
# reset CSRF data in the session
|
|
22
|
+
def clean_up_csrf?
|
|
23
|
+
true
|
|
24
|
+
end
|
|
25
|
+
|
|
19
26
|
private
|
|
20
27
|
|
|
21
28
|
# Receives a resource and check if it is valid by calling valid_for_authentication?
|
data/lib/devise/version.rb
CHANGED
|
@@ -53,8 +53,8 @@ module ActiveRecord
|
|
|
53
53
|
t.integer :sign_in_count, default: 0, null: false
|
|
54
54
|
t.datetime :current_sign_in_at
|
|
55
55
|
t.datetime :last_sign_in_at
|
|
56
|
-
t
|
|
57
|
-
t
|
|
56
|
+
t.#{ip_column} :current_sign_in_ip
|
|
57
|
+
t.#{ip_column} :last_sign_in_ip
|
|
58
58
|
|
|
59
59
|
## Confirmable
|
|
60
60
|
# t.string :confirmation_token
|
|
@@ -68,6 +68,23 @@ module ActiveRecord
|
|
|
68
68
|
# t.datetime :locked_at
|
|
69
69
|
RUBY
|
|
70
70
|
end
|
|
71
|
+
|
|
72
|
+
def ip_column
|
|
73
|
+
# Padded with spaces so it aligns nicely with the rest of the columns.
|
|
74
|
+
"%-8s" % (inet? ? "inet" : "string")
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def inet?
|
|
78
|
+
rails4? && postgresql?
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def rails4?
|
|
82
|
+
Rails.version.start_with? '4'
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def postgresql?
|
|
86
|
+
ActiveRecord::Base.connection.adapter_name.downcase == "postgresql"
|
|
87
|
+
end
|
|
71
88
|
end
|
|
72
89
|
end
|
|
73
90
|
end
|
|
@@ -6,7 +6,7 @@ Some setup you must do manually if you haven't yet:
|
|
|
6
6
|
is an example of default_url_options appropriate for a development environment
|
|
7
7
|
in config/environments/development.rb:
|
|
8
8
|
|
|
9
|
-
config.action_mailer.default_url_options = { host: 'localhost:3000
|
|
9
|
+
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
|
|
10
10
|
|
|
11
11
|
In production, :host should be set to the actual host of your application.
|
|
12
12
|
|
|
@@ -132,6 +132,9 @@ Devise.setup do |config|
|
|
|
132
132
|
# The time the user will be remembered without asking for credentials again.
|
|
133
133
|
# config.remember_for = 2.weeks
|
|
134
134
|
|
|
135
|
+
# Invalidates all the remember me tokens when the user signs out.
|
|
136
|
+
config.expire_all_remember_me_on_sign_out = true
|
|
137
|
+
|
|
135
138
|
# If true, extends the user's remember period when remembered via cookie.
|
|
136
139
|
# config.extend_remember_period = false
|
|
137
140
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Usage: cached-bundle install --deployment
|
|
3
|
+
#
|
|
4
|
+
# After running `bundle`, caches the `vendor/bundle` directory to S3.
|
|
5
|
+
# On the next run, restores the cached directory before running `bundle`.
|
|
6
|
+
# When `Gemfile.lock` changes, the cache gets rebuilt.
|
|
7
|
+
#
|
|
8
|
+
# Requirements:
|
|
9
|
+
# - Gemfile.lock
|
|
10
|
+
# - TRAVIS_REPO_SLUG
|
|
11
|
+
# - TRAVIS_RUBY_VERSION
|
|
12
|
+
# - AMAZON_S3_BUCKET
|
|
13
|
+
# - script/s3-put
|
|
14
|
+
# - bundle
|
|
15
|
+
# - curl
|
|
16
|
+
#
|
|
17
|
+
# Author: Mislav Marohnić
|
|
18
|
+
|
|
19
|
+
set -e
|
|
20
|
+
|
|
21
|
+
compute_md5() {
|
|
22
|
+
local output="$(openssl md5)"
|
|
23
|
+
echo "${output##* }"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
download() {
|
|
27
|
+
curl --tcp-nodelay -qsfL "$1" -o "$2"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
gemfile="${BUNDLE_GEMFILE:-Gemfile}"
|
|
32
|
+
bundle_fullpath="$(dirname $gemfile)/vendor/bundle"
|
|
33
|
+
bundle_path=${bundle_fullpath#$PWD/}
|
|
34
|
+
gemfile_hash="$(compute_md5 <"${gemfile}.lock")"
|
|
35
|
+
cache_name="${TRAVIS_RUBY_VERSION}-${gemfile_hash}.tgz"
|
|
36
|
+
fetch_url="http://${AMAZON_S3_BUCKET}.s3.amazonaws.com/${TRAVIS_REPO_SLUG}/${cache_name}"
|
|
37
|
+
|
|
38
|
+
if download "$fetch_url" "$cache_name"; then
|
|
39
|
+
echo "Reusing cached bundle ${cache_name}"
|
|
40
|
+
tar xzf "$cache_name"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
bundle "$@"
|
|
44
|
+
|
|
45
|
+
if [ ! -f "$cache_name" ] && [ -n "$AMAZON_SECRET_ACCESS_KEY" ]; then
|
|
46
|
+
echo "Caching \`${bundle_path}' to S3"
|
|
47
|
+
tar czf "$cache_name" "$bundle_path"
|
|
48
|
+
script/s3-put "$cache_name" "${AMAZON_S3_BUCKET}:${TRAVIS_REPO_SLUG}/${cache_name}"
|
|
49
|
+
fi
|