From 13001bf1b0f51a77301f812b88889f07d086fe41 Mon Sep 17 00:00:00 2001 From: Zak Burke Date: Thu, 30 May 2024 17:05:03 -0400 Subject: [PATCH] Revert "STCOR-853 do not include credential in /authn/token request (#1480)" (#1486) This reverts commit d6e7af84b5db2baaa60e253816496cd8b79daf0a. We don't want to _send_ old cookies, but we do want to _receive_ new cookies. `omit` ignores both. From https://developer.mozilla.org/en-US/docs/Web/API/fetch#credentials: > `omit`: Tells browsers to exclude credentials from the request, and > ignore any credentials sent back in the response (e.g., any Set-Cookie > header). We may still have a cookie exchange problem, but if we do, `credentials: "omit"` won't solve it. --- CHANGELOG.md | 1 - src/components/OIDCLanding.js | 2 +- src/components/OIDCLanding.test.js | 85 ------------------------------ 3 files changed, 1 insertion(+), 87 deletions(-) delete mode 100644 src/components/OIDCLanding.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 3062f6b7f..492b0fe96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,6 @@ * Idle-session timeout and "Keep working?" modal. Refs STCOR-776. * Use keycloak URLs in place of users-bl for tenant-switch. Refs US1153537. * Fix 404 error page when logging in after changing password in Eureka. Refs STCOR-845. -* Omit credentials in requests to `/authn/token` to prevent redirect tailspin. Refs STCOR-853. ## [10.1.1](https://github.com/folio-org/stripes-core/tree/v10.1.1) (2024-03-25) [Full Changelog](https://github.com/folio-org/stripes-core/compare/v10.1.0...v10.1.1) diff --git a/src/components/OIDCLanding.js b/src/components/OIDCLanding.js index 7d351d249..5887c67e0 100644 --- a/src/components/OIDCLanding.js +++ b/src/components/OIDCLanding.js @@ -59,7 +59,7 @@ const OIDCLanding = () => { if (otp) { setPotp(otp); fetch(`${okapi.url}/authn/token?code=${otp}&redirect-uri=${window.location.protocol}//${window.location.host}/oidc-landing`, { - credentials: 'omit', + credentials: 'include', headers: { 'X-Okapi-tenant': okapi.tenant, 'Content-Type': 'application/json' }, mode: 'cors', }) diff --git a/src/components/OIDCLanding.test.js b/src/components/OIDCLanding.test.js deleted file mode 100644 index 9a075176f..000000000 --- a/src/components/OIDCLanding.test.js +++ /dev/null @@ -1,85 +0,0 @@ -import { render, screen, waitFor } from '@folio/jest-config-stripes/testing-library/react'; - -import { requestUserWithPerms, setTokenExpiry } from '../loginServices'; -import OIDCLanding from './OIDCLanding'; - -jest.mock('react-router-dom', () => ({ - useLocation: () => ({ - search: 'session_state=dead-beef&code=c0ffee' - }), - Redirect: () => <>Redirect, -})); - -jest.mock('react-redux', () => ({ - useStore: () => { }, -})); - -jest.mock('../StripesContext', () => ({ - useStripes: () => ({ - okapi: { url: 'https://whaterver' }, - }), -})); - -// jest.mock('../loginServices'); - - -const mockSetTokenExpiry = jest.fn(); -const mockRequestUserWithPerms = jest.fn(); -const mockFoo = jest.fn(); -jest.mock('../loginServices', () => ({ - setTokenExpiry: () => mockSetTokenExpiry(), - requestUserWithPerms: () => mockRequestUserWithPerms(), - foo: () => mockFoo(), -})); - - -// fetch success: resolve promise with ok == true and $data in json() -const mockFetchSuccess = (data) => { - global.fetch = jest.fn().mockImplementation(() => ( - Promise.resolve({ - ok: true, - json: () => Promise.resolve(data), - headers: new Map(), - }) - )); -}; - -// fetch failure: resolve promise with ok == false and $error in json() -const mockFetchError = (error) => { - global.fetch = jest.fn().mockImplementation(() => ( - Promise.resolve({ - ok: false, - json: () => Promise.resolve(error), - headers: new Map(), - }) - )); -}; - -// restore default fetch impl -const mockFetchCleanUp = () => { - global.fetch.mockClear(); - delete global.fetch; -}; - -describe('OIDCLanding', () => { - it('calls requestUserWithPerms, setTokenExpiry on success', async () => { - mockFetchSuccess({ - accessTokenExpiration: '2024-05-23T09:47:17.000-04:00', - refreshTokenExpiration: '2024-05-23T10:07:17.000-04:00', - }); - - await render(); - screen.getByText('Loading'); - await waitFor(() => expect(mockSetTokenExpiry).toHaveBeenCalledTimes(1)); - await waitFor(() => expect(mockRequestUserWithPerms).toHaveBeenCalledTimes(1)); - mockFetchCleanUp(); - }); - - it('displays an error on failure', async () => { - mockFetchError('barf'); - - await render(); - await screen.findByText('errors.saml.missingToken'); - mockFetchCleanUp(); - }); -});