@shopify/shopify-app-remix 4.0.6 → 4.1.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.
- package/dist/cjs/server/adapters/node/index.js +0 -1
- package/dist/cjs/server/adapters/node/index.js.map +1 -1
- package/dist/cjs/server/authenticate/admin/authenticate.js +0 -1
- package/dist/cjs/server/authenticate/admin/authenticate.js.map +1 -1
- package/dist/cjs/server/authenticate/admin/billing/cancel.js +0 -1
- package/dist/cjs/server/authenticate/admin/billing/cancel.js.map +1 -1
- package/dist/cjs/server/authenticate/admin/billing/check.js +0 -1
- package/dist/cjs/server/authenticate/admin/billing/check.js.map +1 -1
- package/dist/cjs/server/authenticate/admin/billing/create-usage-record.js +0 -1
- package/dist/cjs/server/authenticate/admin/billing/create-usage-record.js.map +1 -1
- package/dist/cjs/server/authenticate/admin/billing/request.js +0 -1
- package/dist/cjs/server/authenticate/admin/billing/request.js.map +1 -1
- package/dist/cjs/server/authenticate/admin/billing/require.js +0 -1
- package/dist/cjs/server/authenticate/admin/billing/require.js.map +1 -1
- package/dist/cjs/server/authenticate/admin/billing/update-usage-subscription-capped-amount.js +0 -1
- package/dist/cjs/server/authenticate/admin/billing/update-usage-subscription-capped-amount.js.map +1 -1
- package/dist/cjs/server/authenticate/admin/strategies/auth-code-flow.js +1 -1
- package/dist/cjs/server/authenticate/admin/strategies/auth-code-flow.js.map +1 -1
- package/dist/cjs/server/authenticate/admin/strategies/merchant-custom-app.js +0 -1
- package/dist/cjs/server/authenticate/admin/strategies/merchant-custom-app.js.map +1 -1
- package/dist/cjs/server/authenticate/admin/strategies/token-exchange.js +5 -2
- package/dist/cjs/server/authenticate/admin/strategies/token-exchange.js.map +1 -1
- package/dist/cjs/server/authenticate/flow/authenticate.js +5 -3
- package/dist/cjs/server/authenticate/flow/authenticate.js.map +1 -1
- package/dist/cjs/server/authenticate/fulfillment-service/authenticate.js +3 -4
- package/dist/cjs/server/authenticate/fulfillment-service/authenticate.js.map +1 -1
- package/dist/cjs/server/authenticate/public/appProxy/authenticate.js +5 -3
- package/dist/cjs/server/authenticate/public/appProxy/authenticate.js.map +1 -1
- package/dist/cjs/server/authenticate/public/extension/authenticate.js +0 -1
- package/dist/cjs/server/authenticate/public/extension/authenticate.js.map +1 -1
- package/dist/cjs/server/authenticate/webhooks/authenticate.js +3 -3
- package/dist/cjs/server/authenticate/webhooks/authenticate.js.map +1 -1
- package/dist/cjs/server/future/flags.js.map +1 -1
- package/dist/cjs/server/{authenticate/helpers → helpers}/create-or-load-offline-session.js +2 -2
- package/dist/cjs/server/helpers/create-or-load-offline-session.js.map +1 -0
- package/dist/cjs/server/helpers/ensure-offline-token-is-not-expired.js +23 -0
- package/dist/cjs/server/helpers/ensure-offline-token-is-not-expired.js.map +1 -0
- package/dist/cjs/server/helpers/ensure-valid-offline-session.js +14 -0
- package/dist/cjs/server/helpers/ensure-valid-offline-session.js.map +1 -0
- package/dist/cjs/server/helpers/refresh-token.js +31 -0
- package/dist/cjs/server/helpers/refresh-token.js.map +1 -0
- package/dist/cjs/server/unauthenticated/admin/factory.js +4 -2
- package/dist/cjs/server/unauthenticated/admin/factory.js.map +1 -1
- package/dist/cjs/server/unauthenticated/storefront/factory.js +4 -2
- package/dist/cjs/server/unauthenticated/storefront/factory.js.map +1 -1
- package/dist/cjs/server/version.js +1 -1
- package/dist/cjs/server/version.js.map +1 -1
- package/dist/esm/server/adapters/node/index.mjs +0 -1
- package/dist/esm/server/adapters/node/index.mjs.map +1 -1
- package/dist/esm/server/authenticate/admin/authenticate.mjs +0 -1
- package/dist/esm/server/authenticate/admin/authenticate.mjs.map +1 -1
- package/dist/esm/server/authenticate/admin/billing/cancel.mjs +0 -1
- package/dist/esm/server/authenticate/admin/billing/cancel.mjs.map +1 -1
- package/dist/esm/server/authenticate/admin/billing/check.mjs +0 -1
- package/dist/esm/server/authenticate/admin/billing/check.mjs.map +1 -1
- package/dist/esm/server/authenticate/admin/billing/create-usage-record.mjs +0 -1
- package/dist/esm/server/authenticate/admin/billing/create-usage-record.mjs.map +1 -1
- package/dist/esm/server/authenticate/admin/billing/request.mjs +0 -1
- package/dist/esm/server/authenticate/admin/billing/request.mjs.map +1 -1
- package/dist/esm/server/authenticate/admin/billing/require.mjs +0 -1
- package/dist/esm/server/authenticate/admin/billing/require.mjs.map +1 -1
- package/dist/esm/server/authenticate/admin/billing/update-usage-subscription-capped-amount.mjs +0 -1
- package/dist/esm/server/authenticate/admin/billing/update-usage-subscription-capped-amount.mjs.map +1 -1
- package/dist/esm/server/authenticate/admin/strategies/auth-code-flow.mjs +1 -1
- package/dist/esm/server/authenticate/admin/strategies/auth-code-flow.mjs.map +1 -1
- package/dist/esm/server/authenticate/admin/strategies/merchant-custom-app.mjs +0 -1
- package/dist/esm/server/authenticate/admin/strategies/merchant-custom-app.mjs.map +1 -1
- package/dist/esm/server/authenticate/admin/strategies/token-exchange.mjs +5 -2
- package/dist/esm/server/authenticate/admin/strategies/token-exchange.mjs.map +1 -1
- package/dist/esm/server/authenticate/flow/authenticate.mjs +5 -3
- package/dist/esm/server/authenticate/flow/authenticate.mjs.map +1 -1
- package/dist/esm/server/authenticate/fulfillment-service/authenticate.mjs +3 -4
- package/dist/esm/server/authenticate/fulfillment-service/authenticate.mjs.map +1 -1
- package/dist/esm/server/authenticate/public/appProxy/authenticate.mjs +5 -3
- package/dist/esm/server/authenticate/public/appProxy/authenticate.mjs.map +1 -1
- package/dist/esm/server/authenticate/public/extension/authenticate.mjs +0 -1
- package/dist/esm/server/authenticate/public/extension/authenticate.mjs.map +1 -1
- package/dist/esm/server/authenticate/webhooks/authenticate.mjs +3 -3
- package/dist/esm/server/authenticate/webhooks/authenticate.mjs.map +1 -1
- package/dist/esm/server/future/flags.mjs.map +1 -1
- package/dist/esm/server/{authenticate/helpers → helpers}/create-or-load-offline-session.mjs +2 -2
- package/dist/esm/server/helpers/create-or-load-offline-session.mjs.map +1 -0
- package/dist/esm/server/helpers/ensure-offline-token-is-not-expired.mjs +20 -0
- package/dist/esm/server/helpers/ensure-offline-token-is-not-expired.mjs.map +1 -0
- package/dist/esm/server/helpers/ensure-valid-offline-session.mjs +12 -0
- package/dist/esm/server/helpers/ensure-valid-offline-session.mjs.map +1 -0
- package/dist/esm/server/helpers/refresh-token.mjs +27 -0
- package/dist/esm/server/helpers/refresh-token.mjs.map +1 -0
- package/dist/esm/server/unauthenticated/admin/factory.mjs +4 -2
- package/dist/esm/server/unauthenticated/admin/factory.mjs.map +1 -1
- package/dist/esm/server/unauthenticated/storefront/factory.mjs +4 -2
- package/dist/esm/server/unauthenticated/storefront/factory.mjs.map +1 -1
- package/dist/esm/server/version.mjs +1 -1
- package/dist/esm/server/version.mjs.map +1 -1
- package/dist/ts/server/authenticate/admin/strategies/auth-code-flow.d.ts.map +1 -1
- package/dist/ts/server/authenticate/admin/strategies/token-exchange.d.ts.map +1 -1
- package/dist/ts/server/authenticate/flow/authenticate.d.ts.map +1 -1
- package/dist/ts/server/authenticate/helpers/index.d.ts +0 -1
- package/dist/ts/server/authenticate/helpers/index.d.ts.map +1 -1
- package/dist/ts/server/authenticate/public/appProxy/authenticate.d.ts.map +1 -1
- package/dist/ts/server/future/flags.d.ts +8 -1
- package/dist/ts/server/future/flags.d.ts.map +1 -1
- package/dist/ts/server/helpers/create-or-load-offline-session.d.ts +3 -0
- package/dist/ts/server/helpers/create-or-load-offline-session.d.ts.map +1 -0
- package/dist/ts/server/helpers/ensure-offline-token-is-not-expired.d.ts +5 -0
- package/dist/ts/server/helpers/ensure-offline-token-is-not-expired.d.ts.map +1 -0
- package/dist/ts/server/helpers/ensure-valid-offline-session.d.ts +3 -0
- package/dist/ts/server/helpers/ensure-valid-offline-session.d.ts.map +1 -0
- package/dist/ts/server/helpers/index.d.ts +5 -0
- package/dist/ts/server/helpers/index.d.ts.map +1 -0
- package/dist/ts/server/helpers/refresh-token.d.ts +4 -0
- package/dist/ts/server/helpers/refresh-token.d.ts.map +1 -0
- package/dist/ts/server/unauthenticated/storefront/factory.d.ts.map +1 -1
- package/dist/ts/server/version.d.ts +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/dist/cjs/server/authenticate/helpers/create-or-load-offline-session.js.map +0 -1
- package/dist/esm/server/authenticate/helpers/create-or-load-offline-session.mjs.map +0 -1
- package/dist/ts/server/authenticate/helpers/create-or-load-offline-session.d.ts +0 -3
- package/dist/ts/server/authenticate/helpers/create-or-load-offline-session.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticate.js","sources":["../../../../../../../src/server/authenticate/public/appProxy/authenticate.ts"],"sourcesContent":["import {adminClientFactory, storefrontClientFactory} from '../../../clients';\nimport {BasicParams} from '../../../types';\n\nimport {\n AppProxyContext,\n AppProxyContextWithSession,\n AuthenticateAppProxy,\n LiquidResponseFunction,\n} from './types';\n\nexport function authenticateAppProxyFactory(\n params: BasicParams,\n): AuthenticateAppProxy {\n const {
|
|
1
|
+
{"version":3,"file":"authenticate.js","sources":["../../../../../../../src/server/authenticate/public/appProxy/authenticate.ts"],"sourcesContent":["import {adminClientFactory, storefrontClientFactory} from '../../../clients';\nimport {ensureValidOfflineSession} from '../../../helpers';\nimport {BasicParams} from '../../../types';\n\nimport {\n AppProxyContext,\n AppProxyContextWithSession,\n AuthenticateAppProxy,\n LiquidResponseFunction,\n} from './types';\n\nexport function authenticateAppProxyFactory(\n params: BasicParams,\n): AuthenticateAppProxy {\n const {logger} = params;\n\n return async function authenticate(\n request: Request,\n ): Promise<AppProxyContext | AppProxyContextWithSession> {\n const url = new URL(request.url);\n const shop = url.searchParams.get('shop')!;\n logger.info('Authenticating app proxy request', {shop});\n\n if (!(await validateAppProxyHmac(params, url))) {\n logger.info('App proxy request has invalid signature', {shop});\n throw new Response(undefined, {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n const session = await ensureValidOfflineSession(params, shop);\n\n if (!session) {\n logger.debug('Could not find offline session, returning empty context', {\n shop,\n ...Object.fromEntries(url.searchParams.entries()),\n });\n\n const context: AppProxyContext = {\n liquid,\n session: undefined,\n admin: undefined,\n storefront: undefined,\n };\n\n return context;\n }\n\n const context: AppProxyContextWithSession = {\n liquid,\n session,\n admin: adminClientFactory({params, session}),\n storefront: storefrontClientFactory({params, session}),\n };\n\n return context;\n };\n}\n\nconst liquid: LiquidResponseFunction = (body, initAndOptions) => {\n const processedBody = processLiquidBody(body);\n\n if (typeof initAndOptions !== 'object') {\n return new Response(processedBody, {\n status: initAndOptions || 200,\n headers: {\n 'Content-Type': 'application/liquid',\n },\n });\n }\n\n const {layout, ...responseInit} = initAndOptions || {};\n const responseBody =\n layout === false ? `{% layout none %} ${processedBody}` : processedBody;\n\n const headers = new Headers(responseInit.headers);\n headers.set('Content-Type', 'application/liquid');\n\n return new Response(responseBody, {\n ...responseInit,\n headers,\n });\n};\n\nasync function validateAppProxyHmac(\n params: BasicParams,\n url: URL,\n): Promise<boolean> {\n const {api, logger} = params;\n\n try {\n let searchParams = new URLSearchParams(url.search);\n if (!searchParams.get('index')) {\n searchParams.delete('index');\n }\n\n let isValid = await api.utils.validateHmac(\n Object.fromEntries(searchParams.entries()),\n {signator: 'appProxy'},\n );\n\n if (!isValid) {\n const cleanPath = url.pathname\n .replace(/^\\//, '')\n .replace(/\\/$/, '')\n .replaceAll('/', '.');\n const data = `routes%2F${cleanPath}`;\n\n searchParams = new URLSearchParams(\n `?_data=${data}&${searchParams.toString().replace(/^\\?/, '')}`,\n );\n\n isValid = await api.utils.validateHmac(\n Object.fromEntries(searchParams.entries()),\n {signator: 'appProxy'},\n );\n\n if (!isValid) {\n const searchParams = new URLSearchParams(\n `?_data=${data}._index&${url.search.replace(/^\\?/, '')}`,\n );\n\n isValid = await api.utils.validateHmac(\n Object.fromEntries(searchParams.entries()),\n {signator: 'appProxy'},\n );\n }\n }\n\n return isValid;\n } catch (error) {\n const shop = url.searchParams.get('shop')!;\n logger.info(error.message, {shop});\n throw new Response(undefined, {status: 400, statusText: 'Bad Request'});\n }\n}\n\nfunction processLiquidBody(body: string) {\n return (\n body\n // Add trailing slashes to relative form action URLs\n .replaceAll(\n /<(form[^>]+)action=\"(\\/[^\"?]+)(\\?[^\"]+)?\">/g,\n '<$1action=\"$2/$3\">',\n )\n // Add trailing slashes to relative link href URLs\n .replaceAll(/<(a[^>]+)href=\"(\\/[^\"?]+)(\\?[^\"]+)?\">/g, '<$1href=\"$2/$3\">')\n );\n}\n"],"names":["ensureValidOfflineSession","adminClientFactory","storefrontClientFactory"],"mappings":";;;;;;;;AAWM,SAAU,2BAA2B,CACzC,MAAmB,EAAA;AAEnB,IAAA,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM;AAEvB,IAAA,OAAO,eAAe,YAAY,CAChC,OAAgB,EAAA;QAEhB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;QAChC,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAE;QAC1C,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,EAAC,IAAI,EAAC,CAAC;QAEvD,IAAI,EAAE,MAAM,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE;YAC9C,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE,EAAC,IAAI,EAAC,CAAC;AAC9D,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,aAAa;AAC1B,aAAA,CAAC;QACJ;QAEA,MAAM,OAAO,GAAG,MAAMA,mDAAyB,CAAC,MAAM,EAAE,IAAI,CAAC;QAE7D,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,MAAM,CAAC,KAAK,CAAC,yDAAyD,EAAE;gBACtE,IAAI;gBACJ,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;AAClD,aAAA,CAAC;AAEF,YAAA,MAAM,OAAO,GAAoB;gBAC/B,MAAM;AACN,gBAAA,OAAO,EAAE,SAAS;AAClB,gBAAA,KAAK,EAAE,SAAS;AAChB,gBAAA,UAAU,EAAE,SAAS;aACtB;AAED,YAAA,OAAO,OAAO;QAChB;AAEA,QAAA,MAAM,OAAO,GAA+B;YAC1C,MAAM;YACN,OAAO;YACP,KAAK,EAAEC,4BAAkB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;YAC5C,UAAU,EAAEC,+BAAuB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;SACvD;AAED,QAAA,OAAO,OAAO;AAChB,IAAA,CAAC;AACH;AAEA,MAAM,MAAM,GAA2B,CAAC,IAAI,EAAE,cAAc,KAAI;AAC9D,IAAA,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC;AAE7C,IAAA,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE;AACtC,QAAA,OAAO,IAAI,QAAQ,CAAC,aAAa,EAAE;YACjC,MAAM,EAAE,cAAc,IAAI,GAAG;AAC7B,YAAA,OAAO,EAAE;AACP,gBAAA,cAAc,EAAE,oBAAoB;AACrC,aAAA;AACF,SAAA,CAAC;IACJ;IAEA,MAAM,EAAC,MAAM,EAAE,GAAG,YAAY,EAAC,GAAG,cAAc,IAAI,EAAE;AACtD,IAAA,MAAM,YAAY,GAChB,MAAM,KAAK,KAAK,GAAG,CAAA,kBAAA,EAAqB,aAAa,CAAA,CAAE,GAAG,aAAa;IAEzE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC;AACjD,IAAA,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,oBAAoB,CAAC;AAEjD,IAAA,OAAO,IAAI,QAAQ,CAAC,YAAY,EAAE;AAChC,QAAA,GAAG,YAAY;QACf,OAAO;AACR,KAAA,CAAC;AACJ,CAAC;AAED,eAAe,oBAAoB,CACjC,MAAmB,EACnB,GAAQ,EAAA;AAER,IAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,IAAA,IAAI;QACF,IAAI,YAAY,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC;QAClD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;AAC9B,YAAA,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC;QAC9B;QAEA,IAAI,OAAO,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,YAAY,CACxC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,EAC1C,EAAC,QAAQ,EAAE,UAAU,EAAC,CACvB;QAED,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,MAAM,SAAS,GAAG,GAAG,CAAC;AACnB,iBAAA,OAAO,CAAC,KAAK,EAAE,EAAE;AACjB,iBAAA,OAAO,CAAC,KAAK,EAAE,EAAE;AACjB,iBAAA,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;AACvB,YAAA,MAAM,IAAI,GAAG,CAAA,SAAA,EAAY,SAAS,EAAE;YAEpC,YAAY,GAAG,IAAI,eAAe,CAChC,UAAU,IAAI,CAAA,CAAA,EAAI,YAAY,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA,CAAE,CAC/D;YAED,OAAO,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,YAAY,CACpC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,EAC1C,EAAC,QAAQ,EAAE,UAAU,EAAC,CACvB;YAED,IAAI,CAAC,OAAO,EAAE;gBACZ,MAAM,YAAY,GAAG,IAAI,eAAe,CACtC,CAAA,OAAA,EAAU,IAAI,WAAW,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA,CAAE,CACzD;gBAED,OAAO,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,YAAY,CACpC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,EAC1C,EAAC,QAAQ,EAAE,UAAU,EAAC,CACvB;YACH;QACF;AAEA,QAAA,OAAO,OAAO;IAChB;IAAE,OAAO,KAAK,EAAE;QACd,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAE;QAC1C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAC,IAAI,EAAC,CAAC;AAClC,QAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAC,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,aAAa,EAAC,CAAC;IACzE;AACF;AAEA,SAAS,iBAAiB,CAAC,IAAY,EAAA;AACrC,IAAA,QACE;;AAEG,SAAA,UAAU,CACT,6CAA6C,EAC7C,oBAAoB;;AAGrB,SAAA,UAAU,CAAC,wCAAwC,EAAE,kBAAkB,CAAC;AAE/E;;;;"}
|
|
@@ -6,7 +6,6 @@ var getSessionTokenHeader = require('../../helpers/get-session-token-header.js')
|
|
|
6
6
|
var rejectBotRequest = require('../../helpers/reject-bot-request.js');
|
|
7
7
|
var respondToOptionsRequest = require('../../helpers/respond-to-options-request.js');
|
|
8
8
|
require('@remix-run/server-runtime');
|
|
9
|
-
require('../../../types.js');
|
|
10
9
|
var getShopFromRequest = require('../../helpers/get-shop-from-request.js');
|
|
11
10
|
|
|
12
11
|
function authenticateExtensionFactory(params, requestType) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticate.js","sources":["../../../../../../../src/server/authenticate/public/extension/authenticate.ts"],"sourcesContent":["import {BasicParams} from '../../../types';\nimport {\n respondToBotRequest,\n respondToOptionsRequest,\n getSessionTokenHeader,\n validateSessionToken,\n ensureCORSHeadersFactory,\n getShopFromRequest,\n} from '../../helpers';\n\nimport {AuthenticateExtension, ExtensionContext} from './types';\n\nexport function authenticateExtensionFactory(\n params: BasicParams,\n requestType: string,\n): AuthenticateExtension {\n return async function authenticateExtension(\n request,\n options = {},\n ): Promise<ExtensionContext> {\n const {logger} = params;\n\n const corsHeaders = options.corsHeaders ?? [];\n\n respondToBotRequest(params, request);\n respondToOptionsRequest(params, request, corsHeaders);\n\n const sessionTokenHeader = getSessionTokenHeader(request);\n\n logger.info(`Authenticating ${requestType} request`, {\n shop: getShopFromRequest(request),\n });\n\n if (!sessionTokenHeader) {\n logger.debug('Request did not contain a session token', {\n shop: getShopFromRequest(request),\n });\n throw new Response(undefined, {\n status: 401,\n statusText: 'Unauthorized',\n });\n }\n\n return {\n sessionToken: await validateSessionToken(\n params,\n request,\n sessionTokenHeader,\n {checkAudience: false, retryRequest: false},\n ),\n cors: ensureCORSHeadersFactory(params, request, corsHeaders),\n };\n };\n}\n"],"names":["respondToBotRequest","respondToOptionsRequest","getSessionTokenHeader","getShopFromRequest","validateSessionToken","ensureCORSHeadersFactory"],"mappings":"
|
|
1
|
+
{"version":3,"file":"authenticate.js","sources":["../../../../../../../src/server/authenticate/public/extension/authenticate.ts"],"sourcesContent":["import {BasicParams} from '../../../types';\nimport {\n respondToBotRequest,\n respondToOptionsRequest,\n getSessionTokenHeader,\n validateSessionToken,\n ensureCORSHeadersFactory,\n getShopFromRequest,\n} from '../../helpers';\n\nimport {AuthenticateExtension, ExtensionContext} from './types';\n\nexport function authenticateExtensionFactory(\n params: BasicParams,\n requestType: string,\n): AuthenticateExtension {\n return async function authenticateExtension(\n request,\n options = {},\n ): Promise<ExtensionContext> {\n const {logger} = params;\n\n const corsHeaders = options.corsHeaders ?? [];\n\n respondToBotRequest(params, request);\n respondToOptionsRequest(params, request, corsHeaders);\n\n const sessionTokenHeader = getSessionTokenHeader(request);\n\n logger.info(`Authenticating ${requestType} request`, {\n shop: getShopFromRequest(request),\n });\n\n if (!sessionTokenHeader) {\n logger.debug('Request did not contain a session token', {\n shop: getShopFromRequest(request),\n });\n throw new Response(undefined, {\n status: 401,\n statusText: 'Unauthorized',\n });\n }\n\n return {\n sessionToken: await validateSessionToken(\n params,\n request,\n sessionTokenHeader,\n {checkAudience: false, retryRequest: false},\n ),\n cors: ensureCORSHeadersFactory(params, request, corsHeaders),\n };\n };\n}\n"],"names":["respondToBotRequest","respondToOptionsRequest","getSessionTokenHeader","getShopFromRequest","validateSessionToken","ensureCORSHeadersFactory"],"mappings":";;;;;;;;;;AAYM,SAAU,4BAA4B,CAC1C,MAAmB,EACnB,WAAmB,EAAA;IAEnB,OAAO,eAAe,qBAAqB,CACzC,OAAO,EACP,OAAO,GAAG,EAAE,EAAA;AAEZ,QAAA,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM;AAEvB,QAAA,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE;AAE7C,QAAAA,oCAAmB,CAAC,MAAM,EAAE,OAAO,CAAC;AACpC,QAAAC,+CAAuB,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC;AAErD,QAAA,MAAM,kBAAkB,GAAGC,2CAAqB,CAAC,OAAO,CAAC;AAEzD,QAAA,MAAM,CAAC,IAAI,CAAC,CAAA,eAAA,EAAkB,WAAW,UAAU,EAAE;AACnD,YAAA,IAAI,EAAEC,qCAAkB,CAAC,OAAO,CAAC;AAClC,SAAA,CAAC;QAEF,IAAI,CAAC,kBAAkB,EAAE;AACvB,YAAA,MAAM,CAAC,KAAK,CAAC,yCAAyC,EAAE;AACtD,gBAAA,IAAI,EAAEA,qCAAkB,CAAC,OAAO,CAAC;AAClC,aAAA,CAAC;AACF,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,cAAc;AAC3B,aAAA,CAAC;QACJ;QAEA,OAAO;AACL,YAAA,YAAY,EAAE,MAAMC,yCAAoB,CACtC,MAAM,EACN,OAAO,EACP,kBAAkB,EAClB,EAAC,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAC,CAC5C;YACD,IAAI,EAAEC,0CAAwB,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC;SAC7D;AACH,IAAA,CAAC;AACH;;;;"}
|
|
@@ -4,8 +4,8 @@ var shopifyApi = require('@shopify/shopify-api');
|
|
|
4
4
|
var factory = require('../../clients/admin/factory.js');
|
|
5
5
|
require('@remix-run/server-runtime');
|
|
6
6
|
var handleClientError = require('../admin/helpers/handle-client-error.js');
|
|
7
|
-
require('
|
|
8
|
-
|
|
7
|
+
var ensureValidOfflineSession = require('../../helpers/ensure-valid-offline-session.js');
|
|
8
|
+
require('../../types.js');
|
|
9
9
|
|
|
10
10
|
function authenticateWebhookFactory(params) {
|
|
11
11
|
const { api, logger } = params;
|
|
@@ -35,7 +35,7 @@ function authenticateWebhookFactory(params) {
|
|
|
35
35
|
throw new Response(undefined, { status: 400, statusText: 'Bad Request' });
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
const session = await
|
|
38
|
+
const session = await ensureValidOfflineSession.ensureValidOfflineSession(params, check.domain);
|
|
39
39
|
const webhookContext = {
|
|
40
40
|
apiVersion: check.apiVersion,
|
|
41
41
|
shop: check.domain,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticate.js","sources":["../../../../../../src/server/authenticate/webhooks/authenticate.ts"],"sourcesContent":["import {WebhookValidationErrorReason} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../types';\nimport {adminClientFactory} from '../../clients';\nimport {handleClientErrorFactory} from '../admin/helpers';\nimport {
|
|
1
|
+
{"version":3,"file":"authenticate.js","sources":["../../../../../../src/server/authenticate/webhooks/authenticate.ts"],"sourcesContent":["import {WebhookValidationErrorReason} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../types';\nimport {adminClientFactory} from '../../clients';\nimport {handleClientErrorFactory} from '../admin/helpers';\nimport {ensureValidOfflineSession} from '../../helpers';\n\nimport type {\n AuthenticateWebhook,\n WebhookContext,\n WebhookContextWithoutSession,\n} from './types';\n\nexport function authenticateWebhookFactory<Topics extends string>(\n params: BasicParams,\n): AuthenticateWebhook<Topics> {\n const {api, logger} = params;\n\n return async function authenticate(\n request: Request,\n ): Promise<WebhookContext<Topics>> {\n if (request.method !== 'POST') {\n logger.debug(\n 'Received a non-POST request for a webhook. Only POST requests are allowed.',\n {url: request.url, method: request.method},\n );\n throw new Response(undefined, {\n status: 405,\n statusText: 'Method not allowed',\n });\n }\n\n const rawBody = await request.text();\n\n const check = await api.webhooks.validate({\n rawBody,\n rawRequest: request,\n });\n\n if (!check.valid) {\n if (check.reason === WebhookValidationErrorReason.InvalidHmac) {\n logger.debug('Webhook HMAC validation failed', check);\n throw new Response(undefined, {\n status: 401,\n statusText: 'Unauthorized',\n });\n } else {\n logger.debug('Webhook validation failed', check);\n throw new Response(undefined, {status: 400, statusText: 'Bad Request'});\n }\n }\n const session = await ensureValidOfflineSession(params, check.domain);\n const webhookContext: WebhookContextWithoutSession<Topics> = {\n apiVersion: check.apiVersion,\n shop: check.domain,\n topic: check.topic as Topics,\n webhookId: check.webhookId,\n payload: JSON.parse(rawBody),\n subTopic: check.subTopic || undefined,\n session: undefined,\n admin: undefined,\n };\n\n if (!session) {\n return webhookContext;\n }\n\n const admin = adminClientFactory({\n params,\n session,\n handleClientError: handleClientErrorFactory({request}),\n });\n\n return {\n ...webhookContext,\n session,\n admin,\n };\n };\n}\n"],"names":["WebhookValidationErrorReason","ensureValidOfflineSession","adminClientFactory","handleClientErrorFactory"],"mappings":";;;;;;;;;AAaM,SAAU,0BAA0B,CACxC,MAAmB,EAAA;AAEnB,IAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,IAAA,OAAO,eAAe,YAAY,CAChC,OAAgB,EAAA;AAEhB,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE;AAC7B,YAAA,MAAM,CAAC,KAAK,CACV,4EAA4E,EAC5E,EAAC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAC,CAC3C;AACD,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,oBAAoB;AACjC,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE;QAEpC,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACxC,OAAO;AACP,YAAA,UAAU,EAAE,OAAO;AACpB,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;YAChB,IAAI,KAAK,CAAC,MAAM,KAAKA,uCAA4B,CAAC,WAAW,EAAE;AAC7D,gBAAA,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC;AACrD,gBAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,oBAAA,MAAM,EAAE,GAAG;AACX,oBAAA,UAAU,EAAE,cAAc;AAC3B,iBAAA,CAAC;YACJ;iBAAO;AACL,gBAAA,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC;AAChD,gBAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAC,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,aAAa,EAAC,CAAC;YACzE;QACF;QACA,MAAM,OAAO,GAAG,MAAMC,mDAAyB,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;AACrE,QAAA,MAAM,cAAc,GAAyC;YAC3D,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,IAAI,EAAE,KAAK,CAAC,MAAM;YAClB,KAAK,EAAE,KAAK,CAAC,KAAe;YAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;AAC1B,YAAA,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AAC5B,YAAA,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS;AACrC,YAAA,OAAO,EAAE,SAAS;AAClB,YAAA,KAAK,EAAE,SAAS;SACjB;QAED,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,OAAO,cAAc;QACvB;QAEA,MAAM,KAAK,GAAGC,0BAAkB,CAAC;YAC/B,MAAM;YACN,OAAO;AACP,YAAA,iBAAiB,EAAEC,0CAAwB,CAAC,EAAC,OAAO,EAAC,CAAC;AACvD,SAAA,CAAC;QAEF,OAAO;AACL,YAAA,GAAG,cAAc;YACjB,OAAO;YACP,KAAK;SACN;AACH,IAAA,CAAC;AACH;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flags.js","sources":["../../../../../src/server/future/flags.ts"],"sourcesContent":["import type {ConfigParams, Shopify} from '@shopify/shopify-api';\n\nimport {AppConfig} from '../config-types';\n\n// When adding new flags, you should also add them to the `TEST_FUTURE_FLAGS` object in `test-config.ts` to ensure that\n// it doesn't cause regressions.\nexport interface FutureFlags {\n /**\n * When enabled, embedded apps will fetch access tokens via [token exchange](https://shopify.dev/docs/apps/auth/get-access-tokens/token-exchange).\n * This assumes the app has scopes declared for [Shopify managing installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation).\n *\n * Learn more about this [new embedded app auth strategy](https://shopify.dev/docs/api/shopify-app-remix#embedded-auth-strategy).\n *\n * @default false\n */\n unstable_newEmbeddedAuthStrategy?: boolean;\n}\n\n// When adding new flags, use this format:\n// apiFutureFlag: Future extends FutureFlags ? Future['remixFutureFlag'] : false;\nexport interface ApiFutureFlags<
|
|
1
|
+
{"version":3,"file":"flags.js","sources":["../../../../../src/server/future/flags.ts"],"sourcesContent":["import type {ConfigParams, Shopify} from '@shopify/shopify-api';\n\nimport {AppConfig} from '../config-types';\n\n// When adding new flags, you should also add them to the `TEST_FUTURE_FLAGS` object in `test-config.ts` to ensure that\n// it doesn't cause regressions.\nexport interface FutureFlags {\n /**\n * When enabled, embedded apps will fetch access tokens via [token exchange](https://shopify.dev/docs/apps/auth/get-access-tokens/token-exchange).\n * This assumes the app has scopes declared for [Shopify managing installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation).\n *\n * Learn more about this [new embedded app auth strategy](https://shopify.dev/docs/api/shopify-app-remix#embedded-auth-strategy).\n *\n * @default false\n */\n unstable_newEmbeddedAuthStrategy?: boolean;\n /**\n * When enabled, the app will start using expiring offline access tokens and automatically refresh them when they are close to expiring.\n *\n * @default false\n */\n expiringOfflineAccessTokens?: boolean;\n}\n\n// When adding new flags, use this format:\n// apiFutureFlag: Future extends FutureFlags ? Future['remixFutureFlag'] : false;\nexport interface ApiFutureFlags<Future extends FutureFlagOptions> {\n expiringOfflineAccessTokens: Future extends FutureFlags\n ? Future['expiringOfflineAccessTokens']\n : false;\n unstable_managedPricingSupport: true;\n}\n\nexport type ApiConfigWithFutureFlags<Future extends FutureFlagOptions> =\n ConfigParams<ApiFutureFlags<Future>>;\n\nexport type FutureFlagOptions = FutureFlags | undefined;\n\nexport type FeatureEnabled<\n Future extends FutureFlagOptions,\n Flag extends keyof FutureFlags,\n> = Future extends FutureFlags\n ? Future[Flag] extends true\n ? true\n : false\n : false;\n\nexport function logDisabledFutureFlags(\n config: AppConfig,\n logger: Shopify['logger'],\n) {\n const logFlag = (flag: string, message: string) =>\n logger.info(`Future flag ${flag} is disabled.\\n\\n ${message}\\n`);\n\n if (!config.future.unstable_newEmbeddedAuthStrategy) {\n logFlag(\n 'unstable_newEmbeddedAuthStrategy',\n 'Enable this to use OAuth token exchange instead of auth code to generate API access tokens.' +\n '\\n Your app must be using Shopify managed install: https://shopify.dev/docs/apps/auth/installation',\n );\n }\n}\n"],"names":[],"mappings":";;AA+CM,SAAU,sBAAsB,CACpC,MAAiB,EACjB,MAAyB,EAAA;AAEzB,IAAA,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,OAAe,KAC5C,MAAM,CAAC,IAAI,CAAC,CAAA,YAAA,EAAe,IAAI,sBAAsB,OAAO,CAAA,EAAA,CAAI,CAAC;AAEnE,IAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,gCAAgC,EAAE;QACnD,OAAO,CACL,kCAAkC,EAClC,6FAA6F;AAC3F,YAAA,qGAAqG,CACxG;IACH;AACF;;;;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var types = require('
|
|
3
|
+
var types = require('../types.js');
|
|
4
4
|
|
|
5
|
-
async function createOrLoadOfflineSession(
|
|
5
|
+
async function createOrLoadOfflineSession({ api, config, logger }, shop) {
|
|
6
6
|
if (config.distribution === types.AppDistribution.ShopifyAdmin) {
|
|
7
7
|
logger.debug('Creating custom app session from configured access token', {
|
|
8
8
|
shop,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-or-load-offline-session.js","sources":["../../../../../src/server/helpers/create-or-load-offline-session.ts"],"sourcesContent":["import {AppDistribution, BasicParams} from '../types';\n\nexport async function createOrLoadOfflineSession(\n {api, config, logger}: BasicParams,\n shop: string,\n) {\n if (config.distribution === AppDistribution.ShopifyAdmin) {\n logger.debug('Creating custom app session from configured access token', {\n shop,\n });\n return api.session.customAppSession(shop);\n } else {\n logger.debug('Loading offline session from session storage', {shop});\n const offlineSessionId = api.session.getOfflineId(shop);\n const session = await config.sessionStorage!.loadSession(offlineSessionId);\n\n return session;\n }\n}\n"],"names":["AppDistribution"],"mappings":";;;;AAEO,eAAe,0BAA0B,CAC9C,EAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAc,EAClC,IAAY,EAAA;IAEZ,IAAI,MAAM,CAAC,YAAY,KAAKA,qBAAe,CAAC,YAAY,EAAE;AACxD,QAAA,MAAM,CAAC,KAAK,CAAC,0DAA0D,EAAE;YACvE,IAAI;AACL,SAAA,CAAC;QACF,OAAO,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC;IAC3C;SAAO;QACL,MAAM,CAAC,KAAK,CAAC,8CAA8C,EAAE,EAAC,IAAI,EAAC,CAAC;QACpE,MAAM,gBAAgB,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC;QACvD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,cAAe,CAAC,WAAW,CAAC,gBAAgB,CAAC;AAE1E,QAAA,OAAO,OAAO;IAChB;AACF;;;;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var types = require('../types.js');
|
|
4
|
+
var refreshToken = require('./refresh-token.js');
|
|
5
|
+
|
|
6
|
+
// 5 minutes
|
|
7
|
+
const WITHIN_MILLISECONDS_OF_EXPIRY = 5 * 60 * 1000;
|
|
8
|
+
async function ensureOfflineTokenIsNotExpired(session, params, shop) {
|
|
9
|
+
const { config } = params;
|
|
10
|
+
if (config.future?.expiringOfflineAccessTokens &&
|
|
11
|
+
session.isExpired(WITHIN_MILLISECONDS_OF_EXPIRY) &&
|
|
12
|
+
config.distribution !== types.AppDistribution.ShopifyAdmin &&
|
|
13
|
+
session.refreshToken) {
|
|
14
|
+
const offlineSession = await refreshToken.default(params, shop, session.refreshToken);
|
|
15
|
+
await config.sessionStorage.storeSession(offlineSession);
|
|
16
|
+
return offlineSession;
|
|
17
|
+
}
|
|
18
|
+
return session;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
exports.WITHIN_MILLISECONDS_OF_EXPIRY = WITHIN_MILLISECONDS_OF_EXPIRY;
|
|
22
|
+
exports.ensureOfflineTokenIsNotExpired = ensureOfflineTokenIsNotExpired;
|
|
23
|
+
//# sourceMappingURL=ensure-offline-token-is-not-expired.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-offline-token-is-not-expired.js","sources":["../../../../../src/server/helpers/ensure-offline-token-is-not-expired.ts"],"sourcesContent":["import {Session} from '@shopify/shopify-api';\n\nimport {AppDistribution, BasicParams} from '../types';\n\nimport refreshToken from './refresh-token';\n\n// 5 minutes\nexport const WITHIN_MILLISECONDS_OF_EXPIRY = 5 * 60 * 1000;\n\nexport async function ensureOfflineTokenIsNotExpired(\n session: Session,\n params: BasicParams,\n shop: string,\n) {\n const {config} = params;\n if (\n config.future?.expiringOfflineAccessTokens &&\n session.isExpired(WITHIN_MILLISECONDS_OF_EXPIRY) &&\n config.distribution !== AppDistribution.ShopifyAdmin &&\n session.refreshToken\n ) {\n const offlineSession = await refreshToken(\n params,\n shop,\n session.refreshToken,\n );\n\n await config.sessionStorage!.storeSession(offlineSession);\n return offlineSession;\n }\n return session;\n}\n"],"names":["AppDistribution","refreshToken"],"mappings":";;;;;AAMA;MACa,6BAA6B,GAAG,CAAC,GAAG,EAAE,GAAG;AAE/C,eAAe,8BAA8B,CAClD,OAAgB,EAChB,MAAmB,EACnB,IAAY,EAAA;AAEZ,IAAA,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM;AACvB,IAAA,IACE,MAAM,CAAC,MAAM,EAAE,2BAA2B;AAC1C,QAAA,OAAO,CAAC,SAAS,CAAC,6BAA6B,CAAC;AAChD,QAAA,MAAM,CAAC,YAAY,KAAKA,qBAAe,CAAC,YAAY;QACpD,OAAO,CAAC,YAAY,EACpB;AACA,QAAA,MAAM,cAAc,GAAG,MAAMC,oBAAY,CACvC,MAAM,EACN,IAAI,EACJ,OAAO,CAAC,YAAY,CACrB;QAED,MAAM,MAAM,CAAC,cAAe,CAAC,YAAY,CAAC,cAAc,CAAC;AACzD,QAAA,OAAO,cAAc;IACvB;AACA,IAAA,OAAO,OAAO;AAChB;;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var createOrLoadOfflineSession = require('./create-or-load-offline-session.js');
|
|
4
|
+
var ensureOfflineTokenIsNotExpired = require('./ensure-offline-token-is-not-expired.js');
|
|
5
|
+
|
|
6
|
+
async function ensureValidOfflineSession(params, shop) {
|
|
7
|
+
const session = await createOrLoadOfflineSession.createOrLoadOfflineSession(params, shop);
|
|
8
|
+
if (!session)
|
|
9
|
+
return undefined;
|
|
10
|
+
return ensureOfflineTokenIsNotExpired.ensureOfflineTokenIsNotExpired(session, params, shop);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
exports.ensureValidOfflineSession = ensureValidOfflineSession;
|
|
14
|
+
//# sourceMappingURL=ensure-valid-offline-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-valid-offline-session.js","sources":["../../../../../src/server/helpers/ensure-valid-offline-session.ts"],"sourcesContent":["import {BasicParams} from '../types';\n\nimport {createOrLoadOfflineSession} from './create-or-load-offline-session';\nimport {ensureOfflineTokenIsNotExpired} from './ensure-offline-token-is-not-expired';\n\nexport async function ensureValidOfflineSession(\n params: BasicParams,\n shop: string,\n) {\n const session = await createOrLoadOfflineSession(params, shop);\n\n if (!session) return undefined;\n\n return ensureOfflineTokenIsNotExpired(session, params, shop);\n}\n"],"names":["createOrLoadOfflineSession","ensureOfflineTokenIsNotExpired"],"mappings":";;;;;AAKO,eAAe,yBAAyB,CAC7C,MAAmB,EACnB,IAAY,EAAA;IAEZ,MAAM,OAAO,GAAG,MAAMA,qDAA0B,CAAC,MAAM,EAAE,IAAI,CAAC;AAE9D,IAAA,IAAI,CAAC,OAAO;AAAE,QAAA,OAAO,SAAS;IAE9B,OAAOC,6DAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC;AAC9D;;;;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var shopifyApi = require('@shopify/shopify-api');
|
|
6
|
+
|
|
7
|
+
async function refreshToken(params, shop, refreshToken) {
|
|
8
|
+
const { api } = params;
|
|
9
|
+
try {
|
|
10
|
+
const { session } = await api.auth.refreshToken({
|
|
11
|
+
shop,
|
|
12
|
+
refreshToken,
|
|
13
|
+
});
|
|
14
|
+
return session;
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
if (error instanceof shopifyApi.InvalidJwtError ||
|
|
18
|
+
(error instanceof shopifyApi.HttpResponseError &&
|
|
19
|
+
error.response.code === 400 &&
|
|
20
|
+
error.response.body?.error === 'invalid_subject_token')) {
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
throw new Response(undefined, {
|
|
24
|
+
status: 500,
|
|
25
|
+
statusText: 'Internal Server Error',
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
exports.default = refreshToken;
|
|
31
|
+
//# sourceMappingURL=refresh-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh-token.js","sources":["../../../../../src/server/helpers/refresh-token.ts"],"sourcesContent":["import {\n HttpResponseError,\n InvalidJwtError,\n Session,\n} from '@shopify/shopify-api';\n\nimport {BasicParams} from '../types';\n\nexport default async function refreshToken(\n params: BasicParams,\n shop: string,\n refreshToken: string,\n): Promise<Session> {\n const {api} = params;\n try {\n const {session} = await api.auth.refreshToken({\n shop,\n refreshToken,\n });\n return session;\n } catch (error) {\n if (\n error instanceof InvalidJwtError ||\n (error instanceof HttpResponseError &&\n error.response.code === 400 &&\n error.response.body?.error === 'invalid_subject_token')\n ) {\n throw error;\n }\n throw new Response(undefined, {\n status: 500,\n statusText: 'Internal Server Error',\n });\n }\n}\n"],"names":["InvalidJwtError","HttpResponseError"],"mappings":";;;;;;AAQe,eAAe,YAAY,CACxC,MAAmB,EACnB,IAAY,EACZ,YAAoB,EAAA;AAEpB,IAAA,MAAM,EAAC,GAAG,EAAC,GAAG,MAAM;AACpB,IAAA,IAAI;QACF,MAAM,EAAC,OAAO,EAAC,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC;YAC5C,IAAI;YACJ,YAAY;AACb,SAAA,CAAC;AACF,QAAA,OAAO,OAAO;IAChB;IAAE,OAAO,KAAK,EAAE;QACd,IACE,KAAK,YAAYA,0BAAe;aAC/B,KAAK,YAAYC,4BAAiB;AACjC,gBAAA,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG;gBAC3B,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,KAAK,uBAAuB,CAAC,EACzD;AACA,YAAA,MAAM,KAAK;QACb;AACA,QAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,YAAA,MAAM,EAAE,GAAG;AACX,YAAA,UAAU,EAAE,uBAAuB;AACpC,SAAA,CAAC;IACJ;AACF;;;;"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var ensureValidOfflineSession = require('../../helpers/ensure-valid-offline-session.js');
|
|
4
|
+
require('../../types.js');
|
|
5
|
+
require('@shopify/shopify-api');
|
|
4
6
|
var errors = require('../../errors.js');
|
|
5
7
|
var factory = require('../../clients/admin/factory.js');
|
|
6
8
|
|
|
7
9
|
function unauthenticatedAdminContextFactory(params) {
|
|
8
10
|
return async (shop) => {
|
|
9
|
-
const session = await
|
|
11
|
+
const session = await ensureValidOfflineSession.ensureValidOfflineSession(params, shop);
|
|
10
12
|
if (!session) {
|
|
11
13
|
throw new errors.SessionNotFoundError(`Could not find a session for shop ${shop} when creating unauthenticated admin context`);
|
|
12
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sources":["../../../../../../src/server/unauthenticated/admin/factory.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"factory.js","sources":["../../../../../../src/server/unauthenticated/admin/factory.ts"],"sourcesContent":["import {ensureValidOfflineSession} from '../../helpers';\nimport {SessionNotFoundError} from '../../errors';\nimport {BasicParams} from '../../types';\nimport {adminClientFactory} from '../../clients/admin';\n\nimport {UnauthenticatedAdminContext} from './types';\n\nexport function unauthenticatedAdminContextFactory(params: BasicParams) {\n return async (shop: string): Promise<UnauthenticatedAdminContext> => {\n const session = await ensureValidOfflineSession(params, shop);\n\n if (!session) {\n throw new SessionNotFoundError(\n `Could not find a session for shop ${shop} when creating unauthenticated admin context`,\n );\n }\n\n return {\n session,\n admin: adminClientFactory({params, session}),\n };\n };\n}\n"],"names":["ensureValidOfflineSession","SessionNotFoundError","adminClientFactory"],"mappings":";;;;;;;;AAOM,SAAU,kCAAkC,CAAC,MAAmB,EAAA;AACpE,IAAA,OAAO,OAAO,IAAY,KAA0C;QAClE,MAAM,OAAO,GAAG,MAAMA,mDAAyB,CAAC,MAAM,EAAE,IAAI,CAAC;QAE7D,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,MAAM,IAAIC,2BAAoB,CAC5B,qCAAqC,IAAI,CAAA,4CAAA,CAA8C,CACxF;QACH;QAEA,OAAO;YACL,OAAO;YACP,KAAK,EAAEC,0BAAkB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;SAC7C;AACH,IAAA,CAAC;AACH;;;;"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var createOrLoadOfflineSession = require('../../authenticate/helpers/create-or-load-offline-session.js');
|
|
4
3
|
var errors = require('../../errors.js');
|
|
5
4
|
var factory = require('../../clients/storefront/factory.js');
|
|
5
|
+
var ensureValidOfflineSession = require('../../helpers/ensure-valid-offline-session.js');
|
|
6
|
+
require('../../types.js');
|
|
7
|
+
require('@shopify/shopify-api');
|
|
6
8
|
|
|
7
9
|
function unauthenticatedStorefrontContextFactory(params) {
|
|
8
10
|
return async (shop) => {
|
|
9
|
-
const session = await
|
|
11
|
+
const session = await ensureValidOfflineSession.ensureValidOfflineSession(params, shop);
|
|
10
12
|
if (!session) {
|
|
11
13
|
throw new errors.SessionNotFoundError(`Could not find a session for shop ${shop} when creating unauthenticated storefront context`);
|
|
12
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sources":["../../../../../../src/server/unauthenticated/storefront/factory.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"factory.js","sources":["../../../../../../src/server/unauthenticated/storefront/factory.ts"],"sourcesContent":["import {SessionNotFoundError} from '../../errors';\nimport {BasicParams} from '../../types';\nimport {storefrontClientFactory} from '../../clients/storefront';\nimport {ensureValidOfflineSession} from '../../helpers';\n\nimport {\n UnauthenticatedStorefrontContext,\n GetUnauthenticatedStorefrontContext,\n} from './types';\n\nexport function unauthenticatedStorefrontContextFactory(\n params: BasicParams,\n): GetUnauthenticatedStorefrontContext {\n return async (shop: string): Promise<UnauthenticatedStorefrontContext> => {\n const session = await ensureValidOfflineSession(params, shop);\n\n if (!session) {\n throw new SessionNotFoundError(\n `Could not find a session for shop ${shop} when creating unauthenticated storefront context`,\n );\n }\n\n return {\n session,\n storefront: storefrontClientFactory({params, session}),\n };\n };\n}\n"],"names":["ensureValidOfflineSession","SessionNotFoundError","storefrontClientFactory"],"mappings":";;;;;;;;AAUM,SAAU,uCAAuC,CACrD,MAAmB,EAAA;AAEnB,IAAA,OAAO,OAAO,IAAY,KAA+C;QACvE,MAAM,OAAO,GAAG,MAAMA,mDAAyB,CAAC,MAAM,EAAE,IAAI,CAAC;QAE7D,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,MAAM,IAAIC,2BAAoB,CAC5B,qCAAqC,IAAI,CAAA,iDAAA,CAAmD,CAC7F;QACH;QAEA,OAAO;YACL,OAAO;YACP,UAAU,EAAEC,+BAAuB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;SACvD;AACH,IAAA,CAAC;AACH;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sources":["../../../../src/server/version.ts"],"sourcesContent":["export const SHOPIFY_REMIX_LIBRARY_VERSION = '4.0
|
|
1
|
+
{"version":3,"file":"version.js","sources":["../../../../src/server/version.ts"],"sourcesContent":["export const SHOPIFY_REMIX_LIBRARY_VERSION = '4.1.0';\n"],"names":[],"mappings":";;AAAO,MAAM,6BAA6B,GAAG;;;;"}
|
|
@@ -2,7 +2,6 @@ import { setAbstractRuntimeString } from '@shopify/shopify-api/runtime';
|
|
|
2
2
|
import { setAppBridgeUrlOverride } from '../../authenticate/helpers/app-bridge-url.mjs';
|
|
3
3
|
import '@remix-run/server-runtime';
|
|
4
4
|
import 'isbot';
|
|
5
|
-
import '../../types.mjs';
|
|
6
5
|
|
|
7
6
|
setAbstractRuntimeString(() => {
|
|
8
7
|
return `Remix (Node)`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../../../src/server/adapters/node/index.ts"],"sourcesContent":["import {setAbstractRuntimeString} from '@shopify/shopify-api/runtime';\n\nimport {setAppBridgeUrlOverride} from '../../authenticate/helpers';\n\nsetAbstractRuntimeString(() => {\n return `Remix (Node)`;\n});\n\n/* eslint-disable no-process-env */\nif (process.env.APP_BRIDGE_URL) {\n setAppBridgeUrlOverride(process.env.APP_BRIDGE_URL);\n}\n/* eslint-enable no-process-env */\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../../../src/server/adapters/node/index.ts"],"sourcesContent":["import {setAbstractRuntimeString} from '@shopify/shopify-api/runtime';\n\nimport {setAppBridgeUrlOverride} from '../../authenticate/helpers';\n\nsetAbstractRuntimeString(() => {\n return `Remix (Node)`;\n});\n\n/* eslint-disable no-process-env */\nif (process.env.APP_BRIDGE_URL) {\n setAppBridgeUrlOverride(process.env.APP_BRIDGE_URL);\n}\n/* eslint-enable no-process-env */\n"],"names":[],"mappings":";;;;;AAIA,wBAAwB,CAAC,MAAK;AAC5B,IAAA,OAAO,cAAc;AACvB,CAAC,CAAC;AAEF;AACA,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE;AAC9B,IAAA,uBAAuB,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;AACrD;AACA"}
|
|
@@ -4,7 +4,6 @@ import { getSessionTokenHeader, getSessionTokenFromUrlParam } from '../helpers/g
|
|
|
4
4
|
import { respondToBotRequest } from '../helpers/reject-bot-request.mjs';
|
|
5
5
|
import { respondToOptionsRequest } from '../helpers/respond-to-options-request.mjs';
|
|
6
6
|
import '@remix-run/server-runtime';
|
|
7
|
-
import '../../types.mjs';
|
|
8
7
|
import { getShopFromRequest } from '../helpers/get-shop-from-request.mjs';
|
|
9
8
|
import { cancelBillingFactory } from './billing/cancel.mjs';
|
|
10
9
|
import { requireBillingFactory } from './billing/require.mjs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticate.mjs","sources":["../../../../../../src/server/authenticate/admin/authenticate.ts"],"sourcesContent":["import {JwtPayload, Session} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../types';\nimport type {AppConfigArg} from '../../config-types';\nimport {\n getSessionTokenHeader,\n ensureCORSHeadersFactory,\n getSessionTokenFromUrlParam,\n respondToBotRequest,\n respondToOptionsRequest,\n validateSessionToken,\n getShopFromRequest,\n} from '../helpers';\n\nimport {\n cancelBillingFactory,\n requestBillingFactory,\n requireBillingFactory,\n checkBillingFactory,\n createUsageRecordFactory,\n updateUsageCappedAmountFactory,\n} from './billing';\nimport type {\n AdminContext,\n AuthenticateAdmin,\n EmbeddedAdminContext,\n NonEmbeddedAdminContext,\n} from './types';\nimport {\n createAdminApiContext,\n ensureAppIsEmbeddedIfRequired,\n ensureSessionTokenSearchParamIfRequired,\n redirectFactory,\n renderAppBridge,\n validateShopAndHostParams,\n} from './helpers';\nimport {AuthorizationStrategy} from './strategies/types';\nimport {scopesApiFactory} from './scope/factory';\n\nexport interface SessionTokenContext {\n shop: string;\n sessionId?: string;\n sessionToken?: string;\n payload?: JwtPayload;\n}\n\ninterface AuthStrategyParams extends BasicParams {\n strategy: AuthorizationStrategy;\n}\n\nexport function authStrategyFactory<ConfigArg extends AppConfigArg>({\n strategy,\n ...params\n}: AuthStrategyParams): AuthenticateAdmin<ConfigArg> {\n const {api, logger, config} = params;\n\n async function respondToBouncePageRequest(request: Request) {\n const url = new URL(request.url);\n\n if (url.pathname === config.auth.patchSessionTokenPath) {\n logger.debug('Rendering bounce page', {\n shop: getShopFromRequest(request),\n });\n throw renderAppBridge({config, logger, api}, request);\n }\n }\n\n async function respondToExitIframeRequest(request: Request) {\n const url = new URL(request.url);\n\n if (url.pathname === config.auth.exitIframePath) {\n const destination = url.searchParams.get('exitIframe')!;\n\n logger.debug('Rendering exit iframe page', {\n shop: getShopFromRequest(request),\n destination,\n });\n throw renderAppBridge({config, logger, api}, request, {url: destination});\n }\n }\n\n type AdminContextBase =\n | EmbeddedAdminContext<ConfigArg>\n | NonEmbeddedAdminContext<ConfigArg>;\n\n function createContext(\n request: Request,\n session: Session,\n authStrategy: AuthorizationStrategy,\n sessionToken?: JwtPayload,\n ): AdminContext<ConfigArg> {\n let context: AdminContextBase = {\n admin: createAdminApiContext(\n session,\n params,\n authStrategy.handleClientError(request),\n ),\n billing: {\n require: requireBillingFactory(params, request, session),\n check: checkBillingFactory(params, request, session),\n request: requestBillingFactory(params, request, session),\n cancel: cancelBillingFactory(params, request, session),\n createUsageRecord: createUsageRecordFactory(params, request, session),\n updateUsageCappedAmount: updateUsageCappedAmountFactory(\n params,\n request,\n session,\n ),\n },\n\n session,\n cors: ensureCORSHeadersFactory(params, request),\n };\n\n context = addEmbeddedFeatures(context, request, session, sessionToken);\n context = addScopesFeatures(context);\n\n return context as AdminContext<ConfigArg>;\n }\n\n function addEmbeddedFeatures(\n context: AdminContextBase,\n request: Request,\n session: Session,\n sessionToken?: JwtPayload,\n ) {\n if (config.isEmbeddedApp) {\n return {\n ...context,\n sessionToken,\n redirect: redirectFactory(params, request, session.shop),\n };\n }\n return context;\n }\n\n function addScopesFeatures(context: AdminContextBase) {\n return {\n ...context,\n scopes: scopesApiFactory(params, context.session, context.admin),\n };\n }\n\n return async function authenticateAdmin(request: Request) {\n try {\n respondToBotRequest(params, request);\n respondToOptionsRequest(params, request);\n await respondToBouncePageRequest(request);\n await respondToExitIframeRequest(request);\n await strategy.respondToOAuthRequests(request);\n\n // If this is a valid request, but it doesn't have a session token header, this is a document request. We need to\n // ensure we're embedded if needed and we have the information needed to load the session.\n if (!getSessionTokenHeader(request)) {\n validateShopAndHostParams(params, request);\n await ensureAppIsEmbeddedIfRequired(params, request);\n await ensureSessionTokenSearchParamIfRequired(params, request);\n }\n\n logger.info('Authenticating admin request', {\n shop: getShopFromRequest(request),\n });\n\n const {payload, shop, sessionId, sessionToken} =\n await getSessionTokenContext(params, request);\n\n logger.debug('Loading session from storage', {shop, sessionId});\n const existingSession = sessionId\n ? await config.sessionStorage!.loadSession(sessionId)\n : undefined;\n\n const session = await strategy.authenticate(request, {\n session: existingSession,\n sessionToken,\n shop,\n });\n\n return createContext(request, session, strategy, payload);\n } catch (errorOrResponse) {\n if (errorOrResponse instanceof Response) {\n logger.debug('Authenticate returned a response', {\n shop: getShopFromRequest(request),\n });\n ensureCORSHeadersFactory(params, request)(errorOrResponse);\n }\n\n throw errorOrResponse;\n }\n };\n}\n\nasync function getSessionTokenContext(\n params: BasicParams,\n request: Request,\n): Promise<SessionTokenContext> {\n const {api, config, logger} = params;\n\n const headerSessionToken = getSessionTokenHeader(request);\n const searchParamSessionToken = getSessionTokenFromUrlParam(request);\n const sessionToken = (headerSessionToken || searchParamSessionToken)!;\n\n logger.debug('Attempting to authenticate session token', {\n shop: getShopFromRequest(request),\n sessionToken: JSON.stringify({\n header: headerSessionToken,\n search: searchParamSessionToken,\n }),\n });\n\n if (config.isEmbeddedApp) {\n const payload = await validateSessionToken(params, request, sessionToken);\n const dest = new URL(payload.dest);\n const shop = dest.hostname;\n\n logger.debug('Session token is valid - authenticated', {shop, payload});\n const sessionId = config.useOnlineTokens\n ? api.session.getJwtSessionId(shop, payload.sub)\n : api.session.getOfflineId(shop);\n\n return {shop, payload, sessionId, sessionToken};\n }\n\n const url = new URL(request.url);\n const shop = url.searchParams.get('shop')!;\n\n const sessionId = await api.session.getCurrentId({\n isOnline: config.useOnlineTokens,\n rawRequest: request,\n });\n\n return {shop, sessionId, payload: undefined, sessionToken};\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"authenticate.mjs","sources":["../../../../../../src/server/authenticate/admin/authenticate.ts"],"sourcesContent":["import {JwtPayload, Session} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../types';\nimport type {AppConfigArg} from '../../config-types';\nimport {\n getSessionTokenHeader,\n ensureCORSHeadersFactory,\n getSessionTokenFromUrlParam,\n respondToBotRequest,\n respondToOptionsRequest,\n validateSessionToken,\n getShopFromRequest,\n} from '../helpers';\n\nimport {\n cancelBillingFactory,\n requestBillingFactory,\n requireBillingFactory,\n checkBillingFactory,\n createUsageRecordFactory,\n updateUsageCappedAmountFactory,\n} from './billing';\nimport type {\n AdminContext,\n AuthenticateAdmin,\n EmbeddedAdminContext,\n NonEmbeddedAdminContext,\n} from './types';\nimport {\n createAdminApiContext,\n ensureAppIsEmbeddedIfRequired,\n ensureSessionTokenSearchParamIfRequired,\n redirectFactory,\n renderAppBridge,\n validateShopAndHostParams,\n} from './helpers';\nimport {AuthorizationStrategy} from './strategies/types';\nimport {scopesApiFactory} from './scope/factory';\n\nexport interface SessionTokenContext {\n shop: string;\n sessionId?: string;\n sessionToken?: string;\n payload?: JwtPayload;\n}\n\ninterface AuthStrategyParams extends BasicParams {\n strategy: AuthorizationStrategy;\n}\n\nexport function authStrategyFactory<ConfigArg extends AppConfigArg>({\n strategy,\n ...params\n}: AuthStrategyParams): AuthenticateAdmin<ConfigArg> {\n const {api, logger, config} = params;\n\n async function respondToBouncePageRequest(request: Request) {\n const url = new URL(request.url);\n\n if (url.pathname === config.auth.patchSessionTokenPath) {\n logger.debug('Rendering bounce page', {\n shop: getShopFromRequest(request),\n });\n throw renderAppBridge({config, logger, api}, request);\n }\n }\n\n async function respondToExitIframeRequest(request: Request) {\n const url = new URL(request.url);\n\n if (url.pathname === config.auth.exitIframePath) {\n const destination = url.searchParams.get('exitIframe')!;\n\n logger.debug('Rendering exit iframe page', {\n shop: getShopFromRequest(request),\n destination,\n });\n throw renderAppBridge({config, logger, api}, request, {url: destination});\n }\n }\n\n type AdminContextBase =\n | EmbeddedAdminContext<ConfigArg>\n | NonEmbeddedAdminContext<ConfigArg>;\n\n function createContext(\n request: Request,\n session: Session,\n authStrategy: AuthorizationStrategy,\n sessionToken?: JwtPayload,\n ): AdminContext<ConfigArg> {\n let context: AdminContextBase = {\n admin: createAdminApiContext(\n session,\n params,\n authStrategy.handleClientError(request),\n ),\n billing: {\n require: requireBillingFactory(params, request, session),\n check: checkBillingFactory(params, request, session),\n request: requestBillingFactory(params, request, session),\n cancel: cancelBillingFactory(params, request, session),\n createUsageRecord: createUsageRecordFactory(params, request, session),\n updateUsageCappedAmount: updateUsageCappedAmountFactory(\n params,\n request,\n session,\n ),\n },\n\n session,\n cors: ensureCORSHeadersFactory(params, request),\n };\n\n context = addEmbeddedFeatures(context, request, session, sessionToken);\n context = addScopesFeatures(context);\n\n return context as AdminContext<ConfigArg>;\n }\n\n function addEmbeddedFeatures(\n context: AdminContextBase,\n request: Request,\n session: Session,\n sessionToken?: JwtPayload,\n ) {\n if (config.isEmbeddedApp) {\n return {\n ...context,\n sessionToken,\n redirect: redirectFactory(params, request, session.shop),\n };\n }\n return context;\n }\n\n function addScopesFeatures(context: AdminContextBase) {\n return {\n ...context,\n scopes: scopesApiFactory(params, context.session, context.admin),\n };\n }\n\n return async function authenticateAdmin(request: Request) {\n try {\n respondToBotRequest(params, request);\n respondToOptionsRequest(params, request);\n await respondToBouncePageRequest(request);\n await respondToExitIframeRequest(request);\n await strategy.respondToOAuthRequests(request);\n\n // If this is a valid request, but it doesn't have a session token header, this is a document request. We need to\n // ensure we're embedded if needed and we have the information needed to load the session.\n if (!getSessionTokenHeader(request)) {\n validateShopAndHostParams(params, request);\n await ensureAppIsEmbeddedIfRequired(params, request);\n await ensureSessionTokenSearchParamIfRequired(params, request);\n }\n\n logger.info('Authenticating admin request', {\n shop: getShopFromRequest(request),\n });\n\n const {payload, shop, sessionId, sessionToken} =\n await getSessionTokenContext(params, request);\n\n logger.debug('Loading session from storage', {shop, sessionId});\n const existingSession = sessionId\n ? await config.sessionStorage!.loadSession(sessionId)\n : undefined;\n\n const session = await strategy.authenticate(request, {\n session: existingSession,\n sessionToken,\n shop,\n });\n\n return createContext(request, session, strategy, payload);\n } catch (errorOrResponse) {\n if (errorOrResponse instanceof Response) {\n logger.debug('Authenticate returned a response', {\n shop: getShopFromRequest(request),\n });\n ensureCORSHeadersFactory(params, request)(errorOrResponse);\n }\n\n throw errorOrResponse;\n }\n };\n}\n\nasync function getSessionTokenContext(\n params: BasicParams,\n request: Request,\n): Promise<SessionTokenContext> {\n const {api, config, logger} = params;\n\n const headerSessionToken = getSessionTokenHeader(request);\n const searchParamSessionToken = getSessionTokenFromUrlParam(request);\n const sessionToken = (headerSessionToken || searchParamSessionToken)!;\n\n logger.debug('Attempting to authenticate session token', {\n shop: getShopFromRequest(request),\n sessionToken: JSON.stringify({\n header: headerSessionToken,\n search: searchParamSessionToken,\n }),\n });\n\n if (config.isEmbeddedApp) {\n const payload = await validateSessionToken(params, request, sessionToken);\n const dest = new URL(payload.dest);\n const shop = dest.hostname;\n\n logger.debug('Session token is valid - authenticated', {shop, payload});\n const sessionId = config.useOnlineTokens\n ? api.session.getJwtSessionId(shop, payload.sub)\n : api.session.getOfflineId(shop);\n\n return {shop, payload, sessionId, sessionToken};\n }\n\n const url = new URL(request.url);\n const shop = url.searchParams.get('shop')!;\n\n const sessionId = await api.session.getCurrentId({\n isOnline: config.useOnlineTokens,\n rawRequest: request,\n });\n\n return {shop, sessionId, payload: undefined, sessionToken};\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,6 @@ import '@remix-run/server-runtime';
|
|
|
3
3
|
import { redirectToAuthPage } from '../helpers/redirect-to-auth-page.mjs';
|
|
4
4
|
import { invalidateAccessToken } from '../../helpers/invalidate-access-token.mjs';
|
|
5
5
|
import 'isbot';
|
|
6
|
-
import '../../../types.mjs';
|
|
7
6
|
|
|
8
7
|
function cancelBillingFactory(params, request, session) {
|
|
9
8
|
return async function cancelBilling(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cancel.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/cancel.ts"],"sourcesContent":["import {HttpResponseError, Session} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../../types';\nimport {redirectToAuthPage} from '../helpers';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport type {CancelBillingOptions} from './types';\n\nexport function cancelBillingFactory(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n return async function cancelBilling(options: CancelBillingOptions) {\n const {api, logger} = params;\n\n logger.debug('Cancelling billing', {shop: session.shop, ...options});\n\n try {\n return await api.billing.cancel({\n session,\n subscriptionId: options.subscriptionId,\n isTest: options.isTest,\n prorate: options.prorate,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', {\n shop: session.shop,\n });\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n };\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cancel.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/cancel.ts"],"sourcesContent":["import {HttpResponseError, Session} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../../types';\nimport {redirectToAuthPage} from '../helpers';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport type {CancelBillingOptions} from './types';\n\nexport function cancelBillingFactory(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n return async function cancelBilling(options: CancelBillingOptions) {\n const {api, logger} = params;\n\n logger.debug('Cancelling billing', {shop: session.shop, ...options});\n\n try {\n return await api.billing.cancel({\n session,\n subscriptionId: options.subscriptionId,\n isTest: options.isTest,\n prorate: options.prorate,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', {\n shop: session.shop,\n });\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n };\n}\n"],"names":[],"mappings":";;;;;;SAQgB,oBAAoB,CAClC,MAAmB,EACnB,OAAgB,EAChB,OAAgB,EAAA;AAEhB,IAAA,OAAO,eAAe,aAAa,CAAC,OAA6B,EAAA;AAC/D,QAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,QAAA,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,OAAO,EAAC,CAAC;AAEpE,QAAA,IAAI;AACF,YAAA,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC9B,OAAO;gBACP,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,OAAO,EAAE,OAAO,CAAC,OAAO;AACzB,aAAA,CAAC;QACJ;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,KAAK,YAAY,iBAAiB,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,EAAE;AACrE,gBAAA,MAAM,CAAC,KAAK,CAAC,6CAA6C,EAAE;oBAC1D,IAAI,EAAE,OAAO,CAAC,IAAI;AACnB,iBAAA,CAAC;AACF,gBAAA,MAAM,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC;gBAC5C,MAAM,MAAM,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;YAC/D;iBAAO;AACL,gBAAA,MAAM,KAAK;YACb;QACF;AACF,IAAA,CAAC;AACH;;;;"}
|
|
@@ -3,7 +3,6 @@ import '@remix-run/server-runtime';
|
|
|
3
3
|
import { redirectToAuthPage } from '../helpers/redirect-to-auth-page.mjs';
|
|
4
4
|
import { invalidateAccessToken } from '../../helpers/invalidate-access-token.mjs';
|
|
5
5
|
import 'isbot';
|
|
6
|
-
import '../../../types.mjs';
|
|
7
6
|
|
|
8
7
|
function checkBillingFactory(params, request, session) {
|
|
9
8
|
return async function checkBilling(options = {}) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/check.ts"],"sourcesContent":["import {HttpResponseError, Session} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../../types';\nimport {redirectToAuthPage} from '../helpers';\nimport type {AppConfigArg} from '../../../config-types';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport type {CheckBillingOptions} from './types';\n\nexport function checkBillingFactory<Config extends AppConfigArg>(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n return async function checkBilling(\n options: CheckBillingOptions<Config> = {},\n ) {\n const {api, logger} = params;\n\n logger.debug('Checking billing plans', {shop: session.shop, ...options});\n\n try {\n return await api.billing.check({\n session,\n plans: options.plans as string[],\n isTest: options.isTest,\n returnObject: true,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', {\n shop: session.shop,\n });\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n };\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"check.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/check.ts"],"sourcesContent":["import {HttpResponseError, Session} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../../types';\nimport {redirectToAuthPage} from '../helpers';\nimport type {AppConfigArg} from '../../../config-types';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport type {CheckBillingOptions} from './types';\n\nexport function checkBillingFactory<Config extends AppConfigArg>(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n return async function checkBilling(\n options: CheckBillingOptions<Config> = {},\n ) {\n const {api, logger} = params;\n\n logger.debug('Checking billing plans', {shop: session.shop, ...options});\n\n try {\n return await api.billing.check({\n session,\n plans: options.plans as string[],\n isTest: options.isTest,\n returnObject: true,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', {\n shop: session.shop,\n });\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n };\n}\n"],"names":[],"mappings":";;;;;;SASgB,mBAAmB,CACjC,MAAmB,EACnB,OAAgB,EAChB,OAAgB,EAAA;AAEhB,IAAA,OAAO,eAAe,YAAY,CAChC,UAAuC,EAAE,EAAA;AAEzC,QAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,QAAA,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,EAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,OAAO,EAAC,CAAC;AAExE,QAAA,IAAI;AACF,YAAA,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC;gBAC7B,OAAO;gBACP,KAAK,EAAE,OAAO,CAAC,KAAiB;gBAChC,MAAM,EAAE,OAAO,CAAC,MAAM;AACtB,gBAAA,YAAY,EAAE,IAAI;AACnB,aAAA,CAAC;QACJ;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,KAAK,YAAY,iBAAiB,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,EAAE;AACrE,gBAAA,MAAM,CAAC,KAAK,CAAC,6CAA6C,EAAE;oBAC1D,IAAI,EAAE,OAAO,CAAC,IAAI;AACnB,iBAAA,CAAC;AACF,gBAAA,MAAM,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC;gBAC5C,MAAM,MAAM,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;YAC/D;iBAAO;AACL,gBAAA,MAAM,KAAK;YACb;QACF;AACF,IAAA,CAAC;AACH;;;;"}
|
|
@@ -3,7 +3,6 @@ import '@remix-run/server-runtime';
|
|
|
3
3
|
import { redirectToAuthPage } from '../helpers/redirect-to-auth-page.mjs';
|
|
4
4
|
import { invalidateAccessToken } from '../../helpers/invalidate-access-token.mjs';
|
|
5
5
|
import 'isbot';
|
|
6
|
-
import '../../../types.mjs';
|
|
7
6
|
|
|
8
7
|
function createUsageRecordFactory(params, request, session) {
|
|
9
8
|
return async function createUsageRecord(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-usage-record.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/create-usage-record.ts"],"sourcesContent":["import {HttpResponseError, Session} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../../types';\nimport {redirectToAuthPage} from '../helpers';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport type {CreateUsageRecordOptions} from './types';\n\nexport function createUsageRecordFactory(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n return async function createUsageRecord(options: CreateUsageRecordOptions) {\n const {api, logger} = params;\n\n logger.debug('Create usage record', {shop: session.shop, ...options});\n\n try {\n return await api.billing.createUsageRecord({\n ...options,\n session,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', {\n shop: session.shop,\n });\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n };\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create-usage-record.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/create-usage-record.ts"],"sourcesContent":["import {HttpResponseError, Session} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../../types';\nimport {redirectToAuthPage} from '../helpers';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport type {CreateUsageRecordOptions} from './types';\n\nexport function createUsageRecordFactory(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n return async function createUsageRecord(options: CreateUsageRecordOptions) {\n const {api, logger} = params;\n\n logger.debug('Create usage record', {shop: session.shop, ...options});\n\n try {\n return await api.billing.createUsageRecord({\n ...options,\n session,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', {\n shop: session.shop,\n });\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n };\n}\n"],"names":[],"mappings":";;;;;;SAQgB,wBAAwB,CACtC,MAAmB,EACnB,OAAgB,EAChB,OAAgB,EAAA;AAEhB,IAAA,OAAO,eAAe,iBAAiB,CAAC,OAAiC,EAAA;AACvE,QAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,QAAA,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,OAAO,EAAC,CAAC;AAErE,QAAA,IAAI;AACF,YAAA,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC;AACzC,gBAAA,GAAG,OAAO;gBACV,OAAO;AACR,aAAA,CAAC;QACJ;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,KAAK,YAAY,iBAAiB,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,EAAE;AACrE,gBAAA,MAAM,CAAC,KAAK,CAAC,6CAA6C,EAAE;oBAC1D,IAAI,EAAE,OAAO,CAAC,IAAI;AACnB,iBAAA,CAAC;AACF,gBAAA,MAAM,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC;gBAC5C,MAAM,MAAM,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;YAC/D;iBAAO;AACL,gBAAA,MAAM,KAAK;YACb;QACF;AACF,IAAA,CAAC;AACH;;;;"}
|
|
@@ -3,7 +3,6 @@ import '@remix-run/server-runtime';
|
|
|
3
3
|
import { redirectToAuthPage } from '../helpers/redirect-to-auth-page.mjs';
|
|
4
4
|
import { invalidateAccessToken } from '../../helpers/invalidate-access-token.mjs';
|
|
5
5
|
import 'isbot';
|
|
6
|
-
import '../../../types.mjs';
|
|
7
6
|
import { redirectOutOfApp } from './helpers.mjs';
|
|
8
7
|
|
|
9
8
|
function requestBillingFactory(params, request, session) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/request.ts"],"sourcesContent":["import {\n BillingRequestResponseObject,\n HttpResponseError,\n Session,\n} from '@shopify/shopify-api';\n\nimport {AppConfigArg} from '../../../config-types';\nimport {BasicParams} from '../../../types';\nimport {redirectToAuthPage} from '../helpers';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport {redirectOutOfApp} from './helpers';\nimport type {RequestBillingOptions} from './types';\n\nexport function requestBillingFactory<Config extends AppConfigArg>(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n return async function requestBilling({\n plan,\n isTest,\n returnUrl,\n ...overrides\n }: RequestBillingOptions<Config>): Promise<never> {\n const {api, logger} = params;\n\n logger.info('Requesting billing', {\n shop: session.shop,\n plan,\n isTest,\n returnUrl,\n });\n\n let result: BillingRequestResponseObject;\n try {\n result = await api.billing.request({\n plan: plan as string,\n session,\n isTest,\n returnUrl,\n returnObject: true,\n ...overrides,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', {\n shop: session.shop,\n });\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n\n throw redirectOutOfApp(\n params,\n request,\n result.confirmationUrl,\n session.shop,\n );\n };\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"request.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/request.ts"],"sourcesContent":["import {\n BillingRequestResponseObject,\n HttpResponseError,\n Session,\n} from '@shopify/shopify-api';\n\nimport {AppConfigArg} from '../../../config-types';\nimport {BasicParams} from '../../../types';\nimport {redirectToAuthPage} from '../helpers';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport {redirectOutOfApp} from './helpers';\nimport type {RequestBillingOptions} from './types';\n\nexport function requestBillingFactory<Config extends AppConfigArg>(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n return async function requestBilling({\n plan,\n isTest,\n returnUrl,\n ...overrides\n }: RequestBillingOptions<Config>): Promise<never> {\n const {api, logger} = params;\n\n logger.info('Requesting billing', {\n shop: session.shop,\n plan,\n isTest,\n returnUrl,\n });\n\n let result: BillingRequestResponseObject;\n try {\n result = await api.billing.request({\n plan: plan as string,\n session,\n isTest,\n returnUrl,\n returnObject: true,\n ...overrides,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', {\n shop: session.shop,\n });\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n\n throw redirectOutOfApp(\n params,\n request,\n result.confirmationUrl,\n session.shop,\n );\n };\n}\n"],"names":[],"mappings":";;;;;;;SAcgB,qBAAqB,CACnC,MAAmB,EACnB,OAAgB,EAChB,OAAgB,EAAA;AAEhB,IAAA,OAAO,eAAe,cAAc,CAAC,EACnC,IAAI,EACJ,MAAM,EACN,SAAS,EACT,GAAG,SAAS,EACkB,EAAA;AAC9B,QAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,QAAA,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE;YAChC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI;YACJ,MAAM;YACN,SAAS;AACV,SAAA,CAAC;AAEF,QAAA,IAAI,MAAoC;AACxC,QAAA,IAAI;AACF,YAAA,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;AACjC,gBAAA,IAAI,EAAE,IAAc;gBACpB,OAAO;gBACP,MAAM;gBACN,SAAS;AACT,gBAAA,YAAY,EAAE,IAAI;AAClB,gBAAA,GAAG,SAAS;AACb,aAAA,CAAC;QACJ;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,KAAK,YAAY,iBAAiB,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,EAAE;AACrE,gBAAA,MAAM,CAAC,KAAK,CAAC,6CAA6C,EAAE;oBAC1D,IAAI,EAAE,OAAO,CAAC,IAAI;AACnB,iBAAA,CAAC;AACF,gBAAA,MAAM,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC;gBAC5C,MAAM,MAAM,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;YAC/D;iBAAO;AACL,gBAAA,MAAM,KAAK;YACb;QACF;AAEA,QAAA,MAAM,gBAAgB,CACpB,MAAM,EACN,OAAO,EACP,MAAM,CAAC,eAAe,EACtB,OAAO,CAAC,IAAI,CACb;AACH,IAAA,CAAC;AACH;;;;"}
|
|
@@ -3,7 +3,6 @@ import '@remix-run/server-runtime';
|
|
|
3
3
|
import { redirectToAuthPage } from '../helpers/redirect-to-auth-page.mjs';
|
|
4
4
|
import { invalidateAccessToken } from '../../helpers/invalidate-access-token.mjs';
|
|
5
5
|
import 'isbot';
|
|
6
|
-
import '../../../types.mjs';
|
|
7
6
|
|
|
8
7
|
function requireBillingFactory(params, request, session) {
|
|
9
8
|
const { api, logger } = params;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"require.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/require.ts"],"sourcesContent":["import {\n BillingCheckResponseObject,\n HttpResponseError,\n Session,\n} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../../types';\nimport type {AppConfigArg} from '../../../config-types';\nimport {redirectToAuthPage} from '../helpers';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport type {RequireBillingOptions} from './types';\n\nexport function requireBillingFactory<Config extends AppConfigArg>(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n const {api, logger} = params;\n\n return async function requireBilling(options: RequireBillingOptions<Config>) {\n const logContext = {\n shop: session.shop,\n plans: options.plans,\n isTest: options.isTest,\n };\n\n logger.debug('Checking billing for the shop', logContext);\n\n let data: BillingCheckResponseObject;\n try {\n data = await api.billing.check({\n session,\n plans: options.plans as string[],\n isTest: options.isTest,\n returnObject: true,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', logContext);\n\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n\n if (!data.hasActivePayment) {\n logger.debug('Billing check failed', logContext);\n throw await options.onFailure(new Error('Billing check failed'));\n }\n\n logger.debug('Billing check succeeded', logContext);\n\n return data;\n };\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"require.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/require.ts"],"sourcesContent":["import {\n BillingCheckResponseObject,\n HttpResponseError,\n Session,\n} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../../types';\nimport type {AppConfigArg} from '../../../config-types';\nimport {redirectToAuthPage} from '../helpers';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport type {RequireBillingOptions} from './types';\n\nexport function requireBillingFactory<Config extends AppConfigArg>(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n const {api, logger} = params;\n\n return async function requireBilling(options: RequireBillingOptions<Config>) {\n const logContext = {\n shop: session.shop,\n plans: options.plans,\n isTest: options.isTest,\n };\n\n logger.debug('Checking billing for the shop', logContext);\n\n let data: BillingCheckResponseObject;\n try {\n data = await api.billing.check({\n session,\n plans: options.plans as string[],\n isTest: options.isTest,\n returnObject: true,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', logContext);\n\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n\n if (!data.hasActivePayment) {\n logger.debug('Billing check failed', logContext);\n throw await options.onFailure(new Error('Billing check failed'));\n }\n\n logger.debug('Billing check succeeded', logContext);\n\n return data;\n };\n}\n"],"names":[],"mappings":";;;;;;SAagB,qBAAqB,CACnC,MAAmB,EACnB,OAAgB,EAChB,OAAgB,EAAA;AAEhB,IAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,IAAA,OAAO,eAAe,cAAc,CAAC,OAAsC,EAAA;AACzE,QAAA,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB;AAED,QAAA,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,UAAU,CAAC;AAEzD,QAAA,IAAI,IAAgC;AACpC,QAAA,IAAI;AACF,YAAA,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC;gBAC7B,OAAO;gBACP,KAAK,EAAE,OAAO,CAAC,KAAiB;gBAChC,MAAM,EAAE,OAAO,CAAC,MAAM;AACtB,gBAAA,YAAY,EAAE,IAAI;AACnB,aAAA,CAAC;QACJ;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,KAAK,YAAY,iBAAiB,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,EAAE;AACrE,gBAAA,MAAM,CAAC,KAAK,CAAC,6CAA6C,EAAE,UAAU,CAAC;AAEvE,gBAAA,MAAM,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC;gBAC5C,MAAM,MAAM,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;YAC/D;iBAAO;AACL,gBAAA,MAAM,KAAK;YACb;QACF;AAEA,QAAA,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;AAC1B,YAAA,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,UAAU,CAAC;YAChD,MAAM,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAClE;AAEA,QAAA,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,UAAU,CAAC;AAEnD,QAAA,OAAO,IAAI;AACb,IAAA,CAAC;AACH;;;;"}
|
package/dist/esm/server/authenticate/admin/billing/update-usage-subscription-capped-amount.mjs
CHANGED
|
@@ -3,7 +3,6 @@ import '@remix-run/server-runtime';
|
|
|
3
3
|
import { redirectToAuthPage } from '../helpers/redirect-to-auth-page.mjs';
|
|
4
4
|
import { invalidateAccessToken } from '../../helpers/invalidate-access-token.mjs';
|
|
5
5
|
import 'isbot';
|
|
6
|
-
import '../../../types.mjs';
|
|
7
6
|
import { redirectOutOfApp } from './helpers.mjs';
|
|
8
7
|
|
|
9
8
|
function updateUsageCappedAmountFactory(params, request, session) {
|
package/dist/esm/server/authenticate/admin/billing/update-usage-subscription-capped-amount.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-usage-subscription-capped-amount.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/update-usage-subscription-capped-amount.ts"],"sourcesContent":["import {\n HttpResponseError,\n Session,\n UpdateCappedAmountConfirmation,\n} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../../types';\nimport {redirectToAuthPage} from '../helpers';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport {UpdateUsageCappedAmountOptions} from './types';\nimport {redirectOutOfApp} from './helpers';\n\nexport function updateUsageCappedAmountFactory(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n return async function updateUsageCappedAmount(\n options: UpdateUsageCappedAmountOptions,\n ): Promise<never> {\n const {api, logger} = params;\n\n logger.debug('Updating usage subscription capped amount', {\n shop: session.shop,\n ...options,\n });\n\n let result: UpdateCappedAmountConfirmation;\n try {\n result = await api.billing.updateUsageCappedAmount({\n session,\n subscriptionLineItemId: options.subscriptionLineItemId,\n cappedAmount: options.cappedAmount,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', {\n shop: session.shop,\n });\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n\n throw redirectOutOfApp(\n params,\n request,\n result.confirmationUrl,\n session.shop,\n );\n };\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update-usage-subscription-capped-amount.mjs","sources":["../../../../../../../src/server/authenticate/admin/billing/update-usage-subscription-capped-amount.ts"],"sourcesContent":["import {\n HttpResponseError,\n Session,\n UpdateCappedAmountConfirmation,\n} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../../types';\nimport {redirectToAuthPage} from '../helpers';\nimport {invalidateAccessToken} from '../../helpers';\n\nimport {UpdateUsageCappedAmountOptions} from './types';\nimport {redirectOutOfApp} from './helpers';\n\nexport function updateUsageCappedAmountFactory(\n params: BasicParams,\n request: Request,\n session: Session,\n) {\n return async function updateUsageCappedAmount(\n options: UpdateUsageCappedAmountOptions,\n ): Promise<never> {\n const {api, logger} = params;\n\n logger.debug('Updating usage subscription capped amount', {\n shop: session.shop,\n ...options,\n });\n\n let result: UpdateCappedAmountConfirmation;\n try {\n result = await api.billing.updateUsageCappedAmount({\n session,\n subscriptionLineItemId: options.subscriptionLineItemId,\n cappedAmount: options.cappedAmount,\n });\n } catch (error) {\n if (error instanceof HttpResponseError && error.response.code === 401) {\n logger.debug('API token was invalid, redirecting to OAuth', {\n shop: session.shop,\n });\n await invalidateAccessToken(params, session);\n throw await redirectToAuthPage(params, request, session.shop);\n } else {\n throw error;\n }\n }\n\n throw redirectOutOfApp(\n params,\n request,\n result.confirmationUrl,\n session.shop,\n );\n };\n}\n"],"names":[],"mappings":";;;;;;;SAagB,8BAA8B,CAC5C,MAAmB,EACnB,OAAgB,EAChB,OAAgB,EAAA;AAEhB,IAAA,OAAO,eAAe,uBAAuB,CAC3C,OAAuC,EAAA;AAEvC,QAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,QAAA,MAAM,CAAC,KAAK,CAAC,2CAA2C,EAAE;YACxD,IAAI,EAAE,OAAO,CAAC,IAAI;AAClB,YAAA,GAAG,OAAO;AACX,SAAA,CAAC;AAEF,QAAA,IAAI,MAAsC;AAC1C,QAAA,IAAI;AACF,YAAA,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,uBAAuB,CAAC;gBACjD,OAAO;gBACP,sBAAsB,EAAE,OAAO,CAAC,sBAAsB;gBACtD,YAAY,EAAE,OAAO,CAAC,YAAY;AACnC,aAAA,CAAC;QACJ;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,KAAK,YAAY,iBAAiB,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,EAAE;AACrE,gBAAA,MAAM,CAAC,KAAK,CAAC,6CAA6C,EAAE;oBAC1D,IAAI,EAAE,OAAO,CAAC,IAAI;AACnB,iBAAA,CAAC;AACF,gBAAA,MAAM,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC;gBAC5C,MAAM,MAAM,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;YAC/D;iBAAO;AACL,gBAAA,MAAM,KAAK;YACb;QACF;AAEA,QAAA,MAAM,gBAAgB,CACpB,MAAM,EACN,OAAO,EACP,MAAM,CAAC,eAAe,EACtB,OAAO,CAAC,IAAI,CACb;AACH,IAAA,CAAC;AACH;;;;"}
|
|
@@ -9,7 +9,6 @@ import { getSessionTokenHeader } from '../../helpers/get-session-token-header.mj
|
|
|
9
9
|
import { triggerAfterAuthHook } from '../helpers/trigger-after-auth-hook.mjs';
|
|
10
10
|
import { validateShopAndHostParams } from '../helpers/validate-shop-and-host-params.mjs';
|
|
11
11
|
import 'isbot';
|
|
12
|
-
import '../../../types.mjs';
|
|
13
12
|
|
|
14
13
|
class AuthCodeFlowStrategy {
|
|
15
14
|
api;
|
|
@@ -128,6 +127,7 @@ class AuthCodeFlowStrategy {
|
|
|
128
127
|
try {
|
|
129
128
|
const { session, headers: responseHeaders } = await api.auth.callback({
|
|
130
129
|
rawRequest: request,
|
|
130
|
+
expiring: config.future.expiringOfflineAccessTokens,
|
|
131
131
|
});
|
|
132
132
|
await config.sessionStorage.storeSession(session);
|
|
133
133
|
if (config.useOnlineTokens && !session.isOnline) {
|