shopify-app-js 0.0.1-security → 1.0.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.

Potentially problematic release.


This version of shopify-app-js might be problematic. Click here for more details.

Files changed (424) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +14 -0
  3. package/.changeset/flat-clouds-camp.md +5 -0
  4. package/.eslintrc.js +36 -0
  5. package/.github/CODEOWNERS +1 -0
  6. package/.github/ISSUE_TEMPLATE/BUG_REPORT.md +36 -0
  7. package/.github/ISSUE_TEMPLATE/ENHANCEMENT.md +9 -0
  8. package/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +9 -0
  9. package/.github/PULL_REQUEST_TEMPLATE.md +34 -0
  10. package/.github/dependabot.yml +9 -0
  11. package/.github/workflows/changelog.yml +30 -0
  12. package/.github/workflows/ci.yml +22 -0
  13. package/.github/workflows/cla.yml +22 -0
  14. package/.github/workflows/close-waiting-for-response-issues.yml +20 -0
  15. package/.github/workflows/main-release.yml +36 -0
  16. package/.github/workflows/markdown_link_check.yml +14 -0
  17. package/.github/workflows/markdown_link_checker_config.json +9 -0
  18. package/.github/workflows/publish-experimental-build.yml +30 -0
  19. package/.github/workflows/release-candidate.yml +35 -0
  20. package/.github/workflows/remove-labels-on-activity.yml +16 -0
  21. package/.github/workflows/stale.yml +26 -0
  22. package/.prettierignore +5 -0
  23. package/.prettierrc +1 -0
  24. package/CODE_OF_CONDUCT.md +46 -0
  25. package/CONTRIBUTING.md +39 -0
  26. package/LICENSE.md +9 -0
  27. package/README.md +62 -3
  28. package/RELEASING.md +142 -0
  29. package/loom.config.ts +115 -0
  30. package/package.json +44 -3
  31. package/packages/.prettierrc +1 -0
  32. package/packages/shopify-app-express/CHANGELOG.md +316 -0
  33. package/packages/shopify-app-express/LICENSE.md +9 -0
  34. package/packages/shopify-app-express/README.md +93 -0
  35. package/packages/shopify-app-express/docs/reference/README.md +3 -0
  36. package/packages/shopify-app-express/docs/reference/auth.md +76 -0
  37. package/packages/shopify-app-express/docs/reference/cspHeaders.md +24 -0
  38. package/packages/shopify-app-express/docs/reference/ensureInstalledOnShop.md +17 -0
  39. package/packages/shopify-app-express/docs/reference/migrating-app-v6-api-lib-to-express-lib.md +345 -0
  40. package/packages/shopify-app-express/docs/reference/processWebhooks.md +67 -0
  41. package/packages/shopify-app-express/docs/reference/redirectOutOfApp.md +77 -0
  42. package/packages/shopify-app-express/docs/reference/redirectToShopifyOrAppRoot.md +20 -0
  43. package/packages/shopify-app-express/docs/reference/shopifyApp.md +148 -0
  44. package/packages/shopify-app-express/docs/reference/validateAuthenticatedSession.md +30 -0
  45. package/packages/shopify-app-express/loom.config.ts +27 -0
  46. package/packages/shopify-app-express/package.json +54 -0
  47. package/packages/shopify-app-express/src/__tests__/index.test.ts +100 -0
  48. package/packages/shopify-app-express/src/__tests__/integration/oauth.test.ts +445 -0
  49. package/packages/shopify-app-express/src/__tests__/integration/responses.ts +135 -0
  50. package/packages/shopify-app-express/src/__tests__/integration/types.ts +22 -0
  51. package/packages/shopify-app-express/src/__tests__/integration/utils.ts +68 -0
  52. package/packages/shopify-app-express/src/__tests__/integration/webhooks.test.ts +208 -0
  53. package/packages/shopify-app-express/src/__tests__/redirect-to-auth.test.ts +103 -0
  54. package/packages/shopify-app-express/src/__tests__/setup-jest.ts +8 -0
  55. package/packages/shopify-app-express/src/__tests__/test-helper.ts +204 -0
  56. package/packages/shopify-app-express/src/app-installations.ts +42 -0
  57. package/packages/shopify-app-express/src/auth/__tests__/auth.test.ts +303 -0
  58. package/packages/shopify-app-express/src/auth/auth-callback.ts +131 -0
  59. package/packages/shopify-app-express/src/auth/index.ts +32 -0
  60. package/packages/shopify-app-express/src/auth/types.ts +13 -0
  61. package/packages/shopify-app-express/src/config-types.ts +38 -0
  62. package/packages/shopify-app-express/src/error.ts +8 -0
  63. package/packages/shopify-app-express/src/index.ts +171 -0
  64. package/packages/shopify-app-express/src/middlewares/__tests__/csp-headers.test.ts +69 -0
  65. package/packages/shopify-app-express/src/middlewares/__tests__/ensure-installed-on-shop.test.ts +193 -0
  66. package/packages/shopify-app-express/src/middlewares/__tests__/redirect-to-shopify-or-app-root.test.ts +59 -0
  67. package/packages/shopify-app-express/src/middlewares/__tests__/validate-authenticated-session.test.ts +319 -0
  68. package/packages/shopify-app-express/src/middlewares/csp-headers.ts +31 -0
  69. package/packages/shopify-app-express/src/middlewares/ensure-installed-on-shop.ts +176 -0
  70. package/packages/shopify-app-express/src/middlewares/has-valid-access-token.ts +25 -0
  71. package/packages/shopify-app-express/src/middlewares/index.ts +15 -0
  72. package/packages/shopify-app-express/src/middlewares/redirect-to-shopify-or-app-root.ts +39 -0
  73. package/packages/shopify-app-express/src/middlewares/types.ts +6 -0
  74. package/packages/shopify-app-express/src/middlewares/validate-authenticated-session.ts +142 -0
  75. package/packages/shopify-app-express/src/redirect-out-of-app.ts +80 -0
  76. package/packages/shopify-app-express/src/redirect-to-auth.ts +70 -0
  77. package/packages/shopify-app-express/src/types.ts +26 -0
  78. package/packages/shopify-app-express/src/version.ts +1 -0
  79. package/packages/shopify-app-express/src/webhooks/__tests__/process.test.ts +138 -0
  80. package/packages/shopify-app-express/src/webhooks/index.ts +54 -0
  81. package/packages/shopify-app-express/src/webhooks/process.ts +22 -0
  82. package/packages/shopify-app-express/src/webhooks/types.ts +24 -0
  83. package/packages/shopify-app-express/tsconfig.json +10 -0
  84. package/packages/shopify-app-remix/.eslintrc.js +3 -0
  85. package/packages/shopify-app-remix/CHANGELOG.md +569 -0
  86. package/packages/shopify-app-remix/LICENSE.md +9 -0
  87. package/packages/shopify-app-remix/README.md +223 -0
  88. package/packages/shopify-app-remix/docs/build-docs.sh +11 -0
  89. package/packages/shopify-app-remix/docs/generated/generated_docs_data.json +18650 -0
  90. package/packages/shopify-app-remix/docs/generated/generated_static_pages.json +540 -0
  91. package/packages/shopify-app-remix/docs/staticPages/admin.doc.ts +130 -0
  92. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/auth-cors.example.tsx +11 -0
  93. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/auth.example.tsx +19 -0
  94. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/graphql.example.tsx +29 -0
  95. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/headers.example.tsx +10 -0
  96. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/rest-resources.example.tsx +9 -0
  97. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/rest.example.tsx +17 -0
  98. package/packages/shopify-app-remix/docs/staticPages/examples/guides/future-flags/config.example.ts +8 -0
  99. package/packages/shopify-app-remix/docs/staticPages/examples/guides/future-flags/unstable.example.ts +9 -0
  100. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/.graphqlrc.ts +16 -0
  101. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/install.npm.example.sh +2 -0
  102. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/install.pnpm.example.sh +2 -0
  103. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/install.yarn.example.sh +2 -0
  104. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/package.json +5 -0
  105. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/run.npm.example.sh +1 -0
  106. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/run.pnpm.example.sh +1 -0
  107. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/run.yarn.example.sh +1 -0
  108. package/packages/shopify-app-remix/docs/staticPages/examples/guides/webhooks/config.example.ts +19 -0
  109. package/packages/shopify-app-remix/docs/staticPages/examples/guides/webhooks/endpoint.example.ts +24 -0
  110. package/packages/shopify-app-remix/docs/staticPages/examples/index/app-provider.example.ts +30 -0
  111. package/packages/shopify-app-remix/docs/staticPages/examples/index/boundaries.example.ts +9 -0
  112. package/packages/shopify-app-remix/docs/staticPages/examples/index/create.npm.example.sh +1 -0
  113. package/packages/shopify-app-remix/docs/staticPages/examples/index/create.pnpm.example.sh +1 -0
  114. package/packages/shopify-app-remix/docs/staticPages/examples/index/create.yarn.example.sh +1 -0
  115. package/packages/shopify-app-remix/docs/staticPages/examples/index/embedded-app-auth-strategy-config.example.ts +10 -0
  116. package/packages/shopify-app-remix/docs/staticPages/examples/index/entry-server.example.ts +12 -0
  117. package/packages/shopify-app-remix/docs/staticPages/examples/index/install.npm.example.sh +1 -0
  118. package/packages/shopify-app-remix/docs/staticPages/examples/index/install.pnpm.example.sh +1 -0
  119. package/packages/shopify-app-remix/docs/staticPages/examples/index/install.yarn.example.sh +1 -0
  120. package/packages/shopify-app-remix/docs/staticPages/examples/index/shopify-app.example.ts +14 -0
  121. package/packages/shopify-app-remix/docs/staticPages/examples/index/splat-route.example.ts +11 -0
  122. package/packages/shopify-app-remix/docs/staticPages/future-flags.doc.ts +94 -0
  123. package/packages/shopify-app-remix/docs/staticPages/graphql-types.doc.ts +148 -0
  124. package/packages/shopify-app-remix/docs/staticPages/index.doc.ts +227 -0
  125. package/packages/shopify-app-remix/docs/staticPages/webhooks.doc.ts +64 -0
  126. package/packages/shopify-app-remix/docs/tsconfig.docs.json +9 -0
  127. package/packages/shopify-app-remix/docs/typeOverride.json +1 -0
  128. package/packages/shopify-app-remix/docs/upcoming_changes.md +153 -0
  129. package/packages/shopify-app-remix/loom.config.ts +57 -0
  130. package/packages/shopify-app-remix/package.json +93 -0
  131. package/packages/shopify-app-remix/src/react/.eslintrc.js +16 -0
  132. package/packages/shopify-app-remix/src/react/__tests__/test-helper.ts +22 -0
  133. package/packages/shopify-app-remix/src/react/components/AppProvider/AppProvider.doc.ts +34 -0
  134. package/packages/shopify-app-remix/src/react/components/AppProvider/AppProvider.tsx +121 -0
  135. package/packages/shopify-app-remix/src/react/components/AppProvider/__tests__/AppProvider.test.tsx +68 -0
  136. package/packages/shopify-app-remix/src/react/components/AppProvider/index.ts +1 -0
  137. package/packages/shopify-app-remix/src/react/components/RemixPolarisLink.tsx +14 -0
  138. package/packages/shopify-app-remix/src/react/components/index.ts +1 -0
  139. package/packages/shopify-app-remix/src/react/const.ts +2 -0
  140. package/packages/shopify-app-remix/src/react/index.ts +1 -0
  141. package/packages/shopify-app-remix/src/server/.eslintrc.js +16 -0
  142. package/packages/shopify-app-remix/src/server/__test-helpers/__tests__/request-mock.test.ts +171 -0
  143. package/packages/shopify-app-remix/src/server/__test-helpers/const.ts +11 -0
  144. package/packages/shopify-app-remix/src/server/__test-helpers/expect-admin-api-client.ts +119 -0
  145. package/packages/shopify-app-remix/src/server/__test-helpers/expect-begin-auth-redirect.ts +22 -0
  146. package/packages/shopify-app-remix/src/server/__test-helpers/expect-document-request-headers.ts +25 -0
  147. package/packages/shopify-app-remix/src/server/__test-helpers/expect-exit-iframe.ts +37 -0
  148. package/packages/shopify-app-remix/src/server/__test-helpers/expect-login-redirect.ts +8 -0
  149. package/packages/shopify-app-remix/src/server/__test-helpers/expect-storefront-api-client.ts +50 -0
  150. package/packages/shopify-app-remix/src/server/__test-helpers/get-hmac.ts +10 -0
  151. package/packages/shopify-app-remix/src/server/__test-helpers/get-jwt.ts +31 -0
  152. package/packages/shopify-app-remix/src/server/__test-helpers/get-thrown-response.ts +17 -0
  153. package/packages/shopify-app-remix/src/server/__test-helpers/index.ts +14 -0
  154. package/packages/shopify-app-remix/src/server/__test-helpers/request-mock.ts +169 -0
  155. package/packages/shopify-app-remix/src/server/__test-helpers/setup-valid-session.ts +45 -0
  156. package/packages/shopify-app-remix/src/server/__test-helpers/sign-request-cookie.ts +21 -0
  157. package/packages/shopify-app-remix/src/server/__test-helpers/test-config.ts +112 -0
  158. package/packages/shopify-app-remix/src/server/__tests__/override-logger.test.ts +101 -0
  159. package/packages/shopify-app-remix/src/server/__tests__/shopify-app.test.ts +119 -0
  160. package/packages/shopify-app-remix/src/server/adapters/__tests__/node-app-bridge-url.test.ts +18 -0
  161. package/packages/shopify-app-remix/src/server/adapters/__tests__/node.test.ts +28 -0
  162. package/packages/shopify-app-remix/src/server/adapters/node/__tests__/setup-jest.ts +10 -0
  163. package/packages/shopify-app-remix/src/server/adapters/node/index.ts +20 -0
  164. package/packages/shopify-app-remix/src/server/adapters/vercel/__tests__/setup-jest.ts +12 -0
  165. package/packages/shopify-app-remix/src/server/adapters/vercel/index.ts +13 -0
  166. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/admin-client.test.ts +181 -0
  167. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/doc-request-path.test.ts +151 -0
  168. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/exit-i-frame-path.test.ts +99 -0
  169. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/patch-session-token-path.test.ts +58 -0
  170. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/reject-bot.test.ts +23 -0
  171. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/respond-to-options.test.ts +50 -0
  172. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/session-token-header-path.test.ts +91 -0
  173. package/packages/shopify-app-remix/src/server/authenticate/admin/authenticate.admin.doc.ts +37 -0
  174. package/packages/shopify-app-remix/src/server/authenticate/admin/authenticate.ts +201 -0
  175. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/__tests__/cancel.test.ts +258 -0
  176. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/__tests__/check.test.ts +254 -0
  177. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/__tests__/mock-responses.ts +65 -0
  178. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/__tests__/request.test.ts +373 -0
  179. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/__tests__/require.test.ts +316 -0
  180. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/authenticate.admin.billing.doc.ts +28 -0
  181. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/cancel.ts +37 -0
  182. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/check.ts +38 -0
  183. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/index.ts +4 -0
  184. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/request.ts +101 -0
  185. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/require.ts +56 -0
  186. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/types.ts +383 -0
  187. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/__tests__/redirect.test.ts +313 -0
  188. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/__tests__/validate-redirect-url.test.ts +84 -0
  189. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/begin-auth.ts +17 -0
  190. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/create-admin-api-context.ts +22 -0
  191. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/ensure-app-is-embedded-if-required.ts +18 -0
  192. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/ensure-session-token-search-param-if-required.ts +25 -0
  193. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/handle-client-error.ts +43 -0
  194. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/index.ts +14 -0
  195. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect-to-auth-page.ts +28 -0
  196. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect-to-bounce-page.ts +23 -0
  197. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect-to-shopify-or-app-root.ts +21 -0
  198. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect-with-app-bridge-headers.ts +13 -0
  199. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect-with-exitiframe.ts +28 -0
  200. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect.ts +83 -0
  201. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/render-app-bridge.ts +46 -0
  202. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/trigger-after-auth-hook.ts +28 -0
  203. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/validate-redirect-url.ts +67 -0
  204. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/validate-shop-and-host-params.ts +28 -0
  205. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/admin-client.test.ts +222 -0
  206. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/auth-callback-path.test.ts +395 -0
  207. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/auth-path.test.ts +83 -0
  208. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/authenticate.test.ts +183 -0
  209. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/ensure-installed-on-shop.test.ts +234 -0
  210. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/session-token-header-path.test.ts +79 -0
  211. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/token-exchange/admin-client.test.ts +189 -0
  212. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/token-exchange/authenticate.test.ts +310 -0
  213. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/auth-code-flow.ts +333 -0
  214. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/token-exchange.ts +169 -0
  215. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/types.ts +29 -0
  216. package/packages/shopify-app-remix/src/server/authenticate/admin/types.ts +199 -0
  217. package/packages/shopify-app-remix/src/server/authenticate/const.ts +15 -0
  218. package/packages/shopify-app-remix/src/server/authenticate/flow/__tests__/authenticate.test.ts +142 -0
  219. package/packages/shopify-app-remix/src/server/authenticate/flow/authenticate.flow.doc.ts +34 -0
  220. package/packages/shopify-app-remix/src/server/authenticate/flow/authenticate.ts +71 -0
  221. package/packages/shopify-app-remix/src/server/authenticate/flow/types.ts +90 -0
  222. package/packages/shopify-app-remix/src/server/authenticate/helpers/__tests__/add-response-headers.test.ts +25 -0
  223. package/packages/shopify-app-remix/src/server/authenticate/helpers/__tests__/app-bridge-url.test.ts +21 -0
  224. package/packages/shopify-app-remix/src/server/authenticate/helpers/__tests__/idempotent-promise-handler.test.ts +104 -0
  225. package/packages/shopify-app-remix/src/server/authenticate/helpers/add-response-headers.ts +43 -0
  226. package/packages/shopify-app-remix/src/server/authenticate/helpers/app-bridge-url.ts +10 -0
  227. package/packages/shopify-app-remix/src/server/authenticate/helpers/ensure-cors-headers.ts +38 -0
  228. package/packages/shopify-app-remix/src/server/authenticate/helpers/get-session-token-header.ts +11 -0
  229. package/packages/shopify-app-remix/src/server/authenticate/helpers/idempotent-promise-handler.ts +45 -0
  230. package/packages/shopify-app-remix/src/server/authenticate/helpers/index.ts +8 -0
  231. package/packages/shopify-app-remix/src/server/authenticate/helpers/reject-bot-request.ts +13 -0
  232. package/packages/shopify-app-remix/src/server/authenticate/helpers/respond-to-invalid-session-token.ts +29 -0
  233. package/packages/shopify-app-remix/src/server/authenticate/helpers/respond-to-options-request.ts +26 -0
  234. package/packages/shopify-app-remix/src/server/authenticate/helpers/validate-session-token.ts +32 -0
  235. package/packages/shopify-app-remix/src/server/authenticate/login/__tests__/login.test.ts +157 -0
  236. package/packages/shopify-app-remix/src/server/authenticate/login/login.ts +53 -0
  237. package/packages/shopify-app-remix/src/server/authenticate/public/__tests__/factory.test.ts +224 -0
  238. package/packages/shopify-app-remix/src/server/authenticate/public/appProxy/__tests__/authenticate.test.ts +282 -0
  239. package/packages/shopify-app-remix/src/server/authenticate/public/appProxy/authenticate.public.app-proxy.doc.ts +36 -0
  240. package/packages/shopify-app-remix/src/server/authenticate/public/appProxy/authenticate.ts +90 -0
  241. package/packages/shopify-app-remix/src/server/authenticate/public/appProxy/types.ts +164 -0
  242. package/packages/shopify-app-remix/src/server/authenticate/public/checkout/__tests__/authenticate.test.ts +142 -0
  243. package/packages/shopify-app-remix/src/server/authenticate/public/checkout/authenticate.public.checkout.doc.ts +23 -0
  244. package/packages/shopify-app-remix/src/server/authenticate/public/checkout/authenticate.ts +45 -0
  245. package/packages/shopify-app-remix/src/server/authenticate/public/checkout/types.ts +65 -0
  246. package/packages/shopify-app-remix/src/server/authenticate/public/factory.ts +49 -0
  247. package/packages/shopify-app-remix/src/server/authenticate/public/index.ts +1 -0
  248. package/packages/shopify-app-remix/src/server/authenticate/public/types.ts +77 -0
  249. package/packages/shopify-app-remix/src/server/authenticate/webhooks/__tests__/authenticate.test.ts +207 -0
  250. package/packages/shopify-app-remix/src/server/authenticate/webhooks/__tests__/mock-responses.ts +45 -0
  251. package/packages/shopify-app-remix/src/server/authenticate/webhooks/__tests__/register.test.ts +210 -0
  252. package/packages/shopify-app-remix/src/server/authenticate/webhooks/authenticate.ts +113 -0
  253. package/packages/shopify-app-remix/src/server/authenticate/webhooks/authenticate.webhooks.doc.ts +28 -0
  254. package/packages/shopify-app-remix/src/server/authenticate/webhooks/index.ts +1 -0
  255. package/packages/shopify-app-remix/src/server/authenticate/webhooks/register.ts +48 -0
  256. package/packages/shopify-app-remix/src/server/authenticate/webhooks/types.ts +246 -0
  257. package/packages/shopify-app-remix/src/server/boundary/__tests__/error.test.tsx +36 -0
  258. package/packages/shopify-app-remix/src/server/boundary/__tests__/headers.test.ts +66 -0
  259. package/packages/shopify-app-remix/src/server/boundary/error.tsx +14 -0
  260. package/packages/shopify-app-remix/src/server/boundary/headers.ts +15 -0
  261. package/packages/shopify-app-remix/src/server/boundary/index.ts +39 -0
  262. package/packages/shopify-app-remix/src/server/boundary/types.ts +4 -0
  263. package/packages/shopify-app-remix/src/server/clients/admin/authenticate.admin.api.doc.ts +34 -0
  264. package/packages/shopify-app-remix/src/server/clients/admin/factory.ts +30 -0
  265. package/packages/shopify-app-remix/src/server/clients/admin/graphql.ts +39 -0
  266. package/packages/shopify-app-remix/src/server/clients/admin/index.ts +2 -0
  267. package/packages/shopify-app-remix/src/server/clients/admin/rest.ts +157 -0
  268. package/packages/shopify-app-remix/src/server/clients/admin/types.ts +178 -0
  269. package/packages/shopify-app-remix/src/server/clients/index.ts +2 -0
  270. package/packages/shopify-app-remix/src/server/clients/storefront/authenticate.storefront.api.doc.ts +34 -0
  271. package/packages/shopify-app-remix/src/server/clients/storefront/factory.ts +32 -0
  272. package/packages/shopify-app-remix/src/server/clients/storefront/index.ts +2 -0
  273. package/packages/shopify-app-remix/src/server/clients/storefront/types.ts +31 -0
  274. package/packages/shopify-app-remix/src/server/clients/types.ts +27 -0
  275. package/packages/shopify-app-remix/src/server/config-types.ts +293 -0
  276. package/packages/shopify-app-remix/src/server/errors.ts +3 -0
  277. package/packages/shopify-app-remix/src/server/future/flags.ts +57 -0
  278. package/packages/shopify-app-remix/src/server/index.ts +20 -0
  279. package/packages/shopify-app-remix/src/server/override-logger.ts +42 -0
  280. package/packages/shopify-app-remix/src/server/shopify-app.doc.ts +45 -0
  281. package/packages/shopify-app-remix/src/server/shopify-app.ts +198 -0
  282. package/packages/shopify-app-remix/src/server/types.ts +509 -0
  283. package/packages/shopify-app-remix/src/server/unauthenticated/admin/__tests__/factory.test.ts +30 -0
  284. package/packages/shopify-app-remix/src/server/unauthenticated/admin/factory.ts +29 -0
  285. package/packages/shopify-app-remix/src/server/unauthenticated/admin/index.ts +1 -0
  286. package/packages/shopify-app-remix/src/server/unauthenticated/admin/types.ts +117 -0
  287. package/packages/shopify-app-remix/src/server/unauthenticated/admin/unauthenticated.admin.doc.ts +40 -0
  288. package/packages/shopify-app-remix/src/server/unauthenticated/helpers/get-offline-session.ts +13 -0
  289. package/packages/shopify-app-remix/src/server/unauthenticated/helpers/index.ts +1 -0
  290. package/packages/shopify-app-remix/src/server/unauthenticated/storefront/__tests__/factory.test.ts +30 -0
  291. package/packages/shopify-app-remix/src/server/unauthenticated/storefront/factory.ts +28 -0
  292. package/packages/shopify-app-remix/src/server/unauthenticated/storefront/index.ts +1 -0
  293. package/packages/shopify-app-remix/src/server/unauthenticated/storefront/types.ts +39 -0
  294. package/packages/shopify-app-remix/src/server/unauthenticated/storefront/unauthenticated.storefront.doc.ts +40 -0
  295. package/packages/shopify-app-remix/src/server/unauthenticated/types.ts +68 -0
  296. package/packages/shopify-app-remix/src/server/version.ts +1 -0
  297. package/packages/shopify-app-remix/tsconfig.json +11 -0
  298. package/packages/shopify-app-session-storage/CHANGELOG.md +149 -0
  299. package/packages/shopify-app-session-storage/LICENSE.md +9 -0
  300. package/packages/shopify-app-session-storage/README.md +5 -0
  301. package/packages/shopify-app-session-storage/implementing-session-storage.md +214 -0
  302. package/packages/shopify-app-session-storage/loom.config.ts +45 -0
  303. package/packages/shopify-app-session-storage/package.json +44 -0
  304. package/packages/shopify-app-session-storage/src/__tests__/setup-jest.ts +8 -0
  305. package/packages/shopify-app-session-storage/src/abstract-migration-engine.ts +53 -0
  306. package/packages/shopify-app-session-storage/src/index.ts +3 -0
  307. package/packages/shopify-app-session-storage/src/rdbms-session-storage-migrator.ts +59 -0
  308. package/packages/shopify-app-session-storage/src/types.ts +174 -0
  309. package/packages/shopify-app-session-storage/tsconfig.json +10 -0
  310. package/packages/shopify-app-session-storage-dynamodb/CHANGELOG.md +150 -0
  311. package/packages/shopify-app-session-storage-dynamodb/LICENSE.md +9 -0
  312. package/packages/shopify-app-session-storage-dynamodb/README.md +75 -0
  313. package/packages/shopify-app-session-storage-dynamodb/loom.config.ts +27 -0
  314. package/packages/shopify-app-session-storage-dynamodb/package.json +51 -0
  315. package/packages/shopify-app-session-storage-dynamodb/src/__tests__/dynamodb.test.ts +93 -0
  316. package/packages/shopify-app-session-storage-dynamodb/src/__tests__/setup-jest.ts +8 -0
  317. package/packages/shopify-app-session-storage-dynamodb/src/dynamodb.ts +126 -0
  318. package/packages/shopify-app-session-storage-dynamodb/tsconfig.json +10 -0
  319. package/packages/shopify-app-session-storage-kv/CHANGELOG.md +204 -0
  320. package/packages/shopify-app-session-storage-kv/LICENSE.md +9 -0
  321. package/packages/shopify-app-session-storage-kv/README.md +41 -0
  322. package/packages/shopify-app-session-storage-kv/loom.config.ts +27 -0
  323. package/packages/shopify-app-session-storage-kv/package.json +52 -0
  324. package/packages/shopify-app-session-storage-kv/src/__tests__/kv-namespace-dummy-worker.ts +8 -0
  325. package/packages/shopify-app-session-storage-kv/src/__tests__/kv.test.ts +22 -0
  326. package/packages/shopify-app-session-storage-kv/src/__tests__/setup-jest.ts +8 -0
  327. package/packages/shopify-app-session-storage-kv/src/kv.ts +87 -0
  328. package/packages/shopify-app-session-storage-kv/tsconfig.json +11 -0
  329. package/packages/shopify-app-session-storage-memory/CHANGELOG.md +190 -0
  330. package/packages/shopify-app-session-storage-memory/LICENSE.md +9 -0
  331. package/packages/shopify-app-session-storage-memory/README.md +19 -0
  332. package/packages/shopify-app-session-storage-memory/loom.config.ts +27 -0
  333. package/packages/shopify-app-session-storage-memory/package.json +46 -0
  334. package/packages/shopify-app-session-storage-memory/src/__tests__/memory.test.ts +12 -0
  335. package/packages/shopify-app-session-storage-memory/src/__tests__/setup-jest.ts +8 -0
  336. package/packages/shopify-app-session-storage-memory/src/memory.ts +34 -0
  337. package/packages/shopify-app-session-storage-memory/tsconfig.json +10 -0
  338. package/packages/shopify-app-session-storage-mongodb/CHANGELOG.md +208 -0
  339. package/packages/shopify-app-session-storage-mongodb/LICENSE.md +9 -0
  340. package/packages/shopify-app-session-storage-mongodb/README.md +30 -0
  341. package/packages/shopify-app-session-storage-mongodb/loom.config.ts +27 -0
  342. package/packages/shopify-app-session-storage-mongodb/package.json +49 -0
  343. package/packages/shopify-app-session-storage-mongodb/src/__tests__/mongodb.test.ts +54 -0
  344. package/packages/shopify-app-session-storage-mongodb/src/__tests__/setup-jest.ts +8 -0
  345. package/packages/shopify-app-session-storage-mongodb/src/mongodb.ts +120 -0
  346. package/packages/shopify-app-session-storage-mongodb/tsconfig.json +10 -0
  347. package/packages/shopify-app-session-storage-mysql/CHANGELOG.md +220 -0
  348. package/packages/shopify-app-session-storage-mysql/LICENSE.md +9 -0
  349. package/packages/shopify-app-session-storage-mysql/README.md +41 -0
  350. package/packages/shopify-app-session-storage-mysql/loom.config.ts +27 -0
  351. package/packages/shopify-app-session-storage-mysql/package.json +50 -0
  352. package/packages/shopify-app-session-storage-mysql/src/__tests__/mysql.test.ts +137 -0
  353. package/packages/shopify-app-session-storage-mysql/src/__tests__/setup-jest.ts +8 -0
  354. package/packages/shopify-app-session-storage-mysql/src/migrations.ts +18 -0
  355. package/packages/shopify-app-session-storage-mysql/src/mysql-connection.ts +108 -0
  356. package/packages/shopify-app-session-storage-mysql/src/mysql-migrator.ts +53 -0
  357. package/packages/shopify-app-session-storage-mysql/src/mysql.ts +178 -0
  358. package/packages/shopify-app-session-storage-mysql/tsconfig.json +10 -0
  359. package/packages/shopify-app-session-storage-postgresql/CHANGELOG.md +210 -0
  360. package/packages/shopify-app-session-storage-postgresql/LICENSE.md +9 -0
  361. package/packages/shopify-app-session-storage-postgresql/README.md +39 -0
  362. package/packages/shopify-app-session-storage-postgresql/loom.config.ts +27 -0
  363. package/packages/shopify-app-session-storage-postgresql/package.json +52 -0
  364. package/packages/shopify-app-session-storage-postgresql/src/__tests__/migrate-to-case-sensitivity.test.ts +344 -0
  365. package/packages/shopify-app-session-storage-postgresql/src/__tests__/postgresql.test.ts +136 -0
  366. package/packages/shopify-app-session-storage-postgresql/src/__tests__/setup-jest.ts +8 -0
  367. package/packages/shopify-app-session-storage-postgresql/src/migrations.ts +70 -0
  368. package/packages/shopify-app-session-storage-postgresql/src/postgres-connection.ts +94 -0
  369. package/packages/shopify-app-session-storage-postgresql/src/postgres-migrator.ts +27 -0
  370. package/packages/shopify-app-session-storage-postgresql/src/postgresql.ts +178 -0
  371. package/packages/shopify-app-session-storage-postgresql/tsconfig.json +10 -0
  372. package/packages/shopify-app-session-storage-prisma/CHANGELOG.md +148 -0
  373. package/packages/shopify-app-session-storage-prisma/LICENSE.md +9 -0
  374. package/packages/shopify-app-session-storage-prisma/README.md +68 -0
  375. package/packages/shopify-app-session-storage-prisma/loom.config.ts +27 -0
  376. package/packages/shopify-app-session-storage-prisma/package.json +51 -0
  377. package/packages/shopify-app-session-storage-prisma/prisma/migrations/20230425184828_init/migration.sql +11 -0
  378. package/packages/shopify-app-session-storage-prisma/prisma/migrations/20230906155758_mySession/migration.sql +11 -0
  379. package/packages/shopify-app-session-storage-prisma/prisma/migrations/migration_lock.toml +3 -0
  380. package/packages/shopify-app-session-storage-prisma/prisma/schema.prisma +30 -0
  381. package/packages/shopify-app-session-storage-prisma/src/__tests__/prisma.test.ts +66 -0
  382. package/packages/shopify-app-session-storage-prisma/src/__tests__/setup-jest.ts +8 -0
  383. package/packages/shopify-app-session-storage-prisma/src/prisma.ts +145 -0
  384. package/packages/shopify-app-session-storage-prisma/tsconfig.json +10 -0
  385. package/packages/shopify-app-session-storage-redis/CHANGELOG.md +200 -0
  386. package/packages/shopify-app-session-storage-redis/LICENSE.md +9 -0
  387. package/packages/shopify-app-session-storage-redis/README.md +38 -0
  388. package/packages/shopify-app-session-storage-redis/loom.config.ts +27 -0
  389. package/packages/shopify-app-session-storage-redis/package.json +50 -0
  390. package/packages/shopify-app-session-storage-redis/src/__tests__/migration-test-data.ts +46 -0
  391. package/packages/shopify-app-session-storage-redis/src/__tests__/redis.conf +2 -0
  392. package/packages/shopify-app-session-storage-redis/src/__tests__/redis.test.ts +236 -0
  393. package/packages/shopify-app-session-storage-redis/src/__tests__/setup-jest.ts +8 -0
  394. package/packages/shopify-app-session-storage-redis/src/migrations.ts +36 -0
  395. package/packages/shopify-app-session-storage-redis/src/redis-connection.ts +64 -0
  396. package/packages/shopify-app-session-storage-redis/src/redis-migrator.ts +58 -0
  397. package/packages/shopify-app-session-storage-redis/src/redis.ts +167 -0
  398. package/packages/shopify-app-session-storage-redis/tsconfig.json +10 -0
  399. package/packages/shopify-app-session-storage-sqlite/CHANGELOG.md +202 -0
  400. package/packages/shopify-app-session-storage-sqlite/LICENSE.md +9 -0
  401. package/packages/shopify-app-session-storage-sqlite/README.md +25 -0
  402. package/packages/shopify-app-session-storage-sqlite/loom.config.ts +27 -0
  403. package/packages/shopify-app-session-storage-sqlite/package.json +51 -0
  404. package/packages/shopify-app-session-storage-sqlite/src/__tests__/setup-jest.ts +8 -0
  405. package/packages/shopify-app-session-storage-sqlite/src/__tests__/sqlite.test.ts +44 -0
  406. package/packages/shopify-app-session-storage-sqlite/src/migrations.ts +54 -0
  407. package/packages/shopify-app-session-storage-sqlite/src/sqlite-connection.ts +80 -0
  408. package/packages/shopify-app-session-storage-sqlite/src/sqlite-migrator.ts +34 -0
  409. package/packages/shopify-app-session-storage-sqlite/src/sqlite.ts +147 -0
  410. package/packages/shopify-app-session-storage-sqlite/tsconfig.json +10 -0
  411. package/packages/shopify-app-session-storage-test-utils/CHANGELOG.md +185 -0
  412. package/packages/shopify-app-session-storage-test-utils/LICENSE.md +9 -0
  413. package/packages/shopify-app-session-storage-test-utils/loom.config.ts +27 -0
  414. package/packages/shopify-app-session-storage-test-utils/package.json +48 -0
  415. package/packages/shopify-app-session-storage-test-utils/src/__tests__/session-test-utils.test.ts +273 -0
  416. package/packages/shopify-app-session-storage-test-utils/src/battery-of-tests.ts +250 -0
  417. package/packages/shopify-app-session-storage-test-utils/src/index.ts +2 -0
  418. package/packages/shopify-app-session-storage-test-utils/src/session-test-utils.ts +24 -0
  419. package/packages/shopify-app-session-storage-test-utils/src/utils.ts +71 -0
  420. package/packages/shopify-app-session-storage-test-utils/tsconfig.json +10 -0
  421. package/tests/setup/build.js +1 -0
  422. package/tests/setup/setup-jest.ts +8 -0
  423. package/tsconfig.base.json +41 -0
  424. package/tsconfig.json +19 -0
