spiffy_stores_app 8.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rubocop.yml +7 -0
  4. data/.travis.yml +9 -0
  5. data/CHANGELOG.md +3 -0
  6. data/Gemfile +6 -0
  7. data/README.md +346 -0
  8. data/Rakefile +6 -0
  9. data/app/assets/javascripts/spiffy_stores_app/redirect.js +19 -0
  10. data/app/controllers/spiffy_stores_app/authenticated_controller.rb +11 -0
  11. data/app/controllers/spiffy_stores_app/sessions_controller.rb +113 -0
  12. data/app/controllers/spiffy_stores_app/webhooks_controller.rb +36 -0
  13. data/app/views/spiffy_stores_app/sessions/new.html.erb +123 -0
  14. data/app/views/spiffy_stores_app/shared/redirect.html.erb +22 -0
  15. data/config/locales/de.yml +3 -0
  16. data/config/locales/en.yml +4 -0
  17. data/config/locales/es.yml +3 -0
  18. data/config/locales/fr.yml +4 -0
  19. data/config/locales/ja.yml +3 -0
  20. data/config/routes.rb +12 -0
  21. data/docs/Quickstart.md +76 -0
  22. data/images/app-proxy-screenshot.png +0 -0
  23. data/lib/generators/spiffy_stores_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +43 -0
  24. data/lib/generators/spiffy_stores_app/add_after_authenticate_job/templates/after_authenticate_job.rb +10 -0
  25. data/lib/generators/spiffy_stores_app/add_webhook/add_webhook_generator.rb +68 -0
  26. data/lib/generators/spiffy_stores_app/add_webhook/templates/webhook_job.rb +8 -0
  27. data/lib/generators/spiffy_stores_app/app_proxy_controller/app_proxy_controller_generator.rb +25 -0
  28. data/lib/generators/spiffy_stores_app/app_proxy_controller/templates/app_proxy_controller.rb +8 -0
  29. data/lib/generators/spiffy_stores_app/app_proxy_controller/templates/app_proxy_route.rb +10 -0
  30. data/lib/generators/spiffy_stores_app/app_proxy_controller/templates/index.html.erb +19 -0
  31. data/lib/generators/spiffy_stores_app/controllers/controllers_generator.rb +29 -0
  32. data/lib/generators/spiffy_stores_app/home_controller/home_controller_generator.rb +31 -0
  33. data/lib/generators/spiffy_stores_app/home_controller/templates/home_controller.rb +6 -0
  34. data/lib/generators/spiffy_stores_app/home_controller/templates/index.html.erb +21 -0
  35. data/lib/generators/spiffy_stores_app/home_controller/templates/spiffy_stores_app_ready_script.html.erb +7 -0
  36. data/lib/generators/spiffy_stores_app/install/install_generator.rb +58 -0
  37. data/lib/generators/spiffy_stores_app/install/templates/_flash_messages.html.erb +19 -0
  38. data/lib/generators/spiffy_stores_app/install/templates/embedded_app.html.erb +40 -0
  39. data/lib/generators/spiffy_stores_app/install/templates/omniauth.rb +2 -0
  40. data/lib/generators/spiffy_stores_app/install/templates/spiffy_provider.rb +11 -0
  41. data/lib/generators/spiffy_stores_app/install/templates/spiffy_stores_app.rb +9 -0
  42. data/lib/generators/spiffy_stores_app/routes/routes_generator.rb +31 -0
  43. data/lib/generators/spiffy_stores_app/routes/templates/routes.rb +11 -0
  44. data/lib/generators/spiffy_stores_app/shop_model/shop_model_generator.rb +38 -0
  45. data/lib/generators/spiffy_stores_app/shop_model/templates/db/migrate/create_shops.erb +15 -0
  46. data/lib/generators/spiffy_stores_app/shop_model/templates/shop.rb +3 -0
  47. data/lib/generators/spiffy_stores_app/shop_model/templates/shops.yml +3 -0
  48. data/lib/generators/spiffy_stores_app/spiffy_stores_app_generator.rb +16 -0
  49. data/lib/generators/spiffy_stores_app/views/views_generator.rb +29 -0
  50. data/lib/spiffy_stores_app.rb +34 -0
  51. data/lib/spiffy_stores_app/configuration.rb +72 -0
  52. data/lib/spiffy_stores_app/controller_concerns/app_proxy_verification.rb +38 -0
  53. data/lib/spiffy_stores_app/controller_concerns/embedded_app.rb +19 -0
  54. data/lib/spiffy_stores_app/controller_concerns/localization.rb +22 -0
  55. data/lib/spiffy_stores_app/controller_concerns/login_protection.rb +103 -0
  56. data/lib/spiffy_stores_app/controller_concerns/webhook_verification.rb +34 -0
  57. data/lib/spiffy_stores_app/engine.rb +10 -0
  58. data/lib/spiffy_stores_app/jobs/scripttags_manager_job.rb +15 -0
  59. data/lib/spiffy_stores_app/jobs/webhooks_manager_job.rb +15 -0
  60. data/lib/spiffy_stores_app/managers/scripttags_manager.rb +77 -0
  61. data/lib/spiffy_stores_app/managers/webhooks_manager.rb +61 -0
  62. data/lib/spiffy_stores_app/session/in_memory_session_store.rb +27 -0
  63. data/lib/spiffy_stores_app/session/session_repository.rb +34 -0
  64. data/lib/spiffy_stores_app/session/session_storage.rb +32 -0
  65. data/lib/spiffy_stores_app/utils.rb +16 -0
  66. data/lib/spiffy_stores_app/version.rb +3 -0
  67. data/spiffy_stores_app.gemspec +26 -0
  68. metadata +220 -0
