@shopsbuilder/auth-sdk 1.2.7 → 1.2.9

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.
@@ -4,6 +4,7 @@ declare const getAccessTokenKey: (prefix?: string) => string;
4
4
  declare class SaleorAccessTokenStorageHandler {
5
5
  private storage;
6
6
  private prefix?;
7
+ private cachedToken;
7
8
  constructor(storage: StorageRepository, prefix?: string | undefined);
8
9
  getAccessToken: () => string | null;
9
10
  setAccessToken: (token: string) => void;
@@ -4,6 +4,7 @@ declare const getAccessTokenKey: (prefix?: string) => string;
4
4
  declare class SaleorAccessTokenStorageHandler {
5
5
  private storage;
6
6
  private prefix?;
7
+ private cachedToken;
7
8
  constructor(storage: StorageRepository, prefix?: string | undefined);
8
9
  getAccessToken: () => string | null;
9
10
  setAccessToken: (token: string) => void;
@@ -30,15 +30,22 @@ var SaleorAccessTokenStorageHandler = class {
30
30
  this.storage = storage;
31
31
  this.prefix = prefix;
32
32
  }
33
+ // In-memory cache so the token is available even when the storage
34
+ // backend is read-only (e.g. Next.js cookies during render).
35
+ cachedToken = null;
33
36
  getAccessToken = () => {
37
+ if (this.cachedToken)
38
+ return this.cachedToken;
34
39
  const key = getAccessTokenKey(this.prefix);
35
40
  return this.storage.getItem(key);
36
41
  };
37
42
  setAccessToken = (token) => {
43
+ this.cachedToken = token;
38
44
  const key = getAccessTokenKey(this.prefix);
39
45
  return this.storage.setItem(key, token);
40
46
  };
41
47
  clearAuthStorage = () => {
48
+ this.cachedToken = null;
42
49
  const key = getAccessTokenKey(this.prefix);
43
50
  return this.storage.removeItem(key);
44
51
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SaleorAccessTokenStorageHandler,
3
3
  getAccessTokenKey
4
- } from "./chunk-BZFBMGPG.mjs";
4
+ } from "./chunk-B326YIV6.mjs";
5
5
  export {
6
6
  SaleorAccessTokenStorageHandler,
7
7
  getAccessTokenKey
@@ -3,12 +3,6 @@ import { StorageRepository, FetchWithAdditionalParams, PasswordResetVariables, P
3
3
  interface SaleorAuthClientProps {
4
4
  onAuthRefresh?: (isAuthenticating: boolean) => void;
5
5
  saleorApiUrl: string;
6
- /**
7
- * Prefix used for storage keys. Defaults to saleorApiUrl.
8
- * Set this to the public API URL when the server uses an internal URL
9
- * for saleorApiUrl, so that cookie keys match between client and server.
10
- */
11
- storageKeyPrefix?: string;
12
6
  refreshTokenStorage?: StorageRepository;
13
7
  accessTokenStorage?: StorageRepository;
14
8
  tokenGracePeriod?: number;
@@ -39,7 +33,7 @@ declare class SaleorAuthClient {
39
33
  * }, [])
40
34
  * ```
41
35
  */
42
- constructor({ saleorApiUrl, storageKeyPrefix, refreshTokenStorage, accessTokenStorage, onAuthRefresh, tokenGracePeriod, defaultRequestInit, }: SaleorAuthClientProps);
36
+ constructor({ saleorApiUrl, refreshTokenStorage, accessTokenStorage, onAuthRefresh, tokenGracePeriod, defaultRequestInit, }: SaleorAuthClientProps);
43
37
  cleanup: () => void;
44
38
  private runAuthorizedRequest;
45
39
  private handleRequestWithTokenRefresh;
@@ -3,12 +3,6 @@ import { StorageRepository, FetchWithAdditionalParams, PasswordResetVariables, P
3
3
  interface SaleorAuthClientProps {
4
4
  onAuthRefresh?: (isAuthenticating: boolean) => void;
5
5
  saleorApiUrl: string;
6
- /**
7
- * Prefix used for storage keys. Defaults to saleorApiUrl.
8
- * Set this to the public API URL when the server uses an internal URL
9
- * for saleorApiUrl, so that cookie keys match between client and server.
10
- */
11
- storageKeyPrefix?: string;
12
6
  refreshTokenStorage?: StorageRepository;
13
7
  accessTokenStorage?: StorageRepository;
14
8
  tokenGracePeriod?: number;
@@ -39,7 +33,7 @@ declare class SaleorAuthClient {
39
33
  * }, [])
40
34
  * ```
41
35
  */
42
- constructor({ saleorApiUrl, storageKeyPrefix, refreshTokenStorage, accessTokenStorage, onAuthRefresh, tokenGracePeriod, defaultRequestInit, }: SaleorAuthClientProps);
36
+ constructor({ saleorApiUrl, refreshTokenStorage, accessTokenStorage, onAuthRefresh, tokenGracePeriod, defaultRequestInit, }: SaleorAuthClientProps);
43
37
  cleanup: () => void;
44
38
  private runAuthorizedRequest;
45
39
  private handleRequestWithTokenRefresh;
@@ -110,6 +110,10 @@ var getTokenExpiry = (token) => {
110
110
  const parsedTokenData = decodeToken(token);
111
111
  return parsedTokenData.exp * MILLI_MULTIPLYER || 0;
112
112
  };
113
+ var getTokenIss = (token) => {
114
+ const parsedTokenData = decodeToken(token);
115
+ return parsedTokenData.iss;
116
+ };
113
117
  var isExpiredToken = (token, tokenGracePeriod) => {
114
118
  return getTokenExpiry(token) - tokenGracePeriod <= Date.now();
115
119
  };
@@ -239,15 +243,22 @@ var SaleorAccessTokenStorageHandler = class {
239
243
  this.storage = storage;
240
244
  this.prefix = prefix;
241
245
  }
246
+ // In-memory cache so the token is available even when the storage
247
+ // backend is read-only (e.g. Next.js cookies during render).
248
+ cachedToken = null;
242
249
  getAccessToken = () => {
250
+ if (this.cachedToken)
251
+ return this.cachedToken;
243
252
  const key = getAccessTokenKey(this.prefix);
244
253
  return this.storage.getItem(key);
245
254
  };
246
255
  setAccessToken = (token) => {
256
+ this.cachedToken = token;
247
257
  const key = getAccessTokenKey(this.prefix);
248
258
  return this.storage.setItem(key, token);
249
259
  };
250
260
  clearAuthStorage = () => {
261
+ this.cachedToken = null;
251
262
  const key = getAccessTokenKey(this.prefix);
252
263
  return this.storage.removeItem(key);
253
264
  };
@@ -283,7 +294,6 @@ var SaleorAuthClient = class {
283
294
  */
284
295
  constructor({
285
296
  saleorApiUrl,
286
- storageKeyPrefix,
287
297
  refreshTokenStorage,
288
298
  accessTokenStorage,
289
299
  onAuthRefresh,
@@ -296,23 +306,47 @@ var SaleorAuthClient = class {
296
306
  }
297
307
  this.onAuthRefresh = onAuthRefresh;
298
308
  this.saleorApiUrl = saleorApiUrl;
299
- const keyPrefix = storageKeyPrefix ?? saleorApiUrl;
300
309
  const refreshTokenRepo = refreshTokenStorage ?? (typeof window !== "undefined" ? window.localStorage : void 0);
301
- this.refreshTokenStorage = refreshTokenRepo ? new SaleorRefreshTokenStorageHandler(refreshTokenRepo, keyPrefix) : null;
310
+ this.refreshTokenStorage = refreshTokenRepo ? new SaleorRefreshTokenStorageHandler(refreshTokenRepo, saleorApiUrl) : null;
302
311
  const accessTokenRepo = accessTokenStorage ?? getInMemoryAccessTokenStorage();
303
- this.accessTokenStorage = new SaleorAccessTokenStorageHandler(accessTokenRepo, keyPrefix);
312
+ this.accessTokenStorage = new SaleorAccessTokenStorageHandler(accessTokenRepo, saleorApiUrl);
304
313
  }
305
314
  cleanup = () => {
306
315
  this.refreshTokenStorage?.cleanup();
307
316
  };
308
- runAuthorizedRequest = (input, init) => {
317
+ runAuthorizedRequest = (input, init, additionalParams) => {
309
318
  const token = this.accessTokenStorage.getAccessToken();
310
319
  if (!token) {
311
320
  return fetch(input, init);
312
321
  }
313
- const headers = new Headers(init?.headers);
314
- headers.set("Authorization", `Bearer ${token}`);
315
- return fetch(input, { ...init, headers });
322
+ const headers = init?.headers || {};
323
+ const getURL = (input2) => {
324
+ if (typeof input2 === "string") {
325
+ return input2;
326
+ } else if ("url" in input2) {
327
+ return input2.url;
328
+ } else {
329
+ return input2.href;
330
+ }
331
+ };
332
+ const iss = getTokenIss(token);
333
+ const issuerAndDomainMatch = getURL(input) === iss;
334
+ const shouldAddAuthorizationHeader = issuerAndDomainMatch || additionalParams?.allowPassingTokenToThirdPartyDomains;
335
+ if (!issuerAndDomainMatch) {
336
+ if (shouldAddAuthorizationHeader) {
337
+ console.warn(
338
+ "Token's `iss` and request URL do not match but `allowPassingTokenToThirdPartyDomains` was specified."
339
+ );
340
+ } else {
341
+ console.warn(
342
+ "Token's `iss` and request URL do not match. Not adding `Authorization` header to the request."
343
+ );
344
+ }
345
+ }
346
+ return fetch(input, {
347
+ ...init,
348
+ headers: shouldAddAuthorizationHeader ? { ...headers, Authorization: `Bearer ${token}` } : headers
349
+ });
316
350
  };
317
351
  handleRequestWithTokenRefresh = async (input, requestInit, additionalParams) => {
318
352
  const refreshToken = this.refreshTokenStorage?.getRefreshToken();
@@ -324,37 +358,15 @@ var SaleorAuthClient = class {
324
358
  this.onAuthRefresh?.(true);
325
359
  if (this.tokenRefreshPromise) {
326
360
  const response = await this.tokenRefreshPromise;
327
- const responseClone = response.clone();
328
- const rawText = await response.clone().text();
329
- console.log("[auth-sdk] Token refresh raw response:", JSON.stringify({
330
- status: response.status,
331
- statusText: response.statusText,
332
- headers: Object.fromEntries(response.headers.entries()),
333
- bodyLength: rawText.length,
334
- body: rawText.slice(0, 500)
335
- }));
336
- let res;
337
- try {
338
- res = await responseClone.json();
339
- } catch {
340
- console.error("[auth-sdk] Token refresh response is not valid JSON, status:", response.status);
341
- this.onAuthRefresh?.(false);
342
- this.tokenRefreshPromise = null;
343
- this.refreshTokenStorage?.clearAuthStorage();
344
- return fetch(input, requestInit);
345
- }
346
- const graphqlErrors = res.errors;
347
- const token = res.data?.tokenRefresh?.token;
348
- const refreshErrors = res.data?.tokenRefresh?.errors;
361
+ const res = await response.clone().json();
362
+ const {
363
+ errors: graphqlErrors,
364
+ data: {
365
+ tokenRefresh: { errors, token }
366
+ }
367
+ } = res;
349
368
  this.onAuthRefresh?.(false);
350
- if (refreshErrors?.length || graphqlErrors?.length || !token) {
351
- console.warn("[auth-sdk] Token refresh failed:", JSON.stringify({
352
- graphqlErrors: graphqlErrors ?? [],
353
- refreshErrors: refreshErrors ?? [],
354
- hasToken: Boolean(token),
355
- httpStatus: response.status,
356
- rawData: res.data ?? null
357
- }));
369
+ if (errors?.length || graphqlErrors?.length || !token) {
358
370
  this.tokenRefreshPromise = null;
359
371
  this.refreshTokenStorage?.clearAuthStorage();
360
372
  return fetch(input, requestInit);
@@ -364,32 +376,10 @@ var SaleorAuthClient = class {
364
376
  this.tokenRefreshPromise = null;
365
377
  return this.runAuthorizedRequest(input, requestInit, additionalParams);
366
378
  }
367
- const refreshHeaders = {
368
- "Content-Type": "application/json"
369
- };
370
- if (requestInit?.headers) {
371
- const origHeaders = new Headers(requestInit.headers);
372
- for (const [key, value] of origHeaders.entries()) {
373
- if (key !== "host" && key !== "content-type") {
374
- refreshHeaders[key] = value;
375
- }
376
- }
377
- }
378
- const refreshBody = JSON.stringify({
379
- query: TOKEN_REFRESH.toString(),
380
- variables: { refreshToken }
381
- });
382
- console.log("[auth-sdk] Token refresh request:", JSON.stringify({
383
- url: this.saleorApiUrl,
384
- headers: refreshHeaders,
385
- bodyLength: refreshBody.length,
386
- bodyPreview: refreshBody.slice(0, 200)
387
- }));
388
- this.tokenRefreshPromise = fetch(this.saleorApiUrl, {
389
- method: "POST",
390
- headers: refreshHeaders,
391
- body: refreshBody
392
- });
379
+ this.tokenRefreshPromise = fetch(
380
+ this.saleorApiUrl,
381
+ getRequestData(TOKEN_REFRESH, { refreshToken }, { ...this.defaultRequestInit, ...requestInit })
382
+ );
393
383
  return this.fetchWithAuth(input, requestInit, additionalParams);
394
384
  };
395
385
  handleSignIn = async (response) => {
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  SaleorAuthClient,
3
3
  createSaleorAuthClient
4
- } from "./chunk-UHR2J6FG.mjs";
5
- import "./chunk-BZFBMGPG.mjs";
4
+ } from "./chunk-GFXR244N.mjs";
5
+ import "./chunk-B326YIV6.mjs";
6
6
  import "./chunk-263DHBMK.mjs";
7
7
  import "./chunk-UDLCOX6B.mjs";
8
8
  import "./chunk-7JTFMRQS.mjs";
@@ -5,15 +5,22 @@ var SaleorAccessTokenStorageHandler = class {
5
5
  this.storage = storage;
6
6
  this.prefix = prefix;
7
7
  }
8
+ // In-memory cache so the token is available even when the storage
9
+ // backend is read-only (e.g. Next.js cookies during render).
10
+ cachedToken = null;
8
11
  getAccessToken = () => {
12
+ if (this.cachedToken)
13
+ return this.cachedToken;
9
14
  const key = getAccessTokenKey(this.prefix);
10
15
  return this.storage.getItem(key);
11
16
  };
12
17
  setAccessToken = (token) => {
18
+ this.cachedToken = token;
13
19
  const key = getAccessTokenKey(this.prefix);
14
20
  return this.storage.setItem(key, token);
15
21
  };
16
22
  clearAuthStorage = () => {
23
+ this.cachedToken = null;
17
24
  const key = getAccessTokenKey(this.prefix);
18
25
  return this.storage.removeItem(key);
19
26
  };
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  SaleorAccessTokenStorageHandler
3
- } from "./chunk-BZFBMGPG.mjs";
3
+ } from "./chunk-B326YIV6.mjs";
4
4
  import {
5
5
  SaleorRefreshTokenStorageHandler
6
6
  } from "./chunk-263DHBMK.mjs";
7
7
  import {
8
8
  getRequestData,
9
+ getTokenIss,
9
10
  invariant,
10
11
  isExpiredToken
11
12
  } from "./chunk-UDLCOX6B.mjs";
@@ -46,7 +47,6 @@ var SaleorAuthClient = class {
46
47
  */
47
48
  constructor({
48
49
  saleorApiUrl,
49
- storageKeyPrefix,
50
50
  refreshTokenStorage,
51
51
  accessTokenStorage,
52
52
  onAuthRefresh,
@@ -59,23 +59,47 @@ var SaleorAuthClient = class {
59
59
  }
60
60
  this.onAuthRefresh = onAuthRefresh;
61
61
  this.saleorApiUrl = saleorApiUrl;
62
- const keyPrefix = storageKeyPrefix ?? saleorApiUrl;
63
62
  const refreshTokenRepo = refreshTokenStorage ?? (typeof window !== "undefined" ? window.localStorage : void 0);
64
- this.refreshTokenStorage = refreshTokenRepo ? new SaleorRefreshTokenStorageHandler(refreshTokenRepo, keyPrefix) : null;
63
+ this.refreshTokenStorage = refreshTokenRepo ? new SaleorRefreshTokenStorageHandler(refreshTokenRepo, saleorApiUrl) : null;
65
64
  const accessTokenRepo = accessTokenStorage ?? getInMemoryAccessTokenStorage();
66
- this.accessTokenStorage = new SaleorAccessTokenStorageHandler(accessTokenRepo, keyPrefix);
65
+ this.accessTokenStorage = new SaleorAccessTokenStorageHandler(accessTokenRepo, saleorApiUrl);
67
66
  }
68
67
  cleanup = () => {
69
68
  this.refreshTokenStorage?.cleanup();
70
69
  };
71
- runAuthorizedRequest = (input, init) => {
70
+ runAuthorizedRequest = (input, init, additionalParams) => {
72
71
  const token = this.accessTokenStorage.getAccessToken();
73
72
  if (!token) {
74
73
  return fetch(input, init);
75
74
  }
76
- const headers = new Headers(init?.headers);
77
- headers.set("Authorization", `Bearer ${token}`);
78
- return fetch(input, { ...init, headers });
75
+ const headers = init?.headers || {};
76
+ const getURL = (input2) => {
77
+ if (typeof input2 === "string") {
78
+ return input2;
79
+ } else if ("url" in input2) {
80
+ return input2.url;
81
+ } else {
82
+ return input2.href;
83
+ }
84
+ };
85
+ const iss = getTokenIss(token);
86
+ const issuerAndDomainMatch = getURL(input) === iss;
87
+ const shouldAddAuthorizationHeader = issuerAndDomainMatch || additionalParams?.allowPassingTokenToThirdPartyDomains;
88
+ if (!issuerAndDomainMatch) {
89
+ if (shouldAddAuthorizationHeader) {
90
+ console.warn(
91
+ "Token's `iss` and request URL do not match but `allowPassingTokenToThirdPartyDomains` was specified."
92
+ );
93
+ } else {
94
+ console.warn(
95
+ "Token's `iss` and request URL do not match. Not adding `Authorization` header to the request."
96
+ );
97
+ }
98
+ }
99
+ return fetch(input, {
100
+ ...init,
101
+ headers: shouldAddAuthorizationHeader ? { ...headers, Authorization: `Bearer ${token}` } : headers
102
+ });
79
103
  };
80
104
  handleRequestWithTokenRefresh = async (input, requestInit, additionalParams) => {
81
105
  const refreshToken = this.refreshTokenStorage?.getRefreshToken();
@@ -87,37 +111,15 @@ var SaleorAuthClient = class {
87
111
  this.onAuthRefresh?.(true);
88
112
  if (this.tokenRefreshPromise) {
89
113
  const response = await this.tokenRefreshPromise;
90
- const responseClone = response.clone();
91
- const rawText = await response.clone().text();
92
- console.log("[auth-sdk] Token refresh raw response:", JSON.stringify({
93
- status: response.status,
94
- statusText: response.statusText,
95
- headers: Object.fromEntries(response.headers.entries()),
96
- bodyLength: rawText.length,
97
- body: rawText.slice(0, 500)
98
- }));
99
- let res;
100
- try {
101
- res = await responseClone.json();
102
- } catch {
103
- console.error("[auth-sdk] Token refresh response is not valid JSON, status:", response.status);
104
- this.onAuthRefresh?.(false);
105
- this.tokenRefreshPromise = null;
106
- this.refreshTokenStorage?.clearAuthStorage();
107
- return fetch(input, requestInit);
108
- }
109
- const graphqlErrors = res.errors;
110
- const token = res.data?.tokenRefresh?.token;
111
- const refreshErrors = res.data?.tokenRefresh?.errors;
114
+ const res = await response.clone().json();
115
+ const {
116
+ errors: graphqlErrors,
117
+ data: {
118
+ tokenRefresh: { errors, token }
119
+ }
120
+ } = res;
112
121
  this.onAuthRefresh?.(false);
113
- if (refreshErrors?.length || graphqlErrors?.length || !token) {
114
- console.warn("[auth-sdk] Token refresh failed:", JSON.stringify({
115
- graphqlErrors: graphqlErrors ?? [],
116
- refreshErrors: refreshErrors ?? [],
117
- hasToken: Boolean(token),
118
- httpStatus: response.status,
119
- rawData: res.data ?? null
120
- }));
122
+ if (errors?.length || graphqlErrors?.length || !token) {
121
123
  this.tokenRefreshPromise = null;
122
124
  this.refreshTokenStorage?.clearAuthStorage();
123
125
  return fetch(input, requestInit);
@@ -127,32 +129,10 @@ var SaleorAuthClient = class {
127
129
  this.tokenRefreshPromise = null;
128
130
  return this.runAuthorizedRequest(input, requestInit, additionalParams);
129
131
  }
130
- const refreshHeaders = {
131
- "Content-Type": "application/json"
132
- };
133
- if (requestInit?.headers) {
134
- const origHeaders = new Headers(requestInit.headers);
135
- for (const [key, value] of origHeaders.entries()) {
136
- if (key !== "host" && key !== "content-type") {
137
- refreshHeaders[key] = value;
138
- }
139
- }
140
- }
141
- const refreshBody = JSON.stringify({
142
- query: TOKEN_REFRESH.toString(),
143
- variables: { refreshToken }
144
- });
145
- console.log("[auth-sdk] Token refresh request:", JSON.stringify({
146
- url: this.saleorApiUrl,
147
- headers: refreshHeaders,
148
- bodyLength: refreshBody.length,
149
- bodyPreview: refreshBody.slice(0, 200)
150
- }));
151
- this.tokenRefreshPromise = fetch(this.saleorApiUrl, {
152
- method: "POST",
153
- headers: refreshHeaders,
154
- body: refreshBody
155
- });
132
+ this.tokenRefreshPromise = fetch(
133
+ this.saleorApiUrl,
134
+ getRequestData(TOKEN_REFRESH, { refreshToken }, { ...this.defaultRequestInit, ...requestInit })
135
+ );
156
136
  return this.fetchWithAuth(input, requestInit, additionalParams);
157
137
  };
158
138
  handleSignIn = async (response) => {
package/dist/index.js CHANGED
@@ -113,6 +113,10 @@ var getTokenExpiry = (token) => {
113
113
  const parsedTokenData = decodeToken(token);
114
114
  return parsedTokenData.exp * MILLI_MULTIPLYER || 0;
115
115
  };
116
+ var getTokenIss = (token) => {
117
+ const parsedTokenData = decodeToken(token);
118
+ return parsedTokenData.iss;
119
+ };
116
120
  var isExpiredToken = (token, tokenGracePeriod) => {
117
121
  return getTokenExpiry(token) - tokenGracePeriod <= Date.now();
118
122
  };
@@ -242,15 +246,22 @@ var SaleorAccessTokenStorageHandler = class {
242
246
  this.storage = storage;
243
247
  this.prefix = prefix;
244
248
  }
249
+ // In-memory cache so the token is available even when the storage
250
+ // backend is read-only (e.g. Next.js cookies during render).
251
+ cachedToken = null;
245
252
  getAccessToken = () => {
253
+ if (this.cachedToken)
254
+ return this.cachedToken;
246
255
  const key = getAccessTokenKey(this.prefix);
247
256
  return this.storage.getItem(key);
248
257
  };
249
258
  setAccessToken = (token) => {
259
+ this.cachedToken = token;
250
260
  const key = getAccessTokenKey(this.prefix);
251
261
  return this.storage.setItem(key, token);
252
262
  };
253
263
  clearAuthStorage = () => {
264
+ this.cachedToken = null;
254
265
  const key = getAccessTokenKey(this.prefix);
255
266
  return this.storage.removeItem(key);
256
267
  };
@@ -286,7 +297,6 @@ var SaleorAuthClient = class {
286
297
  */
287
298
  constructor({
288
299
  saleorApiUrl,
289
- storageKeyPrefix,
290
300
  refreshTokenStorage,
291
301
  accessTokenStorage,
292
302
  onAuthRefresh,
@@ -299,23 +309,47 @@ var SaleorAuthClient = class {
299
309
  }
300
310
  this.onAuthRefresh = onAuthRefresh;
301
311
  this.saleorApiUrl = saleorApiUrl;
302
- const keyPrefix = storageKeyPrefix ?? saleorApiUrl;
303
312
  const refreshTokenRepo = refreshTokenStorage ?? (typeof window !== "undefined" ? window.localStorage : void 0);
304
- this.refreshTokenStorage = refreshTokenRepo ? new SaleorRefreshTokenStorageHandler(refreshTokenRepo, keyPrefix) : null;
313
+ this.refreshTokenStorage = refreshTokenRepo ? new SaleorRefreshTokenStorageHandler(refreshTokenRepo, saleorApiUrl) : null;
305
314
  const accessTokenRepo = accessTokenStorage ?? getInMemoryAccessTokenStorage();
306
- this.accessTokenStorage = new SaleorAccessTokenStorageHandler(accessTokenRepo, keyPrefix);
315
+ this.accessTokenStorage = new SaleorAccessTokenStorageHandler(accessTokenRepo, saleorApiUrl);
307
316
  }
308
317
  cleanup = () => {
309
318
  this.refreshTokenStorage?.cleanup();
310
319
  };
311
- runAuthorizedRequest = (input, init) => {
320
+ runAuthorizedRequest = (input, init, additionalParams) => {
312
321
  const token = this.accessTokenStorage.getAccessToken();
313
322
  if (!token) {
314
323
  return fetch(input, init);
315
324
  }
316
- const headers = new Headers(init?.headers);
317
- headers.set("Authorization", `Bearer ${token}`);
318
- return fetch(input, { ...init, headers });
325
+ const headers = init?.headers || {};
326
+ const getURL = (input2) => {
327
+ if (typeof input2 === "string") {
328
+ return input2;
329
+ } else if ("url" in input2) {
330
+ return input2.url;
331
+ } else {
332
+ return input2.href;
333
+ }
334
+ };
335
+ const iss = getTokenIss(token);
336
+ const issuerAndDomainMatch = getURL(input) === iss;
337
+ const shouldAddAuthorizationHeader = issuerAndDomainMatch || additionalParams?.allowPassingTokenToThirdPartyDomains;
338
+ if (!issuerAndDomainMatch) {
339
+ if (shouldAddAuthorizationHeader) {
340
+ console.warn(
341
+ "Token's `iss` and request URL do not match but `allowPassingTokenToThirdPartyDomains` was specified."
342
+ );
343
+ } else {
344
+ console.warn(
345
+ "Token's `iss` and request URL do not match. Not adding `Authorization` header to the request."
346
+ );
347
+ }
348
+ }
349
+ return fetch(input, {
350
+ ...init,
351
+ headers: shouldAddAuthorizationHeader ? { ...headers, Authorization: `Bearer ${token}` } : headers
352
+ });
319
353
  };
320
354
  handleRequestWithTokenRefresh = async (input, requestInit, additionalParams) => {
321
355
  const refreshToken = this.refreshTokenStorage?.getRefreshToken();
@@ -327,37 +361,15 @@ var SaleorAuthClient = class {
327
361
  this.onAuthRefresh?.(true);
328
362
  if (this.tokenRefreshPromise) {
329
363
  const response = await this.tokenRefreshPromise;
330
- const responseClone = response.clone();
331
- const rawText = await response.clone().text();
332
- console.log("[auth-sdk] Token refresh raw response:", JSON.stringify({
333
- status: response.status,
334
- statusText: response.statusText,
335
- headers: Object.fromEntries(response.headers.entries()),
336
- bodyLength: rawText.length,
337
- body: rawText.slice(0, 500)
338
- }));
339
- let res;
340
- try {
341
- res = await responseClone.json();
342
- } catch {
343
- console.error("[auth-sdk] Token refresh response is not valid JSON, status:", response.status);
344
- this.onAuthRefresh?.(false);
345
- this.tokenRefreshPromise = null;
346
- this.refreshTokenStorage?.clearAuthStorage();
347
- return fetch(input, requestInit);
348
- }
349
- const graphqlErrors = res.errors;
350
- const token = res.data?.tokenRefresh?.token;
351
- const refreshErrors = res.data?.tokenRefresh?.errors;
364
+ const res = await response.clone().json();
365
+ const {
366
+ errors: graphqlErrors,
367
+ data: {
368
+ tokenRefresh: { errors, token }
369
+ }
370
+ } = res;
352
371
  this.onAuthRefresh?.(false);
353
- if (refreshErrors?.length || graphqlErrors?.length || !token) {
354
- console.warn("[auth-sdk] Token refresh failed:", JSON.stringify({
355
- graphqlErrors: graphqlErrors ?? [],
356
- refreshErrors: refreshErrors ?? [],
357
- hasToken: Boolean(token),
358
- httpStatus: response.status,
359
- rawData: res.data ?? null
360
- }));
372
+ if (errors?.length || graphqlErrors?.length || !token) {
361
373
  this.tokenRefreshPromise = null;
362
374
  this.refreshTokenStorage?.clearAuthStorage();
363
375
  return fetch(input, requestInit);
@@ -367,32 +379,10 @@ var SaleorAuthClient = class {
367
379
  this.tokenRefreshPromise = null;
368
380
  return this.runAuthorizedRequest(input, requestInit, additionalParams);
369
381
  }
370
- const refreshHeaders = {
371
- "Content-Type": "application/json"
372
- };
373
- if (requestInit?.headers) {
374
- const origHeaders = new Headers(requestInit.headers);
375
- for (const [key, value] of origHeaders.entries()) {
376
- if (key !== "host" && key !== "content-type") {
377
- refreshHeaders[key] = value;
378
- }
379
- }
380
- }
381
- const refreshBody = JSON.stringify({
382
- query: TOKEN_REFRESH.toString(),
383
- variables: { refreshToken }
384
- });
385
- console.log("[auth-sdk] Token refresh request:", JSON.stringify({
386
- url: this.saleorApiUrl,
387
- headers: refreshHeaders,
388
- bodyLength: refreshBody.length,
389
- bodyPreview: refreshBody.slice(0, 200)
390
- }));
391
- this.tokenRefreshPromise = fetch(this.saleorApiUrl, {
392
- method: "POST",
393
- headers: refreshHeaders,
394
- body: refreshBody
395
- });
382
+ this.tokenRefreshPromise = fetch(
383
+ this.saleorApiUrl,
384
+ getRequestData(TOKEN_REFRESH, { refreshToken }, { ...this.defaultRequestInit, ...requestInit })
385
+ );
396
386
  return this.fetchWithAuth(input, requestInit, additionalParams);
397
387
  };
398
388
  handleSignIn = async (response) => {
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  SaleorAuthClient,
3
3
  createSaleorAuthClient
4
- } from "./chunk-UHR2J6FG.mjs";
5
- import "./chunk-BZFBMGPG.mjs";
4
+ } from "./chunk-GFXR244N.mjs";
5
+ import "./chunk-B326YIV6.mjs";
6
6
  import "./chunk-263DHBMK.mjs";
7
7
  import {
8
8
  GraphQLError,
@@ -2,8 +2,8 @@ import {
2
2
  SaleorAuthProvider
3
3
  } from "../chunk-74GMXOK4.mjs";
4
4
  import "../chunk-NAQNA6DI.mjs";
5
- import "../chunk-UHR2J6FG.mjs";
6
- import "../chunk-BZFBMGPG.mjs";
5
+ import "../chunk-GFXR244N.mjs";
6
+ import "../chunk-B326YIV6.mjs";
7
7
  import "../chunk-263DHBMK.mjs";
8
8
  import "../chunk-UDLCOX6B.mjs";
9
9
  import "../chunk-7JTFMRQS.mjs";
@@ -3,8 +3,8 @@ import {
3
3
  createSafeContext,
4
4
  useSaleorAuthContext
5
5
  } from "../chunk-NAQNA6DI.mjs";
6
- import "../chunk-UHR2J6FG.mjs";
7
- import "../chunk-BZFBMGPG.mjs";
6
+ import "../chunk-GFXR244N.mjs";
7
+ import "../chunk-B326YIV6.mjs";
8
8
  import "../chunk-263DHBMK.mjs";
9
9
  import "../chunk-UDLCOX6B.mjs";
10
10
  import "../chunk-7JTFMRQS.mjs";
@@ -12,8 +12,8 @@ import {
12
12
  import {
13
13
  useSaleorExternalAuth
14
14
  } from "../chunk-Q3UFWDCC.mjs";
15
- import "../chunk-UHR2J6FG.mjs";
16
- import "../chunk-BZFBMGPG.mjs";
15
+ import "../chunk-GFXR244N.mjs";
16
+ import "../chunk-B326YIV6.mjs";
17
17
  import "../chunk-263DHBMK.mjs";
18
18
  import "../chunk-T35JF4IS.mjs";
19
19
  import "../chunk-KLIEZ4V4.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopsbuilder/auth-sdk",
3
- "version": "1.2.7",
3
+ "version": "1.2.9",
4
4
  "description": "Auth SDK for Saleor",
5
5
  "sideEffects": false,
6
6
  "files": ["dist/", "README.md"],