@@ -0,0 +1,93 @@
1
+ # `@shopify/shopify-app-express`
2
+
3
+ <!-- ![Build Status]() -->
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE.md)
6
+ [![npm version](https://badge.fury.io/js/%40shopify%2Fshopify-app-express.svg)](https://badge.fury.io/js/%40shopify%2Fshopify-app-express)
7
+
8
+ This package makes it easy for [Express.js](https://expressjs.com/) apps to integrate with Shopify.
9
+ It builds on the `@shopify/shopify-api` package and creates a middleware layer that allows the app to communicate with and authenticate requests from Shopify.
10
+
11
+ > **Note**: this package will enable your app's backend to work with Shopify APIs, and by default it will behave as an [embedded app](https://shopify.dev/docs/apps/auth/oauth/session-tokens). You'll need to use [Shopify App Bridge](https://shopify.dev/docs/apps/tools/app-bridge) in your frontend to authenticate requests to the backend.
12
+
13
+ ## Requirements
14
+
15
+ To follow these usage guides, you will need to:
16
+
17
+ - have a Shopify Partner account and development store
18
+ - have an app already set up on your partner account
19
+ - have a JavaScript package manager such as [yarn](https://yarnpkg.com) installed
20
+
21
+ ## Getting started
22
+
23
+ To install this package, you can run this on your terminal:
24
+
25
+ ```bash
26
+ # Create your project folder
27
+ mkdir /my/project/path
28
+ # Set up a new yarn project
29
+ yarn init .
30
+ # You can use your preferred Node package manager
31
+ yarn add @shopify/shopify-app-express
32
+ ```
33
+
34
+ Then, you can import the package in your app by creating an `index.js` file containing:
35
+
36
+ ```ts
37
+ const express = require('express');
38
+ const {shopifyApp} = require('@shopify/shopify-app-express');
39
+
40
+ const PORT = 8080;
41
+
42
+ const shopify = shopifyApp({
43
+ api: {
44
+ apiKey: 'ApiKeyFromPartnersDashboard',
45
+ apiSecretKey: 'ApiSecretKeyFromPartnersDashboard',
46
+ scopes: ['your_scopes'],
47
+ hostScheme: 'http',
48
+ hostName: `localhost:${PORT}`,
49
+ },
50
+ auth: {
51
+ path: '/api/auth',
52
+ callbackPath: '/api/auth/callback',
53
+ },
54
+ webhooks: {
55
+ path: '/api/webhooks',
56
+ },
57
+ });
58
+
59
+ const app = express();
60
+
61
+ app.get(shopify.config.auth.path, shopify.auth.begin());
62
+ app.get(
63
+ shopify.config.auth.callbackPath,
64
+ shopify.auth.callback(),
65
+ shopify.redirectToShopifyOrAppRoot(),
66
+ );
67
+ app.post(
68
+ shopify.config.webhooks.path,
69
+ shopify.processWebhooks({webhookHandlers}),
70
+ );
71
+
72
+ app.get('/', shopify.ensureInstalledOnShop(), (req, res) => {
73
+ res.send('Hello world!');
74
+ });
75
+
76
+ app.listen(PORT, () => console.log('Server started'));
77
+ ```
78
+
79
+ Once you set the appropriate configuration values, you can then run your Express app as usual, for instance using:
80
+
81
+ ```bash
82
+ node ./index.js
83
+ ```
84
+
85
+ To load your app within the Shopify Admin app, you need to:
86
+
87
+ 1. Update your app's URL in your Partners Dashboard app setup page to `http://localhost:8080`
88
+ 1. Update your app's callback URL to `http://localhost:8080/api/auth/callback` in that same page
89
+ 1. Go to **Test your app** in Partners Dashboard and select your development store
90
+
91
+ ## Next steps
92
+
93
+ Now that your app is up and running, you can learn more about the `shopifyApp` object in [the reference docs](./docs/reference/shopifyApp.md).
@@ -0,0 +1,3 @@
1
+ # Package reference
2
+
3
+ - [`shopifyApp`](./shopifyApp.md)
@@ -0,0 +1,76 @@
1
+ # `shopify.auth`
2
+
3
+ This object contains two express middleware functions: `begin` and `callback`.
4
+
5
+ When setting up the OAuth routes, the app must redirect the user to the appropriate location.
6
+ By default, we recommend using the `shopify.redirectToShopifyOrAppRoot` middleware to load your app in the correct location, but you can choose to redirect anywhere else.
7
+
8
+ ## Properties
9
+
10
+ ### `begin`
11
+
12
+ `() => RequestHandler`
13
+
14
+ This function returns an Express middleware that initiates an OAuth process with Shopify, by requesting the merchant to approve the selected scopes.
15
+ It doesn't take any arguments, but the route that uses this middleware must match the configuration in `auth.path`.
16
+
17
+ ### `callback`
18
+
19
+ `() => RequestHandler`
20
+
21
+ This function returns an Express middleware that completes an OAuth process with Shopify, by validating that the call originated from Shopify and storing a `Session` in the database.
22
+
23
+ The session is available to the following handlers via the `res.locals.shopify.session` object.
24
+
25
+ > **Note**: this middleware **_DOES NOT_** redirect anywhere, so the request **_WILL NOT_** trigger a response by default. If you don't need to perform any actions after OAuth, we recommend using the `shopify.redirectToShopifyOrAppRoot()` middleware.
26
+
27
+ ## Example
28
+
29
+ For example, the following callback will check for and request payment after OAuth if the merchant hasn't paid for the app yet.
30
+
31
+ ```ts
32
+ const shopify = shopifyApp({
33
+ api: {
34
+ billing: {
35
+ 'My plan': {
36
+ amount: 10,
37
+ currencyCode: 'USD',
38
+ interval: BillingInterval.Every30Days,
39
+ },
40
+ },
41
+ },
42
+ auth: {
43
+ path: '/auth',
44
+ callbackPath: '/auth/callback',
45
+ },
46
+ });
47
+
48
+ app.get(shopify.config.auth.path, shopify.auth.begin());
49
+ app.get(
50
+ shopify.config.auth.callbackPath,
51
+ shopify.auth.callback(),
52
+ // Request payment if required
53
+ async (req, res, next) => {
54
+ const session = res.locals.shopify.session;
55
+ const hasPayment = await shopify.api.billing.check({
56
+ session,
57
+ plans: ['My plan'],
58
+ isTest: true,
59
+ });
60
+
61
+ if (hasPayment) {
62
+ next();
63
+ } else {
64
+ res.redirect(
65
+ await shopify.api.billing.request({
66
+ session,
67
+ plan: 'My plan',
68
+ isTest: true,
69
+ }),
70
+ );
71
+ }
72
+ },
73
+ // Load the app otherwise
74
+ shopify.redirectToShopifyOrAppRoot(),
75
+ );
76
+ ```
@@ -0,0 +1,24 @@
1
+ # `shopify.cspHeaders`
2
+
3
+ This function creates an Express middleware that ensures any response will have the `Content-Security-Policy` header set correctly to prevent clickjacking attacks.
4
+
5
+ This middleware behaves slightly differently depending on whether your app is embedded or not.
6
+
7
+ - When embedded, the `Content-Security-Policy` will be set to `frame-ancestors https://admin.shopify.com/ https://[shop].myshopify.com`, where [shop] is dynamically set to the shop domain the app is embedded on.
8
+ - When not embedded, the `Content-Security-Policy` will be set to `frame-ancestors none`.
9
+
10
+ Please visit [our documentation](https://shopify.dev/docs/apps/store/security/iframe-protection) to learn more about setting up iframe protection.
11
+
12
+ ## Example
13
+
14
+ ```ts
15
+ const app = express();
16
+ const shopifyApp = shopifyApp({
17
+ //...
18
+ });
19
+
20
+ // ...
21
+ app.use(shopifyApp.cspHeaders());
22
+
23
+ // ...
24
+ ```
@@ -0,0 +1,17 @@
1
+ # `shopify.ensureInstalledOnShop`
2
+
3
+ This function creates an Express middleware that ensures any request to that endpoint belongs to a shop that has already installed the app. You should call this middleware in any endpoint that renders HTML, if your app is embedded.
4
+
5
+ You don't need to use it if your app is not embedded, because you can use `validateAuthenticatedSession` on any non-embedded request.
6
+ If you call this middleware on a non-embedded app, it will behave like `validateAuthenticatedSession` instead.
7
+
8
+ ## Example
9
+
10
+ ```ts
11
+ const app = express();
12
+
13
+ // If the app wasn't installed in the shop, Shopify will prompt the merchant for permissions.
14
+ app.use('/', shopify.ensureInstalledOnShop(), (req, res) => {
15
+ res.send('Hello world!');
16
+ });
17
+ ```
@@ -0,0 +1,345 @@
1
+ # Instructions to migrate an app based on v6 API library to use this Express library
2
+
3
+ If you have an Express app that has been migrated to use version 6 of the `@shopify/shopify-api` library, this guide will show how to migrate to using this Express library.
4
+
5
+ > **Note** This guide uses Shopify's node app template to demonstate the migration steps. Your app will likely have additional functionality that will need similar migration.
6
+
7
+ > **Note** If you wish to practice this migration prior to applying it to your own app, create an app with one of the following commands, based on your package manager preference:
8
+ >
9
+ > ```shell
10
+ > yarn create @shopify/app --template https://github.com/Shopify/shopify-app-template-node#cli_three_api_six
11
+ > # or
12
+ > npm init @shopify/app@latest -- --template https://github.com/Shopify/shopify-app-template-node#cli_three_api_six
13
+ > # or
14
+ > pnpm create @shopify/app@latest --template https://github.com/Shopify/shopify-app-template-node#cli_three_api_six
15
+ > ```
16
+
17
+ ## Steps
18
+
19
+ ### 1. Change into the `web` directory
20
+
21
+ This is root directory of where most of the changes will occur.
22
+
23
+ ```shell
24
+ cd web
25
+ ```
26
+
27
+ ### 2. Update the project to use `v1` of the `@shopify/shopify-app-express` package
28
+
29
+ ```shell
30
+ yarn remove @shopify/shopify-api cookie-parser express
31
+ yarn add @shopify/shopify-app-express
32
+ # or
33
+ npm uninstall @shopify/shopify-api cookie-parser express
34
+ npm install @shopify/shopify-app-express
35
+ # or
36
+ pnpm uninstall @shopify/shopify-api cookie-parser express
37
+ pnpm install @shopify/shopify-app-express
38
+ ```
39
+
40
+ ### 3. Update the `gdpr.js` file
41
+
42
+ This file needs to be updated to export a structure of webhook handlers that can then be passed to the Shopify Express app object. The comments have been removed from the code below for brevity.
43
+
44
+ ```diff
45
+ import { DeliveryMethod } from "@shopify/shopify-api";
46
+ -import shopify from "./shopify.js";
47
+
48
+ -export async function setupGDPRWebHooks(path) {
49
+ +export default {
50
+ - await shopify.webhooks.addHandlers({
51
+ - CUSTOMERS_DATA_REQUEST: {
52
+ - deliveryMethod: DeliveryMethod.Http,
53
+ - callbackUrl: path,
54
+ - callback: async (topic, shop, body, webhookId) => {
55
+ - const payload = JSON.parse(body);
56
+ - },
57
+ + CUSTOMERS_DATA_REQUEST: {
58
+ + deliveryMethod: DeliveryMethod.Http,
59
+ + callbackUrl: "/api/webhooks",
60
+ + callback: async (topic, shop, body, webhookId) => {
61
+ + const payload = JSON.parse(body);
62
+ },
63
+ - });
64
+ + },
65
+
66
+ - await shopify.webhooks.addHandlers({
67
+ - CUSTOMERS_REDACT: {
68
+ - deliveryMethod: DeliveryMethod.Http,
69
+ - callbackUrl: path,
70
+ - callback: async (topic, shop, body, webhookId) => {
71
+ - const payload = JSON.parse(body);
72
+ - },
73
+ + CUSTOMERS_REDACT: {
74
+ + deliveryMethod: DeliveryMethod.Http,
75
+ + callbackUrl: "/api/webhooks",
76
+ + callback: async (topic, shop, body, webhookId) => {
77
+ + const payload = JSON.parse(body);
78
+ },
79
+ - });
80
+ + },
81
+
82
+ - await shopify.webhooks.addHandlers({
83
+ - SHOP_REDACT: {
84
+ - deliveryMethod: DeliveryMethod.Http,
85
+ - callbackUrl: path,
86
+ - callback: async (topic, shop, body, webhookId) => {
87
+ - const payload = JSON.parse(body);
88
+ - },
89
+ + SHOP_REDACT: {
90
+ + deliveryMethod: DeliveryMethod.Http,
91
+ + callbackUrl: "/api/webhooks",
92
+ + callback: async (topic, shop, body, webhookId) => {
93
+ + const payload = JSON.parse(body);
94
+ },
95
+ - });
96
+ -}
97
+ + },
98
+ +};
99
+ ```
100
+
101
+ ### 4. Update the `shopify.js` file
102
+
103
+ When using the Express library, the Shopify API library will be available via the Shopify Express object. The Express object also requires an implementation of `SessionStorage` to manage the storage of sessions on behalf of the application.
104
+
105
+ ```diff
106
+ -import "@shopify/shopify-api/adapters/node";
107
+ -import { shopifyApi, BillingInterval, LATEST_API_VERSION } from "@shopify/shopify-api";
108
+ +import { BillingInterval, LATEST_API_VERSION } from "@shopify/shopify-api";
109
+ +import { shopifyApp } from "@shopify/shopify-app-express";
110
+ +import { SQLiteSessionStorage } from "@shopify/shopify-app-session-storage-sqlite";
111
+ let { restResources } = await import(
112
+ `@shopify/shopify-api/rest/admin/${LATEST_API_VERSION}`
113
+ );
114
+
115
+ +const DB_PATH = `${process.cwd()}/database.sqlite`;
116
+
117
+ // The transactions with Shopify will always be marked as test transactions, unless NODE_ENV is production.
118
+ // See the ensureBilling helper to learn more about billing in this template.
119
+ const billingConfig = {
120
+ "My Shopify One-Time Charge": {
121
+ // This is an example configuration that would do a one-time charge for $5 (only USD is currently supported)
122
+ amount: 5.0,
123
+ currencyCode: "USD",
124
+ interval: BillingInterval.OneTime,
125
+ },
126
+ };
127
+
128
+ -const apiConfig = {
129
+ - apiKey: process.env.SHOPIFY_API_KEY,
130
+ - apiSecretKey: process.env.SHOPIFY_API_SECRET,
131
+ - scopes: process.env.SCOPES.split(","),
132
+ - hostName: process.env.HOST.replace(/https?:\/\//, ""),
133
+ - hostScheme: process.env.HOST.split("://")[0],
134
+ - apiVersion: LATEST_API_VERSION,
135
+ - isEmbeddedApp: true,
136
+ - ...(process.env.SHOP_CUSTOM_DOMAIN && {
137
+ - customShopDomains: [process.env.SHOP_CUSTOM_DOMAIN],
138
+ - }),
139
+ - billing: undefined, // or replace with billingConfig above to enable example billing
140
+ - restResources,
141
+ -};
142
+ -
143
+ -const shopify = shopifyApi(apiConfig);
144
+ +const shopify = shopifyApp({
145
+ + api: {
146
+ + apiVersion: LATEST_API_VERSION,
147
+ + billingConfig: undefined, // or replace with billingConfig above to enable example billing
148
+ + restResources,
149
+ + },
150
+ + auth: {
151
+ + path: "/api/auth",
152
+ + callbackPath: "/api/auth/callback",
153
+ + },
154
+ + webhooks: {
155
+ + path: "/api/webhooks",
156
+ + },
157
+ + // This should be replaced with your preferred storage strategy
158
+ + sessionStorage: new SQLiteSessionStorage(DB_PATH),
159
+ +});
160
+
161
+ export default shopify;
162
+
163
+ ```
164
+
165
+ > **Note** All the other API configuration values will default to
166
+ >
167
+ > ```ts
168
+ > {
169
+ > apiKey: process.env.SHOPIFY_API_KEY,
170
+ > apiSecretKey: process.env.SHOPIFY_API_SECRET,
171
+ > scopes: process.env.SCOPES.split(","),
172
+ > hostName: process.env.HOST.replace(/https?:\/\//, ""),
173
+ > hostScheme: process.env.HOST.split("://")[0],
174
+ > isEmbeddedApp: true,
175
+ > }
176
+ > ```
177
+
178
+ ### 5. Move the `helpers/product-creater.js` file up one level ...
179
+
180
+ Move the file from the `helpers` directory to the `web` directory. Assuming your terminal is in the `web` directory:
181
+
182
+ ```shell
183
+ # Unix OS, e.g., macOS, Linux, etc.
184
+ mv helpers/product-creator.js .
185
+ # Windows
186
+ move helpers\product-creator.js .
187
+ ```
188
+
189
+ ### 6. ... and update it to use the `shopify` Express instance
190
+
191
+ Note that the `ADJECTIVES` and `NOUN` constants remain the same but have been collapsed/hidden below for brevity.
192
+
193
+ ```diff
194
+ import { GraphqlQueryError } from "@shopify/shopify-api";
195
+ -import shopify from "../shopify.js";
196
+ +import shopify from "./shopify.js";
197
+
198
+ const ADJECTIVES = [ ...
199
+ ];
200
+
201
+ const NOUNS = [ ...
202
+ ];
203
+
204
+ export const DEFAULT_PRODUCTS_COUNT = 5;
205
+ const CREATE_PRODUCTS_MUTATION = `
206
+ mutation populateProduct($input: ProductInput!) {
207
+ productCreate(input: $input) {
208
+ product {
209
+ id
210
+ }
211
+ }
212
+ }
213
+ `;
214
+
215
+ export default async function productCreator(
216
+ session,
217
+ count = DEFAULT_PRODUCTS_COUNT
218
+ ) {
219
+ - const client = new shopify.clients.Graphql({ session });
220
+ + const client = new shopify.api.clients.Graphql({ session });
221
+
222
+ try {
223
+ for (let i = 0; i < count; i++) {
224
+ await client.query({
225
+ data: {
226
+ query: CREATE_PRODUCTS_MUTATION,
227
+ variables: {
228
+ input: {
229
+ title: `${randomTitle()}`,
230
+ variants: [{ price: randomPrice() }],
231
+ },
232
+ },
233
+ },
234
+ });
235
+ }
236
+ } catch (error) {
237
+ if (error instanceof GraphqlQueryError) {
238
+ throw new Error(
239
+ `${error.message}\n${JSON.stringify(error.response, null, 2)}`
240
+ );
241
+ } else {
242
+ throw error;
243
+ }
244
+ }
245
+ }
246
+
247
+ function randomTitle() {
248
+ const adjective = ADJECTIVES[Math.floor(Math.random() * ADJECTIVES.length)];
249
+ const noun = NOUNS[Math.floor(Math.random() * NOUNS.length)];
250
+ return `${adjective} ${noun}`;
251
+ }
252
+
253
+ function randomPrice() {
254
+ return Math.round((Math.random() * 10 + Number.EPSILON) * 100) / 100;
255
+ }
256
+ ```
257
+
258
+ ### 7. Remove unused files
259
+
260
+ The following files can now be deleted, as their functionality has now been incorporated into the Express library.
261
+
262
+ > **Note** These paths are relative to the `web` directory
263
+
264
+ | Filename | Note |
265
+ | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
266
+ | `sqlite-session-storage.js` | An instance of `SQLiteSessionStorage` is passed as a configuration item to `shopifyApp` in `shopify.js`, so that the Shopify Express library can manage session storage directly. |
267
+ | `app_installations.js` | The Shopify Express library uses the session storage to internally track app installations. |
268
+ | `helpers/ensure-billing.js` | :warning: maybe this needs to be retained as an example middleware? |
269
+ | `helpers/redirect-to-auth.js` | This functionality is now incorporated into the Shopify Express library. |
270
+ | `helpers/return-top-level-redirection.js` | This functionality is now incorporated into the Shopify Express library. |
271
+ | `middleware/auth.js` | This functionality is now incorporated into the Shopify Express library. |
272
+ | `middleware/verify-request.js` | This functionality is now incorporated into the Shopify Express library. |
273
+
274
+ ### 8. Update the `index.js` file
275
+
276
+ Replace the `index.js` file with the code below.
277
+
278
+ ```ts
279
+ import {join} from 'path';
280
+ import {readFileSync} from 'fs';
281
+ import express from 'express';
282
+ import serveStatic from 'serve-static';
283
+
284
+ import shopify from './shopify.js';
285
+ import productCreator from './product-creator.js';
286
+ import GDPRWebhookHandlers from './gdpr.js';
287
+
288
+ const PORT = parseInt(process.env.BACKEND_PORT || process.env.PORT, 10);
289
+
290
+ const STATIC_PATH =
291
+ process.env.NODE_ENV === 'production'
292
+ ? `${process.cwd()}/frontend/dist`
293
+ : `${process.cwd()}/frontend/`;
294
+
295
+ const app = express();
296
+
297
+ // Set up Shopify authentication and webhook handling
298
+ app.get(shopify.config.auth.path, shopify.auth.begin());
299
+ app.get(
300
+ shopify.config.auth.callbackPath,
301
+ shopify.auth.callback(),
302
+ shopify.redirectToShopifyOrAppRoot(),
303
+ );
304
+ app.post(
305
+ shopify.config.webhooks.path,
306
+ shopify.processWebhooks({webhookHandlers: GDPRWebhookHandlers}),
307
+ );
308
+
309
+ // All endpoints after this point will require an active session
310
+ app.use('/api/*', shopify.validateAuthenticatedSession());
311
+
312
+ app.use(express.json());
313
+
314
+ app.get('/api/products/count', async (_req, res) => {
315
+ const countData = await shopify.api.rest.Product.count({
316
+ session: res.locals.shopify.session,
317
+ });
318
+ res.status(200).send(countData);
319
+ });
320
+
321
+ app.get('/api/products/create', async (_req, res) => {
322
+ let status = 200;
323
+ let error = null;
324
+
325
+ try {
326
+ await productCreator(res.locals.shopify.session);
327
+ } catch (e) {
328
+ console.log(`Failed to process products/create: ${e.message}`);
329
+ status = 500;
330
+ error = e.message;
331
+ }
332
+ res.status(status).send({success: status === 200, error});
333
+ });
334
+
335
+ app.use(serveStatic(STATIC_PATH, {index: false}));
336
+
337
+ app.use('/*', shopify.ensureInstalledOnShop(), async (_req, res, _next) => {
338
+ return res
339
+ .status(200)
340
+ .set('Content-Type', 'text/html')
341
+ .send(readFileSync(join(STATIC_PATH, 'index.html')));
342
+ });
343
+
344
+ app.listen(PORT);
345
+ ```
@@ -0,0 +1,67 @@
1
+ # `shopify.processWebhooks()`
2
+
3
+ This function creates an Express middleware that processes webhook requests from Shopify, based on the given handlers.
4
+
5
+ It mounts the handlers onto the `shopify` object, and they're registered in `shopify.auth.callback` after we receive an access token to call the API.
6
+
7
+ This middleware will always respond to Shopify, even if there was an error while handling the webhook.
8
+
9
+ :exclamation: **Important**: Shopify always sends POST requests for webhooks.
10
+ Make sure you use this middleware on a `.post()` route.
11
+
12
+ ## Parameters
13
+
14
+ ### `webhookHandlers`
15
+
16
+ `{[topic: string]: WebhookHandler | WebhookHandler[]}`
17
+
18
+ Defines the webhooks your app will listen to, and how to handle them. See [the `@shopify/shopify-api` documentation](https://github.com/Shopify/shopify-api-js/blob/main/packages/shopify-api/docs/guides/webhooks.md) for the allowed values.
19
+
20
+ > **Note**: for HTTP webhook handlers, the `callbackUrl` value must match the route where you use this middleware.
21
+
22
+ ## Example
23
+
24
+ The following example shows how to setup handlers for the mandatory GDPR webhooks.
25
+
26
+ ```ts
27
+ const {DeliveryMethod} = require('@shopify/shopify-api');
28
+
29
+ const shopify = shopifyApp({
30
+ webhooks: {
31
+ path: '/webhooks',
32
+ },
33
+ });
34
+
35
+ const webhookHandlers = {
36
+ CUSTOMERS_DATA_REQUEST: {
37
+ deliveryMethod: DeliveryMethod.Http,
38
+ callbackUrl: shopify.config.webhooks.path,
39
+ callback: async (topic, shop, body, webhookId, apiVersion) => {
40
+ const payload = JSON.parse(body);
41
+ // prepare customers data to send to customer
42
+ },
43
+ },
44
+ CUSTOMERS_REDACT: {
45
+ deliveryMethod: DeliveryMethod.Http,
46
+ callbackUrl: shopify.config.webhooks.path,
47
+ callback: async (topic, shop, body) => {
48
+ const payload = JSON.parse(body);
49
+ // remove customers data
50
+ },
51
+ },
52
+ SHOP_REDACT: {
53
+ deliveryMethod: DeliveryMethod.Http,
54
+ callbackUrl: shopify.config.webhooks.path,
55
+ callback: async (topic, shop, body, webhookId, apiVersion) => {
56
+ const payload = JSON.parse(body);
57
+ // remove shop data
58
+ },
59
+ },
60
+ };
61
+
62
+ // This must be a .post() endpoint
63
+ app.post(
64
+ shopify.config.webhooks.path,
65
+ shopify.processWebhooks({webhookHandlers}),
66
+ );
67
+ ```