Skip to content

Commit 59ebb5e

Browse files
authored
Merge pull request #1370 from Shopify/local-dev-kludges
Support internal Shopify hosts
2 parents b8eee39 + e4d68bb commit 59ebb5e

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Note: For changes to the API, see https://shopify.dev/changelog?filter=api
55

66
- [#1362](https://github.com/Shopify/shopify-api-ruby/pull/1362) Add support for client credentials grant
77
- [#1369](https://github.com/Shopify/shopify-api-ruby/pull/1369) Make `sub` and `sid` jwt claims optional (Checkout ui extension support)
8+
- [#1370](https://github.com/Shopify/shopify-api-ruby/pull/1370) Add support for Shopify internal hosts
89

910
## 14.8.0
1011

lib/shopify_api/auth/oauth.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ def begin_auth(shop:, redirect_path:, is_online: true, scope_override: nil)
4646
}
4747

4848
query_string = URI.encode_www_form(query)
49+
auth_route = auth_base_uri(shop) + "/oauth/authorize?#{query_string}"
4950

50-
auth_route = "https://#{shop}/admin/oauth/authorize?#{query_string}"
5151
{ auth_route: auth_route, cookie: cookie }
5252
end
5353

@@ -106,6 +106,20 @@ def validate_auth_callback(cookies:, auth_query:)
106106

107107
{ session: session, cookie: cookie }
108108
end
109+
110+
private
111+
112+
sig { params(shop: String).returns(String) }
113+
def auth_base_uri(shop)
114+
return "https://#{shop}/admin" unless defined?(DevServer)
115+
116+
# For first-party apps in development only, we leverage DevServer to build the admin base URI
117+
admin_web = T.unsafe(Object.const_get("DevServer")).new("web") # rubocop:disable Sorbet/ConstantsFromStrings
118+
admin_host = admin_web.host!(nonstandard_host_prefix: "admin")
119+
shop_name = shop.split(".").first
120+
121+
"https://#{admin_host}/store/#{shop_name}"
122+
end
109123
end
110124
end
111125
end

lib/shopify_api/clients/http_client.rb

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,17 @@ def request(request, response_as_struct: false)
4040
headers["Content-Type"] = T.must(request.body_type) if request.body_type
4141
headers = headers.merge(T.must(request.extra_headers)) if request.extra_headers
4242

43+
parsed_uri = URI(request_url(request))
44+
45+
headers = append_first_party_development_headers(headers, parsed_uri)
46+
4347
tries = 0
4448
response = HttpResponse.new(code: 0, headers: {}, body: "")
4549
while tries < request.tries
4650
tries += 1
4751
res = T.cast(HTTParty.send(
4852
request.http_method,
49-
request_url(request),
53+
parsed_uri.to_s,
5054
headers: headers,
5155
query: request.query,
5256
body: request.body.class == Hash ? T.unsafe(request.body).to_json : request.body,
@@ -115,6 +119,27 @@ def serialized_error(response)
115119
end
116120
body.to_json
117121
end
122+
123+
private
124+
125+
sig do
126+
params(
127+
headers: T::Hash[T.any(Symbol, String), T.untyped],
128+
parsed_uri: URI::Generic,
129+
).returns(T::Hash[T.any(Symbol, String), T.untyped])
130+
end
131+
def append_first_party_development_headers(headers, parsed_uri)
132+
return headers unless defined?(DevServer)
133+
return headers unless headers["Host"]&.include?(".my.shop.dev") || parsed_uri.host&.include?(".my.shop.dev")
134+
135+
# These headers are only used for first party applications in development mode
136+
headers["x-forwarded-host"] = headers["Host"] || parsed_uri.host
137+
headers["Host"] = T.unsafe(
138+
Object.const_get("DevServer::Core"), # rubocop:disable Sorbet/ConstantsFromStrings
139+
).new.host!(:app)
140+
141+
headers
142+
end
118143
end
119144
end
120145
end

0 commit comments

Comments
 (0)