spree_auth_devise 4.1.0 → 4.3.3
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.
Potentially problematic release.
This version of spree_auth_devise might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gem_release.yml +2 -0
- data/.travis.yml +32 -23
- data/Appraisals +1 -1
- data/Gemfile +1 -0
- data/Rakefile +9 -3
- data/app/controllers/spree/api/v2/storefront/account_confirmations_controller.rb +20 -0
- data/app/controllers/spree/api/v2/storefront/passwords_controller.rb +35 -0
- data/app/controllers/spree/user_confirmations_controller.rb +22 -0
- data/app/controllers/spree/user_passwords_controller.rb +15 -1
- data/app/controllers/spree/user_registrations_controller.rb +15 -0
- data/app/controllers/spree/user_sessions_controller.rb +8 -0
- data/app/mailers/spree/user_mailer.rb +11 -4
- data/app/models/spree/user.rb +46 -0
- data/app/services/spree/account/create.rb +19 -0
- data/app/services/spree/account/update.rb +17 -0
- data/app/views/spree/user_mailer/confirmation_instructions.html.erb +20 -0
- data/app/views/spree/user_mailer/confirmation_instructions.text.erb +8 -5
- data/app/views/spree/user_mailer/reset_password_instructions.html.erb +20 -0
- data/app/views/spree/user_mailer/reset_password_instructions.text.erb +7 -5
- data/config/initializers/warden.rb +1 -1
- data/config/locales/de.yml +16 -0
- data/config/locales/en.yml +18 -5
- data/config/locales/zh-TW.yml +58 -0
- data/config/routes.rb +13 -1
- data/gemfiles/spree_4_1.gemfile +1 -1
- data/lib/controllers/api/spree/api/v2/storefront/account_controller_decorator.rb +41 -0
- data/lib/controllers/backend/spree/admin/user_sessions_controller.rb +16 -0
- data/lib/controllers/frontend/spree/checkout_controller_decorator.rb +2 -1
- data/lib/spree/auth/engine.rb +15 -10
- data/lib/spree/auth/version.rb +9 -0
- data/lib/spree_auth_devise.rb +0 -1
- data/lib/views/backend/spree/admin/user_sessions/new.html.erb +1 -1
- data/spec/controllers/spree/api/v2/storefront/passwords_controller_spec.rb +63 -0
- data/spec/features/admin/sign_in_spec.rb +10 -3
- data/spec/features/checkout_spec.rb +3 -3
- data/spec/features/confirmation_spec.rb +2 -5
- data/spec/features/sign_in_spec.rb +15 -8
- data/spec/features/sign_out_spec.rb +1 -3
- data/spec/mailers/user_mailer_spec.rb +3 -3
- data/spec/models/user_spec.rb +43 -10
- data/spec/requests/spree/api/v2/storefront/account_confirmation_spec.rb +48 -0
- data/spec/requests/spree/api/v2/storefront/account_spec.rb +101 -0
- data/spec/spec_helper.rb +7 -38
- data/spec/support/confirm_helpers.rb +21 -8
- data/spree_auth_devise.gemspec +16 -29
- metadata +32 -362
- data/app/overrides/spree/admin/shared/_header/auth_admin_login_navigation_bar.html.erb.deface +0 -4
- data/spec/support/add_to_cart.rb +0 -22
- data/spec/support/authentication_helpers.rb +0 -14
- data/spec/support/cache_helpers.rb +0 -5
- data/spec/support/capybara.rb +0 -23
- data/spec/support/database_cleaner.rb +0 -17
- data/spec/support/factory_girl.rb +0 -5
- data/spec/support/spree.rb +0 -10
- data/spec/support/user_helper.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88bd67ceeb209cf0a5429d736103ffad339942eefd7cf7f75d6b84dfbb25a553
|
4
|
+
data.tar.gz: 261b34f941e7f6584dfa9fb4a50dc76c8b4aae6f9785db618ef630da1f881312
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 489cf73cb272c2318cc35761e736a9b65fb0549e8ba938550fdf63ed16727a562180e22bfd6f210a6e6384fd8e4bb589e9a4bebf37d0e287e0c712c83e1e7214
|
7
|
+
data.tar.gz: 9e16a12db4e028e6318896d5fded01acda724348587a5f6628e437c81be41ccb4f4c6e537aac344c0ed05d223c27cfc03bcf275513ea7d84fa15eafd1f6b271a
|
data/.gem_release.yml
ADDED
data/.travis.yml
CHANGED
@@ -1,38 +1,47 @@
|
|
1
|
-
|
2
|
-
dist:
|
3
|
-
|
4
|
-
script:
|
5
|
-
- bundle exec rake test_app
|
6
|
-
- bundle exec rake spec
|
1
|
+
os: linux
|
2
|
+
dist: bionic
|
7
3
|
|
8
4
|
addons:
|
9
|
-
|
10
|
-
|
5
|
+
apt:
|
6
|
+
sources:
|
7
|
+
- google-chrome
|
8
|
+
packages:
|
9
|
+
- google-chrome-stable
|
11
10
|
|
12
|
-
|
13
|
-
-
|
14
|
-
-
|
11
|
+
services:
|
12
|
+
- mysql
|
13
|
+
- postgresql
|
15
14
|
|
16
15
|
language: ruby
|
17
16
|
|
18
17
|
rvm:
|
19
|
-
- 2.
|
20
|
-
|
18
|
+
- 2.7
|
19
|
+
- 3.0
|
20
|
+
|
21
|
+
env:
|
22
|
+
- DB=mysql
|
23
|
+
- DB=postgres
|
21
24
|
|
22
25
|
gemfile:
|
23
26
|
- gemfiles/spree_4_1.gemfile
|
24
27
|
- gemfiles/spree_master.gemfile
|
25
28
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
jobs:
|
30
|
+
exclude:
|
31
|
+
- rvm: 3.0
|
32
|
+
gemfile: gemfiles/spree_4_1.gemfile
|
33
|
+
allow_failures:
|
34
|
+
- gemfile: gemfiles/spree_master.gemfile
|
29
35
|
|
30
36
|
before_install:
|
31
|
-
- gem update bundler
|
32
37
|
- mysql -u root -e "GRANT ALL ON *.* TO 'travis'@'%';"
|
33
|
-
|
34
|
-
|
35
|
-
-
|
36
|
-
-
|
37
|
-
-
|
38
|
-
-
|
38
|
+
|
39
|
+
before_script:
|
40
|
+
- CHROME_MAIN_VERSION=`google-chrome-stable --version | sed -E 's/(^Google Chrome |\.[0-9]+ )//g'`
|
41
|
+
- CHROMEDRIVER_VERSION=`curl -s "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$CHROME_MAIN_VERSION"`
|
42
|
+
- curl "https://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_linux64.zip" -O
|
43
|
+
- unzip chromedriver_linux64.zip -d ~/bin
|
44
|
+
|
45
|
+
script:
|
46
|
+
- bundle exec rake test_app
|
47
|
+
- bundle exec rake spec
|
data/Appraisals
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -2,14 +2,20 @@ require 'bundler'
|
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
3
|
|
4
4
|
require 'rspec/core/rake_task'
|
5
|
-
require 'spree/testing_support/
|
5
|
+
require 'spree/testing_support/extension_rake'
|
6
6
|
|
7
7
|
RSpec::Core::RakeTask.new
|
8
8
|
|
9
|
-
task default
|
9
|
+
task :default do
|
10
|
+
if Dir["spec/dummy"].empty?
|
11
|
+
Rake::Task[:test_app].invoke
|
12
|
+
Dir.chdir("../../")
|
13
|
+
end
|
14
|
+
Rake::Task[:spec].invoke
|
15
|
+
end
|
10
16
|
|
11
17
|
desc 'Generates a dummy app for testing'
|
12
18
|
task :test_app do
|
13
19
|
ENV['LIB_NAME'] = 'spree/auth'
|
14
|
-
Rake::Task['
|
20
|
+
Rake::Task['extension:test_app'].invoke
|
15
21
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V2
|
4
|
+
module Storefront
|
5
|
+
class AccountConfirmationsController < ::Spree::Api::V2::BaseController
|
6
|
+
|
7
|
+
def show
|
8
|
+
user = Spree.user_class.confirm_by_token(params[:id])
|
9
|
+
|
10
|
+
if user.errors.empty?
|
11
|
+
render json: { data: { state: user.respond_to?(:state) ? user.state : '' } }, status: :ok
|
12
|
+
else
|
13
|
+
render json: { error: user.errors.full_messages.to_sentence }, status: :unprocessable_entity
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V2
|
4
|
+
module Storefront
|
5
|
+
class PasswordsController < ::Spree::Api::V2::BaseController
|
6
|
+
include Spree::Core::ControllerHelpers::Store
|
7
|
+
|
8
|
+
def create
|
9
|
+
user = Spree.user_class.find_by(email: params[:user][:email])
|
10
|
+
|
11
|
+
if user&.send_reset_password_instructions(current_store)
|
12
|
+
head :ok
|
13
|
+
else
|
14
|
+
head :not_found
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def update
|
19
|
+
user = Spree.user_class.reset_password_by_token(
|
20
|
+
password: params[:user][:password],
|
21
|
+
password_confirmation: params[:user][:password_confirmation],
|
22
|
+
reset_password_token: params[:id]
|
23
|
+
)
|
24
|
+
|
25
|
+
if user.errors.empty?
|
26
|
+
head :ok
|
27
|
+
else
|
28
|
+
render json: { error: user.errors.full_messages.to_sentence }, status: :unprocessable_entity
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -6,8 +6,30 @@ class Spree::UserConfirmationsController < Devise::ConfirmationsController
|
|
6
6
|
include Spree::Core::ControllerHelpers::Order
|
7
7
|
include Spree::Core::ControllerHelpers::Store
|
8
8
|
|
9
|
+
if defined?(Spree::Core::ControllerHelpers::Currency)
|
10
|
+
include Spree::Core::ControllerHelpers::Currency
|
11
|
+
end
|
12
|
+
|
13
|
+
if defined?(Spree::Core::ControllerHelpers::Locale)
|
14
|
+
include Spree::Core::ControllerHelpers::Locale
|
15
|
+
end
|
16
|
+
|
9
17
|
before_action :set_current_order
|
10
18
|
|
19
|
+
if Spree.version.to_f >= 4.2
|
20
|
+
# POST /resource/confirmation
|
21
|
+
def create
|
22
|
+
self.resource = resource_class.send_confirmation_instructions(resource_params, current_store)
|
23
|
+
yield resource if block_given?
|
24
|
+
|
25
|
+
if successfully_sent?(resource)
|
26
|
+
respond_with({}, location: after_resending_confirmation_instructions_path_for(resource_name))
|
27
|
+
else
|
28
|
+
respond_with(resource)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
11
33
|
# GET /resource/confirmation?confirmation_token=abcdef
|
12
34
|
def show
|
13
35
|
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
|
@@ -6,6 +6,14 @@ class Spree::UserPasswordsController < Devise::PasswordsController
|
|
6
6
|
include Spree::Core::ControllerHelpers::Order
|
7
7
|
include Spree::Core::ControllerHelpers::Store
|
8
8
|
|
9
|
+
if defined?(Spree::Core::ControllerHelpers::Currency)
|
10
|
+
include Spree::Core::ControllerHelpers::Currency
|
11
|
+
end
|
12
|
+
|
13
|
+
if defined?(Spree::Core::ControllerHelpers::Locale)
|
14
|
+
include Spree::Core::ControllerHelpers::Locale
|
15
|
+
end
|
16
|
+
|
9
17
|
if defined?(SpreeI18n::ControllerLocaleHelper)
|
10
18
|
include SpreeI18n::ControllerLocaleHelper
|
11
19
|
end
|
@@ -20,7 +28,7 @@ class Spree::UserPasswordsController < Devise::PasswordsController
|
|
20
28
|
# respond_with resource, :location => spree.login_path
|
21
29
|
#
|
22
30
|
def create
|
23
|
-
self.resource = resource_class.send_reset_password_instructions(params[resource_name])
|
31
|
+
self.resource = resource_class.send_reset_password_instructions(params[resource_name], current_store)
|
24
32
|
|
25
33
|
if resource.errors.empty?
|
26
34
|
set_flash_message(:notice, :send_instructions) if is_navigational_format?
|
@@ -53,4 +61,10 @@ class Spree::UserPasswordsController < Devise::PasswordsController
|
|
53
61
|
def new_session_path(resource_name)
|
54
62
|
spree.send("new_#{resource_name}_session_path")
|
55
63
|
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def accurate_title
|
68
|
+
Spree.t(:reset_password)
|
69
|
+
end
|
56
70
|
end
|
@@ -6,6 +6,14 @@ class Spree::UserRegistrationsController < Devise::RegistrationsController
|
|
6
6
|
include Spree::Core::ControllerHelpers::Order
|
7
7
|
include Spree::Core::ControllerHelpers::Store
|
8
8
|
|
9
|
+
if defined?(Spree::Core::ControllerHelpers::Currency)
|
10
|
+
include Spree::Core::ControllerHelpers::Currency
|
11
|
+
end
|
12
|
+
|
13
|
+
if defined?(Spree::Core::ControllerHelpers::Locale)
|
14
|
+
include Spree::Core::ControllerHelpers::Locale
|
15
|
+
end
|
16
|
+
|
9
17
|
if defined?(SpreeI18n::ControllerLocaleHelper)
|
10
18
|
include SpreeI18n::ControllerLocaleHelper
|
11
19
|
end
|
@@ -23,6 +31,7 @@ class Spree::UserRegistrationsController < Devise::RegistrationsController
|
|
23
31
|
# POST /resource/sign_up
|
24
32
|
def create
|
25
33
|
@user = build_resource(spree_user_params)
|
34
|
+
resource.skip_confirmation_notification! if Spree::Auth::Config[:confirmable]
|
26
35
|
resource_saved = resource.save
|
27
36
|
yield resource if block_given?
|
28
37
|
if resource_saved
|
@@ -30,10 +39,12 @@ class Spree::UserRegistrationsController < Devise::RegistrationsController
|
|
30
39
|
set_flash_message :notice, :signed_up
|
31
40
|
sign_up(resource_name, resource)
|
32
41
|
session[:spree_user_signup] = true
|
42
|
+
resource.send_confirmation_instructions(current_store) if Spree::Auth::Config[:confirmable]
|
33
43
|
redirect_to_checkout_or_account_path(resource)
|
34
44
|
else
|
35
45
|
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}"
|
36
46
|
expire_data_after_sign_in!
|
47
|
+
resource.send_confirmation_instructions(current_store) if Spree::Auth::Config[:confirmable]
|
37
48
|
respond_with resource, location: after_inactive_sign_up_path_for(resource)
|
38
49
|
end
|
39
50
|
else
|
@@ -89,6 +100,10 @@ class Spree::UserRegistrationsController < Devise::RegistrationsController
|
|
89
100
|
|
90
101
|
private
|
91
102
|
|
103
|
+
def accurate_title
|
104
|
+
Spree.t(:sign_up)
|
105
|
+
end
|
106
|
+
|
92
107
|
def spree_user_params
|
93
108
|
params.require(:spree_user).permit(Spree::PermittedAttributes.user_attributes)
|
94
109
|
end
|
@@ -6,6 +6,14 @@ class Spree::UserSessionsController < Devise::SessionsController
|
|
6
6
|
include Spree::Core::ControllerHelpers::Order
|
7
7
|
include Spree::Core::ControllerHelpers::Store
|
8
8
|
|
9
|
+
if defined?(Spree::Core::ControllerHelpers::Currency)
|
10
|
+
include Spree::Core::ControllerHelpers::Currency
|
11
|
+
end
|
12
|
+
|
13
|
+
if defined?(Spree::Core::ControllerHelpers::Locale)
|
14
|
+
include Spree::Core::ControllerHelpers::Locale
|
15
|
+
end
|
16
|
+
|
9
17
|
if defined?(SpreeI18n::ControllerLocaleHelper)
|
10
18
|
include SpreeI18n::ControllerLocaleHelper
|
11
19
|
end
|
@@ -1,16 +1,23 @@
|
|
1
1
|
module Spree
|
2
2
|
class UserMailer < BaseMailer
|
3
3
|
def reset_password_instructions(user, token, *_args)
|
4
|
-
|
4
|
+
current_store_id = _args.inject(:merge)[:current_store_id]
|
5
|
+
@current_store = Spree::Store.find(current_store_id) || Spree::Store.current
|
6
|
+
@locale = @current_store.has_attribute?(:default_locale) ? @current_store.default_locale : I18n.default_locale
|
7
|
+
I18n.locale = @locale if @locale.present?
|
8
|
+
@edit_password_reset_url = spree.edit_spree_user_password_url(reset_password_token: token, host: @current_store.url)
|
9
|
+
@user = user
|
5
10
|
|
6
|
-
mail to: user.email, from: from_address, subject:
|
11
|
+
mail to: user.email, from: from_address, subject: @current_store.name + ' ' + I18n.t(:subject, scope: [:devise, :mailer, :reset_password_instructions]), store_url: @current_store.url
|
7
12
|
end
|
8
13
|
|
9
14
|
def confirmation_instructions(user, token, _opts = {})
|
10
|
-
|
15
|
+
current_store_id = _opts[:current_store_id]
|
16
|
+
@current_store = Spree::Store.find(current_store_id) || Spree::Store.current
|
17
|
+
@confirmation_url = spree.confirmation_url(confirmation_token: token, host: Spree::Store.current.url)
|
11
18
|
@email = user.email
|
12
19
|
|
13
|
-
mail to: user.email, from: from_address, subject:
|
20
|
+
mail to: user.email, from: from_address, subject: @current_store.name + ' ' + I18n.t(:subject, scope: [:devise, :mailer, :confirmation_instructions]), store_url: @current_store.url
|
14
21
|
end
|
15
22
|
end
|
16
23
|
end
|
data/app/models/spree/user.rb
CHANGED
@@ -27,8 +27,54 @@ module Spree
|
|
27
27
|
has_spree_role?('admin')
|
28
28
|
end
|
29
29
|
|
30
|
+
def self.send_confirmation_instructions(attributes = {}, current_store)
|
31
|
+
confirmable = find_by_unconfirmed_email_with_errors(attributes) if reconfirmable
|
32
|
+
unless confirmable.try(:persisted?)
|
33
|
+
confirmable = find_or_initialize_with_errors(confirmation_keys, attributes, :not_found)
|
34
|
+
end
|
35
|
+
confirmable.resend_confirmation_instructions(current_store) if confirmable.persisted?
|
36
|
+
confirmable
|
37
|
+
end
|
38
|
+
|
39
|
+
def resend_confirmation_instructions(current_store)
|
40
|
+
pending_any_confirmation do
|
41
|
+
send_confirmation_instructions(current_store)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def send_confirmation_instructions(current_store)
|
46
|
+
unless @raw_confirmation_token
|
47
|
+
generate_confirmation_token!
|
48
|
+
end
|
49
|
+
|
50
|
+
opts = pending_reconfirmation? ? { to: unconfirmed_email } : {}
|
51
|
+
opts[:current_store_id] = current_store&.id || Spree::Store.default.id
|
52
|
+
send_devise_notification(:confirmation_instructions, @raw_confirmation_token, opts)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.send_reset_password_instructions(attributes={}, current_store)
|
56
|
+
recoverable = find_or_initialize_with_errors(reset_password_keys, attributes, :not_found)
|
57
|
+
recoverable.send_reset_password_instructions(current_store) if recoverable.persisted?
|
58
|
+
recoverable
|
59
|
+
end
|
60
|
+
|
61
|
+
def send_reset_password_instructions(current_store)
|
62
|
+
token = set_reset_password_token
|
63
|
+
send_reset_password_instructions_notification(token, current_store.id)
|
64
|
+
|
65
|
+
token
|
66
|
+
end
|
67
|
+
|
68
|
+
def send_reset_password_instructions_notification(token, current_store_id)
|
69
|
+
send_devise_notification(:reset_password_instructions, token, { current_store_id: current_store_id })
|
70
|
+
end
|
71
|
+
|
30
72
|
protected
|
31
73
|
|
74
|
+
def send_on_create_confirmation_instructions(current_store = nil)
|
75
|
+
send_confirmation_instructions(current_store || Spree::Store.default)
|
76
|
+
end
|
77
|
+
|
32
78
|
def password_required?
|
33
79
|
!persisted? || password.present? || password_confirmation.present?
|
34
80
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Spree
|
2
|
+
module Account
|
3
|
+
class Create
|
4
|
+
prepend Spree::ServiceModule::Base
|
5
|
+
|
6
|
+
def call(user_params: nil)
|
7
|
+
user_params ||= {}
|
8
|
+
|
9
|
+
user = Spree.user_class.new(user_params)
|
10
|
+
|
11
|
+
if user.save
|
12
|
+
success(user)
|
13
|
+
else
|
14
|
+
failure(user)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Spree
|
2
|
+
module Account
|
3
|
+
class Update
|
4
|
+
prepend Spree::ServiceModule::Base
|
5
|
+
|
6
|
+
def call(user:, user_params: nil)
|
7
|
+
user_params ||= {}
|
8
|
+
|
9
|
+
if user.update(user_params)
|
10
|
+
success(user)
|
11
|
+
else
|
12
|
+
failure(user)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<h1>
|
2
|
+
<%= Spree.t('user_mailer.confirmation_instructions.welcome', email: @email) %>
|
3
|
+
</h1>
|
4
|
+
<p>
|
5
|
+
<%= Spree.t('user_mailer.confirmation_instructions.instructions_1', { store_name: @current_store.name }) %>
|
6
|
+
</p>
|
7
|
+
<p>
|
8
|
+
<%= Spree.t('user_mailer.confirmation_instructions.instructions_2') %>
|
9
|
+
</p>
|
10
|
+
<p class="body-action">
|
11
|
+
<a href="<%= @confirmation_url %>" class="button button--green"><%= Spree.t('user_mailer.confirmation_instructions.button') %></a>
|
12
|
+
</p>
|
13
|
+
<p>
|
14
|
+
<%= Spree.t('user_mailer.confirmation_instructions.instructions_3') %>
|
15
|
+
</p>
|
16
|
+
<p>
|
17
|
+
<%= Spree.t('user_mailer.confirmation_instructions.thanks') %>
|
18
|
+
<br />
|
19
|
+
<%= Spree.t('user_mailer.confirmation_instructions.store_team', { store_name: @current_store.name }) %>
|
20
|
+
</p>
|