@openmrs/esm-api 10.0.1-pre.4892 → 10.0.1-pre.4915
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/.turbo/turbo-build.log +1 -1
- package/dist/openmrs-fetch.d.ts.map +1 -1
- package/dist/openmrs-fetch.js +13 -8
- package/package.json +9 -9
- package/src/openmrs-fetch.test.ts +40 -0
- package/src/openmrs-fetch.ts +16 -7
package/.turbo/turbo-build.log
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openmrs-fetch.d.ts","sourceRoot":"","sources":["../src/openmrs-fetch.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAIlC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C,mEAAmE;AACnE,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,uEAAuE;AACvE,eAAO,MAAM,WAAW,iBAAiB,CAAC;AAC1C,sDAAsD;AACtD,eAAO,MAAM,eAAe,wBAA2B,CAAC;AAExD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,UASnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,WAAgB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"openmrs-fetch.d.ts","sourceRoot":"","sources":["../src/openmrs-fetch.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAIlC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C,mEAAmE;AACnE,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,uEAAuE;AACvE,eAAO,MAAM,WAAW,iBAAiB,CAAC;AAC1C,sDAAsD;AACtD,eAAO,MAAM,eAAe,wBAA2B,CAAC;AAExD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,UASnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,WAAgB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAuK1G;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,GAAE,WAAgB,gCA8BjF;AAED,qBAAa,iBAAkB,SAAQ,KAAM,YAAW,UAAU;gBACpD,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,GAAG,IAAI,EAAE,iBAAiB,EAAE,KAAK;IAQxG,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IACxE,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAC3B;AAED,KAAK,YAAY,GAAG,MAAM,GAAG,iBAAiB,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,UAAU,SAAS;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;CACnC"}
|
package/dist/openmrs-fetch.js
CHANGED
|
@@ -143,15 +143,20 @@ import { defaultRedirectAuthFailureUrl } from "./config-schema.js";
|
|
|
143
143
|
const response = r;
|
|
144
144
|
const { redirectAuthFailure, followRedirects } = await getConfig('@openmrs/esm-api');
|
|
145
145
|
if (response.ok) {
|
|
146
|
+
/*
|
|
147
|
+
* Backend modules can trigger SPA redirects by returning a `Location` header.
|
|
148
|
+
* This is required because `fetch()` hides HTTP redirects from the application.
|
|
149
|
+
*
|
|
150
|
+
* - Session endpoint (2xx): Authentication challenge URLs (e.g. TOTP,2FA).
|
|
151
|
+
* - HTTP 204: Logout redirect URLs (e.g. Keycloak IdP logout). Refer: OA-41 #1231
|
|
152
|
+
*/ const location = response.headers.get('location');
|
|
153
|
+
const shouldRedirect = followRedirects && location && (url === makeUrl(sessionEndpoint) || response.status === 204);
|
|
154
|
+
if (shouldRedirect) {
|
|
155
|
+
navigate({
|
|
156
|
+
to: location
|
|
157
|
+
});
|
|
158
|
+
}
|
|
146
159
|
if (response.status === 204) {
|
|
147
|
-
if (followRedirects && response.headers.has('location')) {
|
|
148
|
-
const location = response.headers.get('location');
|
|
149
|
-
if (location) {
|
|
150
|
-
navigate({
|
|
151
|
-
to: location
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
160
|
/* HTTP 204 - No Content
|
|
156
161
|
* We should not try to download the empty response as json. Instead,
|
|
157
162
|
* we return null since there is no response body.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-api",
|
|
3
|
-
"version": "10.0.1-pre.
|
|
3
|
+
"version": "10.0.1-pre.4915",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "The javascript module for interacting with the OpenMRS API",
|
|
6
6
|
"type": "module",
|
|
@@ -56,16 +56,16 @@
|
|
|
56
56
|
"lodash-es": "^4.17.21"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@openmrs/esm-config": "^10.0.1-pre.
|
|
60
|
-
"@openmrs/esm-error-handling": "^10.0.1-pre.
|
|
61
|
-
"@openmrs/esm-globals": "^10.0.1-pre.
|
|
62
|
-
"@openmrs/esm-navigation": "^10.0.1-pre.
|
|
59
|
+
"@openmrs/esm-config": "^10.0.1-pre.4915",
|
|
60
|
+
"@openmrs/esm-error-handling": "^10.0.1-pre.4915",
|
|
61
|
+
"@openmrs/esm-globals": "^10.0.1-pre.4915",
|
|
62
|
+
"@openmrs/esm-navigation": "^10.0.1-pre.4915"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@openmrs/esm-config": "10.0.1-pre.
|
|
66
|
-
"@openmrs/esm-error-handling": "10.0.1-pre.
|
|
67
|
-
"@openmrs/esm-globals": "10.0.1-pre.
|
|
68
|
-
"@openmrs/esm-navigation": "10.0.1-pre.
|
|
65
|
+
"@openmrs/esm-config": "10.0.1-pre.4915",
|
|
66
|
+
"@openmrs/esm-error-handling": "10.0.1-pre.4915",
|
|
67
|
+
"@openmrs/esm-globals": "10.0.1-pre.4915",
|
|
68
|
+
"@openmrs/esm-navigation": "10.0.1-pre.4915",
|
|
69
69
|
"@swc/cli": "0.8.1",
|
|
70
70
|
"@swc/core": "1.15.21",
|
|
71
71
|
"@vitest/coverage-v8": "^4.1.2",
|
|
@@ -22,6 +22,7 @@ describe('openmrsFetch', () => {
|
|
|
22
22
|
errors: [401],
|
|
23
23
|
resolvePromise: false,
|
|
24
24
|
},
|
|
25
|
+
followRedirects: true,
|
|
25
26
|
}),
|
|
26
27
|
);
|
|
27
28
|
window.openmrsBase = '/openmrs';
|
|
@@ -131,6 +132,10 @@ describe('openmrsFetch', () => {
|
|
|
131
132
|
Promise.resolve({
|
|
132
133
|
ok: true,
|
|
133
134
|
status: 200,
|
|
135
|
+
headers: {
|
|
136
|
+
has: () => false,
|
|
137
|
+
get: () => null,
|
|
138
|
+
},
|
|
134
139
|
clone: () => ({
|
|
135
140
|
text: () => Promise.resolve('{ "value": "hi" }'),
|
|
136
141
|
}),
|
|
@@ -148,6 +153,10 @@ describe('openmrsFetch', () => {
|
|
|
148
153
|
Promise.resolve({
|
|
149
154
|
ok: true,
|
|
150
155
|
status: 204,
|
|
156
|
+
headers: {
|
|
157
|
+
has: () => false,
|
|
158
|
+
get: () => null,
|
|
159
|
+
},
|
|
151
160
|
json: () => Promise.reject(Error("No json for HTTP 204's!!")),
|
|
152
161
|
}),
|
|
153
162
|
);
|
|
@@ -241,6 +250,33 @@ describe('openmrsFetch', () => {
|
|
|
241
250
|
});
|
|
242
251
|
});
|
|
243
252
|
|
|
253
|
+
it('redirects to the Location header URL when session endpoint called and it contains a Location header', async () => {
|
|
254
|
+
// @ts-expect-error
|
|
255
|
+
window.fetch.mockReturnValue(
|
|
256
|
+
Promise.resolve({
|
|
257
|
+
ok: true,
|
|
258
|
+
status: 200,
|
|
259
|
+
statusText: 'OK',
|
|
260
|
+
headers: {
|
|
261
|
+
has: (name: string) => name.toLowerCase() === 'location',
|
|
262
|
+
get: (name: string) => (name.toLowerCase() === 'location' ? '/openmrs/spa/login' : null),
|
|
263
|
+
},
|
|
264
|
+
clone() {
|
|
265
|
+
return this;
|
|
266
|
+
},
|
|
267
|
+
text: () => Promise.resolve(''),
|
|
268
|
+
}),
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
const fetchPromise = openmrsFetch('/ws/rest/v1/session');
|
|
272
|
+
|
|
273
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
274
|
+
|
|
275
|
+
expect(mockNavigate).toHaveBeenCalledWith({
|
|
276
|
+
to: '/openmrs/spa/login',
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
|
|
244
280
|
it('redirects to the default login URL when a 401 response has no Location header (genuine auth failure)', async () => {
|
|
245
281
|
mockGetConfig.mockResolvedValueOnce({
|
|
246
282
|
redirectAuthFailure: {
|
|
@@ -312,6 +348,10 @@ describe('openmrsObservableFetch', () => {
|
|
|
312
348
|
Promise.resolve({
|
|
313
349
|
ok: true,
|
|
314
350
|
status: 200,
|
|
351
|
+
headers: {
|
|
352
|
+
has: () => false,
|
|
353
|
+
get: () => null,
|
|
354
|
+
},
|
|
315
355
|
clone: () => ({
|
|
316
356
|
text: () => Promise.resolve('{"value": "hi"}'),
|
|
317
357
|
}),
|
package/src/openmrs-fetch.ts
CHANGED
|
@@ -157,15 +157,24 @@ export function openmrsFetch<T = any>(path: string, fetchInit: FetchConfig = {})
|
|
|
157
157
|
return window.fetch(url, fetchInit as RequestInit).then(async (r) => {
|
|
158
158
|
const response = r as FetchResponse<T>;
|
|
159
159
|
const { redirectAuthFailure, followRedirects } = await getConfig<EsmApiConfigObject>('@openmrs/esm-api');
|
|
160
|
+
|
|
160
161
|
if (response.ok) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
162
|
+
/*
|
|
163
|
+
* Backend modules can trigger SPA redirects by returning a `Location` header.
|
|
164
|
+
* This is required because `fetch()` hides HTTP redirects from the application.
|
|
165
|
+
*
|
|
166
|
+
* - Session endpoint (2xx): Authentication challenge URLs (e.g. TOTP,2FA).
|
|
167
|
+
* - HTTP 204: Logout redirect URLs (e.g. Keycloak IdP logout). Refer: OA-41 #1231
|
|
168
|
+
*/
|
|
169
|
+
const location = response.headers.get('location');
|
|
170
|
+
const shouldRedirect =
|
|
171
|
+
followRedirects && location && (url === makeUrl(sessionEndpoint) || response.status === 204);
|
|
168
172
|
|
|
173
|
+
if (shouldRedirect) {
|
|
174
|
+
navigate({ to: location });
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (response.status === 204) {
|
|
169
178
|
/* HTTP 204 - No Content
|
|
170
179
|
* We should not try to download the empty response as json. Instead,
|
|
171
180
|
* we return null since there is no response body.
|