shopify_app 8.2.6 → 8.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +7 -0
- data/CHANGELOG.md +5 -0
- data/README.md +3 -5
- data/app/assets/javascripts/shopify_app/itp_polyfill.js +30 -0
- data/app/assets/javascripts/shopify_app/redirect.js +30 -16
- data/app/controllers/shopify_app/sessions_controller.rb +42 -5
- data/app/views/shopify_app/sessions/enable_cookies.html.erb +386 -0
- data/config/locales/en.yml +4 -0
- data/config/routes.rb +1 -0
- data/lib/generators/shopify_app/install/templates/_flash_messages.html.erb +2 -2
- data/lib/shopify_app/controller_concerns/login_protection.rb +58 -18
- data/lib/shopify_app/engine.rb +4 -1
- data/lib/shopify_app/version.rb +1 -1
- data/translation.yml +7 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67993e953b33ffe850f9db651c7ecc411d5933b2
|
4
|
+
data.tar.gz: ca5981beba2ea540681d77363dc1ae6c4bd009de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7665bf0987e8738cbeb9d8c0e92fa3e3d2055ffe60c80d6b50795d7f2db83e18d7df4fb89da81fc6226cacfc6fbb7fe0059d34a36071d5e90f259cb870004444
|
7
|
+
data.tar.gz: 353060a370d4ba42c86ebc95b0d09f1ee32d3eb106db177df4dec3f2580e0acb30fef419715db35b3a023337d2dd7874718a2e3277ea0729fbb52676394ba72e
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -143,7 +143,7 @@ After running the `install` generator, you can start your app with `bundle exec
|
|
143
143
|
$ rails generate shopify_app:shop_model
|
144
144
|
```
|
145
145
|
|
146
|
-
The install generator doesn't create any database tables or models for you. If you are starting a new app its quite likely that you will want a shops table and model to store the tokens when your app is installed (most of our internally developed apps do!). This generator creates a shop model and a migration. This model includes the `ShopifyApp::SessionStorage` concern which adds two methods to make it compatible as a `SessionRepository`. After running this generator you'll notice the `session_repository` in your `config/initializers/shopify_app.rb` will be set to the `Shop` model. This means that internally ShopifyApp will try and load tokens from this model.
|
146
|
+
The `install` generator doesn't create any database tables or models for you. If you are starting a new app its quite likely that you will want a shops table and model to store the tokens when your app is installed (most of our internally developed apps do!). This generator creates a shop model and a migration. This model includes the `ShopifyApp::SessionStorage` concern which adds two methods to make it compatible as a `SessionRepository`. After running this generator you'll notice the `session_repository` in your `config/initializers/shopify_app.rb` will be set to the `Shop` model. This means that internally ShopifyApp will try and load tokens from this model.
|
147
147
|
|
148
148
|
*Note that you will need to run rake db:migrate after this generator*
|
149
149
|
|
@@ -413,8 +413,6 @@ Tunneling is also useful for working the the embedded app sdk to solve mixed con
|
|
413
413
|
|
414
414
|
Questions or problems?
|
415
415
|
----------------------
|
416
|
-
http://api.shopify.com <= Read up on the possible API calls!
|
417
416
|
|
418
|
-
|
419
|
-
|
420
|
-
http://docs.shopify.com/api/the-basics/getting-started <= Read the docs!
|
417
|
+
- [Ask questions!](https://ecommerce.shopify.com/c/shopify-apis-and-technology)
|
418
|
+
- [Read the docs!](https://help.shopify.com/api/guides)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
(function() {
|
2
|
+
function setCookieAndRedirect() {
|
3
|
+
document.cookie = "shopify.cookies_persist=true";
|
4
|
+
window.location.href = window.shopOrigin + "/admin/apps/" + window.apiKey;
|
5
|
+
}
|
6
|
+
|
7
|
+
function shouldDisplayPrompt() {
|
8
|
+
if (navigator.userAgent.indexOf('com.jadedpixel.pos') !== -1) {
|
9
|
+
return false;
|
10
|
+
}
|
11
|
+
|
12
|
+
if (navigator.userAgent.indexOf('Shopify Mobile/iOS') !== -1) {
|
13
|
+
return false;
|
14
|
+
}
|
15
|
+
|
16
|
+
return Boolean(document.hasStorageAccess);
|
17
|
+
}
|
18
|
+
|
19
|
+
document.addEventListener("DOMContentLoaded", function() {
|
20
|
+
if (shouldDisplayPrompt()) {
|
21
|
+
var itpContent = document.querySelector('#CookiePartitionPrompt');
|
22
|
+
itpContent.style.display = 'block';
|
23
|
+
|
24
|
+
var button = document.querySelector('#AcceptCookies');
|
25
|
+
button.addEventListener('click', setCookieAndRedirect);
|
26
|
+
} else {
|
27
|
+
setCookieAndRedirect();
|
28
|
+
}
|
29
|
+
});
|
30
|
+
})();
|
@@ -1,19 +1,33 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
(function() {
|
2
|
+
function redirect() {
|
3
|
+
var redirectTargetElement = document.getElementById("redirection-target");
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
} else {
|
9
|
-
// If the current window is the 'child', change the parent's URL with postMessage
|
10
|
-
normalizedLink = document.createElement('a');
|
11
|
-
normalizedLink.href = targetInfo.url;
|
5
|
+
if (!redirectTargetElement) {
|
6
|
+
return;
|
7
|
+
}
|
12
8
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
var targetInfo = JSON.parse(redirectTargetElement.dataset.target)
|
10
|
+
|
11
|
+
if (window.top == window.self) {
|
12
|
+
// If the current window is the 'parent', change the URL by setting location.href
|
13
|
+
window.top.location.href = targetInfo.url;
|
14
|
+
} else {
|
15
|
+
// If the current window is the 'child', change the parent's URL with postMessage
|
16
|
+
normalizedLink = document.createElement('a');
|
17
|
+
normalizedLink.href = targetInfo.url;
|
18
|
+
|
19
|
+
data = JSON.stringify({
|
20
|
+
message: 'Shopify.API.remoteRedirect',
|
21
|
+
data: {location: normalizedLink.href}
|
22
|
+
});
|
23
|
+
window.parent.postMessage(data, targetInfo.myshopifyUrl);
|
24
|
+
}
|
18
25
|
}
|
19
|
-
|
26
|
+
|
27
|
+
document.addEventListener("DOMContentLoaded", redirect);
|
28
|
+
|
29
|
+
// In the turbolinks context, neither DOMContentLoaded nor turbolinks:load
|
30
|
+
// consistently fires. This ensures that we at least attempt to fire in the
|
31
|
+
// turbolinks situation as well.
|
32
|
+
redirect();
|
33
|
+
})();
|
@@ -14,6 +14,11 @@ module ShopifyApp
|
|
14
14
|
authenticate
|
15
15
|
end
|
16
16
|
|
17
|
+
def enable_cookies
|
18
|
+
@shop = sanitized_shop_name
|
19
|
+
render_invalid_shop_error unless @shop
|
20
|
+
end
|
21
|
+
|
17
22
|
def callback
|
18
23
|
if auth_hash
|
19
24
|
login_shop
|
@@ -37,15 +42,47 @@ module ShopifyApp
|
|
37
42
|
private
|
38
43
|
|
39
44
|
def authenticate
|
40
|
-
|
41
|
-
|
42
|
-
|
45
|
+
return render_invalid_shop_error unless sanitized_shop_name.present?
|
46
|
+
session['shopify.omniauth_params'] = { shop: sanitized_shop_name }
|
47
|
+
|
48
|
+
if redirect_for_cookie_access?
|
49
|
+
fullpage_redirect_to enable_cookies_path(shop: sanitized_shop_name)
|
50
|
+
elsif authenticate_in_context?
|
51
|
+
authenticate_in_context
|
43
52
|
else
|
44
|
-
|
45
|
-
redirect_to return_address
|
53
|
+
authenticate_at_top_level
|
46
54
|
end
|
47
55
|
end
|
48
56
|
|
57
|
+
def render_invalid_shop_error
|
58
|
+
flash[:error] = I18n.t('invalid_shop_url')
|
59
|
+
redirect_to return_address
|
60
|
+
end
|
61
|
+
|
62
|
+
def authenticate_in_context
|
63
|
+
clear_top_level_oauth_cookie
|
64
|
+
redirect_to "#{main_app.root_path}auth/shopify"
|
65
|
+
end
|
66
|
+
|
67
|
+
def authenticate_at_top_level
|
68
|
+
set_top_level_oauth_cookie
|
69
|
+
fullpage_redirect_to login_url(top_level: true)
|
70
|
+
end
|
71
|
+
|
72
|
+
def authenticate_in_context?
|
73
|
+
return true unless ShopifyApp.configuration.embedded_app?
|
74
|
+
return true if params[:top_level]
|
75
|
+
session['shopify.top_level_oauth']
|
76
|
+
end
|
77
|
+
|
78
|
+
def redirect_for_cookie_access?
|
79
|
+
return false unless ShopifyApp.configuration.embedded_app?
|
80
|
+
return false if params[:top_level]
|
81
|
+
return false if session['shopify.cookies_persist']
|
82
|
+
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
49
86
|
def login_shop
|
50
87
|
sess = ShopifyAPI::Session.new(shop_name, token)
|
51
88
|
|
@@ -0,0 +1,386 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="<%= I18n.locale %>">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8" />
|
5
|
+
<style>
|
6
|
+
html,
|
7
|
+
body {
|
8
|
+
min-height:100%;
|
9
|
+
height:100%;
|
10
|
+
font-size:1.5rem;
|
11
|
+
font-weight:400;
|
12
|
+
line-height:2rem;
|
13
|
+
text-transform:initial;
|
14
|
+
letter-spacing:initial;
|
15
|
+
font-weight:400;
|
16
|
+
color:#212b36;
|
17
|
+
font-family:-apple-system, BlinkMacSystemFont, San Francisco, Roboto, Segoe UI, Helvetica Neue, sans-serif;
|
18
|
+
}
|
19
|
+
|
20
|
+
@media (min-width: 40em) {
|
21
|
+
html,
|
22
|
+
body {
|
23
|
+
font-size:1.4rem;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
html {
|
28
|
+
position:relative;
|
29
|
+
font-size:62.5%;
|
30
|
+
-webkit-font-smoothing:antialiased;
|
31
|
+
-moz-osx-font-smoothing:grayscale;
|
32
|
+
-webkit-text-size-adjust:100%;
|
33
|
+
-ms-text-size-adjust:100%;
|
34
|
+
text-size-adjust:100%;
|
35
|
+
text-rendering:optimizeLegibility;
|
36
|
+
}
|
37
|
+
|
38
|
+
body {
|
39
|
+
min-height:100%;
|
40
|
+
margin:0;
|
41
|
+
padding:0;
|
42
|
+
background-color:#f4f6f8;
|
43
|
+
}
|
44
|
+
|
45
|
+
*,
|
46
|
+
*::before,
|
47
|
+
*::after{
|
48
|
+
box-sizing:border-box; }
|
49
|
+
|
50
|
+
h1,
|
51
|
+
h2,
|
52
|
+
h3,
|
53
|
+
h4,
|
54
|
+
h5,
|
55
|
+
h6,
|
56
|
+
p {
|
57
|
+
margin:0;
|
58
|
+
font-size:1em;
|
59
|
+
font-weight:400;
|
60
|
+
}
|
61
|
+
|
62
|
+
#CookiePartitionPrompt {
|
63
|
+
display: none;
|
64
|
+
}
|
65
|
+
|
66
|
+
.Polaris-Page {
|
67
|
+
margin:0 auto;
|
68
|
+
padding:0;
|
69
|
+
max-width:99.8rem;
|
70
|
+
}
|
71
|
+
|
72
|
+
@media (min-width: 30.625em) {
|
73
|
+
.Polaris-Page {
|
74
|
+
padding:0 2rem;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
@media (min-width: 46.5em) {
|
78
|
+
.Polaris-Page {
|
79
|
+
padding:0 3.2rem;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
.Polaris-Page__Content {
|
84
|
+
margin:2rem 0;
|
85
|
+
}
|
86
|
+
|
87
|
+
@media (min-width: 46.5em) {
|
88
|
+
.Polaris-Page__Content {
|
89
|
+
margin-top:2rem;
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
@media (min-width: 46.5em) {
|
94
|
+
.Polaris-Page {
|
95
|
+
display: flex;
|
96
|
+
justify-content: center;
|
97
|
+
align-items: center;
|
98
|
+
height: 100vh;
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
.Polaris-Layout {
|
103
|
+
display:-webkit-box;
|
104
|
+
display:-ms-flexbox;
|
105
|
+
display:flex;
|
106
|
+
-ms-flex-wrap:wrap;
|
107
|
+
flex-wrap:wrap;
|
108
|
+
-webkit-box-pack:center;
|
109
|
+
-ms-flex-pack:center;
|
110
|
+
justify-content:center;
|
111
|
+
-webkit-box-align:start;
|
112
|
+
-ms-flex-align:start;
|
113
|
+
align-items:flex-start;
|
114
|
+
margin-top:-2rem;
|
115
|
+
margin-left:-2rem;
|
116
|
+
}
|
117
|
+
|
118
|
+
.Polaris-Layout__Section {
|
119
|
+
-webkit-box-flex:2;
|
120
|
+
-ms-flex:2 2 48rem;
|
121
|
+
flex:2 2 48rem;
|
122
|
+
min-width:51%;
|
123
|
+
}
|
124
|
+
|
125
|
+
.Polaris-Layout__Section--fullWidth {
|
126
|
+
-webkit-box-flex:1;
|
127
|
+
-ms-flex:1 1 100%;
|
128
|
+
flex:1 1 100%;
|
129
|
+
}
|
130
|
+
|
131
|
+
.Polaris-Layout__Section {
|
132
|
+
max-width:calc(100% - 2rem);
|
133
|
+
margin-top:2rem;
|
134
|
+
margin-left:2rem;
|
135
|
+
}
|
136
|
+
|
137
|
+
.Polaris-Stack {
|
138
|
+
margin-top:-1.6rem;
|
139
|
+
margin-left:-1.6rem;
|
140
|
+
display:-webkit-box;
|
141
|
+
display:-ms-flexbox;
|
142
|
+
display:flex;
|
143
|
+
-ms-flex-wrap:wrap;
|
144
|
+
flex-wrap:wrap;
|
145
|
+
-webkit-box-align:stretch;
|
146
|
+
-ms-flex-align:stretch;
|
147
|
+
align-items:stretch;
|
148
|
+
}
|
149
|
+
|
150
|
+
.Polaris-Stack > .Polaris-Stack__Item {
|
151
|
+
margin-top:1.6rem;
|
152
|
+
margin-left:1.6rem;
|
153
|
+
max-width:calc(100% - 1.6rem);
|
154
|
+
}
|
155
|
+
|
156
|
+
.Polaris-Stack__Item {
|
157
|
+
-webkit-box-flex:0;
|
158
|
+
-ms-flex:0 0 auto;
|
159
|
+
flex:0 0 auto;
|
160
|
+
min-width:0;
|
161
|
+
}
|
162
|
+
|
163
|
+
.Polaris-Heading {
|
164
|
+
font-size:1.7rem;
|
165
|
+
font-weight:600;
|
166
|
+
line-height:2.4rem;
|
167
|
+
margin:0;
|
168
|
+
}
|
169
|
+
|
170
|
+
@media (min-width: 40em) {
|
171
|
+
.Polaris-Heading {
|
172
|
+
font-size:1.6rem;
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
.Polaris-Card {
|
177
|
+
overflow:hidden;
|
178
|
+
background-color:white;
|
179
|
+
box-shadow:0 0 0 1px rgba(63, 63, 68, 0.05), 0 1px 3px 0 rgba(63, 63, 68, 0.15);
|
180
|
+
}
|
181
|
+
|
182
|
+
.Polaris-Card + .Polaris-Card {
|
183
|
+
margin-top:2rem;
|
184
|
+
}
|
185
|
+
|
186
|
+
@media (min-width: 30.625em) {
|
187
|
+
.Polaris-Card {
|
188
|
+
border-radius:3px;
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
.Polaris-Card__Header {
|
193
|
+
padding:2rem 2rem 0;
|
194
|
+
}
|
195
|
+
|
196
|
+
.Polaris-Card__Section {
|
197
|
+
padding:2rem;
|
198
|
+
}
|
199
|
+
|
200
|
+
.Polaris-Card__Section + .Polaris-Card__Section {
|
201
|
+
border-top:1px solid #dfe3e8;
|
202
|
+
}
|
203
|
+
|
204
|
+
.Polaris-Card__Section--subdued {
|
205
|
+
background-color:#f9fafb;
|
206
|
+
}
|
207
|
+
|
208
|
+
|
209
|
+
.Polaris-Stack--distributionTrailing {
|
210
|
+
-webkit-box-pack:end;
|
211
|
+
-ms-flex-pack:end;
|
212
|
+
justify-content:flex-end;
|
213
|
+
}
|
214
|
+
|
215
|
+
.Polaris-Stack--vertical {
|
216
|
+
-webkit-box-orient:vertical;
|
217
|
+
-webkit-box-direction:normal;
|
218
|
+
-ms-flex-direction:column;
|
219
|
+
flex-direction:column;
|
220
|
+
}
|
221
|
+
|
222
|
+
.Polaris-Button {
|
223
|
+
fill:#637381;
|
224
|
+
position:relative;
|
225
|
+
display:-webkit-inline-box;
|
226
|
+
display:-ms-inline-flexbox;
|
227
|
+
display:inline-flex;
|
228
|
+
-webkit-box-align:center;
|
229
|
+
-ms-flex-align:center;
|
230
|
+
align-items:center;
|
231
|
+
-webkit-box-pack:center;
|
232
|
+
-ms-flex-pack:center;
|
233
|
+
justify-content:center;
|
234
|
+
min-height:3.6rem;
|
235
|
+
min-width:3.6rem;
|
236
|
+
margin:0;
|
237
|
+
padding:0.7rem 1.6rem;
|
238
|
+
background:linear-gradient(to bottom, white, #f9fafb);
|
239
|
+
border:1px solid #c4cdd5;
|
240
|
+
box-shadow:0 1px 0 0 rgba(22, 29, 37, 0.05);
|
241
|
+
border-radius:3px;
|
242
|
+
line-height:1;
|
243
|
+
color:#212b36;
|
244
|
+
text-align:center;
|
245
|
+
cursor:pointer;
|
246
|
+
-webkit-user-select:none;
|
247
|
+
-moz-user-select:none;
|
248
|
+
-ms-user-select:none;
|
249
|
+
user-select:none;
|
250
|
+
text-decoration:none;
|
251
|
+
transition-property:background, border, box-shadow;
|
252
|
+
transition-duration:200ms;
|
253
|
+
transition-timing-function:cubic-bezier(0.64, 0, 0.35, 1);
|
254
|
+
}
|
255
|
+
|
256
|
+
.Polaris-Button:hover {
|
257
|
+
background:linear-gradient(to bottom, #f9fafb, #f4f6f8);
|
258
|
+
border-color:#c4cdd5;
|
259
|
+
}
|
260
|
+
|
261
|
+
.Polaris-Button:focus {
|
262
|
+
border-color:#5c6ac4;
|
263
|
+
outline:0;
|
264
|
+
box-shadow:0 0 0 1px #5c6ac4;
|
265
|
+
}
|
266
|
+
|
267
|
+
.Polaris-Button:active {
|
268
|
+
background:linear-gradient(to bottom, #f4f6f8, #f4f6f8);
|
269
|
+
border-color:#c4cdd5;
|
270
|
+
box-shadow:0 0 0 0 transparent, inset 0 1px 1px 0 rgba(99, 115, 129, 0.1), inset 0 1px 4px 0 rgba(99, 115, 129, 0.2);
|
271
|
+
}
|
272
|
+
|
273
|
+
.Polaris-Button.Polaris-Button--disabled {
|
274
|
+
fill:#919eab;
|
275
|
+
transition:none;
|
276
|
+
background:linear-gradient(to bottom, #f4f6f8, #f4f6f8);
|
277
|
+
color:#919eab;
|
278
|
+
}
|
279
|
+
|
280
|
+
.Polaris-Button__Content {
|
281
|
+
font-size:1.5rem;
|
282
|
+
font-weight:400;
|
283
|
+
line-height:1.6rem;
|
284
|
+
text-transform:initial;
|
285
|
+
letter-spacing:initial;
|
286
|
+
position:relative;
|
287
|
+
display:-webkit-box;
|
288
|
+
display:-ms-flexbox;
|
289
|
+
display:flex;
|
290
|
+
-webkit-box-pack:center;
|
291
|
+
-ms-flex-pack:center;
|
292
|
+
justify-content:center;
|
293
|
+
-webkit-box-align:center;
|
294
|
+
-ms-flex-align:center;
|
295
|
+
align-items:center;
|
296
|
+
min-width:1px;
|
297
|
+
min-height:1px;
|
298
|
+
}
|
299
|
+
|
300
|
+
@media (min-width: 40em) {
|
301
|
+
.Polaris-Button__Content {
|
302
|
+
font-size:1.4rem;
|
303
|
+
}
|
304
|
+
}
|
305
|
+
|
306
|
+
.Polaris-Button--primary {
|
307
|
+
background:linear-gradient(to bottom, #6371c7, #5563c1);
|
308
|
+
border-color:#3f4eae;
|
309
|
+
box-shadow:inset 0 1px 0 0 #6774c8, 0 1px 0 0 rgba(22, 29, 37, 0.05), 0 0 0 0 transparent;
|
310
|
+
color:white;
|
311
|
+
fill:white;
|
312
|
+
}
|
313
|
+
|
314
|
+
.Polaris-Button--primary:hover {
|
315
|
+
background:linear-gradient(to bottom, #5c6ac4, #4959bd);
|
316
|
+
border-color:#3f4eae;
|
317
|
+
color:white;
|
318
|
+
text-decoration:none;
|
319
|
+
}
|
320
|
+
|
321
|
+
.Polaris-Button--primary:focus {
|
322
|
+
border-color:#202e78;
|
323
|
+
box-shadow:inset 0 1px 0 0 #6f7bcb, 0 1px 0 0 rgba(22, 29, 37, 0.05), 0 0 0 1px #202e78;
|
324
|
+
}
|
325
|
+
|
326
|
+
.Polaris-Button--primary:active {
|
327
|
+
background:linear-gradient(to bottom, #3f4eae, #3f4eae);
|
328
|
+
border-color:#38469b;
|
329
|
+
box-shadow:inset 0 0 0 0 transparent, 0 1px 0 0 rgba(22, 29, 37, 0.05), 0 0 1px 0 #38469b;
|
330
|
+
}
|
331
|
+
|
332
|
+
.Polaris-Button--primary.Polaris-Button--disabled {
|
333
|
+
fill:white;
|
334
|
+
background:linear-gradient(to bottom, #bac0e6, #bac0e6);
|
335
|
+
border-color:#a7aedf;
|
336
|
+
box-shadow:none;
|
337
|
+
color:white;
|
338
|
+
}
|
339
|
+
</style>
|
340
|
+
<base target="_top">
|
341
|
+
<title>Redirecting…</title>
|
342
|
+
|
343
|
+
<script>
|
344
|
+
window.apiKey = "<%= ShopifyApp.configuration.api_key %>";
|
345
|
+
window.shopOrigin = "https://<%= @shop %>";
|
346
|
+
</script>
|
347
|
+
|
348
|
+
<%= javascript_include_tag('shopify_app/itp_polyfill', crossorigin: 'anonymous', integrity: true) %>
|
349
|
+
</head>
|
350
|
+
<body>
|
351
|
+
<main id="CookiePartitionPrompt">
|
352
|
+
<div class="Polaris-Page">
|
353
|
+
<div class="Polaris-Page__Content">
|
354
|
+
<div class="Polaris-Layout">
|
355
|
+
<div class="Polaris-Layout__Section">
|
356
|
+
<div class="Polaris-Stack Polaris-Stack--vertical">
|
357
|
+
<div class="Polaris-Stack__Item">
|
358
|
+
<div class="Polaris-Card">
|
359
|
+
<div class="Polaris-Card__Header">
|
360
|
+
<h1 class="Polaris-Heading"><%= I18n.t('enable_cookies_heading', app: ShopifyApp.configuration.application_name) %></h1>
|
361
|
+
</div>
|
362
|
+
<div class="Polaris-Card__Section">
|
363
|
+
<p><%= I18n.t('enable_cookies_body', app: ShopifyApp.configuration.application_name) %></p>
|
364
|
+
</div>
|
365
|
+
<div class="Polaris-Card__Section Polaris-Card__Section--subdued">
|
366
|
+
<p><%= I18n.t('enable_cookies_footer') %></p>
|
367
|
+
</div>
|
368
|
+
</div>
|
369
|
+
</div>
|
370
|
+
<div class="Polaris-Stack__Item">
|
371
|
+
<div class="Polaris-Stack Polaris-Stack--distributionTrailing">
|
372
|
+
<div class="Polaris-Stack__Item">
|
373
|
+
<button type="button" class="Polaris-Button Polaris-Button--primary" id="AcceptCookies">
|
374
|
+
<span class="Polaris-Button__Content"><span><%= I18n.t('enable_cookies_action') %></span></span>
|
375
|
+
</button>
|
376
|
+
</div>
|
377
|
+
</div>
|
378
|
+
</div>
|
379
|
+
</div>
|
380
|
+
</div>
|
381
|
+
</div>
|
382
|
+
</div>
|
383
|
+
</div>
|
384
|
+
</main>
|
385
|
+
</body>
|
386
|
+
</html>
|
data/config/locales/en.yml
CHANGED
@@ -2,3 +2,7 @@ en:
|
|
2
2
|
logged_out: 'Successfully logged out'
|
3
3
|
could_not_log_in: 'Could not log in to Shopify store'
|
4
4
|
invalid_shop_url: 'Invalid shop domain'
|
5
|
+
enable_cookies_heading: "Enable cookies from %{app}"
|
6
|
+
enable_cookies_body: "You must manually enable cookies in this browser in order to use %{app} within Shopify."
|
7
|
+
enable_cookies_footer: 'Cookies let the app authenticate you by temporarily storing your preferences and personal information. They expire after 30 days.'
|
8
|
+
enable_cookies_action: 'Enable cookies'
|
data/config/routes.rb
CHANGED
@@ -2,6 +2,7 @@ ShopifyApp::Engine.routes.draw do
|
|
2
2
|
controller :sessions do
|
3
3
|
get 'login' => :new, :as => :login
|
4
4
|
post 'login' => :create, :as => :authenticate
|
5
|
+
get 'enable_cookies' => :enable_cookies, :as => :enable_cookies
|
5
6
|
get 'auth/shopify/callback' => :callback
|
6
7
|
get 'logout' => :destroy, :as => :logout
|
7
8
|
end
|
@@ -5,11 +5,11 @@
|
|
5
5
|
if (!document.documentElement.hasAttribute("data-turbolinks-preview")) {
|
6
6
|
document.addEventListener(eventName, function flash() {
|
7
7
|
<% if flash[:notice] %>
|
8
|
-
ShopifyApp.flashNotice(
|
8
|
+
ShopifyApp.flashNotice(<%== flash[:notice].to_json %>);
|
9
9
|
<% end %>
|
10
10
|
|
11
11
|
<% if flash[:error] %>
|
12
|
-
ShopifyApp.flashError(
|
12
|
+
ShopifyApp.flashError(<%== flash[:error].to_json %>);
|
13
13
|
<% end %>
|
14
14
|
|
15
15
|
document.removeEventListener(eventName, flash)
|
@@ -5,19 +5,19 @@ module ShopifyApp
|
|
5
5
|
class ShopifyDomainNotFound < StandardError; end
|
6
6
|
|
7
7
|
included do
|
8
|
+
after_action :set_test_cookie
|
8
9
|
rescue_from ActiveResource::UnauthorizedAccess, :with => :close_session
|
9
10
|
end
|
10
11
|
|
11
12
|
def shopify_session
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
redirect_to_login
|
13
|
+
return redirect_to_login unless shop_session
|
14
|
+
clear_top_level_oauth_cookie
|
15
|
+
|
16
|
+
begin
|
17
|
+
ShopifyAPI::Base.activate_session(shop_session)
|
18
|
+
yield
|
19
|
+
ensure
|
20
|
+
ShopifyAPI::Base.clear_session
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -28,8 +28,7 @@ module ShopifyApp
|
|
28
28
|
|
29
29
|
def login_again_if_different_shop
|
30
30
|
if shop_session && params[:shop] && params[:shop].is_a?(String) && (shop_session.url != params[:shop])
|
31
|
-
|
32
|
-
session[:shopify_domain] = nil
|
31
|
+
clear_shop_session
|
33
32
|
redirect_to_login
|
34
33
|
end
|
35
34
|
end
|
@@ -48,25 +47,42 @@ module ShopifyApp
|
|
48
47
|
end
|
49
48
|
|
50
49
|
def close_session
|
50
|
+
clear_shop_session
|
51
|
+
redirect_to login_url
|
52
|
+
end
|
53
|
+
|
54
|
+
def clear_shop_session
|
51
55
|
session[:shopify] = nil
|
52
56
|
session[:shopify_domain] = nil
|
53
|
-
|
57
|
+
session[:shopify_user] = nil
|
54
58
|
end
|
55
59
|
|
56
|
-
def login_url
|
60
|
+
def login_url(top_level: false)
|
57
61
|
url = ShopifyApp.configuration.login_url
|
58
62
|
|
59
|
-
|
60
|
-
query = { shop: sanitized_params[:shop] }.to_query
|
61
|
-
url = "#{url}?#{query}"
|
62
|
-
end
|
63
|
+
query_params = login_url_params(top_level: top_level)
|
63
64
|
|
65
|
+
url = "#{url}?#{query_params.to_query}" if query_params.present?
|
64
66
|
url
|
65
67
|
end
|
66
68
|
|
69
|
+
def login_url_params(top_level:)
|
70
|
+
query_params = {}
|
71
|
+
query_params[:shop] = sanitized_params[:shop] if params[:shop].present?
|
72
|
+
|
73
|
+
has_referer_shop_name = referer_sanitized_shop_name.present?
|
74
|
+
|
75
|
+
if has_referer_shop_name
|
76
|
+
query_params[:shop] ||= referer_sanitized_shop_name
|
77
|
+
end
|
78
|
+
|
79
|
+
query_params[:top_level] = true if top_level
|
80
|
+
query_params
|
81
|
+
end
|
82
|
+
|
67
83
|
def fullpage_redirect_to(url)
|
68
84
|
if ShopifyApp.configuration.embedded_app?
|
69
|
-
render 'shopify_app/shared/redirect', locals: { url: url, current_shopify_domain: current_shopify_domain }
|
85
|
+
render 'shopify_app/shared/redirect', layout: false, locals: { url: url, current_shopify_domain: current_shopify_domain }
|
70
86
|
else
|
71
87
|
redirect_to url
|
72
88
|
end
|
@@ -83,6 +99,17 @@ module ShopifyApp
|
|
83
99
|
@sanitized_shop_name ||= sanitize_shop_param(params)
|
84
100
|
end
|
85
101
|
|
102
|
+
def referer_sanitized_shop_name
|
103
|
+
return unless request.referer.present?
|
104
|
+
|
105
|
+
@referer_sanitized_shop_name ||= begin
|
106
|
+
referer_uri = URI(request.referer)
|
107
|
+
query_params = Rack::Utils.parse_query(referer_uri.query)
|
108
|
+
|
109
|
+
sanitize_shop_param(query_params.with_indifferent_access)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
86
113
|
def sanitize_shop_param(params)
|
87
114
|
return unless params[:shop].present?
|
88
115
|
ShopifyApp::Utils.sanitize_shop_domain(params[:shop])
|
@@ -95,5 +122,18 @@ module ShopifyApp
|
|
95
122
|
end
|
96
123
|
end
|
97
124
|
end
|
125
|
+
|
126
|
+
def set_test_cookie
|
127
|
+
return unless ShopifyApp.configuration.embedded_app?
|
128
|
+
session['shopify.cookies_persist'] = true
|
129
|
+
end
|
130
|
+
|
131
|
+
def clear_top_level_oauth_cookie
|
132
|
+
session.delete('shopify.top_level_oauth')
|
133
|
+
end
|
134
|
+
|
135
|
+
def set_top_level_oauth_cookie
|
136
|
+
session['shopify.top_level_oauth'] = true
|
137
|
+
end
|
98
138
|
end
|
99
139
|
end
|
data/lib/shopify_app/engine.rb
CHANGED
@@ -4,7 +4,10 @@ module ShopifyApp
|
|
4
4
|
isolate_namespace ShopifyApp
|
5
5
|
|
6
6
|
initializer "shopify_app.assets.precompile" do |app|
|
7
|
-
app.config.assets.precompile += %w
|
7
|
+
app.config.assets.precompile += %w[
|
8
|
+
shopify_app/redirect.js
|
9
|
+
shopify_app/itp_polyfill.js
|
10
|
+
]
|
8
11
|
end
|
9
12
|
end
|
10
13
|
end
|
data/lib/shopify_app/version.rb
CHANGED
data/translation.yml
ADDED
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: 8.
|
4
|
+
version: 8.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -130,16 +130,19 @@ extra_rdoc_files: []
|
|
130
130
|
files:
|
131
131
|
- ".github/ISSUE_TEMPLATE.md"
|
132
132
|
- ".gitignore"
|
133
|
+
- ".rubocop.yml"
|
133
134
|
- ".travis.yml"
|
134
135
|
- CHANGELOG.md
|
135
136
|
- Gemfile
|
136
137
|
- LICENSE
|
137
138
|
- README.md
|
138
139
|
- Rakefile
|
140
|
+
- app/assets/javascripts/shopify_app/itp_polyfill.js
|
139
141
|
- app/assets/javascripts/shopify_app/redirect.js
|
140
142
|
- app/controllers/shopify_app/authenticated_controller.rb
|
141
143
|
- app/controllers/shopify_app/sessions_controller.rb
|
142
144
|
- app/controllers/shopify_app/webhooks_controller.rb
|
145
|
+
- app/views/shopify_app/sessions/enable_cookies.html.erb
|
143
146
|
- app/views/shopify_app/sessions/new.html.erb
|
144
147
|
- app/views/shopify_app/shared/redirect.html.erb
|
145
148
|
- config/locales/de.yml
|
@@ -198,6 +201,7 @@ files:
|
|
198
201
|
- lib/shopify_app/version.rb
|
199
202
|
- shipit.rubygems.yml
|
200
203
|
- shopify_app.gemspec
|
204
|
+
- translation.yml
|
201
205
|
homepage:
|
202
206
|
licenses: []
|
203
207
|
metadata: {}
|