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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rubocop.yml +7 -0
- data/.travis.yml +9 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +6 -0
- data/README.md +346 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/spiffy_stores_app/redirect.js +19 -0
- data/app/controllers/spiffy_stores_app/authenticated_controller.rb +11 -0
- data/app/controllers/spiffy_stores_app/sessions_controller.rb +113 -0
- data/app/controllers/spiffy_stores_app/webhooks_controller.rb +36 -0
- data/app/views/spiffy_stores_app/sessions/new.html.erb +123 -0
- data/app/views/spiffy_stores_app/shared/redirect.html.erb +22 -0
- data/config/locales/de.yml +3 -0
- data/config/locales/en.yml +4 -0
- data/config/locales/es.yml +3 -0
- data/config/locales/fr.yml +4 -0
- data/config/locales/ja.yml +3 -0
- data/config/routes.rb +12 -0
- data/docs/Quickstart.md +76 -0
- data/images/app-proxy-screenshot.png +0 -0
- data/lib/generators/spiffy_stores_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +43 -0
- data/lib/generators/spiffy_stores_app/add_after_authenticate_job/templates/after_authenticate_job.rb +10 -0
- data/lib/generators/spiffy_stores_app/add_webhook/add_webhook_generator.rb +68 -0
- data/lib/generators/spiffy_stores_app/add_webhook/templates/webhook_job.rb +8 -0
- data/lib/generators/spiffy_stores_app/app_proxy_controller/app_proxy_controller_generator.rb +25 -0
- data/lib/generators/spiffy_stores_app/app_proxy_controller/templates/app_proxy_controller.rb +8 -0
- data/lib/generators/spiffy_stores_app/app_proxy_controller/templates/app_proxy_route.rb +10 -0
- data/lib/generators/spiffy_stores_app/app_proxy_controller/templates/index.html.erb +19 -0
- data/lib/generators/spiffy_stores_app/controllers/controllers_generator.rb +29 -0
- data/lib/generators/spiffy_stores_app/home_controller/home_controller_generator.rb +31 -0
- data/lib/generators/spiffy_stores_app/home_controller/templates/home_controller.rb +6 -0
- data/lib/generators/spiffy_stores_app/home_controller/templates/index.html.erb +21 -0
- data/lib/generators/spiffy_stores_app/home_controller/templates/spiffy_stores_app_ready_script.html.erb +7 -0
- data/lib/generators/spiffy_stores_app/install/install_generator.rb +58 -0
- data/lib/generators/spiffy_stores_app/install/templates/_flash_messages.html.erb +19 -0
- data/lib/generators/spiffy_stores_app/install/templates/embedded_app.html.erb +40 -0
- data/lib/generators/spiffy_stores_app/install/templates/omniauth.rb +2 -0
- data/lib/generators/spiffy_stores_app/install/templates/spiffy_provider.rb +11 -0
- data/lib/generators/spiffy_stores_app/install/templates/spiffy_stores_app.rb +9 -0
- data/lib/generators/spiffy_stores_app/routes/routes_generator.rb +31 -0
- data/lib/generators/spiffy_stores_app/routes/templates/routes.rb +11 -0
- data/lib/generators/spiffy_stores_app/shop_model/shop_model_generator.rb +38 -0
- data/lib/generators/spiffy_stores_app/shop_model/templates/db/migrate/create_shops.erb +15 -0
- data/lib/generators/spiffy_stores_app/shop_model/templates/shop.rb +3 -0
- data/lib/generators/spiffy_stores_app/shop_model/templates/shops.yml +3 -0
- data/lib/generators/spiffy_stores_app/spiffy_stores_app_generator.rb +16 -0
- data/lib/generators/spiffy_stores_app/views/views_generator.rb +29 -0
- data/lib/spiffy_stores_app.rb +34 -0
- data/lib/spiffy_stores_app/configuration.rb +72 -0
- data/lib/spiffy_stores_app/controller_concerns/app_proxy_verification.rb +38 -0
- data/lib/spiffy_stores_app/controller_concerns/embedded_app.rb +19 -0
- data/lib/spiffy_stores_app/controller_concerns/localization.rb +22 -0
- data/lib/spiffy_stores_app/controller_concerns/login_protection.rb +103 -0
- data/lib/spiffy_stores_app/controller_concerns/webhook_verification.rb +34 -0
- data/lib/spiffy_stores_app/engine.rb +10 -0
- data/lib/spiffy_stores_app/jobs/scripttags_manager_job.rb +15 -0
- data/lib/spiffy_stores_app/jobs/webhooks_manager_job.rb +15 -0
- data/lib/spiffy_stores_app/managers/scripttags_manager.rb +77 -0
- data/lib/spiffy_stores_app/managers/webhooks_manager.rb +61 -0
- data/lib/spiffy_stores_app/session/in_memory_session_store.rb +27 -0
- data/lib/spiffy_stores_app/session/session_repository.rb +34 -0
- data/lib/spiffy_stores_app/session/session_storage.rb +32 -0
- data/lib/spiffy_stores_app/utils.rb +16 -0
- data/lib/spiffy_stores_app/version.rb +3 -0
- data/spiffy_stores_app.gemspec +26 -0
- metadata +220 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
module SpiffyStoresApp
|
2
|
+
class WebhooksController < ActionController::Base
|
3
|
+
include SpiffyStoresApp::WebhookVerification
|
4
|
+
|
5
|
+
class SpiffyStoresApp::MissingWebhookJobError < StandardError; end
|
6
|
+
|
7
|
+
def receive
|
8
|
+
params.permit!
|
9
|
+
job_args = {shop_domain: shop_domain, webhook: webhook_params.to_h}
|
10
|
+
webhook_job_klass.perform_later(job_args)
|
11
|
+
head :no_content
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def webhook_params
|
17
|
+
params.except(:controller, :action, :type)
|
18
|
+
end
|
19
|
+
|
20
|
+
def webhook_job_klass
|
21
|
+
webhook_job_klass_name.safe_constantize or raise SpiffyStoresApp::MissingWebhookJobError
|
22
|
+
end
|
23
|
+
|
24
|
+
def webhook_job_klass_name(type = webhook_type)
|
25
|
+
[webhook_namespace, "#{type}_job"].compact.join('/').classify
|
26
|
+
end
|
27
|
+
|
28
|
+
def webhook_type
|
29
|
+
params[:type]
|
30
|
+
end
|
31
|
+
|
32
|
+
def webhook_namespace
|
33
|
+
SpiffyStoresApp.configuration.webhook_jobs_namespace
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<title>Spiffy Stores App — Installation</title>
|
5
|
+
|
6
|
+
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
8
|
+
|
9
|
+
<style>
|
10
|
+
* {
|
11
|
+
-moz-box-sizing: border-box;
|
12
|
+
-webkit-box-sizing: border-box;
|
13
|
+
box-sizing: border-box;
|
14
|
+
}
|
15
|
+
|
16
|
+
body {
|
17
|
+
padding: 2.5em 0;
|
18
|
+
color: #212b37;
|
19
|
+
font-family: -apple-system,BlinkMacSystemFont,San Francisco,Roboto,Segoe UI,Helvetica Neue,sans-serif;
|
20
|
+
}
|
21
|
+
|
22
|
+
.container {
|
23
|
+
width: 100%;
|
24
|
+
text-align: center;
|
25
|
+
margin-left: auto;
|
26
|
+
margin-right: auto;
|
27
|
+
}
|
28
|
+
|
29
|
+
@media screen and (min-width: 510px) {
|
30
|
+
.container {
|
31
|
+
width: 510px;
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
.title {
|
36
|
+
font-size: 1.5em;
|
37
|
+
margin: 2em auto;
|
38
|
+
display: flex;
|
39
|
+
align-items: center;
|
40
|
+
justify-content: center;
|
41
|
+
word-break: break-all;
|
42
|
+
}
|
43
|
+
|
44
|
+
.subtitle {
|
45
|
+
font-size: 0.8em;
|
46
|
+
font-weight: 500;
|
47
|
+
color: #64737f;
|
48
|
+
line-height: 2em;
|
49
|
+
}
|
50
|
+
|
51
|
+
.error {
|
52
|
+
line-height: 1em;
|
53
|
+
padding: 0.5em;
|
54
|
+
color: red;
|
55
|
+
}
|
56
|
+
|
57
|
+
input.marketing-input {
|
58
|
+
width: 100%;
|
59
|
+
height: 52px;
|
60
|
+
padding: 0 15px;
|
61
|
+
box-shadow: 0 0 0 1px #ddd;
|
62
|
+
border: 0;
|
63
|
+
border-radius: 5px;
|
64
|
+
background-color: #fff;
|
65
|
+
font-size: 1em;
|
66
|
+
margin-bottom: 15px;
|
67
|
+
}
|
68
|
+
|
69
|
+
input.marketing-input:focus {
|
70
|
+
color: #000;
|
71
|
+
outline: 0;
|
72
|
+
box-shadow: 0 0 0 2px #5e6ebf;
|
73
|
+
}
|
74
|
+
|
75
|
+
button.marketing-button {
|
76
|
+
display: inline-block;
|
77
|
+
width: 100%;
|
78
|
+
padding: 1.0625em 1.875em;
|
79
|
+
background-color: #5e6ebf;
|
80
|
+
color: #fff;
|
81
|
+
font-weight: 700;
|
82
|
+
font-size: 1em;
|
83
|
+
text-align: center;
|
84
|
+
outline: none;
|
85
|
+
border: 0 solid transparent;
|
86
|
+
border-radius: 5px;
|
87
|
+
cursor: pointer;
|
88
|
+
}
|
89
|
+
|
90
|
+
button.marketing-button:hover {
|
91
|
+
background: linear-gradient(to bottom, #5c6ac4, #4959bd);
|
92
|
+
border-color: #3f4eae;
|
93
|
+
}
|
94
|
+
|
95
|
+
button.marketing-button:focus {
|
96
|
+
box-shadow: 0 0 0.1875em 0.1875em rgba(94,110,191,0.5);
|
97
|
+
background-color: #223274;
|
98
|
+
color: #fff;
|
99
|
+
}
|
100
|
+
</style>
|
101
|
+
</head>
|
102
|
+
<body>
|
103
|
+
|
104
|
+
<main class="container" role="main">
|
105
|
+
<% application_name = SpiffyStoresApp.configuration.application_name %>
|
106
|
+
<h3 class="title">
|
107
|
+
<%= application_name.presence || 'Spiffy Stores App - Installation' %>
|
108
|
+
</h3>
|
109
|
+
<p class="subtitle">
|
110
|
+
<label for="store">Please enter the name of your "spiffystores.com" store</label>
|
111
|
+
</p>
|
112
|
+
|
113
|
+
<%= form_tag login_path do %>
|
114
|
+
<% if flash[:error] %>
|
115
|
+
<div class="error"><%= flash[:error] %></div>
|
116
|
+
<% end %>
|
117
|
+
<input id="store" name="store" type="text" autofocus="autofocus" placeholder="mystore.spiffystores.com" class="marketing-input">
|
118
|
+
<button type="submit" class="marketing-button">Install</button>
|
119
|
+
<% end %>
|
120
|
+
</main>
|
121
|
+
|
122
|
+
</body>
|
123
|
+
</html>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8" />
|
5
|
+
<base target="_top">
|
6
|
+
<title>Redirecting…</title>
|
7
|
+
<%= javascript_include_tag('spiffy_stores_app/redirect', crossorigin: 'anonymous', integrity: true) %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<%=
|
11
|
+
content_tag(:div, nil,
|
12
|
+
id: 'redirection-target',
|
13
|
+
data: {
|
14
|
+
target: {
|
15
|
+
myspiffyUrl: "https://#{current_spiffy_stores_domain}",
|
16
|
+
url: url,
|
17
|
+
},
|
18
|
+
},
|
19
|
+
)
|
20
|
+
%>
|
21
|
+
</body>
|
22
|
+
</html>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
SpiffyStoresApp::Engine.routes.draw do
|
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
|
12
|
+
end
|
data/docs/Quickstart.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
Quickstart
|
2
|
+
==========
|
3
|
+
|
4
|
+
Build and deploy a new Spiffy Stores App to Heroku in minutes
|
5
|
+
|
6
|
+
1. New Rails App (with postgres)
|
7
|
+
--------------------------------
|
8
|
+
|
9
|
+
```sh
|
10
|
+
$ rails new test-app --database=postgresql
|
11
|
+
$ cd test-app
|
12
|
+
$ git init
|
13
|
+
$ git add .
|
14
|
+
$ git commit -m 'new rails app'
|
15
|
+
```
|
16
|
+
|
17
|
+
2. Create a new Heroku app
|
18
|
+
--------------------------
|
19
|
+
|
20
|
+
The next step is to create a new heroku app. Pull up your heroku dashboard and make a new app!
|
21
|
+
|
22
|
+
cli:
|
23
|
+
```sh
|
24
|
+
$ heroku create name
|
25
|
+
$ heroku git:remote -a name
|
26
|
+
```
|
27
|
+
|
28
|
+
now we need to let git know where the remote server is so we'll be able to deploy later
|
29
|
+
|
30
|
+
web:
|
31
|
+
```sh
|
32
|
+
# https://dashboard.heroku.com/new
|
33
|
+
$ git remote add heroku git@heroku.com:appinfive.git
|
34
|
+
```
|
35
|
+
|
36
|
+
3. Contact Spiffy Stores to create app
|
37
|
+
--------------------------------------
|
38
|
+
You will be given the app credentials and the redirect_uri will be set to the required value.
|
39
|
+
|
40
|
+
* set the callback url to `https://<name>.herokuapp.com/`
|
41
|
+
* choose an embedded app
|
42
|
+
* set the redirect_uri to `https://<name>.herokuapp.com/auth/spiffy/callback`
|
43
|
+
|
44
|
+
|
45
|
+
4. Add SpiffyStoresApp to gemfile
|
46
|
+
----------------------------
|
47
|
+
```sh
|
48
|
+
$ echo "gem 'spiffy_stores_app'" >> Gemfile
|
49
|
+
$ bundle install
|
50
|
+
```
|
51
|
+
|
52
|
+
Note - its recommended to use the latest released version. Check the git tags to see the latest release and then add it to your Gemfile e.g `gem 'spiffy_stores_app', '~> 7.0.0'`
|
53
|
+
|
54
|
+
5. Run the SpiffyStoresApp generator
|
55
|
+
------------------------------------
|
56
|
+
```sh
|
57
|
+
# use the keys for your app that have been provided to you
|
58
|
+
$ rails generate spiffy_stores_app --api_key <spiffy_stores_api_key> --secret <spiffy_stores_api_secret>
|
59
|
+
$ git add .
|
60
|
+
$ git commit -m 'generated spiffy stores app'
|
61
|
+
```
|
62
|
+
|
63
|
+
If you forget to set your keys or redirect uri above, you will find them in the spiffy_stores_app initializer at: `/config/initializers/spiffy_stores_app.rb`.
|
64
|
+
|
65
|
+
We recommend adding a gem or utilizing ENV variables to handle your keys before releasing your app.
|
66
|
+
|
67
|
+
6. Deploy
|
68
|
+
---------
|
69
|
+
```sh
|
70
|
+
$ git push heroku
|
71
|
+
$ heroku run rake db:migrate
|
72
|
+
```
|
73
|
+
|
74
|
+
7. Install the App!
|
75
|
+
-------------------
|
76
|
+
`https://<name>.herokuapp.com/`
|
Binary file
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module SpiffyStoresApp
|
4
|
+
module Generators
|
5
|
+
class AddAfterAuthenticateJobGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
hook_for :test_framework, as: :job, in: :rails do |instance, generator|
|
9
|
+
instance.invoke generator, [ instance.send(:job_file_name) ]
|
10
|
+
end
|
11
|
+
|
12
|
+
def init_after_authenticate_config
|
13
|
+
initializer = load_initializer
|
14
|
+
|
15
|
+
after_authenticate_job_config = " config.after_authenticate_job = { job: SpiffyStores::AfterAuthenticateJob, inline: false }\n"
|
16
|
+
|
17
|
+
inject_into_file(
|
18
|
+
'config/initializers/spiffy_stores_app.rb',
|
19
|
+
after_authenticate_job_config,
|
20
|
+
before: 'end'
|
21
|
+
)
|
22
|
+
|
23
|
+
unless initializer.include?(after_authenticate_job_config)
|
24
|
+
shell.say "Error adding after_authneticate_job to config. Add this line manually: #{after_authenticate_job_config}", :red
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_after_authenticate_job
|
29
|
+
template 'after_authenticate_job.rb', "app/jobs/#{job_file_name}_job.rb"
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def load_initializer
|
35
|
+
File.read(File.join(destination_root, 'config/initializers/spiffy_stores_app.rb'))
|
36
|
+
end
|
37
|
+
|
38
|
+
def job_file_name
|
39
|
+
'spiffy_stores/after_authenticate'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module SpiffyStoresApp
|
4
|
+
module Generators
|
5
|
+
class AddWebhookGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
class_option :topic, type: :string, aliases: "-t", required: true
|
8
|
+
class_option :address, type: :string, aliases: "-a", required: true
|
9
|
+
|
10
|
+
hook_for :test_framework, as: :job, in: :rails do |instance, generator|
|
11
|
+
instance.invoke generator, [ instance.send(:job_file_name) ]
|
12
|
+
end
|
13
|
+
|
14
|
+
def init_webhook_config
|
15
|
+
initializer = load_initializer
|
16
|
+
return if initializer.include?("config.webhooks")
|
17
|
+
|
18
|
+
inject_into_file(
|
19
|
+
'config/initializers/spiffy_stores_app.rb',
|
20
|
+
" config.webhooks = [\n ]\n",
|
21
|
+
before: 'end'
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def inject_webhook_to_spiffy_stores_app_initializer
|
26
|
+
inject_into_file(
|
27
|
+
'config/initializers/spiffy_stores_app.rb',
|
28
|
+
webhook_config,
|
29
|
+
after: "config.webhooks = ["
|
30
|
+
)
|
31
|
+
|
32
|
+
initializer = load_initializer
|
33
|
+
|
34
|
+
unless initializer.include?(webhook_config)
|
35
|
+
shell.say "Error adding webhook to config. Add this line manually: #{webhook_config}", :red
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_webhook_job
|
40
|
+
@job_file_name = job_file_name + '_job'
|
41
|
+
@job_class_name = @job_file_name.classify
|
42
|
+
template 'webhook_job.rb', "app/jobs/#{@job_file_name}.rb"
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def job_file_name
|
48
|
+
address.split('/').last
|
49
|
+
end
|
50
|
+
|
51
|
+
def load_initializer
|
52
|
+
File.read(File.join(destination_root, 'config/initializers/spiffy_stores_app.rb'))
|
53
|
+
end
|
54
|
+
|
55
|
+
def webhook_config
|
56
|
+
"\n {topic: '#{topic}', address: '#{address}', format: 'json'},"
|
57
|
+
end
|
58
|
+
|
59
|
+
def topic
|
60
|
+
options['topic']
|
61
|
+
end
|
62
|
+
|
63
|
+
def address
|
64
|
+
options['address']
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module SpiffyStoresApp
|
4
|
+
module Generators
|
5
|
+
class AppProxyControllerGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
def create_app_proxy_controller
|
9
|
+
template 'app_proxy_controller.rb', 'app/controllers/app_proxy_controller.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_app_proxy_index_view
|
13
|
+
copy_file 'index.html.erb', 'app/views/app_proxy/index.html.erb'
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_app_proxy_route
|
17
|
+
inject_into_file(
|
18
|
+
'config/routes.rb',
|
19
|
+
File.read(File.expand_path(find_in_source_paths('app_proxy_route.rb'))),
|
20
|
+
after: "mount SpiffyStoresApp::Engine, at: '/'\n"
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|