├── .loco-data ├── .gitkeep ├── log │ └── .gitkeep ├── tmp │ └── .gitkeep └── README.md ├── shopinvader ├── lib │ ├── assets │ │ └── .keep │ └── tasks │ │ └── .keep ├── vendor │ └── .keep ├── public │ ├── favicon.ico │ ├── apple-touch-icon.png │ ├── apple-touch-icon-precomposed.png │ ├── 500.html │ └── 422.html ├── test │ ├── fixtures │ │ ├── .keep │ │ └── files │ │ │ └── .keep │ ├── helpers │ │ └── .keep │ ├── mailers │ │ └── .keep │ ├── models │ │ └── .keep │ ├── system │ │ └── .keep │ ├── controllers │ │ └── .keep │ ├── integration │ │ └── .keep │ ├── application_system_test_case.rb │ └── test_helper.rb ├── app │ ├── assets │ │ ├── images │ │ │ └── .keep │ │ ├── javascripts │ │ │ ├── channels │ │ │ │ └── .keep │ │ │ ├── cable.js │ │ │ └── application.js │ │ ├── config │ │ │ └── manifest.js │ │ └── stylesheets │ │ │ └── application.css │ ├── models │ │ └── concerns │ │ │ └── .keep │ ├── controllers │ │ ├── concerns │ │ │ └── .keep │ │ └── application_controller.rb │ ├── views │ │ └── layouts │ │ │ ├── mailer.text.erb │ │ │ ├── mailer.html.erb │ │ │ └── application.html.erb │ ├── helpers │ │ └── application_helper.rb │ ├── jobs │ │ └── application_job.rb │ ├── channels │ │ └── application_cable │ │ │ ├── channel.rb │ │ │ └── connection.rb │ └── mailers │ │ └── application_mailer.rb ├── Procfile ├── yarn.lock ├── bin │ ├── rake │ ├── bundle │ ├── rails │ ├── yarn │ ├── update │ └── setup ├── config │ ├── spring.rb │ ├── environment.rb │ ├── initializers │ │ ├── mime_types.rb │ │ ├── sentry.rb │ │ ├── application_controller_renderer.rb │ │ ├── cookies_serializer.rb │ │ ├── wrap_parameters.rb │ │ ├── filter_parameter_logging.rb │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── inflections.rb │ │ ├── session_store.rb │ │ ├── content_security_policy.rb │ │ ├── dragonfly.rb │ │ ├── carrierwave.rb │ │ ├── locomotive.rb │ │ └── devise.rb │ ├── boot.rb │ ├── cable.yml │ ├── routes.rb │ ├── locales │ │ ├── en.yml │ │ └── devise.en.yml │ ├── secrets.yml │ ├── application.rb │ ├── environments │ │ ├── development.rb │ │ ├── test.rb │ │ └── production.rb │ ├── puma.rb │ └── mongoid.yml ├── config.ru ├── Rakefile ├── Dockerfile ├── Gemfile └── Gemfile.lock ├── docky.yml ├── .dockerignore ├── update.sh ├── bump.sh ├── install ├── shopinvader.sh └── gosu.sh ├── bin └── docker-entrypoint.sh ├── dev.docker-compose.yml ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── docker-compose.yml ├── CHANGELOG.md └── README.md /.loco-data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.loco-data/log/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.loco-data/tmp/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/vendor/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/test/fixtures/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/test/helpers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/test/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/test/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/test/system/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/test/controllers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/test/fixtures/files/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/test/integration/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/public/apple-touch-icon.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docky.yml: -------------------------------------------------------------------------------- 1 | service: locomotive 2 | user: ubuntu 3 | -------------------------------------------------------------------------------- /shopinvader/app/assets/javascripts/channels/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shopinvader/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /shopinvader/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .db 2 | data 3 | environment 4 | **/dev-gem 5 | tmp 6 | log 7 | bundle 8 | -------------------------------------------------------------------------------- /shopinvader/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | end 3 | -------------------------------------------------------------------------------- /shopinvader/Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -C config/puma.rb 2 | worker: bundle exec sidekiq -e production -t 25 3 | -------------------------------------------------------------------------------- /shopinvader/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | end 3 | -------------------------------------------------------------------------------- /shopinvader/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | -------------------------------------------------------------------------------- /shopinvader/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /shopinvader/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /.loco-data/README.md: -------------------------------------------------------------------------------- 1 | # Storage folder for local devs w/ Locomotive 2 | 3 | If you run locomotive w/ docker compose you need this folder for local storage. -------------------------------------------------------------------------------- /shopinvader/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../javascripts .js 3 | //= link_directory ../stylesheets .css 4 | -------------------------------------------------------------------------------- /shopinvader/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /shopinvader/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /shopinvader/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /shopinvader/config/spring.rb: -------------------------------------------------------------------------------- 1 | %w[ 2 | .ruby-version 3 | .rbenv-vars 4 | tmp/restart.txt 5 | tmp/caching-dev.txt 6 | ].each { |path| Spring.watch(path) } 7 | -------------------------------------------------------------------------------- /shopinvader/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /shopinvader/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eo pipefail 3 | 4 | rm -f shopinvader/Gemfile.lock 5 | docky run bundle install 6 | echo "update done, check result the run" 7 | echo "./bump.sh" 8 | -------------------------------------------------------------------------------- /shopinvader/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /shopinvader/test/application_system_test_case.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 4 | driven_by :selenium, using: :chrome, screen_size: [1400, 1400] 5 | end 6 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/sentry.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Sentry.init do |config| 4 | config.breadcrumbs_logger = [:active_support_logger] 5 | config.dsn = ENV['SENTRY_DSN'] 6 | config.enable_tracing = true 7 | end 8 | -------------------------------------------------------------------------------- /shopinvader/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /shopinvader/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require_relative '../config/environment' 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Add more helper methods to be used by all tests here... 7 | end 8 | -------------------------------------------------------------------------------- /shopinvader/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /shopinvader/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: locomotiveapp_production 11 | -------------------------------------------------------------------------------- /bump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eo pipefail 3 | 4 | git add shopinvader/Gemfile shopinvader/Gemfile.lock 5 | TAG="v4.0.x-`date +%Y%m%d`" 6 | MESSAGE="Automatic release $TAG" 7 | git commit -m "$MESSAGE" 8 | git tag "$TAG" 9 | echo "bump done, check result the run" 10 | echo "git push origin master --tag" 11 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /shopinvader/app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /install/shopinvader.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail 3 | 4 | bundle install --without development 5 | mkdir -p tmp log 6 | chown 9999:9999 tmp log 7 | # a fake SECRET KEY is needed to build asset :'( 8 | # https://github.com/rails/rails/issues/32947 9 | SECRET_KEY_BASE=1 RAILS_ENV=production bundle exec rake assets:precompile 10 | rm -rf log/* tmp/* 11 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | -------------------------------------------------------------------------------- /shopinvader/app/assets/javascripts/cable.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | // 4 | //= require action_cable 5 | //= require_self 6 | //= require_tree ./channels 7 | 8 | (function() { 9 | this.App || (this.App = {}); 10 | 11 | App.cable = ActionCable.createConsumer(); 12 | 13 | }).call(this); 14 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure parameters to be filtered from the log file. Use this to limit dissemination of 4 | # sensitive information. See the ActiveSupport::ParameterFilter documentation for supported 5 | # notations and behaviors. 6 | Rails.application.config.filter_parameters += [ 7 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn 8 | ] 9 | -------------------------------------------------------------------------------- /shopinvader/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shopinvader 5 | <%= csrf_meta_tags %> 6 | 7 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> 8 | <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> 9 | <%= Sentry.get_trace_propagation_meta.html_safe %> 10 | 11 | 12 | 13 | <%= yield %> 14 | 15 | 16 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = "1.0" 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in the app/assets 11 | # folder are already added. 12 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) 13 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code 7 | # by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". 8 | Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] 9 | -------------------------------------------------------------------------------- /shopinvader/bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | yarn = ENV["PATH"].split(File::PATH_SEPARATOR). 5 | select { |dir| File.expand_path(dir) != __dir__ }. 6 | product(["yarn", "yarn.cmd", "yarn.ps1"]). 7 | map { |dir, file| File.expand_path(file, dir) }. 8 | find { |file| File.executable?(file) } 9 | 10 | if yarn 11 | exec yarn, *ARGV 12 | else 13 | $stderr.puts "Yarn executable was not detected in the system." 14 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 15 | exit 1 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /bin/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # allow to customize the UID of the loco user, 5 | # so we can share the same than the host's. 6 | # If no user id is set, we use 999 7 | USER_ID=${LOCAL_USER_ID:-999} 8 | 9 | echo "Starting with UID : $USER_ID" 10 | id -u loco &> /dev/null || useradd --shell /bin/bash -u $USER_ID -o -c "" -m loco 11 | 12 | echo "Changing permissions on writable directory with UID : $USER_ID" 13 | chown -R $USER_ID /usr/src/app/log 14 | chown -R $USER_ID /usr/src/app/tmp 15 | chown -R $USER_ID /usr/src/app/public/sites 16 | chown -R $USER_ID /usr/src/app/public/uploaded_assets 17 | 18 | exec "$@" 19 | -------------------------------------------------------------------------------- /shopinvader/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's 5 | // vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. JavaScript code in this file should be added after the last require_* statement. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, "\\1en" 8 | # inflect.singular /^(ox)en/i, "\\1" 9 | # inflect.irregular "person", "people" 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym "RESTful" 16 | # end 17 | -------------------------------------------------------------------------------- /shopinvader/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | 3 | # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. 4 | # Can be used by load balancers and uptime monitors to verify that the app is live. 5 | get '/up', to: 'rails/health#show', as: :rails_health_check 6 | 7 | 8 | # Locomotive Back-office 9 | mount Locomotive::Engine => '/locomotive', as: 'locomotive' # you can change the value of the path, by default set to "/locomotive" 10 | 11 | # Locomotive API 12 | mount Locomotive::API.to_app => '/locomotive(/:site_handle)/api' 13 | 14 | # Render site 15 | mount Locomotive::Steam.to_app => '/', anchor: false 16 | # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 17 | end 18 | -------------------------------------------------------------------------------- /shopinvader/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's 6 | * vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS 10 | * files in this directory. Styles in this file should be added after the last require_* statement. 11 | * It is generally better to create a new file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | -------------------------------------------------------------------------------- /shopinvader/bin/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'fileutils' 3 | include FileUtils 4 | 5 | # path to your application root. 6 | APP_ROOT = File.expand_path('..', __dir__) 7 | 8 | def system!(*args) 9 | system(*args) || abort("\n== Command #{args} failed ==") 10 | end 11 | 12 | chdir APP_ROOT do 13 | # This script is a way to update your development environment automatically. 14 | # Add necessary update steps to this file. 15 | 16 | puts '== Installing dependencies ==' 17 | system! 'gem install bundler --conservative' 18 | system('bundle check') || system!('bundle install') 19 | 20 | # Install JavaScript dependencies if using Yarn 21 | # system('bin/yarn') 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system! 'bin/rails log:clear tmp:clear' 25 | 26 | puts "\n== Restarting application server ==" 27 | system! 'bin/rails restart' 28 | end 29 | -------------------------------------------------------------------------------- /shopinvader/bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "fileutils" 3 | 4 | # path to your application root. 5 | APP_ROOT = File.expand_path("..", __dir__) 6 | 7 | def system!(*args) 8 | system(*args) || abort("\n== Command #{args} failed ==") 9 | end 10 | 11 | FileUtils.chdir APP_ROOT do 12 | # This script is a way to set up or update your development environment automatically. 13 | # This script is idempotent, so that you can run it at any time and get an expectable outcome. 14 | # Add necessary setup steps to this file. 15 | 16 | puts "== Installing dependencies ==" 17 | system! "gem install bundler --conservative" 18 | system("bundle check") || system!("bundle install") 19 | 20 | puts "\n== Removing old logs and tempfiles ==" 21 | system! "bin/rails log:clear tmp:clear" 22 | 23 | puts "\n== Restarting application server ==" 24 | system! "bin/rails restart" 25 | end 26 | -------------------------------------------------------------------------------- /shopinvader/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # 'true': 'foo' 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at https://guides.rubyonrails.org/i18n.html. 31 | 32 | en: 33 | hello: "Hello world" 34 | -------------------------------------------------------------------------------- /dev.docker-compose.yml: -------------------------------------------------------------------------------- 1 | # This is the dev docker compose that I use with docky for dev purpose 2 | # Do not forget to create the mounted directory before 3 | services: 4 | db: 5 | image: mongo:3 6 | volumes: 7 | - ./data/db:/data/db 8 | - ./data/backup:/backup 9 | locomotive: 10 | environment: 11 | - RAILS_ENV=development 12 | - STORE_ASSET_IN_S3=false 13 | - DRAGON_FLY_SECRET=thisISaDEMOkeyNOTsecret 14 | - LOCOMOTIVE_ENABLE_REGISTRATION=true 15 | image: ghcr.io/akretion/docky-ruby:latest 16 | links: 17 | - db 18 | volumes: 19 | - ./shopinvader:/workspace 20 | - ../gems:/workspace/dev-gem 21 | - ./bundle:/usr/local/bundle 22 | - ./data/tmp:/workspace/tmp 23 | - ./data/log:/workspace/log 24 | - ./data/public/sites:/workspace/public/sites 25 | - ./data/public/uploaded_assets:/workspace/public/uploaded_assets 26 | labels: 27 | docky.user: ubuntu 28 | docky.main.service: True 29 | version: '3' 30 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: 8 | - '*' 9 | 10 | jobs: 11 | build-odoo: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Set up Docker Buildx 16 | uses: docker/setup-buildx-action@v1 17 | - name: Login to ghcr.io 18 | uses: docker/login-action@v1 19 | with: 20 | registry: ghcr.io 21 | username: ${{ github.repository_owner }} 22 | password: ${{ secrets.GITHUB_TOKEN }} 23 | - name: Build image 24 | uses: docker/build-push-action@v2 25 | with: 26 | context: shopinvader 27 | file: shopinvader/Dockerfile 28 | tags: | 29 | ghcr.io/${{ github.repository }}:latest, 30 | ghcr.io/${{ github.repository }}:${{ github.ref_name }} 31 | cache-from: type=registry,ref=ghcr.io/${{ github.repository }}:latest 32 | cache-to: type=inline 33 | push: true 34 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # TODO it will be great if we can use the cookie_store 4 | # instead of mongoid_store 5 | # but for this we need to review the way to store the 6 | # cart cache. Currently it's stored in the cookie 7 | 8 | Rails.application.config.session_store( 9 | :mongoid_store, 10 | key: '_station_session', 11 | expire_after: 2.years, 12 | ) 13 | 14 | # Varnish will drop all cookie session for get method 15 | # this mean that we will have a lot of request without any session cookie 16 | # generating a cookie even if the session is empty 17 | 18 | module ActionDispatch 19 | module Session 20 | class MongoStoreBase 21 | alias_method :orig_write_session, :write_session 22 | 23 | def write_session(req, sid, session_data, options) 24 | if session_data.size > 0 25 | orig_write_session(req, sid, session_data, options) 26 | else 27 | delete_session(req, sid, options) 28 | 'nosession' 29 | end 30 | end 31 | 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/content_security_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide content security policy. 4 | # See the Securing Rails Applications Guide for more information: 5 | # https://guides.rubyonrails.org/security.html#content-security-policy-header 6 | 7 | # Rails.application.configure do 8 | # config.content_security_policy do |policy| 9 | # policy.default_src :self, :https 10 | # policy.font_src :self, :https, :data 11 | # policy.img_src :self, :https, :data 12 | # policy.object_src :none 13 | # policy.script_src :self, :https 14 | # policy.style_src :self, :https 15 | # # Specify URI for violation reports 16 | # # policy.report_uri "/csp-violation-report-endpoint" 17 | # end 18 | # 19 | # # Generate session nonces for permitted importmap and inline scripts 20 | # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } 21 | # config.content_security_policy_nonce_directives = %w(script-src) 22 | # 23 | # # Report violations without enforcing the policy. 24 | # # config.content_security_policy_report_only = true 25 | # end 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.rbc 2 | capybara-*.html 3 | .rspec 4 | /log 5 | /tmp 6 | /db/*.sqlite3 7 | /db/*.sqlite3-journal 8 | /public/system 9 | /public/sites 10 | /public/uploaded* 11 | .db/* 12 | /coverage/ 13 | /spec/tmp 14 | **.orig 15 | rerun.txt 16 | pickle-email-*.html 17 | .byebug_history 18 | dev.docker-compose.yml 19 | /dev-gem 20 | public/assets/* 21 | public/sites/* 22 | public/uploaded_assets/* 23 | environment 24 | . 25 | 26 | /shopinvader/vendor/bundle 27 | /shopinvader/public/assets 28 | /shopinvader/public/uploaded_assets 29 | /shopinvader/public/sites 30 | /shopinvader/log 31 | /shopinvader/tmp 32 | /shopinvader/.bundle 33 | 34 | # Ignore local locomotive data 35 | .loco-data/*/* 36 | 37 | # TODO Comment out these rules if you are OK with secrets being uploaded to the repo 38 | config/initializers/secret_token.rb 39 | 40 | ## Environment normalisation: 41 | /.bundle 42 | /vendor/bundle 43 | 44 | # these should all be checked in to normalise the environment: 45 | # Gemfile.lock, .ruby-version, .ruby-gemset 46 | 47 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 48 | .rvmrc 49 | 50 | # if using bower-rails ignore default bower_components path bower.json files 51 | /vendor/assets/bower_components 52 | *.bowerrc 53 | bower.json 54 | 55 | # Ignore pow environment settings 56 | .powenv 57 | -------------------------------------------------------------------------------- /install/gosu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -exo pipefail 3 | 4 | # copy from https://raw.githubusercontent.com/camptocamp/docker-odoo-project/master/install/gosu.sh 5 | 6 | # fix intermittent gpg server error from https://github.com/tianon/gosu/issues/35 7 | export GNUPGHOME="$(mktemp -d)" 8 | for server in $(shuf -e ha.pool.sks-keyservers.net \ 9 | hkp://p80.pool.sks-keyservers.net:80 \ 10 | keyserver.ubuntu.com \ 11 | hkp://keyserver.ubuntu.com:80 \ 12 | pgp.mit.edu) 13 | do 14 | ks_options="" 15 | # $http_proxy is an environment variable which is usually lowcase, a gpg quirk 16 | if [ -n "$http_proxy" ] 17 | then 18 | ks_options="--keyserver-options http-proxy=$http_proxy" 19 | fi 20 | gpg --no-tty --keyserver "$server" $ks_options --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 && break || : 21 | done 22 | curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture)" 23 | curl -o /usr/local/bin/gosu.asc -SL "https://github.com/tianon/gosu/releases/download/1.10/gosu-$(dpkg --print-architecture).asc" 24 | gpg --verify --no-tty /usr/local/bin/gosu.asc 25 | rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc 26 | chmod +x /usr/local/bin/gosu 27 | # verify that the binary works 28 | gosu nobody true 29 | -------------------------------------------------------------------------------- /shopinvader/config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rails secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | # Shared secrets are available across all environments. 14 | 15 | # shared: 16 | # api_key: a1B2c3D4e5F6 17 | 18 | # Environmental secrets are only available for that specific environment. 19 | 20 | development: 21 | secret_key_base: 1737ab05ca0671055dfde63111d302bbd23f5957697431e91f390d341c596f0a887c316755cb0ef1d1d62e90c9d8704dc1f6e84539d858dbd07af9f556fd7e5e 22 | 23 | test: 24 | secret_key_base: 81118a61f67f2ab054bb6a9ae61d11002fd4bc8c873548ac5048ae970235af0b41e743af45243608c5ca43127142d26a7bad4ccf89348e94f999c3350ef1443c 25 | 26 | # Do not keep production secrets in the unencrypted secrets file. 27 | # Instead, either read values from the environment. 28 | # Or, use `bin/rails secrets:setup` to configure encrypted secrets 29 | # and move the `production:` environment over there. 30 | 31 | production: 32 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 33 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/dragonfly.rb: -------------------------------------------------------------------------------- 1 | # Images are transformed by the Heroku app leading to bigger memory + cpu consumption 2 | # This is why it's a good practice to use another Ruby app to handle the transformations 3 | TRANSFORMED_IMAGES_SERVICE_URL = ENV['DRAGONFLYAPP_HOST'] || ENV['DRAGONFLYAPP_URL'] || Rails.application.config.action_controller.asset_host 4 | 5 | # Configure 6 | Dragonfly.app(:engine).configure do 7 | plugin :imagemagick, 8 | convert_command: `which convert`.strip.presence || '/usr/local/bin/convert', 9 | identify_command: `which identify`.strip.presence || '/usr/local/bin/identify' 10 | 11 | processor :thumb, Locomotive::Dragonfly::Processors::SmartThumb.new 12 | 13 | if Rails.env.production? 14 | verify_urls true 15 | 16 | secret ENV['DRAGON_FLY_SECRET'] 17 | else 18 | verify_urls false 19 | end 20 | 21 | url_format '/images/dynamic/:job/:sha/:basename.:ext' 22 | 23 | fetch_file_whitelist /public/ 24 | 25 | fetch_url_whitelist /.+/ 26 | 27 | # we don't care if this is the Heroku app converting the image 28 | url_host (case Rails.env.to_sym 29 | when :production then TRANSFORMED_IMAGES_SERVICE_URL 30 | else nil; end) 31 | end 32 | 33 | Dragonfly.app(:steam).configure do 34 | url_host (case Rails.env.to_sym 35 | when :production then TRANSFORMED_IMAGES_SERVICE_URL 36 | else nil; end) 37 | end 38 | 39 | # Logger 40 | Dragonfly.logger = Rails.logger 41 | 42 | # Mount as middleware 43 | Rails.application.middleware.use Dragonfly::Middleware, :engine 44 | -------------------------------------------------------------------------------- /shopinvader/config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails" 4 | # Pick the frameworks you want: 5 | require "active_model/railtie" 6 | require "active_job/railtie" 7 | require "action_controller/railtie" 8 | require "action_mailer/railtie" 9 | require "action_view/railtie" 10 | require "action_cable/engine" 11 | require "sprockets/railtie" 12 | 13 | # Require the gems listed in Gemfile, including any gems 14 | # you've limited to :test, :development, or :production. 15 | Bundler.require(*Rails.groups) 16 | 17 | module Shopinvader 18 | class Application < Rails::Application 19 | # Initialize configuration defaults for originally generated Rails version. 20 | config.load_defaults 7.1 21 | config.mongoid.logger.level = Logger::INFO 22 | config.logger = Logger.new(STDOUT) 23 | 24 | config.autoload_paths << Rails.root.join('lib') 25 | 26 | config.x.locomotive_search_backend = :algolia 27 | 28 | config.middleware.insert_before 0, Rack::Cors do 29 | allow do 30 | origins '*' 31 | resource '/assets/*', headers: :any, methods: :any 32 | end 33 | end 34 | 35 | initializer 'station.steam', after: 'steam' do |app| 36 | Locomotive::Steam.configure do |config| 37 | ShopInvader.setup 38 | end 39 | Locomotive::Common.configure do |config| 40 | config.notifier = Locomotive::Common::Logger.setup(nil) 41 | end 42 | end 43 | 44 | config.hosts << ->(host) { 45 | permitted_domains = Rails.cache.fetch('locomotive-domains', expires_in: 2.minute) do 46 | Locomotive::Site.pluck(:domains).flatten 47 | end 48 | permitted_domains.include?(host) 49 | } 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | 3 | # This is needed for making locomotive instance communicate w/ master odoo instance in dev mode 4 | # If you don't put odoo in the same composition, just add this shared network and an alias to the odoo one. 5 | # IMPORTANT: to make this work w/ `run --rm` you have to pass `--use-aliases`. 6 | networks: 7 | shopinvader-shared-odoo-net: 8 | name: shopinvader-shared-odoo-net 9 | 10 | services: 11 | db: 12 | image: mongo:3 13 | volumes: 14 | - .db:/data/db 15 | locomotive: 16 | ports: 17 | - 3000:3000 18 | # In production never never never use latest ! 19 | # use a specific tag image in order to be sure 20 | # of what you install 21 | image: quay.io/akretion/shopinvader:latest 22 | links: 23 | - db 24 | volumes: 25 | - .loco-data/tmp:/usr/src/app/tmp:rw 26 | - .loco-data/log:/usr/src/app/log:rw 27 | - .loco-data/public/sites:/usr/src/app/public/sites:rw 28 | - .loco-data/public/uploaded_assets:/usr/src/app/public/uploaded_assets:rw 29 | environment: 30 | - RAILS_ENV=development 31 | - DRAGON_FLY_SECRET=thisISaDEMOkeyNOTsecret 32 | - SECRET_KEY_BASE=aDEMOkeyASwell 33 | - LOCOMOTIVE_ENABLE_REGISTRATION=true 34 | - LOCOMOTIVE_ADMIN_SSL_REDIRECT=false 35 | - RAILS_SERVE_STATIC_FILES=true 36 | networks: 37 | default: 38 | shopinvader-shared-odoo-net: 39 | aliases: 40 | # reach locomotive w/ this alias (eg: from odoo or any other service) 41 | - locomotive.local 42 | wagon: 43 | image: quay.io/akretion/shopinvader-wagon:latest 44 | ports: 45 | - 3333:3333 46 | volumes: 47 | # NOTE: to make this work the do-co file should stay in the root of your shopinvader theme 48 | - .:/workspace 49 | networks: 50 | default: 51 | shopinvader-shared-odoo-net: 52 | aliases: 53 | - locomotive.wagon 54 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/carrierwave.rb: -------------------------------------------------------------------------------- 1 | CarrierWave.configure do |config| 2 | 3 | config.cache_dir = File.join(Rails.root, 'tmp', 'uploads') 4 | 5 | case Rails.env.to_sym 6 | 7 | when :development 8 | config.storage = :file 9 | config.root = File.join(Rails.root, 'public') 10 | 11 | when :production 12 | begin 13 | # context: when we're precompiling the assets in the Dockerfile 14 | break if ENV['S3_BUCKET'].blank? 15 | 16 | # config.storage = :file 17 | # config.root = File.join(Rails.root, 'public') 18 | 19 | # Put your CDN host below instead 20 | if ENV['S3_ASSET_HOST_URL'].present? 21 | config.asset_host = ENV['S3_ASSET_HOST_URL'] 22 | end 23 | 24 | # # You can also use Amazon S3 instead. The following configuration works for AWS 25 | # # 26 | # # WARNING: add the "carrierwave-aws" gem in your Rails app Gemfile. 27 | # # More information here: https://github.com/sorentwo/carrierwave-aws 28 | # 29 | config.storage = :aws 30 | config.aws_bucket = ENV['S3_BUCKET'] 31 | config.aws_acl = 'public-read' 32 | 33 | 34 | config.aws_attributes = { 35 | cache_control: ENV['S3_CACHE_CONTROL'] 36 | } 37 | 38 | config.aws_credentials = { 39 | access_key_id: ENV['S3_KEY_ID'], 40 | secret_access_key: ENV['S3_SECRET_KEY'], 41 | region: ENV['S3_BUCKET_REGION'] 42 | } 43 | 44 | # Use a different endpoint (eg: another provider such as Exoscale) 45 | if ENV['S3_ENDPOINT'].present? 46 | config.aws_credentials[:endpoint] = ENV['S3_ENDPOINT'] 47 | end 48 | 49 | # For some endpoint like minio you need to rewrite path 50 | if ENV['S3_PATH_STYLE'].present? 51 | config.aws_credentials[:force_path_style] = ENV['S3_PATH_STYLE'] 52 | end 53 | 54 | end 55 | 56 | else 57 | # settings for the local filesystem 58 | config.storage = :file 59 | config.root = File.join(Rails.root, 'public') 60 | end 61 | 62 | end 63 | -------------------------------------------------------------------------------- /shopinvader/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # In the development environment your application's code is reloaded any time 7 | # it changes. This slows down response time but is perfect for development 8 | # since you don't have to restart the web server when you make code changes. 9 | config.cache_classes = false 10 | 11 | # Do not eager load code on boot. 12 | config.eager_load = false 13 | 14 | # Show full error reports. 15 | config.consider_all_requests_local = true 16 | 17 | # Enable server timing 18 | config.server_timing = true 19 | 20 | # Enable/disable caching. By default caching is disabled. 21 | # Run rails dev:cache to toggle caching. 22 | if Rails.root.join("tmp/caching-dev.txt").exist? 23 | config.action_controller.perform_caching = true 24 | config.action_controller.enable_fragment_cache_logging = true 25 | 26 | config.cache_store = :memory_store 27 | config.public_file_server.headers = { 28 | "Cache-Control" => "public, max-age=#{2.days.to_i}" 29 | } 30 | else 31 | config.action_controller.perform_caching = false 32 | 33 | config.cache_store = :null_store 34 | end 35 | 36 | # Don't care if the mailer can't send. 37 | config.action_mailer.raise_delivery_errors = false 38 | 39 | config.action_mailer.perform_caching = false 40 | 41 | # Print deprecation notices to the Rails logger. 42 | config.active_support.deprecation = :log 43 | 44 | # Raise exceptions for disallowed deprecations. 45 | config.active_support.disallowed_deprecation = :raise 46 | 47 | # Tell Active Support which deprecation messages to disallow. 48 | config.active_support.disallowed_deprecation_warnings = [] 49 | 50 | 51 | # Raises error for missing translations. 52 | # config.i18n.raise_on_missing_translations = true 53 | 54 | # Annotate rendered view with file names. 55 | # config.action_view.annotate_rendered_view_with_filenames = true 56 | 57 | # Uncomment if you wish to allow Action Cable access from any origin. 58 | # config.action_cable.disable_request_forgery_protection = true 59 | end 60 | -------------------------------------------------------------------------------- /shopinvader/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | # The test environment is used exclusively to run your application's 4 | # test suite. You never need to work with it otherwise. Remember that 5 | # your test database is "scratch space" for the test suite and is wiped 6 | # and recreated between test runs. Don't rely on the data there! 7 | 8 | Rails.application.configure do 9 | # Settings specified here will take precedence over those in config/application.rb. 10 | 11 | # Turn false under Spring and add config.action_view.cache_template_loading = true. 12 | config.cache_classes = true 13 | 14 | # Eager loading loads your whole application. When running a single test locally, 15 | # this probably isn't necessary. It's a good idea to do in a continuous integration 16 | # system, or in some way before deploying your code. 17 | config.eager_load = ENV["CI"].present? 18 | 19 | # Configure public file server for tests with Cache-Control for performance. 20 | config.public_file_server.enabled = true 21 | config.public_file_server.headers = { 22 | "Cache-Control" => "public, max-age=#{1.hour.to_i}" 23 | } 24 | 25 | # Show full error reports and disable caching. 26 | config.consider_all_requests_local = true 27 | config.action_controller.perform_caching = false 28 | config.cache_store = :null_store 29 | 30 | # Raise exceptions instead of rendering exception templates. 31 | config.action_dispatch.show_exceptions = false 32 | 33 | # Disable request forgery protection in test environment. 34 | config.action_controller.allow_forgery_protection = false 35 | 36 | config.action_mailer.perform_caching = false 37 | 38 | # Tell Action Mailer not to deliver emails to the real world. 39 | # The :test delivery method accumulates sent emails in the 40 | # ActionMailer::Base.deliveries array. 41 | config.action_mailer.delivery_method = :test 42 | 43 | # Print deprecation notices to the stderr. 44 | config.active_support.deprecation = :stderr 45 | 46 | # Raise exceptions for disallowed deprecations. 47 | config.active_support.disallowed_deprecation = :raise 48 | 49 | # Tell Active Support which deprecation messages to disallow. 50 | config.active_support.disallowed_deprecation_warnings = [] 51 | 52 | # Raises error for missing translations. 53 | # config.i18n.raise_on_missing_translations = true 54 | 55 | # Annotate rendered view with file names. 56 | # config.action_view.annotate_rendered_view_with_filenames = true 57 | end 58 | -------------------------------------------------------------------------------- /shopinvader/config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers: a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum; this matches the default thread size of Active Record. 6 | # 7 | max_threads_count = ENV.fetch("PUMA_MAX_THREADS") { 16 } 8 | min_threads_count = ENV.fetch("PUMA_MIN_THREADS") { 0 } 9 | threads min_threads_count, max_threads_count 10 | 11 | # Specifies the `worker_timeout` threshold that Puma will use to wait before 12 | # terminating a worker in development environments. 13 | # 14 | worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" 15 | 16 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 17 | # 18 | port ENV.fetch("PORT") { 3000 } 19 | 20 | # Specifies the `environment` that Puma will run in. 21 | # 22 | environment ENV.fetch("RAILS_ENV") { "development" } 23 | 24 | 25 | # Specifies the `pidfile` that Puma will use. 26 | pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } 27 | 28 | # Specifies the number of `workers` to boot in clustered mode. 29 | # Workers are forked web server processes. If using threads and workers together 30 | # the concurrency of the application would be max `threads` * `workers`. 31 | # Workers do not work on JRuby or Windows (both of which do not support 32 | # processes). 33 | # 34 | 35 | workers ENV.fetch("PUMA_WORKERS") { 2 } 36 | 37 | # Use the `preload_app!` method when specifying a `workers` number. 38 | # This directive tells Puma to first boot the application and load code 39 | # before forking the application. This takes advantage of Copy On Write 40 | # process behavior so workers use less memory. 41 | # 42 | preload_app! 43 | 44 | if ENV.fetch("RAILS_ENV") == "production" 45 | before_fork do 46 | require 'puma_worker_killer' 47 | PumaWorkerKiller.config do |config| 48 | config.ram = Integer(ENV['PUMA_MAX_RAM'] || 4096) 49 | config.frequency = 60 50 | config.rolling_restart_frequency = 12 * 3600 51 | end 52 | PumaWorkerKiller.start 53 | end 54 | end 55 | 56 | 57 | # expose PUMA control app if auth token 58 | if ENV['PUMA_AUTH_TOKEN'] 59 | activate_control_app 'tcp://0.0.0.0:9293', { auth_token: ENV['PUMA_AUTH_TOKEN'] } 60 | end 61 | 62 | # Allow puma to be restarted by `rails restart` command. 63 | plugin :tmp_restart 64 | -------------------------------------------------------------------------------- /shopinvader/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile 4 | ARG RUBY_VERSION=3.3.5 5 | FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim AS base 6 | 7 | # Rails app lives here 8 | WORKDIR /rails 9 | 10 | # Set production environment 11 | ENV RAILS_ENV="production" \ 12 | BUNDLE_DEPLOYMENT="1" \ 13 | BUNDLE_PATH="/usr/local/bundle" \ 14 | BUNDLE_WITHOUT="development" 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build gems 20 | RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ 21 | --mount=type=cache,target=/var/lib/apt,sharing=locked \ 22 | apt-get update -qq && \ 23 | apt-get install --no-install-recommends -y build-essential git libvips pkg-config 24 | 25 | # Install application gems 26 | COPY Gemfile Gemfile.lock ./ 27 | RUN --mount=type=cache,target=/root/.gem \ 28 | bundle install && \ 29 | rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ 30 | bundle exec bootsnap precompile --gemfile 31 | 32 | # Copy application code 33 | COPY . . 34 | 35 | # Precompile bootsnap code for faster boot times 36 | RUN bundle exec bootsnap precompile app/ lib/ 37 | 38 | # Install packaged need to build JS libs 39 | RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ 40 | --mount=type=cache,target=/var/lib/apt,sharing=locked \ 41 | apt-get update && apt-get upgrade -y && \ 42 | apt-get install -y nodejs \ 43 | npm 44 | RUN --mount=type=cache,target=/root/.npm npm install -g yarn@1.22.6 45 | 46 | # Precompiling assets for production without requiring secret RAILS_MASTER_KEY 47 | RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile 48 | 49 | # Final stage for app image 50 | FROM base 51 | 52 | # Install packages needed for deployment 53 | RUN apt-get update -qq && \ 54 | apt-get install --no-install-recommends -y curl libsqlite3-0 libvips nodejs imagemagick && \ 55 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 56 | 57 | # Copy built artifacts: gems, application 58 | COPY --from=build /usr/local/bundle /usr/local/bundle 59 | COPY --from=build /rails /rails 60 | 61 | # Run and own only the runtime files as a non-root user for security 62 | RUN useradd rails --create-home --shell /bin/bash && \ 63 | chown -R rails:rails log tmp 64 | USER rails:rails 65 | 66 | # Start the server by default, this can be overwritten at runtime 67 | EXPOSE 3000 68 | CMD ["./bin/rails", "server"] 69 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 2 | * make site lang configurable 3 | 4 | ## v4.0.x-20241022 5 | * add regex support for domain 6 | 7 | ## v4.0.x-20241015 8 | 9 | * Big update the project, use native steam version (not a fork anymore) 10 | * Broken deprecated old syntax have been removed 11 | see: https://github.com/shopinvader/locomotive-shopinvader/commit/335f3cdcba192989af65d7b5056a6376e055ec07 12 | * Following Variable have changed 13 | - STORE_ASSET_IN_S3 not needed anymore (duplicated information), just configure your bucket and it will use it 14 | * Rails 7 filter the domain available 15 | - the domain that locomotive respond is filtered on the list of domain that exist in the database and a cache of 2 minute exists so when you add a new site, please wait 2 minutes max 16 | see here: https://github.com/shopinvader/docker-locomotive-shopinvader/blob/70dc0b2dec31d767904690c1eb0752dd172e1865/shopinvader/config/application.rb#L44 17 | - ALLOWED_DOMAIN => you can add here additionnal domain that you want to allow 18 | 19 | 20 | ## v4.0.x-20201211 21 | 22 | * Update shopinvader lib to solve with_scope in operator with algolia 23 | 24 | ## v4.0.x-20200630 25 | 26 | * Update dependency 27 | * Add the recaptcha support on api endpoint of odoo 28 | in the erp metafields you need to add the field api_required_recaptcha 29 | 30 | ``` 31 | erp: 32 | api_required_recaptcha: > 33 | [{ "method": "POST", "actions": ["lead", "lead/create"]}] 34 | ``` 35 | 36 | ## v4.0.X.20200508 37 | 38 | * fix security issue, params where visible in log, remove them 39 | 40 | ## v4.0.X-20200213 41 | 42 | * fix issue with params in erp tag by updating shopinvader gems 43 | 44 | ## v4.0.x-20200207 45 | 46 | * fix dynamic rendering of esi_include by updating shopinvader gems 47 | 48 | ## v4.0.x-20200206 49 | 50 | * fix rendering of esi_include by updating shopinvader gems 51 | 52 | ## v4.0.x-20200204 53 | 54 | * fix deploying by updating to last version of locomotive engine that force the right version of rack dependency 55 | 56 | ## v4.0.x-20200128 57 | 58 | * move back to ruby 2.6.5 as dependency (steam) generate warning message, we will move later 59 | 60 | ## v4.0.x-20200127 61 | 62 | * fix issue with params in liquid tag by using a fork of steam PR is here : https://github.com/locomotivecms/steam/pull/170 63 | 64 | ## v4.0.x-20200113 65 | 66 | * Big change move to last version of locomotive, this version do not use anymore a liquid fork this have no impact on the templating of website but change a many line in the code source of shopinvader plugin. 67 | * Move to ruby 2.7 68 | -------------------------------------------------------------------------------- /shopinvader/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Erreur 500 - Une erreur technique est survenue 11 | 12 | 13 | 14 | 15 | 58 | 59 | 60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |

