shopify_app 11.7.0 → 12.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3aa1aaa2a6895d06071509e43c6fd7247705d1f8d50831c4db87384a3259df4
4
- data.tar.gz: 50de5f631e15bad635b2b2e43a0aac22c3c3f89ff51addf6866e76a8850f7d0a
3
+ metadata.gz: 5dcd45c8f2586d1be89322c54d902eb7f9d91d28969725d7ba10e332d3165e29
4
+ data.tar.gz: ac7e290930adff81933a9dac3a2b212a0b2d579018cca043ed01f9c54dd78b35
5
5
  SHA512:
6
- metadata.gz: 891c47cacf32a40f6477257b35741b5cba45417a60d7347d8863809a38efd207c86728b285debe552007126c73dfd083949884296b973f9c0b4998ad1c04f2d7
7
- data.tar.gz: 1809b3f6ba4680e23a16660a706d15bdace9b57cb20c129fc021c38850015e69b2570292e34e21297570c053d443a4fcf4f3f2dae5961ce8ee9c5527a0dbbe36
6
+ metadata.gz: 47e1984dd4168715a3b0698f41cfe76fa989121be1f915dde626bd18e769a535431e78694b1e7b5eaac86324e0bfef89e47289fcbf0d1ab8927c1ed5ead6fb66
7
+ data.tar.gz: 3226cfe6d9001f37b2349f039dfe5a860693ef2bf84d2ca4386c7b0c6024d13ac4a998abfbf4ad331cd190f187b95fe7f3069365d08fcc1466627ed528050c66
@@ -1,7 +1,33 @@
1
+ 12.0.3
2
+ ------
3
+ * Moves samesite middleware higher in the stack #898
4
+ * Fix issue where not redirecting user to granted storage page casues infinite loop #900
5
+
6
+ 12.0.2
7
+ ------
8
+ * Reverts "Fix for return_to in safari after enable_cookies/granted_storage_access" introduced in 12.0.1
9
+
10
+ 12.0.1
11
+ ------
12
+ * disable samesite cookie middleware in tests
13
+ * middleware compatibility for ruby 2.3
14
+ * samesite cookie fixes for javascript libraries
15
+ * change generators to add AppBridge instead of EASDK
16
+ * Fix for return_to in safari after enable_cookies/granted_storage_access
17
+
18
+ 12.0.0
19
+ -----
20
+ * Updating shopify_api gem to 9.0.0
21
+
22
+ 11.7.1
23
+ -----
24
+ * Fix to allow SessionStorage to be flexible on what model names that the are used for storing shop and user data
25
+
1
26
  11.7.0
2
27
  -----
