shopify_app 21.8.1 → 21.10.0

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: 36bbee7b9808abae0813b1177ebd8bf8102be7fd81984e5aae8cd9c6d78aca20
4
- data.tar.gz: c1d239928719eb000562a1fbfd0df83ef48db41baf17e923f9968ede0e57466b
3
+ metadata.gz: 927f0886c6d7be713738a4c38d2a1c5319593d2d8e4d200d854957abae73ac09
4
+ data.tar.gz: cca13c50d4cc99853ef10e119d4cb10cf96ba786ee9e146c2acacc12758d741f
5
5
  SHA512:
6
- metadata.gz: 9b3ef76d79690b330e874dde1a11a837c3c85e5db67fe7d3b453e9543cee3291ad22d1794576b2985a3f9601b15156d6b9f476d0b9e9c09932346dcdcf0d759a
7
- data.tar.gz: 2faa1c6bf1691020a0b75728bf85c0483d237b4e0f5ff5cca3d3f0876744828af10228625c1d0426beadc87efebe6f93ae65ec6be37f3ab5d9b7c544af5b7755
6
+ metadata.gz: db9c6d4fdee1744d974fcde46f54d4246c2886dafb4d31f3423d9c903566f730c06a0b3187a21cdd534d7ee63be95c1fa318e85c007b53f682cbf7a6d3184df2
7
+ data.tar.gz: eb437382bf4fba13da3d3780fd05e29360807c8d999239d129dd4ff5e92fc63de33dea382deb9ab9f0e9552d208a1405acb5aa68cb85c20a7310afd81681bcb0
@@ -11,7 +11,7 @@ jobs:
11
11
  steps:
12
12
  - name: Extract tag name
13
13
  id: tag
14
- run: echo "::set-output name=value::${GITHUB_REF##*/}"
14
+ run: echo "value=${GITHUB_REF##*/}" >> "$GITHUB_OUTPUT"
15
15
  - uses: actions/checkout@v3
16
16
 
17
17
  - name: Create Release
data/CHANGELOG.md CHANGED
@@ -1,7 +1,19 @@
1
1
  Unreleased
2
2
  ----------
3
3
 
