shopify_app 16.0.0 → 17.0.3
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/workflows/release.yml +24 -0
- data/CHANGELOG.md +24 -0
- data/Gemfile.lock +13 -9
- data/README.md +35 -14
- data/app/controllers/concerns/shopify_app/ensure_authenticated_links.rb +22 -0
- data/app/controllers/shopify_app/callback_controller.rb +10 -8
- data/app/controllers/shopify_app/sessions_controller.rb +1 -15
- data/config/locales/de.yml +11 -11
- data/config/locales/vi.yml +22 -0
- data/config/locales/zh-CN.yml +1 -1
- data/docs/Releasing.md +5 -3
- data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +16 -7
- data/lib/generators/shopify_app/home_controller/templates/index.html.erb +10 -10
- data/lib/generators/shopify_app/install/install_generator.rb +5 -0
- data/lib/generators/shopify_app/install/templates/shopify_app.rb.tt +10 -4
- data/lib/shopify_app/configuration.rb +3 -0
- data/lib/shopify_app/controller_concerns/itp.rb +0 -2
- data/lib/shopify_app/controller_concerns/login_protection.rb +3 -13
- data/lib/shopify_app/version.rb +1 -1
- data/package.json +1 -1
- data/shopify_app.gemspec +1 -1
- data/translation.yml +1 -1
- data/yarn.lock +70 -101
- metadata +11 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 96eacf692dda7725748337cf7ca8e2e1bc13570ffdefffb47588ccf93feb949f
|
|
4
|
+
data.tar.gz: 52f20a1df1a565802d4ca01dc45b624ecbff7d02eeea4a1cb1d4f905a0a0bf17
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d02120729eebc18d6634b1848e6f85573d44dab582dba38e17d114b4afd0a4072017f9649a276cdf58355693f05e2e9daa53bc519da98b8b3f400cb28f41cfe8
|
|
7
|
+
data.tar.gz: 3332c4c0f8860a95b3e1859f5482cd3c9140943d608173668841f671e037ee7b532a6099eef49a257c254e517baf6d616c0aa3aacf1d298820ec06d8d779885a
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Create Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
create-release:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- name: Extract tag name
|
|
13
|
+
id: tag
|
|
14
|
+
run: echo "::set-output name=value::${GITHUB_REF##*/}"
|
|
15
|
+
- uses: actions/checkout@v2
|
|
16
|
+
|
|
17
|
+
- name: Create Release
|
|
18
|
+
id: create_release
|
|
19
|
+
uses: actions/create-release@v1
|
|
20
|
+
env:
|
|
21
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
22
|
+
with:
|
|
23
|
+
tag_name: ${{ steps.tag.outputs.value }}
|
|
24
|
+
release_name: ${{ steps.tag.outputs.value }}
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
Unreleased
|
|
2
|
+
----------
|
|
3
|
+
|
|
4
|
+
17.0.3 (January 22, 2021)
|
|
5
|
+
----------
|
|
6
|
+
* Amend fix for #1144 to raise on missing API keys only when running the server [#1155](https://github.com/Shopify/shopify_app/pull/1155)
|
|
7
|
+
|
|
8
|
+
17.0.2 (January 20, 2021)
|
|
9
|
+
------
|
|
10
|
+
* Fix failing script tags and webhooks installs after completing OAuth [#1151](https://github.com/Shopify/shopify_app/pull/1151)
|
|
11
|
+
|
|
12
|
+
17.0.1 (January 18, 2021)
|
|
13
|
+
------
|
|
14
|
+
* Don't attempt to read Shopify environment variables when the generators are running, since they may not be present yet [#1144](https://github.com/Shopify/shopify_app/pull/1144)
|
|
15
|
+
|
|
16
|
+
17.0.0 (January 13, 2021)
|
|
17
|
+
------
|
|
18
|
+
* Rails 6.1 is not yet supported [#1134](https://github.com/Shopify/shopify_app/pull/1134)
|
|
19
|
+
|
|
20
|
+
16.1.0
|
|
21
|
+
------
|
|
22
|
+
* Use Session Token auth strategy by default for new embedded apps [#1111](https://github.com/Shopify/shopify_app/pull/1111)
|
|
23
|
+
* Create optional `EnsureAuthenticatedLinks` concern to authenticate deep links using Turbolinks [#1118](https://github.com/Shopify/shopify_app/pull/1118)
|
|
24
|
+
|
|
1
25
|
16.0.0
|
|
2
26
|
------
|
|
3
27
|
* Update all `html.erb` and `css` files to correspond with updated store admin design language [#1102](https://github.com/Shopify/shopify_app/pull/1102)
|
data/Gemfile.lock
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
shopify_app (
|
|
4
|
+
shopify_app (17.0.3)
|
|
5
5
|
browser_sniffer (~> 1.2.2)
|
|
6
6
|
jwt (~> 2.2.1)
|
|
7
7
|
omniauth-shopify-oauth2 (~> 2.2.2)
|
|
8
|
-
rails (> 5.2.1)
|
|
8
|
+
rails (> 5.2.1, < 6.1)
|
|
9
9
|
redirect_safely (~> 1.0)
|
|
10
10
|
shopify_api (~> 9.1)
|
|
11
11
|
|
|
@@ -89,12 +89,14 @@ GEM
|
|
|
89
89
|
crass (1.0.6)
|
|
90
90
|
debug_inspector (0.0.3)
|
|
91
91
|
erubi (1.9.0)
|
|
92
|
-
faraday (1.
|
|
92
|
+
faraday (1.3.0)
|
|
93
|
+
faraday-net_http (~> 1.0)
|
|
93
94
|
multipart-post (>= 1.2, < 3)
|
|
94
95
|
ruby2_keywords
|
|
96
|
+
faraday-net_http (1.0.1)
|
|
95
97
|
globalid (0.4.2)
|
|
96
98
|
activesupport (>= 4.2.0)
|
|
97
|
-
graphql (1.
|
|
99
|
+
graphql (1.12.0)
|
|
98
100
|
graphql-client (0.16.0)
|
|
99
101
|
activesupport (>= 3.0)
|
|
100
102
|
graphql (~> 1.8)
|
|
@@ -113,15 +115,16 @@ GEM
|
|
|
113
115
|
method_source (0.9.2)
|
|
114
116
|
mimemagic (0.3.5)
|
|
115
117
|
mini_mime (1.0.2)
|
|
116
|
-
mini_portile2 (2.
|
|
118
|
+
mini_portile2 (2.5.0)
|
|
117
119
|
minitest (5.14.2)
|
|
118
120
|
mocha (1.11.2)
|
|
119
121
|
multi_json (1.15.0)
|
|
120
122
|
multi_xml (0.6.0)
|
|
121
123
|
multipart-post (2.1.1)
|
|
122
124
|
nio4r (2.5.4)
|
|
123
|
-
nokogiri (1.
|
|
124
|
-
mini_portile2 (~> 2.
|
|
125
|
+
nokogiri (1.11.1)
|
|
126
|
+
mini_portile2 (~> 2.5.0)
|
|
127
|
+
racc (~> 1.4)
|
|
125
128
|
oauth2 (1.4.4)
|
|
126
129
|
faraday (>= 0.8, < 2.0)
|
|
127
130
|
jwt (>= 1.0, < 3.0)
|
|
@@ -149,6 +152,7 @@ GEM
|
|
|
149
152
|
binding_of_caller (>= 0.7)
|
|
150
153
|
pry (>= 0.9.11)
|
|
151
154
|
public_suffix (4.0.6)
|
|
155
|
+
racc (1.5.2)
|
|
152
156
|
rack (2.2.3)
|
|
153
157
|
rack-test (1.1.0)
|
|
154
158
|
rack (>= 1.0, < 3)
|
|
@@ -203,7 +207,7 @@ GEM
|
|
|
203
207
|
rubocop-shopify (1.0.7)
|
|
204
208
|
rubocop (~> 1.4)
|
|
205
209
|
ruby-progressbar (1.10.1)
|
|
206
|
-
ruby2_keywords (0.0.
|
|
210
|
+
ruby2_keywords (0.0.4)
|
|
207
211
|
shopify_api (9.2.0)
|
|
208
212
|
activeresource (>= 4.1.0, < 6.0.0)
|
|
209
213
|
graphql-client
|
|
@@ -216,7 +220,7 @@ GEM
|
|
|
216
220
|
activesupport (>= 4.0)
|
|
217
221
|
sprockets (>= 3.0.0)
|
|
218
222
|
sqlite3 (1.4.2)
|
|
219
|
-
thor (1.0
|
|
223
|
+
thor (1.1.0)
|
|
220
224
|
thread_safe (0.3.6)
|
|
221
225
|
tzinfo (1.2.7)
|
|
222
226
|
thread_safe (~> 0.1)
|
data/README.md
CHANGED
|
@@ -8,6 +8,8 @@ Shopify App
|
|
|
8
8
|
|
|
9
9
|
Shopify Application Rails engine and generator
|
|
10
10
|
|
|
11
|
+
### NOTE: Rails 6.1 or above is not yet supported due to the new `cookies_same_site_protection` setting.
|
|
12
|
+
|
|
11
13
|
#### NOTE: Versions 8.0.0 through 8.2.3 contained a CSRF vulnerability that was addressed in version 8.2.4. Please update to version 8.2.4 if you're using an old version.
|
|
12
14
|
|
|
13
15
|
Table of Contents
|
|
@@ -72,28 +74,31 @@ The latest version of shopify_app is compatible with Rails `>= 5`. Use version `
|
|
|
72
74
|
Generators
|
|
73
75
|
----------
|
|
74
76
|
|
|
75
|
-
###
|
|
77
|
+
### API Keys
|
|
78
|
+
<!-- This anchor name `#api-keys` is linked to from user output in `templates/shopify_app.rb.tt` so beware of changing -->
|
|
79
|
+
Before starting the app, you'll need to ensure it can read the Shopify environment variables `SHOPIFY_API_KEY` and `SHOPIFY_API_SECRET`.
|
|
76
80
|
|
|
77
|
-
|
|
81
|
+
In a development environment, a common approach is to use the [dotenv-rails](https://github.com/bkeepers/dotenv) gem, along with an `.env` file in the following format:
|
|
78
82
|
|
|
79
|
-
```
|
|
80
|
-
|
|
83
|
+
```
|
|
84
|
+
SHOPIFY_API_KEY=your api key
|
|
85
|
+
SHOPIFY_API_SECRET=your api secret
|
|
81
86
|
```
|
|
82
87
|
|
|
83
|
-
|
|
88
|
+
These values can be found on the "App Setup" page in the [Shopify Partners Dashboard][dashboard].
|
|
89
|
+
(If you are using [shopify-app-cli](https://github.com/Shopify/shopify-app-cli) this `.env` file will be created automatically).
|
|
90
|
+
If you are checking your code into a code repository, ensure your `.gitignore` prevents your `.env` file from being checked into any publicly accessible code.
|
|
84
91
|
|
|
85
|
-
###
|
|
92
|
+
### Default Generator
|
|
86
93
|
|
|
87
|
-
The default
|
|
94
|
+
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:
|
|
88
95
|
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
SHOPIFY_API_SECRET=your api secret
|
|
96
|
+
```sh
|
|
97
|
+
$ rails generate shopify_app
|
|
92
98
|
```
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
After running the generator, you will need to run `rails db:migrate` to add new tables to your database. You can start your app with `bundle exec rails server` and install your app by visiting `http://localhost` in your web browser.
|
|
95
101
|
|
|
96
|
-
**You will need to load the ENV variables into your environment, you can do this with the [dot-env](https://github.com/bkeepers/dotenv) gem or any other method you wish to.**
|
|
97
102
|
|
|
98
103
|
### Install Generator
|
|
99
104
|
|
|
@@ -107,6 +112,7 @@ Options include:
|
|
|
107
112
|
(e.g. `--scope read_products, write_orders, write_products` or `--scope "read_products, write_orders, write_products"`)
|
|
108
113
|
For more information, refer to the [docs](http://docs.shopify.com/api/tutorials/oauth).
|
|
109
114
|
* `embedded` - the default is to generate an [embedded app](http://docs.shopify.com/embedded-app-sdk), if you want a legacy non-embedded app then set this to false, `--embedded false`
|
|
115
|
+
* __[Not recommended for embedded apps]__ `with-cookie-authentication` - sets up the authentication strategy of the app to use cookies. By default, it uses JWT based session tokens.
|
|
110
116
|
|
|
111
117
|
You can update any of these settings later on easily; the arguments are simply for convenience.
|
|
112
118
|
|
|
@@ -121,10 +127,10 @@ After running the `install` generator, you can start your app with `bundle exec
|
|
|
121
127
|
$ rails generate shopify_app:home_controller
|
|
122
128
|
```
|
|
123
129
|
|
|
124
|
-
This generator creates an example home controller and view which fetches and displays products using the Shopify API.
|
|
130
|
+
This generator creates an example home controller and view which fetches and displays products using the Shopify API. By default, this generator creates an unauthenticated home_controller and a sample protected products_controller.
|
|
125
131
|
|
|
126
132
|
Options include:
|
|
127
|
-
* __[
|
|
133
|
+
* __[Not recommended for embedded apps]__ `with-cookie-authentication` - This flag generates an authenticated home_controller, where the authentication strategy relies on cookies. By default, this generator creates an unauthenticated home_controller and protected sample products_controller.
|
|
128
134
|
|
|
129
135
|
### Products Controller Generator
|
|
130
136
|
|
|
@@ -279,6 +285,21 @@ The engine provides a `ShopifyApp::Authenticated` concern which should be includ
|
|
|
279
285
|
|
|
280
286
|
For backwards compatibility, the engine still provides a controller called `ShopifyApp::AuthenticatedController` which includes the `ShopifyApp::Authenticated` concern. Note that it inherits directly from `ActionController::Base`, so you will not be able to share functionality between it and your application's `ApplicationController`.
|
|
281
287
|
|
|
288
|
+
### EnsureAuthenticatedLinks
|
|
289
|
+
|
|
290
|
+
The `ShopifyApp::EnsureAuthenticatedLinks` concern helps authenticate users that access protected pages of your app directly.
|
|
291
|
+
|
|
292
|
+
Include this concern in your app's `AuthenticatedController` if your app uses session tokens with [Turbolinks](https://shopify.dev/tutorials/authenticate-server-side-rendered-apps-with-session-tokens-app-bridge-turbolinks). It adds a `before_action` filter that detects whether a session token is present or not. If a session is not found, the user is redirected to your app's splash page path (`root_path`) along with `return_to` and `shop` parameters.
|
|
293
|
+
|
|
294
|
+
Example `AuthenticatedController`:
|
|
295
|
+
|
|
296
|
+
```rb
|
|
297
|
+
class AuthenticatedController < ApplicationController
|
|
298
|
+
include ShopifyApp::EnsureAuthenticatedLinks
|
|
299
|
+
include ShopifyApp::Authenticated
|
|
300
|
+
end
|
|
301
|
+
```
|
|
302
|
+
|
|
282
303
|
### AfterAuthenticate Job
|
|
283
304
|
|
|
284
305
|
If your app needs to perform specific actions after the user is authenticated successfully (i.e. every time a new session is created), ShopifyApp can queue or run a job of your choosing (note that we already provide support for automatically creating Webhooks and Scripttags). To configure the after authenticate job, update your initializer as follows:
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShopifyApp
|
|
4
|
+
module EnsureAuthenticatedLinks
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
before_action :redirect_to_splash_page, if: :missing_expected_jwt?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def redirect_to_splash_page
|
|
14
|
+
splash_page_path = root_path(return_to: request.fullpath, shop: current_shopify_domain)
|
|
15
|
+
redirect_to(splash_page_path)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def missing_expected_jwt?
|
|
19
|
+
jwt_shopify_domain.blank?
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -30,16 +30,12 @@ module ShopifyApp
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def respond_with_user_token_flow
|
|
33
|
-
Rails.logger.debug("[ShopifyApp::CallbackController] Redirecting for user token...")
|
|
34
33
|
redirect_to(login_url_with_optional_shop)
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
def store_access_token_and_build_session
|
|
38
37
|
if native_browser_request?
|
|
39
|
-
Rails.logger.debug("[ShopifyApp::CallbackController] Not a JWT request. Resetting session options...")
|
|
40
38
|
reset_session_options
|
|
41
|
-
else
|
|
42
|
-
Rails.logger.debug("[ShopifyApp::CallbackController] JWT request detected. Setting shopify session...")
|
|
43
39
|
end
|
|
44
40
|
set_shopify_session
|
|
45
41
|
end
|
|
@@ -62,10 +58,8 @@ module ShopifyApp
|
|
|
62
58
|
|
|
63
59
|
def respond_with_error
|
|
64
60
|
if jwt_request?
|
|
65
|
-
Rails.logger.debug("[ShopifyApp::CallbackController] Invalid JWT auth detected.")
|
|
66
61
|
head(:unauthorized)
|
|
67
62
|
else
|
|
68
|
-
Rails.logger.debug("[ShopifyApp::CallbackController] Invalid non JWT auth detected.")
|
|
69
63
|
flash[:error] = I18n.t('could_not_log_in')
|
|
70
64
|
redirect_to(login_url_with_optional_shop)
|
|
71
65
|
end
|
|
@@ -95,6 +89,14 @@ module ShopifyApp
|
|
|
95
89
|
auth_hash.uid
|
|
96
90
|
end
|
|
97
91
|
|
|
92
|
+
def offline_access_token
|
|
93
|
+
ShopifyApp::SessionRepository.retrieve_shop_session_by_shopify_domain(shop_name)&.token
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def online_access_token
|
|
97
|
+
ShopifyApp::SessionRepository.retrieve_user_session_by_shopify_user_id(associated_user_id)&.token
|
|
98
|
+
end
|
|
99
|
+
|
|
98
100
|
def associated_user
|
|
99
101
|
return unless auth_hash.dig('extra', 'associated_user').present?
|
|
100
102
|
|
|
@@ -138,7 +140,7 @@ module ShopifyApp
|
|
|
138
140
|
|
|
139
141
|
WebhooksManager.queue(
|
|
140
142
|
shop_name,
|
|
141
|
-
|
|
143
|
+
offline_access_token || online_access_token,
|
|
142
144
|
ShopifyApp.configuration.webhooks
|
|
143
145
|
)
|
|
144
146
|
end
|
|
@@ -148,7 +150,7 @@ module ShopifyApp
|
|
|
148
150
|
|
|
149
151
|
ScripttagsManager.queue(
|
|
150
152
|
shop_name,
|
|
151
|
-
|
|
153
|
+
offline_access_token || online_access_token,
|
|
152
154
|
ShopifyApp.configuration.scripttags
|
|
153
155
|
)
|
|
154
156
|
end
|
|
@@ -10,19 +10,14 @@ module ShopifyApp
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def new
|
|
13
|
-
if sanitized_shop_name.present?
|
|
14
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Sanitized shop name present. Authenticating...")
|
|
15
|
-
authenticate
|
|
16
|
-
end
|
|
13
|
+
authenticate if sanitized_shop_name.present?
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
def create
|
|
20
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Authenticating...")
|
|
21
17
|
authenticate
|
|
22
18
|
end
|
|
23
19
|
|
|
24
20
|
def enable_cookies
|
|
25
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Enabling cookies...")
|
|
26
21
|
return unless validate_shop_presence
|
|
27
22
|
|
|
28
23
|
render(:enable_cookies, layout: false, locals: {
|
|
@@ -45,7 +40,6 @@ module ShopifyApp
|
|
|
45
40
|
end
|
|
46
41
|
|
|
47
42
|
def granted_storage_access
|
|
48
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Granted storage access.")
|
|
49
43
|
return unless validate_shop_presence
|
|
50
44
|
|
|
51
45
|
session['shopify.granted_storage_access'] = true
|
|
@@ -56,7 +50,6 @@ module ShopifyApp
|
|
|
56
50
|
end
|
|
57
51
|
|
|
58
52
|
def destroy
|
|
59
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Resetting session.")
|
|
60
53
|
reset_session
|
|
61
54
|
flash[:notice] = I18n.t('.logged_out')
|
|
62
55
|
redirect_to(login_url_with_optional_shop)
|
|
@@ -73,23 +66,18 @@ module ShopifyApp
|
|
|
73
66
|
set_user_tokens_option
|
|
74
67
|
|
|
75
68
|
if user_agent_can_partition_cookies
|
|
76
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Authenticating with partitioning...")
|
|
77
69
|
authenticate_with_partitioning
|
|
78
70
|
else
|
|
79
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Authenticating normally...")
|
|
80
71
|
authenticate_normally
|
|
81
72
|
end
|
|
82
73
|
end
|
|
83
74
|
|
|
84
75
|
def authenticate_normally
|
|
85
76
|
if request_storage_access?
|
|
86
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Redirecting to request storage access...")
|
|
87
77
|
redirect_to_request_storage_access
|
|
88
78
|
elsif authenticate_in_context?
|
|
89
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Authenticating in context...")
|
|
90
79
|
authenticate_in_context
|
|
91
80
|
else
|
|
92
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Authenticating at top level...")
|
|
93
81
|
authenticate_at_top_level
|
|
94
82
|
end
|
|
95
83
|
end
|
|
@@ -107,7 +95,6 @@ module ShopifyApp
|
|
|
107
95
|
# rubocop:disable Lint/SuppressedException
|
|
108
96
|
def set_user_tokens_option
|
|
109
97
|
if shop_session.blank?
|
|
110
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Shop session is blank.")
|
|
111
98
|
session[:user_tokens] = false
|
|
112
99
|
return
|
|
113
100
|
end
|
|
@@ -130,7 +117,6 @@ module ShopifyApp
|
|
|
130
117
|
def validate_shop_presence
|
|
131
118
|
@shop = sanitized_shop_name
|
|
132
119
|
unless @shop
|
|
133
|
-
Rails.logger.debug("[ShopifyApp::SessionsController] Invalid shop detected.")
|
|
134
120
|
render_invalid_shop_error
|
|
135
121
|
return false
|
|
136
122
|
end
|
data/config/locales/de.yml
CHANGED
|
@@ -4,19 +4,19 @@ de:
|
|
|
4
4
|
could_not_log_in: Shopify Store Login fehlgeschlagen
|
|
5
5
|
invalid_shop_url: Ungültige Shop-Domain
|
|
6
6
|
enable_cookies_heading: Cookies von %{app} aktivieren
|
|
7
|
-
enable_cookies_body:
|
|
8
|
-
|
|
9
|
-
enable_cookies_footer: Mithilfe von Cookies kann die App
|
|
10
|
-
|
|
11
|
-
Sie laufen nach 30 Tagen ab.
|
|
7
|
+
enable_cookies_body: Du musst Cookies in diesem Browser manuell aktivieren, um %{app}
|
|
8
|
+
in Shopify verwenden zu können.
|
|
9
|
+
enable_cookies_footer: Mithilfe von Cookies kann die App dich authentifizieren,
|
|
10
|
+
indem deine Einstellungen und personenbezogenen Daten vorübergehend gespeichert
|
|
11
|
+
werden. Sie laufen nach 30 Tagen ab.
|
|
12
12
|
enable_cookies_action: Cookies aktivieren
|
|
13
|
-
top_level_interaction_heading:
|
|
14
|
-
top_level_interaction_body:
|
|
15
|
-
auf Cookies bitten, bevor Shopify sie für
|
|
13
|
+
top_level_interaction_heading: Dein Browser muss %{app} authentifizieren
|
|
14
|
+
top_level_interaction_body: Dein Browser verlangt, dass Apps wie %{app} dich um
|
|
15
|
+
Zugriff auf Cookies bitten, bevor Shopify sie für dich öffnen kann.
|
|
16
16
|
top_level_interaction_action: Weiter
|
|
17
17
|
request_storage_access_heading: "%{app} braucht Zugriff auf Cookies"
|
|
18
|
-
request_storage_access_body: Damit kann die App
|
|
19
|
-
Einstellungen und personenbezogenen Daten vorübergehend gespeichert werden.
|
|
20
|
-
|
|
18
|
+
request_storage_access_body: Damit kann die App dich authentifizieren, indem deine
|
|
19
|
+
Einstellungen und personenbezogenen Daten vorübergehend gespeichert werden. Klicke
|
|
20
|
+
auf "Weiter" und erlaube Cookies, um die App zu verwenden.
|
|
21
21
|
request_storage_access_footer: Cookies laufen nach 30 Tagen ab.
|
|
22
22
|
request_storage_access_action: Weiter
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
vi:
|
|
3
|
+
logged_out: Đã đăng xuất thành công
|
|
4
|
+
could_not_log_in: Không thể đăng nhập vào cửa hàng trên Shopify
|
|
5
|
+
invalid_shop_url: Miền cửa hàng không hợp lệ
|
|
6
|
+
enable_cookies_heading: Bật cookie từ %{app}
|
|
7
|
+
enable_cookies_body: Bạn phải bật cookie trong trình duyệt này theo cách thủ công
|
|
8
|
+
để sử dụng %{app} trong Shopify.
|
|
9
|
+
enable_cookies_footer: Cookie cho phép ứng dụng xác thực bạn bằng cách tạm thời
|
|
10
|
+
lưu trữ tùy chọn và thông tin cá nhân của bạn. Những thông tin này sẽ hết hạn
|
|
11
|
+
sau 30 ngày.
|
|
12
|
+
enable_cookies_action: Bật cookie
|
|
13
|
+
top_level_interaction_heading: Trình duyệt của bạn cần xác thực %{app}
|
|
14
|
+
top_level_interaction_body: Trình duyệt của bạn cần các ứng dụng như %{app} để yêu
|
|
15
|
+
cầu quyền truy cập vào cookie thì Shopify mới có thể mở giúp bạn.
|
|
16
|
+
top_level_interaction_action: Tiếp tục
|
|
17
|
+
request_storage_access_heading: "%{app} cần quyền truy cập cookie"
|
|
18
|
+
request_storage_access_body: Nhờ vậy, ứng dụng có thể xác thực bạn bằng cách tạm
|
|
19
|
+
thời lưu trữ thông tin cá nhân của bạn. Nhấp vào tiếp tục và cho phép cookie sử
|
|
20
|
+
dụng ứng dụng.
|
|
21
|
+
request_storage_access_footer: Cookie sẽ hết hạn sau 30 ngày.
|
|
22
|
+
request_storage_access_action: Tiếp tục
|
data/config/locales/zh-CN.yml
CHANGED
|
@@ -8,7 +8,7 @@ zh-CN:
|
|
|
8
8
|
enable_cookies_footer: Cookie 使此应用能够通过暂时存储您的偏好设置和个人信息来验证您的身份。这些信息将在 30 天后过期。
|
|
9
9
|
enable_cookies_action: 启用 Cookie
|
|
10
10
|
top_level_interaction_heading: 您的浏览器需要对 %{app} 进行验证
|
|
11
|
-
top_level_interaction_body: 您的浏览器要求类似 %{app}
|
|
11
|
+
top_level_interaction_body: 您的浏览器要求类似 %{app} 的应用向您申请访问 Cookie,之后 Shopify 才能为您打开它。
|
|
12
12
|
top_level_interaction_action: 继续
|
|
13
13
|
request_storage_access_heading: "%{app} 需要访问 Cookie"
|
|
14
14
|
request_storage_access_body: 这使此应用能够通过暂时存储您的个人信息来验证您的身份。单击继续并启用 Cookie 以使用此应用。
|
data/docs/Releasing.md
CHANGED
|
@@ -5,14 +5,16 @@
|
|
|
5
5
|
1. Create a pull request with the following changes:
|
|
6
6
|
- Update the version of ShopifyApp in lib/shopify_app/version.rb
|
|
7
7
|
- Update the version of shopify_app in package.json
|
|
8
|
+
- Run `bundle` to update `Gemfile.lock`
|
|
8
9
|
- Add a CHANGELOG entry for the new release with the date
|
|
9
10
|
- Change the title of the PR to something like: "Packaging for release X.Y.Z"
|
|
10
11
|
1. Merge your pull request
|
|
11
12
|
1. Checkout and pull from master so you have the latest version of the shopify_app
|
|
12
13
|
1. Tag the HEAD with the version
|
|
13
|
-
```bash
|
|
14
|
-
$ git tag -f vX.Y.Z && git push --tags --force
|
|
15
|
-
```
|
|
14
|
+
```bash
|
|
15
|
+
$ git tag -f vX.Y.Z && git push --tags --force
|
|
16
|
+
```
|
|
17
|
+
1. Check that Create Release workflow successfully runs
|
|
16
18
|
1. Use Shipit to build and push the gem
|
|
17
19
|
|
|
18
20
|
If you see an error like 'You need to create the vX.Y.X tag first', clear git
|
|
@@ -6,16 +6,15 @@ module ShopifyApp
|
|
|
6
6
|
class HomeControllerGenerator < Rails::Generators::Base
|
|
7
7
|
source_root File.expand_path('../templates', __FILE__)
|
|
8
8
|
|
|
9
|
-
class_option :
|
|
9
|
+
class_option :with_cookie_authentication, type: :boolean, default: false
|
|
10
|
+
class_option :embedded, type: :string, default: 'true'
|
|
10
11
|
|
|
11
12
|
def create_home_controller
|
|
12
|
-
@with_session_token = options['with_session_token']
|
|
13
|
-
|
|
14
13
|
template(home_controller_template, 'app/controllers/home_controller.rb')
|
|
15
14
|
end
|
|
16
15
|
|
|
17
16
|
def create_products_controller
|
|
18
|
-
generate("shopify_app:products_controller")
|
|
17
|
+
generate("shopify_app:products_controller") unless with_cookie_authentication?
|
|
19
18
|
end
|
|
20
19
|
|
|
21
20
|
def create_home_index_view
|
|
@@ -28,16 +27,26 @@ module ShopifyApp
|
|
|
28
27
|
|
|
29
28
|
private
|
|
30
29
|
|
|
30
|
+
def embedded?
|
|
31
|
+
options['embedded'] == 'true'
|
|
32
|
+
end
|
|
33
|
+
|
|
31
34
|
def embedded_app?
|
|
32
35
|
ShopifyApp.configuration.embedded_app?
|
|
33
36
|
end
|
|
34
37
|
|
|
35
|
-
def
|
|
36
|
-
|
|
38
|
+
def with_cookie_authentication?
|
|
39
|
+
options['with_cookie_authentication']
|
|
37
40
|
end
|
|
38
41
|
|
|
39
42
|
def home_controller_template
|
|
40
|
-
|
|
43
|
+
return 'unauthenticated_home_controller.rb' unless authenticated_home_controller_required?
|
|
44
|
+
|
|
45
|
+
'home_controller.rb'
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def authenticated_home_controller_required?
|
|
49
|
+
with_cookie_authentication? || !embedded? || !embedded_app?
|
|
41
50
|
end
|
|
42
51
|
end
|
|
43
52
|
end
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
rel="stylesheet"
|
|
8
8
|
href="https://unpkg.com/@shopify/polaris@4.25.0/styles.min.css"
|
|
9
9
|
/>
|
|
10
|
-
<%
|
|
10
|
+
<% unless with_cookie_authentication? %> <script>
|
|
11
11
|
document.addEventListener("DOMContentLoaded", async function() {
|
|
12
12
|
var SessionToken = window["app-bridge"].actions.SessionToken
|
|
13
13
|
var app = window.app;
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
<% end %> </head>
|
|
48
48
|
<body>
|
|
49
49
|
<h2>Products</h2>
|
|
50
|
-
<%
|
|
50
|
+
<% unless with_cookie_authentication? %> <div id="products"><br>Loading...</div><% else %>
|
|
51
51
|
<ul>
|
|
52
52
|
<%% @products.each do |product| %>
|
|
53
53
|
<li><%%= link_to product.title, "https://#{@current_shopify_session.domain}/admin/products/#{product.id}", target: "_top" %></li>
|
|
@@ -55,17 +55,17 @@
|
|
|
55
55
|
</ul>
|
|
56
56
|
|
|
57
57
|
<hr>
|
|
58
|
-
|
|
58
|
+
<% end %>
|
|
59
59
|
<h2>Webhooks</h2>
|
|
60
60
|
|
|
61
61
|
<%% if @webhooks.present? %>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
<ul>
|
|
63
|
+
<%% @webhooks.each do |webhook| %>
|
|
64
|
+
<li><%%= webhook.topic %> : <%%= webhook.address %></li>
|
|
65
|
+
<%% end %>
|
|
66
|
+
</ul>
|
|
67
67
|
<%% else %>
|
|
68
|
-
|
|
69
|
-
<%% end
|
|
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 %>
|
|
70
70
|
</body>
|
|
71
71
|
</html>
|
|
@@ -11,6 +11,7 @@ module ShopifyApp
|
|
|
11
11
|
class_option :scope, type: :array, default: ['read_products']
|
|
12
12
|
class_option :embedded, type: :string, default: 'true'
|
|
13
13
|
class_option :api_version, type: :string, default: nil
|
|
14
|
+
class_option :with_cookie_authentication, type: :boolean, default: false
|
|
14
15
|
|
|
15
16
|
def create_shopify_app_initializer
|
|
16
17
|
@application_name = format_array_argument(options['application_name'])
|
|
@@ -78,6 +79,10 @@ module ShopifyApp
|
|
|
78
79
|
def format_array_argument(array)
|
|
79
80
|
array.join(' ').tr('"', '')
|
|
80
81
|
end
|
|
82
|
+
|
|
83
|
+
def with_cookie_authentication?
|
|
84
|
+
options['with_cookie_authentication'] || !embedded_app?
|
|
85
|
+
end
|
|
81
86
|
end
|
|
82
87
|
end
|
|
83
88
|
end
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
ShopifyApp.configure do |config|
|
|
2
2
|
config.application_name = "<%= @application_name %>"
|
|
3
|
-
config.api_key = ENV.fetch('SHOPIFY_API_KEY', '').presence || raise('Missing SHOPIFY_API_KEY')
|
|
4
|
-
config.secret = ENV.fetch('SHOPIFY_API_SECRET', '').presence || raise('Missing SHOPIFY_API_SECRET')
|
|
5
3
|
config.old_secret = "<%= @old_secret %>"
|
|
6
4
|
config.scope = "<%= @scope %>" # Consult this page for more scope options:
|
|
7
|
-
|
|
5
|
+
# https://help.shopify.com/en/api/getting-started/authentication/oauth/scopes
|
|
8
6
|
config.embedded_app = <%= embedded_app? %>
|
|
9
7
|
config.after_authenticate_job = false
|
|
10
8
|
config.api_version = "<%= @api_version %>"
|
|
11
9
|
config.shop_session_repository = 'Shop'
|
|
12
|
-
config.allow_jwt_authentication =
|
|
10
|
+
config.allow_jwt_authentication = <%= !with_cookie_authentication? %>
|
|
11
|
+
config.allow_cookie_authentication = <%= with_cookie_authentication? %>
|
|
12
|
+
|
|
13
|
+
config.api_key = ENV.fetch('SHOPIFY_API_KEY', '').presence
|
|
14
|
+
config.secret = ENV.fetch('SHOPIFY_API_SECRET', '').presence
|
|
15
|
+
if defined? Rails::Server
|
|
16
|
+
raise('Missing SHOPIFY_API_KEY. See https://github.com/Shopify/shopify_app#api-keys') unless config.api_key
|
|
17
|
+
raise('Missing SHOPIFY_API_SECRET. See https://github.com/Shopify/shopify_app#api-keys') unless config.secret
|
|
18
|
+
end
|
|
13
19
|
end
|
|
14
20
|
|
|
15
21
|
# ShopifyApp::Utils.fetch_known_api_versions # Uncomment to fetch known api versions from shopify servers on boot
|
|
@@ -39,12 +39,15 @@ module ShopifyApp
|
|
|
39
39
|
# allow enabling jwt headers for authentication
|
|
40
40
|
attr_accessor :allow_jwt_authentication
|
|
41
41
|
|
|
42
|
+
attr_accessor :allow_cookie_authentication
|
|
43
|
+
|
|
42
44
|
def initialize
|
|
43
45
|
@root_url = '/'
|
|
44
46
|
@myshopify_domain = 'myshopify.com'
|
|
45
47
|
@scripttags_manager_queue_name = Rails.application.config.active_job.queue_name
|
|
46
48
|
@webhooks_manager_queue_name = Rails.application.config.active_job.queue_name
|
|
47
49
|
@disable_webpacker = ENV['SHOPIFY_APP_DISABLE_WEBPACKER'].present?
|
|
50
|
+
@allow_cookie_authentication = true
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
def login_url
|
|
@@ -13,12 +13,10 @@ module ShopifyApp
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def set_top_level_oauth_cookie
|
|
16
|
-
Rails.logger.debug("[ShopifyApp::Itp] Setting top level oauth cookie...")
|
|
17
16
|
session['shopify.top_level_oauth'] = true
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
def clear_top_level_oauth_cookie
|
|
21
|
-
Rails.logger.debug("[ShopifyApp::Itp] Clearing top level oauth cookie...")
|
|
22
20
|
session.delete('shopify.top_level_oauth')
|
|
23
21
|
end
|
|
24
22
|
|
|
@@ -18,24 +18,18 @@ module ShopifyApp
|
|
|
18
18
|
|
|
19
19
|
def activate_shopify_session
|
|
20
20
|
if user_session_expected? && user_session.blank?
|
|
21
|
-
Rails.logger.debug("[ShopifyApp::LoginProtection] User session required. Redirecting to login...")
|
|
22
21
|
signal_access_token_required
|
|
23
22
|
return redirect_to_login
|
|
24
23
|
end
|
|
25
24
|
|
|
26
|
-
if current_shopify_session.blank?
|
|
27
|
-
Rails.logger.debug("[ShopifyApp::LoginProtection] Current shopify session is blank. Redirecting to login...")
|
|
28
|
-
return redirect_to_login
|
|
29
|
-
end
|
|
25
|
+
return redirect_to_login if current_shopify_session.blank?
|
|
30
26
|
|
|
31
27
|
clear_top_level_oauth_cookie
|
|
32
28
|
|
|
33
29
|
begin
|
|
34
|
-
Rails.logger.debug("[ShopifyApp::LoginProtection] Activating session...")
|
|
35
30
|
ShopifyAPI::Base.activate_session(current_shopify_session)
|
|
36
31
|
yield
|
|
37
32
|
ensure
|
|
38
|
-
Rails.logger.debug("[ShopifyApp::LoginProtection] Clearing session...")
|
|
39
33
|
ShopifyAPI::Base.clear_session
|
|
40
34
|
end
|
|
41
35
|
end
|
|
@@ -57,6 +51,7 @@ module ShopifyApp
|
|
|
57
51
|
end
|
|
58
52
|
|
|
59
53
|
def user_session_by_cookie
|
|
54
|
+
return unless ShopifyApp.configuration.allow_cookie_authentication
|
|
60
55
|
return unless session[:user_id].present?
|
|
61
56
|
ShopifyApp::SessionRepository.retrieve_user_session(session[:user_id])
|
|
62
57
|
end
|
|
@@ -72,18 +67,14 @@ module ShopifyApp
|
|
|
72
67
|
end
|
|
73
68
|
|
|
74
69
|
def shop_session_by_cookie
|
|
70
|
+
return unless ShopifyApp.configuration.allow_cookie_authentication
|
|
75
71
|
return unless session[:shop_id].present?
|
|
76
72
|
ShopifyApp::SessionRepository.retrieve_shop_session(session[:shop_id])
|
|
77
73
|
end
|
|
78
74
|
|
|
79
75
|
def login_again_if_different_user_or_shop
|
|
80
76
|
if session[:user_session].present? && params[:session].present? # session data was sent/stored correctly
|
|
81
|
-
Rails.logger.debug("[ShopifyApp::LoginProtection] Session data was sent/stored correctly.")
|
|
82
77
|
clear_session = session[:user_session] != params[:session] # current user is different from stored user
|
|
83
|
-
if clear_session
|
|
84
|
-
Rails.logger.debug("[ShopifyApp::LoginProtection] Current user is different from stored user.")
|
|
85
|
-
end
|
|
86
|
-
clear_session
|
|
87
78
|
end
|
|
88
79
|
|
|
89
80
|
if current_shopify_session &&
|
|
@@ -93,7 +84,6 @@ module ShopifyApp
|
|
|
93
84
|
end
|
|
94
85
|
|
|
95
86
|
if clear_session
|
|
96
|
-
Rails.logger.debug("[ShopifyApp::LoginProtection] Clearing shopify session and redirecting to login...")
|
|
97
87
|
clear_shopify_session
|
|
98
88
|
redirect_to_login
|
|
99
89
|
end
|
data/lib/shopify_app/version.rb
CHANGED
data/package.json
CHANGED
data/shopify_app.gemspec
CHANGED
|
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
|
14
14
|
s.metadata['allowed_push_host'] = 'https://rubygems.org'
|
|
15
15
|
|
|
16
16
|
s.add_runtime_dependency('browser_sniffer', '~> 1.2.2')
|
|
17
|
-
s.add_runtime_dependency('rails', '> 5.2.1')
|
|
17
|
+
s.add_runtime_dependency('rails', '> 5.2.1', '< 6.1')
|
|
18
18
|
s.add_runtime_dependency('shopify_api', '~> 9.1')
|
|
19
19
|
s.add_runtime_dependency('omniauth-shopify-oauth2', '~> 2.2.2')
|
|
20
20
|
s.add_runtime_dependency('jwt', '~> 2.2.1')
|
data/translation.yml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
source_language: en
|
|
2
|
-
target_languages: [cs, da, de, es, fi, fr, hi, it, ja, ko, ms, nb, nl, pl, pt-BR, pt-PT, sv, th, tr, zh-CN, zh-TW]
|
|
2
|
+
target_languages: [cs, da, de, es, fi, fr, hi, it, ja, ko, ms, nb, nl, pl, pt-BR, pt-PT, sv, th, tr, vi, zh-CN, zh-TW]
|
|
3
3
|
components:
|
|
4
4
|
- name: 'merchant'
|
|
5
5
|
paths:
|
data/yarn.lock
CHANGED
|
@@ -1347,11 +1347,6 @@ async-each@^1.0.1:
|
|
|
1347
1347
|
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
|
|
1348
1348
|
integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
|
|
1349
1349
|
|
|
1350
|
-
async-limiter@~1.0.0:
|
|
1351
|
-
version "1.0.1"
|
|
1352
|
-
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
|
|
1353
|
-
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
|
|
1354
|
-
|
|
1355
1350
|
atob@^2.1.2:
|
|
1356
1351
|
version "2.1.2"
|
|
1357
1352
|
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
|
@@ -1419,10 +1414,10 @@ balanced-match@^1.0.0:
|
|
|
1419
1414
|
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
|
1420
1415
|
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
|
1421
1416
|
|
|
1422
|
-
base64-arraybuffer@0.1.
|
|
1423
|
-
version "0.1.
|
|
1424
|
-
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.
|
|
1425
|
-
integrity sha1-
|
|
1417
|
+
base64-arraybuffer@0.1.4:
|
|
1418
|
+
version "0.1.4"
|
|
1419
|
+
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812"
|
|
1420
|
+
integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=
|
|
1426
1421
|
|
|
1427
1422
|
base64-js@^1.0.2:
|
|
1428
1423
|
version "1.3.1"
|
|
@@ -1447,13 +1442,6 @@ base@^0.11.1:
|
|
|
1447
1442
|
mixin-deep "^1.2.0"
|
|
1448
1443
|
pascalcase "^0.1.1"
|
|
1449
1444
|
|
|
1450
|
-
better-assert@~1.0.0:
|
|
1451
|
-
version "1.0.2"
|
|
1452
|
-
resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522"
|
|
1453
|
-
integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=
|
|
1454
|
-
dependencies:
|
|
1455
|
-
callsite "1.0.0"
|
|
1456
|
-
|
|
1457
1445
|
big.js@^5.2.2:
|
|
1458
1446
|
version "5.2.2"
|
|
1459
1447
|
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
|
|
@@ -1689,11 +1677,6 @@ cache-base@^1.0.1:
|
|
|
1689
1677
|
union-value "^1.0.0"
|
|
1690
1678
|
unset-value "^1.0.0"
|
|
1691
1679
|
|
|
1692
|
-
callsite@1.0.0:
|
|
1693
|
-
version "1.0.0"
|
|
1694
|
-
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
|
|
1695
|
-
integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
|
|
1696
|
-
|
|
1697
1680
|
camelcase@^5.0.0, camelcase@^5.3.1:
|
|
1698
1681
|
version "5.3.1"
|
|
1699
1682
|
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
|
|
@@ -1954,10 +1937,10 @@ convert-source-map@^1.7.0:
|
|
|
1954
1937
|
dependencies:
|
|
1955
1938
|
safe-buffer "~5.1.1"
|
|
1956
1939
|
|
|
1957
|
-
cookie
|
|
1958
|
-
version "0.
|
|
1959
|
-
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.
|
|
1960
|
-
integrity
|
|
1940
|
+
cookie@~0.4.1:
|
|
1941
|
+
version "0.4.1"
|
|
1942
|
+
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1"
|
|
1943
|
+
integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==
|
|
1961
1944
|
|
|
1962
1945
|
copy-concurrently@^1.0.0:
|
|
1963
1946
|
version "1.0.5"
|
|
@@ -2236,45 +2219,45 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
|
|
2236
2219
|
dependencies:
|
|
2237
2220
|
once "^1.4.0"
|
|
2238
2221
|
|
|
2239
|
-
engine.io-client@~3.
|
|
2240
|
-
version "3.
|
|
2241
|
-
resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.
|
|
2242
|
-
integrity sha512-
|
|
2222
|
+
engine.io-client@~3.5.0:
|
|
2223
|
+
version "3.5.0"
|
|
2224
|
+
resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.5.0.tgz#fc1b4d9616288ce4f2daf06dcf612413dec941c7"
|
|
2225
|
+
integrity sha512-12wPRfMrugVw/DNyJk34GQ5vIVArEcVMXWugQGGuw2XxUSztFNmJggZmv8IZlLyEdnpO1QB9LkcjeWewO2vxtA==
|
|
2243
2226
|
dependencies:
|
|
2244
2227
|
component-emitter "~1.3.0"
|
|
2245
2228
|
component-inherit "0.0.3"
|
|
2246
|
-
debug "~
|
|
2229
|
+
debug "~3.1.0"
|
|
2247
2230
|
engine.io-parser "~2.2.0"
|
|
2248
2231
|
has-cors "1.1.0"
|
|
2249
2232
|
indexof "0.0.1"
|
|
2250
|
-
parseqs "0.0.
|
|
2251
|
-
parseuri "0.0.
|
|
2252
|
-
ws "~
|
|
2233
|
+
parseqs "0.0.6"
|
|
2234
|
+
parseuri "0.0.6"
|
|
2235
|
+
ws "~7.4.2"
|
|
2253
2236
|
xmlhttprequest-ssl "~1.5.4"
|
|
2254
2237
|
yeast "0.1.2"
|
|
2255
2238
|
|
|
2256
2239
|
engine.io-parser@~2.2.0:
|
|
2257
|
-
version "2.2.
|
|
2258
|
-
resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.
|
|
2259
|
-
integrity sha512-
|
|
2240
|
+
version "2.2.1"
|
|
2241
|
+
resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.1.tgz#57ce5611d9370ee94f99641b589f94c97e4f5da7"
|
|
2242
|
+
integrity sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==
|
|
2260
2243
|
dependencies:
|
|
2261
2244
|
after "0.8.2"
|
|
2262
2245
|
arraybuffer.slice "~0.0.7"
|
|
2263
|
-
base64-arraybuffer "0.1.
|
|
2246
|
+
base64-arraybuffer "0.1.4"
|
|
2264
2247
|
blob "0.0.5"
|
|
2265
2248
|
has-binary2 "~1.0.2"
|
|
2266
2249
|
|
|
2267
|
-
engine.io@~3.
|
|
2268
|
-
version "3.
|
|
2269
|
-
resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.
|
|
2270
|
-
integrity sha512-
|
|
2250
|
+
engine.io@~3.5.0:
|
|
2251
|
+
version "3.5.0"
|
|
2252
|
+
resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.5.0.tgz#9d6b985c8a39b1fe87cd91eb014de0552259821b"
|
|
2253
|
+
integrity sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==
|
|
2271
2254
|
dependencies:
|
|
2272
2255
|
accepts "~1.3.4"
|
|
2273
2256
|
base64id "2.0.0"
|
|
2274
|
-
cookie "0.
|
|
2257
|
+
cookie "~0.4.1"
|
|
2275
2258
|
debug "~4.1.0"
|
|
2276
2259
|
engine.io-parser "~2.2.0"
|
|
2277
|
-
ws "
|
|
2260
|
+
ws "~7.4.2"
|
|
2278
2261
|
|
|
2279
2262
|
enhanced-resolve@^4.3.0:
|
|
2280
2263
|
version "4.3.0"
|
|
@@ -3480,17 +3463,17 @@ miller-rabin@^4.0.0:
|
|
|
3480
3463
|
bn.js "^4.0.0"
|
|
3481
3464
|
brorand "^1.0.1"
|
|
3482
3465
|
|
|
3483
|
-
mime-db@1.
|
|
3484
|
-
version "1.
|
|
3485
|
-
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.
|
|
3486
|
-
integrity sha512
|
|
3466
|
+
mime-db@1.45.0:
|
|
3467
|
+
version "1.45.0"
|
|
3468
|
+
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea"
|
|
3469
|
+
integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==
|
|
3487
3470
|
|
|
3488
3471
|
mime-types@~2.1.24:
|
|
3489
|
-
version "2.1.
|
|
3490
|
-
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.
|
|
3491
|
-
integrity sha512-
|
|
3472
|
+
version "2.1.28"
|
|
3473
|
+
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd"
|
|
3474
|
+
integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==
|
|
3492
3475
|
dependencies:
|
|
3493
|
-
mime-db "1.
|
|
3476
|
+
mime-db "1.45.0"
|
|
3494
3477
|
|
|
3495
3478
|
mime@^2.4.4, mime@^2.4.5:
|
|
3496
3479
|
version "2.4.6"
|
|
@@ -3610,11 +3593,16 @@ ms@2.0.0:
|
|
|
3610
3593
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
|
3611
3594
|
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
|
3612
3595
|
|
|
3613
|
-
ms@2.1.2
|
|
3596
|
+
ms@2.1.2:
|
|
3614
3597
|
version "2.1.2"
|
|
3615
3598
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
|
3616
3599
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
|
3617
3600
|
|
|
3601
|
+
ms@^2.1.1:
|
|
3602
|
+
version "2.1.3"
|
|
3603
|
+
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
|
3604
|
+
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
|
3605
|
+
|
|
3618
3606
|
nan@^2.12.1:
|
|
3619
3607
|
version "2.14.1"
|
|
3620
3608
|
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
|
|
@@ -3709,11 +3697,6 @@ object-assign@^4.1.1:
|
|
|
3709
3697
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
|
3710
3698
|
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
|
3711
3699
|
|
|
3712
|
-
object-component@0.0.3:
|
|
3713
|
-
version "0.0.3"
|
|
3714
|
-
resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291"
|
|
3715
|
-
integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=
|
|
3716
|
-
|
|
3717
3700
|
object-copy@^0.1.0:
|
|
3718
3701
|
version "0.1.0"
|
|
3719
3702
|
resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
|
|
@@ -3841,19 +3824,15 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5:
|
|
|
3841
3824
|
pbkdf2 "^3.0.3"
|
|
3842
3825
|
safe-buffer "^5.1.1"
|
|
3843
3826
|
|
|
3844
|
-
parseqs@0.0.
|
|
3845
|
-
version "0.0.
|
|
3846
|
-
resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.
|
|
3847
|
-
integrity
|
|
3848
|
-
dependencies:
|
|
3849
|
-
better-assert "~1.0.0"
|
|
3827
|
+
parseqs@0.0.6:
|
|
3828
|
+
version "0.0.6"
|
|
3829
|
+
resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.6.tgz#8e4bb5a19d1cdc844a08ac974d34e273afa670d5"
|
|
3830
|
+
integrity sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==
|
|
3850
3831
|
|
|
3851
|
-
parseuri@0.0.
|
|
3852
|
-
version "0.0.
|
|
3853
|
-
resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.
|
|
3854
|
-
integrity
|
|
3855
|
-
dependencies:
|
|
3856
|
-
better-assert "~1.0.0"
|
|
3832
|
+
parseuri@0.0.6:
|
|
3833
|
+
version "0.0.6"
|
|
3834
|
+
resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.6.tgz#e1496e829e3ac2ff47f39a4dd044b32823c4a25a"
|
|
3835
|
+
integrity sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==
|
|
3857
3836
|
|
|
3858
3837
|
parseurl@~1.3.3:
|
|
3859
3838
|
version "1.3.3"
|
|
@@ -4436,32 +4415,29 @@ socket.io-adapter@~1.1.0:
|
|
|
4436
4415
|
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz#ab3f0d6f66b8fc7fca3959ab5991f82221789be9"
|
|
4437
4416
|
integrity sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==
|
|
4438
4417
|
|
|
4439
|
-
socket.io-client@2.
|
|
4440
|
-
version "2.
|
|
4441
|
-
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.
|
|
4442
|
-
integrity sha512-
|
|
4418
|
+
socket.io-client@2.4.0:
|
|
4419
|
+
version "2.4.0"
|
|
4420
|
+
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.4.0.tgz#aafb5d594a3c55a34355562fc8aea22ed9119a35"
|
|
4421
|
+
integrity sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==
|
|
4443
4422
|
dependencies:
|
|
4444
4423
|
backo2 "1.0.2"
|
|
4445
|
-
base64-arraybuffer "0.1.5"
|
|
4446
4424
|
component-bind "1.0.0"
|
|
4447
|
-
component-emitter "1.
|
|
4448
|
-
debug "~
|
|
4449
|
-
engine.io-client "~3.
|
|
4425
|
+
component-emitter "~1.3.0"
|
|
4426
|
+
debug "~3.1.0"
|
|
4427
|
+
engine.io-client "~3.5.0"
|
|
4450
4428
|
has-binary2 "~1.0.2"
|
|
4451
|
-
has-cors "1.1.0"
|
|
4452
4429
|
indexof "0.0.1"
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
parseuri "0.0.5"
|
|
4430
|
+
parseqs "0.0.6"
|
|
4431
|
+
parseuri "0.0.6"
|
|
4456
4432
|
socket.io-parser "~3.3.0"
|
|
4457
4433
|
to-array "0.1.4"
|
|
4458
4434
|
|
|
4459
4435
|
socket.io-parser@~3.3.0:
|
|
4460
|
-
version "3.3.
|
|
4461
|
-
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.
|
|
4462
|
-
integrity sha512-
|
|
4436
|
+
version "3.3.2"
|
|
4437
|
+
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.2.tgz#ef872009d0adcf704f2fbe830191a14752ad50b6"
|
|
4438
|
+
integrity sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==
|
|
4463
4439
|
dependencies:
|
|
4464
|
-
component-emitter "1.
|
|
4440
|
+
component-emitter "~1.3.0"
|
|
4465
4441
|
debug "~3.1.0"
|
|
4466
4442
|
isarray "2.0.1"
|
|
4467
4443
|
|
|
@@ -4475,15 +4451,15 @@ socket.io-parser@~3.4.0:
|
|
|
4475
4451
|
isarray "2.0.1"
|
|
4476
4452
|
|
|
4477
4453
|
socket.io@^2.3.0:
|
|
4478
|
-
version "2.
|
|
4479
|
-
resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.
|
|
4480
|
-
integrity sha512-
|
|
4454
|
+
version "2.4.1"
|
|
4455
|
+
resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.4.1.tgz#95ad861c9a52369d7f1a68acf0d4a1b16da451d2"
|
|
4456
|
+
integrity sha512-Si18v0mMXGAqLqCVpTxBa8MGqriHGQh8ccEOhmsmNS3thNCGBwO8WGrwMibANsWtQQ5NStdZwHqZR3naJVFc3w==
|
|
4481
4457
|
dependencies:
|
|
4482
4458
|
debug "~4.1.0"
|
|
4483
|
-
engine.io "~3.
|
|
4459
|
+
engine.io "~3.5.0"
|
|
4484
4460
|
has-binary2 "~1.0.2"
|
|
4485
4461
|
socket.io-adapter "~1.1.0"
|
|
4486
|
-
socket.io-client "2.
|
|
4462
|
+
socket.io-client "2.4.0"
|
|
4487
4463
|
socket.io-parser "~3.4.0"
|
|
4488
4464
|
|
|
4489
4465
|
source-list-map@^2.0.0:
|
|
@@ -5123,17 +5099,10 @@ wrappy@1:
|
|
|
5123
5099
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
|
5124
5100
|
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
|
5125
5101
|
|
|
5126
|
-
ws
|
|
5127
|
-
version "7.
|
|
5128
|
-
resolved "https://registry.yarnpkg.com/ws/-/ws-7.
|
|
5129
|
-
integrity sha512-
|
|
5130
|
-
|
|
5131
|
-
ws@~6.1.0:
|
|
5132
|
-
version "6.1.4"
|
|
5133
|
-
resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9"
|
|
5134
|
-
integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==
|
|
5135
|
-
dependencies:
|
|
5136
|
-
async-limiter "~1.0.0"
|
|
5102
|
+
ws@~7.4.2:
|
|
5103
|
+
version "7.4.2"
|
|
5104
|
+
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd"
|
|
5105
|
+
integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==
|
|
5137
5106
|
|
|
5138
5107
|
xmlhttprequest-ssl@~1.5.4:
|
|
5139
5108
|
version "1.5.5"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shopify_app
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 17.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shopify
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-01-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: browser_sniffer
|
|
@@ -31,6 +31,9 @@ dependencies:
|
|
|
31
31
|
- - ">"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: 5.2.1
|
|
34
|
+
- - "<"
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: '6.1'
|
|
34
37
|
type: :runtime
|
|
35
38
|
prerelease: false
|
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -38,6 +41,9 @@ dependencies:
|
|
|
38
41
|
- - ">"
|
|
39
42
|
- !ruby/object:Gem::Version
|
|
40
43
|
version: 5.2.1
|
|
44
|
+
- - "<"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '6.1'
|
|
41
47
|
- !ruby/object:Gem::Dependency
|
|
42
48
|
name: shopify_api
|
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -246,6 +252,7 @@ files:
|
|
|
246
252
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
|
247
253
|
- ".github/probots.yml"
|
|
248
254
|
- ".github/workflows/build.yml"
|
|
255
|
+
- ".github/workflows/release.yml"
|
|
249
256
|
- ".github/workflows/rubocop.yml"
|
|
250
257
|
- ".gitignore"
|
|
251
258
|
- ".nvmrc"
|
|
@@ -269,6 +276,7 @@ files:
|
|
|
269
276
|
- app/assets/javascripts/shopify_app/top_level.js
|
|
270
277
|
- app/assets/javascripts/shopify_app/top_level_interaction.js
|
|
271
278
|
- app/controllers/concerns/shopify_app/authenticated.rb
|
|
279
|
+
- app/controllers/concerns/shopify_app/ensure_authenticated_links.rb
|
|
272
280
|
- app/controllers/concerns/shopify_app/require_known_shop.rb
|
|
273
281
|
- app/controllers/shopify_app/authenticated_controller.rb
|
|
274
282
|
- app/controllers/shopify_app/callback_controller.rb
|
|
@@ -306,6 +314,7 @@ files:
|
|
|
306
314
|
- config/locales/sv.yml
|
|
307
315
|
- config/locales/th.yml
|
|
308
316
|
- config/locales/tr.yml
|
|
317
|
+
- config/locales/vi.yml
|
|
309
318
|
- config/locales/zh-CN.yml
|
|
310
319
|
- config/locales/zh-TW.yml
|
|
311
320
|
- config/routes.rb
|