3
28
  * Move ExtensionVerificationController from engine to app controllers, as being in the engine makes ActionController::Base get loaded before app initiates [#855](https://github.com/Shopify/shopify_app/pull/855)
4
29
  * Add back per-user token support (added in 11.5.0, reverted in 11.5.1)
30
+ * If you have an override on the `self.store(auth_session)` method on your `SessionRepository` model, the method signature must be changed as according to this [change](https://github.com/Shopify/shopify_app/pull/856/files#diff-deaed2b262ec885f4e36de05621e41eaR18)
5
31
 
6
32
  11.6.0
7
33
  -----
data/README.md CHANGED
@@ -13,7 +13,7 @@ Shopify Application Rails engine and generator
13
13
  Table of Contents
14
14
  -----------------
15
15
  - [Introduction](#introduction)
16
- - [Becoming a Shopify App Developer](#becoming-a-shopify-app-developer)
16
+ - [Become a Shopify App Developer](#become-a-shopify-app-developer)
17
17
  - [Installation](#installation)
18
18
  - [Generators](#generators)
19
19
  - [Mounting the Engine](#mounting-the-engine)
@@ -31,25 +31,25 @@ Table of Contents
31
31
 
32
32
  Introduction
33
33
  -----------
34
- This gem includes a Rails Engine and generators for writing Rails applications using the Shopify API. The Engine provides a SessionsController and all the required code for authenticating with a shop via Oauth (other authentication methods are not supported).
34
+ Get started with the [Shopify Admin API](https://help.shopify.com/en/api/getting-started) faster; This gem includes a Rails Engine and generators for writing Rails applications using the Shopify API. The Engine provides a SessionsController and all the required code for authenticating with a shop via Oauth (other authentication methods are not supported).
35
35
 
36
- *Note: It's recommended to use this on a new Rails project, so that the generator won't overwrite/delete some of your files.*
36
+ *Note: It's recommended to use this on a new Rails project, so that the generator won't overwrite/delete your files.*
37
37
 
38
- Check out this screencast on how to create and deploy a new Shopify App to Heroku in 5 minutes:
38
+ Learn how to create and deploy a new Shopify App to Heroku with our [quickstart guide](https://github.com/Shopify/shopify_app/blob/master/docs/Quickstart.md), or dive in in less than 5 minutes with this quickstart video:
39
39
 
40
40
  [https://www.youtube.com/watch?v=yGxeoAHlQOg](https://www.youtube.com/watch?v=yGxeoAHlQOg)
41
41
 
42
- Or if you prefer text instructions the steps in the video are written out [here](https://github.com/Shopify/shopify_app/blob/master/docs/Quickstart.md)
43
-
44
- Becoming a Shopify App Developer
42
+ Become a Shopify App Developer
45
43
  --------------------------------
46
- If you don't have a Shopify Partner account yet head over to http://shopify.com/partners to create one, you'll need it before you can start developing apps.
44
+ To become a Shopify App Developer you'll need a [Shopify Partner account.](http://shopify.com/partners) If you don't have a Shopify Partner account, head to http://shopify.com/partners to create one before you start.
45
+
46
+ Once you have a Partner account, [create a new application in the Partner Dashboard](https://help.shopify.com/en/api/tools/partner-dashboard/your-apps) to get an API key and other API credentials.
47
47
 
48
- Once you have a Partner account create a new application to get an API key and other API credentials. To create a development application set the `App URL` to the URL provided by [your tunnel](#app-tunneling) or `http://localhost:3000/` if you are not embeddeding your app inside the admin or receiving webhooks and the `Whitelisted redirection URL(s)` to contain `<App URL>/auth/shopify/callback`. Ensure you are using `https://` URLs if you are using tunneling.
48
+ To create an application for development set your new app's `App URL` to the URL provided by [your tunnel](#app-tunneling), ensuring that you use `https://`. If you are not planning to embed your app inside the Shopify admin or receive webhooks, set your redirect URL to `http://localhost:3000/` and the `Whitelisted redirection URL(s)` to contain `<App URL>/auth/shopify/callback`.
49
49
 
50
50
  Installation
51
51
  ------------
52
- To get started add shopify_app to your Gemfile and bundle install
52
+ To get started add `shopify_app` to your Gemfile and run `bundle install`:
53
53
 
54
54
  ``` sh
55
55
  # Create a new rails app
@@ -61,7 +61,7 @@ $ echo "gem 'shopify_app'" >> Gemfile
61
61
  $ bundle install
62
62
  ```
63
63
 
64
- Now we are ready to run any of the shopify_app generators. The following section explains the generators and what they can do.
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.
65
65
 
66
66
 
67
67
  #### Rails Compatibility
@@ -74,24 +74,24 @@ Generators
74
74
 
75
75
  ### Default Generator
76
76
 
77
- The default generator will run the `install`, `shop`, and `home_controller` generators. This is the recommended way to start your app.
77
+ The default generator will run the `install`, `shop`, and `home_controller` generators. This is the recommended way to start a new app from scratch:
78
78
 
79
79
  ```sh
80
80
  $ rails generate shopify_app
81
81
  ```
82
82
 
83
- After running the generator, you will need to run `rails db:migrate` to add tables to your database. You can start your app with `bundle exec rails server` and install your app by visiting localhost.
83
+ 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.
84
84
 
85
85
  ### API Keys
86
86
 
87
- The default and install generators have been updated to source Shopify API key and secret from a `.env` file, which you will need to create with the following format:
87
+ The default and install generators have been updated to source Shopify API key and secret from an Environment (`.env`) variables file, which you will need to create with the following format:
88
88
 
89
89
  ```
90
90
  SHOPIFY_API_KEY=your api key
91
91
  SHOPIFY_API_SECRET=your api secret
92
92
  ```
93
93
 
94
- These values can be found on the "App Setup" page in the [Shopify Partners Dashboard][dashboard].
94
+ These values can be found on the "App Setup" page in the [Shopify Partners Dashboard][dashboard]. 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.
95
95
 
96
96
  ### Install Generator
97
97
 
@@ -123,7 +123,7 @@ After running the `install` generator, you can start your app with `bundle exec
123
123
  $ rails generate shopify_app:home_controller
124
124
  ```
125
125
 
126
- This generator creates an example home controller and view which fetches and displays products using the ShopifyAPI
126
+ This generator creates an example home controller and view which fetches and displays products using the Shopify API
127
127
 
128
128
 
129
129
  ### App Proxy Controller Generator
@@ -213,7 +213,7 @@ Authentication
213
213
 
214
214
  ### ShopifyApp::SessionRepository
215
215
 
216
- `ShopifyApp::SessionRepository` allows you as a developer to define how your sessions are stored and retrieved for shops. The `SessionRepository` is configured in the `config/initializers/shopify_app.rb` file and can be set to any object that implements `self.store(auth_session)` which stores the session and returns a unique identifier and `self.retrieve(id)` which returns a `ShopifyAPI::Session` for the passed id. See either the `ShopifyApp::InMemorySessionStore` class or the `ShopifyApp::SessionStorage` concern for details.
216
+ `ShopifyApp::SessionRepository` allows you as a developer to define how your sessions are stored and retrieved for shops. The `SessionRepository` is configured in the `config/initializers/shopify_app.rb` file and can be set to any object that implements `self.store(auth_session, *args)` which stores the session and returns a unique identifier and `self.retrieve(id)` which returns a `ShopifyAPI::Session` for the passed id. These methods are already implemented as part of the `ShopifyApp::SessionStorage` concern, but can be overridden for custom implementation.
217
217
 
218
218
  If you only run the install generator then by default you will have an in memory store but it **won't work** on multi-server environments including Heroku. For multi-server environments, implement one of the following token-storage strategies.
219
219
 
@@ -233,6 +233,8 @@ This will generate a user model which will be the storage for the tokens necessa
233
233
 
234
234
  The current Shopify user will be stored in the rails session at `session[:shopify_user]`
235
235
 
236
+ In this mode, The `self.store(auth_session, *args)` will be invoked with a Shopify User object hash, which is then used to store the token as part of a user record, rather than a store record.
237
+
236
238
  This will change the type of token that Shopify returns and it will only be valid for a short time. Read more about `Online access` [here](https://help.shopify.com/api/getting-started/authentication/oauth). Note that this means you won't be able to use this token to respond to Webhooks.
237
239
 
238
240
  #### Migrating from shop-based to user-based token strategy
@@ -406,9 +408,11 @@ strategy.options[:old_client_secret] = ShopifyApp.configuration.old_secret
406
408
  App Tunneling
407
409
  -------------
408
410
 
409
- Your local app needs to be accessible from the public Internet in order to install it on a shop, use the [App Proxy Controller](#app-proxy-controller-generator) or receive Webhooks. Use a tunneling service like [ngrok](https://ngrok.com/), [Forward](https://forwardhq.com/), [Beeceptor](https://beeceptor.com/), [Mockbin](http://mockbin.org/), [Hookbin](https://hookbin.com/), etc.
411
+ Your local app needs to be accessible from the public Internet in order to install it on a Shopify store, to use the [App Proxy Controller](#app-proxy-controller-generator) or receive Webhooks.
410
412
 
411
- For example with [ngrok](https://ngrok.com/), run this command to set up proxying to Rails' default port:
413
+ Use a tunneling service like [ngrok](https://ngrok.com/), [Forward](https://forwardhq.com/), [Beeceptor](https://beeceptor.com/), [Mockbin](http://mockbin.org/), or [Hookbin](https://hookbin.com/) to make your development environment accessible to the internet.
414
+
415
+ For example with [ngrok](https://ngrok.com/), run this command to set up a tunnel proxy to Rails' default port:
412
416
 
413
417
  ```sh
414
418
  ngrok http 3000
@@ -435,6 +439,11 @@ end
435
439
  Create your app proxy url in the [Shopify Partners' Dashboard][dashboard], making sure to point it to `https://your_app_website.com/app_proxy`.
436
440
  ![Creating an App Proxy](/images/app-proxy-screenshot.png)
437
441
 
442
+ App Bridge
443
+ ---
444
+
445
+ A basic example of using [App Bridge][app-bridge] is included in the install generator. An app instance is automatically initialized in [shopify_app.js](https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/install/templates/shopify_app.js) and [flash_messages.js](https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/install/templates/flash_messages.js) converts Rails [flash messages](https://api.rubyonrails.org/classes/ActionDispatch/Flash.html) to App Bridge Toast actions automatically. By default, this library is included via [unpkg in the embedded_app layout](https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/install/templates/embedded_app.html.erb#L27). For more advanced uses it is recommended to [install App Bridge via npm or yarn](https://help.shopify.com/en/api/embedded-apps/app-bridge/getting-started#set-up-shopify-app-bridge-in-your-app).
446
+
438
447
  Troubleshooting
439
448
  ---------------
440
449
 
@@ -455,6 +464,12 @@ Questions or problems?
455
464
  - [Ask questions!](https://ecommerce.shopify.com/c/shopify-apis-and-technology)
456
465
  - [Read the docs!](https://help.shopify.com/api/guides)
457
466
 
467
+ Upgrading to 11.7.0
468
+ ---------------------------
469
+
470
+ ### Session storage method signature breaking change
471
+ If you override `def self.store(auth_session)` method in your session storage model (e.g. Shop), the method signature has changed to `def self.store(auth_session, *args)` in order to support user-based token storage. Please update your method signature to include the second argument.
472
+
458
473
  Rails 6 Compatibility
459
474
  ---------------------
460
475
 
@@ -527,3 +542,4 @@ is changed to
527
542
  You will need to also follow the ShopifyAPI [upgrade guide](https://github.com/Shopify/shopify_api/blob/master/README.md#-breaking-change-notice-for-version-700-) to ensure your app is ready to work with api versioning.
528
543
 
529
544
  [dashboard]:https://partners.shopify.com
545
+ [app-bridge]:https://help.shopify.com/en/api/embedded-apps/app-bridge
@@ -4,31 +4,31 @@
4
4
  this.itpAction = document.getElementById('TopLevelInteractionButton');
5
5
  this.redirectUrl = opts.redirectUrl;
6
6
  }
7
-
7
+
8
8
  ITPHelper.prototype.redirect = function() {
9
9
  sessionStorage.setItem('shopify.top_level_interaction', true);
10
10
  window.location.href = this.redirectUrl;
11
11
  }
12
-
12
+
13
13
  ITPHelper.prototype.userAgentIsAffected = function() {
14
14
  return Boolean(document.hasStorageAccess);
15
15
  }
16
-
16
+
17
17
  ITPHelper.prototype.canPartitionCookies = function() {
18
18
  var versionRegEx = /Version\/12\.0\.?\d? Safari/;
19
19
  return versionRegEx.test(navigator.userAgent);
20
20
  }
21
-
21
+
22
22
  ITPHelper.prototype.setUpContent = function(onClick) {
23
23
  this.itpContent.style.display = 'block';
24
24
  this.itpAction.addEventListener('click', this.redirect.bind(this));
25
25
  }
26
-
26
+
27
27
  ITPHelper.prototype.execute = function() {
28
28
  if (!this.itpContent) {
29
29
  return;
30
30
  }
31
-
31
+
32
32
  if (this.userAgentIsAffected()) {
33
33
  this.setUpContent();
34
34
  } else {
@@ -32,10 +32,39 @@
32
32
  window.location.href = this.redirectData.appHomeUrl;
33
33
  }
34
34
 
35
+ StorageAccessHelper.prototype.sameSiteNoneIncompatible = function(ua) {
36
+ return ua.includes("iPhone OS 12_") || ua.includes("iPad; CPU OS 12_") || //iOS 12
37
+ (ua.includes("UCBrowser/")
38
+ ? this.isOlderUcBrowser(ua) //UC Browser < 12.13.2
39
+ : (ua.includes("Chrome/5") || ua.includes("Chrome/6"))) ||
40
+ ua.includes("Chromium/5") || ua.includes("Chromium/6") ||
41
+ (ua.includes(" OS X 10_14_") &&
42
+ ((ua.includes("Version/") && ua.includes("Safari")) || //Safari on MacOS 10.14
43
+ ua.endsWith("(KHTML, like Gecko)"))); //Web view on MacOS 10.14
44
+ }
45
+
46
+ StorageAccessHelper.prototype.isOlderUcBrowser = function(ua) {
47
+ var match = ua.match(/UCBrowser\/(\d+)\.(\d+)\.(\d+)\./);
48
+ if (!match) return false;
49
+ var major = parseInt(match[1]);
50
+ var minor = parseInt(match[2]);
51
+ var build = parseInt(match[3]);
52
+ if (major != 12) return major < 12;
53
+ if (minor != 13) return minor < 13;
54
+ return build < 2;
55
+ }
56
+
57
+ StorageAccessHelper.prototype.setCookie = function(value) {
58
+ if(!this.sameSiteNoneIncompatible(navigator.userAgent)) {
59
+ value += '; secure; SameSite=None'
60
+ }
61
+ document.cookie = value;
62
+ }
63
+
35
64
  StorageAccessHelper.prototype.grantedStorageAccess = function() {
36
65
  try {
37
66
  sessionStorage.setItem('shopify.granted_storage_access', true);
38
- document.cookie = 'shopify.granted_storage_access=true';
67
+ this.setCookie('shopify.granted_storage_access=true');
39
68
  if (!document.cookie) {
40
69
  throw 'Cannot set third-party cookie.'
41
70
  }
@@ -107,7 +136,7 @@
107
136
  }
108
137
 
109
138
  StorageAccessHelper.prototype.setCookieAndRedirect = function() {
110
- document.cookie = "shopify.cookies_persist=true";
139
+ this.setCookie('shopify.cookies_persist=true');
111
140
  var helper = this.setUpHelper();
112
141
  helper.redirect();
113
142
  }
@@ -4,7 +4,7 @@ pt-BR:
4
4
  could_not_log_in: Não foi possível fazer login na Shopify store
5
5
  invalid_shop_url: Domínio de loja inválido
6
6
  enable_cookies_heading: Habilitar cookies de %{app}
7
- enable_cookies_body: Você deve habilitar manualmente os cookies neste navegador
7
+ enable_cookies_body: Você precisa habilitar manualmente os cookies neste navegador
8
8
  para usar %{app} dentro da Shopify.
9
9
  enable_cookies_footer: Os cookies permitem que o app o autentique armazenando temporariamente
10
10
  suas preferências e dados pessoais. Eles expiram depois de 30 dias.
@@ -1,11 +1,13 @@
1
1
  Quickstart
2
2
  ==========
3
3
 
4
- Build and deploy a new Shopify App to Heroku in minutes
4
+ Get started building and deploying a new Shopify App to Heroku in just a few minutes. This guide assumes you have Ruby/Rails installed on your computer already; if you haven't done that already start with [this guide.](https://guides.rubyonrails.org/v5.0/getting_started.html#installing-rails)
5
5
 
6
6
  1. New Rails App (with postgres)
7
7
  --------------------------------
8
8
 
9
+ To create a new Rails app and use this generator, open your terminal and run the following commands:
10
+
9
11
  ```sh
10
12
  $ rails new test-app --database=postgresql
11
13
  $ cd test-app
@@ -17,43 +19,51 @@ $ git commit -m 'new rails app'
17
19
  2. Create a new Heroku app
18
20
  --------------------------
19
21
 
20
- The next step is to create a new heroku app. Pull up your heroku dashboard and make a new app!
22
+ The next step is to create a new Heroku app to host your application. If you haven't got a Heroku account yet, create a free account [here](https://www.heroku.com/).
23
+
24
+ Head to the Heroku dashboard and create a new app, or run the following commands with the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli#download-and-install) installed, substituting `name` for the name of your own app:
21
25
 
22
- cli:
26
+ CLI:
23
27
  ```sh
24
28
  $ heroku create name
25
29
  $ heroku git:remote -a name
26
30
  ```
27
31
 
28
- now we need to let git know where the remote server is so we'll be able to deploy later
32
+ Once you have created an app on Heroku, we need to let Git know where the Heroku server is so we can deploy to it later. Copy the app's name from your Heroku dashboard and substitute `appname.git` with the name you chose earlier:
29
33
 
30
34
  web:
31
35
  ```sh
32
36
  # https://dashboard.heroku.com/new
33
- $ git remote add heroku git@heroku.com:appinfive.git
37
+ $ git remote add heroku git@heroku.com:appname.git
34
38
  ```
35
39
 
36
- 3. Create a new App in the partners area
40
+ 3. Create a new App in the Shopify Partner dashboard
37
41
  -----------------------------------------
42
+ * Create a Shopify app in the [Partners dashboard](https://partner.shopify.com). For this tutorial, you can choose either a public or custom app, but you can [learn about App Types here.](https://help.shopify.com/en/manual/apps/app-types)
38
43
  [https://app.shopify.com/services/partners/api_clients](https://app.shopify.com/services/partners/api_clients)
39
- * set the callback url to `https://<name>.herokuapp.com/`
40
- * choose an embedded app
41
- * set the redirect_uri to `https://<name>.herokuapp.com/auth/shopify/callback`
42
-
44
+ * Set the callback url to `https://<appname>.herokuapp.com/`
45
+ * Choose an embedded app
46
+ * Set the app's `redirect_uri` to `https://<appname>.herokuapp.com/auth/shopify/callback`
43
47
 
44
- 4. Add ShopifyApp to gemfile
48
+ 4. Add ShopifyApp to Gemfile
45
49
  ----------------------------
50
+
51
+ Run these commands to add the `shopify_app` Gem to your app:
52
+
46
53
  ```sh
47
54
  $ echo "gem 'shopify_app'" >> Gemfile
48
55
  $ bundle install
49
56
  ```
50
57
 
51
- 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 'shopify_app', '~> 7.0.0'`
58
+ **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'`
52
59
 
53
60
  5. Run the ShopifyApp generator
54
61
  -------------------------------
62
+
63
+ Generate the code for your app by running these commands:
64
+
55
65
  ```sh
56
- # use the keys from your app in the partners area
66
+ # Use the keys from your app you created in the partners area
57
67
  $ rails generate shopify_app --api_key <shopify_api_key> --secret <shopify_api_secret>
58
68
  $ git add .
59
69
  $ git commit -m 'generated shopify app'
@@ -61,10 +71,12 @@ $ git commit -m 'generated shopify app'
61
71
 
62
72
  If you forget to set your keys or redirect uri above, you will find them in the shopify_app initializer at: `/config/initializers/shopify_app.rb`.
63
73
 
64
- We recommend adding a gem or utilizing ENV variables to handle your keys before releasing your app.
74
+ We recommend adding a gem or utilizing environment variables (`.env`) to handle your keys before releasing your app. [Learn more about using environment variables.](https://www.honeybadger.io/blog/ruby-guide-environment-variables/)
65
75
 
66
- 6. Deploy
76
+ 6. Deploy your app
67
77
  ---------
78
+
79
+ Once you've generated your app, push it into your Heroku environment to see it up and running:
68
80
  ```sh
69
81
  $ git push heroku
70
82
  $ heroku run rake db:migrate
@@ -72,4 +84,20 @@ $ heroku run rake db:migrate
72
84
 
73
85
  7. Install the App!
74
86
  -------------------
75
- `https://<name>.herokuapp.com/`
87
+
88
+ Ensure you have created a [development store](https://help.shopify.com/en/api/getting-started/making-your-first-request#create-a-development-store) using the Shopify Partner Dashboard. If you don't already have one, [create one by following these instructions](https://help.shopify.com/en/api/getting-started/making-your-first-request#create-a-development-store).
89
+
90
+ ##### Note: The following step will cause your store to become `transfer-disabled.` Read more about store transfer and why it's important [here](https://help.shopify.com/en/api/guides/store-transfers#transfer-disabled-stores). This is an irreversible change, so be sure you don't plan to transfer this store to a merchant.
91
+
92
+ Install the app onto your new development store using the Partner Dashboard. Log in to your account, visit the apps page, click the app you created earlier, and looking for the `Test your app` instructions where you can select a store to install your app on.
93
+
94
+ ![Installing an app on the partners dashboard dropdown](/docs/install-on-dev-shop.png)
95
+
96
+ ### OR
97
+
98
+ ![Installing an app on the partners dashboard card](/docs/test-your-app.png)
99
+
100
+ 8. Great work!
101
+ -------------------
102
+
103
+ You're done creating your first app on Shopify. Keep going and learn more by [diving into our full documentation](https://help.shopify.com/en/api/getting-started), or join our [community of developers.](https://community.shopify.com/c/Shopify-Apps/bd-p/shopify-apps)
Binary file
@@ -3,11 +3,7 @@
3
3
  class MarketingActivitiesController < ShopifyApp::ExtensionVerificationController
4
4
  def preload_form_data
5
5
  preload_data = {
6
- "form_data": {
7
- "budget": {
8
- "currency": "USD",
9
- }
10
- }
6
+ "form_data": {}
11
7
  }
12
8
  render(json: preload_data, status: :ok)
13
9
  end
@@ -11,12 +11,6 @@ module ShopifyApp
11
11
 
12
12
  def create_home_index_view
13
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('shopify_app_ready_script.html.erb')))
18
- )
19
- end
20
14
  end
21
15
 
22
16
  def add_home_index_route
@@ -24,11 +24,11 @@
24
24
 
25
25
  <%= render 'layouts/flash_messages' %>
26
26
 
27
- <script src="https://cdn.shopify.com/s/assets/external/app.js?<%= Time.now.strftime('%Y%m%d%H') %>"></script>
27
+ <script src="https://unpkg.com/@shopify/app-bridge"></script>
28
28
 
29
29
  <%= content_tag(:div, nil, id: 'shopify-app-init', data: {
30
30
  api_key: ShopifyApp.configuration.api_key,
31
- shop_origin: ("https://#{ @shop_session.url }" if @shop_session),
31
+ shop_origin: (@shop_session.domain if @shop_session),
32
32
  debug: Rails.env.development?
33
33
  } ) %>
34
34
 
@@ -4,12 +4,21 @@ if (!document.documentElement.hasAttribute("data-turbolinks-preview")) {
4
4
  document.addEventListener(eventName, function flash() {
5
5
  var flashData = JSON.parse(document.getElementById('shopify-app-flash').dataset.flash);
6
6
 
7
+ var Toast = window['app-bridge'].actions.Toast;
8
+
7
9
  if (flashData.notice) {
8
- ShopifyApp.flashNotice(flashData.notice);
10
+ Toast.create(app, {
11
+ message: flashData.notice,
12
+ duration: 5000,
13
+ }).dispatch(Toast.Action.SHOW);
9
14
  }
10
15
 
11
16
  if (flashData.error) {
12
- ShopifyApp.flashError(flashData.error);
17
+ Toast.create(app, {
18
+ message: flashData.error,
19
+ duration: 5000,
20
+ isError: true,
21
+ }).dispatch(Toast.Action.SHOW);
13
22
  }
14
23
 
15
24
  document.removeEventListener(eventName, flash)
@@ -1,9 +1,15 @@
1
1
  document.addEventListener('DOMContentLoaded', () => {
2
2
  var data = document.getElementById('shopify-app-init').dataset;
3
- ShopifyApp.init({
3
+ var AppBridge = window['app-bridge'];
4
+ var createApp = AppBridge.default;
5
+ window.app = createApp({
4
6
  apiKey: data.apiKey,
5
7
  shopOrigin: data.shopOrigin,
6
- debug: data.debug === 'true',
7
- forceRedirect: true
8
+ });
9
+
10
+ var actions = AppBridge.actions;
11
+ var TitleBar = actions.TitleBar;
12
+ TitleBar.create(app, {
13
+ title: data.page,
8
14
  });
9
15
  });
@@ -66,7 +66,7 @@ module ShopifyApp
66
66
  end
67
67
 
68
68
  def enable_same_site_none
69
- @enable_same_site_none.nil? ? embedded_app? : @enable_same_site_none
69
+ !Rails.env.test? && (@enable_same_site_none.nil? ? embedded_app? : @enable_same_site_none)
70
70
  end
71
71
  end
72
72
 
@@ -63,8 +63,14 @@ module ShopifyApp
63
63
  head :unauthorized
64
64
  else
65
65
  if request.get?
66
- session[:return_to] = "#{request.path}?#{sanitized_params.to_query}"
66
+ path = request.path
67
+ query = sanitized_params.to_query
68
+ else
69
+ referer = URI(request.referer || "/")
70
+ path = referer.path
71
+ query = "#{referer.query}&#{sanitized_params.to_query}"
67
72
  end
73
+ session[:return_to] = "#{path}?#{query}"
68
74
  redirect_to(login_url_with_optional_shop)
69
75
  end
70
76
  end
@@ -14,7 +14,7 @@ module ShopifyApp
14
14
  end
15
15
 
16
16
  initializer "shopify_app.middleware" do |app|
17
- app.config.middleware.insert_before(ActionDispatch::Cookies, ShopifyApp::SameSiteCookieMiddleware)
17
+ app.config.middleware.insert_after(::Rack::Runtime, ShopifyApp::SameSiteCookieMiddleware)
18
18
  end
19
19
  end
20
20
  end
@@ -1,25 +1,32 @@
1
1
  module ShopifyApp
2
2
  class SameSiteCookieMiddleware
3
+ COOKIE_SEPARATOR = "\n"
4
+
3
5
  def initialize(app)
4
6
  @app = app
5
7
  end
6
8
 
7
9
  def call(env)
8
- _status, headers, _body = @app.call(env)
9
- ensure
10
+ status, headers, body = @app.call(env)
10
11
  user_agent = env['HTTP_USER_AGENT']
11
12
 
12
- if headers && headers['Set-Cookie'] && !SameSiteCookieMiddleware.same_site_none_incompatible?(user_agent) &&
13
+ if headers && headers['Set-Cookie'] &&
14
+ !SameSiteCookieMiddleware.same_site_none_incompatible?(user_agent) &&
13
15
  ShopifyApp.configuration.enable_same_site_none
14
16
 
15
- cookies = headers['Set-Cookie'].split("\n").compact
16
-
17
- cookies.each do |cookie|
18
- unless cookie.include?("; SameSite")
19
- headers['Set-Cookie'] = headers['Set-Cookie'].gsub("#{cookie}", "#{cookie}; secure; SameSite=None")
17
+ set_cookies = headers['Set-Cookie']
18
+ .split(COOKIE_SEPARATOR)
19
+ .compact
20
+ .map do |cookie|
21
+ cookie << '; Secure' if not cookie =~ /;\s*secure/i
22
+ cookie << '; SameSite=None' unless cookie =~ /;\s*samesite=/i
23
+ cookie
20
24
  end
21
- end
25
+
26
+ headers['Set-Cookie'] = set_cookies.join(COOKIE_SEPARATOR)
22
27
  end
28
+
29
+ [status, headers, body]
23
30
  end
24
31
 
25
32
  def self.same_site_none_incompatible?(user_agent)
@@ -31,8 +38,8 @@ module ShopifyApp
31
38
  end
32
39
 
33
40
  def self.webkit_same_site_bug?(sniffer)
34
- (sniffer.os == :ios && sniffer.os_version.match?(/^([0-9]|1[12])[\.\_]/)) ||
35
- (sniffer.os == :mac && sniffer.browser == :safari && sniffer.os_version.match?(/^10[\.\_]14/))
41
+ (sniffer.os == :ios && sniffer.os_version.match(/^([0-9]|1[12])[\.\_]/)) ||
42
+ (sniffer.os == :mac && sniffer.browser == :safari && sniffer.os_version.match(/^10[\.\_]14/))
36
43
  end
37
44
 
38
45
  def self.drops_unrecognized_same_site_cookies?(sniffer)
@@ -41,11 +48,11 @@ module ShopifyApp
41
48
  end
42
49
 
43
50
  def self.chromium_based?(sniffer)
44
- sniffer.browser_name.downcase.match?(/chrom(e|ium)/)
51
+ sniffer.browser_name.downcase.match(/chrom(e|ium)/)
45
52
  end
46
53
 
47
54
  def self.uc_browser?(sniffer)
48
- sniffer.user_agent.downcase.match?(/uc\s?browser/)
55
+ sniffer.user_agent.downcase.match(/uc\s?browser/)
49
56
  end
50
57
 
51
58
  def self.uc_browser_version_at_least?(sniffer:, major:, minor:, build:)
@@ -3,6 +3,12 @@ module ShopifyApp
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
+ if ShopifyApp.configuration.per_user_tokens?
7
+ extend ShopifyApp::SessionStorage::UserStorageStrategy
8
+ else
9
+ extend ShopifyApp::SessionStorage::ShopStorageStrategy
10
+ end
11
+
6
12
  validates :shopify_token, presence: true
7
13
  validates :api_version, presence: true
8
14
  validates :shopify_domain, presence: true,
@@ -19,22 +25,5 @@ module ShopifyApp
19
25
  &block
20
26
  )
21
27
  end
22
-
23
- class_methods do
24
-
25
- def strategy_klass
26
- ShopifyApp.configuration.per_user_tokens? ?
27
- ShopifyApp::SessionStorage::UserStorageStrategy :
28
- ShopifyApp::SessionStorage::ShopStorageStrategy
29
- end
30
-
31
- def store(auth_session, user: nil)
32
- strategy_klass.store(auth_session, user)
33
- end
34
-
35
- def retrieve(id)
36
- strategy_klass.retrieve(id)
37
- end
38
- end
39
28
  end
40
29
  end
@@ -1,17 +1,16 @@
1
1
  module ShopifyApp
2
2
  module SessionStorage
3
- class ShopStorageStrategy
4
-
5
- def self.store(auth_session, *args)
6
- shop = Shop.find_or_initialize_by(shopify_domain: auth_session.domain)
3
+ module ShopStorageStrategy
4
+ def store(auth_session, *args)
5
+ shop = find_or_initialize_by(shopify_domain: auth_session.domain)
7
6
  shop.shopify_token = auth_session.token
8
7
  shop.save!
9
8
  shop.id
10
9
  end
11
10
 
12
- def self.retrieve(id)
11
+ def retrieve(id)
13
12
  return unless id
14
- if shop = Shop.find_by(id: id)
13
+ if shop = self.find_by(id: id)
15
14
  ShopifyAPI::Session.new(
16
15
  domain: shop.shopify_domain,
17
16
  token: shop.shopify_token,
@@ -1,18 +1,17 @@
1
1
  module ShopifyApp
2
2
  module SessionStorage
3
- class UserStorageStrategy
4
-
5
- def self.store(auth_session, user)
6
- user = User.find_or_initialize_by(shopify_user_id: user[:id])
3
+ module UserStorageStrategy
4
+ def store(auth_session, user)
5
+ user = find_or_initialize_by(shopify_user_id: user[:id])
7
6
  user.shopify_token = auth_session.token
8
7
  user.shopify_domain = auth_session.domain
9
8
  user.save!
10
9
  user.id
11
10
  end
12
11
 
13
- def self.retrieve(id)
12
+ def retrieve(id)
14
13
  return unless id
15
- if user = User.find_by(shopify_user_id: id)
14
+ if user = self.find_by(shopify_user_id: id)
16
15
  ShopifyAPI::Session.new(
17
16
  domain: user.shopify_domain,
18
17
  token: user.shopify_token,
@@ -20,7 +19,6 @@ module ShopifyApp
20
19
  )
21
20
  end
22
21
  end
23
-
24
22
  end
25
23
  end
26
24
  end
@@ -1,3 +1,3 @@
1
1
  module ShopifyApp
2
- VERSION = '11.7.0'.freeze
2
+ VERSION = '12.0.3'.freeze
3
3
  end
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "name": "shopify_app",
3
+ "version": "12.0.2",
3
4
  "repository": "git@github.com:Shopify/shopify_app.git",
4
5
  "author": "Shopify",
5
6
  "license": "MIT",
@@ -23,6 +24,5 @@
23
24
  },
24
25
  "scripts": {
25
26
  "test": "./node_modules/.bin/karma start --browsers ChromeHeadless --single-run"
26
- },
27
- "version": "11.6.0"
27
+ }
28
28
  }
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
 
13
13
  s.add_runtime_dependency('browser_sniffer', '~> 1.1.3')
14
14
  s.add_runtime_dependency('rails', '> 5.2.1')
15
- s.add_runtime_dependency('shopify_api', '~> 8.0')
15
+ s.add_runtime_dependency('shopify_api', '~> 9.0')
16
16
  s.add_runtime_dependency('omniauth-shopify-oauth2', '~> 2.2.0')
17
17
 
18
18
  s.add_development_dependency('rake')
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: 11.7.0
4
+ version: 12.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: 2020-01-15 00:00:00.000000000 Z
11
+ date: 2020-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: browser_sniffer
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '8.0'
47
+ version: '9.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '8.0'
54
+ version: '9.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: omniauth-shopify-oauth2
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -278,6 +278,8 @@ files:
278
278
  - docs/Quickstart.md
279
279
  - docs/Releasing.md
280
280
  - docs/Troubleshooting.md
281
+ - docs/install-on-dev-shop.png
282
+ - docs/test-your-app.png
281
283
  - images/app-proxy-screenshot.png
282
284
  - karma.conf.js
283
285
  - lib/generators/shopify_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb
@@ -296,7 +298,6 @@ files:
296
298
  - lib/generators/shopify_app/home_controller/home_controller_generator.rb
297
299
  - lib/generators/shopify_app/home_controller/templates/home_controller.rb
298
300
  - lib/generators/shopify_app/home_controller/templates/index.html.erb
299
- - lib/generators/shopify_app/home_controller/templates/shopify_app_ready_script.html.erb
300
301
  - lib/generators/shopify_app/install/install_generator.rb
301
302
  - lib/generators/shopify_app/install/templates/_flash_messages.html.erb
302
303
  - lib/generators/shopify_app/install/templates/embedded_app.html.erb
@@ -1,7 +0,0 @@
1
- <% content_for :javascript do %>
2
- <script type="text/javascript">
3
- ShopifyApp.ready(function(){
4
- ShopifyApp.Bar.initialize({ title: "Home" });
5
- });
6
- </script>
7
- <% end %>