4
+ 21.10.0 (January 24, 2024)
5
+ ----------
6
+ * Fix session deletion for users with customized session storage[#1773](https://github.com/Shopify/shopify_app/pull/1773)
7
+ * Add configuration flag `check_session_expiry_date` to trigger a re-auth when the (user) session is expired. The session expiry date must be stored and retrieved for this flag to be effective. When the `UserSessionStorageWithScopes` concern is used, a DB migration can be generated with `rails generate shopify_app:user_model --skip` and should be applied before enabling that flag[#1757](https://github.com/Shopify/shopify_app/pull/1757)
8
+
9
+ 21.9.0 (January 16, 2024)
10
+ ----------
11
+ * Fix `add_webhook` generator to create the webhook jobs under the correct directory[#1748](https://github.com/Shopify/shopify_app/pull/1748)
12
+ * Add support for metafield_namespaces in webhook registration [#1745](https://github.com/Shopify/shopify_app/pull/1745)
13
+ * Bumps `shopify_api` to latest version (13.4.0), adds support for 2024-01 API version [#1776](https://github.com/Shopify/shopify_app/pull/1776)
14
+
4
15
  21.8.1 (December 6, 2023)
16
+ ----------
5
17
  * Bump `shopify_api` to 13.3.1 [1763](https://github.com/Shopify/shopify-api-ruby/blob/main/CHANGELOG.md#1331)
6
18
 
7
19
  21.8.0 (Dec 1, 2023)
data/Gemfile.lock CHANGED
@@ -1,81 +1,81 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shopify_app (21.8.1)
4
+ shopify_app (21.10.0)
5
5
  activeresource
6
6
  addressable (~> 2.7)
7
7
  browser_sniffer (~> 2.0)
8
8
  jwt (>= 2.2.3)
9
9
  rails (> 5.2.1)
10
10
  redirect_safely (~> 1.0)
11
- shopify_api (~> 13.3)
11
+ shopify_api (~> 13.4)
12
12
  sprockets-rails (>= 2.0.0)
13
13
 
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
- actioncable (6.1.7.3)
18
- actionpack (= 6.1.7.3)
19
- activesupport (= 6.1.7.3)
17
+ actioncable (6.1.7.6)
18
+ actionpack (= 6.1.7.6)
19
+ activesupport (= 6.1.7.6)
20
20
  nio4r (~> 2.0)
21
21
  websocket-driver (>= 0.6.1)
22
- actionmailbox (6.1.7.3)
23
- actionpack (= 6.1.7.3)
24
- activejob (= 6.1.7.3)
25
- activerecord (= 6.1.7.3)
26
- activestorage (= 6.1.7.3)
27
- activesupport (= 6.1.7.3)
22
+ actionmailbox (6.1.7.6)
23
+ actionpack (= 6.1.7.6)
24
+ activejob (= 6.1.7.6)
25
+ activerecord (= 6.1.7.6)
26
+ activestorage (= 6.1.7.6)
27
+ activesupport (= 6.1.7.6)
28
28
  mail (>= 2.7.1)
29
- actionmailer (6.1.7.3)
30
- actionpack (= 6.1.7.3)
31
- actionview (= 6.1.7.3)
32
- activejob (= 6.1.7.3)
33
- activesupport (= 6.1.7.3)
29
+ actionmailer (6.1.7.6)
30
+ actionpack (= 6.1.7.6)
31
+ actionview (= 6.1.7.6)
32
+ activejob (= 6.1.7.6)
33
+ activesupport (= 6.1.7.6)
34
34
  mail (~> 2.5, >= 2.5.4)
35
35
  rails-dom-testing (~> 2.0)
36
- actionpack (6.1.7.3)
37
- actionview (= 6.1.7.3)
38
- activesupport (= 6.1.7.3)
36
+ actionpack (6.1.7.6)
37
+ actionview (= 6.1.7.6)
38
+ activesupport (= 6.1.7.6)
39
39
  rack (~> 2.0, >= 2.0.9)
40
40
  rack-test (>= 0.6.3)
41
41
  rails-dom-testing (~> 2.0)
42
42
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
43
- actiontext (6.1.7.3)
44
- actionpack (= 6.1.7.3)
45
- activerecord (= 6.1.7.3)
46
- activestorage (= 6.1.7.3)
47
- activesupport (= 6.1.7.3)
43
+ actiontext (6.1.7.6)
44
+ actionpack (= 6.1.7.6)
45
+ activerecord (= 6.1.7.6)
46
+ activestorage (= 6.1.7.6)
47
+ activesupport (= 6.1.7.6)
48
48
  nokogiri (>= 1.8.5)
49
- actionview (6.1.7.3)
50
- activesupport (= 6.1.7.3)
49
+ actionview (6.1.7.6)
50
+ activesupport (= 6.1.7.6)
51
51
  builder (~> 3.1)
52
52
  erubi (~> 1.4)
53
53
  rails-dom-testing (~> 2.0)
54
54
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
55
- activejob (6.1.7.3)
56
- activesupport (= 6.1.7.3)
55
+ activejob (6.1.7.6)
56
+ activesupport (= 6.1.7.6)
57
57
  globalid (>= 0.3.6)
58
- activemodel (6.1.7.3)
59
- activesupport (= 6.1.7.3)
58
+ activemodel (6.1.7.6)
59
+ activesupport (= 6.1.7.6)
60
60
  activemodel-serializers-xml (1.0.2)
61
61
  activemodel (> 5.x)
62
62
  activesupport (> 5.x)
63
63
  builder (~> 3.1)
64
- activerecord (6.1.7.3)
65
- activemodel (= 6.1.7.3)
66
- activesupport (= 6.1.7.3)
64
+ activerecord (6.1.7.6)
65
+ activemodel (= 6.1.7.6)
66
+ activesupport (= 6.1.7.6)
67
67
  activeresource (6.0.0)
68
68
  activemodel (>= 6.0)
69
69
  activemodel-serializers-xml (~> 1.0)
70
70
  activesupport (>= 6.0)
71
- activestorage (6.1.7.3)
72
- actionpack (= 6.1.7.3)
73
- activejob (= 6.1.7.3)
74
- activerecord (= 6.1.7.3)
75
- activesupport (= 6.1.7.3)
71
+ activestorage (6.1.7.6)
72
+ actionpack (= 6.1.7.6)
73
+ activejob (= 6.1.7.6)
74
+ activerecord (= 6.1.7.6)
75
+ activesupport (= 6.1.7.6)
76
76
  marcel (~> 1.0)
77
77
  mini_mime (>= 1.1.0)
78
- activesupport (6.1.7.3)
78
+ activesupport (6.1.7.6)
79
79
  concurrent-ruby (~> 1.0, >= 1.0.2)
80
80
  i18n (>= 1.6, < 2)
81
81
  minitest (>= 5.1)
@@ -159,20 +159,20 @@ GEM
159
159
  rack (2.2.7)
160
160
  rack-test (2.1.0)
161
161
  rack (>= 1.3)
162
- rails (6.1.7.3)
163
- actioncable (= 6.1.7.3)
164
- actionmailbox (= 6.1.7.3)
165
- actionmailer (= 6.1.7.3)
166
- actionpack (= 6.1.7.3)
167
- actiontext (= 6.1.7.3)
168
- actionview (= 6.1.7.3)
169
- activejob (= 6.1.7.3)
170
- activemodel (= 6.1.7.3)
171
- activerecord (= 6.1.7.3)
172
- activestorage (= 6.1.7.3)
173
- activesupport (= 6.1.7.3)
162
+ rails (6.1.7.6)
163
+ actioncable (= 6.1.7.6)
164
+ actionmailbox (= 6.1.7.6)
165
+ actionmailer (= 6.1.7.6)
166
+ actionpack (= 6.1.7.6)
167
+ actiontext (= 6.1.7.6)
168
+ actionview (= 6.1.7.6)
169
+ activejob (= 6.1.7.6)
170
+ activemodel (= 6.1.7.6)
171
+ activerecord (= 6.1.7.6)
172
+ activestorage (= 6.1.7.6)
173
+ activesupport (= 6.1.7.6)
174
174
  bundler (>= 1.15.0)
175
- railties (= 6.1.7.3)
175
+ railties (= 6.1.7.6)
176
176
  sprockets-rails (>= 2.0.0)
177
177
  rails-controller-testing (1.0.5)
178
178
  actionpack (>= 5.0.1.rc1)
@@ -183,9 +183,9 @@ GEM
183
183
  nokogiri (>= 1.6)
184
184
  rails-html-sanitizer (1.5.0)
185
185
  loofah (~> 2.19, >= 2.19.1)
186
- railties (6.1.7.3)
187
- actionpack (= 6.1.7.3)
188
- activesupport (= 6.1.7.3)
186
+ railties (6.1.7.6)
187
+ actionpack (= 6.1.7.6)
188
+ activesupport (= 6.1.7.6)
189
189
  method_source
190
190
  rake (>= 12.2)
191
191
  thor (~> 1.0)
@@ -217,7 +217,7 @@ GEM
217
217
  ruby-progressbar (1.13.0)
218
218
  ruby2_keywords (0.0.5)
219
219
  securerandom (0.2.2)
220
- shopify_api (13.3.1)
220
+ shopify_api (13.4.0)
221
221
  activesupport
222
222
  concurrent-ruby
223
223
  hash_diff
@@ -4,23 +4,27 @@ Sessions are used to make contextual API calls for either a shop (offline sessio
4
4
 
5
5
  #### Table of contents
6
6
 
7
- - [Sessions](#sessions-1)
8
- - [Types of session tokens](#types-of-session-tokens) - Shop (offline) v.s. User (online)
9
- - [Session token storage](#session-token-storage)
10
- - [Shop (offline) token storage](#shop-offline-token-storage)
11
- - [User (online) token storage](#user-online-token-storage)
12
- - [In-Memory Session Storage for Testing](#in-memory-session-storage-for-testing)
13
- - [Customizing Session Storage with `ShopifyApp::SessionRepository`](#customizing-session-storage-with-shopifyappsessionrepository)
14
- - [Loading Sessions](#loading-sessions)
7
+ - [Sessions](#sessions)
8
+ - [Table of contents](#table-of-contents)
9
+ - [Sessions](#sessions-1)
10
+ - [Types of session tokens](#types-of-session-tokens)
11
+ - [Session token storage](#session-token-storage)
12
+ - [Shop (offline) token storage](#shop-offline-token-storage)
13
+ - [User (online) token storage](#user-online-token-storage)
14
+ - [In-memory Session Storage for testing](#in-memory-session-storage-for-testing)
15
+ - [Customizing Session Storage with `ShopifyApp::SessionRepository`](#customizing-session-storage-with-shopifyappsessionrepository)
16
+ - [⚠️ Custom Session Storage Requirements](#️--custom-session-storage-requirements)
17
+ - [Available `ActiveSupport::Concerns` that contains implementation of the above methods](#available-activesupportconcerns-that-contains-implementation-of-the-above-methods)
18
+ - [Loading Sessions](#loading-sessions)
15
19
  - [Getting Sessions with Controller Concerns](#getting-sessions-with-controller-concerns)
16
- - [Shop session - "EnsureInstalled" ](#shop-sessions---ensureinstalled)
17
- - [User session - "EnsureHasSession" ](#user-sessions---ensurehassession)
18
- - [Getting Sessions from a Shop or User model record - "with_shopify_session"](#getting-sessions-from-a-shop-or-user-model-record---with_shopify_session)
19
- - [Access scopes](#access-scopes)
20
- - [`ShopifyApp::ShopSessionStorageWithScopes`](#shopifyappshopsessionstoragewithscopes)
21
- - [``ShopifyApp::UserSessionStorageWithScopes``](#shopifyappusersessionstoragewithscopes)
22
- - [Migrating from shop-based to user-based token strategy](#migrating-from-shop-based-to-user-based-token-strategy)
23
- - [Migrating from ShopifyApi::Auth::SessionStorage to ShopifyApp::SessionStorage](#migrating-from-shopifyapiauthsessionstorage-to-shopifyappsessionstorage)
20
+ - [**Shop Sessions - `EnsureInstalled`**](#shop-sessions---ensureinstalled)
21
+ - [User Sessions - `EnsureHasSession`](#user-sessions---ensurehassession)
22
+ - [Getting sessions from a Shop or User model record - 'with\_shopify\_session'](#getting-sessions-from-a-shop-or-user-model-record---with_shopify_session)
23
+ - [Access scopes](#access-scopes)
24
+ - [`ShopifyApp::ShopSessionStorageWithScopes`](#shopifyappshopsessionstoragewithscopes)
25
+ - [`ShopifyApp::UserSessionStorageWithScopes`](#shopifyappusersessionstoragewithscopes)
26
+ - [Migrating from shop-based to user-based token strategy](#migrating-from-shop-based-to-user-based-token-strategy)
27
+ - [Migrating from `ShopifyApi::Auth::SessionStorage` to `ShopifyApp::SessionStorage`](#migrating-from-shopifyapiauthsessionstorage-to-shopifyappsessionstorage)
24
28
 
25
29
  ## Sessions
26
30
  #### Types of session tokens
@@ -103,6 +107,7 @@ The custom **Shop** repository must implement the following methods:
103
107
  | `self.store(auth_session)` | `auth_session` (ShopifyAPI::Auth::Session) | - |
104
108
  | `self.retrieve(id)` | `id` (String) | ShopifyAPI::Auth::Session |
105
109
  | `self.retrieve_by_shopify_domain(shopify_domain)` | `shopify_domain` (String) | ShopifyAPI::Auth::Session |
110
+ | `self.destroy_by_shopify_domain(shopify_domain)` | `shopify_domain` (String) | - |
106
111
 
107
112
  The custom **User** repository must implement the following methods:
108
113
  | Method | Parameters | Return Type |
@@ -110,6 +115,7 @@ The custom **User** repository must implement the following methods:
110
115
  | `self.store(auth_session, user)` | <li>`auth_session` (ShopifyAPI::Auth::Session)<br><li>`user` (ShopifyAPI::Auth::AssociatedUser) | - |
111
116
  | `self.retrieve(id)` | `id` (String) | `ShopifyAPI::Auth::Session` |
112
117
  | `self.retrieve_by_shopify_user_id(user_id)` | `user_id` (String) | `ShopifyAPI::Auth::Session` |
118
+ | `self.destroy_by_shopify_user_id(user_id)` | `user_id` (String) | - |
113
119
 
114
120
 
115
121
  These methods are already implemented as a part of the `User` and `Shop` models generated from this gem's generator.
@@ -153,7 +159,7 @@ end
153
159
  ```
154
160
 
155
161
  ##### User Sessions - `EnsureHasSession`
156
- - [EnsureHasSession](https://github.com/Shopify/shopify_app/blob/main/app/controllers/concerns/shopify_app/ensure_has_session.rb) controller concern will load a user session via `current_shopify_session`. As part of loading this session, this concern will also ensure that the user session has the appropriate scopes needed for the application. If the user isn't found or has fewer permitted scopes than are required, they will be prompted to authorize the application.
162
+ - [EnsureHasSession](https://github.com/Shopify/shopify_app/blob/main/app/controllers/concerns/shopify_app/ensure_has_session.rb) controller concern will load a user session via `current_shopify_session`. As part of loading this session, this concern will also ensure that the user session has the appropriate scopes needed for the application and that it is not expired (when `check_session_expiry_date` is enabled). If the user isn't found or has fewer permitted scopes than are required, they will be prompted to authorize the application.
157
163
  - This controller concern should be used if you don't need your app to make calls on behalf of a user. With that in mind, there are a few other embedded concerns that are mixed in to ensure that embedding, CSRF, localization, and billing allow the action for the user.
158
164
  - Example
159
165
  ```ruby
@@ -228,6 +234,9 @@ class User < ActiveRecord::Base
228
234
  end
229
235
  ```
230
236
 
237
+ ## Expiry date
238
+ When the configuration flag `check_session_expiry_date` is set to true, the user session expiry date will be checked to trigger a re-auth and get a fresh user token when it is expired. This requires the `ShopifyAPI::Auth::Session` `expires` attribute to be stored. When the `User` model includes the `UserSessionStorageWithScopes` concern, a DB migration can be generated with `rails generate shopify_app:user_model --skip` to add the `expires_at` attribute to the model.
239
+
231
240
  ## Migrating from shop-based to user-based token strategy
232
241
 
233
242
  1. Run the `user_model` generator as [mentioned above](#user-online-token-storage).
@@ -13,7 +13,7 @@ ShopifyApp can manage your app's webhooks for you if you set which webhooks you
13
13
  ```ruby
14
14
  ShopifyApp.configure do |config|
15
15
  config.webhooks = [
16
- {topic: 'carts/update', path: 'webhooks/carts_update'}
16
+ {topic: 'carts/update', path: 'api/webhooks/carts_update'}
17
17
  ]
18
18
  end
19
19
  ```
@@ -35,7 +35,21 @@ If you are only interested in particular fields, you can optionally filter the d
35
35
  ```ruby
36
36
  ShopifyApp.configure do |config|
37
37
  config.webhooks = [
38
- {topic: 'products/update', path: 'webhooks/products_update', fields: ['title', 'vendor']}
38
+ {topic: 'products/update', path: 'api/webhooks/products_update', fields: ['title', 'vendor']}
39
+ ]
40
+ end
41
+ ```
42
+
43
+ If you need to read metafields, you can pass in the `metafield_namespaces` parameter in `config/webhooks`. Note if you are also using the `fields` parameter you will need to add `metafields` into that as well. Shopify documentation on metafields in webhooks can be found [here](https://shopify.dev/docs/api/admin-rest/2023-10/resources/webhook#resource-object).
44
+
45
+ ```ruby
46
+ ShopifyApp.configure do |config|
47
+ config.webhooks = [
48
+ {
49
+ topic: 'orders/create',
50
+ path: 'api/webhooks/order_create',
51
+ metafield_namespaces: ['app-namespace'],
52
+ },
39
53
  ]
40
54
  end
41
55
  ```
@@ -39,7 +39,12 @@ module ShopifyApp
39
39
  end
40
40
 
41
41
  def add_webhook_job
42
- @job_file_name = job_file_name + "_job"
42
+ namespace = ShopifyApp.configuration.webhook_jobs_namespace
43
+ @job_file_name = if namespace.present?
44
+ "#{namespace}/#{job_file_name}_job"
45
+ else
46
+ "#{job_file_name}_job"
47
+ end
43
48
  @job_class_name = @job_file_name.classify
44
49
  template("webhook_job.rb", "app/jobs/#{@job_file_name}.rb")
45
50
  end
@@ -0,0 +1,5 @@
1
+ class AddUserExpiresAtColumn < ActiveRecord::Migration[<%= rails_migration_version %>]
2
+ def change
3
+ add_column :users, :expires_at, :datetime
4
+ end
5
+ end
@@ -40,6 +40,26 @@ module ShopifyApp
40
40
  end
41
41
  end
42
42
 
43
+ def create_expires_at_storage_in_user_model
44
+ expires_at_column_prompt = <<~PROMPT
45
+ It is highly recommended that apps record the User session expiry date. \
46
+ This will allow to check if the session has expired and re-authenticate \
47
+ without a first call to Shopify.
48
+
49
+ After running the migration, the `check_session_expiry_date` configuration can be enabled.
50
+
51
+ The following migration will add an `expires_at` column to the User model. \
52
+ Do you want to include this migration? [y/n]
53
+ PROMPT
54
+
55
+ if new_shopify_cli_app? || Rails.env.test? || yes?(expires_at_column_prompt)
56
+ migration_template(
57
+ "db/migrate/add_user_expires_at_column.erb",
58
+ "db/migrate/add_user_expires_at_column.rb",
59
+ )
60
+ end
61
+ end
62
+
43
63
  def update_shopify_app_initializer
44
64
  gsub_file("config/initializers/shopify_app.rb", "ShopifyApp::InMemoryUserSessionStore", "User")
45
65
  end
@@ -20,6 +20,7 @@ module ShopifyApp
20
20
  attr_accessor :api_version
21
21
 
22
22
  attr_accessor :reauth_on_access_scope_changes
23
+ attr_accessor :check_session_expiry_date
23
24
  attr_accessor :log_level
24
25
 
25
26
  # customise urls
@@ -44,6 +45,9 @@ module ShopifyApp
44
45
  # takes a ShopifyApp::BillingConfiguration object
45
46
  attr_accessor :billing
46
47
 
48
+ # Work in Progress: enables token exchange authentication flow
49
+ attr_accessor :wip_new_embedded_auth_strategy
50
+
47
51
  def initialize
48
52
  @root_url = "/"
49
53
  @myshopify_domain = "myshopify.com"
@@ -118,6 +122,10 @@ module ShopifyApp
118
122
  def user_access_scopes
119
123
  @user_access_scopes || scope
120
124
  end
125
+
126
+ def use_new_embedded_auth_strategy?
127
+ wip_new_embedded_auth_strategy && embedded_app?
128
+ end
121
129
  end
122
130
 
123
131
  class BillingConfiguration
@@ -30,6 +30,12 @@ module ShopifyApp
30
30
  return redirect_to_login
31
31
  end
32
32
 
33
+ if ShopifyApp.configuration.check_session_expiry_date && current_shopify_session.expired?
34
+ ShopifyApp::Logger.debug("Session expired, redirecting to login")
35
+ clear_shopify_session
36
+ return redirect_to_login
37
+ end
38
+
33
39
  if ShopifyApp.configuration.reauth_on_access_scope_changes &&
34
40
  !ShopifyApp.configuration.user_access_scopes_strategy.covers_scopes?(current_shopify_session)
35
41
  clear_shopify_session
@@ -280,8 +286,8 @@ module ShopifyApp
280
286
 
281
287
  def requested_by_javascript?
282
288
  request.xhr? ||
283
- request.content_type == "text/javascript" ||
284
- request.content_type == "application/javascript"
289
+ request.media_type == "text/javascript" ||
290
+ request.media_type == "application/javascript"
285
291
  end
286
292
  end
287
293
  end
@@ -52,6 +52,7 @@ module ShopifyApp
52
52
  path: webhook_path,
53
53
  handler: delivery_method == :http ? webhook_job_klass(webhook_path) : nil,
54
54
  fields: attributes[:fields],
55
+ metafield_namespaces: attributes[:metafield_namespaces],
55
56
  )
56
57
  end
57
58
  end
@@ -23,6 +23,14 @@ module ShopifyApp
23
23
  user_storage.retrieve_by_shopify_user_id(user_id)
24
24
  end
25
25
 
26
+ def destroy_shop_session_by_domain(shopify_domain)
27
+ shop_storage.destroy_by_shopify_domain(shopify_domain)
28
+ end
29
+
30
+ def destroy_user_session_by_shopify_user_id(user_id)
31
+ user_storage.destroy_by_shopify_user_id(user_id)
32
+ end
33
+
26
34
  def store_shop_session(session)
27
35
  shop_storage.store(session)
28
36
  end
@@ -73,18 +81,17 @@ module ShopifyApp
73
81
  def delete_session(id)
74
82
  match = id.match(/^offline_(.*)/)
75
83
 
76
- record = if match
84
+ if match
77
85
  domain = match[1]
78
86
  ShopifyApp::Logger.debug("Destroying session by domain - domain: #{domain}")
79
- Shop.find_by(shopify_domain: match[1])
87
+ destroy_shop_session_by_domain(domain)
88
+
80
89
  else
81
90
  shopify_user_id = id.split("_").last
82
91
  ShopifyApp::Logger.debug("Destroying session by user - user_id: #{shopify_user_id}")
83
- User.find_by(shopify_user_id: shopify_user_id)
92
+ destroy_user_session_by_shopify_user_id(shopify_user_id)
84
93
  end
85
94
 
86
- record.destroy
87
-
88
95
  true
89
96
  end
90
97
 
@@ -27,6 +27,10 @@ module ShopifyApp
27
27
  construct_session(shop)
28
28
  end
29
29
 
30
+ def destroy_by_shopify_domain(domain)
31
+ destroy_by(shopify_domain: domain)
32
+ end
33
+
30
34
  private
31
35
 
32
36
  def construct_session(shop)
@@ -29,6 +29,10 @@ module ShopifyApp
29
29
  construct_session(shop)
30
30
  end
31
31
 
32
+ def destroy_by_shopify_domain(domain)
33
+ destroy_by(shopify_domain: domain)
34
+ end
35
+
32
36
  private
33
37
 
34
38
  def construct_session(shop)
@@ -28,6 +28,10 @@ module ShopifyApp
28
28
  construct_session(user)
29
29
  end
30
30
 
31
+ def destroy_by_shopify_user_id(user_id)
32
+ destroy_by(shopify_user_id: user_id)
33
+ end
34
+
31
35
  private
32
36
 
33
37
  def construct_session(user)
@@ -15,6 +15,7 @@ module ShopifyApp
15
15
  user.shopify_token = auth_session.access_token
16
16
  user.shopify_domain = auth_session.shop
17
17
  user.access_scopes = auth_session.scope.to_s
18
+ user.expires_at = auth_session.expires
18
19
 
19
20
  user.save!
20
21
  user.id
@@ -30,6 +31,10 @@ module ShopifyApp
30
31
  construct_session(user)
31
32
  end
32
33
 
34
+ def destroy_by_shopify_user_id(user_id)
35
+ destroy_by(shopify_user_id: user_id)
36
+ end
37
+
33
38
  private
34
39
 
35
40
  def construct_session(user)
@@ -52,6 +57,7 @@ module ShopifyApp
52
57
  scope: user.access_scopes,
53
58
  associated_user_scope: user.access_scopes,
54
59
  associated_user: associated_user,
60
+ expires: user.expires_at,
55
61
  )
56
62
  end
57
63
  end
@@ -67,5 +73,24 @@ module ShopifyApp
67
73
  rescue NotImplementedError, NoMethodError
68
74
  raise NotImplementedError, "#access_scopes= must be defined to hook into stored access scopes"
69
75
  end
76
+
77
+ def expires_at=(expires_at)
78
+ super
79
+ rescue NotImplementedError, NoMethodError
80
+ if ShopifyApp.configuration.check_session_expiry_date
81
+ raise NotImplementedError,
82
+ "#expires_at= must be defined to handle storing the session expiry date"
83
+ end
84
+ end
85
+
86
+ def expires_at
87
+ super
88
+ rescue NotImplementedError, NoMethodError
89
+ if ShopifyApp.configuration.check_session_expiry_date
90
+ raise NotImplementedError, "#expires_at must be defined to check the session expiry date"
91
+ end
92
+
93
+ nil
94
+ end
70
95
  end
71
96
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ShopifyApp
4
- VERSION = "21.8.1"
4
+ VERSION = "21.10.0"
5
5
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shopify_app",
3
- "version": "21.8.1",
3
+ "version": "21.10.0",
4
4
  "repository": "git@github.com:Shopify/shopify_app.git",
5
5
  "author": "Shopify",
6
6
  "license": "MIT",
data/shopify_app.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.add_runtime_dependency("jwt", ">= 2.2.3")
21
21
  s.add_runtime_dependency("rails", "> 5.2.1")
22
22
  s.add_runtime_dependency("redirect_safely", "~> 1.0")
23
- s.add_runtime_dependency("shopify_api", "~> 13.3")
23
+ s.add_runtime_dependency("shopify_api", "~> 13.4")
24
24
  s.add_runtime_dependency("sprockets-rails", ">= 2.0.0")
25
25
 
26
26
  s.add_development_dependency("byebug")
data/yarn.lock CHANGED
@@ -2040,9 +2040,9 @@ flatted@^3.2.7:
2040
2040
  integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==
2041
2041
 
2042
2042
  follow-redirects@^1.0.0:
2043
- version "1.15.3"
2044
- resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
2045
- integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==
2043
+ version "1.15.4"
2044
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf"
2045
+ integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==
2046
2046
 
2047
2047
  fs-extra@^8.1.0:
2048
2048
  version "8.1.0"
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: 21.8.1
4
+ version: 21.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-06 00:00:00.000000000 Z
11
+ date: 2024-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeresource
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '13.3'
103
+ version: '13.4'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '13.3'
110
+ version: '13.4'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: sprockets-rails
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -416,6 +416,7 @@ files:
416
416
  - lib/generators/shopify_app/shop_model/templates/shops.yml
417
417
  - lib/generators/shopify_app/shopify_app_generator.rb
418
418
  - lib/generators/shopify_app/user_model/templates/db/migrate/add_user_access_scopes_column.erb
419
+ - lib/generators/shopify_app/user_model/templates/db/migrate/add_user_expires_at_column.erb
419
420
  - lib/generators/shopify_app/user_model/templates/db/migrate/create_users.erb
420
421
  - lib/generators/shopify_app/user_model/templates/user.rb
421
422
  - lib/generators/shopify_app/user_model/templates/users.yml
@@ -488,7 +489,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
488
489
  - !ruby/object:Gem::Version
489
490
  version: '0'
490
491
  requirements: []
491
- rubygems_version: 3.4.22
492
+ rubygems_version: 3.5.4
492
493
  signing_key:
493
494
  specification_version: 4
494
495
  summary: This gem is used to get quickly started with the Shopify API