/* * Wire * Copyright (C) 2018 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ import React from 'react'; import {ClientType} from '@wireapp/api-client/lib/client/index'; import {connect} from 'react-redux'; import {useNavigate} from 'react-router-dom'; import {AnyAction, Dispatch} from 'redux'; import {UrlUtil} from '@wireapp/commons'; import {ContainerXS, Loading} from '@wireapp/react-ui-kit'; import {getLogger} from 'Util/Logger'; import {ClientItem} from './ClientItem'; import {actionRoot as ROOT_ACTIONS} from '../module/action/'; import * as LocalStorageAction from '../module/action/LocalStorageAction'; import {bindActionCreators, RootState} from '../module/reducer'; import {getEntropy} from '../module/selector/AuthSelector'; import * as ClientSelector from '../module/selector/ClientSelector'; import * as SelfSelector from '../module/selector/SelfSelector'; import {QUERY_KEY, ROUTE} from '../route'; const logger = getLogger('ClientList'); type Props = React.HTMLProps; const ClientListComponent = ({ clientError, isFetching, isNoPasswordSSO, permanentClients, entropy, doInitializeClient, doRemoveClient, getLocalStorage, resetAuthError, resetClientError, removeLocalStorage, }: Props & ConnectedProps & DispatchProps) => { const navigate = useNavigate(); const [showLoading, setShowLoading] = React.useState(false); const isOauth = UrlUtil.hasURLParameter(QUERY_KEY.SCOPE); const [currentlySelectedClient, setCurrentlySelectedClient] = React.useState(null); const setSelectedClient = (clientId: string) => { const isSelectedClient = currentlySelectedClient === clientId; const selectedClientId = isSelectedClient ? null : clientId; setCurrentlySelectedClient(selectedClientId); resetAuthError(); resetClientError(); }; const removeClient = async (clientId: string, password?: string) => { try { const SFAcode = (await getLocalStorage(QUERY_KEY.CONVERSATION_CODE)) ?? undefined; setShowLoading(true); await doRemoveClient(clientId, password); const persist = await getLocalStorage(LocalStorageAction.LocalStorageKey.AUTH.PERSIST); await doInitializeClient(persist ? ClientType.PERMANENT : ClientType.TEMPORARY, password, SFAcode, entropy); removeLocalStorage(QUERY_KEY.CONVERSATION_CODE); removeLocalStorage(QUERY_KEY.JOIN_EXPIRES); if (isOauth) { return navigate(ROUTE.AUTHORIZE); } return navigate(ROUTE.HISTORY_INFO); } catch (error) { logger.error(error); } finally { setShowLoading(false); } }; const isSelectedClient = (clientId: string) => clientId === currentlySelectedClient; return isFetching || showLoading ? ( ) : ( {permanentClients.map(client => ( setSelectedClient(client.id)} onClientRemoval={(password?: string) => removeClient(client.id, password)} requirePassword={!isNoPasswordSSO} selected={isSelectedClient(client.id)} /> ))} ); }; type ConnectedProps = ReturnType; const mapStateToProps = (state: RootState) => ({ clientError: ClientSelector.getError(state), entropy: getEntropy(state), isFetching: ClientSelector.isFetching(state), isNoPasswordSSO: SelfSelector.isNoPasswordSSO(state), permanentClients: ClientSelector.getPermanentClients(state), }); type DispatchProps = ReturnType; const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators( { doInitializeClient: ROOT_ACTIONS.clientAction.doInitializeClient, doRemoveClient: ROOT_ACTIONS.clientAction.doRemoveClient, getLocalStorage: ROOT_ACTIONS.localStorageAction.getLocalStorage, removeLocalStorage: ROOT_ACTIONS.localStorageAction.deleteLocalStorage, resetAuthError: ROOT_ACTIONS.authAction.resetAuthError, resetClientError: ROOT_ACTIONS.clientAction.resetClientError, }, dispatch, ); const ClientList = connect(mapStateToProps, mapDispatchToProps)(ClientListComponent); export {ClientList};