disco_app 0.9.9
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 +7 -0
- data/Rakefile +37 -0
- data/app/assets/images/disco_app/icon.svg +1 -0
- data/app/assets/images/disco_app/icons.svg +0 -0
- data/app/assets/javascripts/disco_app/components/custom/filterable_shop_list.js.jsx +61 -0
- data/app/assets/javascripts/disco_app/components/custom/inline-radio-options.es6.jsx +59 -0
- data/app/assets/javascripts/disco_app/components/custom/rules-editor.es6.jsx +417 -0
- data/app/assets/javascripts/disco_app/components/custom/shop_filter_query.js.jsx +13 -0
- data/app/assets/javascripts/disco_app/components/custom/shop_filter_tab.js.jsx +34 -0
- data/app/assets/javascripts/disco_app/components/custom/shop_filter_tabs.js.jsx +21 -0
- data/app/assets/javascripts/disco_app/components/custom/shop_list.js.jsx +142 -0
- data/app/assets/javascripts/disco_app/components/custom/shop_row.js.jsx +43 -0
- data/app/assets/javascripts/disco_app/components/custom/shopify_admin_link.js.jsx +29 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/cards/card-footer.es6.jsx +11 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/cards/card-header.es6.jsx +11 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/cards/card-section.es6.jsx +30 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/cards/card.es6.jsx +16 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/cards/cart-section-title.es6.jsx +9 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/forms/base_form.es6.jsx +72 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/forms/base_input.es6.jsx +20 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/forms/button.es6.jsx +13 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/forms/input-radio.es6.jsx +30 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/forms/input-select.es6.jsx +39 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/forms/input-text.es6.jsx +59 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/forms/input-textarea.es6.jsx +48 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/icons/icon-chevron.es6.jsx +33 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/icons/next-icon.es6.jsx +18 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/input_select.es6.jsx +21 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/tables/table.es6.jsx +22 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/ui-layout/ui-annotated-section.es6.jsx +29 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/ui-layout/ui-empty-state.es6.jsx +35 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/ui-layout/ui-footer-help.es6.jsx +13 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/ui-layout/ui-layout-item.es6.jsx +11 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/ui-layout/ui-layout-section.es6.jsx +19 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/ui-layout/ui-layout-sections.es6.jsx +11 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/ui-layout/ui-layout.es6.jsx +11 -0
- data/app/assets/javascripts/disco_app/components/ui-kit/ui-layout/ui-page-actions.es6.jsx +48 -0
- data/app/assets/javascripts/disco_app/components.js +2 -0
- data/app/assets/javascripts/disco_app/disco_app.js +9 -0
- data/app/assets/javascripts/disco_app/frame.js +152 -0
- data/app/assets/javascripts/disco_app/shopify-turbolinks.js +7 -0
- data/app/assets/javascripts/disco_app/ui-kit.js +1 -0
- data/app/assets/stylesheets/disco_app/admin/_header.scss +75 -0
- data/app/assets/stylesheets/disco_app/admin/_layout.scss +32 -0
- data/app/assets/stylesheets/disco_app/admin/_nav.scss +184 -0
- data/app/assets/stylesheets/disco_app/admin.scss +11 -0
- data/app/assets/stylesheets/disco_app/disco_app.scss +19 -0
- data/app/assets/stylesheets/disco_app/frame/_buttons.scss +54 -0
- data/app/assets/stylesheets/disco_app/frame/_forms.scss +26 -0
- data/app/assets/stylesheets/disco_app/frame/_layout.scss +77 -0
- data/app/assets/stylesheets/disco_app/frame/_type.scss +25 -0
- data/app/assets/stylesheets/disco_app/frame.scss +10 -0
- data/app/assets/stylesheets/disco_app/mixins/_flexbox.scss +400 -0
- data/app/assets/stylesheets/disco_app/ui-kit/_ui-empty-state.scss +121 -0
- data/app/assets/stylesheets/disco_app/ui-kit/_ui-footer-help.scss +28 -0
- data/app/assets/stylesheets/disco_app/ui-kit/_ui-icons.scss +28 -0
- data/app/assets/stylesheets/disco_app/ui-kit/_ui-kit.scss +5113 -0
- data/app/assets/stylesheets/disco_app/ui-kit/_ui-layout.scss +15 -0
- data/app/assets/stylesheets/disco_app/ui-kit/_ui-page-actions.scss +21 -0
- data/app/assets/stylesheets/disco_app/ui-kit/_ui-tabs.scss +75 -0
- data/app/assets/stylesheets/disco_app/ui-kit/_ui-type.scss +13 -0
- data/app/controllers/disco_app/admin/app_settings_controller.rb +3 -0
- data/app/controllers/disco_app/admin/application_controller.rb +3 -0
- data/app/controllers/disco_app/admin/concerns/app_settings_controller.rb +24 -0
- data/app/controllers/disco_app/admin/concerns/authenticated_controller.rb +20 -0
- data/app/controllers/disco_app/admin/concerns/plans_controller.rb +54 -0
- data/app/controllers/disco_app/admin/concerns/shops_controller.rb +7 -0
- data/app/controllers/disco_app/admin/concerns/subscriptions_controller.rb +29 -0
- data/app/controllers/disco_app/admin/plans_controller.rb +3 -0
- data/app/controllers/disco_app/admin/resources/shops_controller.rb +3 -0
- data/app/controllers/disco_app/admin/shops_controller.rb +3 -0
- data/app/controllers/disco_app/admin/subscriptions_controller.rb +3 -0
- data/app/controllers/disco_app/charges_controller.rb +47 -0
- data/app/controllers/disco_app/concerns/app_proxy_controller.rb +40 -0
- data/app/controllers/disco_app/concerns/authenticated_controller.rb +56 -0
- data/app/controllers/disco_app/concerns/carrier_request_controller.rb +21 -0
- data/app/controllers/disco_app/frame_controller.rb +9 -0
- data/app/controllers/disco_app/install_controller.rb +27 -0
- data/app/controllers/disco_app/subscriptions_controller.rb +32 -0
- data/app/controllers/disco_app/webhooks_controller.rb +46 -0
- data/app/controllers/sessions_controller.rb +28 -0
- data/app/helpers/disco_app/application_helper.rb +50 -0
- data/app/jobs/disco_app/app_installed_job.rb +3 -0
- data/app/jobs/disco_app/app_uninstalled_job.rb +3 -0
- data/app/jobs/disco_app/concerns/app_installed_job.rb +39 -0
- data/app/jobs/disco_app/concerns/app_uninstalled_job.rb +20 -0
- data/app/jobs/disco_app/concerns/render_asset_group_job.rb +8 -0
- data/app/jobs/disco_app/concerns/shop_update_job.rb +13 -0
- data/app/jobs/disco_app/concerns/subscription_changed_job.rb +7 -0
- data/app/jobs/disco_app/concerns/synchronise_carrier_service_job.rb +52 -0
- data/app/jobs/disco_app/concerns/synchronise_resources_job.rb +12 -0
- data/app/jobs/disco_app/concerns/synchronise_webhooks_job.rb +61 -0
- data/app/jobs/disco_app/render_asset_group_job.rb +3 -0
- data/app/jobs/disco_app/shop_job.rb +27 -0
- data/app/jobs/disco_app/shop_update_job.rb +3 -0
- data/app/jobs/disco_app/subscription_changed_job.rb +3 -0
- data/app/jobs/disco_app/synchronise_carrier_service_job.rb +3 -0
- data/app/jobs/disco_app/synchronise_resources_job.rb +3 -0
- data/app/jobs/disco_app/synchronise_webhooks_job.rb +3 -0
- data/app/models/disco_app/app_settings.rb +3 -0
- data/app/models/disco_app/application_charge.rb +18 -0
- data/app/models/disco_app/concerns/app_settings.rb +7 -0
- data/app/models/disco_app/concerns/plan.rb +26 -0
- data/app/models/disco_app/concerns/plan_code.rb +15 -0
- data/app/models/disco_app/concerns/renders_assets.rb +166 -0
- data/app/models/disco_app/concerns/shop.rb +68 -0
- data/app/models/disco_app/concerns/subscription.rb +60 -0
- data/app/models/disco_app/concerns/synchronises.rb +50 -0
- data/app/models/disco_app/concerns/taggable.rb +16 -0
- data/app/models/disco_app/plan.rb +3 -0
- data/app/models/disco_app/plan_code.rb +3 -0
- data/app/models/disco_app/recurring_application_charge.rb +18 -0
- data/app/models/disco_app/session_storage.rb +18 -0
- data/app/models/disco_app/shop.rb +3 -0
- data/app/models/disco_app/subscription.rb +3 -0
- data/app/resources/disco_app/admin/resources/concerns/shop_resource.rb +100 -0
- data/app/resources/disco_app/admin/resources/shop_resource.rb +4 -0
- data/app/services/disco_app/carrier_request_service.rb +15 -0
- data/app/services/disco_app/charges_service.rb +81 -0
- data/app/services/disco_app/proxy_service.rb +17 -0
- data/app/services/disco_app/subscription_service.rb +46 -0
- data/app/services/disco_app/webhook_service.rb +30 -0
- data/app/views/disco_app/admin/app_settings/edit.html.erb +5 -0
- data/app/views/disco_app/admin/plans/_form.html.erb +72 -0
- data/app/views/disco_app/admin/plans/_plan_code_fields.html.erb +15 -0
- data/app/views/disco_app/admin/plans/edit.html.erb +7 -0
- data/app/views/disco_app/admin/plans/index.html.erb +43 -0
- data/app/views/disco_app/admin/plans/new.html.erb +7 -0
- data/app/views/disco_app/admin/shops/index.html.erb +13 -0
- data/app/views/disco_app/admin/subscriptions/edit.html.erb +33 -0
- data/app/views/disco_app/charges/activate.html.erb +1 -0
- data/app/views/disco_app/charges/create.html.erb +1 -0
- data/app/views/disco_app/charges/new.html.erb +23 -0
- data/app/views/disco_app/frame/frame.html.erb +36 -0
- data/app/views/disco_app/install/installing.html.erb +7 -0
- data/app/views/disco_app/install/uninstalling.html.erb +1 -0
- data/app/views/disco_app/proxy_errors/404.html.erb +1 -0
- data/app/views/disco_app/shared/_card.html.erb +14 -0
- data/app/views/disco_app/shared/_icons.html.erb +3 -0
- data/app/views/disco_app/shared/_section.html.erb +17 -0
- data/app/views/disco_app/subscriptions/new.html.erb +25 -0
- data/app/views/layouts/admin/_nav_items.erb +20 -0
- data/app/views/layouts/admin.html.erb +67 -0
- data/app/views/layouts/application.html.erb +18 -0
- data/app/views/layouts/embedded_app.html.erb +44 -0
- data/app/views/layouts/embedded_app_modal.html.erb +28 -0
- data/app/views/sessions/new.html.erb +26 -0
- data/config/routes.rb +48 -0
- data/db/migrate/20150525000000_create_shops_if_not_existent.rb +15 -0
- data/db/migrate/20150525162112_add_status_to_shops.rb +5 -0
- data/db/migrate/20150525171422_add_meta_to_shops.rb +11 -0
- data/db/migrate/20150629210346_add_charge_status_to_shop.rb +5 -0
- data/db/migrate/20150814214025_add_more_meta_to_shops.rb +15 -0
- data/db/migrate/20151017231302_create_disco_app_plans.rb +13 -0
- data/db/migrate/20151017232027_create_disco_app_subscriptions.rb +15 -0
- data/db/migrate/20151017234409_move_shop_to_disco_app_engine.rb +5 -0
- data/db/migrate/20160112233706_create_disco_app_sessions.rb +12 -0
- data/db/migrate/20160113194418_add_shop_id_to_disco_app_sessions.rb +6 -0
- data/db/migrate/20160223111044_create_disco_app_settings.rb +8 -0
- data/db/migrate/20160301223215_update_plans.rb +22 -0
- data/db/migrate/20160301224558_update_subscriptions.rb +13 -0
- data/db/migrate/20160302104816_create_disco_app_recurring_application_charges.rb +14 -0
- data/db/migrate/20160302105259_create_disco_app_application_charges.rb +14 -0
- data/db/migrate/20160302134728_drop_charge_status_from_shops.rb +5 -0
- data/db/migrate/20160302142941_add_shopify_attributes_to_charges.rb +8 -0
- data/db/migrate/20160331093148_create_disco_app_plan_codes.rb +14 -0
- data/db/migrate/20160401044420_add_status_to_plan_codes.rb +5 -0
- data/db/migrate/20160401045551_add_amount_and_plan_code_to_disco_app_subscriptions.rb +7 -0
- data/db/migrate/20160425205211_add_source_to_disco_app_subscriptions.rb +5 -0
- data/db/migrate/20160426033520_add_trial_period_days_to_disco_app_subscriptions.rb +5 -0
- data/db/migrate/20160513140727_add_name_to_disco_app_shops.rb +5 -0
- data/db/migrate/20160521135510_move_shop_to_synchronises.rb +61 -0
- data/lib/disco_app/configuration.rb +39 -0
- data/lib/disco_app/constants.rb +4 -0
- data/lib/disco_app/engine.rb +26 -0
- data/lib/disco_app/session.rb +14 -0
- data/lib/disco_app/support/file_fixtures.rb +23 -0
- data/lib/disco_app/test_help.rb +11 -0
- data/lib/disco_app/version.rb +3 -0
- data/lib/disco_app.rb +7 -0
- data/lib/generators/disco_app/USAGE +5 -0
- data/lib/generators/disco_app/disco_app_generator.rb +235 -0
- data/lib/generators/disco_app/templates/assets/javascripts/application.js +17 -0
- data/lib/generators/disco_app/templates/assets/javascripts/components.js +3 -0
- data/lib/generators/disco_app/templates/assets/stylesheets/application.scss +5 -0
- data/lib/generators/disco_app/templates/config/database.yml.tt +20 -0
- data/lib/generators/disco_app/templates/config/newrelic.yml +26 -0
- data/lib/generators/disco_app/templates/config/puma.rb +15 -0
- data/lib/generators/disco_app/templates/controllers/home_controller.rb +7 -0
- data/lib/generators/disco_app/templates/initializers/disco_app.rb +19 -0
- data/lib/generators/disco_app/templates/initializers/rollbar.rb +12 -0
- data/lib/generators/disco_app/templates/initializers/session_store.rb +2 -0
- data/lib/generators/disco_app/templates/initializers/shopify_app.rb +7 -0
- data/lib/generators/disco_app/templates/initializers/shopify_session_repository.rb +7 -0
- data/lib/generators/disco_app/templates/root/CHECKS +4 -0
- data/lib/generators/disco_app/templates/root/Procfile +2 -0
- data/lib/generators/disco_app/templates/views/home/index.html.erb +2 -0
- data/lib/tasks/carrier_service.rake +10 -0
- data/lib/tasks/database.rake +8 -0
- data/lib/tasks/sessions.rake +9 -0
- data/lib/tasks/shops.rake +10 -0
- data/lib/tasks/start.rake +3 -0
- data/lib/tasks/webhooks.rake +10 -0
- data/test/controllers/disco_app/admin/shops_controller_test.rb +54 -0
- data/test/controllers/disco_app/charges_controller_test.rb +99 -0
- data/test/controllers/disco_app/install_controller_test.rb +50 -0
- data/test/controllers/disco_app/subscriptions_controller_test.rb +68 -0
- data/test/controllers/disco_app/webhooks_controller_test.rb +58 -0
- data/test/controllers/home_controller_test.rb +92 -0
- data/test/controllers/proxy_controller_test.rb +42 -0
- data/test/disco_app_test.rb +7 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +17 -0
- data/test/dummy/app/assets/stylesheets/application.scss +5 -0
- data/test/dummy/app/controllers/application_controller.rb +6 -0
- data/test/dummy/app/controllers/disco_app/admin/shops_controller.rb +8 -0
- data/test/dummy/app/controllers/home_controller.rb +7 -0
- data/test/dummy/app/controllers/proxy_controller.rb +8 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/disco_app/app_installed_job.rb +16 -0
- data/test/dummy/app/jobs/disco_app/app_uninstalled_job.rb +11 -0
- data/test/dummy/app/jobs/products_create_job.rb +7 -0
- data/test/dummy/app/jobs/products_delete_job.rb +7 -0
- data/test/dummy/app/jobs/products_update_job.rb +7 -0
- data/test/dummy/app/models/disco_app/shop.rb +15 -0
- data/test/dummy/app/models/js_configuration.rb +8 -0
- data/test/dummy/app/models/product.rb +6 -0
- data/test/dummy/app/models/widget_configuration.rb +10 -0
- data/test/dummy/app/views/assets/script_tag.js.erb +1 -0
- data/test/dummy/app/views/assets/test.js.erb +1 -0
- data/test/dummy/app/views/assets/widget.js.erb +2 -0
- data/test/dummy/app/views/assets/widget.scss.erb +3 -0
- data/test/dummy/app/views/home/index.html.erb +2 -0
- data/test/dummy/app/views/snippets/widget.liquid.erb +1 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +38 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.codeship.yml +23 -0
- data/test/dummy/config/database.gitlab-ci.yml +24 -0
- data/test/dummy/config/database.yml +20 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +85 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/disco_app.rb +19 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/omniauth.rb +9 -0
- data/test/dummy/config/initializers/session_store.rb +2 -0
- data/test/dummy/config/initializers/shopify_app.rb +7 -0
- data/test/dummy/config/initializers/shopify_session_repository.rb +7 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +10 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/migrate/20160307182229_create_products.rb +11 -0
- data/test/dummy/db/migrate/20160530160739_create_asset_models.rb +19 -0
- data/test/dummy/db/schema.rb +141 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/fixtures/api/widget_store/assets/create_script_tag_js_request.json +6 -0
- data/test/fixtures/api/widget_store/assets/create_script_tag_js_response.json +12 -0
- data/test/fixtures/api/widget_store/assets/create_script_tag_request.json +6 -0
- data/test/fixtures/api/widget_store/assets/create_script_tag_response.json +10 -0
- data/test/fixtures/api/widget_store/assets/create_test_js_request.json +6 -0
- data/test/fixtures/api/widget_store/assets/create_test_js_response.json +12 -0
- data/test/fixtures/api/widget_store/assets/create_widget_js_request.json +6 -0
- data/test/fixtures/api/widget_store/assets/create_widget_js_response.json +12 -0
- data/test/fixtures/api/widget_store/assets/create_widget_liquid_request.json +6 -0
- data/test/fixtures/api/widget_store/assets/create_widget_liquid_response.json +12 -0
- data/test/fixtures/api/widget_store/assets/create_widget_scss_request.json +6 -0
- data/test/fixtures/api/widget_store/assets/create_widget_scss_response.json +12 -0
- data/test/fixtures/api/widget_store/assets/get_script_tags_empty_request.json +1 -0
- data/test/fixtures/api/widget_store/assets/get_script_tags_empty_response.json +1 -0
- data/test/fixtures/api/widget_store/assets/get_script_tags_preexisting_request.json +1 -0
- data/test/fixtures/api/widget_store/assets/get_script_tags_preexisting_response.json +12 -0
- data/test/fixtures/api/widget_store/assets/update_script_tag_request.json +10 -0
- data/test/fixtures/api/widget_store/assets/update_script_tag_response.json +10 -0
- data/test/fixtures/api/widget_store/charges/activate_application_charge_request.json +16 -0
- data/test/fixtures/api/widget_store/charges/activate_application_charge_response.json +1 -0
- data/test/fixtures/api/widget_store/charges/activate_recurring_application_charge_request.json +20 -0
- data/test/fixtures/api/widget_store/charges/activate_recurring_application_charge_response.json +1 -0
- data/test/fixtures/api/widget_store/charges/create_application_charge_request.json +9 -0
- data/test/fixtures/api/widget_store/charges/create_application_charge_response.json +16 -0
- data/test/fixtures/api/widget_store/charges/create_recurring_application_charge_request.json +9 -0
- data/test/fixtures/api/widget_store/charges/create_recurring_application_charge_response.json +20 -0
- data/test/fixtures/api/widget_store/charges/create_second_recurring_application_charge_request.json +9 -0
- data/test/fixtures/api/widget_store/charges/create_second_recurring_application_charge_response.json +20 -0
- data/test/fixtures/api/widget_store/charges/get_accepted_application_charge_response.json +16 -0
- data/test/fixtures/api/widget_store/charges/get_accepted_recurring_application_charge_response.json +20 -0
- data/test/fixtures/api/widget_store/charges/get_declined_application_charge_response.json +16 -0
- data/test/fixtures/api/widget_store/charges/get_declined_recurring_application_charge_response.json +20 -0
- data/test/fixtures/api/widget_store/charges/get_pending_application_charge_response.json +16 -0
- data/test/fixtures/api/widget_store/charges/get_pending_recurring_application_charge_response.json +20 -0
- data/test/fixtures/api/widget_store/shop.json +46 -0
- data/test/fixtures/api/widget_store/webhooks.json +1 -0
- data/test/fixtures/assets/test.js +1 -0
- data/test/fixtures/assets/test.min.js +1 -0
- data/test/fixtures/disco_app/application_charges.yml +11 -0
- data/test/fixtures/disco_app/plan_codes.yml +13 -0
- data/test/fixtures/disco_app/plans.yml +37 -0
- data/test/fixtures/disco_app/recurring_application_charges.yml +11 -0
- data/test/fixtures/disco_app/shops.yml +10 -0
- data/test/fixtures/disco_app/subscriptions.yml +22 -0
- data/test/fixtures/js_configurations.yml +3 -0
- data/test/fixtures/products.yml +4 -0
- data/test/fixtures/webhooks/app_uninstalled.json +46 -0
- data/test/fixtures/webhooks/product_created.json +167 -0
- data/test/fixtures/webhooks/product_deleted.json +3 -0
- data/test/fixtures/webhooks/product_updated.json +167 -0
- data/test/fixtures/widget_configurations.yml +4 -0
- data/test/integration/synchronises_test.rb +55 -0
- data/test/jobs/disco_app/app_installed_job_test.rb +55 -0
- data/test/jobs/disco_app/app_uninstalled_job_test.rb +30 -0
- data/test/models/disco_app/plan_test.rb +5 -0
- data/test/models/disco_app/renders_assets_test.rb +109 -0
- data/test/models/disco_app/session_test.rb +31 -0
- data/test/models/disco_app/shop_test.rb +27 -0
- data/test/models/disco_app/subscription_test.rb +19 -0
- data/test/services/disco_app/charges_service_test.rb +112 -0
- data/test/services/disco_app/subscription_service_test.rb +60 -0
- data/test/support/test_file_fixtures.rb +29 -0
- data/test/support/test_shopify_api.rb +16 -0
- data/test/test_helper.rb +55 -0
- metadata +830 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ui-page-actions.scss
|
|
3
|
+
// Styles for UI page actions not provided by the
|
|
4
|
+
// Channel SDK UI Kit.
|
|
5
|
+
// --------------------------------------------------
|
|
6
|
+
|
|
7
|
+
.ui-page-actions {
|
|
8
|
+
@include flexbox();
|
|
9
|
+
margin: 0 auto 20px auto;
|
|
10
|
+
max-width: 1036px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.ui-page-actions__primary {
|
|
14
|
+
@include flex(1 1 auto);
|
|
15
|
+
padding-right: 20px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.ui-page-actions__secondary {
|
|
19
|
+
@include flex(1 1 auto);
|
|
20
|
+
padding: 0 20px;
|
|
21
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ui-tabs.scss
|
|
3
|
+
// Styles for tabs not provided by the Channel SDK UI
|
|
4
|
+
// Kit.
|
|
5
|
+
// --------------------------------------------------
|
|
6
|
+
|
|
7
|
+
.next-tab__list {
|
|
8
|
+
padding: 0;
|
|
9
|
+
margin: 0;
|
|
10
|
+
list-style: none;
|
|
11
|
+
background-color: #f5f6f7;
|
|
12
|
+
overflow: visible;
|
|
13
|
+
border-radius: 3px 3px 0 0;
|
|
14
|
+
|
|
15
|
+
flex-wrap: nowrap;
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: stretch;
|
|
18
|
+
|
|
19
|
+
> li {
|
|
20
|
+
position: relative;
|
|
21
|
+
flex-grow: 0;
|
|
22
|
+
flex-shrink: 0;
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: stretch;
|
|
25
|
+
|
|
26
|
+
&:first-child .next-tab {
|
|
27
|
+
border-top-left-radius: 3px;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.next-tab {
|
|
33
|
+
color: rgba(0,0,0,0.56);
|
|
34
|
+
padding: 15px 20px;
|
|
35
|
+
text-decoration: none;
|
|
36
|
+
border-right: 1px solid #ebeef0;
|
|
37
|
+
border-bottom: 1px solid #ebeef0;
|
|
38
|
+
text-align: center;
|
|
39
|
+
line-height: 1;
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
position: relative;
|
|
42
|
+
-webkit-box-flex: 1;
|
|
43
|
+
-webkit-flex-grow: 1;
|
|
44
|
+
-ms-flex-positive: 1;
|
|
45
|
+
flex-grow: 1;
|
|
46
|
+
display: -webkit-box;
|
|
47
|
+
display: -webkit-flex;
|
|
48
|
+
display: -ms-flexbox;
|
|
49
|
+
display: flex;
|
|
50
|
+
-webkit-box-align: center;
|
|
51
|
+
-webkit-align-items: center;
|
|
52
|
+
-ms-flex-align: center;
|
|
53
|
+
align-items: center;
|
|
54
|
+
-webkit-box-pack: center;
|
|
55
|
+
-webkit-justify-content: center;
|
|
56
|
+
-ms-flex-pack: center;
|
|
57
|
+
justify-content: center;
|
|
58
|
+
|
|
59
|
+
&:focus,
|
|
60
|
+
&:hover {
|
|
61
|
+
outline: none;
|
|
62
|
+
background-color: #fafbfc;
|
|
63
|
+
color: #0078bd;
|
|
64
|
+
text-decoration: none;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&.next-tab--is-active {
|
|
68
|
+
font-weight: normal;
|
|
69
|
+
color: rgba(0,0,0,0.9);
|
|
70
|
+
background-color: #ffffff;
|
|
71
|
+
border-bottom-color: #ffffff;
|
|
72
|
+
cursor: default;
|
|
73
|
+
text-decoration: none;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module DiscoApp::Admin::Concerns::AppSettingsController
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
def edit
|
|
5
|
+
@app_settings = DiscoApp::AppSettings.instance
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def update
|
|
9
|
+
@app_settings = DiscoApp::AppSettings.instance
|
|
10
|
+
if @app_settings.update_attributes(app_settings_params)
|
|
11
|
+
flash[:success] = 'Settings updated.'
|
|
12
|
+
redirect_to edit_admin_app_settings_path
|
|
13
|
+
else
|
|
14
|
+
render 'edit'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def app_settings_params
|
|
21
|
+
params.require(:app_settings)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module DiscoApp::Admin::Concerns::AuthenticatedController
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
|
|
6
|
+
protect_from_forgery with: :exception
|
|
7
|
+
before_action :authenticate_administrator
|
|
8
|
+
layout 'admin'
|
|
9
|
+
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def authenticate_administrator
|
|
15
|
+
authenticate_or_request_with_http_basic do |username, password|
|
|
16
|
+
(not username.blank?) && (not password.blank?) && username == ENV['ADMIN_APP_USERNAME'] && password == ENV['ADMIN_APP_PASSWORD']
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module DiscoApp::Admin::Concerns::PlansController
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
before_action :find_plan, only: [:edit, :update, :destroy]
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def index
|
|
9
|
+
@plans = DiscoApp::Plan.all
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def new
|
|
13
|
+
@plan = DiscoApp::Plan.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def create
|
|
17
|
+
@plan = DiscoApp::Plan.new(plan_params)
|
|
18
|
+
if @plan.save
|
|
19
|
+
redirect_to admin_plans_path
|
|
20
|
+
else
|
|
21
|
+
render 'new'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def edit
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def update
|
|
29
|
+
if @plan.update_attributes(plan_params)
|
|
30
|
+
redirect_to edit_admin_plan_path(@plan)
|
|
31
|
+
else
|
|
32
|
+
render 'edit'
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def destroy
|
|
37
|
+
@plan.destroy
|
|
38
|
+
redirect_to admin_plans_path
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def find_plan
|
|
44
|
+
@plan = DiscoApp::Plan.find(params[:id])
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def plan_params
|
|
48
|
+
params.require(:plan).permit(
|
|
49
|
+
:name, :status, :plan_type, :trial_period_days, :amount,
|
|
50
|
+
:plan_codes_attributes => [:id, :_destroy, :code, :trial_period_days, :amount]
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module DiscoApp::Admin::Concerns::SubscriptionsController
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
before_action :find_subscription
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def edit
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def update
|
|
12
|
+
if @subscription.update_attributes(subscription_params)
|
|
13
|
+
redirect_to edit_admin_shop_subscription_path(@subscription.shop, @subscription)
|
|
14
|
+
else
|
|
15
|
+
render 'edit'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def find_subscription
|
|
22
|
+
@subscription = DiscoApp::Subscription.find_by_id(params[:id])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def subscription_params
|
|
26
|
+
params.require(:subscription).permit(:amount, :trial_period_days)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
class DiscoApp::ChargesController < ApplicationController
|
|
2
|
+
include DiscoApp::Concerns::AuthenticatedController
|
|
3
|
+
|
|
4
|
+
skip_before_action :check_active_charge
|
|
5
|
+
before_action :find_subscription
|
|
6
|
+
|
|
7
|
+
# Display a "pre-charge" page, giving the opportunity to explain why a charge
|
|
8
|
+
# needs to be made.
|
|
9
|
+
def new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Attempt to create a new charge for the logged in shop and selected
|
|
13
|
+
# subscription. If successful, redirect to the (external) charge confirmation
|
|
14
|
+
# URL. If it fails, redirect back to the new charge page.
|
|
15
|
+
def create
|
|
16
|
+
if(charge = DiscoApp::ChargesService.create(@shop, @subscription)).nil?
|
|
17
|
+
redirect_to action: :new
|
|
18
|
+
else
|
|
19
|
+
redirect_to charge.confirmation_url
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Attempt to activate a charge after a user has accepted or declined it.
|
|
24
|
+
# Redirect to the main application's root URL immediately afterwards - if the
|
|
25
|
+
# charge wasn't accepted, the flow will start again.
|
|
26
|
+
def activate
|
|
27
|
+
# First attempt to find a matching charge.
|
|
28
|
+
if(charge = @subscription.charges.find_by(id: params[:id], shopify_id: params[:charge_id])).nil?
|
|
29
|
+
redirect_to action: :new and return
|
|
30
|
+
end
|
|
31
|
+
if DiscoApp::ChargesService.activate(@shop, charge)
|
|
32
|
+
redirect_to main_app.root_url
|
|
33
|
+
else
|
|
34
|
+
redirect_to action: :new
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def find_subscription
|
|
41
|
+
@subscription = @shop.subscriptions.find_by_id!(params[:subscription_id])
|
|
42
|
+
unless @subscription.requires_active_charge? and not @subscription.active_charge?
|
|
43
|
+
redirect_to main_app.root_url
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module DiscoApp::Concerns::AppProxyController
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
before_action :verify_proxy_signature
|
|
6
|
+
before_action :shopify_shop
|
|
7
|
+
after_action :add_liquid_header
|
|
8
|
+
|
|
9
|
+
rescue_from ActiveRecord::RecordNotFound do |exception|
|
|
10
|
+
render_error 404
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def verify_proxy_signature
|
|
17
|
+
unless proxy_signature_is_valid?
|
|
18
|
+
head :unauthorized
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def proxy_signature_is_valid?
|
|
23
|
+
return true if Rails.env.development? and DiscoApp.configuration.skip_proxy_verification?
|
|
24
|
+
DiscoApp::ProxyService.proxy_signature_is_valid?(request.query_string, ShopifyApp.configuration.secret)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def shopify_shop
|
|
28
|
+
@shop = DiscoApp::Shop.find_by_shopify_domain!(params[:shop])
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def add_liquid_header
|
|
32
|
+
response.headers['Content-Type'] = 'application/liquid'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def render_error(status)
|
|
36
|
+
add_liquid_header
|
|
37
|
+
render "disco_app/proxy_errors/#{status}", status: status
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module DiscoApp::Concerns::AuthenticatedController
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
before_action :login_again_if_different_shop
|
|
6
|
+
before_action :shopify_shop
|
|
7
|
+
before_action :check_installed
|
|
8
|
+
before_action :check_current_subscription
|
|
9
|
+
before_action :check_active_charge
|
|
10
|
+
around_filter :shopify_session
|
|
11
|
+
layout 'embedded_app'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def shopify_shop
|
|
17
|
+
if shop_session
|
|
18
|
+
@shop = DiscoApp::Shop.find_by!(shopify_domain: @shop_session.url)
|
|
19
|
+
else
|
|
20
|
+
redirect_to_login
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def check_installed
|
|
25
|
+
if @shop.awaiting_install? or @shop.installing?
|
|
26
|
+
redirect_if_not_current_path disco_app.installing_path
|
|
27
|
+
return
|
|
28
|
+
end
|
|
29
|
+
if @shop.awaiting_uninstall? or @shop.uninstalling?
|
|
30
|
+
redirect_if_not_current_path disco_app.uninstalling_path
|
|
31
|
+
return
|
|
32
|
+
end
|
|
33
|
+
unless @shop.installed?
|
|
34
|
+
redirect_if_not_current_path disco_app.install_path
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def check_current_subscription
|
|
39
|
+
unless @shop.current_subscription?
|
|
40
|
+
redirect_if_not_current_path disco_app.new_subscription_path
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def check_active_charge
|
|
45
|
+
if @shop.current_subscription? and @shop.current_subscription.requires_active_charge? and not @shop.development? and not @shop.current_subscription.active_charge?
|
|
46
|
+
redirect_if_not_current_path disco_app.new_subscription_charge_path(@shop.current_subscription)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def redirect_if_not_current_path(target)
|
|
51
|
+
if request.path != target
|
|
52
|
+
redirect_to target
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module DiscoApp::Concerns::CarrierRequestController
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
before_action :verify_carrier_request
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def verify_carrier_request
|
|
11
|
+
unless carrier_request_signature_is_valid?
|
|
12
|
+
head :unauthorized
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def carrier_request_signature_is_valid?
|
|
17
|
+
return true if Rails.env.development? and DiscoApp.configuration.skip_carrier_request_verification?
|
|
18
|
+
DiscoApp::CarrierRequestService.is_valid_hmac?(request.body.read.to_s, ShopifyApp.configuration.secret, request.headers['HTTP_X_SHOPIFY_HMAC_SHA256'])
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class DiscoApp::InstallController < ApplicationController
|
|
2
|
+
include DiscoApp::Concerns::AuthenticatedController
|
|
3
|
+
|
|
4
|
+
skip_before_action :check_current_subscription
|
|
5
|
+
skip_before_action :check_active_charge
|
|
6
|
+
|
|
7
|
+
# Start the installation process for the current shop, then redirect to the installing screen.
|
|
8
|
+
def install
|
|
9
|
+
DiscoApp::AppInstalledJob.perform_later(@shop, cookies[DiscoApp::CODE_COOKIE_KEY], cookies[DiscoApp::SOURCE_COOKIE_KEY])
|
|
10
|
+
redirect_to action: :installing
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Display an "installing" page.
|
|
14
|
+
def installing
|
|
15
|
+
if @shop.installed?
|
|
16
|
+
redirect_to main_app.root_path
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Display an "uninstalling" page. Should be almost never used.
|
|
21
|
+
def uninstalling
|
|
22
|
+
if @shop.uninstalled?
|
|
23
|
+
redirect_to main_app.root_path
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class DiscoApp::SubscriptionsController < ApplicationController
|
|
2
|
+
include DiscoApp::Concerns::AuthenticatedController
|
|
3
|
+
|
|
4
|
+
skip_before_action :check_current_subscription
|
|
5
|
+
|
|
6
|
+
def new
|
|
7
|
+
@subscription = DiscoApp::Subscription.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def create
|
|
11
|
+
# Get the selected plan. If it's not available or couldn't be found,
|
|
12
|
+
# redirect back to the plan selection page.
|
|
13
|
+
if(plan = DiscoApp::Plan.available.find_by_id(subscription_params[:plan])).nil?
|
|
14
|
+
redirect_to action: :new and return
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Subscribe the current shop to the selected plan. Pass along any cookied
|
|
18
|
+
# plan code and source code.
|
|
19
|
+
if(subscription = DiscoApp::SubscriptionService.subscribe(@shop, plan, cookies[DiscoApp::CODE_COOKIE_KEY], cookies[DiscoApp::SOURCE_COOKIE_KEY])).nil?
|
|
20
|
+
redirect_to action: :new
|
|
21
|
+
else
|
|
22
|
+
redirect_to main_app.root_path
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def subscription_params
|
|
29
|
+
params.require(:subscription).permit(:plan, :plan_code)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module DiscoApp
|
|
2
|
+
class WebhooksController < ActionController::Base
|
|
3
|
+
|
|
4
|
+
before_action :verify_webhook
|
|
5
|
+
|
|
6
|
+
def process_webhook
|
|
7
|
+
# Get the topic and domain for this webhook.
|
|
8
|
+
topic = request.headers['HTTP_X_SHOPIFY_TOPIC']
|
|
9
|
+
domain = request.headers['HTTP_X_SHOPIFY_SHOP_DOMAIN']
|
|
10
|
+
|
|
11
|
+
# Ensure a domain was provided in the headers.
|
|
12
|
+
unless domain
|
|
13
|
+
head :bad_request
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Try to find a matching background job task for the given topic using class name.
|
|
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?
|
|
21
|
+
head :bad_request
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Decode the body data and enqueue the appropriate job.
|
|
25
|
+
data = ActiveSupport::JSON::decode(request.body.read).with_indifferent_access
|
|
26
|
+
job_class.perform_later(domain, data)
|
|
27
|
+
|
|
28
|
+
render nothing: true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def verify_webhook
|
|
34
|
+
unless webhook_is_valid?
|
|
35
|
+
head :unauthorized
|
|
36
|
+
end
|
|
37
|
+
request.body.rewind
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def webhook_is_valid?
|
|
41
|
+
return true if Rails.env.development? and DiscoApp.configuration.skip_webhook_verification?
|
|
42
|
+
DiscoApp::WebhookService.is_valid_hmac?(request.body.read.to_s, ShopifyApp.configuration.secret, request.headers['HTTP_X_SHOPIFY_HMAC_SHA256'])
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class SessionsController < ApplicationController
|
|
2
|
+
include ShopifyApp::SessionsController
|
|
3
|
+
|
|
4
|
+
def referral
|
|
5
|
+
cookies[DiscoApp::SOURCE_COOKIE_KEY] = params[:source] if params[:source].present?
|
|
6
|
+
cookies[DiscoApp::CODE_COOKIE_KEY] = params[:code] if params[:code].present?
|
|
7
|
+
redirect_to root_path
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
protected
|
|
11
|
+
|
|
12
|
+
# Override the authenticate method to allow skipping OAuth in development
|
|
13
|
+
# mode. Skipping OAuth still requires a shop with Shopify domain specified
|
|
14
|
+
# by the `shop` parameter to be present in the local database.
|
|
15
|
+
def authenticate
|
|
16
|
+
if Rails.env.development? and DiscoApp.configuration.skip_oauth?
|
|
17
|
+
shop = DiscoApp::Shop.find_by_shopify_domain!(sanitized_shop_name)
|
|
18
|
+
|
|
19
|
+
sess = ShopifyAPI::Session.new(shop.shopify_domain, shop.shopify_token)
|
|
20
|
+
session[:shopify] = ShopifyApp::SessionRepository.store(sess)
|
|
21
|
+
session[:shopify_domain] = sanitized_shop_name
|
|
22
|
+
|
|
23
|
+
redirect_to disco_app.frame_path and return
|
|
24
|
+
end
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module DiscoApp::ApplicationHelper
|
|
2
|
+
|
|
3
|
+
# Generates a link pointing to an object (such as an order or customer) inside
|
|
4
|
+
# the given shop's Shopify admin. This helper makes it easy to create links
|
|
5
|
+
# to objects within the admin that support both right-clicking and opening in
|
|
6
|
+
# a new tab as well as capturing a left click and redirecting to the relevant
|
|
7
|
+
# object using `ShopifyApp.redirect()`.
|
|
8
|
+
def link_to_shopify_admin(shop, name, admin_path, options = {})
|
|
9
|
+
options[:onclick] = "ShopifyApp.redirect('#{admin_path}'); return false;"
|
|
10
|
+
options[:'data-no-turbolink'] = true
|
|
11
|
+
link_to(name, "https://#{shop.shopify_domain}/admin/#{admin_path}", options)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Generate a link that will open its href in an embedded Shopify modal.
|
|
15
|
+
def link_to_modal(name, path, options = {})
|
|
16
|
+
modal_options = {
|
|
17
|
+
src: path,
|
|
18
|
+
title: options.delete(:modal_title),
|
|
19
|
+
width: options.delete(:modal_width),
|
|
20
|
+
height: options.delete(:modal_height),
|
|
21
|
+
buttons: options.delete(:modal_buttons),
|
|
22
|
+
}
|
|
23
|
+
options[:onclick] = "ShopifyApp.Modal.open(#{modal_options.to_json}); return false;"
|
|
24
|
+
options[:onclick].gsub!(/"function(.*?)"/, 'function\1')
|
|
25
|
+
link_to(name, path, options)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Render a React component with inner HTML content.
|
|
29
|
+
# Thanks to https://github.com/reactjs/react-rails/pull/166#issuecomment-86178980
|
|
30
|
+
def react_component_with_content(name, args = {}, options = {}, &block)
|
|
31
|
+
args[:__html] = capture(&block) if block.present?
|
|
32
|
+
react_component(name, args, options)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Provide link to dynamically add a new nested fields association
|
|
36
|
+
def link_to_add_fields(name, f, association)
|
|
37
|
+
new_object = f.object.send(association).klass.new
|
|
38
|
+
id = new_object.object_id
|
|
39
|
+
fields = f.fields_for(association, new_object, child_index: id) do |builder|
|
|
40
|
+
render(association.to_s.singularize + "_fields", f: builder)
|
|
41
|
+
end
|
|
42
|
+
link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Helper method that provides detailed error information from an active record as JSON
|
|
46
|
+
def errors_to_react(record)
|
|
47
|
+
{type: record.model_name.human.downcase, errors: record.errors.keys, messages: record.errors.full_messages}.as_json
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|