@shopify/hydrogen 2026.4.4 → 2026.4.5
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/development/index.cjs +45 -15
- package/dist/development/index.cjs.map +1 -1
- package/dist/development/index.js +45 -15
- package/dist/development/index.js.map +1 -1
- package/dist/production/index.cjs +46 -46
- package/dist/production/index.cjs.map +1 -1
- package/dist/production/index.js +46 -46
- package/dist/production/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -613,7 +613,7 @@ function getPrivacyBanner() {
|
|
|
613
613
|
}
|
|
614
614
|
|
|
615
615
|
// package.json
|
|
616
|
-
var version = "2026.4.
|
|
616
|
+
var version = "2026.4.5";
|
|
617
617
|
|
|
618
618
|
// src/analytics-manager/ShopifyAnalytics.tsx
|
|
619
619
|
function getCustomerPrivacyRequired() {
|
|
@@ -2009,7 +2009,7 @@ function generateUUID() {
|
|
|
2009
2009
|
}
|
|
2010
2010
|
|
|
2011
2011
|
// src/version.ts
|
|
2012
|
-
var LIB_VERSION = "2026.4.
|
|
2012
|
+
var LIB_VERSION = "2026.4.5";
|
|
2013
2013
|
|
|
2014
2014
|
// src/utils/graphql.ts
|
|
2015
2015
|
function minifyQuery(string) {
|
|
@@ -3780,11 +3780,13 @@ async function refreshToken({
|
|
|
3780
3780
|
const customerAccount = session.get(CUSTOMER_ACCOUNT_SESSION_KEY);
|
|
3781
3781
|
const refreshToken2 = customerAccount?.refreshToken;
|
|
3782
3782
|
const idToken = customerAccount?.idToken;
|
|
3783
|
-
if (!refreshToken2)
|
|
3783
|
+
if (!refreshToken2) {
|
|
3784
|
+
clearSession(session);
|
|
3784
3785
|
throw new BadRequest(
|
|
3785
3786
|
"Unauthorized",
|
|
3786
3787
|
"No refreshToken found in the session. Make sure your session is configured correctly and passed to `createCustomerAccountClient`."
|
|
3787
3788
|
);
|
|
3789
|
+
}
|
|
3788
3790
|
newBody.append("grant_type", "refresh_token");
|
|
3789
3791
|
newBody.append("refresh_token", refreshToken2);
|
|
3790
3792
|
newBody.append("client_id", customerAccountId);
|
|
@@ -3809,6 +3811,9 @@ async function refreshToken({
|
|
|
3809
3811
|
});
|
|
3810
3812
|
if (!response.ok) {
|
|
3811
3813
|
const text = await response.text();
|
|
3814
|
+
if (getOAuthError(text) === "invalid_grant") {
|
|
3815
|
+
clearSession(session);
|
|
3816
|
+
}
|
|
3812
3817
|
throw new Response(text, {
|
|
3813
3818
|
status: response.status,
|
|
3814
3819
|
headers: {
|
|
@@ -3819,9 +3824,13 @@ async function refreshToken({
|
|
|
3819
3824
|
const {
|
|
3820
3825
|
access_token,
|
|
3821
3826
|
expires_in,
|
|
3822
|
-
refresh_token
|
|
3827
|
+
refresh_token,
|
|
3828
|
+
error
|
|
3823
3829
|
} = await response.json();
|
|
3824
3830
|
if (!access_token || access_token.length === 0) {
|
|
3831
|
+
if (error === "invalid_grant") {
|
|
3832
|
+
clearSession(session);
|
|
3833
|
+
}
|
|
3825
3834
|
throw new BadRequest("Unauthorized", "Invalid access token received.");
|
|
3826
3835
|
}
|
|
3827
3836
|
session.set(CUSTOMER_ACCOUNT_SESSION_KEY, {
|
|
@@ -3858,7 +3867,6 @@ async function checkExpires({
|
|
|
3858
3867
|
await locks.refresh;
|
|
3859
3868
|
delete locks.refresh;
|
|
3860
3869
|
} catch (error) {
|
|
3861
|
-
clearSession(session);
|
|
3862
3870
|
if (error && error.status !== 401) {
|
|
3863
3871
|
throw error;
|
|
3864
3872
|
} else {
|
|
@@ -3870,6 +3878,14 @@ async function checkExpires({
|
|
|
3870
3878
|
}
|
|
3871
3879
|
}
|
|
3872
3880
|
}
|
|
3881
|
+
function getOAuthError(body) {
|
|
3882
|
+
try {
|
|
3883
|
+
const data = JSON.parse(body);
|
|
3884
|
+
return typeof data?.error === "string" ? data.error : void 0;
|
|
3885
|
+
} catch {
|
|
3886
|
+
return void 0;
|
|
3887
|
+
}
|
|
3888
|
+
}
|
|
3873
3889
|
function generateCodeVerifier() {
|
|
3874
3890
|
const rando = generateRandomCode();
|
|
3875
3891
|
return base64UrlEncode(rando);
|
|
@@ -3897,9 +3913,7 @@ function convertBufferToString(hash) {
|
|
|
3897
3913
|
return String.fromCharCode(...numberArray);
|
|
3898
3914
|
}
|
|
3899
3915
|
function generateState() {
|
|
3900
|
-
|
|
3901
|
-
const randomString = Math.random().toString(36).substring(2);
|
|
3902
|
-
return timestamp + randomString;
|
|
3916
|
+
return base64UrlEncode(generateRandomCode());
|
|
3903
3917
|
}
|
|
3904
3918
|
async function exchangeAccessToken(authAccessToken, customerAccountId, customerAccountTokenExchangeUrl, httpsOrigin, debugInfo) {
|
|
3905
3919
|
const clientId = customerAccountId;
|
|
@@ -4053,6 +4067,8 @@ function createCustomerAccountHelper(customerApiVersion, shopId) {
|
|
|
4053
4067
|
|
|
4054
4068
|
// src/customer/customer.ts
|
|
4055
4069
|
var HYDROGEN_TUNNEL_DOMAIN_SUFFIX = ".tryhydrogen.dev";
|
|
4070
|
+
var OAUTH_RECOVERY_PARAM = "oauth_recovery";
|
|
4071
|
+
var OAUTH_RECOVERY_STATE_PREFIX = "oauth-recovery.";
|
|
4056
4072
|
function checkTunnelDomain(hostname, useCustomAuthDomain, redirectUri) {
|
|
4057
4073
|
if (hostname.endsWith(HYDROGEN_TUNNEL_DOMAIN_SUFFIX)) return;
|
|
4058
4074
|
if (useCustomAuthDomain) {
|
|
@@ -4284,7 +4300,8 @@ function createCustomerAccountClient({
|
|
|
4284
4300
|
ensureTunnel(requestUrl.hostname);
|
|
4285
4301
|
ifInvalidCredentialThrowError();
|
|
4286
4302
|
const loginUrl = new URL(getCustomerAccountUrl("AUTH" /* AUTH */));
|
|
4287
|
-
const
|
|
4303
|
+
const isOAuthRecovery = requestUrl.searchParams.get(OAUTH_RECOVERY_PARAM) === "true";
|
|
4304
|
+
const state = `${isOAuthRecovery ? OAUTH_RECOVERY_STATE_PREFIX : ""}${generateState()}`;
|
|
4288
4305
|
const nonce = generateNonce();
|
|
4289
4306
|
loginUrl.searchParams.set("client_id", customerAccountId);
|
|
4290
4307
|
loginUrl.searchParams.set("scope", "openid email");
|
|
@@ -4373,17 +4390,30 @@ function createCustomerAccountClient({
|
|
|
4373
4390
|
const code = requestUrl.searchParams.get("code");
|
|
4374
4391
|
const state = requestUrl.searchParams.get("state");
|
|
4375
4392
|
if (!code || !state) {
|
|
4376
|
-
clearSession(session);
|
|
4377
4393
|
throw new BadRequest(
|
|
4378
4394
|
"Unauthorized",
|
|
4379
4395
|
"No code or state parameter found in the redirect URL."
|
|
4380
4396
|
);
|
|
4381
4397
|
}
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4398
|
+
const customerAccountSession = session.get(CUSTOMER_ACCOUNT_SESSION_KEY);
|
|
4399
|
+
if (customerAccountSession?.state !== state) {
|
|
4400
|
+
if (state.startsWith(OAUTH_RECOVERY_STATE_PREFIX)) {
|
|
4401
|
+
throw new BadRequest(
|
|
4402
|
+
"Unable to complete sign in. Please try again.",
|
|
4403
|
+
"The session state does not match the state parameter. Make sure that the session is configured correctly and passed to `createCustomerAccountClient`."
|
|
4404
|
+
);
|
|
4405
|
+
}
|
|
4406
|
+
warnOnce(
|
|
4407
|
+
"[h2:warn:customerAccount] OAuth callback state mismatch. Restarting customer login once."
|
|
4408
|
+
);
|
|
4409
|
+
const recoveryLoginUrl = new URL(loginPath, request.url);
|
|
4410
|
+
recoveryLoginUrl.searchParams.set(
|
|
4411
|
+
"return_to",
|
|
4412
|
+
customerAccountSession?.redirectPath ?? defaultRedirectPath
|
|
4413
|
+
);
|
|
4414
|
+
recoveryLoginUrl.searchParams.set(OAUTH_RECOVERY_PARAM, "true");
|
|
4415
|
+
return redirect(
|
|
4416
|
+
`${recoveryLoginUrl.pathname}${recoveryLoginUrl.search}`
|
|
4387
4417
|
);
|
|
4388
4418
|
}
|
|
4389
4419
|
const clientId = customerAccountId;
|