locomotivecms_steam 1.2.1 → 1.3.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/Gemfile +3 -2
- data/Gemfile.lock +57 -50
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/config/locales/nl.yml +2 -2
- data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/content_entry.rb +8 -0
- data/lib/locomotive/steam/adapters/memory/condition.rb +1 -1
- data/lib/locomotive/steam/configuration.rb +1 -1
- data/lib/locomotive/steam/decorators/template_decorator.rb +1 -1
- data/lib/locomotive/steam/entities/content_entry.rb +17 -0
- data/lib/locomotive/steam/entities/content_type.rb +1 -0
- data/lib/locomotive/steam/entities/content_type_field.rb +1 -0
- data/lib/locomotive/steam/entities/editable_element.rb +4 -0
- data/lib/locomotive/steam/errors.rb +35 -5
- data/lib/locomotive/steam/initializers/sprockets.rb +6 -80
- data/lib/locomotive/steam/liquid/drops/page.rb +9 -2
- data/lib/locomotive/steam/liquid/filters/date.rb +109 -0
- data/lib/locomotive/steam/liquid/tags/action.rb +6 -1
- data/lib/locomotive/steam/liquid/tags/authorize.rb +65 -0
- data/lib/locomotive/steam/liquid/tags/snippet.rb +10 -2
- data/lib/locomotive/steam/liquid/template.rb +3 -1
- data/lib/locomotive/steam/middlewares/auth.rb +187 -0
- data/lib/locomotive/steam/middlewares/redirection.rb +24 -0
- data/lib/locomotive/steam/middlewares/renderer.rb +20 -3
- data/lib/locomotive/steam/middlewares/sitemap.rb +3 -1
- data/lib/locomotive/steam/middlewares/templatized_page.rb +1 -6
- data/lib/locomotive/steam/middlewares/thread_safe.rb +19 -0
- data/lib/locomotive/steam/middlewares/url_redirection.rb +14 -1
- data/lib/locomotive/steam/repositories.rb +5 -1
- data/lib/locomotive/steam/repositories/content_entry_repository.rb +1 -1
- data/lib/locomotive/steam/repositories/content_type_field_repository.rb +4 -0
- data/lib/locomotive/steam/server.rb +2 -0
- data/lib/locomotive/steam/services.rb +9 -1
- data/lib/locomotive/steam/services/action_service.rb +26 -7
- data/lib/locomotive/steam/services/asset_host_service.rb +6 -1
- data/lib/locomotive/steam/services/auth_service.rb +105 -0
- data/lib/locomotive/steam/services/content_entry_service.rb +14 -0
- data/lib/locomotive/steam/services/external_api_service.rb +59 -25
- data/lib/locomotive/steam/services/liquid_parser_service.rb +5 -1
- data/lib/locomotive/steam/services/page_redirection_service.rb +29 -0
- data/lib/locomotive/steam/version.rb +1 -1
- data/locomotivecms_steam.gemspec +18 -16
- data/spec/fixtures/default/app/content_types/accounts.yml +59 -0
- data/spec/fixtures/default/app/content_types/songs.yml +2 -1
- data/spec/fixtures/default/app/views/pages/about_us/john_doe.fr.liquid.haml +5 -1
- data/spec/fixtures/default/app/views/pages/about_us/john_doe.liquid.haml +1 -1
- data/spec/fixtures/default/app/views/pages/account/forgot_password.liquid +39 -0
- data/spec/fixtures/default/app/views/pages/account/me.liquid +15 -0
- data/spec/fixtures/default/app/views/pages/account/reset_password.liquid +42 -0
- data/spec/fixtures/default/app/views/pages/account/sign_in.liquid +49 -0
- data/spec/fixtures/default/app/views/pages/all.liquid.haml +1 -1
- data/spec/fixtures/default/app/views/pages/emails/reset_password.liquid +15 -0
- data/spec/fixtures/default/app/views/pages/songs/template.liquid.haml +1 -1
- data/spec/fixtures/default/config/metafields_schema.yml +10 -0
- data/spec/fixtures/default/config/site.yml +5 -0
- data/spec/fixtures/default/config/translations.yml +25 -1
- data/spec/fixtures/default/data/accounts.yml +15 -0
- data/spec/fixtures/mongodb/locomotive_accounts.bson +0 -0
- data/spec/fixtures/mongodb/locomotive_accounts.metadata.json +1 -1
- data/spec/fixtures/mongodb/locomotive_activities.bson +0 -0
- data/spec/fixtures/mongodb/locomotive_activities.metadata.json +1 -1
- data/spec/fixtures/mongodb/locomotive_content_assets.bson +0 -0
- data/spec/fixtures/mongodb/locomotive_content_assets.metadata.json +1 -1
- data/spec/fixtures/mongodb/locomotive_content_entries.bson +0 -0
- data/spec/fixtures/mongodb/locomotive_content_entries.metadata.json +1 -1
- data/spec/fixtures/mongodb/locomotive_content_types.bson +0 -0
- data/spec/fixtures/mongodb/locomotive_content_types.metadata.json +1 -1
- data/spec/fixtures/mongodb/locomotive_pages.bson +0 -0
- data/spec/fixtures/mongodb/locomotive_pages.metadata.json +1 -1
- data/spec/fixtures/mongodb/locomotive_sites.bson +0 -0
- data/spec/fixtures/mongodb/locomotive_sites.metadata.json +1 -1
- data/spec/fixtures/mongodb/locomotive_snippets.bson +0 -0
- data/spec/fixtures/mongodb/locomotive_snippets.metadata.json +1 -1
- data/spec/fixtures/mongodb/locomotive_theme_assets.bson +0 -0
- data/spec/fixtures/mongodb/locomotive_theme_assets.metadata.json +1 -1
- data/spec/fixtures/mongodb/locomotive_translations.bson +0 -0
- data/spec/fixtures/mongodb/locomotive_translations.metadata.json +1 -1
- data/spec/integration/repositories/content_entry_repository_spec.rb +1 -1
- data/spec/integration/repositories/content_type_repository_spec.rb +1 -1
- data/spec/integration/repositories/page_repository_spec.rb +3 -3
- data/spec/integration/repositories/theme_asset_repository_spec.rb +1 -1
- data/spec/integration/repositories/translation_repository_spec.rb +1 -1
- data/spec/integration/server/auth_spec.rb +196 -0
- data/spec/integration/server/basic_spec.rb +18 -0
- data/spec/integration/server/nav_spec.rb +1 -1
- data/spec/integration/server/sitemap_spec.rb +1 -1
- data/spec/integration/services/content_entry_service_spec.rb +1 -1
- data/spec/integration/services/external_api_service_spec.rb +9 -0
- data/spec/support/helpers.rb +1 -1
- data/spec/unit/adapters/filesystem/yaml_loaders/content_entry_spec.rb +17 -5
- data/spec/unit/adapters/filesystem/yaml_loaders/content_type_spec.rb +4 -4
- data/spec/unit/adapters/filesystem/yaml_loaders/page_spec.rb +7 -7
- data/spec/unit/adapters/filesystem/yaml_loaders/site_spec.rb +1 -1
- data/spec/unit/adapters/filesystem/yaml_loaders/translation_spec.rb +1 -1
- data/spec/unit/entities/content_entry_spec.rb +10 -0
- data/spec/unit/errors_spec.rb +2 -2
- data/spec/unit/initializers/sprockets_spec.rb +0 -14
- data/spec/unit/liquid/drops/page_spec.rb +3 -2
- data/spec/unit/liquid/filters/date_spec.rb +219 -0
- data/spec/unit/liquid/tags/action_spec.rb +9 -0
- data/spec/unit/liquid/tags/authorize_spec.rb +51 -0
- data/spec/unit/liquid/tags/link_to_spec.rb +1 -1
- data/spec/unit/liquid/tags/paginate_spec.rb +1 -1
- data/spec/unit/liquid/tags/snippet_spec.rb +10 -0
- data/spec/unit/middlewares/auth_spec.rb +31 -0
- data/spec/unit/middlewares/redirection_spec.rb +37 -0
- data/spec/unit/middlewares/url_redirection_spec.rb +20 -1
- data/spec/unit/services/action_service_spec.rb +57 -1
- data/spec/unit/services/asset_host_service_spec.rb +15 -0
- data/spec/unit/services/auth_service_spec.rb +156 -0
- data/spec/unit/services/external_api_service_spec.rb +22 -0
- data/spec/unit/services/page_redirection_service_spec.rb +49 -0
- metadata +96 -40
- data/CHANGELOG.md +0 -29
- data/spec/fixtures/mongodb/system.indexes.bson +0 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
module Locomotive::Steam
|
2
|
+
module Middlewares
|
3
|
+
|
4
|
+
# When rendering the page, the developer can stop it at anytime by
|
5
|
+
# raising an RedirectionException exception. The exception message holds
|
6
|
+
# the url we want the user to be redirected to.
|
7
|
+
# This is specifically used by the authorize liquid tag.
|
8
|
+
#
|
9
|
+
class Redirection < ThreadSafe
|
10
|
+
|
11
|
+
include Helpers
|
12
|
+
|
13
|
+
def _call
|
14
|
+
begin
|
15
|
+
self.next
|
16
|
+
rescue Locomotive::Steam::RedirectionException => e
|
17
|
+
redirect_to e.url, 302
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -37,7 +37,12 @@ module Locomotive::Steam
|
|
37
37
|
|
38
38
|
def parse_and_render_liquid
|
39
39
|
document = services.liquid_parser.parse(page)
|
40
|
-
|
40
|
+
begin
|
41
|
+
document.render(liquid_context)
|
42
|
+
rescue Locomotive::Steam::ParsingRenderingError => e
|
43
|
+
e.file = page.template_path if e.file.blank?
|
44
|
+
raise e
|
45
|
+
end
|
41
46
|
end
|
42
47
|
|
43
48
|
def liquid_context
|
@@ -62,7 +67,8 @@ module Locomotive::Steam
|
|
62
67
|
_default_liquid_assigns.merge(
|
63
68
|
_locale_liquid_assigns.merge(
|
64
69
|
_request_liquid_assigns.merge(
|
65
|
-
|
70
|
+
_http_actions_liquid_assigns.merge(
|
71
|
+
_steam_liquid_assigns))))
|
66
72
|
end
|
67
73
|
|
68
74
|
def _default_liquid_assigns
|
@@ -100,13 +106,24 @@ module Locomotive::Steam
|
|
100
106
|
{
|
101
107
|
'base_url' => request.base_url,
|
102
108
|
'fullpath' => request.fullpath,
|
109
|
+
'http_method' => request.request_method,
|
103
110
|
'ip_address' => request.ip,
|
104
111
|
'mounted_on' => mounted_on,
|
105
112
|
'path' => request.path,
|
106
|
-
'post?' => request.post?,
|
107
113
|
'referer' => request.referer,
|
108
114
|
'url' => request.url,
|
109
115
|
'user_agent' => request.user_agent,
|
116
|
+
'host' => request.host_with_port
|
117
|
+
}
|
118
|
+
end
|
119
|
+
|
120
|
+
def _http_actions_liquid_assigns
|
121
|
+
{
|
122
|
+
'head?' => request.head?,
|
123
|
+
'get?' => request.get?,
|
124
|
+
'post?' => request.post?,
|
125
|
+
'put?' => request.put?,
|
126
|
+
'delete?' => request.delete?
|
110
127
|
}
|
111
128
|
end
|
112
129
|
|
@@ -28,7 +28,7 @@ module Locomotive::Steam
|
|
28
28
|
|
29
29
|
def build_pages_to_xml
|
30
30
|
page_repository.published.map do |page|
|
31
|
-
next if page.index? || page.not_found? || page.layout?
|
31
|
+
next if page.index? || page.not_found? || page.layout? || (!page.templatized? && !page.listed?)
|
32
32
|
|
33
33
|
build_page_xml(page)
|
34
34
|
end.flatten.join.strip
|
@@ -56,6 +56,8 @@ module Locomotive::Steam
|
|
56
56
|
return nil unless build_templatized_page_xml?(page, content_type, locale)
|
57
57
|
|
58
58
|
repositories.content_entry.with(content_type).all.map do |entry|
|
59
|
+
next unless entry.visible? # only visible content entry
|
60
|
+
|
59
61
|
_entry = Locomotive::Steam::Decorators::I18nDecorator.new(entry, locale)
|
60
62
|
|
61
63
|
next if _entry._label.blank? # should be translated
|
@@ -38,7 +38,7 @@ module Locomotive::Steam
|
|
38
38
|
# don't accept a non localized entry in a locale other than the default one
|
39
39
|
return nil if type.localized_names.count == 0 && locale.to_s != default_locale.to_s
|
40
40
|
|
41
|
-
|
41
|
+
decorate_entry(content_entry_repository.with(type).by_slug(slug))
|
42
42
|
else
|
43
43
|
nil
|
44
44
|
end
|
@@ -56,11 +56,6 @@ module Locomotive::Steam
|
|
56
56
|
services.page_finder.find('404')
|
57
57
|
end
|
58
58
|
|
59
|
-
def decorate(entry)
|
60
|
-
return nil if entry.nil?
|
61
|
-
Locomotive::Steam::Decorators::I18nDecorator.new(entry, locale, default_locale)
|
62
|
-
end
|
63
|
-
|
64
59
|
end
|
65
60
|
end
|
66
61
|
end
|
@@ -29,6 +29,10 @@ module Locomotive::Steam::Middlewares
|
|
29
29
|
@services ||= env.fetch('steam.services')
|
30
30
|
end
|
31
31
|
|
32
|
+
def repositories
|
33
|
+
@repositories ||= services.repositories
|
34
|
+
end
|
35
|
+
|
32
36
|
def request
|
33
37
|
@request ||= env.fetch('steam.request')
|
34
38
|
end
|
@@ -69,6 +73,21 @@ module Locomotive::Steam::Middlewares
|
|
69
73
|
!!env['steam.live_editing']
|
70
74
|
end
|
71
75
|
|
76
|
+
def decorate_entry(entry)
|
77
|
+
return nil if entry.nil?
|
78
|
+
Locomotive::Steam::Decorators::I18nDecorator.new(entry, locale, default_locale)
|
79
|
+
end
|
80
|
+
|
81
|
+
def default_liquid_context
|
82
|
+
::Liquid::Context.new({ 'site' => site.to_liquid }, {}, {
|
83
|
+
request: request,
|
84
|
+
locale: locale,
|
85
|
+
site: site,
|
86
|
+
services: services,
|
87
|
+
repositories: services.repositories
|
88
|
+
}, true)
|
89
|
+
end
|
90
|
+
|
72
91
|
end
|
73
92
|
|
74
93
|
end
|
@@ -13,16 +13,29 @@ module Locomotive::Steam
|
|
13
13
|
|
14
14
|
def _call
|
15
15
|
if url = redirect_url
|
16
|
+
emit_event
|
17
|
+
|
16
18
|
redirect_to url
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
22
|
protected
|
21
23
|
|
24
|
+
def requested_url
|
25
|
+
request.env['locomotive.path'] || request.fullpath
|
26
|
+
end
|
27
|
+
|
28
|
+
def emit_event
|
29
|
+
ActiveSupport::Notifications.instrument('steam.serve.url_redirection', {
|
30
|
+
site_id: site._id,
|
31
|
+
url: requested_url
|
32
|
+
})
|
33
|
+
end
|
34
|
+
|
22
35
|
def redirect_url
|
23
36
|
return false if site.url_redirections.nil? || site.url_redirections.size == 0
|
24
37
|
|
25
|
-
site.url_redirections.to_h[
|
38
|
+
site.url_redirections.to_h[requested_url]
|
26
39
|
end
|
27
40
|
|
28
41
|
end
|
@@ -43,7 +43,11 @@ module Locomotive
|
|
43
43
|
|
44
44
|
def build_adapter(options)
|
45
45
|
name = ((options || {})[:name] || :filesystem).to_s
|
46
|
-
|
46
|
+
begin
|
47
|
+
require_relative "adapters/#{name.downcase}"
|
48
|
+
rescue LoadError
|
49
|
+
puts 'Not a Steam built-in adapter'
|
50
|
+
end
|
47
51
|
klass = "Locomotive::Steam::#{name.camelize}Adapter".constantize
|
48
52
|
klass.new(options)
|
49
53
|
end
|
@@ -63,7 +63,7 @@ module Locomotive
|
|
63
63
|
end
|
64
64
|
|
65
65
|
register :action do
|
66
|
-
Steam::ActionService.new(current_site, email, content_entry)
|
66
|
+
Steam::ActionService.new(current_site, email, content_entry: content_entry, api: external_api, redirection: page_redirection)
|
67
67
|
end
|
68
68
|
|
69
69
|
register :content_entry do
|
@@ -82,6 +82,10 @@ module Locomotive
|
|
82
82
|
Steam::UrlBuilderService.new(current_site, locale, request)
|
83
83
|
end
|
84
84
|
|
85
|
+
register :page_redirection do
|
86
|
+
Steam::PageRedirectionService.new(page_finder, url_builder)
|
87
|
+
end
|
88
|
+
|
85
89
|
register :theme_asset_url do
|
86
90
|
Steam::ThemeAssetUrlService.new(repositories.theme_asset, asset_host, configuration.theme_assets_checksum)
|
87
91
|
end
|
@@ -118,6 +122,10 @@ module Locomotive
|
|
118
122
|
Steam::EmailService.new(page_finder, liquid_parser, asset_host, configuration.mode == :test)
|
119
123
|
end
|
120
124
|
|
125
|
+
register :auth do
|
126
|
+
Steam::AuthService.new(content_entry, email)
|
127
|
+
end
|
128
|
+
|
121
129
|
register :cache do
|
122
130
|
Steam::NoCacheService.new
|
123
131
|
end
|
@@ -11,6 +11,8 @@ module Locomotive
|
|
11
11
|
|
12
12
|
class ActionService
|
13
13
|
|
14
|
+
SERVICES = %w(content_entry api redirection)
|
15
|
+
|
14
16
|
BUILT_IN_FUNCTIONS = %w(
|
15
17
|
getProp
|
16
18
|
setProp
|
@@ -20,9 +22,11 @@ module Locomotive
|
|
20
22
|
allEntries
|
21
23
|
findEntry
|
22
24
|
createEntry
|
23
|
-
updateEntry
|
25
|
+
updateEntry
|
26
|
+
callAPI
|
27
|
+
redirectTo)
|
24
28
|
|
25
|
-
attr_accessor_initialize :site, :email, :
|
29
|
+
attr_accessor_initialize :site, :email, :services
|
26
30
|
|
27
31
|
def run(script, params = {}, liquid_context)
|
28
32
|
context = Duktape::Context.new
|
@@ -35,15 +39,22 @@ module Locomotive
|
|
35
39
|
}
|
36
40
|
JS
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
42
|
+
begin
|
43
|
+
context.exec_string script
|
44
|
+
context.call_prop('locomotiveAction', site.as_json, params)
|
45
|
+
rescue Locomotive::Steam::RedirectionException
|
46
|
+
raise
|
47
|
+
rescue Exception => e
|
48
|
+
raise Locomotive::Steam::ActionError.new(e, script)
|
49
|
+
end
|
43
50
|
end
|
44
51
|
|
45
52
|
private
|
46
53
|
|
54
|
+
SERVICES.each do |name|
|
55
|
+
define_method(:"#{name}_service") { self.services[:"#{name}"] }
|
56
|
+
end
|
57
|
+
|
47
58
|
def define_built_in_functions(context, liquid_context)
|
48
59
|
BUILT_IN_FUNCTIONS.each do |name|
|
49
60
|
context.define_function name, &send(:"#{name.underscore}_lambda", liquid_context)
|
@@ -86,6 +97,14 @@ module Locomotive
|
|
86
97
|
-> (type, id_or_slug, attributes) { content_entry_service.update(type, id_or_slug, attributes, true) }
|
87
98
|
end
|
88
99
|
|
100
|
+
def call_api_lambda(liquid_context)
|
101
|
+
-> (method, url, options) { api_service.consume(url, (options || {}).with_indifferent_access.merge(method: method), true) }
|
102
|
+
end
|
103
|
+
|
104
|
+
def redirect_to_lambda(liquid_context)
|
105
|
+
-> (page_handle, locale = nil) { redirection_service.redirect_to(page_handle, locale) }
|
106
|
+
end
|
107
|
+
|
89
108
|
end
|
90
109
|
|
91
110
|
end
|
@@ -18,13 +18,18 @@ module Locomotive
|
|
18
18
|
|
19
19
|
return add_timestamp_suffix(source, timestamp) if source =~ Steam::IsHTTP
|
20
20
|
|
21
|
-
url = self.host ?
|
21
|
+
url = self.host ? build_url(host, source) : source
|
22
22
|
|
23
23
|
add_timestamp_suffix(url, timestamp)
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
|
+
def build_url(host, source)
|
29
|
+
clean_source = source.sub(/\A^\//, '')
|
30
|
+
URI.join(host, clean_source).to_s
|
31
|
+
end
|
32
|
+
|
28
33
|
def build_host(host, request, site)
|
29
34
|
if host
|
30
35
|
if host.respond_to?(:call)
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Steam
|
3
|
+
|
4
|
+
class AuthService
|
5
|
+
|
6
|
+
MIN_PASSWORD_LENGTH = 6
|
7
|
+
RESET_TOKEN_LIFETIME = 1 * 3600 # 6 hours in seconds
|
8
|
+
|
9
|
+
attr_accessor_initialize :entries, :email_service
|
10
|
+
|
11
|
+
def find_authenticated_resource(type, id)
|
12
|
+
entries.find(type, id)
|
13
|
+
end
|
14
|
+
|
15
|
+
def sign_in(options)
|
16
|
+
entry = entries.all(options.type, options.id_field => options.id).first
|
17
|
+
|
18
|
+
if entry
|
19
|
+
hashed_password = entry[:"#{options.password_field}_hash"]
|
20
|
+
password = ::BCrypt::Engine.hash_secret(options.password, entry.send(options.password_field).try(:salt))
|
21
|
+
same_password = secure_compare(password, hashed_password)
|
22
|
+
|
23
|
+
return [:signed_in, entry] if same_password
|
24
|
+
end
|
25
|
+
|
26
|
+
:wrong_credentials
|
27
|
+
end
|
28
|
+
|
29
|
+
# options is an instance of the AuthOptions class
|
30
|
+
def forgot_password(options, context)
|
31
|
+
entry = entries.all(options.type, options.id_field => options.id).first
|
32
|
+
|
33
|
+
if entry.nil?
|
34
|
+
:"wrong_#{options.id_field}"
|
35
|
+
else
|
36
|
+
entries.update_decorated_entry(entry, {
|
37
|
+
'_auth_reset_token' => SecureRandom.hex,
|
38
|
+
'_auth_reset_sent_at' => Time.zone.now.iso8601
|
39
|
+
})
|
40
|
+
|
41
|
+
context['reset_password_url'] = options.reset_password_url + '?auth_reset_token=' + entry['_auth_reset_token']
|
42
|
+
context[options.type.singularize] = entry
|
43
|
+
|
44
|
+
send_reset_password_instructions(options, context)
|
45
|
+
|
46
|
+
:"reset_#{options.password_field}_instructions_sent"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def reset_password(options)
|
51
|
+
return :invalid_token if options.reset_token.blank?
|
52
|
+
return :password_too_short if options.password.to_s.size < MIN_PASSWORD_LENGTH
|
53
|
+
|
54
|
+
entry = entries.all(options.type, '_auth_reset_token' => options.reset_token).first
|
55
|
+
|
56
|
+
if entry
|
57
|
+
sent_at = Time.parse(entry[:_auth_reset_sent_at]).to_i
|
58
|
+
now = Time.zone.now.to_i - RESET_TOKEN_LIFETIME
|
59
|
+
|
60
|
+
if sent_at >= now
|
61
|
+
entries.update_decorated_entry(entry, {
|
62
|
+
"#{options.password_field}_hash" => BCrypt::Password.create(options.password),
|
63
|
+
'_auth_reset_token' => nil,
|
64
|
+
'_auth_reset_sent_at' => nil
|
65
|
+
})
|
66
|
+
|
67
|
+
return [:"#{options.password_field}_reset", entry]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
:invalid_token
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def send_reset_password_instructions(options, context)
|
77
|
+
email_options = { from: options.from, to: options.id, subject: options.subject, smtp: options.smtp }
|
78
|
+
|
79
|
+
if options.email_handle
|
80
|
+
email_options[:page_handle] = options.email_handle
|
81
|
+
else
|
82
|
+
email_options[:body] = <<-EMAIL
|
83
|
+
Hi,
|
84
|
+
To reset your password please follow the link below: #{context['reset_password_url']}.
|
85
|
+
Thanks!
|
86
|
+
EMAIL
|
87
|
+
end
|
88
|
+
|
89
|
+
email_service.send_email(email_options, context)
|
90
|
+
end
|
91
|
+
|
92
|
+
# https://github.com/plataformatec/devise/blob/88724e10adaf9ffd1d8dbfbaadda2b9d40de756a/lib/devise.rb#L485
|
93
|
+
def secure_compare(a, b)
|
94
|
+
return false if a.blank? || b.blank? || a.bytesize != b.bytesize
|
95
|
+
l = a.unpack "C#{a.bytesize}"
|
96
|
+
|
97
|
+
res = 0
|
98
|
+
b.each_byte { |byte| res |= byte ^ l.shift }
|
99
|
+
res == 0
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|