diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 00000000..85e35feb
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,23 @@
+AllCops:
+ Exclude:
+ - "vendor/**/*"
+ - "db/**/*"
+ - "bin/*"
+ - "node_modules/**/*"
+ - "config/initializers/devise.rb"
+ - "config/environments/*.rb"
+ - "Gemfile"
+ - "Rakefile"
+
+Style/FrozenStringLiteralComment:
+ Enabled: false
+
+Style/ClassAndModuleChildren:
+ Enabled: false
+
+Style/Documentation:
+ Enabled: false
+
+Metrics/BlockLength:
+ Exclude:
+ - "config/routes.rb"
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index a498d272..0d189f00 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -51,7 +51,7 @@ ARG UID=1000
ARG GID=1000
RUN apt-get update \
- && apt-get install -y --no-install-recommends build-essential curl libpq-dev \
+ && apt-get install -y --no-install-recommends build-essential curl libpq-dev vim \
&& rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man \
&& apt-get clean \
&& groupadd -g "${GID}" ruby \
diff --git a/Gemfile b/Gemfile
index 79a31661..aac3b6fe 100644
--- a/Gemfile
+++ b/Gemfile
@@ -49,6 +49,10 @@ group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "debug", platforms: %i[ mri mingw x64_mingw ]
+ gem "rubocop", require: false
+ gem "rubocop-performance", require: false
+ gem "rubocop-rails", require: false
+
# Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", require: false
end
@@ -70,3 +74,6 @@ group :test do
gem "selenium-webdriver"
gem "webdrivers"
end
+
+ gem "devise"
+ gem "stripe"
\ No newline at end of file
diff --git a/Gemfile.lock b/Gemfile.lock
index 86dcc1a2..b69d2016 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -68,6 +68,8 @@ GEM
tzinfo (~> 2.0)
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
+ ast (2.4.2)
+ bcrypt (3.1.20)
bindex (0.8.1)
bootsnap (1.15.0)
msgpack (~> 1.2)
@@ -90,6 +92,12 @@ GEM
debug (1.6.3)
irb (>= 1.3.6)
reline (>= 0.3.1)
+ devise (4.9.4)
+ bcrypt (~> 3.0)
+ orm_adapter (~> 0.1)
+ railties (>= 4.1.0)
+ responders
+ warden (~> 1.2.3)
erubi (1.11.0)
globalid (1.0.0)
activesupport (>= 5.0)
@@ -103,6 +111,8 @@ GEM
activesupport (>= 5.0.0)
jsbundling-rails (1.0.3)
railties (>= 6.0.0)
+ json (2.9.1)
+ language_server-protocol (3.17.0.3)
loofah (2.19.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
@@ -123,8 +133,15 @@ GEM
net-smtp (0.3.3)
net-protocol
nio4r (2.5.8)
+ nokogiri (1.13.9-aarch64-linux)
+ racc (~> 1.4)
nokogiri (1.13.9-x86_64-linux)
racc (~> 1.4)
+ orm_adapter (0.5.0)
+ parallel (1.26.3)
+ parser (3.3.6.0)
+ ast (~> 2.4.1)
+ racc
pg (1.4.5)
public_suffix (5.0.0)
puma (6.0.0)
@@ -161,6 +178,7 @@ GEM
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
+ rainbow (3.1.1)
rake (13.0.6)
redis (5.0.5)
redis-client (>= 0.9.0)
@@ -169,7 +187,31 @@ GEM
regexp_parser (2.6.1)
reline (0.3.1)
io-console (~> 0.5)
+ responders (3.1.1)
+ actionpack (>= 5.2)
+ railties (>= 5.2)
rexml (3.2.5)
+ rubocop (1.69.0)
+ json (~> 2.3)
+ language_server-protocol (>= 3.17.0)
+ parallel (~> 1.10)
+ parser (>= 3.3.0.2)
+ rainbow (>= 2.2.2, < 4.0)
+ regexp_parser (>= 2.4, < 3.0)
+ rubocop-ast (>= 1.36.1, < 2.0)
+ ruby-progressbar (~> 1.7)
+ unicode-display_width (>= 2.4.0, < 4.0)
+ rubocop-ast (1.37.0)
+ parser (>= 3.3.1.0)
+ rubocop-performance (1.23.1)
+ rubocop (>= 1.48.1, < 2.0)
+ rubocop-ast (>= 1.31.1, < 2.0)
+ rubocop-rails (2.28.0)
+ activesupport (>= 4.2.0)
+ rack (>= 1.1)
+ rubocop (>= 1.52.0, < 2.0)
+ rubocop-ast (>= 1.31.1, < 2.0)
+ ruby-progressbar (1.13.0)
rubyzip (2.3.2)
selenium-webdriver (4.6.1)
childprocess (>= 0.5, < 5.0)
@@ -190,6 +232,7 @@ GEM
sprockets (>= 3.0.0)
stimulus-rails (1.2.0)
railties (>= 6.0.0)
+ stripe (13.3.0)
thor (1.2.1)
timeout (0.3.0)
turbo-rails (1.3.2)
@@ -198,6 +241,11 @@ GEM
railties (>= 6.0.0)
tzinfo (2.0.5)
concurrent-ruby (~> 1.0)
+ unicode-display_width (3.1.3)
+ unicode-emoji (~> 4.0, >= 4.0.4)
+ unicode-emoji (4.0.4)
+ warden (1.2.9)
+ rack (>= 2.0.9)
web-console (4.2.0)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
@@ -216,6 +264,7 @@ GEM
zeitwerk (2.6.6)
PLATFORMS
+ aarch64-linux
x86_64-linux
DEPENDENCIES
@@ -223,6 +272,7 @@ DEPENDENCIES
capybara
cssbundling-rails
debug
+ devise
jbuilder
jsbundling-rails
pg (~> 1.1)
@@ -230,10 +280,14 @@ DEPENDENCIES
rack-mini-profiler
rails (~> 7.0.4)
redis (~> 5.0)
+ rubocop
+ rubocop-performance
+ rubocop-rails
selenium-webdriver
sidekiq (~> 7.0)
sprockets-rails
stimulus-rails
+ stripe
turbo-rails
tzinfo-data
web-console
diff --git a/app/controllers/admin/confirmations_controller.rb b/app/controllers/admin/confirmations_controller.rb
new file mode 100644
index 00000000..8b5c781f
--- /dev/null
+++ b/app/controllers/admin/confirmations_controller.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class Admin::ConfirmationsController < Devise::ConfirmationsController
+ # GET /resource/confirmation/new
+ # def new
+ # super
+ # end
+
+ # POST /resource/confirmation
+ # def create
+ # super
+ # end
+
+ # GET /resource/confirmation?confirmation_token=abcdef
+ # def show
+ # super
+ # end
+
+ # protected
+
+ # The path used after resending confirmation instructions.
+ # def after_resending_confirmation_instructions_path_for(resource_name)
+ # super(resource_name)
+ # end
+
+ # The path used after confirmation.
+ # def after_confirmation_path_for(resource_name, resource)
+ # super(resource_name, resource)
+ # end
+end
diff --git a/app/controllers/admin/omniauth_callbacks_controller.rb b/app/controllers/admin/omniauth_callbacks_controller.rb
new file mode 100644
index 00000000..597707ed
--- /dev/null
+++ b/app/controllers/admin/omniauth_callbacks_controller.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class Admin::OmniauthCallbacksController < Devise::OmniauthCallbacksController
+ # You should configure your model like this:
+ # devise :omniauthable, omniauth_providers: [:twitter]
+
+ # You should also create an action method in this controller like this:
+ # def twitter
+ # end
+
+ # More info at:
+ # https://github.com/heartcombo/devise#omniauth
+
+ # GET|POST /resource/auth/twitter
+ # def passthru
+ # super
+ # end
+
+ # GET|POST /users/auth/twitter/callback
+ # def failure
+ # super
+ # end
+
+ # protected
+
+ # The path used when OmniAuth fails
+ # def after_omniauth_failure_path_for(scope)
+ # super(scope)
+ # end
+end
diff --git a/app/controllers/admin/passwords_controller.rb b/app/controllers/admin/passwords_controller.rb
new file mode 100644
index 00000000..b3605a3a
--- /dev/null
+++ b/app/controllers/admin/passwords_controller.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+class Admin::PasswordsController < Devise::PasswordsController
+ # GET /resource/password/new
+ # def new
+ # super
+ # end
+
+ # POST /resource/password
+ # def create
+ # super
+ # end
+
+ # GET /resource/password/edit?reset_password_token=abcdef
+ # def edit
+ # super
+ # end
+
+ # PUT /resource/password
+ # def update
+ # super
+ # end
+
+ # protected
+
+ # def after_resetting_password_path_for(resource)
+ # super(resource)
+ # end
+
+ # The path used after sending reset password instructions
+ # def after_sending_reset_password_instructions_path_for(resource_name)
+ # super(resource_name)
+ # end
+end
diff --git a/app/controllers/admin/registrations_controller.rb b/app/controllers/admin/registrations_controller.rb
new file mode 100644
index 00000000..6f774e3f
--- /dev/null
+++ b/app/controllers/admin/registrations_controller.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+class Admin::RegistrationsController < Devise::RegistrationsController
+ # before_action :configure_sign_up_params, only: [:create]
+ # before_action :configure_account_update_params, only: [:update]
+
+ # GET /resource/sign_up
+ # def new
+ # super
+ # end
+
+ # POST /resource
+ # def create
+ # super
+ # end
+
+ # GET /resource/edit
+ # def edit
+ # super
+ # end
+
+ # PUT /resource
+ # def update
+ # super
+ # end
+
+ # DELETE /resource
+ # def destroy
+ # super
+ # end
+
+ # GET /resource/cancel
+ # Forces the session data which is usually expired after sign
+ # in to be expired now. This is useful if the user wants to
+ # cancel oauth signing in/up in the middle of the process,
+ # removing all OAuth session data.
+ # def cancel
+ # super
+ # end
+
+ # protected
+
+ # If you have extra params to permit, append them to the sanitizer.
+ # def configure_sign_up_params
+ # devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute])
+ # end
+
+ # If you have extra params to permit, append them to the sanitizer.
+ # def configure_account_update_params
+ # devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
+ # end
+
+ # The path used after sign up.
+ # def after_sign_up_path_for(resource)
+ # super(resource)
+ # end
+
+ # The path used after sign up for inactive accounts.
+ # def after_inactive_sign_up_path_for(resource)
+ # super(resource)
+ # end
+end
diff --git a/app/controllers/admin/sessions_controller.rb b/app/controllers/admin/sessions_controller.rb
new file mode 100644
index 00000000..2e4bae98
--- /dev/null
+++ b/app/controllers/admin/sessions_controller.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class Admin::SessionsController < Devise::SessionsController
+ # before_action :configure_sign_in_params, only: [:create]
+
+ # GET /resource/sign_in
+ # def new
+ # super
+ # end
+
+ # POST /resource/sign_in
+ # def create
+ # super
+ # end
+
+ # DELETE /resource/sign_out
+ # def destroy
+ # super
+ # end
+
+ # protected
+
+ # If you have extra params to permit, append them to the sanitizer.
+ # def configure_sign_in_params
+ # devise_parameter_sanitizer.permit(:sign_in, keys: [:attribute])
+ # end
+end
diff --git a/app/controllers/admin/unlocks_controller.rb b/app/controllers/admin/unlocks_controller.rb
new file mode 100644
index 00000000..4966b9e5
--- /dev/null
+++ b/app/controllers/admin/unlocks_controller.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class Admin::UnlocksController < Devise::UnlocksController
+ # GET /resource/unlock/new
+ # def new
+ # super
+ # end
+
+ # POST /resource/unlock
+ # def create
+ # super
+ # end
+
+ # GET /resource/unlock?unlock_token=abcdef
+ # def show
+ # super
+ # end
+
+ # protected
+
+ # The path used after sending unlock password instructions
+ # def after_sending_unlock_instructions_path_for(resource)
+ # super(resource)
+ # end
+
+ # The path used after unlocking the resource
+ # def after_unlock_path_for(resource)
+ # super(resource)
+ # end
+end
diff --git a/app/controllers/customer/confirmations_controller.rb b/app/controllers/customer/confirmations_controller.rb
new file mode 100644
index 00000000..5292440d
--- /dev/null
+++ b/app/controllers/customer/confirmations_controller.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class Customer::ConfirmationsController < Devise::ConfirmationsController
+ # GET /resource/confirmation/new
+ # def new
+ # super
+ # end
+
+ # POST /resource/confirmation
+ # def create
+ # super
+ # end
+
+ # GET /resource/confirmation?confirmation_token=abcdef
+ # def show
+ # super
+ # end
+
+ # protected
+
+ # The path used after resending confirmation instructions.
+ # def after_resending_confirmation_instructions_path_for(resource_name)
+ # super(resource_name)
+ # end
+
+ # The path used after confirmation.
+ # def after_confirmation_path_for(resource_name, resource)
+ # super(resource_name, resource)
+ # end
+end
diff --git a/app/controllers/customer/omniauth_callbacks_controller.rb b/app/controllers/customer/omniauth_callbacks_controller.rb
new file mode 100644
index 00000000..f40f40fb
--- /dev/null
+++ b/app/controllers/customer/omniauth_callbacks_controller.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class Customer::OmniauthCallbacksController < Devise::OmniauthCallbacksController
+ # You should configure your model like this:
+ # devise :omniauthable, omniauth_providers: [:twitter]
+
+ # You should also create an action method in this controller like this:
+ # def twitter
+ # end
+
+ # More info at:
+ # https://github.com/heartcombo/devise#omniauth
+
+ # GET|POST /resource/auth/twitter
+ # def passthru
+ # super
+ # end
+
+ # GET|POST /users/auth/twitter/callback
+ # def failure
+ # super
+ # end
+
+ # protected
+
+ # The path used when OmniAuth fails
+ # def after_omniauth_failure_path_for(scope)
+ # super(scope)
+ # end
+end
diff --git a/app/controllers/customer/passwords_controller.rb b/app/controllers/customer/passwords_controller.rb
new file mode 100644
index 00000000..40119883
--- /dev/null
+++ b/app/controllers/customer/passwords_controller.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+class Customer::PasswordsController < Devise::PasswordsController
+ # GET /resource/password/new
+ # def new
+ # super
+ # end
+
+ # POST /resource/password
+ # def create
+ # super
+ # end
+
+ # GET /resource/password/edit?reset_password_token=abcdef
+ # def edit
+ # super
+ # end
+
+ # PUT /resource/password
+ # def update
+ # super
+ # end
+
+ # protected
+
+ # def after_resetting_password_path_for(resource)
+ # super(resource)
+ # end
+
+ # The path used after sending reset password instructions
+ # def after_sending_reset_password_instructions_path_for(resource_name)
+ # super(resource_name)
+ # end
+end
diff --git a/app/controllers/customer/registrations_controller.rb b/app/controllers/customer/registrations_controller.rb
new file mode 100644
index 00000000..3ebbdfda
--- /dev/null
+++ b/app/controllers/customer/registrations_controller.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+class Customer::RegistrationsController < Devise::RegistrationsController
+ before_action :configure_sign_up_params, only: [:create]
+ before_action :configure_account_update_params, only: [:update]
+
+ # GET /resource/sign_up
+ # def new
+ # super
+ # end
+
+ # POST /resource
+ # def create
+ # super
+ # end
+
+ # GET /resource/edit
+ # def edit
+ # super
+ # end
+
+ # PUT /resource
+ # def update
+ # super
+ # end
+
+ # DELETE /resource
+ # def destroy
+ # super
+ # end
+
+ # GET /resource/cancel
+ # Forces the session data which is usually expired after sign
+ # in to be expired now. This is useful if the user wants to
+ # cancel oauth signing in/up in the middle of the process,
+ # removing all OAuth session data.
+ # def cancel
+ # super
+ # end
+
+ protected
+
+ # If you have extra params to permit, append them to the sanitizer.
+ def configure_sign_up_params
+ devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
+ end
+
+ # If you have extra params to permit, append them to the sanitizer.
+ def configure_account_update_params
+ devise_parameter_sanitizer.permit(:account_update, keys: [:name])
+ end
+
+ # The path used after sign up.
+ # def after_sign_up_path_for(resource)
+ # super(resource)
+ # end
+
+ # The path used after sign up for inactive accounts.
+ # def after_inactive_sign_up_path_for(resource)
+ # super(resource)
+ # end
+end
diff --git a/app/controllers/customer/sessions_controller.rb b/app/controllers/customer/sessions_controller.rb
new file mode 100644
index 00000000..50c30e98
--- /dev/null
+++ b/app/controllers/customer/sessions_controller.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class Customer::SessionsController < Devise::SessionsController
+ # before_action :configure_sign_in_params, only: [:create]
+
+ # GET /resource/sign_in
+ # def new
+ # super
+ # end
+
+ # POST /resource/sign_in
+ # def create
+ # super
+ # end
+
+ # DELETE /resource/sign_out
+ # def destroy
+ # super
+ # end
+
+ # protected
+
+ # If you have extra params to permit, append them to the sanitizer.
+ # def configure_sign_in_params
+ # devise_parameter_sanitizer.permit(:sign_in, keys: [:attribute])
+ # end
+end
diff --git a/app/controllers/customer/unlocks_controller.rb b/app/controllers/customer/unlocks_controller.rb
new file mode 100644
index 00000000..b75cd82e
--- /dev/null
+++ b/app/controllers/customer/unlocks_controller.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class Customer::UnlocksController < Devise::UnlocksController
+ # GET /resource/unlock/new
+ # def new
+ # super
+ # end
+
+ # POST /resource/unlock
+ # def create
+ # super
+ # end
+
+ # GET /resource/unlock?unlock_token=abcdef
+ # def show
+ # super
+ # end
+
+ # protected
+
+ # The path used after sending unlock password instructions
+ # def after_sending_unlock_instructions_path_for(resource)
+ # super(resource)
+ # end
+
+ # The path used after unlocking the resource
+ # def after_unlock_path_for(resource)
+ # super(resource)
+ # end
+end
diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb
index 45f463e4..2f5a6000 100644
--- a/app/controllers/pages_controller.rb
+++ b/app/controllers/pages_controller.rb
@@ -1,4 +1,3 @@
class PagesController < ApplicationController
- def home
- end
+ def home; end
end
diff --git a/app/controllers/up_controller.rb b/app/controllers/up_controller.rb
index 8416becf..f9f9e796 100644
--- a/app/controllers/up_controller.rb
+++ b/app/controllers/up_controller.rb
@@ -5,7 +5,7 @@ def index
def databases
RedisConn.current.ping
- ActiveRecord::Base.connection.execute("SELECT 1")
+ ActiveRecord::Base.connection.execute('SELECT 1')
head :ok
end
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
index 3c34c814..286b2239 100644
--- a/app/mailers/application_mailer.rb
+++ b/app/mailers/application_mailer.rb
@@ -1,4 +1,4 @@
class ApplicationMailer < ActionMailer::Base
- default from: "from@example.com"
- layout "mailer"
+ default from: 'from@example.com'
+ layout 'mailer'
end
diff --git a/app/models/admin.rb b/app/models/admin.rb
new file mode 100644
index 00000000..7a7be2f6
--- /dev/null
+++ b/app/models/admin.rb
@@ -0,0 +1,6 @@
+class Admin < ApplicationRecord
+ # Include default devise modules. Others available are:
+ # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
+ devise :database_authenticatable, :registerable,
+ :recoverable, :rememberable, :validatable
+end
diff --git a/app/models/customer.rb b/app/models/customer.rb
new file mode 100644
index 00000000..b5eed9be
--- /dev/null
+++ b/app/models/customer.rb
@@ -0,0 +1,15 @@
+class Customer < ApplicationRecord
+ # Include default devise modules. Others available are:
+ # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
+ devise :database_authenticatable, :registerable,
+ :recoverable, :rememberable, :validatable
+ with_options presence: true do
+ validates :name
+ validates :status
+ end
+ enum status: {
+ normal: 0,
+ withdrawn: 1,
+ banned: 2
+ }
+end
diff --git a/app/views/admin/confirmations/new.html.erb b/app/views/admin/confirmations/new.html.erb
new file mode 100644
index 00000000..e4593582
--- /dev/null
+++ b/app/views/admin/confirmations/new.html.erb
@@ -0,0 +1,16 @@
+
Resend confirmation instructions
+
+<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
+ <%= render "admin/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
+
+
+
+ <%= f.submit "Resend confirmation instructions" %>
+
+<% end %>
+
+<%= render "admin/shared/links" %>
diff --git a/app/views/admin/mailer/confirmation_instructions.html.erb b/app/views/admin/mailer/confirmation_instructions.html.erb
new file mode 100644
index 00000000..dc55f64f
--- /dev/null
+++ b/app/views/admin/mailer/confirmation_instructions.html.erb
@@ -0,0 +1,5 @@
+Welcome <%= @email %>!
+
+You can confirm your account email through the link below:
+
+<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>
diff --git a/app/views/admin/mailer/email_changed.html.erb b/app/views/admin/mailer/email_changed.html.erb
new file mode 100644
index 00000000..32f4ba80
--- /dev/null
+++ b/app/views/admin/mailer/email_changed.html.erb
@@ -0,0 +1,7 @@
+Hello <%= @email %>!
+
+<% if @resource.try(:unconfirmed_email?) %>
+ We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.
+<% else %>
+ We're contacting you to notify you that your email has been changed to <%= @resource.email %>.
+<% end %>
diff --git a/app/views/admin/mailer/password_change.html.erb b/app/views/admin/mailer/password_change.html.erb
new file mode 100644
index 00000000..b41daf47
--- /dev/null
+++ b/app/views/admin/mailer/password_change.html.erb
@@ -0,0 +1,3 @@
+Hello <%= @resource.email %>!
+
+We're contacting you to notify you that your password has been changed.
diff --git a/app/views/admin/mailer/reset_password_instructions.html.erb b/app/views/admin/mailer/reset_password_instructions.html.erb
new file mode 100644
index 00000000..f667dc12
--- /dev/null
+++ b/app/views/admin/mailer/reset_password_instructions.html.erb
@@ -0,0 +1,8 @@
+Hello <%= @resource.email %>!
+
+Someone has requested a link to change your password. You can do this through the link below.
+
+<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>
+
+If you didn't request this, please ignore this email.
+Your password won't change until you access the link above and create a new one.
diff --git a/app/views/admin/mailer/unlock_instructions.html.erb b/app/views/admin/mailer/unlock_instructions.html.erb
new file mode 100644
index 00000000..41e148bf
--- /dev/null
+++ b/app/views/admin/mailer/unlock_instructions.html.erb
@@ -0,0 +1,7 @@
+Hello <%= @resource.email %>!
+
+Your account has been locked due to an excessive number of unsuccessful sign in attempts.
+
+Click the link below to unlock your account:
+
+<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>
diff --git a/app/views/admin/passwords/edit.html.erb b/app/views/admin/passwords/edit.html.erb
new file mode 100644
index 00000000..64ee01ff
--- /dev/null
+++ b/app/views/admin/passwords/edit.html.erb
@@ -0,0 +1,25 @@
+Change your password
+
+<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
+ <%= render "admin/shared/error_messages", resource: resource %>
+ <%= f.hidden_field :reset_password_token %>
+
+
+ <%= f.label :password, "New password" %>
+ <% if @minimum_password_length %>
+ (<%= @minimum_password_length %> characters minimum)
+ <% end %>
+ <%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
+
+
+
+ <%= f.label :password_confirmation, "Confirm new password" %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+
+
+
+ <%= f.submit "Change my password" %>
+
+<% end %>
+
+<%= render "admin/shared/links" %>
diff --git a/app/views/admin/passwords/new.html.erb b/app/views/admin/passwords/new.html.erb
new file mode 100644
index 00000000..0e0a9948
--- /dev/null
+++ b/app/views/admin/passwords/new.html.erb
@@ -0,0 +1,16 @@
+Forgot your password?
+
+<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
+ <%= render "admin/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.submit "Send me reset password instructions" %>
+
+<% end %>
+
+<%= render "admin/shared/links" %>
diff --git a/app/views/admin/registrations/edit.html.erb b/app/views/admin/registrations/edit.html.erb
new file mode 100644
index 00000000..87dd8eb1
--- /dev/null
+++ b/app/views/admin/registrations/edit.html.erb
@@ -0,0 +1,43 @@
+Edit <%= resource_name.to_s.humanize %>
+
+<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
+ <%= render "admin/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+ <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
+ Currently waiting confirmation for: <%= resource.unconfirmed_email %>
+ <% end %>
+
+
+ <%= f.label :password %> (leave blank if you don't want to change it)
+ <%= f.password_field :password, autocomplete: "new-password" %>
+ <% if @minimum_password_length %>
+
+ <%= @minimum_password_length %> characters minimum
+ <% end %>
+
+
+
+ <%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+
+
+
+ <%= f.label :current_password %> (we need your current password to confirm your changes)
+ <%= f.password_field :current_password, autocomplete: "current-password" %>
+
+
+
+ <%= f.submit "Update" %>
+
+<% end %>
+
+Cancel my account
+
+Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?" }, method: :delete %>
+
+<%= link_to "Back", :back %>
diff --git a/app/views/admin/registrations/new.html.erb b/app/views/admin/registrations/new.html.erb
new file mode 100644
index 00000000..141c3aa1
--- /dev/null
+++ b/app/views/admin/registrations/new.html.erb
@@ -0,0 +1,29 @@
+Sign up
+
+<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
+ <%= render "admin/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.label :password %>
+ <% if @minimum_password_length %>
+ (<%= @minimum_password_length %> characters minimum)
+ <% end %>
+ <%= f.password_field :password, autocomplete: "new-password" %>
+
+
+
+ <%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+
+
+
+ <%= f.submit "Sign up" %>
+
+<% end %>
+
+<%= render "admin/shared/links" %>
diff --git a/app/views/admin/sessions/new.html.erb b/app/views/admin/sessions/new.html.erb
new file mode 100644
index 00000000..ac415ae5
--- /dev/null
+++ b/app/views/admin/sessions/new.html.erb
@@ -0,0 +1,26 @@
+Log in
+
+<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.label :password %>
+ <%= f.password_field :password, autocomplete: "current-password" %>
+
+
+ <% if devise_mapping.rememberable? %>
+
+ <%= f.check_box :remember_me %>
+ <%= f.label :remember_me %>
+
+ <% end %>
+
+
+ <%= f.submit "Log in" %>
+
+<% end %>
+
+<%= render "admin/shared/links" %>
diff --git a/app/views/admin/shared/_error_messages.html.erb b/app/views/admin/shared/_error_messages.html.erb
new file mode 100644
index 00000000..cabfe307
--- /dev/null
+++ b/app/views/admin/shared/_error_messages.html.erb
@@ -0,0 +1,15 @@
+<% if resource.errors.any? %>
+
+
+ <%= I18n.t("errors.messages.not_saved",
+ count: resource.errors.count,
+ resource: resource.class.model_name.human.downcase)
+ %>
+
+
+ <% resource.errors.full_messages.each do |message| %>
+ - <%= message %>
+ <% end %>
+
+
+<% end %>
diff --git a/app/views/admin/shared/_links.html.erb b/app/views/admin/shared/_links.html.erb
new file mode 100644
index 00000000..7a75304b
--- /dev/null
+++ b/app/views/admin/shared/_links.html.erb
@@ -0,0 +1,25 @@
+<%- if controller_name != 'sessions' %>
+ <%= link_to "Log in", new_session_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
+ <%= link_to "Sign up", new_registration_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
+ <%= link_to "Forgot your password?", new_password_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
+ <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
+ <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.omniauthable? %>
+ <%- resource_class.omniauth_providers.each do |provider| %>
+ <%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %>
+ <% end %>
+<% end %>
diff --git a/app/views/admin/unlocks/new.html.erb b/app/views/admin/unlocks/new.html.erb
new file mode 100644
index 00000000..351c4092
--- /dev/null
+++ b/app/views/admin/unlocks/new.html.erb
@@ -0,0 +1,16 @@
+Resend unlock instructions
+
+<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
+ <%= render "admin/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.submit "Resend unlock instructions" %>
+
+<% end %>
+
+<%= render "admin/shared/links" %>
diff --git a/app/views/customer/confirmations/new.html.erb b/app/views/customer/confirmations/new.html.erb
new file mode 100644
index 00000000..de92b700
--- /dev/null
+++ b/app/views/customer/confirmations/new.html.erb
@@ -0,0 +1,16 @@
+Resend confirmation instructions
+
+<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
+ <%= render "customer/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
+
+
+
+ <%= f.submit "Resend confirmation instructions" %>
+
+<% end %>
+
+<%= render "customer/shared/links" %>
diff --git a/app/views/customer/mailer/confirmation_instructions.html.erb b/app/views/customer/mailer/confirmation_instructions.html.erb
new file mode 100644
index 00000000..dc55f64f
--- /dev/null
+++ b/app/views/customer/mailer/confirmation_instructions.html.erb
@@ -0,0 +1,5 @@
+Welcome <%= @email %>!
+
+You can confirm your account email through the link below:
+
+<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>
diff --git a/app/views/customer/mailer/email_changed.html.erb b/app/views/customer/mailer/email_changed.html.erb
new file mode 100644
index 00000000..32f4ba80
--- /dev/null
+++ b/app/views/customer/mailer/email_changed.html.erb
@@ -0,0 +1,7 @@
+Hello <%= @email %>!
+
+<% if @resource.try(:unconfirmed_email?) %>
+ We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.
+<% else %>
+ We're contacting you to notify you that your email has been changed to <%= @resource.email %>.
+<% end %>
diff --git a/app/views/customer/mailer/password_change.html.erb b/app/views/customer/mailer/password_change.html.erb
new file mode 100644
index 00000000..b41daf47
--- /dev/null
+++ b/app/views/customer/mailer/password_change.html.erb
@@ -0,0 +1,3 @@
+Hello <%= @resource.email %>!
+
+We're contacting you to notify you that your password has been changed.
diff --git a/app/views/customer/mailer/reset_password_instructions.html.erb b/app/views/customer/mailer/reset_password_instructions.html.erb
new file mode 100644
index 00000000..f667dc12
--- /dev/null
+++ b/app/views/customer/mailer/reset_password_instructions.html.erb
@@ -0,0 +1,8 @@
+Hello <%= @resource.email %>!
+
+Someone has requested a link to change your password. You can do this through the link below.
+
+<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>
+
+If you didn't request this, please ignore this email.
+Your password won't change until you access the link above and create a new one.
diff --git a/app/views/customer/mailer/unlock_instructions.html.erb b/app/views/customer/mailer/unlock_instructions.html.erb
new file mode 100644
index 00000000..41e148bf
--- /dev/null
+++ b/app/views/customer/mailer/unlock_instructions.html.erb
@@ -0,0 +1,7 @@
+Hello <%= @resource.email %>!
+
+Your account has been locked due to an excessive number of unsuccessful sign in attempts.
+
+Click the link below to unlock your account:
+
+<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>
diff --git a/app/views/customer/passwords/edit.html.erb b/app/views/customer/passwords/edit.html.erb
new file mode 100644
index 00000000..9d90618b
--- /dev/null
+++ b/app/views/customer/passwords/edit.html.erb
@@ -0,0 +1,25 @@
+Change your password
+
+<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
+ <%= render "customer/shared/error_messages", resource: resource %>
+ <%= f.hidden_field :reset_password_token %>
+
+
+ <%= f.label :password, "New password" %>
+ <% if @minimum_password_length %>
+ (<%= @minimum_password_length %> characters minimum)
+ <% end %>
+ <%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
+
+
+
+ <%= f.label :password_confirmation, "Confirm new password" %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+
+
+
+ <%= f.submit "Change my password" %>
+
+<% end %>
+
+<%= render "customer/shared/links" %>
diff --git a/app/views/customer/passwords/new.html.erb b/app/views/customer/passwords/new.html.erb
new file mode 100644
index 00000000..1c30c566
--- /dev/null
+++ b/app/views/customer/passwords/new.html.erb
@@ -0,0 +1,16 @@
+Forgot your password?
+
+<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
+ <%= render "customer/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.submit "Send me reset password instructions" %>
+
+<% end %>
+
+<%= render "customer/shared/links" %>
diff --git a/app/views/customer/registrations/edit.html.erb b/app/views/customer/registrations/edit.html.erb
new file mode 100644
index 00000000..1752e7cb
--- /dev/null
+++ b/app/views/customer/registrations/edit.html.erb
@@ -0,0 +1,43 @@
+Edit <%= resource_name.to_s.humanize %>
+
+<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
+ <%= render "customer/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+ <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
+ Currently waiting confirmation for: <%= resource.unconfirmed_email %>
+ <% end %>
+
+
+ <%= f.label :password %> (leave blank if you don't want to change it)
+ <%= f.password_field :password, autocomplete: "new-password" %>
+ <% if @minimum_password_length %>
+
+ <%= @minimum_password_length %> characters minimum
+ <% end %>
+
+
+
+ <%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+
+
+
+ <%= f.label :current_password %> (we need your current password to confirm your changes)
+ <%= f.password_field :current_password, autocomplete: "current-password" %>
+
+
+
+ <%= f.submit "Update" %>
+
+<% end %>
+
+Cancel my account
+
+Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?" }, method: :delete %>
+
+<%= link_to "Back", :back %>
diff --git a/app/views/customer/registrations/new.html.erb b/app/views/customer/registrations/new.html.erb
new file mode 100644
index 00000000..23f7811d
--- /dev/null
+++ b/app/views/customer/registrations/new.html.erb
@@ -0,0 +1,29 @@
+Sign up
+
+<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
+ <%= render "customer/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.label :password %>
+ <% if @minimum_password_length %>
+ (<%= @minimum_password_length %> characters minimum)
+ <% end %>
+ <%= f.password_field :password, autocomplete: "new-password" %>
+
+
+
+ <%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+
+
+
+ <%= f.submit "Sign up" %>
+
+<% end %>
+
+<%= render "customer/shared/links" %>
diff --git a/app/views/customer/sessions/new.html.erb b/app/views/customer/sessions/new.html.erb
new file mode 100644
index 00000000..75b38fdc
--- /dev/null
+++ b/app/views/customer/sessions/new.html.erb
@@ -0,0 +1,26 @@
+Log in
+
+<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.label :password %>
+ <%= f.password_field :password, autocomplete: "current-password" %>
+
+
+ <% if devise_mapping.rememberable? %>
+
+ <%= f.check_box :remember_me %>
+ <%= f.label :remember_me %>
+
+ <% end %>
+
+
+ <%= f.submit "Log in" %>
+
+<% end %>
+
+<%= render "customer/shared/links" %>
diff --git a/app/views/customer/shared/_error_messages.html.erb b/app/views/customer/shared/_error_messages.html.erb
new file mode 100644
index 00000000..cabfe307
--- /dev/null
+++ b/app/views/customer/shared/_error_messages.html.erb
@@ -0,0 +1,15 @@
+<% if resource.errors.any? %>
+
+
+ <%= I18n.t("errors.messages.not_saved",
+ count: resource.errors.count,
+ resource: resource.class.model_name.human.downcase)
+ %>
+
+
+ <% resource.errors.full_messages.each do |message| %>
+ - <%= message %>
+ <% end %>
+
+
+<% end %>
diff --git a/app/views/customer/shared/_links.html.erb b/app/views/customer/shared/_links.html.erb
new file mode 100644
index 00000000..7a75304b
--- /dev/null
+++ b/app/views/customer/shared/_links.html.erb
@@ -0,0 +1,25 @@
+<%- if controller_name != 'sessions' %>
+ <%= link_to "Log in", new_session_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
+ <%= link_to "Sign up", new_registration_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
+ <%= link_to "Forgot your password?", new_password_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
+ <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
+ <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
+<% end %>
+
+<%- if devise_mapping.omniauthable? %>
+ <%- resource_class.omniauth_providers.each do |provider| %>
+ <%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %>
+ <% end %>
+<% end %>
diff --git a/app/views/customer/unlocks/new.html.erb b/app/views/customer/unlocks/new.html.erb
new file mode 100644
index 00000000..0a46d3ce
--- /dev/null
+++ b/app/views/customer/unlocks/new.html.erb
@@ -0,0 +1,16 @@
+Resend unlock instructions
+
+<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
+ <%= render "customer/shared/error_messages", resource: resource %>
+
+
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+
+
+
+ <%= f.submit "Resend unlock instructions" %>
+
+<% end %>
+
+<%= render "customer/shared/links" %>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index f86a39fc..aad4230c 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -1,7 +1,7 @@
- Docker + Rails
+ Ecommerce
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
diff --git a/cable/config.ru b/cable/config.ru
index 335cda22..338dff91 100644
--- a/cable/config.ru
+++ b/cable/config.ru
@@ -1,6 +1,6 @@
# This file is used to start the Action Cable server.
-require_relative "../config/environment"
+require_relative '../config/environment'
Rails.application.eager_load!
run ActionCable.server
diff --git a/config.ru b/config.ru
index 4a3c09a6..ad1fbf29 100644
--- a/config.ru
+++ b/config.ru
@@ -1,6 +1,6 @@
# This file is used by Rack-based servers to start the application.
-require_relative "config/environment"
+require_relative 'config/environment'
run Rails.application
Rails.application.load_server
diff --git a/config/application.rb b/config/application.rb
index f625f0a4..c018ffd0 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -1,6 +1,6 @@
-require_relative "boot"
+require_relative 'boot'
-require "rails/all"
+require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
@@ -13,14 +13,14 @@ class Application < Rails::Application
# Log to STDOUT because Docker expects all processes to log here. You could
# then collect logs using journald, syslog or forward them somewhere else.
- logger = ActiveSupport::Logger.new(STDOUT)
+ logger = ActiveSupport::Logger.new($stdout)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
# Set Redis as the back-end for the cache.
config.cache_store = :redis_cache_store, {
- url: ENV.fetch("REDIS_URL") { "redis://redis:6379/1" },
- namespace: "cache"
+ url: ENV.fetch('REDIS_URL') { 'redis://redis:6379/1' },
+ namespace: 'cache'
}
# Set Sidekiq as the back-end for Active Job.
@@ -28,11 +28,17 @@ class Application < Rails::Application
# Mount Action Cable outside the main process or domain.
config.action_cable.mount_path = nil
- config.action_cable.url = ENV.fetch("ACTION_CABLE_FRONTEND_URL") { "ws://localhost:28080" }
+ config.action_cable.url = ENV.fetch('ACTION_CABLE_FRONTEND_URL') { 'ws://localhost:28080' }
# Only allow connections to Action Cable from these domains.
- origins = ENV.fetch("ACTION_CABLE_ALLOWED_REQUEST_ORIGINS") { "http:\/\/localhost*" }.split(",")
+ origins = ENV.fetch('ACTION_CABLE_ALLOWED_REQUEST_ORIGINS') { "http:\/\/localhost*" }.split(',')
origins.map! { |url| /#{url}/ }
config.action_cable.allowed_request_origins = origins
+ # Customizing Rails Generators
+ config.generators do |g|
+ g.assets false
+ g.skip_routes true
+ g.test_framework false
+ end
end
end
diff --git a/config/boot.rb b/config/boot.rb
index 4786697d..f4d9a88c 100644
--- a/config/boot.rb
+++ b/config/boot.rb
@@ -1,7 +1,7 @@
-ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
# Set up gems listed in the Gemfile.
-require "bundler/setup"
+require 'bundler/setup'
# Speed up boot time by caching expensive operations, but not in production.
-require "bootsnap/setup" if Gem.loaded_specs.has_key?("bootsnap")
+require 'bootsnap/setup' if Gem.loaded_specs.key?('bootsnap')
diff --git a/config/database.yml b/config/database.yml
index 9d643d0e..d45b06df 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -1,7 +1,7 @@
default: &default
adapter: "postgresql"
encoding: "unicode"
- database: "<%= ENV.fetch("POSTGRES_DB") { "hello" } %>"
+ database: "<%= ENV.fetch("POSTGRES_DB") { "ecommerce" } %>"
username: "<%= ENV.fetch("POSTGRES_USER") { "hello" } %>"
password: "<%= ENV.fetch("POSTGRES_PASSWORD") { "password" } %>"
host: "<%= ENV.fetch("POSTGRES_HOST") { "postgres" } %>"
@@ -11,12 +11,12 @@ default: &default
development:
<<: *default
- database: <%= ENV.fetch("POSTGRES_DB") { "hello" } %>_development
+ database: <%= ENV.fetch("POSTGRES_DB") { "ecommerce" } %>_development
test:
<<: *default
- database: <%= ENV.fetch("POSTGRES_DB") { "hello" } %>_test
+ database: <%= ENV.fetch("POSTGRES_DB") { "ecommerce" } %>_test
production:
<<: *default
- database: <%= ENV.fetch("POSTGRES_DB") { "hello" } %>_production
+ database: <%= ENV.fetch("POSTGRES_DB") { "ecommerce" } %>_production
diff --git a/config/environment.rb b/config/environment.rb
index cac53157..426333bb 100644
--- a/config/environment.rb
+++ b/config/environment.rb
@@ -1,5 +1,5 @@
# Load the Rails application.
-require_relative "application"
+require_relative 'application'
# Initialize the Rails application.
Rails.application.initialize!
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
index 6feaec25..5323cffc 100644
--- a/config/initializers/assets.rb
+++ b/config/initializers/assets.rb
@@ -1,14 +1,14 @@
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
-Rails.application.config.assets.version = "1.0"
+Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path.
# Rails.application.config.assets.paths << Emoji.images_path
# Add node_modules folder to the asset load path, its location has been
# customized due to what's set in .yarnrc.
-Rails.application.config.assets.paths << "/node_modules"
+Rails.application.config.assets.paths << '/node_modules'
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
new file mode 100644
index 00000000..395290e1
--- /dev/null
+++ b/config/initializers/devise.rb
@@ -0,0 +1,313 @@
+# frozen_string_literal: true
+
+# Assuming you have not yet modified this file, each configuration option below
+# is set to its default value. Note that some are commented out while others
+# are not: uncommented lines are intended to protect your configuration from
+# breaking changes in upgrades (i.e., in the event that future versions of
+# Devise change the default values for those options).
+#
+# Use this hook to configure devise mailer, warden hooks and so forth.
+# Many of these configuration options can be set straight in your model.
+Devise.setup do |config|
+ # The secret key used by Devise. Devise uses this key to generate
+ # random tokens. Changing this key will render invalid all existing
+ # confirmation, reset password and unlock tokens in the database.
+ # Devise will use the `secret_key_base` as its `secret_key`
+ # by default. You can change it below and use your own secret key.
+ # config.secret_key = 'ddc77c7d9257d50f6bd0b1707a63df90ed500ab973480d44845cf1905243ec8a23c0626bd6e07895590b3cdc90a00563dfdc4fc35eb2b656ef01eaa52b256850'
+
+ # ==> Controller configuration
+ # Configure the parent class to the devise controllers.
+ # config.parent_controller = 'DeviseController'
+
+ # ==> Mailer Configuration
+ # Configure the e-mail address which will be shown in Devise::Mailer,
+ # note that it will be overwritten if you use your own mailer class
+ # with default "from" parameter.
+ config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
+
+ # Configure the class responsible to send e-mails.
+ # config.mailer = 'Devise::Mailer'
+
+ # Configure the parent class responsible to send e-mails.
+ # config.parent_mailer = 'ActionMailer::Base'
+
+ # ==> ORM configuration
+ # Load and configure the ORM. Supports :active_record (default) and
+ # :mongoid (bson_ext recommended) by default. Other ORMs may be
+ # available as additional gems.
+ require 'devise/orm/active_record'
+
+ # ==> Configuration for any authentication mechanism
+ # Configure which keys are used when authenticating a user. The default is
+ # just :email. You can configure it to use [:username, :subdomain], so for
+ # authenticating a user, both parameters are required. Remember that those
+ # parameters are used only when authenticating and not when retrieving from
+ # session. If you need permissions, you should implement that in a before filter.
+ # You can also supply a hash where the value is a boolean determining whether
+ # or not authentication should be aborted when the value is not present.
+ # config.authentication_keys = [:email]
+
+ # Configure parameters from the request object used for authentication. Each entry
+ # given should be a request method and it will automatically be passed to the
+ # find_for_authentication method and considered in your model lookup. For instance,
+ # if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
+ # The same considerations mentioned for authentication_keys also apply to request_keys.
+ # config.request_keys = []
+
+ # Configure which authentication keys should be case-insensitive.
+ # These keys will be downcased upon creating or modifying a user and when used
+ # to authenticate or find a user. Default is :email.
+ config.case_insensitive_keys = [:email]
+
+ # Configure which authentication keys should have whitespace stripped.
+ # These keys will have whitespace before and after removed upon creating or
+ # modifying a user and when used to authenticate or find a user. Default is :email.
+ config.strip_whitespace_keys = [:email]
+
+ # Tell if authentication through request.params is enabled. True by default.
+ # It can be set to an array that will enable params authentication only for the
+ # given strategies, for example, `config.params_authenticatable = [:database]` will
+ # enable it only for database (email + password) authentication.
+ # config.params_authenticatable = true
+
+ # Tell if authentication through HTTP Auth is enabled. False by default.
+ # It can be set to an array that will enable http authentication only for the
+ # given strategies, for example, `config.http_authenticatable = [:database]` will
+ # enable it only for database authentication.
+ # For API-only applications to support authentication "out-of-the-box", you will likely want to
+ # enable this with :database unless you are using a custom strategy.
+ # The supported strategies are:
+ # :database = Support basic authentication with authentication key + password
+ # config.http_authenticatable = false
+
+ # If 401 status code should be returned for AJAX requests. True by default.
+ # config.http_authenticatable_on_xhr = true
+
+ # The realm used in Http Basic Authentication. 'Application' by default.
+ # config.http_authentication_realm = 'Application'
+
+ # It will change confirmation, password recovery and other workflows
+ # to behave the same regardless if the e-mail provided was right or wrong.
+ # Does not affect registerable.
+ # config.paranoid = true
+
+ # By default Devise will store the user in session. You can skip storage for
+ # particular strategies by setting this option.
+ # Notice that if you are skipping storage for all authentication paths, you
+ # may want to disable generating routes to Devise's sessions controller by
+ # passing skip: :sessions to `devise_for` in your config/routes.rb
+ config.skip_session_storage = [:http_auth]
+
+ # By default, Devise cleans up the CSRF token on authentication to
+ # avoid CSRF token fixation attacks. This means that, when using AJAX
+ # requests for sign in and sign up, you need to get a new CSRF token
+ # from the server. You can disable this option at your own risk.
+ # config.clean_up_csrf_token_on_authentication = true
+
+ # When false, Devise will not attempt to reload routes on eager load.
+ # This can reduce the time taken to boot the app but if your application
+ # requires the Devise mappings to be loaded during boot time the application
+ # won't boot properly.
+ # config.reload_routes = true
+
+ # ==> Configuration for :database_authenticatable
+ # For bcrypt, this is the cost for hashing the password and defaults to 12. If
+ # using other algorithms, it sets how many times you want the password to be hashed.
+ # The number of stretches used for generating the hashed password are stored
+ # with the hashed password. This allows you to change the stretches without
+ # invalidating existing passwords.
+ #
+ # Limiting the stretches to just one in testing will increase the performance of
+ # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
+ # a value less than 10 in other environments. Note that, for bcrypt (the default
+ # algorithm), the cost increases exponentially with the number of stretches (e.g.
+ # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation).
+ config.stretches = Rails.env.test? ? 1 : 12
+
+ # Set up a pepper to generate the hashed password.
+ # config.pepper = 'd08691b5bc46215b5b48019054c84144e63e5fabfaa0cda76c7571ae3c3b5d84d97a6d69dedd9988c78da7fe59600e8bdff13237e7c388f0dd04506b81a3b00c'
+
+ # Send a notification to the original email when the user's email is changed.
+ # config.send_email_changed_notification = false
+
+ # Send a notification email when the user's password is changed.
+ # config.send_password_change_notification = false
+
+ # ==> Configuration for :confirmable
+ # A period that the user is allowed to access the website even without
+ # confirming their account. For instance, if set to 2.days, the user will be
+ # able to access the website for two days without confirming their account,
+ # access will be blocked just in the third day.
+ # You can also set it to nil, which will allow the user to access the website
+ # without confirming their account.
+ # Default is 0.days, meaning the user cannot access the website without
+ # confirming their account.
+ # config.allow_unconfirmed_access_for = 2.days
+
+ # A period that the user is allowed to confirm their account before their
+ # token becomes invalid. For example, if set to 3.days, the user can confirm
+ # their account within 3 days after the mail was sent, but on the fourth day
+ # their account can't be confirmed with the token any more.
+ # Default is nil, meaning there is no restriction on how long a user can take
+ # before confirming their account.
+ # config.confirm_within = 3.days
+
+ # If true, requires any email changes to be confirmed (exactly the same way as
+ # initial account confirmation) to be applied. Requires additional unconfirmed_email
+ # db field (see migrations). Until confirmed, new email is stored in
+ # unconfirmed_email column, and copied to email column on successful confirmation.
+ config.reconfirmable = true
+
+ # Defines which key will be used when confirming an account
+ # config.confirmation_keys = [:email]
+
+ # ==> Configuration for :rememberable
+ # The time the user will be remembered without asking for credentials again.
+ # config.remember_for = 2.weeks
+
+ # Invalidates all the remember me tokens when the user signs out.
+ config.expire_all_remember_me_on_sign_out = true
+
+ # If true, extends the user's remember period when remembered via cookie.
+ # config.extend_remember_period = false
+
+ # Options to be passed to the created cookie. For instance, you can set
+ # secure: true in order to force SSL only cookies.
+ # config.rememberable_options = {}
+
+ # ==> Configuration for :validatable
+ # Range for password length.
+ config.password_length = 6..128
+
+ # Email regex used to validate email formats. It simply asserts that
+ # one (and only one) @ exists in the given string. This is mainly
+ # to give user feedback and not to assert the e-mail validity.
+ config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
+
+ # ==> Configuration for :timeoutable
+ # The time you want to timeout the user session without activity. After this
+ # time the user will be asked for credentials again. Default is 30 minutes.
+ # config.timeout_in = 30.minutes
+
+ # ==> Configuration for :lockable
+ # Defines which strategy will be used to lock an account.
+ # :failed_attempts = Locks an account after a number of failed attempts to sign in.
+ # :none = No lock strategy. You should handle locking by yourself.
+ # config.lock_strategy = :failed_attempts
+
+ # Defines which key will be used when locking and unlocking an account
+ # config.unlock_keys = [:email]
+
+ # Defines which strategy will be used to unlock an account.
+ # :email = Sends an unlock link to the user email
+ # :time = Re-enables login after a certain amount of time (see :unlock_in below)
+ # :both = Enables both strategies
+ # :none = No unlock strategy. You should handle unlocking by yourself.
+ # config.unlock_strategy = :both
+
+ # Number of authentication tries before locking an account if lock_strategy
+ # is failed attempts.
+ # config.maximum_attempts = 20
+
+ # Time interval to unlock the account if :time is enabled as unlock_strategy.
+ # config.unlock_in = 1.hour
+
+ # Warn on the last attempt before the account is locked.
+ # config.last_attempt_warning = true
+
+ # ==> Configuration for :recoverable
+ #
+ # Defines which key will be used when recovering the password for an account
+ # config.reset_password_keys = [:email]
+
+ # Time interval you can reset your password with a reset password key.
+ # Don't put a too small interval or your users won't have the time to
+ # change their passwords.
+ config.reset_password_within = 6.hours
+
+ # When set to false, does not sign a user in automatically after their password is
+ # reset. Defaults to true, so a user is signed in automatically after a reset.
+ # config.sign_in_after_reset_password = true
+
+ # ==> Configuration for :encryptable
+ # Allow you to use another hashing or encryption algorithm besides bcrypt (default).
+ # You can use :sha1, :sha512 or algorithms from others authentication tools as
+ # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20
+ # for default behavior) and :restful_authentication_sha1 (then you should set
+ # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper).
+ #
+ # Require the `devise-encryptable` gem when using anything other than bcrypt
+ # config.encryptor = :sha512
+
+ # ==> Scopes configuration
+ # Turn scoped views on. Before rendering "sessions/new", it will first check for
+ # "users/sessions/new". It's turned off by default because it's slower if you
+ # are using only default views.
+ config.scoped_views = true
+
+ # Configure the default scope given to Warden. By default it's the first
+ # devise role declared in your routes (usually :user).
+ # config.default_scope = :user
+
+ # Set this configuration to false if you want /users/sign_out to sign out
+ # only the current scope. By default, Devise signs out all scopes.
+ config.sign_out_all_scopes = false
+
+ # ==> Navigation configuration
+ # Lists the formats that should be treated as navigational. Formats like
+ # :html should redirect to the sign in page when the user does not have
+ # access, but formats like :xml or :json, should return 401.
+ #
+ # If you have any extra navigational formats, like :iphone or :mobile, you
+ # should add them to the navigational formats lists.
+ #
+ # The "*/*" below is required to match Internet Explorer requests.
+ # config.navigational_formats = ['*/*', :html, :turbo_stream]
+
+ # The default HTTP method used to sign out a resource. Default is :delete.
+ config.sign_out_via = :delete
+
+ # ==> OmniAuth
+ # Add a new OmniAuth provider. Check the wiki for more information on setting
+ # up on your models and hooks.
+ # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
+
+ # ==> Warden configuration
+ # If you want to use other strategies, that are not supported by Devise, or
+ # change the failure app, you can configure them inside the config.warden block.
+ #
+ # config.warden do |manager|
+ # manager.intercept_401 = false
+ # manager.default_strategies(scope: :user).unshift :some_external_strategy
+ # end
+
+ # ==> Mountable engine configurations
+ # When using Devise inside an engine, let's call it `MyEngine`, and this engine
+ # is mountable, there are some extra configurations to be taken into account.
+ # The following options are available, assuming the engine is mounted as:
+ #
+ # mount MyEngine, at: '/my_engine'
+ #
+ # The router that invoked `devise_for`, in the example above, would be:
+ # config.router_name = :my_engine
+ #
+ # When using OmniAuth, Devise cannot automatically set OmniAuth path,
+ # so you need to do it manually. For the users scope, it would be:
+ # config.omniauth_path_prefix = '/my_engine/users/auth'
+
+ # ==> Hotwire/Turbo configuration
+ # When using Devise with Hotwire/Turbo, the http status for error responses
+ # and some redirects must match the following. The default in Devise for existing
+ # apps is `200 OK` and `302 Found` respectively, but new apps are generated with
+ # these new defaults that match Hotwire/Turbo behavior.
+ # Note: These might become the new default in future versions of Devise.
+ config.responder.error_status = :unprocessable_entity
+ config.responder.redirect_status = :see_other
+
+ # ==> Configuration for :registerable
+
+ # When set to false, does not sign a user in automatically after their password is
+ # changed. Defaults to true, so a user is signed in automatically after changing a password.
+ # config.sign_in_after_change_password = true
+end
diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb
index 4b34a036..3e696949 100644
--- a/config/initializers/filter_parameter_logging.rb
+++ b/config/initializers/filter_parameter_logging.rb
@@ -1,6 +1,6 @@
# Be sure to restart your server when you modify this file.
# Configure sensitive parameters which will be filtered from the log file.
-Rails.application.config.filter_parameters += [
- :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
+Rails.application.config.filter_parameters += %i[
+ passw secret token _key crypt salt certificate otp ssn
]
diff --git a/config/initializers/rack_mini_profiler.rb b/config/initializers/rack_mini_profiler.rb
index 3142b91a..e99bf5df 100644
--- a/config/initializers/rack_mini_profiler.rb
+++ b/config/initializers/rack_mini_profiler.rb
@@ -1,3 +1 @@
-if Rails.env.development?
- Rack::MiniProfiler.config.enable_hotwire_turbo_drive_support = true
-end
+Rack::MiniProfiler.config.enable_hotwire_turbo_drive_support = true if Rails.env.development?
diff --git a/config/initializers/redis.rb b/config/initializers/redis.rb
index 4f80c2e1..09b749b4 100644
--- a/config/initializers/redis.rb
+++ b/config/initializers/redis.rb
@@ -1,5 +1,5 @@
module RedisConn
def self.current
- @redis ||= Redis.new(url: ENV.fetch("REDIS_URL") { "redis://redis:6379/1" })
+ @current ||= Redis.new(url: ENV.fetch('REDIS_URL') { 'redis://redis:6379/1' })
end
end
diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb
index ea96d81c..2945258d 100644
--- a/config/initializers/sidekiq.rb
+++ b/config/initializers/sidekiq.rb
@@ -1,4 +1,4 @@
-sidekiq_config = { url: ENV.fetch("REDIS_URL") { "redis://redis:6379/1" } }
+sidekiq_config = { url: ENV.fetch('REDIS_URL') { 'redis://redis:6379/1' } }
Sidekiq.configure_server do |config|
config.redis = sidekiq_config
diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml
new file mode 100644
index 00000000..260e1c4b
--- /dev/null
+++ b/config/locales/devise.en.yml
@@ -0,0 +1,65 @@
+# Additional translations at https://github.com/heartcombo/devise/wiki/I18n
+
+en:
+ devise:
+ confirmations:
+ confirmed: "Your email address has been successfully confirmed."
+ send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes."
+ send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
+ failure:
+ already_authenticated: "You are already signed in."
+ inactive: "Your account is not activated yet."
+ invalid: "Invalid %{authentication_keys} or password."
+ locked: "Your account is locked."
+ last_attempt: "You have one more attempt before your account is locked."
+ not_found_in_database: "Invalid %{authentication_keys} or password."
+ timeout: "Your session expired. Please sign in again to continue."
+ unauthenticated: "You need to sign in or sign up before continuing."
+ unconfirmed: "You have to confirm your email address before continuing."
+ mailer:
+ confirmation_instructions:
+ subject: "Confirmation instructions"
+ reset_password_instructions:
+ subject: "Reset password instructions"
+ unlock_instructions:
+ subject: "Unlock instructions"
+ email_changed:
+ subject: "Email Changed"
+ password_change:
+ subject: "Password Changed"
+ omniauth_callbacks:
+ failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
+ success: "Successfully authenticated from %{kind} account."
+ passwords:
+ no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
+ send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
+ send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
+ updated: "Your password has been changed successfully. You are now signed in."
+ updated_not_active: "Your password has been changed successfully."
+ registrations:
+ destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon."
+ signed_up: "Welcome! You have signed up successfully."
+ signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
+ signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
+ signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
+ update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirmation link to confirm your new email address."
+ updated: "Your account has been updated successfully."
+ updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again."
+ sessions:
+ signed_in: "Signed in successfully."
+ signed_out: "Signed out successfully."
+ already_signed_out: "Signed out successfully."
+ unlocks:
+ send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes."
+ send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
+ unlocked: "Your account has been unlocked successfully. Please sign in to continue."
+ errors:
+ messages:
+ already_confirmed: "was already confirmed, please try signing in"
+ confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
+ expired: "has expired, please request a new one"
+ not_found: "not found"
+ not_locked: "was not locked"
+ not_saved:
+ one: "1 error prohibited this %{resource} from being saved:"
+ other: "%{count} errors prohibited this %{resource} from being saved:"
diff --git a/config/puma.rb b/config/puma.rb
index 66f133d9..96e870f8 100644
--- a/config/puma.rb
+++ b/config/puma.rb
@@ -1,13 +1,13 @@
# Specify the bind host and environment.
-bind "tcp://0.0.0.0:#{ENV.fetch("PORT") { "8000" }}"
-environment ENV.fetch("RAILS_ENV") { "production" }
+bind "tcp://0.0.0.0:#{ENV.fetch('PORT') { '8000' }}"
+environment ENV.fetch('RAILS_ENV') { 'production' }
# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
-threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
+threads_count = ENV.fetch('RAILS_MAX_THREADS', 5)
threads threads_count, threads_count
# Specifies the number of `workers` to boot in clustered mode.
@@ -15,11 +15,11 @@
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes). It defaults to the number of (virtual cores * 2).
-workers = ENV.fetch("WEB_CONCURRENCY") { Etc.nprocessors * 2 }
+ENV.fetch('WEB_CONCURRENCY') { Etc.nprocessors * 2 }
# Specifies the `worker_timeout` threshold that Puma will use to wait before
# terminating a worker in development environments.
-worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
+worker_timeout 3600 if ENV.fetch('RAILS_ENV', 'development') == 'development'
# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
diff --git a/config/routes.rb b/config/routes.rb
index 27a06af5..5adef6a6 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,25 +1,13 @@
Rails.application.routes.draw do
- root to: "pages#home"
+ devise_for :admins, controllers: {
+ sessions: 'admin/sessions'
+ }
+ devise_for :customers, controllers: {
+ sessions: 'customer/sessions',
+ registrations: 'customer/registrations'
+ }
+ root to: 'pages#home'
- get "/up/", to: "up#index", as: :up
- get "/up/databases", to: "up#databases", as: :up_databases
-
- # Sidekiq has a web dashboard which you can enable below. It's turned off by
- # default because you very likely wouldn't want this to be available to
- # everyone in production.
- #
- # Uncomment the 2 lines below to enable the dashboard WITHOUT authentication,
- # but be careful because even anonymous web visitors will be able to see it!
- # require "sidekiq/web"
- # mount Sidekiq::Web => "/sidekiq"
- #
- # If you add Devise to this project and happen to have an admin? attribute
- # on your user you can uncomment the 4 lines below to only allow access to
- # the dashboard if you're an admin. Feel free to adjust things as needed.
- # require "sidekiq/web"
- # authenticate :user, lambda { |u| u.admin? } do
- # mount Sidekiq::Web => "/sidekiq"
- # end
-
- # Learn more about this file at: https://guides.rubyonrails.org/routing.html
+ get '/up/', to: 'up#index', as: :up
+ get '/up/databases', to: 'up#databases', as: :up_databases
end
diff --git a/config/spring.rb b/config/spring.rb
index 15f8f536..27d71993 100644
--- a/config/spring.rb
+++ b/config/spring.rb
@@ -1,4 +1,4 @@
Spring.watch(
- "tmp/restart.txt",
- "tmp/caching-dev.txt"
+ 'tmp/restart.txt',
+ 'tmp/caching-dev.txt'
)
diff --git a/db/migrate/20250106004537_devise_create_admins.rb b/db/migrate/20250106004537_devise_create_admins.rb
new file mode 100644
index 00000000..52717eeb
--- /dev/null
+++ b/db/migrate/20250106004537_devise_create_admins.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+class DeviseCreateAdmins < ActiveRecord::Migration[7.0]
+ def change
+ create_table :admins do |t|
+ ## Database authenticatable
+ t.string :email, null: false, default: ""
+ t.string :encrypted_password, null: false, default: ""
+
+ ## Recoverable
+ t.string :reset_password_token
+ t.datetime :reset_password_sent_at
+
+ ## Rememberable
+ t.datetime :remember_created_at
+
+ ## Trackable
+ # t.integer :sign_in_count, default: 0, null: false
+ # t.datetime :current_sign_in_at
+ # t.datetime :last_sign_in_at
+ # t.string :current_sign_in_ip
+ # t.string :last_sign_in_ip
+
+ ## Confirmable
+ # t.string :confirmation_token
+ # t.datetime :confirmed_at
+ # t.datetime :confirmation_sent_at
+ # t.string :unconfirmed_email # Only if using reconfirmable
+
+ ## Lockable
+ # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
+ # t.string :unlock_token # Only if unlock strategy is :email or :both
+ # t.datetime :locked_at
+
+
+ t.timestamps null: false
+ end
+
+ add_index :admins, :email, unique: true
+ add_index :admins, :reset_password_token, unique: true
+ # add_index :admins, :confirmation_token, unique: true
+ # add_index :admins, :unlock_token, unique: true
+ end
+end
diff --git a/db/migrate/20250106004602_devise_create_customers.rb b/db/migrate/20250106004602_devise_create_customers.rb
new file mode 100644
index 00000000..db64eb85
--- /dev/null
+++ b/db/migrate/20250106004602_devise_create_customers.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+class DeviseCreateCustomers < ActiveRecord::Migration[7.0]
+ def change
+ create_table :customers do |t|
+ ## Database authenticatable
+ t.string :email, null: false, default: ""
+ t.string :encrypted_password, null: false, default: ""
+
+ ## Recoverable
+ t.string :reset_password_token
+ t.datetime :reset_password_sent_at
+
+ ## Rememberable
+ t.datetime :remember_created_at
+
+ ## Trackable
+ # t.integer :sign_in_count, default: 0, null: false
+ # t.datetime :current_sign_in_at
+ # t.datetime :last_sign_in_at
+ # t.string :current_sign_in_ip
+ # t.string :last_sign_in_ip
+
+ ## Confirmable
+ # t.string :confirmation_token
+ # t.datetime :confirmed_at
+ # t.datetime :confirmation_sent_at
+ # t.string :unconfirmed_email # Only if using reconfirmable
+
+ ## Lockable
+ # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
+ # t.string :unlock_token # Only if unlock strategy is :email or :both
+ # t.datetime :locked_at
+
+ t.string :name, null: false
+ t.integer :status, null: false,default: 0
+
+ t.timestamps null: false
+ end
+
+ add_index :customers, :email, unique: true
+ add_index :customers, :reset_password_token, unique: true
+ # add_index :customers, :confirmation_token, unique: true
+ # add_index :customers, :unlock_token, unique: true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 4603022a..0cdd11c1 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,9 +10,34 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 0) do
-
+ActiveRecord::Schema[7.0].define(version: 2025_01_06_004602) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
+ create_table "admins", force: :cascade do |t|
+ t.string "email", default: "", null: false
+ t.string "encrypted_password", default: "", null: false
+ t.string "reset_password_token"
+ t.datetime "reset_password_sent_at"
+ t.datetime "remember_created_at"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["email"], name: "index_admins_on_email", unique: true
+ t.index ["reset_password_token"], name: "index_admins_on_reset_password_token", unique: true
+ end
+
+ create_table "customers", force: :cascade do |t|
+ t.string "email", default: "", null: false
+ t.string "encrypted_password", default: "", null: false
+ t.string "reset_password_token"
+ t.datetime "reset_password_sent_at"
+ t.datetime "remember_created_at"
+ t.string "name", null: false
+ t.integer "status", default: 0, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["email"], name: "index_customers_on_email", unique: true
+ t.index ["reset_password_token"], name: "index_customers_on_reset_password_token", unique: true
+ end
+
end
diff --git a/docker-compose.yml b/docker-compose.yml
index c338bb61..92d7d56d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -46,7 +46,7 @@ services:
environment:
POSTGRES_USER: "${POSTGRES_USER}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
- # POSTGRES_DB: "${POSTGRES_DB}"
+ POSTGRES_DB: "${POSTGRES_DB}"
image: "postgres:15.1-bullseye"
profiles: ["postgres"]
restart: "${DOCKER_RESTART_POLICY:-unless-stopped}"
diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb
index d19212ab..23701b43 100644
--- a/test/application_system_test_case.rb
+++ b/test/application_system_test_case.rb
@@ -1,4 +1,4 @@
-require "test_helper"
+require 'test_helper'
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
diff --git a/test/channels/application_cable/connection_test.rb b/test/channels/application_cable/connection_test.rb
index 800405f1..d05dbd24 100644
--- a/test/channels/application_cable/connection_test.rb
+++ b/test/channels/application_cable/connection_test.rb
@@ -1,4 +1,4 @@
-require "test_helper"
+require 'test_helper'
class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase
# test "connects with cookies" do
diff --git a/test/controllers/pages_controller_test.rb b/test/controllers/pages_controller_test.rb
index a36b550c..57d0b409 100644
--- a/test/controllers/pages_controller_test.rb
+++ b/test/controllers/pages_controller_test.rb
@@ -1,12 +1,12 @@
-require "test_helper"
+require 'test_helper'
class PagesControllerTest < ActionDispatch::IntegrationTest
- test "should get home" do
+ test 'should get home' do
get root_url
assert_response :success
end
- test "should get up" do
+ test 'should get up' do
get up_url
assert_response :success
end
diff --git a/test/controllers/up_controller_test.rb b/test/controllers/up_controller_test.rb
index b517c427..80a9c1e7 100644
--- a/test/controllers/up_controller_test.rb
+++ b/test/controllers/up_controller_test.rb
@@ -1,12 +1,12 @@
-require "test_helper"
+require 'test_helper'
class UpControllerTest < ActionDispatch::IntegrationTest
- test "should get up" do
+ test 'should get up' do
get up_url
assert_response :success
end
- test "should get up databases" do
+ test 'should get up databases' do
get up_databases_url
assert_response :success
end
diff --git a/test/test_helper.rb b/test/test_helper.rb
index d713e377..d5300f88 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -1,6 +1,6 @@
-ENV["RAILS_ENV"] ||= "test"
-require_relative "../config/environment"
-require "rails/test_help"
+ENV['RAILS_ENV'] ||= 'test'
+require_relative '../config/environment'
+require 'rails/test_help'
class ActiveSupport::TestCase
# Run tests in parallel with specified workers