shopify_app 19.0.1 → 20.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|