oidc-spa 8.6.6 → 8.6.8

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 @@ import {
4
4
  substitutePlaceholderByRealToken
5
5
  } from "./tokenPlaceholderSubstitution";
6
6
  import { getIsHostnameAuthorized } from "../tools/isHostnameAuthorized";
7
+ import { getIsLikelyDevServer } from "../tools/isLikelyDevServer";
7
8
 
8
9
  type Params = {
9
10
  resourceServersAllowedHostnames: string[] | undefined;
@@ -33,237 +34,271 @@ function patchFetchApiToSubstituteTokenPlaceholder(params: {
33
34
  const { resourceServersAllowedHostnames } = params;
34
35
 
35
36
  const fetch_actual = window.fetch;
37
+ //@ts-expect-error
38
+ const fetchLater_actual: typeof fetch_actual | undefined = window.fetchLater;
36
39
 
37
- window.fetch = async function fetch(input, init) {
38
- const request = input instanceof Request ? input : new Request(input, init);
40
+ const createFetchOrFetchLater = (params: { isFetchLater: boolean }) => {
41
+ const { isFetchLater } = params;
39
42
 
40
- let didSubstitute = false;
43
+ const fn: typeof fetch_actual = async (input, init) => {
44
+ const request = input instanceof Request ? input : new Request(input, init);
41
45
 
42
- let url: string;
46
+ let didSubstitute = false;
43
47
 
44
- {
45
- const url_before = `${request.url}`;
48
+ let url: string;
46
49
 
47
- url = substitutePlaceholderByRealToken(url_before);
50
+ {
51
+ const url_before = `${request.url}`;
48
52
 
49
- if (url !== url_before) {
50
- didSubstitute = true;
53
+ url = substitutePlaceholderByRealToken(url_before);
54
+
55
+ if (url !== url_before) {
56
+ didSubstitute = true;
57
+ }
51
58
  }
52
- }
53
59
 
54
- prevent_fetching_of_hashed_js_assets: {
55
- const { pathname } = new URL(url, window.location.href);
60
+ prevent_fetching_of_hashed_js_assets: {
61
+ const { pathname } = new URL(url, window.location.href);
56
62
 
57
- if (!viteHashedJsAssetPathRegExp.test(pathname)) {
58
- break prevent_fetching_of_hashed_js_assets;
63
+ if (!viteHashedJsAssetPathRegExp.test(pathname)) {
64
+ break prevent_fetching_of_hashed_js_assets;
65
+ }
66
+
67
+ throw new Error("oidc-spa: Blocked request to hashed js static asset.");
59
68
  }
60
69
 
61
- throw new Error("oidc-spa: Blocked request to hashed js static asset.");
62
- }
70
+ const headers = new Headers();
71
+ request.headers.forEach((value, key) => {
72
+ const nextValue = substitutePlaceholderByRealToken(value);
63
73
 
64
- const headers = new Headers();
65
- request.headers.forEach((value, key) => {
66
- const nextValue = substitutePlaceholderByRealToken(value);
74
+ if (nextValue !== value) {
75
+ didSubstitute = true;
76
+ }
67
77
 
68
- if (nextValue !== value) {
69
- didSubstitute = true;
70
- }
78
+ headers.set(key, nextValue);
79
+ });
71
80
 
72
- headers.set(key, nextValue);
73
- });
81
+ let body: BodyInit | undefined;
74
82
 
75
- let body: BodyInit | undefined;
83
+ handle_body: {
84
+ from_init: {
85
+ if (!init) {
86
+ break from_init;
87
+ }
76
88
 
77
- handle_body: {
78
- from_init: {
79
- if (!init) {
80
- break from_init;
81
- }
89
+ if (!init.body) {
90
+ break from_init;
91
+ }
82
92
 
83
- if (!init.body) {
84
- break from_init;
85
- }
93
+ if (input instanceof Request && input.body !== null) {
94
+ break from_init;
95
+ }
86
96
 
87
- if (input instanceof Request && input.body !== null) {
88
- break from_init;
89
- }
97
+ if (typeof init.body === "string") {
98
+ body = substitutePlaceholderByRealToken(init.body);
90
99
 
91
- if (typeof init.body === "string") {
92
- body = substitutePlaceholderByRealToken(init.body);
100
+ if (init.body !== body) {
101
+ didSubstitute = true;
102
+ }
93
103
 
94
- if (init.body !== body) {
95
- didSubstitute = true;
104
+ break handle_body;
96
105
  }
97
106
 
98
- break handle_body;
99
- }
107
+ if (init.body instanceof URLSearchParams) {
108
+ let didUrlSearchParamsSubstitute = false;
109
+ const next = new URLSearchParams();
110
+
111
+ init.body.forEach((value, key) => {
112
+ const nextValue = substitutePlaceholderByRealToken(value);
100
113
 
101
- if (init.body instanceof URLSearchParams) {
102
- let didUrlSearchParamsSubstitute = false;
103
- const next = new URLSearchParams();
114
+ if (nextValue !== value) {
115
+ didUrlSearchParamsSubstitute = true;
116
+ }
104
117
 
105
- init.body.forEach((value, key) => {
106
- const nextValue = substitutePlaceholderByRealToken(value);
118
+ next.append(key, nextValue);
119
+ });
107
120
 
108
- if (nextValue !== value) {
109
- didUrlSearchParamsSubstitute = true;
121
+ if (didUrlSearchParamsSubstitute) {
122
+ didSubstitute = true;
110
123
  }
111
124
 
112
- next.append(key, nextValue);
113
- });
125
+ body = didUrlSearchParamsSubstitute ? next : init.body;
114
126
 
115
- if (didUrlSearchParamsSubstitute) {
116
- didSubstitute = true;
127
+ break handle_body;
117
128
  }
118
129
 
119
- body = didUrlSearchParamsSubstitute ? next : init.body;
130
+ if (init.body instanceof FormData) {
131
+ let didFormDataSubstitute = false;
132
+ const next = new FormData();
120
133
 
121
- break handle_body;
122
- }
134
+ init.body.forEach((value, key) => {
135
+ if (typeof value === "string") {
136
+ const nextValue = substitutePlaceholderByRealToken(value);
123
137
 
124
- if (init.body instanceof FormData) {
125
- let didFormDataSubstitute = false;
126
- const next = new FormData();
138
+ if (nextValue !== value) {
139
+ didFormDataSubstitute = true;
140
+ }
127
141
 
128
- init.body.forEach((value, key) => {
129
- if (typeof value === "string") {
130
- const nextValue = substitutePlaceholderByRealToken(value);
142
+ next.append(key, nextValue);
131
143
 
132
- if (nextValue !== value) {
133
- didFormDataSubstitute = true;
144
+ return;
134
145
  }
135
146
 
136
- next.append(key, nextValue);
147
+ next.append(key, value);
148
+ });
137
149
 
138
- return;
150
+ if (didFormDataSubstitute) {
151
+ didSubstitute = true;
139
152
  }
140
153
 
141
- next.append(key, value);
142
- });
154
+ body = didFormDataSubstitute ? next : init.body;
143
155
 
144
- if (didFormDataSubstitute) {
145
- didSubstitute = true;
156
+ break handle_body;
146
157
  }
147
158
 
148
- body = didFormDataSubstitute ? next : init.body;
159
+ if (init.body instanceof Blob) {
160
+ break from_init;
161
+ }
149
162
 
163
+ body = init.body;
150
164
  break handle_body;
151
165
  }
152
166
 
153
- if (init.body instanceof Blob) {
154
- break from_init;
167
+ if (request.body === null) {
168
+ body = undefined;
169
+ break handle_body;
155
170
  }
156
171
 
157
- body = init.body;
158
- break handle_body;
159
- }
172
+ const shouldInspectBody = (() => {
173
+ let ct = headers.get("Content-Type");
160
174
 
161
- if (request.body === null) {
162
- body = undefined;
163
- break handle_body;
164
- }
175
+ if (ct === null) {
176
+ return false;
177
+ }
165
178
 
166
- const shouldInspectBody = (() => {
167
- let ct = headers.get("Content-Type");
179
+ ct = ct.toLocaleLowerCase();
168
180
 
169
- if (ct === null) {
170
- return false;
171
- }
181
+ if (
182
+ !ct.startsWith("application/json") &&
183
+ !ct.startsWith("application/x-www-form-urlencoded")
184
+ ) {
185
+ return false;
186
+ }
172
187
 
173
- ct = ct.toLocaleLowerCase();
188
+ const len_str = headers.get("Content-Length");
174
189
 
175
- if (
176
- !ct.startsWith("application/json") &&
177
- !ct.startsWith("application/x-www-form-urlencoded")
178
- ) {
179
- return false;
180
- }
190
+ if (len_str === null) {
191
+ // NOTE: This will have performance implications for large bodies
192
+ // but we have no other way to know the size
193
+ return true;
194
+ }
195
+
196
+ const len = parseInt(len_str, 10);
181
197
 
182
- const len_str = headers.get("Content-Length");
198
+ if (!Number.isFinite(len) || len > 100_000) {
199
+ return false;
200
+ }
183
201
 
184
- if (len_str === null) {
185
- // NOTE: This will have performance implications for large bodies
186
- // but we have no other way to know the size
187
202
  return true;
203
+ })();
204
+
205
+ if (!shouldInspectBody) {
206
+ body = request.body;
207
+ break handle_body;
188
208
  }
189
209
 
190
- const len = parseInt(len_str, 10);
210
+ const bodyText = await request.clone().text();
211
+ const nextBodyText = substitutePlaceholderByRealToken(bodyText);
191
212
 
192
- if (!Number.isFinite(len) || len > 100_000) {
193
- return false;
213
+ if (nextBodyText !== bodyText) {
214
+ didSubstitute = true;
194
215
  }
195
216
 
196
- return true;
197
- })();
198
-
199
- if (!shouldInspectBody) {
200
- body = request.body;
201
- break handle_body;
217
+ body = nextBodyText;
202
218
  }
203
219
 
204
- const bodyText = await request.clone().text();
205
- const nextBodyText = substitutePlaceholderByRealToken(bodyText);
206
-
207
- if (nextBodyText !== bodyText) {
208
- didSubstitute = true;
209
- }
220
+ block_authed_request_to_unauthorized_hostnames: {
221
+ if (!didSubstitute) {
222
+ break block_authed_request_to_unauthorized_hostnames;
223
+ }
210
224
 
211
- body = nextBodyText;
212
- }
225
+ const { hostname } = new URL(url, window.location.href);
213
226
 
214
- block_authed_request_to_unauthorized_hostnames: {
215
- if (!didSubstitute) {
216
- break block_authed_request_to_unauthorized_hostnames;
217
- }
227
+ if (
228
+ getIsHostnameAuthorized({
229
+ allowedHostnames: resourceServersAllowedHostnames,
230
+ extendAuthorizationToParentDomain: true,
231
+ hostname
232
+ })
233
+ ) {
234
+ break block_authed_request_to_unauthorized_hostnames;
235
+ }
218
236
 
219
- const { hostname } = new URL(url, window.location.href);
237
+ throw new Error(
238
+ [
239
+ `oidc-spa: Blocked authed request to ${hostname}.`,
240
+ `To authorize this request add "${hostname}" to`,
241
+ "`resourceServersAllowedHostnames`."
242
+ ].join(" ")
243
+ );
244
+ }
245
+
246
+ const nextInit: RequestInit = {
247
+ method: request.method,
248
+ headers,
249
+ body,
250
+ mode: request.mode,
251
+ credentials: request.credentials,
252
+ cache: request.cache,
253
+ redirect: request.redirect,
254
+ referrer: request.referrer,
255
+ referrerPolicy: request.referrerPolicy,
256
+ integrity: request.integrity,
257
+ keepalive: request.keepalive,
258
+ signal: request.signal
259
+ };
260
+
261
+ {
262
+ //@ts-expect-error
263
+ const duplex = init?.duplex ?? (input instanceof Request ? input.duplex : undefined);
220
264
 
221
- if (
222
- getIsHostnameAuthorized({
223
- allowedHostnames: resourceServersAllowedHostnames,
224
- extendAuthorizationToParentDomain: true,
225
- hostname
226
- })
227
- ) {
228
- break block_authed_request_to_unauthorized_hostnames;
265
+ if (duplex !== undefined) {
266
+ //@ts-expect-error
267
+ nextInit.duplex = duplex;
268
+ }
229
269
  }
230
270
 
231
- throw new Error(
232
- [
233
- `oidc-spa: Blocked authed request to ${hostname}.`,
234
- `To authorize this request add "${hostname}" to`,
235
- "`resourceServersAllowedHostnames`."
236
- ].join(" ")
237
- );
238
- }
271
+ fetch_later: {
272
+ if (!isFetchLater) {
273
+ break fetch_later;
274
+ }
239
275
 
240
- const nextInit: RequestInit = {
241
- method: request.method,
242
- headers,
243
- body,
244
- mode: request.mode,
245
- credentials: request.credentials,
246
- cache: request.cache,
247
- redirect: request.redirect,
248
- referrer: request.referrer,
249
- referrerPolicy: request.referrerPolicy,
250
- integrity: request.integrity,
251
- keepalive: request.keepalive,
252
- signal: request.signal
253
- };
276
+ assert(fetchLater_actual !== undefined);
254
277
 
255
- {
256
- //@ts-expect-error
257
- const duplex = init?.duplex ?? (input instanceof Request ? input.duplex : undefined);
278
+ const activateAfter =
279
+ //@ts-expect-error
280
+ init?.activateAfter ?? (input instanceof Request ? input.activateAfter : undefined);
258
281
 
259
- if (duplex !== undefined) {
260
- //@ts-expect-error
261
- nextInit.duplex = duplex;
282
+ if (activateAfter !== undefined) {
283
+ //@ts-expect-error
284
+ nextInit.activateAfter = activateAfter;
285
+ }
286
+
287
+ return fetchLater_actual(url, nextInit);
262
288
  }
263
- }
264
289
 
265
- return fetch_actual(url, nextInit);
290
+ return fetch_actual(url, nextInit);
291
+ };
292
+
293
+ return fn;
266
294
  };
295
+
296
+ window.fetch = createFetchOrFetchLater({ isFetchLater: false });
297
+ // @ts-expect-error
298
+ if (window.fetchLater) {
299
+ // @ts-expect-error
300
+ window.fetchLater = createFetchOrFetchLater({ isFetchLater: true });
301
+ }
267
302
  }
268
303
 
269
304
  function patchXMLHttpRequestApiToSubstituteTokenPlaceholder(params: {
@@ -330,6 +365,11 @@ function patchXMLHttpRequestApiToSubstituteTokenPlaceholder(params: {
330
365
  XMLHttpRequest.prototype.send = function send(body) {
331
366
  const state = stateByInstance.get(this);
332
367
 
368
+ // NOTE: Vite's dev server instantiates a websocket before earlyInit runs.
369
+ if (state === undefined && getIsLikelyDevServer()) {
370
+ return send_actual.call(this, body);
371
+ }
372
+
333
373
  assert(state !== undefined, "32323484");
334
374
 
335
375
  let nextBody = body;
@@ -1,11 +1,19 @@
1
+ import { isBrowser } from "./isBrowser";
2
+
1
3
  let isLikelyDevServer_cache: boolean | undefined = undefined;
2
4
 
5
+ const hasRefreshReg = isBrowser && "$RefreshReg$" in window;
6
+
3
7
  export function getIsLikelyDevServer(): boolean {
4
8
  if (isLikelyDevServer_cache !== undefined) {
5
9
  return isLikelyDevServer_cache;
6
10
  }
7
11
 
8
12
  const isLikelyDevServer = (() => {
13
+ if (hasRefreshReg) {
14
+ return true;
15
+ }
16
+
9
17
  const origin = window.location.origin;
10
18
 
11
19
  if (/^https?:\/\/localhost/.test(origin)) {
@@ -1,12 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getIsLikelyDevServer = getIsLikelyDevServer;
4
+ const isBrowser_1 = require("./isBrowser");
4
5
  let isLikelyDevServer_cache = undefined;
6
+ const hasRefreshReg = isBrowser_1.isBrowser && "$RefreshReg$" in window;
5
7
  function getIsLikelyDevServer() {
6
8
  if (isLikelyDevServer_cache !== undefined) {
7
9
  return isLikelyDevServer_cache;
8
10
  }
9
11
  const isLikelyDevServer = (() => {
12
+ if (hasRefreshReg) {
13
+ return true;
14
+ }
10
15
  const origin = window.location.origin;
11
16
  if (/^https?:\/\/localhost/.test(origin)) {
12
17
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"isLikelyDevServer.js","sourceRoot":"","sources":["../src/tools/isLikelyDevServer.ts"],"names":[],"mappings":";;AAEA,oDA0BC;AA5BD,IAAI,uBAAuB,GAAwB,SAAS,CAAC;AAE7D,SAAgB,oBAAoB;IAChC,IAAI,uBAAuB,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,uBAAuB,CAAC;IACnC,CAAC;IAED,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE;QAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAEtC,IAAI,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC,EAAE,CAAC;IAEL,uBAAuB,GAAG,iBAAiB,CAAC;IAE5C,OAAO,iBAAiB,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"isLikelyDevServer.js","sourceRoot":"","sources":["../src/tools/isLikelyDevServer.ts"],"names":[],"mappings":";;AAMA,oDA8BC;AApCD,2CAAwC;AAExC,IAAI,uBAAuB,GAAwB,SAAS,CAAC;AAE7D,MAAM,aAAa,GAAG,qBAAS,IAAI,cAAc,IAAI,MAAM,CAAC;AAE5D,SAAgB,oBAAoB;IAChC,IAAI,uBAAuB,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,uBAAuB,CAAC;IACnC,CAAC;IAED,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE;QAC5B,IAAI,aAAa,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAEtC,IAAI,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC,EAAE,CAAC;IAEL,uBAAuB,GAAG,iBAAiB,CAAC;IAE5C,OAAO,iBAAiB,CAAC;AAC7B,CAAC"}