Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
188 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import React, { useEffect } from 'react'; | ||
import createApp from '@shopify/app-bridge'; | ||
import { Redirect } from '@shopify/app-bridge/actions'; | ||
import { Frame, TextContainer, Layout, Page } from '@shopify/polaris' | ||
|
||
export default function ExternalRedirect({ shopUrl, shopifyApiKey, redirectLocation }) { | ||
const app = createApp({ | ||
apiKey: shopifyApiKey, | ||
shopOrigin: shopUrl, | ||
}); | ||
|
||
const redirect = Redirect.create(app); | ||
|
||
const doRedirect = () => { | ||
if (window.self == window.top) { | ||
// do a normal redirect if not in an iFrame | ||
window.location = redirectLocation | ||
} else { | ||
redirect.dispatch(Redirect.Action.REMOTE, redirectLocation) | ||
} | ||
} | ||
|
||
useEffect(() => { | ||
doRedirect() | ||
}, []) | ||
|
||
return ( | ||
<Page title="You are being redirected"> | ||
<Layout> | ||
<Layout.Section> | ||
<Frame> | ||
<TextContainer style="padding-top: 3 rem;"> | ||
<p> | ||
If you are not automatically redirected within 5 seconds, | ||
<a href="#" onClick={doRedirect}>click here</a> | ||
</p> | ||
</TextContainer> | ||
</Frame> | ||
</Layout.Section> | ||
</Layout> | ||
</Page> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
defmodule Shopifex.RuntimeError do | ||
defexception message: "An error occurred" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
defmodule Shopifex.Plug.EnsureScopes do | ||
@moduledoc """ | ||
This plug ensures that the shop which is currently loaded in the session | ||
has all of the scopes which are defined under `config :shopifex, scopes: "foo"`. | ||
If the current shop does not have all the scopes, the conn is redirected to | ||
the Shopify OAuth update flow. | ||
Simply adding a new scope to your `:shopifex, scopes: "foo"` config will | ||
trigger an OAuth update with your installations. | ||
""" | ||
import Plug.Conn | ||
import Phoenix.Controller | ||
require Logger | ||
|
||
def init(options) do | ||
# initialize options | ||
options | ||
end | ||
|
||
def call(conn, _) do | ||
case Shopifex.Plug.current_shop(conn) do | ||
nil -> | ||
raise( | ||
Shopifex.RuntimeError, | ||
""" | ||
`Shopifex.Plug.EnsureScopes` must be placed in the pipeline after a plug which places a shop in the session; such as `Shopifex.Plug.ShopifySession` or `Shopifex.Plug.ShopifyWebhook` | ||
""" | ||
) | ||
|
||
shop -> | ||
required_scopes = String.split(Application.get_env(:shopifex, :scopes), ",") | ||
shop_scopes = String.split(shop.scope, ",") | ||
|
||
case required_scopes -- shop_scopes do | ||
[] -> | ||
conn | ||
|
||
missing_scopes -> | ||
Logger.info( | ||
"Shop #{shop.url} is missing required scopes #{inspect(missing_scopes)}, initiating app update" | ||
) | ||
|
||
reinstall_url = | ||
"https://#{shop.url}/admin/oauth/authorize?client_id=#{Application.fetch_env!(:shopifex, :api_key)}&scope=#{Application.fetch_env!(:shopifex, :scopes)}&redirect_uri=#{Application.fetch_env!(:shopifex, :reinstall_uri)}" | ||
|
||
conn | ||
|> put_view(ShopifexWeb.PageView) | ||
|> put_layout({ShopifexWeb.LayoutView, "app.html"}) | ||
|> render("redirect.html", redirect_location: reinstall_url) | ||
|> halt() | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<%= | ||
ReactPhoenix.ClientSide.react_component( | ||
"Components.WrappedRedirect", | ||
%{ | ||
shop_url: Shopifex.Plug.current_shop(@conn).url, | ||
redirect_location: @redirect_location, | ||
shopify_api_key: Application.get_env(:shopifex, :api_key) | ||
} | ||
) | ||
%> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
defmodule ShopifexWeb.PageView do | ||
use ShopifexWeb, :view | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
defmodule Shopifex.Plug.EnsureScopesTest do | ||
use ShopifexWeb.ConnCase | ||
|
||
setup do | ||
conn = build_conn(:get, "/my-route?foo=bar&fizz=buzz") | ||
{:ok, conn: conn} | ||
end | ||
|
||
setup [:shop_in_session] | ||
|
||
test "shop scopes matching shopifex config passes plug", %{ | ||
conn: conn | ||
} do | ||
shop = Shopifex.Plug.current_shop(conn) | ||
Application.put_env(:shopifex, :scopes, shop.scope) | ||
|
||
conn = Shopifex.Plug.EnsureScopes.call(conn, []) | ||
|
||
refute conn.halted | ||
end | ||
|
||
test "renders redirect page with location to Shopify OAuth update flow", %{ | ||
conn: conn | ||
} do | ||
Application.put_env(:shopifex, :scopes, "read_orders") | ||
|
||
conn = Shopifex.Plug.EnsureScopes.call(conn, []) | ||
|
||
assert conn.halted | ||
assert html_response(conn, 200) =~ "Components.WrappedRedirect" | ||
|
||
assert conn.assigns.redirect_location =~ | ||
"https://shopifex.myshopify.com/admin/oauth/authorize?client_id=thisisafakeapikey" | ||
end | ||
|
||
test "throws error when shop not in session", %{ | ||
conn: conn | ||
} do | ||
assert_raise Shopifex.RuntimeError, fn -> | ||
conn | ||
|> Map.put(:private, %{}) | ||
|> Shopifex.Plug.EnsureScopes.call([]) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters