Current section

Files

Jump to
shopifex lib shopifex_web routes.ex
Raw

lib/shopifex_web/routes.ex

defmodule ShopifexWeb.Routes do
@moduledoc """
Provides macros for easily responding to Shopify requests within your Shopifex router.
## pipelines
Call the `pipelines` macro in your router to inject some standard router pipelines into your router module.
These pipelines can be used for responding to webhooks, admin links, proxy requests, and requests to load your app within the Shopify admin.
## auth routes
Call the `auth_routes` macro in your router to inject the standard Shopify app routes which your app will need.
This includes routes for loading the app in Shopfiy the admin, app installation and app updates.
## payment routes
Call the `payment_routes` macro in your router to inject the routes required by the Shopifex PaymentGuard system.
"""
@doc """
Injects the following Shopify router pipelines into your Shopifex application's router.
- `:shopify_session`: Validates request (HMAC header/param or token param) and makes session information available via Shopifex.Plug API. Also removes iFrame blocking headers so app can render in Shopify admin.
- `:shopify_webhook`: Validates Shopify webhook requests HMAC and makes session information available via Shopifex.Plug API.
- `:shopify_admin_link`: Validates Shopify admin link & bulk action link requests and makes session information available via Shopifex.Plug API. Also removes iFrame blocking headers so app can render in Shopify admin.
- `:shopify_api`: Ensures that a valid Shopify session token or Shopifex token are present in Authorization header. Useful for async requests between your SPA front end and Shopifex backend.
- `:shopifex_browser`: Same as your normal :browser pipeline, except it calls Shopifex.Plug.LoadInIframe. Deprecated; does not work with Phoenix 1.6 generated apps.
- `:shopify_embedded`: Sets Content-Security-Policy headers to restrict app loading to within the Shopify admin. Read more: https://shopify.dev/apps/store/security/iframe-protection#embedded-apps
"""
defmacro pipelines() do
quote do
pipeline :shopifex_browser do
plug(:accepts, ["html"])
plug(:fetch_session)
plug(:fetch_flash)
plug(:put_secure_browser_headers)
plug(Shopifex.Plug.LoadInIframe)
end
pipeline :shopify_session do
plug(Shopifex.Plug.ShopifySession)
plug(Shopifex.Plug.EnsureScopes)
plug(Shopifex.Plug.LoadInIframe)
end
pipeline :validate_install_hmac do
plug(Shopifex.Plug.ValidateHmac)
end
pipeline :shopify_webhook do
plug(:fetch_session)
plug(Shopifex.Plug.FetchFlash)
plug(Shopifex.Plug.ShopifyWebhook)
end
pipeline :shopify_proxy do
plug(:fetch_session)
plug(Shopifex.Plug.FetchFlash)
plug(Shopifex.Plug.ValidateHmac)
end
pipeline :shopify_admin_link do
plug(:accepts, ["json"])
plug(:fetch_session)
plug(Shopifex.Plug.FetchFlash)
plug(Shopifex.Plug.LoadInIframe)
plug(Shopifex.Plug.ShopifyWebhook)
plug(Shopifex.Plug.EnsureScopes)
end
pipeline :shopify_api do
plug(CORSPlug, origin: "*")
plug(:accepts, ["json"])
plug(
Guardian.Plug.Pipeline,
module: Shopifex.Guardian,
error_handler: ShopifexWeb.AuthErrorHandler
)
plug(Guardian.Plug.VerifyHeader)
plug(Guardian.Plug.EnsureAuthenticated)
plug(Guardian.Plug.LoadResource)
end
pipeline :shopifex_api do
plug(CORSPlug, origin: "*")
plug(:accepts, ["json"])
plug(
Guardian.Plug.Pipeline,
module: Shopifex.Guardian,
error_handler: ShopifexWeb.AuthErrorHandler
)
plug(Guardian.Plug.VerifyHeader)
plug(Guardian.Plug.EnsureAuthenticated)
plug(Guardian.Plug.LoadResource)
end
pipeline :shopify_embedded do
plug(Shopifex.Plug.SetCSPHeader)
end
end
end
defmacro auth_routes(controller \\ ShopifexWeb.AuthController) do
quote do
scope "/auth" do
pipe_through([:shopifex_browser, :shopify_session])
get("/", unquote(controller), :auth)
end
scope "/auth" do
pipe_through([:shopifex_browser, :validate_install_hmac])
get("/install", unquote(controller), :install)
get("/update", unquote(controller), :update)
end
scope "/initialize-installation" do
pipe_through([:shopifex_browser])
get("/", unquote(controller), :initialize_installation)
end
end
end
defmacro payment_routes(controller \\ ShopifexWeb.PaymentController, opts \\ []) do
# TODO: make embedded default in v3+
payment_pages_pipe_through =
if opts[:shopify_embedded] do
[:shopifex_browser, :shopify_session, :shopify_embedded]
else
[:shopifex_browser, :shopify_session]
end
quote do
scope "/payment" do
pipe_through(unquote(payment_pages_pipe_through))
get("/show-plans", unquote(controller), :show_plans)
post("/select-plan", unquote(controller), :select_plan)
end
scope "/payment" do
pipe_through([:shopifex_browser])
get("/complete", unquote(controller), :complete_payment)
end
scope "/payment" do
pipe_through([:shopify_api])
scope "/api" do
options("/select-plan", unquote(controller), :select_plan)
post("/select-plan", unquote(controller), :select_plan)
end
end
end
end
@doc """
Generate a live session with the current_shop and session token assigned. All other
options are passed through to `live_session`.
"""
@spec shopifex_live_session(atom, opts :: Keyword.t()) :: Macro.t()
defmacro shopifex_live_session(session_name, opts \\ [], do: block) do
quote do
shopifex_live_session_opts = unquote(opts) |> ShopifexWeb.LiveSession.opts()
Phoenix.LiveView.Router.live_session unquote(session_name), shopifex_live_session_opts do
unquote(block)
end
end
end
end