shopify_app 13.3.0 → 14.1.0
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 +4 -4
- data/.github/PULL_REQUEST_TEMPLATE.md +6 -0
- data/.travis.yml +0 -1
- data/CHANGELOG.md +22 -0
- data/README.md +12 -3
- data/app/assets/javascripts/shopify_app/app_bridge_redirect.js +18 -0
- data/app/assets/javascripts/shopify_app/redirect.js +4 -9
- data/app/assets/javascripts/shopify_app/storage_access.js +3 -11
- data/app/controllers/concerns/shopify_app/authenticated.rb +1 -0
- data/app/controllers/shopify_app/callback_controller.rb +2 -2
- data/app/views/shopify_app/sessions/enable_cookies.html.erb +6 -6
- data/app/views/shopify_app/sessions/request_storage_access.html.erb +5 -0
- data/app/views/shopify_app/shared/redirect.html.erb +6 -1
- data/docs/Quickstart.md +2 -3
- data/docs/Releasing.md +12 -12
- data/lib/generators/shopify_app/authenticated_controller/authenticated_controller_generator.rb +1 -1
- data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +20 -2
- data/lib/generators/shopify_app/home_controller/templates/index.html.erb +67 -17
- data/lib/generators/shopify_app/home_controller/templates/unauthenticated_home_controller.rb +10 -0
- data/lib/generators/shopify_app/install/templates/embedded_app.html.erb +1 -1
- data/lib/generators/shopify_app/install/templates/flash_messages.js +0 -2
- data/lib/generators/shopify_app/install/templates/shopify_app.rb.tt +1 -0
- data/lib/generators/shopify_app/products_controller/products_controller_generator.rb +19 -0
- data/lib/generators/shopify_app/products_controller/templates/products_controller.rb +8 -0
- data/lib/generators/shopify_app/shopify_app_generator.rb +1 -1
- data/lib/shopify_app.rb +1 -0
- data/lib/shopify_app/controller_concerns/csrf_protection.rb +15 -0
- data/lib/shopify_app/controller_concerns/login_protection.rb +8 -0
- data/lib/shopify_app/version.rb +1 -1
- data/package-lock.json +7 -75
- data/package.json +2 -2
- data/shopify_app.gemspec +2 -2
- data/yarn.lock +248 -178
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db65febc756d6f85ea5ee8f2d109e5e8fa8087ed4b1eaa3df2e1d0abfa33e95c
|
4
|
+
data.tar.gz: 74c591a7dc4f9f6d0fc88f5be084decd7746a6052a72698e34938caeb8b4ef49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76e46bf49ceb4d417df9e414c2bb957bff0726f8a1e54bcb87df36a19ec1efe7b32c71dda81b8f1d0425acfccedd375149c5e975ac7f7281d3bb62136d578b49
|
7
|
+
data.tar.gz: e2459eb498a8b220d888fc1412231b2ce736cd779a4cfac6aa9fa1ce61cbe111a17d2a89427d6e0e38e67a9b3c201a5c0cfcba63c624dcdc27dbd5d8417dd47c
|
@@ -0,0 +1,6 @@
|
|
1
|
+
Before submitting the PR, please consider if any of the following are needed:
|
2
|
+
|
3
|
+
- [ ] Update `CHANGELOG.md` if the changes would impact users
|
4
|
+
- [ ] Update `README.md`, if appropriate.
|
5
|
+
- [ ] Update any relevant pages in `docs/`, if necessary
|
6
|
+
- [ ] For security fixes, the [Disclosure Policy](https://github.com/Shopify/shopify_app/blob/master/SECURITY.md#disclosure-policy) must be followed.
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
14.1.0
|
2
|
+
------
|
3
|
+
* Replace redirect calls to use App Bridge redirect functionality
|
4
|
+
|
5
|
+
14.0.0
|
6
|
+
------
|
7
|
+
* Ruby 2.4 is no longer supported by this gem
|
8
|
+
* Bump gemspec ruby dependency to 2.5
|
9
|
+
* (Beta) Add `--with-session-token` flag to the Shopify App generator to create an app that is compatible with App Bridge Authentication
|
10
|
+
|
11
|
+
13.5.0
|
12
|
+
------
|
13
|
+
* Add `signal_access_token_required` helper method for apps to indicate access token has expired and that a new one is required
|
14
|
+
|
15
|
+
13.4.1
|
16
|
+
------
|
17
|
+
* Fix the version checks for the dependency on `shopify_api` to allow all of v9.X
|
18
|
+
|
19
|
+
13.4.0
|
20
|
+
------
|
21
|
+
* Skip CSRF protection if a valid signed JWT token is present as we trust Shopify to be the only source that can sign it securely. [#994](https://github.com/Shopify/shopify_app/pull/994)
|
22
|
+
|
1
23
|
13.3.0
|
2
24
|
------
|
3
25
|
* Added Payload Verification module [#992](https://github.com/Shopify/shopify_app/pull/992)
|
data/README.md
CHANGED
@@ -58,8 +58,7 @@ $ rails new my_shopify_app
|
|
58
58
|
$ cd my_shopify_app
|
59
59
|
|
60
60
|
# Add the gem shopify_app to your Gemfile
|
61
|
-
$
|
62
|
-
$ bundle install
|
61
|
+
$ bundle add shopify_app
|
63
62
|
```
|
64
63
|
|
65
64
|
Now we are ready to run any of the [generators](#generators) included with `shopify_app`. The following section explains the generators and what you can do with them.
|
@@ -75,7 +74,7 @@ Generators
|
|
75
74
|
|
76
75
|
### Default Generator
|
77
76
|
|
78
|
-
The default generator will run the `install`, `shop`, and `home_controller` generators. This is the recommended way to start a new app from scratch:
|
77
|
+
The default generator will run the `install`, `shop`, `authenticated_controller`, and `home_controller` generators. This is the recommended way to start a new app from scratch:
|
79
78
|
|
80
79
|
```sh
|
81
80
|
$ rails generate shopify_app
|
@@ -124,6 +123,16 @@ $ rails generate shopify_app:home_controller
|
|
124
123
|
|
125
124
|
This generator creates an example home controller and view which fetches and displays products using the Shopify API.
|
126
125
|
|
126
|
+
Options include:
|
127
|
+
* __[beta]__ `with-session-token`: This flag generates an unauthenticated home_controller and a protected sample products_controller. It also creates a home view that leverages a session token to fetch products from your products_controller. Use this flag if you plan to build a single-page application or to secure your app using JWT session tokens (e.g. `--with-session-token` or `--with-session-token true`).
|
128
|
+
|
129
|
+
### Products Controller Generator
|
130
|
+
|
131
|
+
```sh
|
132
|
+
$ rails generate shopify_app:products_controller
|
133
|
+
```
|
134
|
+
|
135
|
+
This generator creates an example products API controller to fetch products using the Shopify API.
|
127
136
|
|
128
137
|
### App Proxy Controller Generator
|
129
138
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
(function(window) {
|
2
|
+
function appBridgeRedirect(url) {
|
3
|
+
var AppBridge = window['app-bridge'];
|
4
|
+
var createApp = AppBridge.default;
|
5
|
+
var Redirect = AppBridge.actions.Redirect;
|
6
|
+
var app = createApp({
|
7
|
+
apiKey: window.apiKey,
|
8
|
+
shopOrigin: window.shopOrigin.replace(/^https:\/\//, ''),
|
9
|
+
});
|
10
|
+
|
11
|
+
var normalizedLink = document.createElement('a');
|
12
|
+
normalizedLink.href = url;
|
13
|
+
|
14
|
+
Redirect.create(app).dispatch(Redirect.Action.REMOTE, normalizedLink.href);
|
15
|
+
}
|
16
|
+
|
17
|
+
window.appBridgeRedirect = appBridgeRedirect;
|
18
|
+
})(window);
|
@@ -1,3 +1,5 @@
|
|
1
|
+
//= require ./app_bridge_redirect.js
|
2
|
+
|
1
3
|
(function() {
|
2
4
|
function redirect() {
|
3
5
|
var redirectTargetElement = document.getElementById("redirection-target");
|
@@ -12,15 +14,8 @@
|
|
12
14
|
// If the current window is the 'parent', change the URL by setting location.href
|
13
15
|
window.top.location.href = targetInfo.url;
|
14
16
|
} else {
|
15
|
-
// If the current window is the 'child', change the parent's URL with
|
16
|
-
|
17
|
-
normalizedLink.href = targetInfo.url;
|
18
|
-
|
19
|
-
data = JSON.stringify({
|
20
|
-
message: 'Shopify.API.remoteRedirect',
|
21
|
-
data: {location: normalizedLink.href}
|
22
|
-
});
|
23
|
-
window.parent.postMessage(data, targetInfo.myshopifyUrl);
|
17
|
+
// If the current window is the 'child', change the parent's URL with App Bridge Redirect
|
18
|
+
window.appBridgeRedirect(targetInfo.url);
|
24
19
|
}
|
25
20
|
}
|
26
21
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
//= require ./app_bridge_redirect.js
|
2
|
+
|
1
3
|
(function() {
|
2
4
|
var ACCESS_GRANTED_STATUS = 'storage_access_granted';
|
3
5
|
var ACCESS_DENIED_STATUS = 'storage_access_denied';
|
@@ -11,17 +13,7 @@
|
|
11
13
|
}
|
12
14
|
|
13
15
|
StorageAccessHelper.prototype.redirectToAppTLD = function(storageAccessStatus) {
|
14
|
-
|
15
|
-
|
16
|
-
normalizedLink.href = this.setNormalizedLink(storageAccessStatus);
|
17
|
-
|
18
|
-
data = JSON.stringify({
|
19
|
-
message: 'Shopify.API.remoteRedirect',
|
20
|
-
data: {
|
21
|
-
location: normalizedLink.href,
|
22
|
-
}
|
23
|
-
});
|
24
|
-
window.parent.postMessage(data, this.redirectData.myshopifyUrl);
|
16
|
+
window.appBridgeRedirect(this.setNormalizedLink(storageAccessStatus));
|
25
17
|
}
|
26
18
|
|
27
19
|
StorageAccessHelper.prototype.redirectToAppsIndex = function() {
|
@@ -7,6 +7,7 @@ module ShopifyApp
|
|
7
7
|
included do
|
8
8
|
include ShopifyApp::Localization
|
9
9
|
include ShopifyApp::LoginProtection
|
10
|
+
include ShopifyApp::CsrfProtection
|
10
11
|
include ShopifyApp::EmbeddedApp
|
11
12
|
before_action :login_again_if_different_user_or_shop
|
12
13
|
around_action :activate_shopify_session
|
@@ -65,9 +65,9 @@ module ShopifyApp
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def associated_user
|
68
|
-
return unless auth_hash
|
68
|
+
return unless auth_hash.dig('extra', 'associated_user').present?
|
69
69
|
|
70
|
-
auth_hash['extra']['associated_user']
|
70
|
+
auth_hash['extra']['associated_user'].merge('scope' => auth_hash['extra']['associated_user_scope'])
|
71
71
|
end
|
72
72
|
|
73
73
|
def associated_user_id
|
@@ -5,6 +5,12 @@
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
6
6
|
<base target="_top">
|
7
7
|
<title>Redirecting…</title>
|
8
|
+
<script src="https://unpkg.com/@shopify/app-bridge@^1"></script>
|
9
|
+
<script>
|
10
|
+
window.apiKey = "<%= ShopifyApp.configuration.api_key %>";
|
11
|
+
window.shopOrigin = "https://<%= @shop %>";
|
12
|
+
window.returnTo = "<%= params[:return_to] %>"
|
13
|
+
</script>
|
8
14
|
<%= render 'shopify_app/partials/layout_styles' %>
|
9
15
|
<%= render 'shopify_app/partials/typography_styles' %>
|
10
16
|
<%= render 'shopify_app/partials/card_styles' %>
|
@@ -14,12 +20,6 @@
|
|
14
20
|
display: none;
|
15
21
|
}
|
16
22
|
</style>
|
17
|
-
<script>
|
18
|
-
window.apiKey = "<%= ShopifyApp.configuration.api_key %>";
|
19
|
-
window.shopOrigin = "https://<%= @shop %>";
|
20
|
-
window.returnTo = "<%= params[:return_to] %>"
|
21
|
-
</script>
|
22
|
-
|
23
23
|
<%= javascript_include_tag('shopify_app/enable_cookies', crossorigin: 'anonymous', integrity: true) %>
|
24
24
|
</head>
|
25
25
|
<body>
|
@@ -5,6 +5,11 @@
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
6
6
|
<base target="_top">
|
7
7
|
<title>Redirecting…</title>
|
8
|
+
<script src="https://unpkg.com/@shopify/app-bridge@^1"></script>
|
9
|
+
<script>
|
10
|
+
window.apiKey = "<%= ShopifyApp.configuration.api_key %>";
|
11
|
+
window.shopOrigin = "https://<%= current_shopify_domain %>";
|
12
|
+
</script>
|
8
13
|
<%= render 'shopify_app/partials/layout_styles' %>
|
9
14
|
<%= render 'shopify_app/partials/typography_styles' %>
|
10
15
|
<%= render 'shopify_app/partials/card_styles' %>
|
@@ -1,10 +1,15 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
|
-
<html lang="
|
2
|
+
<html lang="<%= I18n.locale %>">
|
3
3
|
<head>
|
4
4
|
<meta charset="utf-8" />
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
6
6
|
<base target="_top">
|
7
7
|
<title>Redirecting…</title>
|
8
|
+
<script src="https://unpkg.com/@shopify/app-bridge@^1"></script>
|
9
|
+
<script>
|
10
|
+
window.apiKey = "<%= ShopifyApp.configuration.api_key %>";
|
11
|
+
window.shopOrigin = "https://<%= current_shopify_domain %>";
|
12
|
+
</script>
|
8
13
|
<%= javascript_include_tag('shopify_app/redirect', crossorigin: 'anonymous', integrity: true) %>
|
9
14
|
</head>
|
10
15
|
<body>
|
data/docs/Quickstart.md
CHANGED
@@ -40,11 +40,10 @@ $ heroku create name
|
|
40
40
|
4. Add ShopifyApp to Gemfile
|
41
41
|
----------------------------
|
42
42
|
|
43
|
-
Run
|
43
|
+
Run this command to add the `shopify_app` Gem to your app:
|
44
44
|
|
45
45
|
```sh
|
46
|
-
$
|
47
|
-
$ bundle install
|
46
|
+
$ bundle add shopify_app
|
48
47
|
```
|
49
48
|
|
50
49
|
**Note:** we recommend using the latest version of Shopify Gem. Check the [Git tags](https://github.com/Shopify/shopify_app/tags) to see the latest release version and then add it to your Gemfile e.g `gem 'shopify_app', '~> 7.0.0'`
|
data/docs/Releasing.md
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
Releasing ShopifyApp
|
2
2
|
|
3
3
|
1. Check the Semantic Versioning page for info on how to version the new release: http://semver.org
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
4
|
+
1. Create a pull request with the following changes:
|
5
|
+
- Update the version of ShopifyApp in lib/shopify_app/version.rb
|
6
|
+
- Update the version of shopify_app in package.json
|
7
|
+
- Add a CHANGELOG entry for the new release with the date
|
8
|
+
- Change the title of the PR to something like: "Packaging for release X.Y.Z"
|
9
|
+
1. Merge your pull request
|
10
|
+
1. Checkout and pull from master so you have the latest version of the shopify_app
|
11
|
+
1. Tag the HEAD with the version
|
12
|
+
```bash
|
13
|
+
$ git tag -f vX.Y.Z && git push --tags --force
|
14
|
+
```
|
15
|
+
1. Use Shipit to build and push the gem
|
16
16
|
|
17
17
|
If you see an error like 'You need to create the vX.Y.X tag first', clear GIT
|
18
18
|
cache in Shipit settings
|
data/lib/generators/shopify_app/authenticated_controller/authenticated_controller_generator.rb
CHANGED
@@ -7,7 +7,7 @@ module ShopifyApp
|
|
7
7
|
class AuthenticatedControllerGenerator < Rails::Generators::Base
|
8
8
|
source_root File.expand_path('../templates', __FILE__)
|
9
9
|
|
10
|
-
def
|
10
|
+
def create_authenticated_controller
|
11
11
|
template('authenticated_controller.rb', 'app/controllers/authenticated_controller.rb')
|
12
12
|
end
|
13
13
|
end
|
@@ -6,21 +6,39 @@ module ShopifyApp
|
|
6
6
|
class HomeControllerGenerator < Rails::Generators::Base
|
7
7
|
source_root File.expand_path('../templates', __FILE__)
|
8
8
|
|
9
|
+
class_option :with_session_token, type: :boolean, default: false
|
10
|
+
|
9
11
|
def create_home_controller
|
10
|
-
|
12
|
+
@with_session_token = options['with_session_token']
|
13
|
+
|
14
|
+
template(home_controller_template, 'app/controllers/home_controller.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_products_controller
|
18
|
+
generate("shopify_app:products_controller") if with_session_token?
|
11
19
|
end
|
12
20
|
|
13
21
|
def create_home_index_view
|
14
|
-
|
22
|
+
template('index.html.erb', 'app/views/home/index.html.erb')
|
15
23
|
end
|
16
24
|
|
17
25
|
def add_home_index_route
|
18
26
|
route("root :to => 'home#index'")
|
19
27
|
end
|
20
28
|
|
29
|
+
private
|
30
|
+
|
21
31
|
def embedded_app?
|
22
32
|
ShopifyApp.configuration.embedded_app?
|
23
33
|
end
|
34
|
+
|
35
|
+
def with_session_token?
|
36
|
+
@with_session_token
|
37
|
+
end
|
38
|
+
|
39
|
+
def home_controller_template
|
40
|
+
with_session_token? ? 'unauthenticated_home_controller.rb' : 'home_controller.rb'
|
41
|
+
end
|
24
42
|
end
|
25
43
|
end
|
26
44
|
end
|
@@ -1,21 +1,71 @@
|
|
1
|
-
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="<%= I18n.locale %>">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8" />
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
6
|
+
<link
|
7
|
+
rel="stylesheet"
|
8
|
+
href="https://unpkg.com/@shopify/polaris@4.25.0/styles.min.css"
|
9
|
+
/>
|
10
|
+
<% if @with_session_token %> <script>
|
11
|
+
document.addEventListener("DOMContentLoaded", async function() {
|
12
|
+
var SessionToken = window["app-bridge"].actions.SessionToken
|
13
|
+
var app = window.app;
|
2
14
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
<% end %>
|
7
|
-
</ul>
|
15
|
+
app.dispatch(
|
16
|
+
SessionToken.request(),
|
17
|
+
);
|
8
18
|
|
9
|
-
|
19
|
+
// Save a session token for future requests
|
20
|
+
window.sessionToken = await new Promise((resolve) => {
|
21
|
+
app.subscribe(SessionToken.ActionType.RESPOND, (data) => {
|
22
|
+
resolve(data.sessionToken || "");
|
23
|
+
});
|
24
|
+
});
|
10
25
|
|
11
|
-
|
26
|
+
var fetchProducts = function() {
|
27
|
+
var headers = new Headers({ "Authorization": "Bearer " + window.sessionToken });
|
28
|
+
return fetch("/products", { headers })
|
29
|
+
.then(response => response.json())
|
30
|
+
.then(data => {
|
31
|
+
var products = data.products;
|
12
32
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
33
|
+
if (products === undefined || products.length == 0) {
|
34
|
+
document.getElementById("products").innerHTML = "<br>No products to display.";
|
35
|
+
} else {
|
36
|
+
var list = "";
|
37
|
+
products.forEach((product) => {
|
38
|
+
var link = `<a target="_top" href="https://<%%= @shop_origin %>/admin/products/${product.id}">`
|
39
|
+
list += "<li>" + link + product.title + "</a></li>";
|
40
|
+
});
|
41
|
+
document.getElementById("products").innerHTML = "<ul>" + list + "</ul>";
|
42
|
+
}
|
43
|
+
});
|
44
|
+
}();
|
45
|
+
});
|
46
|
+
</script>
|
47
|
+
<% end %> </head>
|
48
|
+
<body>
|
49
|
+
<h2>Products</h2>
|
50
|
+
<% if @with_session_token %> <div id="products"><br>Loading...</div><% else %>
|
51
|
+
<ul>
|
52
|
+
<%% @products.each do |product| %>
|
53
|
+
<li><%%= link_to product.title, "https://#{@current_shopify_session.domain}/admin/products/#{product.id}", target: "_top" %></li>
|
54
|
+
<%% end %>
|
55
|
+
</ul>
|
56
|
+
|
57
|
+
<hr>
|
58
|
+
|
59
|
+
<h2>Webhooks</h2>
|
60
|
+
|
61
|
+
<%% if @webhooks.present? %>
|
62
|
+
<ul>
|
63
|
+
<%% @webhooks.each do |webhook| %>
|
64
|
+
<li><%%= webhook.topic %> : <%%= webhook.address %></li>
|
65
|
+
<%% end %>
|
66
|
+
</ul>
|
67
|
+
<%% else %>
|
68
|
+
<p>This app has not created any webhooks for this Shop. Add webhooks to your ShopifyApp initializer if you need webhooks</p>
|
69
|
+
<%% end %><% end %>
|
70
|
+
</body>
|
71
|
+
</html>
|
@@ -28,7 +28,7 @@
|
|
28
28
|
|
29
29
|
<%= content_tag(:div, nil, id: 'shopify-app-init', data: {
|
30
30
|
api_key: ShopifyApp.configuration.api_key,
|
31
|
-
shop_origin: (@current_shopify_session.domain if @current_shopify_session),
|
31
|
+
shop_origin: @shop_origin || (@current_shopify_session.domain if @current_shopify_session),
|
32
32
|
debug: Rails.env.development?
|
33
33
|
} ) %>
|
34
34
|
|