disco_app 0.5.6 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/disco_app/icon.svg +1 -0
  3. data/app/assets/stylesheets/disco_app/{bootstrap-custom.scss → bootstrap/_custom.scss} +3 -4
  4. data/app/assets/stylesheets/disco_app/bootstrap/_variables.scss +872 -0
  5. data/app/assets/stylesheets/disco_app/disco/_buttons.scss +31 -0
  6. data/app/assets/stylesheets/disco_app/disco/_cards.scss +43 -0
  7. data/app/assets/stylesheets/disco_app/disco/_forms.scss +23 -0
  8. data/app/assets/stylesheets/disco_app/disco/_sections.scss +61 -0
  9. data/app/assets/stylesheets/disco_app/disco/_type.scss +21 -0
  10. data/app/assets/stylesheets/disco_app/disco/mixins/_flexbox.scss +394 -0
  11. data/app/assets/stylesheets/disco_app/disco_app.scss +12 -6
  12. data/app/controllers/disco_app/authenticated_controller.rb +1 -1
  13. data/app/controllers/disco_app/install_controller.rb +1 -1
  14. data/app/controllers/disco_app/webhooks_controller.rb +11 -9
  15. data/app/jobs/disco_app/app_installed_job.rb +1 -1
  16. data/app/jobs/disco_app/app_uninstalled_job.rb +2 -17
  17. data/app/jobs/disco_app/concerns/app_uninstalled_job.rb +19 -0
  18. data/app/jobs/disco_app/shop_job.rb +1 -1
  19. data/app/jobs/disco_app/shop_update_job.rb +1 -1
  20. data/app/models/disco_app/concerns/plan.rb +14 -0
  21. data/app/models/disco_app/concerns/shop.rb +62 -0
  22. data/app/models/disco_app/concerns/subscription.rb +14 -0
  23. data/app/models/disco_app/plan.rb +3 -0
  24. data/app/models/disco_app/session_storage.rb +18 -0
  25. data/app/models/disco_app/shop.rb +2 -43
  26. data/app/models/disco_app/subscription.rb +3 -0
  27. data/app/services/disco_app/subscription_service.rb +25 -0
  28. data/app/services/disco_app/webhook_service.rb +30 -0
  29. data/app/views/disco_app/shared/_card.html.erb +16 -0
  30. data/app/views/disco_app/shared/_section.html.erb +17 -0
  31. data/{lib/generators/disco_app/templates → app}/views/layouts/embedded_app.html.erb +14 -6
  32. data/db/migrate/20150525000000_create_shops_if_not_existent.rb +15 -0
  33. data/db/migrate/20151017231302_create_disco_app_plans.rb +13 -0
  34. data/db/migrate/20151017232027_create_disco_app_subscriptions.rb +15 -0
  35. data/db/migrate/20151017234409_move_shop_to_disco_app_engine.rb +5 -0
  36. data/lib/disco_app/engine.rb +5 -0
  37. data/lib/disco_app/version.rb +1 -1
  38. data/lib/generators/disco_app/disco_app_generator.rb +31 -54
  39. data/lib/generators/disco_app/mailify/mailify_generator.rb +55 -0
  40. data/lib/generators/disco_app/templates/initializers/shopify_session_repository.rb +7 -0
  41. data/test/controllers/disco_app/install_controller_test.rb +50 -0
  42. data/test/controllers/disco_app/webhooks_controller_test.rb +58 -0
  43. data/test/controllers/home_controller_test.rb +61 -0
  44. data/test/dummy/app/assets/javascripts/application.js +4 -0
  45. data/test/dummy/app/assets/stylesheets/application.scss +5 -0
  46. data/test/dummy/app/controllers/application_controller.rb +1 -0
  47. data/test/dummy/app/controllers/home_controller.rb +7 -0
  48. data/test/dummy/app/jobs/disco_app/app_uninstalled_job.rb +11 -0
  49. data/test/dummy/app/models/disco_app/shop.rb +15 -0
  50. data/test/dummy/app/views/home/index.html.erb +2 -0
  51. data/test/dummy/config/application.rb +11 -0
  52. data/test/dummy/config/environments/production.rb +7 -1
  53. data/test/dummy/config/initializers/disco_app.rb +1 -0
  54. data/test/dummy/config/initializers/omniauth.rb +9 -0
  55. data/test/dummy/config/initializers/shopify_app.rb +7 -0
  56. data/test/dummy/config/initializers/shopify_session_repository.rb +7 -0
  57. data/test/dummy/config/routes.rb +5 -1
  58. data/test/dummy/config/secrets.yml +2 -2
  59. data/test/dummy/db/schema.rb +70 -0
  60. data/test/fixtures/api/widget_store/shop.json +46 -0
  61. data/test/fixtures/disco_app/plans.yml +32 -0
  62. data/test/fixtures/disco_app/shops.yml +10 -0
  63. data/test/fixtures/disco_app/subscriptions.yml +26 -0
  64. data/test/fixtures/webhooks/app_uninstalled.json +46 -0
  65. data/test/jobs/disco_app/app_installed_job_test.rb +29 -0
  66. data/test/jobs/disco_app/app_uninstalled_job_test.rb +32 -0
  67. data/test/models/disco_app/plan_test.rb +5 -0
  68. data/test/models/disco_app/shop_test.rb +26 -0
  69. data/test/models/disco_app/subscription_test.rb +6 -0
  70. data/test/services/disco_app/subscription_service_test.rb +28 -0
  71. data/test/support/test_file_fixtures.rb +29 -0
  72. data/test/test_helper.rb +32 -1
  73. metadata +148 -30
  74. data/app/assets/stylesheets/disco_app/bootstrap-variables.scss +0 -12
  75. data/lib/generators/disco_app/templates/jobs/app_installed_job.rb +0 -2
  76. data/lib/generators/disco_app/templates/jobs/app_uninstalled_job.rb +0 -2
  77. data/lib/generators/disco_app/templates/jobs/shop_update_job.rb +0 -2
  78. data/lib/generators/disco_app/templates/models/shop.rb +0 -3
  79. data/test/dummy/README.rdoc +0 -28
  80. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  81. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  82. data/test/lib/generators/disco_app/disco_app_generator_test.rb +0 -16
  83. /data/{lib/generators/disco_app/templates → app}/views/layouts/application.html.erb +0 -0
  84. /data/{lib/generators/disco_app/templates → app}/views/sessions/new.html.erb +0 -0