@@ -0,0 +1,8 @@
1
+ class AppProxyController < ApplicationController
2
+ include SpiffyStoresApp::AppProxyVerification
3
+
4
+ def index
5
+ render layout: false, content_type: 'application/liquid'
6
+ end
7
+
8
+ end
@@ -0,0 +1,10 @@
1
+
2
+ namespace :app_proxy do
3
+ root action: 'index'
4
+ # simple routes without a specified controller will go to AppProxyController
5
+
6
+ # more complex routes will go to controllers in the AppProxy namespace
7
+ # resources :reviews
8
+ # GET /app_proxy/reviews will now be routed to
9
+ # AppProxy::ReviewsController#index, for example
10
+ end
@@ -0,0 +1,19 @@
1
+ <h2>App Proxy Page</h2>
2
+
3
+ <p>Congratulations! You have successfully configured App Proxy for your Spiffy Stores application.</p>
4
+ <p>Any valid liquid code included in this page will be parsed and rendered by Spiffy Stores.</p>
5
+
6
+ <br>
7
+
8
+ <pre>
9
+ Your Shop Details:
10
+ <hr>
11
+ Store Name : {{ shop.name }}
12
+ spiffystores name : {{ shop.short_name }}
13
+ Primary Domain of Shop : {{ shop.domain }}
14
+ Shop URL : {{ shop.url }}
15
+ Shop Currency : {{ shop.currency }}
16
+ No. of products in this shop : {{ shop.products_count }}
17
+ <br>
18
+ <hr>
19
+ </pre>
@@ -0,0 +1,29 @@
1
+ require 'rails/generators/base'
2
+
3
+ module SpiffyStoresApp
4
+ module Generators
5
+ class ControllersGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("../../../../..", __FILE__)
7
+
8
+ def create_controllers
9
+ controllers.each do |controller|
10
+ copy_file controller
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def controllers
17
+ files_within_root('.', 'app/controllers/spiffy_stores_app/*.*')
18
+ end
19
+
20
+ def files_within_root(prefix, glob)
21
+ root = "#{self.class.source_root}/#{prefix}"
22
+
23
+ Dir["#{root}/#{glob}"].sort.map do |full_path|
24
+ full_path.sub(root, '.').gsub('/./', '/')
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ require 'rails/generators/base'
2
+
3
+ module SpiffyStoresApp
4
+ module Generators
5
+ class HomeControllerGenerator < Rails::Generators::Base
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ def create_home_controller
9
+ template 'home_controller.rb', 'app/controllers/home_controller.rb'
10
+ end
11
+
12
+ def create_home_index_view
13
+ copy_file 'index.html.erb', 'app/views/home/index.html.erb'
14
+ if embedded_app?
15
+ prepend_to_file(
16
+ 'app/views/home/index.html.erb',
17
+ File.read(File.expand_path(find_in_source_paths('spiffy_stores_app_ready_script.html.erb')))
18
+ )
19
+ end
20
+ end
21
+
22
+ def add_home_index_route
23
+ route "root :to => 'home#index'"
24
+ end
25
+
26
+ def embedded_app?
27
+ SpiffyStoresApp.configuration.embedded_app?
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,6 @@
1
+ class HomeController < SpiffyStoresApp::AuthenticatedController
2
+ def index
3
+ @products = SpiffyStoresAPI::Product.find(:all, params: { limit: 10 })
4
+ @webhooks = SpiffyStoresAPI::Webhook.find(:all)
5
+ end
6
+ end
@@ -0,0 +1,21 @@
1
+ <h2>Products</h2>
2
+
3
+ <ul>
4
+ <% @products.each do |product| %>
5
+ <li><%= link_to product.title, "https://#{@shop_session.url}/admin/products/#{product.id}", target: "_top" %></li>
6
+ <% end %>
7
+ </ul>
8
+
9
+ <hr>
10
+
11
+ <h2>Webhooks</h2>
12
+
13
+ <% if @webhooks.present? %>
14
+ <ul>
15
+ <% @webhooks.each do |webhook| %>
16
+ <li><%= webhook.topic %> : <%= webhook.address %></li>
17
+ <% end %>
18
+ </ul>
19
+ <% else %>
20
+ <p>This app has not created any webhooks for this Store. Add webhooks to your SpiffyStoresApp initializer if you need webhooks</p>
21
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <% content_for :javascript do %>
2
+ <script type="text/javascript">
3
+ SpiffyApp.ready(function(){
4
+ SpiffyApp.Bar.initialize({ title: "Home" });
5
+ });
6
+ </script>
7
+ <% end %>
@@ -0,0 +1,58 @@
1
+ require 'rails/generators/base'
2
+
3
+ module SpiffyStoresApp
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ class_option :application_name, type: :array, default: ['My', 'Spiffy', 'Stores', 'App']
10
+ class_option :api_key, type: :string, default: '<api_key>'
11
+ class_option :secret, type: :string, default: '<secret>'
12
+ class_option :scope, type: :array, default: ['read_orders,', 'read_products']
13
+ class_option :embedded, type: :string, default: 'true'
14
+
15
+ def create_spiffy_stores_app_initializer
16
+ @application_name = format_array_argument(options['application_name'])
17
+ @api_key = options['api_key']
18
+ @secret = options['secret']
19
+ @scope = format_array_argument(options['scope'])
20
+
21
+ template 'spiffy_stores_app.rb', 'config/initializers/spiffy_stores_app.rb'
22
+ end
23
+
24
+ def create_and_inject_into_omniauth_initializer
25
+ unless File.exist? "config/initializers/omniauth.rb"
26
+ copy_file 'omniauth.rb', 'config/initializers/omniauth.rb'
27
+ end
28
+
29
+ inject_into_file(
30
+ 'config/initializers/omniauth.rb',
31
+ File.read(File.expand_path(find_in_source_paths('spiffy_provider.rb'))),
32
+ after: "Rails.application.config.middleware.use OmniAuth::Builder do\n"
33
+ )
34
+ end
35
+
36
+ def create_embedded_app_layout
37
+ if embedded_app?
38
+ copy_file 'embedded_app.html.erb', 'app/views/layouts/embedded_app.html.erb'
39
+ copy_file '_flash_messages.html.erb', 'app/views/layouts/_flash_messages.html.erb'
40
+ end
41
+ end
42
+
43
+ def mount_engine
44
+ route "mount SpiffyStoresApp::Engine, at: '/'"
45
+ end
46
+
47
+ private
48
+
49
+ def embedded_app?
50
+ options['embedded'] == 'true'
51
+ end
52
+
53
+ def format_array_argument(array)
54
+ array.join(' ').tr('"', '')
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,19 @@
1
+ <% content_for :javascript do %>
2
+ <script type="text/javascript">
3
+ var eventName = typeof(Turbolinks) !== 'undefined' ? 'turbolinks:load' : 'DOMContentLoaded';
4
+
5
+ if (!document.documentElement.hasAttribute("data-turbolinks-preview")) {
6
+ document.addEventListener(eventName, function flash() {
7
+ <% if flash[:notice] %>
8
+ SpiffyApp.flashNotice(<%== flash[:notice].to_json %>);
9
+ <% end %>
10
+
11
+ <% if flash[:error] %>
12
+ SpiffyApp.flashError(<%== flash[:error].to_json %>);
13
+ <% end %>
14
+
15
+ document.removeEventListener(eventName, flash)
16
+ });
17
+ }
18
+ </script>
19
+ <% end %>
@@ -0,0 +1,40 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <% application_name = SpiffyStoresApp.configuration.application_name %>
6
+ <title><%= application_name %></title>
7
+ <%= stylesheet_link_tag 'application' %>
8
+ <%= javascript_include_tag 'application', "data-turbolinks-track" => true %>
9
+ <%= csrf_meta_tags %>
10
+ </head>
11
+
12
+ <body>
13
+ <div class="app-wrapper">
14
+ <div class="app-content">
15
+ <main role="main">
16
+ <%= yield %>
17
+ </main>
18
+ </div>
19
+ </div>
20
+
21
+ <%= render 'layouts/flash_messages' %>
22
+
23
+ <script src="https://spiffyserver.com/global/app.js?<%= Time.now.strftime('%Y%m%d%H') %>"></script>
24
+
25
+ <script type="text/javascript">
26
+ SpiffyApp.init({
27
+ apiKey: "<%= SpiffyStoresApp.configuration.api_key %>",
28
+ shopOrigin: "<%= "https://#{ @shop_session.url }" if @shop_session %>",
29
+ debug: <%= Rails.env.development? ? 'true' : 'false' %>,
30
+ forceRedirect: true
31
+ });
32
+ </script>
33
+
34
+ <% if content_for?(:javascript) %>
35
+ <div id="ContentForJavascript" data-turbolinks-temporary>
36
+ <%= yield :javascript %>
37
+ </div>
38
+ <% end %>
39
+ </body>
40
+ </html>
@@ -0,0 +1,2 @@
1
+ Rails.application.config.middleware.use OmniAuth::Builder do
2
+ end
@@ -0,0 +1,11 @@
1
+ provider :spiffy,
2
+ SpiffyStoresApp.configuration.api_key,
3
+ SpiffyStoresApp.configuration.secret,
4
+ scope: SpiffyStoresApp.configuration.scope,
5
+ setup: lambda { |env|
6
+ strategy = env['omniauth.strategy']
7
+
8
+ spiffy_auth_params = strategy.session['spiffy.omniauth_params']&.with_indifferent_access
9
+ store = spiffy_auth_params.present? ? "https://#{spiffy_auth_params[:store]}" : ''
10
+ strategy.options[:client_options][:site] = store
11
+ }
@@ -0,0 +1,9 @@
1
+ SpiffyStoresApp.configure do |config|
2
+ config.application_name = "<%= @application_name %>"
3
+ config.api_key = "<%= @api_key %>"
4
+ config.secret = "<%= @secret %>"
5
+ config.scope = "<%= @scope %>"
6
+ config.embedded_app = <%= embedded_app? %>
7
+ config.after_authenticate_job = false
8
+ config.session_repository = SpiffyStoresApp::InMemorySessionStore
9
+ end
@@ -0,0 +1,31 @@
1
+ require 'rails/generators/base'
2
+
3
+ module SpiffyStoresApp
4
+ module Generators
5
+ class RoutesGenerator < Rails::Generators::Base
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ def inject_spiffy_stores_app_routes_into_application_routes
9
+ route(session_routes)
10
+ end
11
+
12
+ def disable_engine_routes
13
+ gsub_file(
14
+ 'config/routes.rb',
15
+ "mount SpiffyStoresApp::Engine, at: '/'",
16
+ ''
17
+ )
18
+ end
19
+
20
+ private
21
+
22
+ def session_routes
23
+ File.read(routes_file_path)
24
+ end
25
+
26
+ def routes_file_path
27
+ File.expand_path(find_in_source_paths('routes.rb'))
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+
2
+ controller :sessions do
3
+ get 'login' => :new, :as => :login
4
+ post 'login' => :create, :as => :authenticate
5
+ get 'auth/spiffy/callback' => :callback
6
+ get 'logout' => :destroy, :as => :logout
7
+ end
8
+
9
+ namespace :webhooks do
10
+ post ':type' => :receive
11
+ end
@@ -0,0 +1,38 @@
1
+ require 'rails/generators/base'
2
+ require 'rails/generators/active_record'
3
+
4
+ module SpiffyStoresApp
5
+ module Generators
6
+ class ShopModelGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+ source_root File.expand_path('../templates', __FILE__)
9
+
10
+ def create_shop_model
11
+ copy_file 'shop.rb', 'app/models/shop.rb'
12
+ end
13
+
14
+ def create_shop_migration
15
+ migration_template 'db/migrate/create_shops.erb', 'db/migrate/create_shops.rb'
16
+ end
17
+
18
+ def update_spiffy_stores_app_initializer
19
+ gsub_file 'config/initializers/spiffy_stores_app.rb', 'SpiffyStoresApp::InMemorySessionStore', 'Shop'
20
+ end
21
+
22
+ def create_shop_fixtures
23
+ copy_file 'shops.yml', 'test/fixtures/shops.yml'
24
+ end
25
+
26
+ private
27
+
28
+ def rails_migration_version
29
+ Rails.version.match(/\d\.\d/)[0]
30
+ end
31
+
32
+ # for generating a timestamp when using `create_migration`
33
+ def self.next_migration_number(dir)
34
+ ActiveRecord::Generators::Base.next_migration_number(dir)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ class CreateShops < ActiveRecord::Migration[<%= rails_migration_version %>]
2
+ def self.up
3
+ create_table :shops do |t|
4
+ t.string :spiffy_stores_domain, null: false
5
+ t.string :spiffy_stores_token, null: false
6
+ t.timestamps
7
+ end
8
+
9
+ add_index :shops, :spiffy_stores_domain, unique: true
10
+ end
11
+
12
+ def self.down
13
+ drop_table :shops
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ class Shop < ActiveRecord::Base
2
+ include SpiffyStoresApp::SessionStorage
3
+ end
@@ -0,0 +1,3 @@
1
+ regular_shop:
2
+ spiffy_stores_domain: 'regular-shop.spiffystores.com'
3
+ spiffy_stores_token: 'token'
@@ -0,0 +1,16 @@
1
+ module SpiffyStoresApp
2
+ module Generators
3
+ class SpiffyStoresAppGenerator < Rails::Generators::Base
4
+ def initialize(args, *options)
5
+ @opts = options.first
6
+ super(args, *options)
7
+ end
8
+
9
+ def run_all_generators
10
+ generate "spiffy_stores_app:install #{@opts.join(' ')}"
11
+ generate "spiffy_stores_app:shop_model"
12
+ generate "spiffy_stores_app:home_controller"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ require 'rails/generators/base'
2
+
3
+ module SpiffyStoresApp
4
+ module Generators
5
+ class ViewsGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("../../../../..", __FILE__)
7
+
8
+ def create_views
9
+ views.each do |view|
10
+ copy_file view
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def views
17
+ files_within_root('.', 'app/views/**/*.*')
18
+ end
19
+
20
+ def files_within_root(prefix, glob)
21
+ root = "#{self.class.source_root}/#{prefix}"
22
+
23
+ Dir["#{root}/#{glob}"].sort.map do |full_path|
24
+ full_path.sub(root, '.').gsub('/./', '/')
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end