@shopify/shopify-app-remix 2.5.0 → 2.5.1

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.
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var appBridgeUrl = require('../../helpers/app-bridge-url.js');
6
6
  var addResponseHeaders = require('../../helpers/add-response-headers.js');
7
+ var validateRedirectUrl = require('./validate-redirect-url.js');
7
8
 
8
9
  function renderAppBridge({
9
10
  config
@@ -11,7 +12,7 @@ function renderAppBridge({
11
12
  let redirectToScript = '';
12
13
  if (redirectTo) {
13
14
  var _redirectTo$target;
14
- const destination = new URL(redirectTo.url, config.appUrl);
15
+ const destination = validateRedirectUrl.sanitizeRedirectUrl(config.appUrl, redirectTo.url);
15
16
  const target = (_redirectTo$target = redirectTo.target) !== null && _redirectTo$target !== void 0 ? _redirectTo$target : '_top';
16
17
  redirectToScript = `<script>window.open(${JSON.stringify(destination.toString())}, ${JSON.stringify(target)})</script>`;
17
18
  }
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var shopifyApi = require('@shopify/shopify-api');
6
+
7
+ const FILE_URI_MATCH = /\/\/\//;
8
+ const INVALID_RELATIVE_URL = /[/\\][/\\]/;
9
+ const WHITESPACE_CHARACTER = /\s/;
10
+ const VALID_PROTOCOLS = ['https:', 'http:'];
11
+ function isSafe(domain, redirectUrl, requireSSL = true) {
12
+ if (typeof redirectUrl !== 'string') {
13
+ return false;
14
+ }
15
+ if (FILE_URI_MATCH.test(redirectUrl) || WHITESPACE_CHARACTER.test(redirectUrl)) {
16
+ return false;
17
+ }
18
+ let url;
19
+ try {
20
+ url = new URL(redirectUrl, domain);
21
+ } catch (error) {
22
+ return false;
23
+ }
24
+ if (INVALID_RELATIVE_URL.test(url.pathname)) {
25
+ return false;
26
+ }
27
+ if (!VALID_PROTOCOLS.includes(url.protocol)) {
28
+ return false;
29
+ }
30
+ if (requireSSL && url.protocol !== 'https:') {
31
+ return false;
32
+ }
33
+ return true;
34
+ }
35
+ function sanitizeRedirectUrl(domain, redirectUrl, options = {}) {
36
+ if (isSafe(domain, redirectUrl, options.requireSSL)) {
37
+ return new URL(redirectUrl, domain);
38
+ } else if (options.throwOnInvalid === false) {
39
+ return undefined;
40
+ } else {
41
+ throw new shopifyApi.ShopifyError('Invalid URL. Refusing to redirect');
42
+ }
43
+ }
44
+
45
+ exports.sanitizeRedirectUrl = sanitizeRedirectUrl;
@@ -2,6 +2,6 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const SHOPIFY_REMIX_LIBRARY_VERSION = '2.5.0';
5
+ const SHOPIFY_REMIX_LIBRARY_VERSION = '2.5.1';
6
6
 
7
7
  exports.SHOPIFY_REMIX_LIBRARY_VERSION = SHOPIFY_REMIX_LIBRARY_VERSION;
@@ -1 +1 @@
1
- {"version":3,"file":"render-app-bridge.d.ts","sourceRoot":"","sources":["../../../../../../src/server/authenticate/admin/helpers/render-app-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAI3C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,GAAG,CAAC;AAEtC,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IAClB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,wBAAgB,eAAe,CAC7B,EAAC,MAAM,EAAC,EAAE,WAAW,EACrB,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,iBAAiB,GAC7B,KAAK,CA2BP"}
1
+ {"version":3,"file":"render-app-bridge.d.ts","sourceRoot":"","sources":["../../../../../../src/server/authenticate/admin/helpers/render-app-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAM3C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,GAAG,CAAC;AAEtC,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IAClB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,wBAAgB,eAAe,CAC7B,EAAC,MAAM,EAAC,EAAE,WAAW,EACrB,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,iBAAiB,GAC7B,KAAK,CA4BP"}
@@ -3,12 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.renderAppBridge = void 0;
4
4
  var app_bridge_url_1 = require("../../helpers/app-bridge-url");
5
5
  var add_response_headers_1 = require("../../helpers/add-response-headers");
6
+ var validate_redirect_url_1 = require("./validate-redirect-url");
6
7
  function renderAppBridge(_a, request, redirectTo) {
7
8
  var _b;
8
9
  var config = _a.config;
9
10
  var redirectToScript = '';
10
11
  if (redirectTo) {
11
- var destination = new URL(redirectTo.url, config.appUrl);
12
+ var destination = (0, validate_redirect_url_1.sanitizeRedirectUrl)(config.appUrl, redirectTo.url);
12
13
  var target = (_b = redirectTo.target) !== null && _b !== void 0 ? _b : '_top';
13
14
  redirectToScript = "<script>window.open(".concat(JSON.stringify(destination.toString()), ", ").concat(JSON.stringify(target), ")</script>");
14
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"render-app-bridge.js","sourceRoot":"","sources":["../../../../../../src/server/authenticate/admin/helpers/render-app-bridge.ts"],"names":[],"mappings":";;;AACA,+DAA0D;AAC1D,2EAA8E;AAS9E,SAAgB,eAAe,CAC7B,EAAqB,EACrB,OAAgB,EAChB,UAA8B;;QAF7B,MAAM,YAAA;IAIP,IAAI,gBAAgB,GAAG,EAAE,CAAC;IAC1B,IAAI,UAAU,EAAE,CAAC;QACf,IAAM,WAAW,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAM,MAAM,GAAG,MAAA,UAAU,CAAC,MAAM,mCAAI,MAAM,CAAC;QAE3C,gBAAgB,GAAG,8BAAuB,IAAI,CAAC,SAAS,CACtD,WAAW,CAAC,QAAQ,EAAE,CACvB,eAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,eAAY,CAAC;IAC3C,CAAC;IAED,IAAM,eAAe,GAAG,IAAI,OAAO,CAAC;QAClC,cAAc,EAAE,yBAAyB;KAC1C,CAAC,CAAC;IACH,IAAA,iDAA0B,EACxB,eAAe,EACf,MAAM,CAAC,aAAa,EACpB,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAC9C,CAAC;IAEF,MAAM,IAAI,QAAQ,CAChB,yCAC0B,MAAM,CAAC,MAAM,sBAAU,IAAA,6BAAY,GAAE,iCAC3D,gBAAgB,WACnB,EACD,EAAC,OAAO,EAAE,eAAe,EAAC,CAC3B,CAAC;AACJ,CAAC;AA/BD,0CA+BC"}
1
+ {"version":3,"file":"render-app-bridge.js","sourceRoot":"","sources":["../../../../../../src/server/authenticate/admin/helpers/render-app-bridge.ts"],"names":[],"mappings":";;;AACA,+DAA0D;AAC1D,2EAA8E;AAE9E,iEAA4D;AAS5D,SAAgB,eAAe,CAC7B,EAAqB,EACrB,OAAgB,EAChB,UAA8B;;QAF7B,MAAM,YAAA;IAIP,IAAI,gBAAgB,GAAG,EAAE,CAAC;IAC1B,IAAI,UAAU,EAAE,CAAC;QACf,IAAM,WAAW,GAAG,IAAA,2CAAmB,EAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;QAEvE,IAAM,MAAM,GAAG,MAAA,UAAU,CAAC,MAAM,mCAAI,MAAM,CAAC;QAE3C,gBAAgB,GAAG,8BAAuB,IAAI,CAAC,SAAS,CACtD,WAAW,CAAC,QAAQ,EAAE,CACvB,eAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,eAAY,CAAC;IAC3C,CAAC;IAED,IAAM,eAAe,GAAG,IAAI,OAAO,CAAC;QAClC,cAAc,EAAE,yBAAyB;KAC1C,CAAC,CAAC;IACH,IAAA,iDAA0B,EACxB,eAAe,EACf,MAAM,CAAC,aAAa,EACpB,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAC9C,CAAC;IAEF,MAAM,IAAI,QAAQ,CAChB,yCAC0B,MAAM,CAAC,MAAM,sBAAU,IAAA,6BAAY,GAAE,iCAC3D,gBAAgB,WACnB,EACD,EAAC,OAAO,EAAE,eAAe,EAAC,CAC3B,CAAC;AACJ,CAAC;AAhCD,0CAgCC"}
@@ -0,0 +1,8 @@
1
+ interface Options {
2
+ requireSSL?: boolean;
3
+ throwOnInvalid?: boolean;
4
+ }
5
+ type SanitizedRedirectUrl<OptionsArg extends Options> = OptionsArg['throwOnInvalid'] extends false ? URL | undefined : URL;
6
+ export declare function sanitizeRedirectUrl<OptionsArg extends Options>(domain: string, redirectUrl: unknown, options?: OptionsArg): SanitizedRedirectUrl<OptionsArg>;
7
+ export {};
8
+ //# sourceMappingURL=validate-redirect-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-redirect-url.d.ts","sourceRoot":"","sources":["../../../../../../src/server/authenticate/admin/helpers/validate-redirect-url.ts"],"names":[],"mappings":"AAEA,UAAU,OAAO;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,KAAK,oBAAoB,CAAC,UAAU,SAAS,OAAO,IAClD,UAAU,CAAC,gBAAgB,CAAC,SAAS,KAAK,GAAG,GAAG,GAAG,SAAS,GAAG,GAAG,CAAC;AA8CrE,wBAAgB,mBAAmB,CAAC,UAAU,SAAS,OAAO,EAC5D,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,OAAO,EACpB,OAAO,GAAE,UAA6B,GACrC,oBAAoB,CAAC,UAAU,CAAC,CAQlC"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sanitizeRedirectUrl = void 0;
4
+ var shopify_api_1 = require("@shopify/shopify-api");
5
+ var FILE_URI_MATCH = /\/\/\//;
6
+ var INVALID_RELATIVE_URL = /[/\\][/\\]/;
7
+ var WHITESPACE_CHARACTER = /\s/;
8
+ var VALID_PROTOCOLS = ['https:', 'http:'];
9
+ function isSafe(domain, redirectUrl, requireSSL) {
10
+ if (requireSSL === void 0) { requireSSL = true; }
11
+ if (typeof redirectUrl !== 'string') {
12
+ return false;
13
+ }
14
+ if (FILE_URI_MATCH.test(redirectUrl) ||
15
+ WHITESPACE_CHARACTER.test(redirectUrl)) {
16
+ return false;
17
+ }
18
+ var url;
19
+ try {
20
+ url = new URL(redirectUrl, domain);
21
+ }
22
+ catch (error) {
23
+ return false;
24
+ }
25
+ if (INVALID_RELATIVE_URL.test(url.pathname)) {
26
+ return false;
27
+ }
28
+ if (!VALID_PROTOCOLS.includes(url.protocol)) {
29
+ return false;
30
+ }
31
+ if (requireSSL && url.protocol !== 'https:') {
32
+ return false;
33
+ }
34
+ return true;
35
+ }
36
+ function sanitizeRedirectUrl(domain, redirectUrl, options) {
37
+ if (options === void 0) { options = {}; }
38
+ if (isSafe(domain, redirectUrl, options.requireSSL)) {
39
+ return new URL(redirectUrl, domain);
40
+ }
41
+ else if (options.throwOnInvalid === false) {
42
+ return undefined;
43
+ }
44
+ else {
45
+ throw new shopify_api_1.ShopifyError('Invalid URL. Refusing to redirect');
46
+ }
47
+ }
48
+ exports.sanitizeRedirectUrl = sanitizeRedirectUrl;
49
+ //# sourceMappingURL=validate-redirect-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-redirect-url.js","sourceRoot":"","sources":["../../../../../../src/server/authenticate/admin/helpers/validate-redirect-url.ts"],"names":[],"mappings":";;;AAAA,oDAAkD;AAUlD,IAAM,cAAc,GAAG,QAAQ,CAAC;AAChC,IAAM,oBAAoB,GAAG,YAAY,CAAC;AAC1C,IAAM,oBAAoB,GAAG,IAAI,CAAC;AAClC,IAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAE5C,SAAS,MAAM,CACb,MAAc,EACd,WAAoB,EACpB,UAAsC;IAAtC,2BAAA,EAAA,iBAAsC;IAEtC,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IACE,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC;QAChC,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,EACtC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,GAAQ,CAAC;IAEb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,UAAU,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,mBAAmB,CACjC,MAAc,EACd,WAAoB,EACpB,OAAsC;IAAtC,wBAAA,EAAA,UAAsB,EAAgB;IAEtC,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACpD,OAAO,IAAI,GAAG,CAAC,WAAW,EAAE,MAAM,CAAqC,CAAC;IAC1E,CAAC;SAAM,IAAI,OAAO,CAAC,cAAc,KAAK,KAAK,EAAE,CAAC;QAC5C,OAAO,SAA6C,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,0BAAY,CAAC,mCAAmC,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AAZD,kDAYC"}
@@ -1,2 +1,2 @@
1
- export declare const SHOPIFY_REMIX_LIBRARY_VERSION = "2.5.0";
1
+ export declare const SHOPIFY_REMIX_LIBRARY_VERSION = "2.5.1";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SHOPIFY_REMIX_LIBRARY_VERSION = void 0;
4
- exports.SHOPIFY_REMIX_LIBRARY_VERSION = '2.5.0';
4
+ exports.SHOPIFY_REMIX_LIBRARY_VERSION = '2.5.1';
5
5
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopify/shopify-app-remix",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "Shopify Remix - to simplify the building of Shopify Apps with Remix",
5
5
  "repository": {
6
6
  "type": "git",