@@ -0,0 +1,31 @@
1
+ //
2
+ // Replicate the styles for Shopify Admin buttons.
3
+ // --------------------------------------------------
4
+
5
+ .btn {
6
+ line-height: 1;
7
+ padding: 8.5px 15px;
8
+ }
9
+
10
+ .btn-default {
11
+ &:hover, &:focus, &:active, &.active {
12
+ border-color: #d3dbe2;
13
+ background-color: #f5f6f7;
14
+ }
15
+ }
16
+
17
+ .btn-primary {
18
+ &:hover, &:focus, &:active, &.active {
19
+ border-color: #4293c2;
20
+ background-color: #4293c2;
21
+ }
22
+ }
23
+
24
+ .btn-disabled {
25
+ &, &:hover, &:focus, &:active {
26
+ cursor: default;
27
+ background: #fafbfc;
28
+ color: #c3cfd8;
29
+ border: 1px solid #d3dbe2;
30
+ }
31
+ }
@@ -0,0 +1,43 @@
1
+ //
2
+ // Replicate the styles for Shopify Admin cards.
3
+ // --------------------------------------------------
4
+
5
+ .next-card {
6
+ background-color: #ffffff;
7
+ border-radius: 3px;
8
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
9
+ }
10
+
11
+ .next-card ~ .next-card {
12
+ margin-top: 20px;
13
+ }
14
+
15
+ .next-card__header {
16
+ padding: 20px 20px 0;
17
+
18
+ h1, h2, h3 {
19
+ margin-bottom: 0;
20
+ font-size: 18px;
21
+ line-height: 1.2em;
22
+ }
23
+ }
24
+
25
+ .next-card__footer {
26
+ padding: 0 20px 20px;
27
+ }
28
+
29
+ .next-card__section {
30
+ padding: 20px;
31
+ }
32
+
33
+ .next-card--aside,
34
+ .next-card--disabled {
35
+ background-color: #f5f6f7;
36
+ }
37
+
38
+ .next-card--disabled {
39
+ .next-card__header,
40
+ .next-card__section {
41
+ color: #777777;
42
+ }
43
+ }
@@ -0,0 +1,23 @@
1
+ //
2
+ // Replicate the styles for Shopify Admin forms.
3
+ // --------------------------------------------------
4
+
5
+ .form-control {
6
+ -webkit-box-shadow: none;
7
+ box-shadow: none;
8
+
9
+ font-size: 15px;
10
+ line-height: 20px;
11
+
12
+ &:focus {
13
+ -webkit-box-shadow: none;
14
+ box-shadow: none;
15
+ }
16
+ }
17
+
18
+ .help-block {
19
+ font-style: italic;
20
+ font-size: 13px;
21
+ color: #95a7b7;
22
+ margin-top: 5px;
23
+ }
@@ -0,0 +1,61 @@
1
+ //
2
+ // Replicate the styles for Shopify Admin sections
3
+ // and flexbox layout.
4
+ // --------------------------------------------------
5
+
6
+
7
+ //== Layout
8
+ //
9
+ //## Simple Flexbox layout utilities.
10
+
11
+ .layout-content {
12
+ display: flex;
13
+ }
14
+
15
+ .layout-content__sidebar {
16
+ padding: 20px;
17
+ @include flex(1, 1, 25%);
18
+ max-width: 25%
19
+ }
20
+
21
+ .layout-content__main {
22
+ padding: 20px;
23
+ @include flex(1, 1, 0%);
24
+ }
25
+
26
+ .layout-content__first {
27
+ padding-right: 0;
28
+ }
29
+
30
+
31
+ //== Section
32
+ //
33
+ //## Simple Flexbox layout utilities.
34
+
35
+ //** Main section wrapper.
36
+ .section {
37
+ margin: 0;
38
+ padding: 0;
39
+ border-bottom: 1px solid #e6e6e6;
40
+ }
41
+
42
+ //** Section "summary" to the left of the section.
43
+ .section-summary {
44
+ padding: 20px 20px 20px 30px;
45
+
46
+ h1, h2 {
47
+ line-height: 1.325;
48
+ margin-top: -4px;
49
+ font-size: 18px;
50
+ margin-bottom: 10px;
51
+ }
52
+
53
+ p {
54
+ color: #798c9c;
55
+ margin-bottom: 15px;
56
+
57
+ &:last-child {
58
+ margin-bottom: 0;
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,21 @@
1
+ //
2
+ // Replicate the styles for Shopify Admin typography.
3
+ // --------------------------------------------------
4
+
5
+
6
+ //== Headings
7
+ //
8
+ //## Heading styles.
9
+
10
+ h1, .h1,
11
+ h2, .h2,
12
+ h3, .h3,
13
+ h4, .h4,
14
+ h5, .h5,
15
+ h6, .h6 {
16
+ margin: 0 0 20px 0;
17
+ }
18
+
19
+ p {
20
+ margin: 0;
21
+ }
@@ -0,0 +1,394 @@
1
+ // Flexbox Mixins
2
+ // http://philipwalton.github.io/solved-by-flexbox/
3
+ // https://github.com/philipwalton/solved-by-flexbox
4
+ //
5
+ // Copyright (c) 2013 Brian Franco
6
+ //
7
+ // Permission is hereby granted, free of charge, to any person obtaining a
8
+ // copy of this software and associated documentation files (the
9
+ // "Software"), to deal in the Software without restriction, including
10
+ // without limitation the rights to use, copy, modify, merge, publish,
11
+ // distribute, sublicense, and/or sell copies of the Software, and to
12
+ // permit persons to whom the Software is furnished to do so, subject to
13
+ // the following conditions:
14
+ // The above copyright notice and this permission notice shall be included
15
+ // in all copies or substantial portions of the Software.
16
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
+ // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ //
24
+ // This is a set of mixins for those who want to mess around with flexbox
25
+ // using the native support of current browsers. For full support table
26
+ // check: http://caniuse.com/flexbox
27
+ //
28
+ // Basically this will use:
29
+ //
30
+ // * Fallback, old syntax (IE10, mobile webkit browsers - no wrapping)
31
+ // * Final standards syntax (FF, Safari, Chrome, IE11, Opera)
32
+ //
33
+ // This was inspired by:
34
+ //
35
+ // * http://dev.opera.com/articles/view/advanced-cross-browser-flexbox/
36
+ //
37
+ // With help from:
38
+ //
39
+ // * http://w3.org/tr/css3-flexbox/
40
+ // * http://the-echoplex.net/flexyboxes/
41
+ // * http://msdn.microsoft.com/en-us/library/ie/hh772069(v=vs.85).aspx
42
+ // * http://css-tricks.com/using-flexbox/
43
+ // * http://dev.opera.com/articles/view/advanced-cross-browser-flexbox/
44
+ // * https://developer.mozilla.org/en-us/docs/web/guide/css/flexible_boxes
45
+
46
+ //----------------------------------------------------------------------
47
+
48
+ // Flexbox Containers
49
+ //
50
+ // The 'flex' value causes an element to generate a block-level flex
51
+ // container box.
52
+ //
53
+ // The 'inline-flex' value causes an element to generate a inline-level
54
+ // flex container box.
55
+ //
56
+ // display: flex | inline-flex
57
+ //
58
+ // http://w3.org/tr/css3-flexbox/#flex-containers
59
+ //
60
+ // (Placeholder selectors for each type, for those who rather @extend)
61
+
62
+ @mixin flexbox {
63
+ display: -webkit-box;
64
+ display: -webkit-flex;
65
+ display: -moz-flex;
66
+ display: -ms-flexbox;
67
+ display: flex;
68
+ }
69
+
70
+ %flexbox { @include flexbox; }
71
+
72
+ //----------------------------------
73
+
74
+ @mixin inline-flex {
75
+ display: -webkit-inline-box;
76
+ display: -webkit-inline-flex;
77
+ display: -moz-inline-flex;
78
+ display: -ms-inline-flexbox;
79
+ display: inline-flex;
80
+ }
81
+
82
+ %inline-flex { @include inline-flex; }
83
+
84
+ //----------------------------------------------------------------------
85
+
86
+ // Flexbox Direction
87
+ //
88
+ // The 'flex-direction' property specifies how flex items are placed in
89
+ // the flex container, by setting the direction of the flex container's
90
+ // main axis. This determines the direction that flex items are laid out in.
91
+ //
92
+ // Values: row | row-reverse | column | column-reverse
93
+ // Default: row
94
+ //
95
+ // http://w3.org/tr/css3-flexbox/#flex-direction-property
96
+
97
+ @mixin flex-direction($value: row) {
98
+ @if $value == row-reverse {
99
+ -webkit-box-direction: reverse;
100
+ -webkit-box-orient: horizontal;
101
+ } @else if $value == column {
102
+ -webkit-box-direction: normal;
103
+ -webkit-box-orient: vertical;
104
+ } @else if $value == column-reverse {
105
+ -webkit-box-direction: reverse;
106
+ -webkit-box-orient: vertical;
107
+ } @else {
108
+ -webkit-box-direction: normal;
109
+ -webkit-box-orient: horizontal;
110
+ }
111
+ -webkit-flex-direction: $value;
112
+ -moz-flex-direction: $value;
113
+ -ms-flex-direction: $value;
114
+ flex-direction: $value;
115
+ }
116
+ // Shorter version:
117
+ @mixin flex-dir($args...) { @include flex-direction($args...); }
118
+
119
+ //----------------------------------------------------------------------
120
+
121
+ // Flexbox Wrap
122
+ //
123
+ // The 'flex-wrap' property controls whether the flex container is single-line
124
+ // or multi-line, and the direction of the cross-axis, which determines
125
+ // the direction new lines are stacked in.
126
+ //
127
+ // Values: nowrap | wrap | wrap-reverse
128
+ // Default: nowrap
129
+ //
130
+ // http://w3.org/tr/css3-flexbox/#flex-wrap-property
131
+
132
+ @mixin flex-wrap($value: nowrap) {
133
+ // No Webkit Box fallback.
134
+ -webkit-flex-wrap: $value;
135
+ -moz-flex-wrap: $value;
136
+ @if $value == nowrap {
137
+ -ms-flex-wrap: none;
138
+ } @else {
139
+ -ms-flex-wrap: $value;
140
+ }
141
+ flex-wrap: $value;
142
+ }
143
+
144
+ //----------------------------------------------------------------------
145
+
146
+ // Flexbox Flow (shorthand)
147
+ //
148
+ // The 'flex-flow' property is a shorthand for setting the 'flex-direction'
149
+ // and 'flex-wrap' properties, which together define the flex container's
150
+ // main and cross axes.
151
+ //
152
+ // Values: <flex-direction> | <flex-wrap>
153
+ // Default: row nowrap
154
+ //
155
+ // http://w3.org/tr/css3-flexbox/#flex-flow-property
156
+
157
+ @mixin flex-flow($values: (row nowrap)) {
158
+ // No Webkit Box fallback.
159
+ -webkit-flex-flow: $values;
160
+ -moz-flex-flow: $values;
161
+ -ms-flex-flow: $values;
162
+ flex-flow: $values;
163
+ }
164
+
165
+ //----------------------------------------------------------------------
166
+
167
+ // Flexbox Order
168
+ //
169
+ // The 'order' property controls the order in which flex items appear within
170
+ // their flex container, by assigning them to ordinal groups.
171
+ //
172
+ // Default: 0
173
+ //
174
+ // http://w3.org/tr/css3-flexbox/#order-property
175
+
176
+ @mixin order($int: 0) {
177
+ -webkit-box-ordinal-group: $int + 1;
178
+ -webkit-order: $int;
179
+ -moz-order: $int;
180
+ -ms-flex-order: $int;
181
+ order: $int;
182
+ }
183
+
184
+ //----------------------------------------------------------------------
185
+
186
+ // Flexbox Grow
187
+ //
188
+ // The 'flex-grow' property sets the flex grow factor. Negative numbers
189
+ // are invalid.
190
+ //
191
+ // Default: 0
192
+ //
193
+ // http://w3.org/tr/css3-flexbox/#flex-grow-property
194
+
195
+ @mixin flex-grow($int: 0) {
196
+ -webkit-box-flex: $int;
197
+ -webkit-flex-grow: $int;
198
+ -moz-flex-grow: $int;
199
+ -ms-flex-positive: $int;
200
+ flex-grow: $int;
201
+ }
202
+
203
+ //----------------------------------------------------------------------
204
+
205
+ // Flexbox Shrink
206
+ //
207
+ // The 'flex-shrink' property sets the flex shrink factor. Negative numbers
208
+ // are invalid.
209
+ //
210
+ // Default: 1
211
+ //
212
+ // http://w3.org/tr/css3-flexbox/#flex-shrink-property
213
+
214
+ @mixin flex-shrink($int: 1) {
215
+ -webkit-flex-shrink: $int;
216
+ -moz-flex-shrink: $int;
217
+ -ms-flex-negative: $int;
218
+ flex-shrink: $int;
219
+ }
220
+
221
+ //----------------------------------------------------------------------
222
+
223
+ // Flexbox Basis
224
+ //
225
+ // The 'flex-basis' property sets the flex basis. Negative lengths are invalid.
226
+ //
227
+ // Values: Like "width"
228
+ // Default: auto
229
+ //
230
+ // http://www.w3.org/TR/css3-flexbox/#flex-basis-property
231
+
232
+ @mixin flex-basis($value: auto) {
233
+ -webkit-flex-basis: $value;
234
+ -moz-flex-basis: $value;
235
+ -ms-flex-preferred-size: $value;
236
+ flex-basis: $value;
237
+ }
238
+
239
+ //----------------------------------------------------------------------
240
+
241
+ // Flexbox "Flex" (shorthand)
242
+ //
243
+ // The 'flex' property specifies the components of a flexible length: the
244
+ // flex grow factor and flex shrink factor, and the flex basis. When an
245
+ // element is a flex item, 'flex' is consulted instead of the main size
246
+ // property to determine the main size of the element. If an element is
247
+ // not a flex item, 'flex' has no effect.
248
+ //
249
+ // Values: none | <flex-grow> <flex-shrink> || <flex-basis>
250
+ // Default: See individual properties (1 1 0).
251
+ //
252
+ // http://w3.org/tr/css3-flexbox/#flex-property
253
+
254
+ @mixin flex($fg: 1, $fs: null, $fb: null) {
255
+
256
+ // Set a variable to be used by box-flex properties
257
+ $fg-boxflex: $fg;
258
+
259
+ // Box-Flex only supports a flex-grow value so let's grab the
260
+ // first item in the list and just return that.
261
+ @if type-of($fg) == 'list' {
262
+ $fg-boxflex: nth($fg, 1);
263
+ }
264
+
265
+ -webkit-box-flex: $fg-boxflex;
266
+ -webkit-flex: $fg $fs $fb;
267
+ -moz-box-flex: $fg-boxflex;
268
+ -moz-flex: $fg $fs $fb;
269
+ -ms-flex: $fg $fs $fb;
270
+ flex: $fg $fs $fb;
271
+ }
272
+
273
+ //----------------------------------------------------------------------
274
+
275
+ // Flexbox Justify Content
276
+ //
277
+ // The 'justify-content' property aligns flex items along the main axis
278
+ // of the current line of the flex container. This is done after any flexible
279
+ // lengths and any auto margins have been resolved. Typically it helps distribute
280
+ // extra free space leftover when either all the flex items on a line are
281
+ // inflexible, or are flexible but have reached their maximum size. It also
282
+ // exerts some control over the alignment of items when they overflow the line.
283
+ //
284
+ // Note: 'space-*' values not supported in older syntaxes.
285
+ //
286
+ // Values: flex-start | flex-end | center | space-between | space-around
287
+ // Default: flex-start
288
+ //
289
+ // http://w3.org/tr/css3-flexbox/#justify-content-property
290
+
291
+ @mixin justify-content($value: flex-start) {
292
+ @if $value == flex-start {
293
+ -webkit-box-pack: start;
294
+ -ms-flex-pack: start;
295
+ } @else if $value == flex-end {
296
+ -webkit-box-pack: end;
297
+ -ms-flex-pack: end;
298
+ } @else if $value == space-between {
299
+ -webkit-box-pack: justify;
300
+ -ms-flex-pack: justify;
301
+ } @else if $value == space-around {
302
+ -ms-flex-pack: distribute;
303
+ } @else {
304
+ -webkit-box-pack: $value;
305
+ -ms-flex-pack: $value;
306
+ }
307
+ -webkit-justify-content: $value;
308
+ -moz-justify-content: $value;
309
+ justify-content: $value;
310
+ }
311
+ // Shorter version:
312
+ @mixin flex-just($args...) { @include justify-content($args...); }
313
+
314
+ //----------------------------------------------------------------------
315
+
316
+ // Flexbox Align Items
317
+ //
318
+ // Flex items can be aligned in the cross axis of the current line of the
319
+ // flex container, similar to 'justify-content' but in the perpendicular
320
+ // direction. 'align-items' sets the default alignment for all of the flex
321
+ // container's items, including anonymous flex items. 'align-self' allows
322
+ // this default alignment to be overridden for individual flex items. (For
323
+ // anonymous flex items, 'align-self' always matches the value of 'align-items'
324
+ // on their associated flex container.)
325
+ //
326
+ // Values: flex-start | flex-end | center | baseline | stretch
327
+ // Default: stretch
328
+ //
329
+ // http://w3.org/tr/css3-flexbox/#align-items-property
330
+
331
+ @mixin align-items($value: stretch) {
332
+ @if $value == flex-start {
333
+ -webkit-box-align: start;
334
+ -ms-flex-align: start;
335
+ } @else if $value == flex-end {
336
+ -webkit-box-align: end;
337
+ -ms-flex-align: end;
338
+ } @else {
339
+ -webkit-box-align: $value;
340
+ -ms-flex-align: $value;
341
+ }
342
+ -webkit-align-items: $value;
343
+ -moz-align-items: $value;
344
+ align-items: $value;
345
+ }
346
+
347
+ //----------------------------------
348
+
349
+ // Flexbox Align Self
350
+ //
351
+ // Values: auto | flex-start | flex-end | center | baseline | stretch
352
+ // Default: auto
353
+
354
+ @mixin align-self($value: auto) {
355
+ // No Webkit Box Fallback.
356
+ -webkit-align-self: $value;
357
+ -moz-align-self: $value;
358
+ @if $value == flex-start {
359
+ -ms-flex-item-align: start;
360
+ } @else if $value == flex-end {
361
+ -ms-flex-item-align: end;
362
+ } @else {
363
+ -ms-flex-item-align: $value;
364
+ }
365
+ align-self: $value;
366
+ }
367
+
368
+ //----------------------------------------------------------------------
369
+
370
+ // Flexbox Align Content
371
+ //
372
+ // The 'align-content' property aligns a flex container's lines within the
373
+ // flex container when there is extra space in the cross-axis, similar to
374
+ // how 'justify-content' aligns individual items within the main-axis. Note,
375
+ // this property has no effect when the flexbox has only a single line.
376
+ //
377
+ // Values: flex-start | flex-end | center | space-between | space-around | stretch
378
+ // Default: stretch
379
+ //
380
+ // http://w3.org/tr/css3-flexbox/#align-content-property
381
+
382
+ @mixin align-content($value: stretch) {
383
+ // No Webkit Box Fallback.
384
+ -webkit-align-content: $value;
385
+ -moz-align-content: $value;
386
+ @if $value == flex-start {
387
+ -ms-flex-line-pack: start;
388
+ } @else if $value == flex-end {
389
+ -ms-flex-line-pack: end;
390
+ } @else {
391
+ -ms-flex-line-pack: $value;
392
+ }
393
+ align-content: $value;
394
+ }
@@ -1,7 +1,13 @@
1
- /*!
2
- * disco_app/disco_app.scss
3
- * Base styles for Disco applications.
4
- */
1
+ //
2
+ // Styles for Disco applications.
3
+ // --------------------------------------------------
4
+
5
5
  @import 'bootstrap-sprockets';
6
- @import 'bootstrap-variables';
7
- @import 'bootstrap-custom';
6
+ @import 'bootstrap/variables';
7
+ @import 'bootstrap/custom';
8
+ @import 'disco/mixins/flexbox';
9
+ @import 'disco/type';
10
+ @import 'disco/sections';
11
+ @import 'disco/cards';
12
+ @import 'disco/buttons';
13
+ @import 'disco/forms';
@@ -14,7 +14,7 @@ module DiscoApp
14
14
 
15
15
  def shopify_shop
16
16
  if shop_session
17
- @shop = ::Shop.find_by!(shopify_domain: @shop_session.url)
17
+ @shop = Shop.find_by!(shopify_domain: @shop_session.url)
18
18
  else
19
19
  redirect_to_login
20
20
  end
@@ -4,7 +4,7 @@ module DiscoApp
4
4
 
5
5
  # Start the installation process for the current shop, then redirect to the installing screen.
6
6
  def install
7
- ::AppInstalledJob.perform_later(@shop.shopify_domain)
7
+ AppInstalledJob.perform_later(@shop.shopify_domain)
8
8
  redirect_to action: :installing
9
9
  end
10
10
 
@@ -8,10 +8,16 @@ module DiscoApp
8
8
  topic = request.headers['HTTP_X_SHOPIFY_TOPIC']
9
9
  domain = request.headers['HTTP_X_SHOPIFY_SHOP_DOMAIN']
10
10
 
11
+ # Ensure a domain was provided in the headers.
12
+ unless domain
13
+ head :bad_request
14
+ end
15
+
11
16
  # Try to find a matching background job task for the given topic using class name.
12
- begin
13
- job_class = "#{topic}_job".gsub('/', '_').classify.constantize
14
- rescue NameError
17
+ job_class = DiscoApp::WebhookService.find_job_class(topic)
18
+
19
+ # Return bad request if we couldn't match a job class.
20
+ unless job_class.present?
15
21
  head :bad_request
16
22
  end
17
23
 
@@ -26,15 +32,11 @@ module DiscoApp
26
32
 
27
33
  # Verify a webhook request.
28
34
  def verify_webhook
29
- data = request.body.read.to_s
30
- hmac_header = request.headers['HTTP_X_SHOPIFY_HMAC_SHA256']
31
- digest = OpenSSL::Digest::Digest.new('sha256')
32
- calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, ShopifyApp.configuration.secret, data)).strip
33
- unless calculated_hmac == hmac_header
35
+ unless DiscoApp::WebhookService.is_valid_hmac?(request.body.read.to_s, ShopifyApp.configuration.secret, request.headers['HTTP_X_SHOPIFY_HMAC_SHA256'])
34
36
  head :unauthorized
35
37
  end
36
38
  request.body.rewind
37
39
  end
38
40
 
39
41
  end
40
- end
42
+ end
@@ -13,7 +13,7 @@ module DiscoApp
13
13
  end
14
14
 
15
15
  # Perform initial update of shop information.
16
- ::ShopUpdateJob.perform_now(domain)
16
+ DiscoApp::ShopUpdateJob.perform_now(domain)
17
17
 
18
18
  end
19
19
 
@@ -1,18 +1,3 @@
1
- module DiscoApp
2
- class AppUninstalledJob < DiscoApp::ShopJob
3
-
4
- before_enqueue { @shop.awaiting_uninstall! }
5
- before_perform { @shop.uninstalling! }
6
- after_perform { @shop.uninstalled! }
7
-
8
- def perform(domain, shop_data)
9
-
10
- # Mark the shop's charge status as "cancelled" unless charges have been waived.
11
- unless @shop.charge_waived?
12
- @shop.charge_cancelled!
13
- end
14
-
15
- end
16
-
17
- end
1
+ class DiscoApp::AppUninstalledJob < DiscoApp::ShopJob
2
+ include DiscoApp::Concerns::AppUninstalledJob
18
3
  end