Le site a rencontré une erreur.

73 |
74 |

75 | Nos techniciens mettent tout en œuvre pour que le site soit de nouveau accessible.
76 | Nous vous invitons à réessayer ultérieurement. 77 |

78 | 79 |
80 |
81 |
82 |
83 |
84 | 87 | 92 | 93 |
94 |
95 |
96 |
97 | 98 | 99 | -------------------------------------------------------------------------------- /shopinvader/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | git_source(:github) { |repo| "https://github.com/#{repo}.git" } 3 | 4 | ruby '3.3.5' 5 | 6 | gem 'rails', '~> 7.1', '< 7.2' 7 | gem 'rack-cors', require: 'rack/cors' 8 | gem 'puma', '~> 6.4.0' 9 | gem 'devise' 10 | gem 'carrierwave-aws' 11 | gem 'mimemagic', '~> 0.4.3' 12 | 13 | # gem 'pry' 14 | # gem 'custom_fields', path: '../../custom_fields' # for Developers 15 | # gem 'locomotivecms_common', path: '../../common', require: false 16 | 17 | # gem 'locomotivecms_steam', path: '../../steam', require: false 18 | # gem 'locomotivecms', path: '../../engine' 19 | 20 | # gem 'locomotivecms_search', path: '../../search' 21 | 22 | gem 'locomotivecms', github: 'locomotivecms/engine', ref: 'e6fb512c' 23 | gem 'locomotivecms_steam', github: 'locomotivecms/steam', ref: 'ba10b57b', require: false 24 | gem 'locomotivecms_common', github: 'locomotivecms/common', ref: 'c78da158', require: false 25 | # gem 'locomotivecms_search', github: 'locomotivecms/search', ref: '35e5813' 26 | gem 'custom_fields', github: 'locomotivecms/custom_fields', ref: '87bf1b', require: false 27 | 28 | 29 | # Shopinvader specific 30 | gem 'shop_invader', github: 'shopinvader/locomotive-shopinvader', branch: 'v4.0.x' 31 | gem 'mongo_session_store', '~> 3.2.1' 32 | gem 'puma_worker_killer' 33 | 34 | 35 | # Reduces boot times through caching; required in config/boot.rb 36 | gem "bootsnap", require: false 37 | 38 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 39 | # gem 'rails', '~> 7.0', '>= 7.0.4.2' 40 | # Use Puma as the app server 41 | 42 | # gem 'passenger-rails' 43 | 44 | # Use SCSS for stylesheets 45 | 46 | 47 | # gem 'sass-rails', '~> 5.0' 48 | # Use Uglifier as compressor for JavaScript assets 49 | # gem 'uglifier', '>= 4.1.20' 50 | # See https://github.com/rails/execjs#readme for more supported runtimes 51 | # gem 'mini_racer', platforms: :ruby 52 | 53 | # Use CoffeeScript for .coffee assets and views 54 | # gem 'coffee-rails', '~> 5.0' 55 | # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks 56 | # gem 'turbolinks', '~> 5' 57 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 58 | # gem 'jbuilder', '~> 2.5' 59 | # Use Redis adapter to run Action Cable in production + Cache 60 | 61 | 62 | # Use ActiveModel has_secure_password 63 | # gem 'bcrypt', '~> 3.1.7' 64 | 65 | 66 | 67 | # gem 'sidekiq' 68 | 69 | # Use Capistrano for deployment 70 | # gem 'capistrano-rails', group: :development 71 | 72 | group :development, :test do 73 | gem "debug", ">= 1.0.0" 74 | gem 'dotenv' 75 | end 76 | 77 | group :development do 78 | # Access an interactive console on exception pages or by calling 'console' anywhere in the code. 79 | # gem 'web-console', '>= 3.3.0' 80 | # gem 'listen', '>= 3.0.5', '< 3.2' 81 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 82 | # gem 'spring' 83 | # gem 'spring-watcher-listen', '~> 2.0.0' 84 | end 85 | 86 | group :test do 87 | # Adds support for Capybara system testing and selenium driver 88 | # gem 'capybara', '~> 2.15' 89 | # gem 'selenium-webdriver' 90 | # Easy installation and use of chromedriver to run system tests with Chrome 91 | # gem 'chromedriver-helper' 92 | end 93 | 94 | group :production do 95 | gem "stackprof" 96 | gem "sentry-ruby" 97 | gem "sentry-rails" 98 | end 99 | 100 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 101 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 102 | -------------------------------------------------------------------------------- /shopinvader/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Erreur 500 - Une erreur technique est survenue 11 | 12 | 13 | 14 | 15 | 67 | 68 | 69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |

