shopify_app 21.9.0 → 22.00.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug-report.md +23 -18
- data/.github/workflows/build.yml +1 -1
- data/.github/workflows/release.yml +1 -1
- data/.github/workflows/rubocop.yml +2 -2
- data/CHANGELOG.md +20 -1
- data/CODE_OF_CONDUCT.md +46 -0
- data/Gemfile.lock +7 -9
- data/README.md +0 -1
- data/app/controllers/concerns/shopify_app/ensure_authenticated_links.rb +5 -1
- data/app/controllers/concerns/shopify_app/ensure_installed.rb +2 -2
- data/app/controllers/shopify_app/callback_controller.rb +15 -14
- data/config/routes.rb +1 -1
- data/docs/Upgrading.md +25 -1
- data/docs/shopify_app/controller-concerns.md +21 -0
- data/docs/shopify_app/generators.md +2 -2
- data/docs/shopify_app/sessions.md +26 -17
- data/lib/generators/shopify_app/user_model/templates/db/migrate/add_user_expires_at_column.erb +5 -0
- data/lib/generators/shopify_app/user_model/user_model_generator.rb +20 -0
- data/lib/shopify_app/configuration.rb +8 -0
- data/lib/shopify_app/controller_concerns/embedded_app.rb +12 -4
- data/lib/shopify_app/controller_concerns/login_protection.rb +15 -11
- data/lib/shopify_app/engine.rb +1 -2
- data/lib/shopify_app/session/session_repository.rb +12 -5
- data/lib/shopify_app/session/shop_session_storage.rb +4 -0
- data/lib/shopify_app/session/shop_session_storage_with_scopes.rb +4 -0
- data/lib/shopify_app/session/user_session_storage.rb +4 -0
- data/lib/shopify_app/session/user_session_storage_with_scopes.rb +25 -0
- data/lib/shopify_app/version.rb +1 -1
- data/lib/shopify_app.rb +0 -3
- data/package.json +1 -1
- data/shopify_app.gemspec +2 -3
- metadata +8 -28
- data/app/controllers/concerns/shopify_app/authenticated.rb +0 -17
- data/app/controllers/concerns/shopify_app/require_known_shop.rb +0 -16
- data/docs/shopify_app/script-tags.md +0 -28
- data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +0 -42
- data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +0 -63
- data/lib/shopify_app/controller_concerns/itp.rb +0 -50
- data/lib/shopify_app/jobs/scripttags_manager_job.rb +0 -16
- data/lib/shopify_app/managers/scripttags_manager.rb +0 -85
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d5156af0790e87945886e2c5edd99822d04fb05b88ad318558ab7a71aec764e
|
4
|
+
data.tar.gz: e192e1581b1f9f183e3f10a9a8c4c8cb337202ea1bcf1325cc1c4ea5ba06a1f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 951051cf5170c58847b8f2fde2e779916f66afa8fba6ea3be75d9aaee605f747b334fb28022d5149909cdb96b10741fa8be8f69ab98df631fe07d3d19c24484d
|
7
|
+
data.tar.gz: 45bff8811720fd20cf7141441cc8ee70b0b7ca046962670b4bbf4d91e480be08220f744185e98a8e8d71ff64532f698b513a8ab534e7fc0b30126cdebee93748
|
@@ -6,36 +6,41 @@ labels: "Type: Bug 🐛"
|
|
6
6
|
|
7
7
|
# Issue summary
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
Before opening this issue, I have:
|
10
|
+
|
11
|
+
- [ ] Upgraded to the latest version of the package
|
12
|
+
- `shopify_app` version:
|
13
|
+
- Ruby version:
|
14
|
+
- Operating system:
|
15
|
+
- [ ] Set `log_level: :debug` [in my configuration](https://github.com/Shopify/shopify-api-ruby#setup-shopify-context), if applicable
|
16
|
+
- [ ] Found a reliable way to reproduce the problem that indicates it's a problem with the package
|
17
|
+
- [ ] Looked for similar issues in this repository
|
18
|
+
- [ ] Checked that this isn't an issue with a Shopify API
|
19
|
+
- If it is, please create a post in the [Shopify community forums](https://community.shopify.com/c/partners-and-developers/ct-p/appdev) or report it to [Shopify Partner Support](https://help.shopify.com/en/support/partners/org-select)
|
13
20
|
|
14
|
-
|
15
|
-
|
16
|
-
Learn more: https://github.com/Shopify/shopify-api-ruby#setup-shopify-context
|
21
|
+
<!--
|
22
|
+
Write a short description of the issue here.
|
17
23
|
|
24
|
+
We can only fix issues for which there is a clear reproduction scenario.
|
25
|
+
The more context you can provide, the easier it becomes for us to investigate and fix the issue.
|
18
26
|
-->
|
19
27
|
|
20
|
-
- `shopify_api` version:
|
21
|
-
- `shopify_app` version:
|
22
|
-
- Ruby version:
|
23
|
-
- Operating system:
|
24
|
-
|
25
|
-
```
|
26
|
-
// Paste any relevant logs here
|
27
|
-
```
|
28
|
-
|
29
28
|
## Expected behavior
|
30
29
|
|
31
|
-
|
30
|
+
What do you think should happen?
|
32
31
|
|
33
32
|
## Actual behavior
|
34
33
|
|
35
|
-
|
34
|
+
What actually happens?
|
36
35
|
|
37
36
|
## Steps to reproduce the problem
|
38
37
|
|
39
38
|
1.
|
40
39
|
1.
|
41
40
|
1.
|
41
|
+
|
42
|
+
## Debug logs
|
43
|
+
|
44
|
+
```
|
45
|
+
// Paste any relevant logs here
|
46
|
+
```
|
data/.github/workflows/build.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,26 @@
|
|
1
1
|
Unreleased
|
2
2
|
----------
|
3
3
|
|
4
|
-
|
4
|
+
22.00.0 (March 5, 2024)
|
5
|
+
----------
|
6
|
+
* ⚠️ [Breaking] Bumps minimum supported Ruby version to 3.0. Bumps `shopify_api` to 14.0 [1801](https://github.com/Shopify/shopify_app/pull/1801)
|
7
|
+
* ⚠️ [Breaking] Removes deprecated controller concerns that were renamed in `v21.10.0`. [1805](https://github.com/Shopify/shopify_app/pull/1805)
|
8
|
+
* ⚠️ [Breaking] Removes deprecated `ScripttagManager`. We realize there was communication error in our logging where we logged future deprecation instead of our inteded removal. Since we have been logging that for 2 years we felt we'd move forward with the removal instead pushing this off until the next major release. [1806](https://github.com/Shopify/shopify_app/pull/1806)
|
9
|
+
* ⚠️ [Breaking] Removes ITP controller concern and `browser_sniffer` dependency.[1810](https://github.com/Shopify/shopify_app/pull/1810)
|
10
|
+
* ⚠️ [Breaking] Removes Marketing Extensions generator [1810](https://github.com/Shopify/shopify_app/pull/1810)
|
11
|
+
* ⚠️ [Breaking] Thows an error if a controller includes incompatible concerns (LoginProtection/EnsureInstalled) [1809](https://github.com/Shopify/shopify_app/pull/1809)
|
12
|
+
* ⚠️ [Breaking] No longer rescues non-shopify API errors during OAuth
|
13
|
+
callback [1807](https://github.com/Shopify/shopify_app/pull/1807)
|
14
|
+
* Make type param for webhooks route optional. This will fix a bug with CLI initiated webhooks.[1786](https://github.com/Shopify/shopify_app/pull/1786)
|
15
|
+
* Fix redirecting to login when we catch a 401 response from Shopify, so that it can also handle cases where the app is already embedded when that happens.[1787](https://github.com/Shopify/shopify_app/pull/1787)
|
16
|
+
* Always register webhooks with offline sessions.[1788](https://github.com/Shopify/shopify_app/pull/1788)
|
17
|
+
|
18
|
+
21.10.0 (January 24, 2024)
|
19
|
+
----------
|
20
|
+
* Fix session deletion for users with customized session storage[#1773](https://github.com/Shopify/shopify_app/pull/1773)
|
21
|
+
* 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)
|
22
|
+
|
23
|
+
21.9.0 (January 16, 2024)
|
5
24
|
----------
|
6
25
|
* Fix `add_webhook` generator to create the webhook jobs under the correct directory[#1748](https://github.com/Shopify/shopify_app/pull/1748)
|
7
26
|
* Add support for metafield_namespaces in webhook registration [#1745](https://github.com/Shopify/shopify_app/pull/1745)
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
4
|
+
fostering an open and welcoming community, we pledge to respect all
|
5
|
+
people who contribute through reporting issues, posting feature
|
6
|
+
requests, updating documentation, submitting pull requests or patches,
|
7
|
+
and other activities.
|
8
|
+
|
9
|
+
We are committed to making participation in this project a
|
10
|
+
harassment-free experience for everyone, regardless of level of
|
11
|
+
experience, gender, gender identity and expression, sexual orientation,
|
12
|
+
disability, personal appearance, body size, race, ethnicity, age,
|
13
|
+
religion, or nationality.
|
14
|
+
|
15
|
+
Examples of unacceptable behavior by participants include:
|
16
|
+
|
17
|
+
- The use of sexualized language or imagery
|
18
|
+
- Personal attacks
|
19
|
+
- Trolling or insulting/derogatory comments
|
20
|
+
- Public or private harassment
|
21
|
+
- Publishing other's private information, such as physical or electronic
|
22
|
+
addresses, without explicit permission
|
23
|
+
- Other unethical or unprofessional conduct
|
24
|
+
|
25
|
+
Project maintainers have the right and responsibility to remove, edit,
|
26
|
+
or reject comments, commits, code, wiki edits, issues, and other
|
27
|
+
contributions that are not aligned to this Code of Conduct, or to ban
|
28
|
+
temporarily or permanently any contributor for other behaviors that they
|
29
|
+
deem inappropriate, threatening, offensive, or harmful.
|
30
|
+
|
31
|
+
By adopting this Code of Conduct, project maintainers commit themselves
|
32
|
+
to fairly and consistently applying these principles to every aspect of
|
33
|
+
managing this project. Project maintainers who do not follow or enforce
|
34
|
+
the Code of Conduct may be permanently removed from the project team.
|
35
|
+
|
36
|
+
This Code of Conduct applies both within project spaces and in public
|
37
|
+
spaces when an individual is representing the project or its community.
|
38
|
+
|
39
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may
|
40
|
+
be reported by contacting a project maintainer at <opensource@shopify.com>.
|
41
|
+
All complaints will be reviewed and investigated and will result in a response
|
42
|
+
that is deemed necessary and appropriate to the circumstances. Maintainers are
|
43
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
44
|
+
|
45
|
+
This Code of Conduct is adapted from the Contributor Covenant, version
|
46
|
+
1.3.0, available from http://contributor-covenant.org/version/1/3/0/
|
data/Gemfile.lock
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
shopify_app (
|
4
|
+
shopify_app (22.00.0)
|
5
5
|
activeresource
|
6
6
|
addressable (~> 2.7)
|
7
|
-
browser_sniffer (~> 2.0)
|
8
7
|
jwt (>= 2.2.3)
|
9
8
|
rails (> 5.2.1)
|
10
9
|
redirect_safely (~> 1.0)
|
11
|
-
shopify_api (~>
|
10
|
+
shopify_api (~> 14)
|
12
11
|
sprockets-rails (>= 2.0.0)
|
13
12
|
|
14
13
|
GEM
|
@@ -86,7 +85,6 @@ GEM
|
|
86
85
|
ast (2.4.2)
|
87
86
|
binding_of_caller (1.0.0)
|
88
87
|
debug_inspector (>= 0.0.1)
|
89
|
-
browser_sniffer (2.2.0)
|
90
88
|
builder (3.2.4)
|
91
89
|
byebug (11.1.3)
|
92
90
|
coderay (1.1.3)
|
@@ -134,11 +132,11 @@ GEM
|
|
134
132
|
net-smtp (0.3.3)
|
135
133
|
net-protocol
|
136
134
|
nio4r (2.5.9)
|
137
|
-
nokogiri (1.
|
135
|
+
nokogiri (1.16.2-arm64-darwin)
|
138
136
|
racc (~> 1.4)
|
139
|
-
nokogiri (1.
|
137
|
+
nokogiri (1.16.2-x86_64-darwin)
|
140
138
|
racc (~> 1.4)
|
141
|
-
nokogiri (1.
|
139
|
+
nokogiri (1.16.2-x86_64-linux)
|
142
140
|
racc (~> 1.4)
|
143
141
|
oj (3.14.3)
|
144
142
|
openssl (3.1.0)
|
@@ -155,7 +153,7 @@ GEM
|
|
155
153
|
binding_of_caller (~> 1.0)
|
156
154
|
pry (~> 0.13)
|
157
155
|
public_suffix (5.0.1)
|
158
|
-
racc (1.
|
156
|
+
racc (1.7.3)
|
159
157
|
rack (2.2.7)
|
160
158
|
rack-test (2.1.0)
|
161
159
|
rack (>= 1.3)
|
@@ -217,7 +215,7 @@ GEM
|
|
217
215
|
ruby-progressbar (1.13.0)
|
218
216
|
ruby2_keywords (0.0.5)
|
219
217
|
securerandom (0.2.2)
|
220
|
-
shopify_api (
|
218
|
+
shopify_api (14.0.0)
|
221
219
|
activesupport
|
222
220
|
concurrent-ruby
|
223
221
|
hash_diff
|
data/README.md
CHANGED
@@ -106,7 +106,6 @@ You can find documentation on gem usage, concepts, mixins, installation, and mor
|
|
106
106
|
* [Engine](/docs/shopify_app/engine.md)
|
107
107
|
* [Controller Concerns](/docs/shopify_app/controller-concerns.md)
|
108
108
|
* [Generators](/docs/shopify_app/generators.md)
|
109
|
-
* [ScriptTags](/docs/shopify_app/script-tags.md)
|
110
109
|
* [Sessions](/docs/shopify_app/sessions.md)
|
111
110
|
* [Handling changes in access scopes](/docs/shopify_app/handling-access-scopes-changes.md)
|
112
111
|
* [Testing](/docs/shopify_app/testing.md)
|
@@ -20,11 +20,15 @@ module ShopifyApp
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def splash_page_with_params(params)
|
23
|
-
uri = URI(
|
23
|
+
uri = URI(base_url)
|
24
24
|
uri.query = params.compact.to_query
|
25
25
|
uri.to_s
|
26
26
|
end
|
27
27
|
|
28
|
+
def base_url
|
29
|
+
ShopifyApp.configuration.root_url.presence || root_path
|
30
|
+
end
|
31
|
+
|
28
32
|
def redirect_to_splash_page
|
29
33
|
redirect_to(splash_page)
|
30
34
|
rescue ::ShopifyApp::ShopifyDomainNotFound => error
|
@@ -9,10 +9,10 @@ module ShopifyApp
|
|
9
9
|
if defined?(ShopifyApp::LoginProtection) && ancestors.include?(ShopifyApp::LoginProtection)
|
10
10
|
message = <<~EOS
|
11
11
|
We detected the use of incompatible concerns (EnsureInstalled and LoginProtection) in #{name},
|
12
|
-
which
|
12
|
+
which leads to unpredictable behavior. You cannot include both concerns in the same controller.
|
13
13
|
EOS
|
14
14
|
|
15
|
-
|
15
|
+
raise message
|
16
16
|
end
|
17
17
|
|
18
18
|
before_action :check_shop_domain
|
@@ -10,8 +10,12 @@ module ShopifyApp
|
|
10
10
|
begin
|
11
11
|
api_session, cookie = validated_auth_objects
|
12
12
|
rescue => error
|
13
|
-
|
14
|
-
|
13
|
+
if error.class.module_parent == ShopifyAPI::Errors
|
14
|
+
callback_rescue(error)
|
15
|
+
return respond_with_error
|
16
|
+
else
|
17
|
+
raise error
|
18
|
+
end
|
15
19
|
end
|
16
20
|
|
17
21
|
save_session(api_session) if api_session
|
@@ -25,6 +29,10 @@ module ShopifyApp
|
|
25
29
|
|
26
30
|
private
|
27
31
|
|
32
|
+
def callback_rescue(error)
|
33
|
+
ShopifyApp::Logger.debug("#{error.class} was rescued and redirected to login_url_with_optional_shop")
|
34
|
+
end
|
35
|
+
|
28
36
|
def deprecate_callback_rescue(error)
|
29
37
|
message = <<~EOS
|
30
38
|
An error of type #{error.class} was rescued. This is not part of `ShopifyAPI::Errors`, which could indicate a
|
@@ -130,8 +138,11 @@ module ShopifyApp
|
|
130
138
|
end
|
131
139
|
|
132
140
|
def perform_post_authenticate_jobs(session)
|
133
|
-
|
134
|
-
|
141
|
+
# Ensure we use the shop session to install webhooks
|
142
|
+
session_for_shop = session.online? ? shop_session : session
|
143
|
+
|
144
|
+
install_webhooks(session_for_shop)
|
145
|
+
|
135
146
|
perform_after_authenticate_job(session)
|
136
147
|
end
|
137
148
|
|
@@ -141,16 +152,6 @@ module ShopifyApp
|
|
141
152
|
WebhooksManager.queue(session.shop, session.access_token)
|
142
153
|
end
|
143
154
|
|
144
|
-
def install_scripttags(session)
|
145
|
-
return unless ShopifyApp.configuration.has_scripttags?
|
146
|
-
|
147
|
-
ScripttagsManager.queue(
|
148
|
-
session.shop,
|
149
|
-
session.access_token,
|
150
|
-
ShopifyApp.configuration.scripttags,
|
151
|
-
)
|
152
|
-
end
|
153
|
-
|
154
155
|
def perform_after_authenticate_job(session)
|
155
156
|
config = ShopifyApp.configuration.after_authenticate_job
|
156
157
|
|
data/config/routes.rb
CHANGED
data/docs/Upgrading.md
CHANGED
@@ -8,6 +8,8 @@ This file documents important changes needed to upgrade your app's Shopify App v
|
|
8
8
|
|
9
9
|
[Unreleased](#unreleased)
|
10
10
|
|
11
|
+
[Upgrading to `v22.0.0`](#upgrading-to-v2200)
|
12
|
+
|
11
13
|
[Upgrading to `v20.3.0`](#upgrading-to-v2030)
|
12
14
|
|
13
15
|
[Upgrading to `v20.2.0`](#upgrading-to-v2020)
|
@@ -38,8 +40,30 @@ We also recommend the use of a staging site which matches your production enviro
|
|
38
40
|
|
39
41
|
If you do run into issues, we recommend looking at our [debugging tips.](https://github.com/Shopify/shopify_app/blob/main/docs/Troubleshooting.md#debugging-tips)
|
40
42
|
|
43
|
+
## Upgrading to `v22.0.0`
|
44
|
+
#### Dropped support for Ruby 2.x
|
45
|
+
Support for Ruby 2.x has been dropped as it is no longer supported. You'll need to upgrade to 3.x.x
|
46
|
+
|
47
|
+
#### Renamed Controller Concerns
|
48
|
+
The following controller concerns have been renamed/replaced in `v21.10.0` and have now been removed. To upgrade, please rename any usage in your apps's controllers that include them to the following:
|
49
|
+
|
50
|
+
|Old Deprecated Controller Concern |Replaced By New Controller Concern|
|
51
|
+
|---|---|
|
52
|
+
|`Authenticated`|`EnsureHasSession`|
|
53
|
+
|`RequireKnownShop`|`EnsureInstalled`|
|
54
|
+
|
55
|
+
The new names better reflect what assurances the including the controller concern provide. The new concern provide similar if not identical functionality as the concerns they replaced.
|
56
|
+
|
57
|
+
#### Remove ScripttagManager
|
58
|
+
Script tag usage has largely been replaced with the adoption of [theme app extensions](https://shopify.dev/docs/apps/online-store/theme-app-extensions) and [thank you order status customization](https://shopify.dev/docs/apps/checkout/thank-you-order-status). The manager has been removed with this major release due to effective replacement and a goal to have parity in supported functionality across language stacks.
|
59
|
+
|
60
|
+
If you find yourself still using Scipt Tags and want to continue the pattern of declarative management of script tags this gem used to use, we recommend porting the logic [the manager used in prior versions](https://github.com/Shopify/shopify_app/blob/2336fabc6d0b45a4dee3f336455dace4d2d88bc4/lib/shopify_app/managers/scripttags_manager.rb#L4) and implementing it in a [post authentication job](https://github.com/Shopify/shopify_app/blob/main/docs/shopify_app/authentication.md#run-jobs-after-the-oauth-flow). This is the recommended flow to create script tags (or any other logic) for stores that install your app.
|
61
|
+
|
62
|
+
#### No longer rescue non-shopify API errors during customized OAuth flow
|
63
|
+
If you have customized authentication logic and are counting on the `CallbackController` to catch your error and redirect to login, you'll need to catch that error and redirect to `login_url_with_optional_shop`.
|
64
|
+
|
41
65
|
## Upgrading to 21.3.0
|
42
|
-
The `Itp` controller concern has been removed from `LoginProtection` which is included by the `Authenticated` controller concern.
|
66
|
+
The `Itp` controller concern has been removed from `LoginProtection` which is included by the `Authenticated`/`EnsureHasSession` controller concern.
|
43
67
|
If any of your controllers are dependant on methods from `Itp` then you can include `ShopifyApp::Itp` directly.
|
44
68
|
You may notice a deprecation notice saying, `Itp will be removed in an upcoming version`.
|
45
69
|
This is because we intend on removing `Itp` completely in `v22.0.0`, but this will work in the meantime.
|
@@ -64,5 +64,26 @@ Implements Rails' [protect_from_forgery](https://api.rubyonrails.org/classes/Act
|
|
64
64
|
#### EmbeddedApp
|
65
65
|
If your ShopifyApp configuration has the `embedded_app` config set to true, [P3P header](https://www.w3.org/P3P/) and [content security policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) are handled for you.
|
66
66
|
|
67
|
+
By default, the `EmbeddedApp` concern also sets the layout file to be `app/views/layouts/embedded_app.html.erb`.
|
68
|
+
|
69
|
+
Sometimes one wants to run an embedded app in non-embedded mode. For example:
|
70
|
+
|
71
|
+
- When the remote environment is a CI;
|
72
|
+
- When the remote environment is a preview/PR app;
|
73
|
+
- When the developer wants to run the app in a non-embedded mode for testing.
|
74
|
+
|
75
|
+
To use the same application layout for every application controller, a developer can now overwrite the `#use_embedded_app_layout?` method.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
class ApplicationController
|
79
|
+
# Ensures every controller is using the standard app/views/layouts/application.html.erb layout.
|
80
|
+
#
|
81
|
+
# @return [true, false]
|
82
|
+
def use_embedded_app_layout?
|
83
|
+
false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
67
88
|
#### EnsureBilling
|
68
89
|
If billing is enabled for the app, the active payment for the session is queried and enforced if needed. If billing is required the user will be redirected to a page requesting payment.
|
@@ -68,13 +68,13 @@ Specify whether the app is an embedded app. Apps are embedded by default.
|
|
68
68
|
|
69
69
|
#### `$ rails generate shopify_app:shop_model`
|
70
70
|
|
71
|
-
This generator creates a `Shop` model and a migration to store shop installation records. See [*Shop-based token strategy*](/docs/shopify_app/
|
71
|
+
This generator creates a `Shop` model and a migration to store shop installation records. See [*Shop-based token strategy*](/docs/shopify_app/sessions.md#shop-offline-token-storage) to learn more.
|
72
72
|
|
73
73
|
---
|
74
74
|
|
75
75
|
#### `$ rails generate shopify_app:user_model`
|
76
76
|
|
77
|
-
This generator creates a `User` model and a migration to store user records. See [*User-based token strategy*](/docs/shopify_app/
|
77
|
+
This generator creates a `User` model and a migration to store user records. See [*User-based token strategy*](/docs/shopify_app/sessions.md#user-online-token-storage) to learn more.
|
78
78
|
|
79
79
|
---
|
80
80
|
|
@@ -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
|
8
|
-
|
9
|
-
- [
|
10
|
-
- [
|
11
|
-
- [
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
17
|
-
- [User
|
18
|
-
- [Getting
|
19
|
-
- [Access scopes](#access-scopes)
|
20
|
-
|
21
|
-
|
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).
|
@@ -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
|
@@ -7,14 +7,22 @@ module ShopifyApp
|
|
7
7
|
include ShopifyApp::FrameAncestors
|
8
8
|
|
9
9
|
included do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
layout :embedded_app_layout
|
11
|
+
after_action :set_esdk_headers, if: -> { ShopifyApp.configuration.embedded_app? }
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def use_embedded_app_layout?
|
17
|
+
ShopifyApp.configuration.embedded_app?
|
14
18
|
end
|
15
19
|
|
16
20
|
private
|
17
21
|
|
22
|
+
def embedded_app_layout
|
23
|
+
"embedded_app" if use_embedded_app_layout?
|
24
|
+
end
|
25
|
+
|
18
26
|
def set_esdk_headers
|
19
27
|
response.set_header("P3P", 'CP="Not used"')
|
20
28
|
response.headers.except!("X-Frame-Options")
|