shopify_app 19.0.1 → 20.0.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/.github/workflows/build.yml +1 -1
- data/CHANGELOG.md +25 -3
- data/Gemfile.lock +11 -11
- data/README.md +0 -1
- data/app/assets/javascripts/shopify_app/app_bridge_3.1.1.js +10 -0
- data/app/assets/javascripts/shopify_app/app_bridge_redirect.js +1 -1
- data/app/assets/javascripts/shopify_app/app_bridge_utils_3.1.1.js +1 -0
- data/app/assets/javascripts/shopify_app/redirect.js +6 -8
- data/app/controllers/concerns/shopify_app/authenticated.rb +3 -0
- data/app/controllers/shopify_app/callback_controller.rb +28 -1
- data/app/controllers/shopify_app/sessions_controller.rb +3 -1
- data/config/routes.rb +17 -3
- data/docs/Releasing.md +1 -1
- data/docs/Upgrading.md +30 -17
- data/lib/generators/shopify_app/install/templates/shopify_app.rb.tt +13 -0
- data/lib/shopify_app/configuration.rb +31 -0
- data/lib/shopify_app/controller_concerns/ensure_billing.rb +254 -0
- data/lib/shopify_app/controller_concerns/login_protection.rb +26 -0
- data/lib/shopify_app/session/session_repository.rb +1 -1
- data/lib/shopify_app/session/user_session_storage_with_scopes.rb +1 -1
- data/lib/shopify_app/version.rb +1 -1
- data/lib/shopify_app.rb +1 -0
- data/package.json +1 -1
- data/shopify_app.gemspec +3 -3
- data/yarn.lock +3 -3
- metadata +11 -9
- data/app/assets/javascripts/shopify_app/app_bridge_2.0.12.js +0 -10
@@ -0,0 +1 @@
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("app-bridge-utils",[],e):"object"==typeof exports?exports["app-bridge-utils"]=e():t["app-bridge-utils"]=e()}(window,(function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=13)}([function(t,e,n){"use strict";var r=this&&this.__assign||function(){return(r=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t}).apply(this,arguments)},o=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.NonSnakeCaseGroup=e.findMatchInEnum=e.forEachInEnum=e.getMergedProps=e.updateActionFromPayload=e.isValidOptionalString=e.isValidOptionalNumber=e.getEventNameSpace=e.getVersion=e.actionWrapper=void 0;var i=n(5),a=o(n(18)),u=n(1),s=n(19);function c(){return s.version}function p(t,e){var n=a.default(t,e);return n||Object.assign(t,e)}e.actionWrapper=function(t){return r(r({},t),{version:c(),clientInterface:{name:s.name,version:c()}})},e.getVersion=c,e.getEventNameSpace=function(t,n,r){if(n.startsWith(""+i.PREFIX+i.SEPARATOR))return n;var o=function(t){if(e.NonSnakeCaseGroup.includes(t))return t.toUpperCase();return(n=t,n.replace(/([A-Z])/g,(function(t,e,n){return(0===n?"":"_")+t[0].toLowerCase()}))).toUpperCase();var n}(t);if(r){var a=r.subgroups,u=r.type;a&&a.length>0&&(o+=o.length>0?i.SEPARATOR:"",a.forEach((function(t,e){o+=""+t.toUpperCase()+(e<a.length-1?i.SEPARATOR:"")}))),u!==t&&u&&(o+=""+(o.length>0?i.SEPARATOR:"")+u.toUpperCase())}return o&&(o+=""+(o.length>0?i.SEPARATOR:"")+n.toUpperCase()),""+i.PREFIX+i.SEPARATOR+o},e.isValidOptionalNumber=function(t){return null==t||"number"==typeof t},e.isValidOptionalString=function(t){return null==t||"string"==typeof t},e.updateActionFromPayload=function(t,e){return t.id===e.id&&(Object.assign(t,p(t,e)),!0)},e.getMergedProps=p,e.forEachInEnum=function(t,e){Object.keys(t).forEach((function(n){e(t[n])}))},e.findMatchInEnum=function(t,e){var n=Object.keys(t).find((function(n){return e===t[n]}));return n?t[n]:void 0},e.NonSnakeCaseGroup=[u.Group.AuthCode,u.Group.Button,u.Group.ButtonGroup,u.Group.Cart,u.Group.Error,u.Group.Features,u.Group.Fullscreen,u.Group.Link,u.Group.Loading,u.Group.Menu,u.Group.Modal,u.Group.Navigation,u.Group.Pos,u.Group.Print,u.Group.ResourcePicker,u.Group.Scanner,u.Group.SessionToken,u.Group.Share,u.Group.TitleBar,u.Group.Toast,u.Group.unstable_Picker]},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ComponentType=e.Group=void 0,function(t){t.AuthCode="AuthCode",t.Button="Button",t.ButtonGroup="ButtonGroup",t.Cart="Cart",t.Client="Client",t.ContextualSaveBar="ContextualSaveBar",t.Error="Error",t.Features="Features",t.FeedbackModal="FeedbackModal",t.Fullscreen="Fullscreen",t.LeaveConfirmation="LeaveConfirmation",t.Link="Link",t.Loading="Loading",t.Menu="Menu",t.Modal="Modal",t.Navigation="Navigation",t.Performance="Performance",t.Pos="Pos",t.Print="Print",t.ResourcePicker="Resource_Picker",t.unstable_Picker="unstable_Picker",t.Scanner="Scanner",t.SessionToken="SessionToken",t.Share="Share",t.TitleBar="TitleBar",t.Toast="Toast",t.MarketingExternalActivityTopBar="MarketingExternalActivityTopBar"}(e.Group||(e.Group={})),function(t){t.Button="Button",t.ButtonGroup="ButtonGroup"}(e.ComponentType||(e.ComponentType={}))},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.throwError=e.fromAction=e.AppBridgeError=e.invalidOriginAction=e.isErrorEventName=e.permissionAction=e.networkAction=e.persistenceAction=e.unsupportedOperationAction=e.unexpectedAction=e.invalidAction=e.invalidActionType=e.invalidPayload=e.Message=e.AppActionType=e.Action=void 0;var r,o=n(0),i=n(1);function a(t,e,n){var r=e.payload;return o.actionWrapper({type:t,group:i.Group.Error,payload:{action:e,message:n,type:t,id:r&&r.id?r.id:void 0}})}!function(t){t.INVALID_ACTION="APP::ERROR::INVALID_ACTION",t.INVALID_ACTION_TYPE="APP::ERROR::INVALID_ACTION_TYPE",t.INVALID_PAYLOAD="APP::ERROR::INVALID_PAYLOAD",t.INVALID_OPTIONS="APP::ERROR::INVALID_OPTIONS",t.UNEXPECTED_ACTION="APP::ERROR::UNEXPECTED_ACTION",t.PERSISTENCE="APP::ERROR::PERSISTENCE",t.UNSUPPORTED_OPERATION="APP::ERROR::UNSUPPORTED_OPERATION",t.NETWORK="APP::ERROR::NETWORK",t.PERMISSION="APP::ERROR::PERMISSION",t.FAILED_AUTHENTICATION="APP::ERROR::FAILED_AUTHENTICATION",t.INVALID_ORIGIN="APP::ERROR::INVALID_ORIGIN"}(r=e.Action||(e.Action={})),function(t){t.INVALID_CONFIG="APP::ERROR::INVALID_CONFIG",t.MISSING_CONFIG="APP::APP_ERROR::MISSING_CONFIG",t.MISSING_APP_BRIDGE_MIDDLEWARE="APP::APP_ERROR::MISSING_APP_BRIDGE_MIDDLEWARE",t.WINDOW_UNDEFINED="APP::APP_ERROR::WINDOW_UNDEFINED",t.REDUX_REINSTANTIATED="APP::APP_ERROR::REDUX_REINSTANTIATED",t.MISSING_LOCAL_ORIGIN="APP::APP_ERROR::MISSING_LOCAL_ORIGIN",t.MISSING_HOST_PROVIDER="APP::APP_ERROR::MISSING_HOST_PROVIDER",t.MISSING_ROUTER_CONTEXT="APP::APP_ERROR::MISSING_ROUTER_CONTEXT",t.MISSING_HISTORY_BLOCK="APP::APP_ERROR::MISSING_HISTORY_BLOCK"}(e.AppActionType||(e.AppActionType={})),function(t){t.MISSING_PAYLOAD="Missing payload",t.INVALID_PAYLOAD_ID="Id in payload is missing or invalid"}(e.Message||(e.Message={})),e.invalidPayload=function(t,e){return a(r.INVALID_PAYLOAD,t,e||"The action's payload is missing required properties or has invalid properties")},e.invalidActionType=function(t,e){return o.actionWrapper({group:i.Group.Error,payload:{action:t,message:e||"The action type is invalid or unsupported",type:r.INVALID_ACTION_TYPE},type:r.INVALID_ACTION_TYPE})},e.invalidAction=function(t,e){return o.actionWrapper({group:i.Group.Error,payload:{action:t,message:e||"The action's has missing/invalid values for `group`, `type` or `version`",type:r.INVALID_ACTION},type:r.INVALID_ACTION})},e.unexpectedAction=function(t,e){return o.actionWrapper({group:i.Group.Error,payload:{action:t,message:e||"Action cannot be called at this time",type:r.UNEXPECTED_ACTION},type:r.UNEXPECTED_ACTION})},e.unsupportedOperationAction=function(t,e){return a(r.UNSUPPORTED_OPERATION,t,e||"The action type is unsupported")},e.persistenceAction=function(t,e){return a(r.PERSISTENCE,t,e||"Action cannot be persisted on server")},e.networkAction=function(t,e){return a(r.NETWORK,t,e||"Network error")},e.permissionAction=function(t,e){return a(r.PERMISSION,t,e||"Action is not permitted")},e.isErrorEventName=function(t){return"string"==typeof o.findMatchInEnum(r,t)},e.invalidOriginAction=function(t){return o.actionWrapper({group:i.Group.Error,payload:{message:t,type:r.INVALID_ORIGIN},type:r.INVALID_ORIGIN})};var u=function(t){this.name="AppBridgeError",this.message=t,"function"==typeof Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error(this.message).stack};function s(t,e,n){var r=new u(t?e+": "+t:e);return r.action=n,r.type=e,r}e.AppBridgeError=u,u.prototype=Object.create(Error.prototype),e.fromAction=s,e.throwError=function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];var n,r,o=t[0];throw"string"==typeof t[1]?n=t[1]:(r=t[1],n=t[2]||""),s(n,o,r)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.LifecycleHook=e.MessageType=e.PermissionType=e.isV1Config=void 0,e.isV1Config=function(t){return void 0!==t.shopOrigin},function(t){t.Dispatch="Dispatch",t.Subscribe="Subscribe"}(e.PermissionType||(e.PermissionType={})),function(t){t.GetState="getState",t.Dispatch="dispatch",t.Subscribe="subscribe",t.Unsubscribe="unsubscribe"}(e.MessageType||(e.MessageType={})),function(t){t.UpdateAction="UpdateAction",t.DispatchAction="DispatchAction"}(e.LifecycleHook||(e.LifecycleHook={}))},function(t,e,n){"use strict";var r,o=this&&this.__extends||(r=function(t,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])})(t,e)},function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function n(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}),i=this&&this.__assign||function(){return(i=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t}).apply(this,arguments)};Object.defineProperty(e,"__esModule",{value:!0}),e.create=e.Button=e.isValidButtonProps=e.update=e.clickButton=e.Style=e.Icon=e.Action=void 0;var a,u=n(0),s=n(6),c=n(1);function p(t,e,n){var r=e.id,o=u.getEventNameSpace(t,a.CLICK,e),i={id:r,payload:n};return u.actionWrapper({type:o,group:t,payload:i})}function l(t,e,n){var r=e.id,o=n.label,s=u.getEventNameSpace(t,a.UPDATE,e),c=i(i({},n),{id:r,label:o});return u.actionWrapper({type:s,group:t,payload:c})}!function(t){t.CLICK="CLICK",t.UPDATE="UPDATE"}(a=e.Action||(e.Action={})),function(t){t.Print="print"}(e.Icon||(e.Icon={})),function(t){t.Danger="danger"}(e.Style||(e.Style={})),e.clickButton=p,e.update=l,e.isValidButtonProps=function(t){return"string"==typeof t.id&&"string"==typeof t.label};var f=function(t){function e(e,n){var r=t.call(this,e,c.ComponentType.Button,c.Group.Button)||this;return r.disabled=!1,r.loading=!1,r.plain=!1,r.set(n,!1),r}return o(e,t),Object.defineProperty(e.prototype,"options",{get:function(){return{disabled:this.disabled,icon:this.icon,label:this.label,style:this.style,loading:this.loading,plain:this.plain}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"payload",{get:function(){return i(i({},this.options),{id:this.id})},enumerable:!1,configurable:!0}),e.prototype.set=function(t,e){void 0===e&&(e=!0);var n=u.getMergedProps(this.options,t),r=n.label,o=n.disabled,i=n.icon,s=n.style,c=n.loading,p=n.plain;return this.label=r,this.disabled=Boolean(o),this.icon=i,this.style=s,this.loading=Boolean(c),this.plain=Boolean(p),e&&this.dispatch(a.UPDATE),this},e.prototype.dispatch=function(t,e){switch(t){case a.CLICK:this.app.dispatch(p(this.group,this.component,e));break;case a.UPDATE:var n=l(this.group,this.component,this.payload);this.app.dispatch(n)}return this},e}(s.ActionSet);e.Button=f,e.create=function(t,e){return new f(t,e)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.SEPARATOR=e.PREFIX=void 0,e.PREFIX="APP",e.SEPARATOR="::"},function(t,e,n){"use strict";var r,o=this&&this.__extends||(r=function(t,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])})(t,e)},function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function n(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}),i=this&&this.__assign||function(){return(i=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t}).apply(this,arguments)},a=this&&this.__spreadArray||function(t,e){for(var n=0,r=e.length,o=t.length;n<r;n++,o++)t[o]=e[n];return t},u=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.ActionSetWithChildren=e.ActionSet=void 0;var s=n(3),c=n(7),p=n(2),l=n(1),f=u(n(8)),d=n(0),h=function(){function t(t,e,n,r){var o=this;this.app=t,this.type=e,this.group=n,this.subgroups=[],this.subscriptions=[],t||p.throwError(p.Action.INVALID_ACTION,"Missing required `app`"),this.id=r||f.default(),this.defaultGroup=n;var i=this.set;this.set=function(){for(var t,e=[],n=0;n<arguments.length;n++)e[n]=arguments[n];return o.app.hooks?(t=o.app.hooks).run.apply(t,a([s.LifecycleHook.UpdateAction,i,o],e)):i.apply(o,e)}}return t.prototype.set=function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e]},Object.defineProperty(t.prototype,"component",{get:function(){return{id:this.id,subgroups:this.subgroups,type:this.type}},enumerable:!1,configurable:!0}),t.prototype.updateSubscription=function(t,e,n){var r,o=t.eventType,i=t.callback,a=t.component;return(r=this.subscriptions.findIndex((function(e){return e===t})))>=0?this.subscriptions[r].unsubscribe():r=void 0,this.group=e,this.subgroups=n,Object.assign(a,{subgroups:this.subgroups}),this.subscribe(o,i,a,r)},t.prototype.error=function(t){var e=this,n=[];return d.forEachInEnum(p.Action,(function(r){n.push(e.subscriptions.length),e.subscribe(r,t)})),function(){n.map((function(t){return e.subscriptions[t]})).forEach((function(t){c.removeFromCollection(e.subscriptions,t,(function(t){t.unsubscribe()}))}))}},t.prototype.subscribe=function(t,e,n,r){var o,a=this,u=n||this.component,s=t.toUpperCase(),c="number"==typeof r?e:e.bind(this);o=p.isErrorEventName(t)?d.getEventNameSpace(l.Group.Error,t,i(i({},u),{type:""})):d.getEventNameSpace(this.group,t,u);var f=this.app.subscribe(o,c,n?n.id:this.id),h={eventType:s,unsubscribe:f,callback:c,component:u,updateSubscribe:function(t,e){return a.updateSubscription(h,t,e)}};return"number"==typeof r&&r>=0&&r<this.subscriptions.length?this.subscriptions[r]=h:this.subscriptions.push(h),f},t.prototype.unsubscribe=function(t){return void 0===t&&(t=!1),b(this.subscriptions,this.defaultGroup,t),this},t}();e.ActionSet=h;var y=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.children=[],e}return o(e,t),e.prototype.unsubscribe=function(t,n){return void 0===t&&(t=!0),void 0===n&&(n=!1),b(this.subscriptions,this.defaultGroup,n),this.children.forEach((function(n){n instanceof e?n.unsubscribe(t,!t):n.unsubscribe(!t)})),this},e.prototype.getChild=function(t){var e=this.children.findIndex((function(e){return e.id===t}));return e>=0?this.children[e]:void 0},e.prototype.getChildIndex=function(t){return this.children.findIndex((function(e){return e.id===t}))},e.prototype.getChildSubscriptions=function(t,e){return this.subscriptions.filter((function(n){return n.component.id===t&&(!e||e===n.eventType)}))},e.prototype.addChild=function(t,n,r){var o=this,i=t.subscriptions;return this.getChild(t.id)||this.children.push(t),!i||n===t.group&&r===t.subgroups||(i.forEach((function(t){(0,t.updateSubscribe)(n,r)})),Object.assign(t,{group:n,subgroups:r}),t instanceof e&&t.children.forEach((function(t){return o.addChild(t,n,r)}))),this},e.prototype.removeChild=function(t){var e=this;return c.removeFromCollection(this.children,this.getChild(t),(function(){e.subscriptions.filter((function(e){return e.component.id===t})).forEach((function(t){c.removeFromCollection(e.subscriptions,t,(function(t){t.unsubscribe()}))}))})),this},e.prototype.subscribeToChild=function(t,e,n){var r=this,o=n.bind(this);if(e instanceof Array)return e.forEach((function(e){return r.subscribeToChild(t,e,n)})),this;if("string"!=typeof e)return this;var i=e.toUpperCase(),a=this.getChildSubscriptions(t.id,i);if(a.length>0)a.forEach((function(e){return e.updateSubscribe(r.group,t.subgroups)}));else{var u={id:t.id,subgroups:t.subgroups,type:t.type};this.subscribe(i,o,u)}return this},e.prototype.getUpdatedChildActions=function(t,e){if(0!==t.length){for(var n=t.filter((function(t,e,n){return e===n.indexOf(t)})),r=n.map((function(t){return t.id})),o=e.filter((function(t){return r.indexOf(t.id)<0}));o.length>0;){if(!(i=o.pop()))break;this.removeChild(i.id)}return n}for(;e.length>0;){var i;if(!(i=e.pop()))break;this.removeChild(i.id)}},e}(h);function b(t,e,n){void 0===n&&(n=!1),t.forEach((function(t){n?(0,t.updateSubscribe)(e,[]):(0,t.unsubscribe)()})),n||(t.length=0)}e.ActionSetWithChildren=y},function(t,e,n){"use strict";function r(t,e,n){var r=t.findIndex((function(t){return t===e}));return r>=0&&(t.splice(r,1),n&&n(e),!0)}Object.defineProperty(e,"__esModule",{value:!0}),e.removeFromCollection=e.addAndRemoveFromCollection=void 0,e.addAndRemoveFromCollection=function(t,e,n){return t.push(e),function(){return r(t,e,n)}},e.removeFromCollection=r},function(t,e,n){"use strict";function r(t){return Array.from(t).map((function(t){return("00"+t.toString(16)).slice(-2)})).join("")}function o(t){if("function"==typeof Uint8Array&&"object"==typeof window&&window.crypto){var e=new Uint8Array(t),n=window.crypto.getRandomValues(e);if(n)return n}return Array.from(new Array(t),(function(){return 255*Math.random()|0}))}function i(){var t=o(1),e=o(2);return t[0]&=191,e[0]&=79,[r(o(4)),"-",r(o(2)),"-",r(e),"-",r(t),r(o(1)),"-",r(o(6))].join("")}Object.defineProperty(e,"__esModule",{value:!0}),e.generateUuid=void 0,e.generateUuid=i,e.default=i},function(t,e,n){"use strict";(function(t){var n,r;Object.defineProperty(e,"__esModule",{value:!0}),e.isUnframed=e.isDevelopmentClient=e.isProduction=e.isDevelopment=e.isClient=e.isServer=void 0,e.isServer="undefined"==typeof window,e.isClient=!e.isServer,e.isDevelopment=void 0!==t&&t.env&&!1,e.isProduction=!e.isDevelopment,e.isDevelopmentClient=e.isDevelopment&&e.isClient,e.isUnframed=e.isClient&&(null===(r=null===(n=window.navigator)||void 0===n?void 0:n.userAgent)||void 0===r?void 0:r.indexOf("Unframed"))>0}).call(this,n(22))},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.isShopifyPing=e.isShopifyPOS=e.isShopifyMobile=e.isShopifyEmbedded=e.isMobile=void 0;var r=n(9);function o(){return"undefined"!=typeof navigator&&navigator.userAgent.indexOf("Shopify Mobile")>=0}function i(){return"undefined"!=typeof navigator&&navigator.userAgent.indexOf("Shopify POS")>=0}function a(){return"undefined"!=typeof navigator&&navigator.userAgent.indexOf("Shopify Ping")>=0}e.isMobile=function(){return o()||i()||a()},e.isShopifyEmbedded=function(){return r.isClient&&window.top!==window.self||r.isUnframed},e.isShopifyMobile=o,e.isShopifyPOS=i,e.isShopifyPing=a},function(t,e,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(t,e,n,r){void 0===r&&(r=n),Object.defineProperty(t,r,{enumerable:!0,get:function(){return e[n]}})}:function(t,e,n,r){void 0===r&&(r=n),t[r]=e[n]}),o=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),i=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)"default"!==n&&Object.prototype.hasOwnProperty.call(t,n)&&r(e,t,n);return o(e,t),e},a=this&&this.__awaiter||function(t,e,n,r){return new(n||(n=Promise))((function(o,i){function a(t){try{s(r.next(t))}catch(t){i(t)}}function u(t){try{s(r.throw(t))}catch(t){i(t)}}function s(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},u=this&&this.__generator||function(t,e){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=e.call(t,a)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,u])}}};Object.defineProperty(e,"__esModule",{value:!0}),e.getSessionToken=void 0;var s=i(n(24)),c=n(2);e.getSessionToken=function(t){return a(this,void 0,void 0,(function(){return u(this,(function(e){return[2,new Promise((function(e,n){var r=t.subscribe(s.Action.RESPOND,(function(t){var o=t.sessionToken;o?e(o):n(c.fromAction("Failed to retrieve a session token",c.Action.FAILED_AUTHENTICATION)),r()}));t.dispatch(s.request())}))]}))}))}},function(t,e,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(t,e,n,r){void 0===r&&(r=n),Object.defineProperty(t,r,{enumerable:!0,get:function(){return e[n]}})}:function(t,e,n,r){void 0===r&&(r=n),t[r]=e[n]}),o=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),i=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)"default"!==n&&Object.prototype.hasOwnProperty.call(t,n)&&r(e,t,n);return o(e,t),e},a=this&&this.__awaiter||function(t,e,n,r){return new(n||(n=Promise))((function(o,i){function a(t){try{s(r.next(t))}catch(t){i(t)}}function u(t){try{s(r.throw(t))}catch(t){i(t)}}function s(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},u=this&&this.__generator||function(t,e){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=e.call(t,a)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,u])}}},s=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.getAuthorizationCodePayload=void 0;var c=i(n(27)),p=n(2),l=s(n(8));e.getAuthorizationCodePayload=function(t){return a(this,void 0,void 0,(function(){return u(this,(function(e){return[2,new Promise((function(e,n){var r=l.default(),o=t.subscribe(c.Action.RESPOND,(function(t){switch(null==t?void 0:t.status){case"needsExchange":e(t);break;default:n(p.fromAction("Failed to retrieve an authorization code",p.Action.FAILED_AUTHENTICATION))}o()}),r);t.dispatch(c.request(r))}))]}))}))}},function(t,e,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(t,e,n,r){void 0===r&&(r=n),Object.defineProperty(t,r,{enumerable:!0,get:function(){return e[n]}})}:function(t,e,n,r){void 0===r&&(r=n),t[r]=e[n]}),o=this&&this.__exportStar||function(t,e){for(var n in t)"default"===n||Object.prototype.hasOwnProperty.call(e,n)||r(e,t,n)};Object.defineProperty(e,"__esModule",{value:!0}),o(n(14),e)},function(t,e,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(t,e,n,r){void 0===r&&(r=n),Object.defineProperty(t,r,{enumerable:!0,get:function(){return e[n]}})}:function(t,e,n,r){void 0===r&&(r=n),t[r]=e[n]}),o=this&&this.__exportStar||function(t,e){for(var n in t)"default"===n||Object.prototype.hasOwnProperty.call(e,n)||r(e,t,n)};Object.defineProperty(e,"__esModule",{value:!0}),o(n(15),e),o(n(10),e),o(n(23),e),o(n(26),e)},function(t,e,n){"use strict";var r=this&&this.__awaiter||function(t,e,n,r){return new(n||(n=Promise))((function(o,i){function a(t){try{s(r.next(t))}catch(t){i(t)}}function u(t){try{s(r.throw(t))}catch(t){i(t)}}function s(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},o=this&&this.__generator||function(t,e){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=e.call(t,a)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,u])}}};Object.defineProperty(e,"__esModule",{value:!0}),e.createMutationObserver=e.setupModalAutoSizing=void 0;var i=n(16),a=n(20),u=n(10),s="app-bridge-utils-modal-auto-size",c=function(){if("undefined"==typeof document)return null;var t=document.createElement("style");return t.type="text/css",t.innerHTML="."+s+" { overflow: hidden; height: auto; min-height: auto; }",t}();function p(t,e){if("undefined"!=typeof document){var n,r=-1,o=new MutationObserver((function(){n&&window.clearTimeout(n);n=window.setTimeout(a,16)}));return o.observe(document,{attributes:!0,attributeOldValue:!1,characterData:!0,characterDataOldValue:!1,childList:!0,subtree:!0}),a(),o}function a(){var n=document.body.scrollHeight;n!==r&&(r=n,t.dispatch(i.updateModalSize({id:e,height:String(n)})))}}e.setupModalAutoSizing=function(t){return r(this,void 0,void 0,(function(){function e(){r&&(r(),r=void 0)}function n(n){var o=n.context,i=n.modal.id;return u.isMobile()||o!==a.Context.Modal?(e(),e):(r||(r=function(t,e){if(!c)return function(){};var n=document.getElementsByTagName("head")[0],r=document.body.classList;n.appendChild(c),r.add(s);var o=p(t,e);return function(){r.remove(s),n.contains(c)&&n.removeChild(c),o&&o.disconnect()}}(t,i)),e)}var r;return o(this,(function(r){switch(r.label){case 0:return[4,t.getState().then(n)];case 1:return r.sent(),[2,e]}}))}))},e.createMutationObserver=p},function(t,e,n){"use strict";var r,o=this&&this.__extends||(r=function(t,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])})(t,e)},function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function n(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}),i=this&&this.__assign||function(){return(i=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t}).apply(this,arguments)};Object.defineProperty(e,"__esModule",{value:!0}),e.create=e.ModalIframe=e.ModalMessage=e.Modal=e.isMessageModal=e.isIframeModal=e.data=e.update=e.clickFooterButton=e.updateModalSize=e.closeModal=e.openModal=e.Size=e.Action=void 0;var a,u,s=n(17),c=n(0),p=n(6),l=n(1),f=n(4);!function(t){t.OPEN="APP::MODAL::OPEN",t.CLOSE="APP::MODAL::CLOSE",t.UPDATE="APP::MODAL::UPDATE",t.UPDATE_CONTENT="APP::MODAL::CONTENT::UPDATE",t.FOOTER_BUTTON_CLICK="APP::MODAL::FOOTER::BUTTON::CLICK",t.FOOTER_BUTTON_UPDATE="APP::MODAL::FOOTER::BUTTON::UPDATE",t.UPDATE_SIZE="APP::MODAL::UPDATE_SIZE",t.DATA="APP::MODAL::DATA"}(a=e.Action||(e.Action={})),function(t){t.Small="small",t.Medium="medium",t.Large="large",t.Full="full",t.Auto="auto"}(u=e.Size||(e.Size={}));var d={group:l.Group.Modal,subgroups:["Footer"],type:l.ComponentType.Button};function h(t){return c.actionWrapper({group:l.Group.Modal,payload:t,type:a.OPEN})}function y(t){return c.actionWrapper({group:l.Group.Modal,payload:t,type:a.CLOSE})}function b(t){return c.actionWrapper({payload:t,group:l.Group.Modal,type:a.UPDATE})}function v(t){return c.actionWrapper({payload:t,group:l.Group.Modal,type:a.DATA})}function g(t){return"string"==typeof t.url||"string"==typeof t.path}e.openModal=h,e.closeModal=y,e.updateModalSize=function(t){return c.actionWrapper({group:l.Group.Modal,payload:t,type:a.UPDATE_SIZE})},e.clickFooterButton=function(t,e){var n=i({id:t},d);return f.clickButton(l.Group.Modal,n,e)},e.update=b,e.data=v,e.isIframeModal=g,e.isMessageModal=function(t){return"string"==typeof t.message};var O=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.size=u.Small,e}return o(e,t),Object.defineProperty(e.prototype,"footer",{get:function(){if(this.footerPrimary||this.footerSecondary)return{buttons:{primary:this.footerPrimary,secondary:this.footerSecondary}}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"footerOptions",{get:function(){if(this.footerPrimaryOptions||this.footerSecondaryOptions)return{buttons:{primary:this.footerPrimaryOptions,secondary:this.footerSecondaryOptions}}},enumerable:!1,configurable:!0}),e.prototype.close=function(){this.app.dispatch(y({id:this.id}))},e.prototype.setFooterPrimaryButton=function(t,e){var n=this,r=d.subgroups;this.footerPrimaryOptions=this.getChildButton(t,this.footerPrimaryOptions),this.footerPrimary=this.footerPrimaryOptions?s.getSingleButton(this,this.footerPrimaryOptions,r,(function(t){n.updatePrimaryFooterButton(t,e)})):void 0},e.prototype.setFooterSecondaryButtons=function(t,e){var n=this,r=d.subgroups,o=t||[],i=this.footerOptions&&this.footerOptions.buttons.secondary||[];this.footerSecondaryOptions=this.getUpdatedChildActions(o,i),this.footerSecondary=this.footerSecondaryOptions?this.footerSecondaryOptions.map((function(t){return s.getSingleButton(n,t,r,(function(t){n.updateSecondaryFooterButton(t,e)}))})):void 0},e.prototype.getChildButton=function(t,e){var n=t?[t]:[],r=e?[e]:[],o=this.getUpdatedChildActions(n,r);return o?o[0]:void 0},e.prototype.updatePrimaryFooterButton=function(t,e){this.footer&&this.footer.buttons.primary&&c.updateActionFromPayload(this.footer.buttons.primary,t)&&e()},e.prototype.updateSecondaryFooterButton=function(t,e){if(this.footer&&this.footer.buttons&&this.footer.buttons.secondary){for(var n,r=0,o=this.footer.buttons.secondary;r<o.length;r++){var i=o[r];if(n=c.updateActionFromPayload(i,t))break}n&&e()}},e}(p.ActionSetWithChildren);e.Modal=O;var P=function(t){function e(e,n){var r=t.call(this,e,l.Group.Modal,l.Group.Modal)||this;return r.set(n,!1),r}return o(e,t),Object.defineProperty(e.prototype,"payload",{get:function(){return i(i({},this.options),{footer:this.footer,id:this.id})},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"options",{get:function(){return{footer:this.footerOptions,message:this.message,size:this.size,title:this.title}},enumerable:!1,configurable:!0}),e.prototype.set=function(t,e){var n=this;void 0===e&&(e=!0);var r=c.getMergedProps(this.options,t),o=r.title,i=r.footer,u=r.message,s=r.size;return this.title=o,this.message=u,this.size=s,this.setFooterPrimaryButton(i?i.buttons.primary:void 0,(function(){n.dispatch(a.UPDATE)})),this.setFooterSecondaryButtons(i?i.buttons.secondary:void 0,(function(){n.dispatch(a.UPDATE)})),e&&this.dispatch(a.UPDATE),this},e.prototype.dispatch=function(t){switch(t){case a.OPEN:this.app.dispatch(h(this.payload));break;case a.CLOSE:this.close();break;case a.UPDATE:this.app.dispatch(b(this.payload))}return this},e}(O);e.ModalMessage=P;var A=function(t){function e(e,n){var r=t.call(this,e,l.Group.Modal,l.Group.Modal)||this;return r.set(n,!1),r}return o(e,t),Object.defineProperty(e.prototype,"payload",{get:function(){return i(i({},this.options),{footer:this.footer,id:this.id})},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"options",{get:function(){return{footer:this.footerOptions,path:this.path,size:this.size,title:this.title,url:this.url,loading:this.loading}},enumerable:!1,configurable:!0}),e.prototype.set=function(t,e){var n=this;void 0===e&&(e=!0);var r=c.getMergedProps(this.options,t),o=r.title,i=r.footer,u=r.path,s=r.url,p=r.size,l=r.loading;return this.title=o,this.url=s,this.path=u,this.size=p,this.loading=l,this.setFooterPrimaryButton(i?i.buttons.primary:void 0,(function(){n.dispatch(a.UPDATE)})),this.setFooterSecondaryButtons(i?i.buttons.secondary:void 0,(function(){n.dispatch(a.UPDATE)})),e&&this.dispatch(a.UPDATE),this},e.prototype.dispatch=function(t,e){switch(t){case a.OPEN:this.app.dispatch(h(this.payload));break;case a.CLOSE:this.close();break;case a.UPDATE:this.app.dispatch(b(this.payload));break;case a.DATA:this.app.dispatch(v(e||{}))}return this},e}(O);e.ModalIframe=A;e.create=function(t,e){return g(e)?new A(t,e):new P(t,e)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.getSingleButton=void 0;var r=n(4);e.getSingleButton=function(t,e,n,o){return t.addChild(e,t.group,n),t.subscribeToChild(e,r.Action.UPDATE,o),e.payload}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=function t(e,n){if(null==n)return n;if(void 0===e||!Object.prototype.isPrototypeOf.call(Object.getPrototypeOf(e),n)||"Object"!==n.constructor.name&&"Array"!==n.constructor.name)return n;var r={};return Object.keys(n).forEach((function(o){Object.prototype.hasOwnProperty.call(e,o)?"object"!=typeof e[o]||Array.isArray(e[o])?r[o]=n[o]:r[o]=t(e[o],n[o]):r[o]=n[o]})),Object.keys(e).forEach((function(t){Object.prototype.hasOwnProperty.call(n,t)||(r[t]=e[t])})),Object.setPrototypeOf(r,Object.getPrototypeOf(e)),r}},function(t){t.exports=JSON.parse('{"name":"@shopify/app-bridge","version":"3.1.1","types":"index.d.ts","main":"index.js","unpkg":"umd/index.js","jsdelivr":"umd/index.js","files":["/actions/","/client/","/umd/","/util/","/validate/","/development.d.ts","/development.js","/index.d.ts","/index.js","/MessageTransport.d.ts","/MessageTransport.js","/production.d.ts","/production.js"],"private":false,"publishConfig":{"access":"public","@shopify:registry":"https://registry.npmjs.org"},"repository":"git@github.com:Shopify/app-bridge.git","homepage":"https://shopify.dev/tools/app-bridge","author":"Shopify Inc.","license":"MIT","scripts":{"build":"yarn build:tsc && yarn build:npm && yarn build:umd","build:tsc":"NODE_ENV=production tsc","build:umd":"NODE_ENV=production webpack -p","build:npm":"shx cp -r ./npm/index.js ./index.js","check":"tsc","clean":"cat package.json | node -pe \\"JSON.parse(require(\'fs\').readFileSync(\'/dev/stdin\').toString()).files.map(f => \'./\'+f).join(\' \')\\" | xargs rm -rf","pack":"yarn pack","size":"size-limit"},"sideEffects":false,"size-limit":[{"limit":"17 KB","path":"production.js"}],"dependencies":{"base64url":"^3.0.1"},"devDependencies":{"@types/node":"^10.12.5","shx":"^0.3.3"}}')},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.createTransportListener=e.fromWindow=e.fromFrame=e.Context=void 0;var r=n(2),o=n(21),i=n(3),a=n(7),u=n(9);!function(t){t.Modal="Modal",t.Main="Main"}(e.Context||(e.Context={})),e.fromFrame=function(t,e,n){var i=[],s=t.host,c=t.window;if(!s)throw r.fromAction("App frame is undefined",r.AppActionType.WINDOW_UNDEFINED);return u.isUnframed&&window.MobileWebView&&Object.assign(window.MobileWebView,{postMessageToIframe:function(t,e){null==c||c.postMessage(t,e),function(t){return null!==t&&"object"==typeof t&&!Array.isArray(t)&&"dispatch"===t.type&&"object"==typeof t.payload}(t)&&s.postMessage(JSON.stringify(t.payload),location.origin)},updateIframeUrl:function(n){var r=window.location,o=(t.window||{}).location;try{new URL(n).origin===e&&o?o.replace(n):r.href=n}catch(t){}}}),s.addEventListener("message",(function(t){if(t.source!==s&&o.isAppMessage(t))if(t.origin===e)if(u.isUnframed&&window.MobileWebView){p=JSON.stringify({id:"unframed://fromClient",origin:e,data:t.data});window.MobileWebView.postMessage(p)}else for(var n=0,a=i;n<a.length;n++){(0,a[n])(t)}else{var p,l="Message origin '"+t.origin+"' does not match app origin '"+e+"'.",f={type:"dispatch",payload:p=r.invalidOriginAction(l)};null==c||c.postMessage(f,t.origin)}})),{context:n,localOrigin:e,frameWindow:c,hostFrame:s,dispatch:function(t){null==c||c.postMessage(t,e)},subscribe:function(t){return a.addAndRemoveFromCollection(i,t)}}},e.fromWindow=function(t,e){var n=[];return void 0!==typeof window&&window.addEventListener("message",(function(e){if((window!==t||u.isUnframed)&&e.source===t&&(o.isAppBridgeAction(e.data.payload)||o.isAppMessage(e)))for(var r=0,i=n;r<i.length;r++){(0,i[r])(e)}})),{localOrigin:e,hostFrame:t,dispatch:function(n){var r;if(null===(r=n.source)||void 0===r?void 0:r.host)if(u.isUnframed&&window&&window.MobileWebView){var o=JSON.stringify({id:"unframed://fromClient",origin:e,data:n});window.MobileWebView.postMessage(o)}else{var i=new URL("https://"+n.source.host).origin;t.postMessage(n,i)}},subscribe:function(t){return a.addAndRemoveFromCollection(n,t)}}},e.createTransportListener=function(){var t=[],e={};return{createSubscribeHandler:function(n){return function(){if(arguments.length<2)return a.addAndRemoveFromCollection(t,{callback:arguments[0]});var r=Array.from(arguments),o=r[0],u=r[1],s=r[2],c={callback:u,id:s},p={type:o,id:s};return Object.prototype.hasOwnProperty.call(e,o)||(e[o]=[]),n&&n(i.MessageType.Subscribe,p),a.addAndRemoveFromCollection(e[o],c,(function(){n&&n(i.MessageType.Unsubscribe,p)}))}},handleMessage:function(e){t.forEach((function(t){return t.callback(e)}))},handleActionDispatch:function(t){var n=t.type,r=t.payload,o=!1;if(Object.prototype.hasOwnProperty.call(e,n))for(var i=0,a=e[n];i<a.length;i++){var u=a[i],s=u.id,c=u.callback;!(r&&r.id===s)&&s||(c(r),o=!0)}return o}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.isAppMessage=e.isPermitted=e.getPermissionKey=e.isFromApp=e.isAppBridgeAction=void 0;var r=n(3),o=n(5),i=n(0);function a(t){return t.replace(new RegExp("^"+o.PREFIX+o.SEPARATOR+"\\w+"+o.SEPARATOR),"")}e.isAppBridgeAction=function(t){return t instanceof Object&&Object.prototype.hasOwnProperty.call(t,"type")&&t.type.toString().startsWith(o.PREFIX)},e.isFromApp=function(t){return"object"==typeof t&&"object"==typeof t.source&&"string"==typeof t.source.apiKey},e.getPermissionKey=a,e.isPermitted=function(t,e,n){var r=e.group,o=e.type;if(!r||!Object.prototype.hasOwnProperty.call(t,r))return!1;var i=t[r];if(!i)return!1;var u=a(o);return!!i[u]&&!0===i[u][n]},e.isAppMessage=function(t){if("object"!=typeof t||!t.data||"object"!=typeof t.data)return!1;var e=t.data;return Object.prototype.hasOwnProperty.call(e,"type")&&void 0!==i.findMatchInEnum(r.MessageType,e.type)}},function(t,e){var n,r,o=t.exports={};function i(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function u(t){if(n===setTimeout)return setTimeout(t,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(t){n=i}try{r="function"==typeof clearTimeout?clearTimeout:a}catch(t){r=a}}();var s,c=[],p=!1,l=-1;function f(){p&&s&&(p=!1,s.length?c=s.concat(c):l=-1,c.length&&d())}function d(){if(!p){var t=u(f);p=!0;for(var e=c.length;e;){for(s=c,c=[];++l<e;)s&&s[l].run();l=-1,e=c.length}s=null,p=!1,function(t){if(r===clearTimeout)return clearTimeout(t);if((r===a||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(t);try{r(t)}catch(e){try{return r.call(null,t)}catch(e){return r.call(this,t)}}}(t)}}function h(t,e){this.fun=t,this.array=e}function y(){}o.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];c.push(new h(t,e)),1!==c.length||p||u(d)},h.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=y,o.addListener=y,o.once=y,o.off=y,o.removeListener=y,o.removeAllListeners=y,o.emit=y,o.prependListener=y,o.prependOnceListener=y,o.listeners=function(t){return[]},o.binding=function(t){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(t){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},function(t,e,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(t,e,n,r){void 0===r&&(r=n),Object.defineProperty(t,r,{enumerable:!0,get:function(){return e[n]}})}:function(t,e,n,r){void 0===r&&(r=n),t[r]=e[n]}),o=this&&this.__exportStar||function(t,e){for(var n in t)"default"===n||Object.prototype.hasOwnProperty.call(e,n)||r(e,t,n)};Object.defineProperty(e,"__esModule",{value:!0}),o(n(11),e),o(n(25),e)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.respond=e.request=e.Action=void 0;var r,o=n(0),i=n(1);!function(t){t.REQUEST="APP::SESSION_TOKEN::REQUEST",t.RESPOND="APP::SESSION_TOKEN::RESPOND"}(r=e.Action||(e.Action={})),e.request=function(){return o.actionWrapper({group:i.Group.SessionToken,type:r.REQUEST})},e.respond=function(t){return o.actionWrapper({payload:t,group:i.Group.SessionToken,type:r.RESPOND})}},function(t,e,n){"use strict";var r=this&&this.__assign||function(){return(r=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t}).apply(this,arguments)},o=this&&this.__awaiter||function(t,e,n,r){return new(n||(n=Promise))((function(o,i){function a(t){try{s(r.next(t))}catch(t){i(t)}}function u(t){try{s(r.throw(t))}catch(t){i(t)}}function s(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},i=this&&this.__generator||function(t,e){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=e.call(t,a)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,u])}}};Object.defineProperty(e,"__esModule",{value:!0}),e.authenticatedFetch=void 0;var a=n(11);e.authenticatedFetch=function(t,e){var n=this;return void 0===e&&(e=fetch),function(u,s){return void 0===s&&(s={}),o(n,void 0,void 0,(function(){var n,o,c;return i(this,(function(i){switch(i.label){case 0:return[4,a.getSessionToken(t)];case 1:return n=i.sent(),(o=new Headers(s.headers)).append("Authorization","Bearer "+n),o.append("X-Requested-With","XMLHttpRequest"),c={},o.forEach((function(t,e){c[e]=t})),[2,e(u,r(r({},s),{headers:c}))]}}))}))}}},function(t,e,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(t,e,n,r){void 0===r&&(r=n),Object.defineProperty(t,r,{enumerable:!0,get:function(){return e[n]}})}:function(t,e,n,r){void 0===r&&(r=n),t[r]=e[n]}),o=this&&this.__exportStar||function(t,e){for(var n in t)"default"===n||Object.prototype.hasOwnProperty.call(e,n)||r(e,t,n)};Object.defineProperty(e,"__esModule",{value:!0}),o(n(12),e),o(n(28),e)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.respond=e.request=e.Action=void 0;var r,o=n(0),i=n(1);!function(t){t.REQUEST="APP::AUTH_CODE::REQUEST",t.RESPOND="APP::AUTH_CODE::RESPOND"}(r=e.Action||(e.Action={})),e.request=function(t){return o.actionWrapper({group:i.Group.AuthCode,type:r.REQUEST,payload:{id:t}})},e.respond=function(t){return o.actionWrapper({payload:t,group:i.Group.AuthCode,type:r.RESPOND})}},function(t,e,n){"use strict";var r=this&&this.__awaiter||function(t,e,n,r){return new(n||(n=Promise))((function(o,i){function a(t){try{s(r.next(t))}catch(t){i(t)}}function u(t){try{s(r.throw(t))}catch(t){i(t)}}function s(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},o=this&&this.__generator||function(t,e){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=e.call(t,a)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,u])}}};Object.defineProperty(e,"__esModule",{value:!0}),e.userAuthorizedFetch=void 0;var i=n(12);function a(t){var e=t.headers.get("X-Shopify-API-Request-Failure-Unauthorized");return!!e&&"true"===e.toLowerCase()}e.userAuthorizedFetch=function(t){var e=this,n=t.app,u=t.callbackUri,s=void 0===u?"auth/shopify/callback":u,c=t.isAuthorizationCodeRequired,p=void 0===c?a:c,l=t.fetchOperation;return function(t,a){return r(e,void 0,void 0,(function(){var e,r,u,c,f,d,h;return o(this,(function(o){switch(o.label){case 0:return[4,l(t,a)];case 1:return e=o.sent(),p(e)?[4,i.getAuthorizationCodePayload(n)]:[2,e];case 2:return r=o.sent(),u=r.code,c=r.hmac,f=r.shop,d=r.timestamp,h=encodeURI("https://"+window.location.hostname+"/"+s+"?code="+u+"&hmac="+c+"&shop="+f+"×tamp="+d),[4,l(h,{})];case 3:if(!o.sent().ok)throw new Error("Failed to authorize request.");return[2,l(t,a)]}}))}))}}}])}));
|
@@ -1,4 +1,5 @@
|
|
1
1
|
//= require ./app_bridge_redirect.js
|
2
|
+
//= require ./app_bridge_utils_3.1.1.js
|
2
3
|
|
3
4
|
(function () {
|
4
5
|
function redirect() {
|
@@ -10,15 +11,12 @@
|
|
10
11
|
|
11
12
|
var targetInfo = JSON.parse(redirectTargetElement.dataset.target);
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
} else {
|
17
|
-
// If the current window is the 'child' or embedded, change the parent's URL with
|
18
|
-
// App Bridge redirect. This case can happen when an app updates its access scopes,
|
19
|
-
// or the unlikely scenario where the shop thinks the app is installed, but the
|
20
|
-
// app does not have an record for the shop.
|
14
|
+
var appBridgeUtils = window['app-bridge-utils'];
|
15
|
+
|
16
|
+
if (appBridgeUtils.isShopifyEmbedded()) {
|
21
17
|
window.appBridgeRedirect(targetInfo.url);
|
18
|
+
} else {
|
19
|
+
window.top.location.href = targetInfo.url;
|
22
20
|
}
|
23
21
|
}
|
24
22
|
|
@@ -9,8 +9,11 @@ module ShopifyApp
|
|
9
9
|
include ShopifyApp::LoginProtection
|
10
10
|
include ShopifyApp::CsrfProtection
|
11
11
|
include ShopifyApp::EmbeddedApp
|
12
|
+
include ShopifyApp::EnsureBilling
|
13
|
+
|
12
14
|
before_action :login_again_if_different_user_or_shop
|
13
15
|
around_action :activate_shopify_session
|
16
|
+
after_action :add_top_level_redirection_headers
|
14
17
|
end
|
15
18
|
end
|
16
19
|
end
|
@@ -4,6 +4,7 @@ module ShopifyApp
|
|
4
4
|
# Performs login after OAuth completes
|
5
5
|
class CallbackController < ActionController::Base
|
6
6
|
include ShopifyApp::LoginProtection
|
7
|
+
include ShopifyApp::EnsureBilling
|
7
8
|
|
8
9
|
def callback
|
9
10
|
begin
|
@@ -27,9 +28,16 @@ module ShopifyApp
|
|
27
28
|
value: auth_result[:cookie].value,
|
28
29
|
}
|
29
30
|
|
31
|
+
session[:shopify_user_id] = auth_result[:session].associated_user.id if auth_result[:session].online?
|
32
|
+
|
33
|
+
if start_user_token_flow?(auth_result[:session])
|
34
|
+
return respond_with_user_token_flow
|
35
|
+
end
|
36
|
+
|
30
37
|
perform_post_authenticate_jobs(auth_result[:session])
|
38
|
+
has_payment = check_billing(auth_result[:session])
|
31
39
|
|
32
|
-
respond_successfully
|
40
|
+
respond_successfully if has_payment
|
33
41
|
end
|
34
42
|
|
35
43
|
private
|
@@ -43,6 +51,25 @@ module ShopifyApp
|
|
43
51
|
redirect_to(login_url_with_optional_shop)
|
44
52
|
end
|
45
53
|
|
54
|
+
def respond_with_user_token_flow
|
55
|
+
redirect_to(login_url_with_optional_shop)
|
56
|
+
end
|
57
|
+
|
58
|
+
def start_user_token_flow?(shopify_session)
|
59
|
+
return false unless ShopifyApp::SessionRepository.user_storage.present?
|
60
|
+
return false if shopify_session.online?
|
61
|
+
update_user_access_scopes?
|
62
|
+
end
|
63
|
+
|
64
|
+
def update_user_access_scopes?
|
65
|
+
return true if session[:shopify_user_id].nil?
|
66
|
+
user_access_scopes_strategy.update_access_scopes?(shopify_user_id: session[:shopify_user_id])
|
67
|
+
end
|
68
|
+
|
69
|
+
def user_access_scopes_strategy
|
70
|
+
ShopifyApp.configuration.user_access_scopes_strategy
|
71
|
+
end
|
72
|
+
|
46
73
|
def perform_post_authenticate_jobs(session)
|
47
74
|
install_webhooks(session)
|
48
75
|
install_scripttags(session)
|
@@ -44,9 +44,11 @@ module ShopifyApp
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def start_oauth
|
47
|
+
callback_url = ShopifyApp.configuration.login_callback_url.gsub(%r{^/}, "")
|
48
|
+
|
47
49
|
auth_attributes = ShopifyAPI::Auth::Oauth.begin_auth(
|
48
50
|
shop: sanitized_shop_name,
|
49
|
-
redirect_path: "
|
51
|
+
redirect_path: "/#{callback_url}",
|
50
52
|
is_online: user_session_expected?
|
51
53
|
)
|
52
54
|
cookies.encrypted[auth_attributes[:cookie].name] = {
|
data/config/routes.rb
CHANGED
@@ -1,14 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
ShopifyApp::Engine.routes.draw do
|
4
|
+
login_url = ShopifyApp.configuration.login_url.gsub(/^#{ShopifyApp.configuration.root_url}/, "")
|
5
|
+
login_callback_url = ShopifyApp.configuration.login_callback_url.gsub(/^#{ShopifyApp.configuration.root_url}/, "")
|
6
|
+
|
4
7
|
controller :sessions do
|
5
|
-
get
|
6
|
-
post
|
8
|
+
get login_url => :new, :as => :login
|
9
|
+
post login_url => :create, :as => :authenticate
|
7
10
|
get "logout" => :destroy, :as => :logout
|
11
|
+
|
12
|
+
# Kept to prevent apps relying on these routes from breaking
|
13
|
+
if login_url.gsub(%r{^/}, "") != "login"
|
14
|
+
get "login" => :new, :as => :default_login
|
15
|
+
post "login" => :create, :as => :default_authenticate
|
16
|
+
end
|
8
17
|
end
|
9
18
|
|
10
19
|
controller :callback do
|
11
|
-
get
|
20
|
+
get login_callback_url => :callback
|
21
|
+
|
22
|
+
# Kept to prevent apps relying on these routes from breaking
|
23
|
+
if login_callback_url.gsub(%r{^/}, "") != "auth/shopify/callback"
|
24
|
+
get "auth/shopify/callback" => :default_callback
|
25
|
+
end
|
12
26
|
end
|
13
27
|
|
14
28
|
namespace :webhooks do
|
data/docs/Releasing.md
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
1. Checkout and pull from master so you have the latest version of the shopify_app
|
13
13
|
1. Tag the HEAD with the version
|
14
14
|
```bash
|
15
|
-
$ git tag -f vX.Y.Z && git push
|
15
|
+
$ git tag -f vX.Y.Z && git push origin vX.Y.Z
|
16
16
|
```
|
17
17
|
1. Check that Create Release workflow successfully runs
|
18
18
|
1. Use Shipit to build and push the gem
|
data/docs/Upgrading.md
CHANGED
@@ -23,18 +23,23 @@ gem.
|
|
23
23
|
|
24
24
|
### High-level process
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
- Delete `config/initializers/omniauth.rb` as apps no longer need to initialize `OmniAuth` directly.
|
27
|
+
- Delete `config/initializers/user_agent.rb` as `shopify_app` will set the right `User-Agent` header for interacting
|
28
28
|
with the Shopify API. If the app requires further information in the `User-Agent` header beyond what Shopify API
|
29
29
|
requires, specify this in the `ShopifyAPI::Context.user_agent_prefix` setting.
|
30
|
-
|
30
|
+
- Remove `allow_jwt_authentication=` and `allow_cookie_authentication=` invocations from
|
31
31
|
`config/initializers/shopify_app.rb` as the decision logic for which authentication method to use is now handled
|
32
32
|
internally by the `shopify_api` gem, using the `ShopifyAPI::Context.embedded_app` setting.
|
33
|
-
|
34
|
-
the documentation for addressing these breaking changes on GitHub [here](https://github.com/Shopify/shopify_api
|
33
|
+
- `v19.0.0` updates the `shopify_api` dependency to `10.0.0`. This version of `shopify_api` has breaking changes. See
|
34
|
+
the documentation for addressing these breaking changes on GitHub [here](https://github.com/Shopify/shopify_api#breaking-change-notice-for-version-1000).
|
35
35
|
|
36
36
|
### Specific cases
|
37
37
|
|
38
|
+
#### Shopify user id in session
|
39
|
+
|
40
|
+
Previously, we set the entire app user object in the `session` object.
|
41
|
+
As of v19, since we no longer save the app user to the session (but only the shopify user id), we now store it as `session[:shopify_user_id]`. Please make sure to update any references to that object.
|
42
|
+
|
38
43
|
#### Webhook Jobs
|
39
44
|
|
40
45
|
Add a new `handle` method to existing webhook jobs to go through the updated `shopify_api` gem.
|
@@ -97,6 +102,7 @@ Rails.application.config.after_initialize do
|
|
97
102
|
end
|
98
103
|
end
|
99
104
|
```
|
105
|
+
|
100
106
|
## Upgrading to `v18.1.2`
|
101
107
|
|
102
108
|
Version 18.1.2 replaces the deprecated EASDK redirect with an App Bridge 2 redirect when attempting to break out of an iframe. This happens when an app is installed, requires new access scopes, or re-authentication because the login session is expired.
|
@@ -105,7 +111,7 @@ Version 18.1.2 replaces the deprecated EASDK redirect with an App Bridge 2 redir
|
|
105
111
|
|
106
112
|
### Different SameSite cookie attribute behaviour
|
107
113
|
|
108
|
-
To support Rails
|
114
|
+
To support Rails `v6.1`, the [`SameSiteCookieMiddleware`](/lib/shopify_app/middleware/same_site_cookie_middleware.rb) was updated to configure cookies to `SameSite=None` if the app is embedded. Before this release, cookies were configured to `SameSite=None` only if this attribute had not previously been set before.
|
109
115
|
|
110
116
|
```diff
|
111
117
|
# same_site_cookie_middleware.rb
|
@@ -122,32 +128,33 @@ change to how session stores work. Here are the steps to migrate to 13.x
|
|
122
128
|
|
123
129
|
### Changes to `config/initializers/shopify_app.rb`
|
124
130
|
|
125
|
-
-
|
126
|
-
-
|
127
|
-
-
|
131
|
+
- _REMOVE_ `config.per_user_tokens = [true|false]` this is no longer needed
|
132
|
+
- _CHANGE_ `config.session_repository = 'Shop'` To `config.shop_session_repository = 'Shop'`
|
133
|
+
- _ADD (optional)_ User Session Storage `config.user_session_repository = 'User'`
|
128
134
|
|
129
135
|
### Shop Model Changes (normally `app/models/shop.rb`)
|
130
136
|
|
131
|
-
-
|
137
|
+
- _CHANGE_ `include ShopifyApp::SessionStorage` to `include ShopifyApp::ShopSessionStorage`
|
132
138
|
|
133
139
|
### Changes to the @shop_session instance variable (normally in `app/controllers/*.rb`)
|
134
140
|
|
135
|
-
-
|
141
|
+
- _CHANGE_ if you are using shop sessions, `@shop_session` will need to be changed to `@current_shopify_session`.
|
136
142
|
|
137
143
|
### Changes to Rails `session`
|
138
144
|
|
139
|
-
-
|
145
|
+
- _CHANGE_ `session[:shopify]` is no longer set. Use `session[:user_id]` if your app uses user based tokens, or `session[:shop_id]` if your app uses shop based tokens.
|
140
146
|
|
141
147
|
### Changes to `ShopifyApp::LoginProtection`
|
142
148
|
|
143
149
|
`ShopifyApp::LoginProtection`
|
144
150
|
|
145
151
|
- CHANGE if you are using `ShopifyApp::LoginProtection#shopify_session` in your code, it will need to be
|
146
|
-
changed to `ShopifyApp::LoginProtection#activate_shopify_session`
|
152
|
+
changed to `ShopifyApp::LoginProtection#activate_shopify_session`
|
147
153
|
- CHANGE if you are using `ShopifyApp::LoginProtection#clear_shop_session` in your code, it will need to be
|
148
|
-
changed to `ShopifyApp::LoginProtection#clear_shopify_session`
|
154
|
+
changed to `ShopifyApp::LoginProtection#clear_shopify_session`
|
149
155
|
|
150
156
|
### Notes
|
157
|
+
|
151
158
|
You do not need a user model; a shop session is fine for most applications.
|
152
159
|
|
153
160
|
---
|
@@ -155,6 +162,7 @@ You do not need a user model; a shop session is fine for most applications.
|
|
155
162
|
## Upgrading to `v11.7.0`
|
156
163
|
|
157
164
|
### Session storage method signature breaking change
|
165
|
+
|
158
166
|
If you override `def self.store(auth_session)` method in your session storage model (e.g. Shop), the method signature has changed to `def self.store(auth_session, *args)` in order to support user-based token storage. Please update your method signature to include the second argument.
|
159
167
|
|
160
168
|
---
|
@@ -165,13 +173,15 @@ If you override `def self.store(auth_session)` method in your session storage mo
|
|
165
173
|
|
166
174
|
Add an API version configuration in `config/initializers/shopify_app.rb`
|
167
175
|
Set this to the version you want to run against by default. See [Shopify API docs](https://help.shopify.com/api/versioning) for versions available.
|
176
|
+
|
168
177
|
```ruby
|
169
178
|
config.api_version = '2019-04'
|
170
179
|
```
|
171
180
|
|
172
181
|
### Session storage change
|
173
182
|
|
174
|
-
You will need to add an `api_version` method to your session storage object.
|
183
|
+
You will need to add an `api_version` method to your session storage object. The default implementation for this is.
|
184
|
+
|
175
185
|
```ruby
|
176
186
|
def api_version
|
177
187
|
ShopifyApp.configuration.api_version
|
@@ -181,6 +191,7 @@ end
|
|
181
191
|
### Generated file change
|
182
192
|
|
183
193
|
`embedded_app.html.erb` the usage of `shop_session.url` needs to be changed to `shop_session.domain`
|
194
|
+
|
184
195
|
```erb
|
185
196
|
<script type="text/javascript">
|
186
197
|
ShopifyApp.init({
|
@@ -193,7 +204,9 @@ end
|
|
193
204
|
});
|
194
205
|
</script>
|
195
206
|
```
|
207
|
+
|
196
208
|
is changed to
|
209
|
+
|
197
210
|
```erb
|
198
211
|
<script type="text/javascript">
|
199
212
|
ShopifyApp.init({
|
@@ -211,5 +224,5 @@ is changed to
|
|
211
224
|
|
212
225
|
You will need to also follow the ShopifyAPI [upgrade guide](https://github.com/Shopify/shopify_api/blob/master/README.md#-breaking-change-notice-for-version-700-) to ensure your app is ready to work with API versioning.
|
213
226
|
|
214
|
-
[dashboard]:https://partners.shopify.com
|
215
|
-
[app-bridge]:https://shopify.dev/apps/tools/app-bridge
|
227
|
+
[dashboard]: https://partners.shopify.com
|
228
|
+
[app-bridge]: https://shopify.dev/apps/tools/app-bridge
|
@@ -13,6 +13,19 @@ ShopifyApp.configure do |config|
|
|
13
13
|
config.api_key = ENV.fetch('SHOPIFY_API_KEY', '').presence
|
14
14
|
config.secret = ENV.fetch('SHOPIFY_API_SECRET', '').presence
|
15
15
|
|
16
|
+
# You may want to charge merchants for using your app. Setting the billing configuration will cause the Authenticated
|
17
|
+
# controller concern to check that the session is for a merchant that has an active one-time payment or subscription.
|
18
|
+
# If no payment is found, it starts off the process and sends the merchant to a confirmation URL so that they can
|
19
|
+
# approve the purchase.
|
20
|
+
#
|
21
|
+
# Learn more about billing in our documentation: https://shopify.dev/apps/billing
|
22
|
+
# config.billing = ShopifyApp::BillingConfiguration.new(
|
23
|
+
# charge_name: "My app billing charge",
|
24
|
+
# amount: 5,
|
25
|
+
# interval: ShopifyApp::BillingConfiguration::INTERVAL_EVERY_30_DAYS,
|
26
|
+
# currency_code: "USD", # Only supports USD for now
|
27
|
+
# )
|
28
|
+
|
16
29
|
if defined? Rails::Server
|
17
30
|
raise('Missing SHOPIFY_API_KEY. See https://github.com/Shopify/shopify_app#requirements') unless config.api_key
|
18
31
|
raise('Missing SHOPIFY_API_SECRET. See https://github.com/Shopify/shopify_app#requirements') unless config.secret
|
@@ -24,6 +24,7 @@ module ShopifyApp
|
|
24
24
|
# customise urls
|
25
25
|
attr_accessor :root_url
|
26
26
|
attr_writer :login_url
|
27
|
+
attr_writer :login_callback_url
|
27
28
|
|
28
29
|
# customise ActiveJob queue names
|
29
30
|
attr_accessor :scripttags_manager_queue_name
|
@@ -38,6 +39,9 @@ module ShopifyApp
|
|
38
39
|
# allow namespacing webhook jobs
|
39
40
|
attr_accessor :webhook_jobs_namespace
|
40
41
|
|
42
|
+
# takes a ShopifyApp::BillingConfiguration object
|
43
|
+
attr_accessor :billing
|
44
|
+
|
41
45
|
def initialize
|
42
46
|
@root_url = "/"
|
43
47
|
@myshopify_domain = "myshopify.com"
|
@@ -50,6 +54,11 @@ module ShopifyApp
|
|
50
54
|
@login_url || File.join(@root_url, "login")
|
51
55
|
end
|
52
56
|
|
57
|
+
def login_callback_url
|
58
|
+
# Not including @root_url to keep historic behaviour
|
59
|
+
@login_callback_url || File.join("auth/shopify/callback")
|
60
|
+
end
|
61
|
+
|
53
62
|
def user_session_repository=(klass)
|
54
63
|
ShopifyApp::SessionRepository.user_storage = klass
|
55
64
|
end
|
@@ -84,6 +93,10 @@ module ShopifyApp
|
|
84
93
|
scripttags.present?
|
85
94
|
end
|
86
95
|
|
96
|
+
def requires_billing?
|
97
|
+
billing.present?
|
98
|
+
end
|
99
|
+
|
87
100
|
def shop_access_scopes
|
88
101
|
@shop_access_scopes || scope
|
89
102
|
end
|
@@ -93,6 +106,24 @@ module ShopifyApp
|
|
93
106
|
end
|
94
107
|
end
|
95
108
|
|
109
|
+
class BillingConfiguration
|
110
|
+
INTERVAL_ONE_TIME = "ONE_TIME"
|
111
|
+
INTERVAL_EVERY_30_DAYS = "EVERY_30_DAYS"
|
112
|
+
INTERVAL_ANNUAL = "ANNUAL"
|
113
|
+
|
114
|
+
attr_reader :charge_name
|
115
|
+
attr_reader :amount
|
116
|
+
attr_reader :currency_code
|
117
|
+
attr_reader :interval
|
118
|
+
|
119
|
+
def initialize(charge_name:, amount:, interval:, currency_code: "USD")
|
120
|
+
@charge_name = charge_name
|
121
|
+
@amount = amount
|
122
|
+
@currency_code = currency_code
|
123
|
+
@interval = interval
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
96
127
|
def self.configuration
|
97
128
|
@configuration ||= Configuration.new
|
98
129
|
end
|