From faec2aedc6a815849a7642c6fb3b09b521f8a594 Mon Sep 17 00:00:00 2001 From: Ross Patterson Date: Sun, 20 Jun 2021 22:03:30 -0700 Subject: [PATCH] fix(auth): UI logged-in detection for other auths Defer to the API, specifically the presence of the `login` action, to determine if a user is logged in instead of depending on the implementation detail of the UI JWT login process. Refs #134784 --- CHANGELOG.md | 3 ++ src/actions/types/types.test.js | 8 ++-- .../manage/Contents/Contents.test.jsx | 4 +- src/components/manage/Edit/Edit.test.jsx | 47 +++++++------------ .../manage/Toolbar/Toolbar.test.jsx | 2 +- .../theme/Anontools/Anontools.test.jsx | 13 +++-- .../__snapshots__/Anontools.test.jsx.snap | 4 +- src/components/theme/App/App.test.jsx | 8 ++-- src/components/theme/Header/Header.jsx | 3 +- src/components/theme/Header/Header.test.jsx | 6 ++- src/components/theme/Login/Login.test.jsx | 5 ++ src/components/theme/View/View.test.jsx | 18 ++++--- src/selectors/userSession/userSession.js | 5 +- 13 files changed, 65 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e93425699a..815f08336a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,10 @@ ### Breaking ### Feature + - Allowing user to paste url in search box in objectBrowser @iFlameing +- Detect when a user has logged in by means other than JWT, such as ZMI `Basic` + authentication or the classic HTML Plone `@login` view @rpatterson ### Bugfix diff --git a/src/actions/types/types.test.js b/src/actions/types/types.test.js index 885be2ec12..486b8b64f9 100644 --- a/src/actions/types/types.test.js +++ b/src/actions/types/types.test.js @@ -1,13 +1,15 @@ import { getTypes } from './types'; import { GET_TYPES } from '@plone/volto/constants/ActionTypes'; +import { arrayWIdsToObject } from '@plone/volto/helpers/Utils/Utils'; + +const actions = { user: [{ id: 'logout' }] }; +const actionsById = arrayWIdsToObject(actions); describe('Types action', () => { describe('getTypes', () => { it('should create an action to get the types', () => { const getState = () => ({ - userSession: { - token: 'thetoken', - }, + actions: { actions, actionsById }, }); const url = '/blog'; const dispatch = jest.fn(); diff --git a/src/components/manage/Contents/Contents.test.jsx b/src/components/manage/Contents/Contents.test.jsx index 8963041329..8e021e3ec3 100644 --- a/src/components/manage/Contents/Contents.test.jsx +++ b/src/components/manage/Contents/Contents.test.jsx @@ -41,6 +41,7 @@ const actions = { title: 'Contents', }, ], + user: [{ id: 'logout' }], }; const actionsById = arrayWIdsToObject(actions); @@ -48,9 +49,6 @@ describe('Contents', () => { it('renders a folder contents view component', () => { const store = mockStore({ actions: { actions, actionsById }, - userSession: { - token: '14134234123qwdaf', - }, search: { items: [ { diff --git a/src/components/manage/Edit/Edit.test.jsx b/src/components/manage/Edit/Edit.test.jsx index 5e28911e95..ed0dc3f278 100644 --- a/src/components/manage/Edit/Edit.test.jsx +++ b/src/components/manage/Edit/Edit.test.jsx @@ -2,8 +2,8 @@ import React from 'react'; import renderer from 'react-test-renderer'; import configureStore from 'redux-mock-store'; import { Provider } from 'react-intl-redux'; -import jwt from 'jsonwebtoken'; +import { arrayWIdsToObject } from '@plone/volto/helpers/Utils/Utils'; import { __test__ as Edit } from './Edit'; const mockStore = configureStore(); @@ -13,24 +13,23 @@ jest.mock('react-portal', () => ({ })); jest.mock('../Form/Form', () => jest.fn(() =>
)); +const actions = { + document_actions: [], + object: [ + { + icon: '', + id: 'edit', + title: 'Edit', + }, + ], + user: [{ id: 'logout' }], +}; +const actionsById = arrayWIdsToObject(actions); + describe('Edit', () => { it('renders an empty edit component', () => { const store = mockStore({ - userSession: { - token: jwt.sign({ fullname: 'John Doe' }, 'secret'), - }, - actions: { - actions: { - document_actions: [], - object: [ - { - icon: '', - id: 'edit', - title: 'Edit', - }, - ], - }, - }, + actions: { actions, actionsById }, schema: { schema: null, }, @@ -61,21 +60,7 @@ describe('Edit', () => { it('renders an edit component', () => { const store = mockStore({ - userSession: { - token: jwt.sign({ fullname: 'John Doe' }, 'secret'), - }, - actions: { - actions: { - document_actions: [], - object: [ - { - icon: '', - id: 'edit', - title: 'Edit', - }, - ], - }, - }, + actions: { actions, actionsById }, schema: { schema: { some: 'field', diff --git a/src/components/manage/Toolbar/Toolbar.test.jsx b/src/components/manage/Toolbar/Toolbar.test.jsx index f1328eb7de..22135c2fe4 100644 --- a/src/components/manage/Toolbar/Toolbar.test.jsx +++ b/src/components/manage/Toolbar/Toolbar.test.jsx @@ -108,7 +108,7 @@ const actions = { title: 'Log out', }, ], -} +}; const actionsById = arrayWIdsToObject(actions); describe('Toolbar', () => { diff --git a/src/components/theme/Anontools/Anontools.test.jsx b/src/components/theme/Anontools/Anontools.test.jsx index 628e214925..3b64f27631 100644 --- a/src/components/theme/Anontools/Anontools.test.jsx +++ b/src/components/theme/Anontools/Anontools.test.jsx @@ -5,13 +5,17 @@ import { Provider } from 'react-intl-redux'; import { MemoryRouter } from 'react-router-dom'; import Anontools from './Anontools'; +import { arrayWIdsToObject } from '@plone/volto/helpers/Utils/Utils'; const mockStore = configureStore(); +const actions = { user: [{ id: 'login' }] }; +const actionsById = arrayWIdsToObject(actions); + describe('Anontools', () => { - it('renders an anontools component when no token is specified', () => { + it('renders an anontools component when no use is logged in', () => { const store = mockStore({ - userSession: { token: null }, + actions: { actions, actionsById }, content: { data: { '@id': 'myid' } }, intl: { locale: 'en', @@ -29,9 +33,10 @@ describe('Anontools', () => { expect(json).toMatchSnapshot(); }); - it('should not render an anontools component when a token is specified', () => { + it('should not render an anontools component when a user is logged in', () => { + const actions = { user: [{ id: 'logout' }] }; const store = mockStore({ - userSession: { token: '1234' }, + actions: { actions, actionsById: arrayWIdsToObject(actions) }, content: { data: {} }, intl: { locale: 'en', diff --git a/src/components/theme/Anontools/__snapshots__/Anontools.test.jsx.snap b/src/components/theme/Anontools/__snapshots__/Anontools.test.jsx.snap index 70b76d32f0..68bfb1abfb 100644 --- a/src/components/theme/Anontools/__snapshots__/Anontools.test.jsx.snap +++ b/src/components/theme/Anontools/__snapshots__/Anontools.test.jsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Anontools renders an anontools component when no token is specified 1`] = ` +exports[`Anontools renders an anontools component when no use is logged in 1`] = `
@@ -19,4 +19,4 @@ exports[`Anontools renders an anontools component when no token is specified 1`]
`; -exports[`Anontools should not render an anontools component when a token is specified 1`] = `null`; +exports[`Anontools should not render an anontools component when a user is logged in 1`] = `null`; diff --git a/src/components/theme/App/App.test.jsx b/src/components/theme/App/App.test.jsx index 2a34423864..a6b2748998 100644 --- a/src/components/theme/App/App.test.jsx +++ b/src/components/theme/App/App.test.jsx @@ -6,6 +6,7 @@ import { MemoryRouter } from 'react-router-dom'; import config from '@plone/volto/registry'; import { __test__ as App } from './App'; +import { arrayWIdsToObject } from '@plone/volto/helpers/Utils/Utils'; beforeAll(() => { config.settings.navDepth = 1; @@ -35,12 +36,13 @@ jest.mock('semantic-ui-react', () => ({ })); jest.mock('../Footer/Footer', () => jest.fn(() =>