Le site à rencontré une erreur.

82 |
83 |

Nos techniciens mettent tout en oeuvre pour que le site soit de nouveau accessible au plus vite.
84 | Nous vous invitons à réessayer ultérieurement.

85 |
86 |
87 |
88 |
89 | 98 |
99 |
100 |
101 | 102 | 103 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/locomotive.rb: -------------------------------------------------------------------------------- 1 | Locomotive.configure do |config| 2 | 3 | # enable it if you want Locomotive to render the site of the Rails application embedding the engine 4 | #if Rails.env.production? 5 | # config.host = 'beta.locomotive.works' 6 | #end 7 | 8 | # list of forbidden handles for a site because there are in conflicts with internal resources. 9 | # config.reserved_site_handles = %w(sites my_account password sign_in sign_out) 10 | 11 | # list of domains which can't be used by any Locomotive sites 12 | # config.reserved_domains = [] 13 | 14 | # configure how many items we display in sub menu in the "Models" section. 15 | config.ui = { 16 | per_page: 10 17 | } 18 | 19 | # default locale (for now, only en, de, fr, pl, pt, pt-BR, it, nl, nb, ja, cs, bg, sk, sv and uk are supported) 20 | config.default_locale = :en 21 | 22 | # locales allowed for the back-office UI 23 | config.locales = [:en, :fr, :de, :"zh-CN", :cs, :el, :lt, :"pt-BR", :nl, :ru, :it] 24 | 25 | # available locales suggested to "localize" a site. You will have to pick up at least one among that list. 26 | # sadly mongodb have index limitation we need to restrict the index used here 27 | if ENV["LOCOMOTIVE_SITE_ALLOWED_LOCALES"].present? 28 | config.site_locales = ENV["LOCOMOTIVE_SITE_ALLOWED_LOCALES"].split(",") 29 | else 30 | config.site_locales = %w{en de fr es pt it nl} 31 | end 32 | 33 | # tell if logs of the Engine (back-office) are enabled. Useful for debug purpose. 34 | config.enable_logs = true 35 | 36 | # setup the logger for Steam (rendering) 37 | # config.steam_log_file = ENV['LOCOMOTIVE_STEAM_LOG'] || Rails.root.join('log', 'steam.log') 38 | config.steam_log_level = ::Logger::INFO 39 | 40 | # the API authentication requires to developer to pass 2 params in the header 41 | # of the request: X-Locomotive-Account-Email and X-Locomotive-Token. 42 | # However, to keep backward compatability with v2.x versions, you can use 43 | # the "token" request param instead although it is considered unsafe. 44 | config.unsafe_token_authentication = false 45 | 46 | # Uncomment this line to force Locomotive to redirect all requests in the 47 | # back-office to https in production. 48 | config.enable_admin_ssl = (ENV['LOCOMOTIVE_ADMIN_SSL_REDIRECT'] || 'true') == 'true' 49 | 50 | # Configure the e-mail address which will be shown in the DeviseMailer, NotificationMailer, ...etc 51 | # if you do not put the domain name in the email, Locomotive will take the default domain name depending 52 | # on your deployment target (server, Heroku, Bushido, ...etc) 53 | # 54 | # Ex: 55 | # config.mailer_sender = 'support' 56 | config.mailer_sender = ENV['SMTP_SENDER'] 57 | 58 | # Add the checksum of a theme asset at the end of its path to allow public caching. 59 | # By default, it's disabled. 60 | # 61 | # config.theme_assets_checksum = true 62 | 63 | # Rack-cache settings, mainly used for the inline resizing image module. Default options: 64 | # config.rack_cache = { 65 | # verbose: true, 66 | # metastore: URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/meta"), # URI encoded in case of spaces 67 | # entitystore: URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/body") 68 | # } 69 | # If you do want to disable it for good, just use the following syntax 70 | # config.rack_cache = false 71 | # 72 | # Note: by default, rack/cache is disabled in the Heroku platform 73 | 74 | # Dragonfly within Steam uses it to generate the protective SHA 75 | config.steam_image_resizer_secret = ENV['DRAGON_FLY_SECRET'] 76 | 77 | # Indicate whether you want to allow users to register with the site. If set 78 | # to false the registration page will not be shown. (Default: true) 79 | 80 | config.enable_registration = ENV['LOCOMOTIVE_ENABLE_REGISTRATION'] == 'true' 81 | 82 | end 83 | -------------------------------------------------------------------------------- /shopinvader/config/locales/devise.en.yml: -------------------------------------------------------------------------------- 1 | # Additional translations at https://github.com/plataformatec/devise/wiki/I18n 2 | 3 | en: 4 | devise: 5 | confirmations: 6 | confirmed: "Your email address has been successfully confirmed." 7 | send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes." 8 | 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." 9 | failure: 10 | already_authenticated: "You are already signed in." 11 | inactive: "Your account is not activated yet." 12 | invalid: "Invalid %{authentication_keys} or password." 13 | locked: "Your account is locked." 14 | last_attempt: "You have one more attempt before your account is locked." 15 | not_found_in_database: "Invalid %{authentication_keys} or password." 16 | timeout: "Your session expired. Please sign in again to continue." 17 | unauthenticated: "You need to sign in or sign up before continuing." 18 | unconfirmed: "You have to confirm your email address before continuing." 19 | mailer: 20 | confirmation_instructions: 21 | subject: "Confirmation instructions" 22 | reset_password_instructions: 23 | subject: "Reset password instructions" 24 | unlock_instructions: 25 | subject: "Unlock instructions" 26 | email_changed: 27 | subject: "Email Changed" 28 | password_change: 29 | subject: "Password Changed" 30 | omniauth_callbacks: 31 | failure: "Could not authenticate you from %{kind} because \"%{reason}\"." 32 | success: "Successfully authenticated from %{kind} account." 33 | passwords: 34 | 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." 35 | send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes." 36 | 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." 37 | updated: "Your password has been changed successfully. You are now signed in." 38 | updated_not_active: "Your password has been changed successfully." 39 | registrations: 40 | destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon." 41 | signed_up: "Welcome! You have signed up successfully." 42 | signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." 43 | signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." 44 | 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." 45 | update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address." 46 | updated: "Your account has been updated successfully." 47 | sessions: 48 | signed_in: "Signed in successfully." 49 | signed_out: "Signed out successfully." 50 | already_signed_out: "Signed out successfully." 51 | unlocks: 52 | send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes." 53 | send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes." 54 | unlocked: "Your account has been unlocked successfully. Please sign in to continue." 55 | errors: 56 | messages: 57 | already_confirmed: "was already confirmed, please try signing in" 58 | confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" 59 | expired: "has expired, please request a new one" 60 | not_found: "not found" 61 | not_locked: "was not locked" 62 | not_saved: 63 | one: "1 error prohibited this %{resource} from being saved:" 64 | other: "%{count} errors prohibited this %{resource} from being saved:" 65 | -------------------------------------------------------------------------------- /shopinvader/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # Code is not reloaded between requests. 7 | config.cache_classes = true 8 | 9 | # Eager load code on boot. This eager loads most of Rails and 10 | # your application in memory, allowing both threaded web servers 11 | # and those relying on copy on write to perform better. 12 | # Rake tasks automatically ignore this option for performance. 13 | config.eager_load = true 14 | 15 | # Full error reports are disabled and caching is turned on. 16 | config.consider_all_requests_local = false 17 | config.action_controller.perform_caching = true 18 | 19 | # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] 20 | # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). 21 | # config.require_master_key = true 22 | 23 | # Disable serving static files from the `/public` folder by default since 24 | # Apache or NGINX already handles this. 25 | config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? 26 | 27 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 28 | # config.asset_host = "http://assets.example.com" 29 | config.action_controller.asset_host = ENV['CDN_ASSET_HOST'] 30 | 31 | config.assets.compile = false 32 | 33 | # Specifies the header that your server uses for sending files. 34 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache 35 | # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX 36 | 37 | # Mount Action Cable outside main process or domain. 38 | # config.action_cable.mount_path = nil 39 | # config.action_cable.url = "wss://example.com/cable" 40 | # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] 41 | 42 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 43 | # config.force_ssl = true 44 | 45 | # Include generic and useful information about system operation, but avoid logging too much 46 | # information to avoid inadvertent exposure of personally identifiable information (PII). 47 | config.log_level = :info 48 | 49 | # Prepend all log lines with the following tags. 50 | config.log_tags = [ :request_id ] 51 | 52 | # Use a different cache store in production. 53 | # config.cache_store = :mem_cache_store 54 | 55 | # Use a real queuing backend for Active Job (and separate queues per environment). 56 | # config.active_job.queue_adapter = :resque 57 | # config.active_job.queue_name_prefix = "locomotiveapp_production" 58 | 59 | config.action_mailer.perform_caching = false 60 | 61 | config.action_mailer.delivery_method = :smtp 62 | config.action_mailer.perform_deliveries = true 63 | config.action_mailer.smtp_settings = { 64 | :user_name => ENV["SMTP_USERNAME"], 65 | :password => ENV["SMTP_PASSWORD"], 66 | :address => ENV["SMTP_ADDRESS"], 67 | :port => ENV["SMTP_PORT"], 68 | :authentication => ENV["SMTP_AUTHENTICATION"] || :plain, 69 | :enable_starttls_auto => (ENV['SMTP_ENABLE_STARTTLS_AUTO'] || "true") == "true" 70 | } 71 | if ENV["SMTP_HELO_DOMAIN"].present? 72 | config.action_mailer.smtp_settings[:domain] = ENV["SMTP_HELO_DOMAIN"] 73 | end 74 | 75 | # Ignore bad email addresses and do not raise email delivery errors. 76 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 77 | # config.action_mailer.raise_delivery_errors = false 78 | 79 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 80 | # the I18n.default_locale when a translation cannot be found). 81 | config.i18n.fallbacks = true 82 | 83 | # Don't log any deprecations. 84 | config.active_support.report_deprecations = false 85 | 86 | # Use default logging formatter so that PID and timestamp are not suppressed. 87 | config.log_formatter = ::Logger::Formatter.new 88 | 89 | # Use a different logger for distributed setups. 90 | # require "syslog/logger" 91 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new "app-name") 92 | 93 | if ENV["RAILS_LOG_TO_STDOUT"].present? 94 | logger = ActiveSupport::Logger.new(STDOUT) 95 | logger.formatter = config.log_formatter 96 | config.logger = ActiveSupport::TaggedLogging.new(logger) 97 | end 98 | 99 | if ENV["ALLOWED_HOSTS"].present? 100 | config.hosts += ENV["ALLOWED_HOSTS"].split(",") 101 | end 102 | 103 | allowed_hosts_regex = ENV.fetch('ALLOWED_HOSTS_REGEX', '').split(',') 104 | allowed_hosts_regex.each do |regex| 105 | config.hosts << Regexp.new(regex.strip) 106 | end 107 | 108 | end 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shopinvader container ready for deployment 2 | 3 | This is the official container for shopinvader 4 | 5 | ## How to use this image 6 | 7 | 1. copy the file `docker-compose.yml` of this directory in your project folder 8 | 2. copy `.loco-data` folder to your project folder and add ignore its content in .gitignore 9 | 3. Run it with ```docker-compose up```. 10 | 4. Locomotive is now available on http://localhost:3000 11 | 12 | 13 | # Develop / Debug 14 | 15 | ## Static files served from AWS S3 16 | 17 | If you are using amazon S3 for storing your asset you need to download them in dev mode. 18 | 19 | Before please install aws cli and read the documentation. 20 | 21 | In short for installing aws and configuring the api key 22 | ``` 23 | sudo apt install awscli 24 | aws configure 25 | ``` 26 | 27 | Now let's synchronise the assets 28 | 29 | ``` 30 | aws s3 sync s3://mybucket/sites .loco-data/public/sites 31 | aws s3 sync s3://mybucket/uploaded_assets .loco-data/public/uploaded_assets 32 | 33 | ``` 34 | 35 | ## Locomotive theme development 36 | 37 | The `docker-compose.yml` here provides a `wagon` container as well. 38 | `wagon` is the LocomotiveCMS service to deploy resources to a Locomotive site 39 | or to develop your own theme. 40 | 41 | To run it: 42 | 43 | ``` 44 | $ docker-compose run --service-ports wagon gosu ubuntu bash 45 | ``` 46 | From there you'll be able to run all wagon commands without having to install wagon by yourself. 47 | See https://doc.locomotivecms.com/docs (just skip wagon installation steps). 48 | 49 | NOTE: to make wagon work, the docker-compose file should stay inside your Locomotive theme folder. 50 | Otherwise you'll have to change the workspace volume. 51 | 52 | # Available Environement Variables 53 | 54 | ## Locomotive configuration 55 | 56 | ### ALLOWED_HOSTS 57 | 58 | If you want to reach the server with a domain that is not in the list of existing website on your locomotive 59 | you can allow specific domain like this: 60 | 61 | ``` 62 | ALLOWED_HOSTS=foo1.exemple.org,10.10.10.82:3000,localhost:3000 63 | ``` 64 | 65 | You can also add regex 66 | 67 | ``` 68 | ALLOWED_HOSTS_REGEX=10\.0\.[012]\.\d+ 69 | ``` 70 | 71 | 72 | 73 | ### LOCOMOTIVE_ENABLE_REGISTRATION 74 | 75 | ``` 76 | LOCOMOTIVE_ENABLE_REGISTRATION=[true|false] (default: false) 77 | ``` 78 | Enables self registration on Locomotive admin backend. 79 | 80 | ### LOCOMOTIVE_ADMIN_SSL_REDIRECT 81 | 82 | ``` 83 | LOCOMOTIVE_ADMIN_SSL_REDIRECT=[true|false] (default: true) 84 | ``` 85 | Force redirection of admin backend to HTTPS. 86 | 87 | ### LOCOMOTIVE_SITE_ALLOWED_LOCALES 88 | 89 | LOCOMOTIVE_SITE_ALLOWED_LOCALES="fr,ca,es" 90 | 91 | Note: be carefull if you add too many lang (more than 7) you can reach some index limitation on mongodb 92 | 93 | If not defined then allowed lang are the following: "en,de,fr,es,pt,it,nl" 94 | 95 | ## RAILS configuration 96 | 97 | ### RAILS_ENV 98 | ``` 99 | RAILS_ENV=[production|development] 100 | ``` 101 | Tells RoR which kind of env your are working with. 102 | 103 | ### SECRET_BASE 104 | ``` 105 | SECRET_KEY_BASE=6810991e8c119bdfe5f4dd[...]d88d1a5bcb69d6ed0cdc19892 106 | ``` 107 | This key is used to encrypt important data such as cookies and user passwords. 108 | You can generate one by running this command: 109 | ``` 110 | $ docker-compose run --rm locomotive rake secret 111 | ``` 112 | 113 | As it's used to encode passwords, if you restore a DB locally you must config this otherwise you won't be able login. 114 | The other option is to reset the passwords for admin users. 115 | NOTE: website users are not the same as backend users. 116 | 117 | For more info https://medium.com/@michaeljcoyne/understanding-the-secret-key-base-in-ruby-on-rails-ce2f6f9968a1 118 | 119 | ### DEVISE_PEPPER 120 | 121 | ``` 122 | DEVISE_PEPPER=myExtraSecret 123 | ``` 124 | This is "a string which is appended onto the password pre-hashing but not stored in the database (unlike salt, which is appended as well but stored with the password in the DB); and cost, a measure of how secure the hash should be (see the docs). Both of these are static and you can hard-code them into your non-Devise app (but make sure to keep pepper secret!)." 125 | 126 | For more information: 127 | 128 | * https://stackoverflow.com/questions/45988723/what-password-hashing-algorithm-does-devise-use 129 | * https://github.com/plataformatec/devise/blob/88724e10adaf9ffd1d8dbfbaadda2b9d40de756a/lib/devise/encryptor.rb 130 | 131 | 132 | ### DRAGON_FLY_SECRET 133 | 134 | ``` 135 | DRAGON_FLY_SECRET=b75886dec470b846594[...]fe3e7a244b61242b6cec04 136 | ``` 137 | This key is used to used to generate the protective SHA. 138 | See dragonfly configuration for more information: http://markevans.github.io/dragonfly/configuration 139 | You can generate one by running this command: 140 | ``` 141 | $ docker-compose run --rm locomotive rake secret 142 | ``` 143 | 144 | ### RAILS_SERVE_STATIC_FILES 145 | 146 | ``` 147 | RAILS_SERVE_STATIC_FILES=[true|false] (default: false) 148 | ``` 149 | 150 | ## MongoDB configuration 151 | 152 | MONGODB_URI 153 | MONGODB_MAX_POOL_SIZE (default: 5) 154 | 155 | ## PUMA configuration 156 | 157 | ``` 158 | PUMA_MIN_THREAD 159 | PUMA_MAX_THREAD 160 | PUMA_WORKER 161 | PUMA_AUTH_TOKEN 162 | PUMA_MAX_RAM (default 4096Mo) 163 | ``` 164 | 165 | ## Configuration for storing the asset in amazon S3 166 | 167 | ``` 168 | S3_BUCKET 169 | S3_KEY_ID 170 | S3_SECRET_KEY 171 | S3_BUCKET_REGION 172 | S3_ASSET_HOST_URL 173 | S3_CACHE_CONTROL 174 | S3_ENDPOINT (optionnal: usefull when using S3 compatible provider) 175 | S3_PATH_STYLE (optionnal: required by some S3 compatible provider like Minio) 176 | ``` 177 | 178 | ## SMTP configuration 179 | 180 | ``` 181 | SMTP_ENABLE_STARTTLS_AUTO (default True) 182 | SMTP_HELO_DOMAIN 183 | SMTP_ADDRESS 184 | SMTP_PORT 185 | SMTP_SENDER 186 | SMTP_USERNAME 187 | SMTP_PASSWORD 188 | SMTP_AUTHENTICATION (default plain) 189 | ``` 190 | 191 | ## Sentry configuration 192 | 193 | ``` 194 | SENTRY_DSN 195 | ``` 196 | 197 | ## Rake task 198 | 199 | Locomotive include several maintance task based on rake 200 | 201 | You can list all of them using 202 | 203 | ``` 204 | rake -T 205 | 206 | ``` 207 | 208 | ### Index generation 209 | ``` 210 | rake db:mongoid:create_indexes 211 | ``` 212 | 213 | ### Purge old session 214 | 215 | In mongo db sheeh you can purge the old session using (TODO we should do a rake task) 216 | 217 | ``` 218 | db.getCollection("sessions").deleteMany({"updated_at": {$lt:ISODate("2023-12-06")}}) 219 | ``` 220 | 221 | 222 | 223 | # TODO 224 | - improve configuration of allowed lang in front and limitation of indexing with mongodb 225 | - improve log managment (ready for kibana) 226 | -------------------------------------------------------------------------------- /shopinvader/config/mongoid.yml: -------------------------------------------------------------------------------- 1 | production: 2 | clients: 3 | default: 4 | uri: <%= ENV['MONGODB_URI'] %> 5 | options: 6 | # consistency: :strong 7 | # identity_map_enabled: true 8 | max_pool_size: <%= ENV['MONGODB_MAX_POOL_SIZE'] || 5 %> 9 | development: 10 | # Configure available database clients. (required) 11 | clients: 12 | # Defines the default client. (required) 13 | default: 14 | # Defines the name of the default database that Mongoid can connect to. 15 | # (required). 16 | database: shopinvader 17 | # Provides the hosts the default client can connect to. Must be an array 18 | # of host:port pairs. (required) 19 | hosts: 20 | - <%= ENV['MONGODB_DEV_HOST'] || 'db' %>:27017 21 | options: 22 | # Change the default write concern. (default = { w: 1 }) 23 | # write: 24 | # w: 1 25 | 26 | # Change the default read preference. Valid options for mode are: :secondary, 27 | # :secondary_preferred, :primary, :primary_preferred, :nearest 28 | # (default: primary) 29 | # read: 30 | # mode: :secondary_preferred 31 | # tag_sets: 32 | # - use: web 33 | 34 | # The name of the user for authentication. 35 | # user: 'user' 36 | 37 | # The password of the user for authentication. 38 | # password: 'password' 39 | 40 | # The user's database roles. 41 | # roles: 42 | # - 'dbOwner' 43 | 44 | # Change the default authentication mechanism. Valid options are: :scram, 45 | # :mongodb_cr, :mongodb_x509, and :plain. Note that all authentication 46 | # mechanisms require username and password, with the exception of :mongodb_x509. 47 | # Default on mongoDB 3.0 is :scram, default on 2.4 and 2.6 is :plain. 48 | # auth_mech: :scram 49 | 50 | # The database or source to authenticate the user against. 51 | # (default: the database specified above or admin) 52 | # auth_source: admin 53 | 54 | # Force a the driver cluster to behave in a certain manner instead of auto- 55 | # discovering. Can be one of: :direct, :replica_set, :sharded. Set to :direct 56 | # when connecting to hidden members of a replica set. 57 | # connect: :direct 58 | 59 | # Changes the default time in seconds the server monitors refresh their status 60 | # via ismaster commands. (default: 10) 61 | # heartbeat_frequency: 10 62 | 63 | # The time in seconds for selecting servers for a near read preference. (default: 0.015) 64 | # local_threshold: 0.015 65 | 66 | # The timeout in seconds for selecting a server for an operation. (default: 30) 67 | # server_selection_timeout: 30 68 | 69 | # The maximum number of connections in the connection pool. (default: 5) 70 | # max_pool_size: 5 71 | 72 | # The minimum number of connections in the connection pool. (default: 1) 73 | # min_pool_size: 1 74 | 75 | # The time to wait, in seconds, in the connection pool for a connection 76 | # to be checked in before timing out. (default: 5) 77 | # wait_queue_timeout: 5 78 | 79 | # The time to wait to establish a connection before timing out, in seconds. 80 | # (default: 5) 81 | # connect_timeout: 5 82 | 83 | # The timeout to wait to execute operations on a socket before raising an error. 84 | # (default: 5) 85 | # socket_timeout: 5 86 | 87 | # The name of the replica set to connect to. Servers provided as seeds that do 88 | # not belong to this replica set will be ignored. 89 | # replica_set: name 90 | 91 | # Whether to connect to the servers via ssl. (default: false) 92 | # ssl: true 93 | 94 | # The certificate file used to identify the connection against MongoDB. 95 | # ssl_cert: /path/to/my.cert 96 | 97 | # The private keyfile used to identify the connection against MongoDB. 98 | # Note that even if the key is stored in the same file as the certificate, 99 | # both need to be explicitly specified. 100 | # ssl_key: /path/to/my.key 101 | 102 | # A passphrase for the private key. 103 | # ssl_key_pass_phrase: password 104 | 105 | # Whether or not to do peer certification validation. (default: true) 106 | # ssl_verify: true 107 | 108 | # The file containing a set of concatenated certification authority certifications 109 | # used to validate certs passed from the other end of the connection. 110 | # ssl_ca_cert: /path/to/ca.cert 111 | 112 | 113 | # Configure Mongoid specific options. (optional) 114 | options: 115 | # Includes the root model name in json serialization. (default: false) 116 | # include_root_in_json: false 117 | 118 | # Include the _type field in serialization. (default: false) 119 | # include_type_for_serialization: false 120 | 121 | # Preload all models in development, needed when models use 122 | # inheritance. (default: false) 123 | # preload_models: false 124 | 125 | # Raise an error when performing a #find and the document is not found. 126 | # (default: true) 127 | # raise_not_found_error: true 128 | 129 | # Raise an error when defining a scope with the same name as an 130 | # existing method. (default: false) 131 | # scope_overwrite_exception: false 132 | 133 | # Raise an error when defining a field with the same name as an 134 | # existing method. (default: false) 135 | # duplicate_fields_exception: false 136 | 137 | # Use Active Support's time zone in conversions. (default: true) 138 | # use_activesupport_time_zone: true 139 | 140 | # Ensure all times are UTC in the app side. (default: false) 141 | # use_utc: false 142 | 143 | # Set the Mongoid and Ruby driver log levels when not in a Rails 144 | # environment. The Mongoid logger will be set to the Rails logger 145 | # otherwise.(default: :info) 146 | # log_level: :info 147 | 148 | # Control whether `belongs_to` association is required. By default 149 | # `belongs_to` will trigger a validation error if the association 150 | # is not present. (default: true) 151 | # belongs_to_required_by_default: true 152 | 153 | # Application name that is printed to the mongodb logs upon establishing a 154 | # connection in server versions >= 3.4. Note that the name cannot exceed 128 bytes. 155 | # app_name: MyApplicationName 156 | test: 157 | clients: 158 | default: 159 | database: shopinvader_test 160 | hosts: 161 | - db:27017 162 | options: 163 | read: 164 | mode: :primary 165 | max_pool_size: 1 166 | -------------------------------------------------------------------------------- /shopinvader/config/initializers/devise.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Use this hook to configure devise mailer, warden hooks and so forth. 4 | # Many of these configuration options can be set straight in your model. 5 | Devise.setup do |config| 6 | # The secret key used by Devise. Devise uses this key to generate 7 | # random tokens. Changing this key will render invalid all existing 8 | # confirmation, reset password and unlock tokens in the database. 9 | # Devise will use the `secret_key_base` as its `secret_key` 10 | # by default. You can change it below and use your own secret key. 11 | # config.secret_key = 'd039eaba25b8f421bf260604c5e7152b6bfd7266d946c43cf7b5397c81290293593052837f16cf9521756e2e045faaa44ed9dae8259452fd631a97709f85481a' 12 | 13 | # ==> Mailer Configuration 14 | # Configure the e-mail address which will be shown in Devise::Mailer, 15 | # note that it will be overwritten if you use your own mailer class 16 | # with default "from" parameter. 17 | # config.mailer_sender = ENV['SMTP_SENDER'] 18 | 19 | # Configure the class responsible to send e-mails. 20 | # config.mailer = 'Devise::Mailer' 21 | 22 | # Configure the parent class responsible to send e-mails. 23 | # config.parent_mailer = 'ActionMailer::Base' 24 | 25 | # ==> ORM configuration 26 | # Load and configure the ORM. Supports :active_record (default) and 27 | # :mongoid (bson_ext recommended) by default. Other ORMs may be 28 | # available as additional gems. 29 | require 'devise/orm/mongoid' 30 | 31 | # ==> Configuration for any authentication mechanism 32 | # Configure which keys are used when authenticating a user. The default is 33 | # just :email. You can configure it to use [:username, :subdomain], so for 34 | # authenticating a user, both parameters are required. Remember that those 35 | # parameters are used only when authenticating and not when retrieving from 36 | # session. If you need permissions, you should implement that in a before filter. 37 | # You can also supply a hash where the value is a boolean determining whether 38 | # or not authentication should be aborted when the value is not present. 39 | # config.authentication_keys = [:email] 40 | 41 | # Configure parameters from the request object used for authentication. Each entry 42 | # given should be a request method and it will automatically be passed to the 43 | # find_for_authentication method and considered in your model lookup. For instance, 44 | # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. 45 | # The same considerations mentioned for authentication_keys also apply to request_keys. 46 | # config.request_keys = [] 47 | 48 | # Configure which authentication keys should be case-insensitive. 49 | # These keys will be downcased upon creating or modifying a user and when used 50 | # to authenticate or find a user. Default is :email. 51 | config.case_insensitive_keys = [:email] 52 | 53 | # Configure which authentication keys should have whitespace stripped. 54 | # These keys will have whitespace before and after removed upon creating or 55 | # modifying a user and when used to authenticate or find a user. Default is :email. 56 | config.strip_whitespace_keys = [:email] 57 | 58 | # Tell if authentication through request.params is enabled. True by default. 59 | # It can be set to an array that will enable params authentication only for the 60 | # given strategies, for example, `config.params_authenticatable = [:database]` will 61 | # enable it only for database (email + password) authentication. 62 | # config.params_authenticatable = true 63 | 64 | # Tell if authentication through HTTP Auth is enabled. False by default. 65 | # It can be set to an array that will enable http authentication only for the 66 | # given strategies, for example, `config.http_authenticatable = [:database]` will 67 | # enable it only for database authentication. The supported strategies are: 68 | # :database = Support basic authentication with authentication key + password 69 | # config.http_authenticatable = false 70 | 71 | # If 401 status code should be returned for AJAX requests. True by default. 72 | # config.http_authenticatable_on_xhr = true 73 | 74 | # The realm used in Http Basic Authentication. 'Application' by default. 75 | # config.http_authentication_realm = 'Application' 76 | 77 | # It will change confirmation, password recovery and other workflows 78 | # to behave the same regardless if the e-mail provided was right or wrong. 79 | # Does not affect registerable. 80 | # config.paranoid = true 81 | 82 | # By default Devise will store the user in session. You can skip storage for 83 | # particular strategies by setting this option. 84 | # Notice that if you are skipping storage for all authentication paths, you 85 | # may want to disable generating routes to Devise's sessions controller by 86 | # passing skip: :sessions to `devise_for` in your config/routes.rb 87 | config.skip_session_storage = [:http_auth] 88 | 89 | # By default, Devise cleans up the CSRF token on authentication to 90 | # avoid CSRF token fixation attacks. This means that, when using AJAX 91 | # requests for sign in and sign up, you need to get a new CSRF token 92 | # from the server. You can disable this option at your own risk. 93 | # config.clean_up_csrf_token_on_authentication = true 94 | 95 | # When false, Devise will not attempt to reload routes on eager load. 96 | # This can reduce the time taken to boot the app but if your application 97 | # requires the Devise mappings to be loaded during boot time the application 98 | # won't boot properly. 99 | # config.reload_routes = true 100 | 101 | # ==> Configuration for :database_authenticatable 102 | # For bcrypt, this is the cost for hashing the password and defaults to 11. If 103 | # using other algorithms, it sets how many times you want the password to be hashed. 104 | # 105 | # Limiting the stretches to just one in testing will increase the performance of 106 | # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use 107 | # a value less than 10 in other environments. Note that, for bcrypt (the default 108 | # algorithm), the cost increases exponentially with the number of stretches (e.g. 109 | # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). 110 | config.stretches = Rails.env.test? ? 1 : 11 111 | 112 | # Set up a pepper to generate the hashed password. 113 | config.pepper = ENV['DEVISE_PEPPER'] 114 | 115 | # Send a notification to the original email when the user's email is changed. 116 | # config.send_email_changed_notification = false 117 | 118 | # Send a notification email when the user's password is changed. 119 | # config.send_password_change_notification = false 120 | 121 | # ==> Configuration for :confirmable 122 | # A period that the user is allowed to access the website even without 123 | # confirming their account. For instance, if set to 2.days, the user will be 124 | # able to access the website for two days without confirming their account, 125 | # access will be blocked just in the third day. Default is 0.days, meaning 126 | # the user cannot access the website without confirming their account. 127 | # config.allow_unconfirmed_access_for = 2.days 128 | 129 | # A period that the user is allowed to confirm their account before their 130 | # token becomes invalid. For example, if set to 3.days, the user can confirm 131 | # their account within 3 days after the mail was sent, but on the fourth day 132 | # their account can't be confirmed with the token any more. 133 | # Default is nil, meaning there is no restriction on how long a user can take 134 | # before confirming their account. 135 | # config.confirm_within = 3.days 136 | 137 | # If true, requires any email changes to be confirmed (exactly the same way as 138 | # initial account confirmation) to be applied. Requires additional unconfirmed_email 139 | # db field (see migrations). Until confirmed, new email is stored in 140 | # unconfirmed_email column, and copied to email column on successful confirmation. 141 | config.reconfirmable = true 142 | 143 | # Defines which key will be used when confirming an account 144 | # config.confirmation_keys = [:email] 145 | 146 | # ==> Configuration for :rememberable 147 | # The time the user will be remembered without asking for credentials again. 148 | # config.remember_for = 2.weeks 149 | 150 | # Invalidates all the remember me tokens when the user signs out. 151 | config.expire_all_remember_me_on_sign_out = true 152 | 153 | # If true, extends the user's remember period when remembered via cookie. 154 | # config.extend_remember_period = false 155 | 156 | # Options to be passed to the created cookie. For instance, you can set 157 | # secure: true in order to force SSL only cookies. 158 | # config.rememberable_options = {} 159 | 160 | # ==> Configuration for :validatable 161 | # Range for password length. 162 | config.password_length = 6..128 163 | 164 | # Email regex used to validate email formats. It simply asserts that 165 | # one (and only one) @ exists in the given string. This is mainly 166 | # to give user feedback and not to assert the e-mail validity. 167 | config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ 168 | 169 | # ==> Configuration for :timeoutable 170 | # The time you want to timeout the user session without activity. After this 171 | # time the user will be asked for credentials again. Default is 30 minutes. 172 | # config.timeout_in = 30.minutes 173 | 174 | # ==> Configuration for :lockable 175 | # Defines which strategy will be used to lock an account. 176 | # :failed_attempts = Locks an account after a number of failed attempts to sign in. 177 | # :none = No lock strategy. You should handle locking by yourself. 178 | # config.lock_strategy = :failed_attempts 179 | 180 | # Defines which key will be used when locking and unlocking an account 181 | # config.unlock_keys = [:email] 182 | 183 | # Defines which strategy will be used to unlock an account. 184 | # :email = Sends an unlock link to the user email 185 | # :time = Re-enables login after a certain amount of time (see :unlock_in below) 186 | # :both = Enables both strategies 187 | # :none = No unlock strategy. You should handle unlocking by yourself. 188 | # config.unlock_strategy = :both 189 | 190 | # Number of authentication tries before locking an account if lock_strategy 191 | # is failed attempts. 192 | # config.maximum_attempts = 20 193 | 194 | # Time interval to unlock the account if :time is enabled as unlock_strategy. 195 | # config.unlock_in = 1.hour 196 | 197 | # Warn on the last attempt before the account is locked. 198 | # config.last_attempt_warning = true 199 | 200 | # ==> Configuration for :recoverable 201 | # 202 | # Defines which key will be used when recovering the password for an account 203 | # config.reset_password_keys = [:email] 204 | 205 | # Time interval you can reset your password with a reset password key. 206 | # Don't put a too small interval or your users won't have the time to 207 | # change their passwords. 208 | config.reset_password_within = 6.hours 209 | 210 | # When set to false, does not sign a user in automatically after their password is 211 | # reset. Defaults to true, so a user is signed in automatically after a reset. 212 | # config.sign_in_after_reset_password = true 213 | 214 | # ==> Configuration for :encryptable 215 | # Allow you to use another hashing or encryption algorithm besides bcrypt (default). 216 | # You can use :sha1, :sha512 or algorithms from others authentication tools as 217 | # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20 218 | # for default behavior) and :restful_authentication_sha1 (then you should set 219 | # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper). 220 | # 221 | # Require the `devise-encryptable` gem when using anything other than bcrypt 222 | # config.encryptor = :sha512 223 | 224 | # ==> Scopes configuration 225 | # Turn scoped views on. Before rendering "sessions/new", it will first check for 226 | # "users/sessions/new". It's turned off by default because it's slower if you 227 | # are using only default views. 228 | # config.scoped_views = false 229 | 230 | # Configure the default scope given to Warden. By default it's the first 231 | # devise role declared in your routes (usually :user). 232 | # config.default_scope = :user 233 | 234 | # Set this configuration to false if you want /users/sign_out to sign out 235 | # only the current scope. By default, Devise signs out all scopes. 236 | # config.sign_out_all_scopes = true 237 | 238 | # ==> Navigation configuration 239 | # Lists the formats that should be treated as navigational. Formats like 240 | # :html, should redirect to the sign in page when the user does not have 241 | # access, but formats like :xml or :json, should return 401. 242 | # 243 | # If you have any extra navigational formats, like :iphone or :mobile, you 244 | # should add them to the navigational formats lists. 245 | # 246 | # The "*/*" below is required to match Internet Explorer requests. 247 | # config.navigational_formats = ['*/*', :html] 248 | 249 | # The default HTTP method used to sign out a resource. Default is :delete. 250 | config.sign_out_via = :delete 251 | 252 | # ==> OmniAuth 253 | # Add a new OmniAuth provider. Check the wiki for more information on setting 254 | # up on your models and hooks. 255 | # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' 256 | 257 | # ==> Warden configuration 258 | # If you want to use other strategies, that are not supported by Devise, or 259 | # change the failure app, you can configure them inside the config.warden block. 260 | # 261 | # config.warden do |manager| 262 | # manager.intercept_401 = false 263 | # manager.default_strategies(scope: :user).unshift :some_external_strategy 264 | # end 265 | 266 | # ==> Mountable engine configurations 267 | # When using Devise inside an engine, let's call it `MyEngine`, and this engine 268 | # is mountable, there are some extra configurations to be taken into account. 269 | # The following options are available, assuming the engine is mounted as: 270 | # 271 | # mount MyEngine, at: '/my_engine' 272 | # 273 | # The router that invoked `devise_for`, in the example above, would be: 274 | # config.router_name = :my_engine 275 | # 276 | # When using OmniAuth, Devise cannot automatically set OmniAuth path, 277 | # so you need to do it manually. For the users scope, it would be: 278 | # config.omniauth_path_prefix = '/my_engine/users/auth' 279 | end 280 | -------------------------------------------------------------------------------- /shopinvader/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GIT 2 | remote: https://github.com/locomotivecms/common.git 3 | revision: c78da1584e1f2fdf9c7382b4cb03dcb4d8ae4387 4 | ref: c78da158 5 | specs: 6 | locomotivecms_common (0.6.0.alpha1) 7 | activesupport (>= 5) 8 | attr_extras (~> 7.1.0) 9 | colorize 10 | stringex (~> 2.8.5) 11 | 12 | GIT 13 | remote: https://github.com/locomotivecms/custom_fields.git 14 | revision: 87bf1b389dcb710f3261abb3380a6da97cad1095 15 | ref: 87bf1b 16 | specs: 17 | custom_fields (2.14.0.alpha1) 18 | activesupport (>= 7, < 8.0) 19 | bcrypt (~> 3.1.18) 20 | carrierwave-mongoid (~> 1.4.0) 21 | monetize (~> 1.12.0) 22 | mongoid (>= 7, < 9.0) 23 | 24 | GIT 25 | remote: https://github.com/locomotivecms/engine.git 26 | revision: e6fb512c08f7108eb024b7e56b8f4f153570f78e 27 | ref: e6fb512c 28 | specs: 29 | locomotivecms (4.2.0.alpha2) 30 | actionmailer-with-request (~> 0.5.0) 31 | adomain (~> 0.2.4) 32 | autoprefixer-rails (~> 10.4.13) 33 | bazaar (~> 0.0.2) 34 | bootstrap-kaminari-views (~> 0.0.5) 35 | bootstrap-sass (~> 3.4.1) 36 | carrierwave (~> 1.3.3) 37 | carrierwave-mongoid (~> 1.4.0) 38 | coffee-rails (~> 5.0) 39 | custom_fields (~> 2.14.0.alpha1) 40 | devise (~> 4.9.3) 41 | devise-encryptable (~> 0.2.0) 42 | dragonfly (~> 1.4.0) 43 | flash_cookie_session (~> 1.1.6) 44 | font-awesome-sass (~> 6.3.0) 45 | grape (~> 2.1.3) 46 | grape-entity (~> 0.10.0) 47 | highline (~> 2.1.0) 48 | jbuilder (~> 2.11) 49 | jquery-rails (~> 4.5.1) 50 | jquery-ui-rails (~> 6.0.1) 51 | json-schema (~> 3.0.0) 52 | kaminari-actionview (~> 1.2.2) 53 | kaminari-mongoid (~> 1.0.2) 54 | locomotivecms_steam (~> 1.8.0.alpha1) 55 | mongo (~> 2.19.3) 56 | mongoid (~> 8.0.7) 57 | mongoid-tree (~> 2.2.0) 58 | multi_json (~> 1.15.0) 59 | origin (~> 2.3.1) 60 | pundit (~> 2.3.0) 61 | rack-cache (~> 1.14.0) 62 | rails (>= 7.1) 63 | rails-html-sanitizer (~> 1.6.0) 64 | rails-i18n (~> 7.0.6) 65 | responders (~> 3.1.0) 66 | sass-rails (~> 6.0.0) 67 | simple_form (~> 5.2.0) 68 | simple_token_authentication (~> 1.18.1) 69 | slim (~> 5.0.0) 70 | sprockets-rails (~> 3.4.2) 71 | yajl-ruby (~> 1.4.3) 72 | 73 | GIT 74 | remote: https://github.com/locomotivecms/steam.git 75 | revision: ba10b57b1aabbb434a9202d9296436355c988757 76 | ref: ba10b57b 77 | specs: 78 | locomotivecms_steam (1.8.0.alpha2) 79 | RedCloth (~> 4.3.2) 80 | bcrypt (~> 3.1.11) 81 | chronic (~> 0.10.2) 82 | dragonfly (~> 1.4.0) 83 | duktape (~> 2.0.1.1) 84 | execjs (~> 2.9.1) 85 | httparty (~> 0.22.0) 86 | kramdown (~> 2.3.0) 87 | liquid (~> 4.0.4) 88 | locomotivecms_common (~> 0.6.0.alpha1) 89 | mime-types (~> 3.5.0) 90 | mimetype-fu (~> 0.1.2) 91 | moneta (~> 1.6.0) 92 | morphine (~> 0.1.1) 93 | multi_json (~> 1.15.0) 94 | nokogiri (~> 1.16.7) 95 | parser (~> 3.3) 96 | pony (~> 1.12) 97 | rack-cache (>= 1.7, < 2) 98 | rack-rewrite (~> 1.5.1) 99 | rack-session (~> 2.0.0) 100 | rack_csrf (~> 2.6.0) 101 | sanitize (~> 6.0.1) 102 | 103 | GIT 104 | remote: https://github.com/shopinvader/locomotive-shopinvader.git 105 | revision: effff0501d5d6582f9d096aba837019e1e621147 106 | branch: v4.0.x 107 | specs: 108 | shop_invader (0.1.0) 109 | algoliasearch (~> 1.13.0) 110 | elasticsearch (~> 6.2.0) 111 | faraday (~> 0.17) 112 | jwt (~> 2.2.1) 113 | rack-utm (~> 0.0.2) 114 | 115 | GEM 116 | remote: https://rubygems.org/ 117 | specs: 118 | RedCloth (4.3.4) 119 | actioncable (7.1.4.1) 120 | actionpack (= 7.1.4.1) 121 | activesupport (= 7.1.4.1) 122 | nio4r (~> 2.0) 123 | websocket-driver (>= 0.6.1) 124 | zeitwerk (~> 2.6) 125 | actionmailbox (7.1.4.1) 126 | actionpack (= 7.1.4.1) 127 | activejob (= 7.1.4.1) 128 | activerecord (= 7.1.4.1) 129 | activestorage (= 7.1.4.1) 130 | activesupport (= 7.1.4.1) 131 | mail (>= 2.7.1) 132 | net-imap 133 | net-pop 134 | net-smtp 135 | actionmailer (7.1.4.1) 136 | actionpack (= 7.1.4.1) 137 | actionview (= 7.1.4.1) 138 | activejob (= 7.1.4.1) 139 | activesupport (= 7.1.4.1) 140 | mail (~> 2.5, >= 2.5.4) 141 | net-imap 142 | net-pop 143 | net-smtp 144 | rails-dom-testing (~> 2.2) 145 | actionmailer-with-request (0.5.0) 146 | rails (>= 5) 147 | actionpack (7.1.4.1) 148 | actionview (= 7.1.4.1) 149 | activesupport (= 7.1.4.1) 150 | nokogiri (>= 1.8.5) 151 | racc 152 | rack (>= 2.2.4) 153 | rack-session (>= 1.0.1) 154 | rack-test (>= 0.6.3) 155 | rails-dom-testing (~> 2.2) 156 | rails-html-sanitizer (~> 1.6) 157 | actiontext (7.1.4.1) 158 | actionpack (= 7.1.4.1) 159 | activerecord (= 7.1.4.1) 160 | activestorage (= 7.1.4.1) 161 | activesupport (= 7.1.4.1) 162 | globalid (>= 0.6.0) 163 | nokogiri (>= 1.8.5) 164 | actionview (7.1.4.1) 165 | activesupport (= 7.1.4.1) 166 | builder (~> 3.1) 167 | erubi (~> 1.11) 168 | rails-dom-testing (~> 2.2) 169 | rails-html-sanitizer (~> 1.6) 170 | activejob (7.1.4.1) 171 | activesupport (= 7.1.4.1) 172 | globalid (>= 0.3.6) 173 | activemodel (7.1.4.1) 174 | activesupport (= 7.1.4.1) 175 | activerecord (7.1.4.1) 176 | activemodel (= 7.1.4.1) 177 | activesupport (= 7.1.4.1) 178 | timeout (>= 0.4.0) 179 | activestorage (7.1.4.1) 180 | actionpack (= 7.1.4.1) 181 | activejob (= 7.1.4.1) 182 | activerecord (= 7.1.4.1) 183 | activesupport (= 7.1.4.1) 184 | marcel (~> 1.0) 185 | activesupport (7.1.4.1) 186 | base64 187 | bigdecimal 188 | concurrent-ruby (~> 1.0, >= 1.0.2) 189 | connection_pool (>= 2.2.5) 190 | drb 191 | i18n (>= 1.6, < 2) 192 | minitest (>= 5.1) 193 | mutex_m 194 | tzinfo (~> 2.0) 195 | addressable (2.8.7) 196 | public_suffix (>= 2.0.2, < 7.0) 197 | adomain (0.2.4) 198 | addressable (~> 2.5) 199 | logger 200 | algoliasearch (1.13.0) 201 | httpclient (~> 2.8.3) 202 | json (>= 1.5.1) 203 | ast (2.4.2) 204 | attr_extras (7.1.0) 205 | autoprefixer-rails (10.4.19.0) 206 | execjs (~> 2) 207 | aws-eventstream (1.3.0) 208 | aws-partitions (1.992.0) 209 | aws-sdk-core (3.210.0) 210 | aws-eventstream (~> 1, >= 1.3.0) 211 | aws-partitions (~> 1, >= 1.992.0) 212 | aws-sigv4 (~> 1.9) 213 | jmespath (~> 1, >= 1.6.1) 214 | aws-sdk-kms (1.95.0) 215 | aws-sdk-core (~> 3, >= 3.210.0) 216 | aws-sigv4 (~> 1.5) 217 | aws-sdk-s3 (1.169.0) 218 | aws-sdk-core (~> 3, >= 3.210.0) 219 | aws-sdk-kms (~> 1) 220 | aws-sigv4 (~> 1.5) 221 | aws-sigv4 (1.10.0) 222 | aws-eventstream (~> 1, >= 1.0.2) 223 | base64 (0.2.0) 224 | bazaar (0.0.2) 225 | bcrypt (3.1.20) 226 | bigdecimal (3.1.8) 227 | bootsnap (1.18.4) 228 | msgpack (~> 1.2) 229 | bootstrap-kaminari-views (0.0.5) 230 | kaminari (>= 0.13) 231 | rails (>= 3.1) 232 | bootstrap-sass (3.4.1) 233 | autoprefixer-rails (>= 5.2.1) 234 | sassc (>= 2.0.0) 235 | bson (4.15.0) 236 | builder (3.3.0) 237 | carrierwave (1.3.4) 238 | activemodel (>= 4.0.0) 239 | activesupport (>= 4.0.0) 240 | mime-types (>= 1.16) 241 | ssrf_filter (~> 1.0, < 1.1.0) 242 | carrierwave-aws (1.4.0) 243 | aws-sdk-s3 (~> 1.0) 244 | carrierwave (>= 0.7, < 2.1) 245 | carrierwave-mongoid (1.4.0) 246 | carrierwave (>= 0.8, < 3) 247 | mongoid (>= 3.0, < 9.0) 248 | mongoid-grid_fs (>= 1.3, < 3.0) 249 | chronic (0.10.2) 250 | coffee-rails (5.0.0) 251 | coffee-script (>= 2.2.0) 252 | railties (>= 5.2.0) 253 | coffee-script (2.4.1) 254 | coffee-script-source 255 | execjs 256 | coffee-script-source (1.12.2) 257 | colorize (1.1.0) 258 | concurrent-ruby (1.3.4) 259 | connection_pool (2.4.1) 260 | crass (1.0.6) 261 | csv (3.3.0) 262 | date (3.3.4) 263 | debug (1.9.2) 264 | irb (~> 1.10) 265 | reline (>= 0.3.8) 266 | devise (4.9.4) 267 | bcrypt (~> 3.0) 268 | orm_adapter (~> 0.1) 269 | railties (>= 4.1.0) 270 | responders 271 | warden (~> 1.2.3) 272 | devise-encryptable (0.2.0) 273 | devise (>= 2.1.0) 274 | dotenv (3.1.4) 275 | dragonfly (1.4.0) 276 | addressable (~> 2.3) 277 | multi_json (~> 1.0) 278 | rack (>= 1.3) 279 | drb (2.2.1) 280 | dry-core (1.0.1) 281 | concurrent-ruby (~> 1.0) 282 | zeitwerk (~> 2.6) 283 | dry-inflector (1.1.0) 284 | dry-logic (1.5.0) 285 | concurrent-ruby (~> 1.0) 286 | dry-core (~> 1.0, < 2) 287 | zeitwerk (~> 2.6) 288 | dry-types (1.7.2) 289 | bigdecimal (~> 3.0) 290 | concurrent-ruby (~> 1.0) 291 | dry-core (~> 1.0) 292 | dry-inflector (~> 1.0) 293 | dry-logic (~> 1.4) 294 | zeitwerk (~> 2.6) 295 | duktape (2.0.1.1) 296 | elasticsearch (6.2.0) 297 | elasticsearch-api (= 6.2.0) 298 | elasticsearch-transport (= 6.2.0) 299 | elasticsearch-api (6.2.0) 300 | multi_json 301 | elasticsearch-transport (6.2.0) 302 | faraday 303 | multi_json 304 | erubi (1.13.0) 305 | execjs (2.9.1) 306 | faraday (0.17.6) 307 | multipart-post (>= 1.2, < 3) 308 | ffi (1.17.0-aarch64-linux-gnu) 309 | ffi (1.17.0-aarch64-linux-musl) 310 | ffi (1.17.0-arm-linux-gnu) 311 | ffi (1.17.0-arm-linux-musl) 312 | ffi (1.17.0-arm64-darwin) 313 | ffi (1.17.0-x86-linux-gnu) 314 | ffi (1.17.0-x86-linux-musl) 315 | ffi (1.17.0-x86_64-darwin) 316 | ffi (1.17.0-x86_64-linux-gnu) 317 | ffi (1.17.0-x86_64-linux-musl) 318 | flash_cookie_session (1.1.6) 319 | rails (>= 3.0) 320 | font-awesome-sass (6.3.0) 321 | sassc (~> 2.0) 322 | get_process_mem (1.0.0) 323 | bigdecimal (>= 2.0) 324 | ffi (~> 1.0) 325 | globalid (1.2.1) 326 | activesupport (>= 6.1) 327 | grape (2.1.3) 328 | activesupport (>= 6) 329 | dry-types (>= 1.1) 330 | mustermann-grape (~> 1.1.0) 331 | rack (>= 2) 332 | zeitwerk 333 | grape-entity (0.10.2) 334 | activesupport (>= 3.0.0) 335 | multi_json (>= 1.3.2) 336 | highline (2.1.0) 337 | httparty (0.22.0) 338 | csv 339 | mini_mime (>= 1.0.0) 340 | multi_xml (>= 0.5.2) 341 | httpclient (2.8.3) 342 | i18n (1.14.6) 343 | concurrent-ruby (~> 1.0) 344 | io-console (0.7.2) 345 | irb (1.14.1) 346 | rdoc (>= 4.0.0) 347 | reline (>= 0.4.2) 348 | jbuilder (2.13.0) 349 | actionview (>= 5.0.0) 350 | activesupport (>= 5.0.0) 351 | jmespath (1.6.2) 352 | jquery-rails (4.5.1) 353 | rails-dom-testing (>= 1, < 3) 354 | railties (>= 4.2.0) 355 | thor (>= 0.14, < 2.0) 356 | jquery-ui-rails (6.0.1) 357 | railties (>= 3.2.16) 358 | json (2.7.2) 359 | json-schema (3.0.0) 360 | addressable (>= 2.8) 361 | jwt (2.2.3) 362 | kaminari (1.2.2) 363 | activesupport (>= 4.1.0) 364 | kaminari-actionview (= 1.2.2) 365 | kaminari-activerecord (= 1.2.2) 366 | kaminari-core (= 1.2.2) 367 | kaminari-actionview (1.2.2) 368 | actionview 369 | kaminari-core (= 1.2.2) 370 | kaminari-activerecord (1.2.2) 371 | activerecord 372 | kaminari-core (= 1.2.2) 373 | kaminari-core (1.2.2) 374 | kaminari-mongoid (1.0.2) 375 | kaminari-core (~> 1.0) 376 | mongoid 377 | kramdown (2.3.2) 378 | rexml 379 | liquid (4.0.4) 380 | logger (1.6.1) 381 | loofah (2.22.0) 382 | crass (~> 1.0.2) 383 | nokogiri (>= 1.12.0) 384 | mail (2.8.1) 385 | mini_mime (>= 0.1.1) 386 | net-imap 387 | net-pop 388 | net-smtp 389 | marcel (1.0.4) 390 | mime-types (3.5.2) 391 | mime-types-data (~> 3.2015) 392 | mime-types-data (3.2024.1001) 393 | mimemagic (0.4.3) 394 | nokogiri (~> 1) 395 | rake 396 | mimetype-fu (0.1.2) 397 | mini_mime (1.1.5) 398 | minitest (5.25.1) 399 | moneta (1.6.0) 400 | monetize (1.12.0) 401 | money (~> 6.12) 402 | money (6.19.0) 403 | i18n (>= 0.6.4, <= 2) 404 | mongo (2.19.3) 405 | bson (>= 4.14.1, < 5.0.0) 406 | mongo_session_store (3.2.1) 407 | actionpack (>= 4.0) 408 | mongo (~> 2.0) 409 | mongoid (8.0.8) 410 | activemodel (>= 5.1, < 7.2, != 7.0.0) 411 | mongo (>= 2.18.0, < 3.0.0) 412 | ruby2_keywords (~> 0.0.5) 413 | mongoid-grid_fs (2.5.0) 414 | mime-types (>= 1.0, < 4.0) 415 | mongoid (>= 3.0, < 9.0) 416 | mongoid-tree (2.2.0) 417 | mongoid (>= 4.0, < 9) 418 | morphine (0.1.1) 419 | msgpack (1.7.3) 420 | multi_json (1.15.0) 421 | multi_xml (0.7.1) 422 | bigdecimal (~> 3.1) 423 | multipart-post (2.4.1) 424 | mustermann (3.0.3) 425 | ruby2_keywords (~> 0.0.1) 426 | mustermann-grape (1.1.0) 427 | mustermann (>= 1.0.0) 428 | mutex_m (0.2.0) 429 | net-imap (0.5.0) 430 | date 431 | net-protocol 432 | net-pop (0.1.2) 433 | net-protocol 434 | net-protocol (0.2.2) 435 | timeout 436 | net-smtp (0.5.0) 437 | net-protocol 438 | nio4r (2.7.3) 439 | nokogiri (1.16.7-aarch64-linux) 440 | racc (~> 1.4) 441 | nokogiri (1.16.7-arm-linux) 442 | racc (~> 1.4) 443 | nokogiri (1.16.7-arm64-darwin) 444 | racc (~> 1.4) 445 | nokogiri (1.16.7-x86-linux) 446 | racc (~> 1.4) 447 | nokogiri (1.16.7-x86_64-darwin) 448 | racc (~> 1.4) 449 | nokogiri (1.16.7-x86_64-linux) 450 | racc (~> 1.4) 451 | origin (2.3.1) 452 | orm_adapter (0.5.0) 453 | parser (3.3.5.0) 454 | ast (~> 2.4.1) 455 | racc 456 | pony (1.13.1) 457 | mail (>= 2.0) 458 | psych (5.1.2) 459 | stringio 460 | public_suffix (6.0.1) 461 | puma (6.4.3) 462 | nio4r (~> 2.0) 463 | puma_worker_killer (1.0.0) 464 | bigdecimal (>= 2.0) 465 | get_process_mem (>= 0.2) 466 | puma (>= 2.7) 467 | pundit (2.3.2) 468 | activesupport (>= 3.0.0) 469 | racc (1.8.1) 470 | rack (3.1.8) 471 | rack-cache (1.14.0) 472 | rack (>= 0.4) 473 | rack-cors (2.0.2) 474 | rack (>= 2.0.0) 475 | rack-rewrite (1.5.1) 476 | rack-session (2.0.0) 477 | rack (>= 3.0.0) 478 | rack-test (2.1.0) 479 | rack (>= 1.3) 480 | rack-utm (0.0.2) 481 | rack 482 | rack_csrf (2.6.0) 483 | rack (>= 1.1.0) 484 | rackup (2.1.0) 485 | rack (>= 3) 486 | webrick (~> 1.8) 487 | rails (7.1.4.1) 488 | actioncable (= 7.1.4.1) 489 | actionmailbox (= 7.1.4.1) 490 | actionmailer (= 7.1.4.1) 491 | actionpack (= 7.1.4.1) 492 | actiontext (= 7.1.4.1) 493 | actionview (= 7.1.4.1) 494 | activejob (= 7.1.4.1) 495 | activemodel (= 7.1.4.1) 496 | activerecord (= 7.1.4.1) 497 | activestorage (= 7.1.4.1) 498 | activesupport (= 7.1.4.1) 499 | bundler (>= 1.15.0) 500 | railties (= 7.1.4.1) 501 | rails-dom-testing (2.2.0) 502 | activesupport (>= 5.0.0) 503 | minitest 504 | nokogiri (>= 1.6) 505 | rails-html-sanitizer (1.6.0) 506 | loofah (~> 2.21) 507 | nokogiri (~> 1.14) 508 | rails-i18n (7.0.9) 509 | i18n (>= 0.7, < 2) 510 | railties (>= 6.0.0, < 8) 511 | railties (7.1.4.1) 512 | actionpack (= 7.1.4.1) 513 | activesupport (= 7.1.4.1) 514 | irb 515 | rackup (>= 1.0.0) 516 | rake (>= 12.2) 517 | thor (~> 1.0, >= 1.2.2) 518 | zeitwerk (~> 2.6) 519 | rake (13.2.1) 520 | rdoc (6.7.0) 521 | psych (>= 4.0.0) 522 | reline (0.5.10) 523 | io-console (~> 0.5) 524 | responders (3.1.1) 525 | actionpack (>= 5.2) 526 | railties (>= 5.2) 527 | rexml (3.3.8) 528 | ruby2_keywords (0.0.5) 529 | sanitize (6.0.2) 530 | crass (~> 1.0.2) 531 | nokogiri (>= 1.12.0) 532 | sass-rails (6.0.0) 533 | sassc-rails (~> 2.1, >= 2.1.1) 534 | sassc (2.4.0) 535 | ffi (~> 1.9) 536 | sassc-rails (2.1.2) 537 | railties (>= 4.0.0) 538 | sassc (>= 2.0) 539 | sprockets (> 3.0) 540 | sprockets-rails 541 | tilt 542 | sentry-rails (5.21.0) 543 | railties (>= 5.0) 544 | sentry-ruby (~> 5.21.0) 545 | sentry-ruby (5.21.0) 546 | bigdecimal 547 | concurrent-ruby (~> 1.0, >= 1.0.2) 548 | simple_form (5.2.0) 549 | actionpack (>= 5.2) 550 | activemodel (>= 5.2) 551 | simple_token_authentication (1.18.1) 552 | actionmailer (>= 3.2.6, < 8) 553 | actionpack (>= 3.2.6, < 8) 554 | devise (>= 3.2, < 6) 555 | slim (5.0.0) 556 | temple (~> 0.10.0) 557 | tilt (>= 2.0.6, < 2.1) 558 | sprockets (4.2.1) 559 | concurrent-ruby (~> 1.0) 560 | rack (>= 2.2.4, < 4) 561 | sprockets-rails (3.4.2) 562 | actionpack (>= 5.2) 563 | activesupport (>= 5.2) 564 | sprockets (>= 3.0.0) 565 | ssrf_filter (1.0.8) 566 | stackprof (0.2.26) 567 | stringex (2.8.6) 568 | stringio (3.1.1) 569 | temple (0.10.3) 570 | thor (1.3.2) 571 | tilt (2.0.11) 572 | timeout (0.4.1) 573 | tzinfo (2.0.6) 574 | concurrent-ruby (~> 1.0) 575 | warden (1.2.9) 576 | rack (>= 2.0.9) 577 | webrick (1.8.2) 578 | websocket-driver (0.7.6) 579 | websocket-extensions (>= 0.1.0) 580 | websocket-extensions (0.1.5) 581 | yajl-ruby (1.4.3) 582 | zeitwerk (2.7.1) 583 | 584 | PLATFORMS 585 | aarch64-linux 586 | aarch64-linux-gnu 587 | aarch64-linux-musl 588 | arm-linux 589 | arm-linux-gnu 590 | arm-linux-musl 591 | arm64-darwin 592 | x86-linux 593 | x86-linux-gnu 594 | x86-linux-musl 595 | x86_64-darwin 596 | x86_64-linux-gnu 597 | x86_64-linux-musl 598 | 599 | DEPENDENCIES 600 | bootsnap 601 | carrierwave-aws 602 | custom_fields! 603 | debug (>= 1.0.0) 604 | devise 605 | dotenv 606 | locomotivecms! 607 | locomotivecms_common! 608 | locomotivecms_steam! 609 | mimemagic (~> 0.4.3) 610 | mongo_session_store (~> 3.2.1) 611 | puma (~> 6.4.0) 612 | puma_worker_killer 613 | rack-cors 614 | rails (~> 7.1, < 7.2) 615 | sentry-rails 616 | sentry-ruby 617 | shop_invader! 618 | stackprof 619 | tzinfo-data 620 | 621 | RUBY VERSION 622 | ruby 3.3.5p100 623 | 624 | BUNDLED WITH 625 | 2.5.16 626 | --------------------------------------------------------------------------------