Security Key method is not displayed if browser does not support it.

pull/342/head
Clement Michaud 2019-03-24 22:36:49 +01:00
parent a717b965c1
commit a4b129a676
4 changed files with 16 additions and 20 deletions

View File

@ -8,6 +8,7 @@ export interface OwnProps {}
export interface StateProps { export interface StateProps {
availableMethods: Method2FA[] | null; availableMethods: Method2FA[] | null;
isSecurityKeySupported: boolean;
} }
export interface DispatchProps { export interface DispatchProps {
@ -48,8 +49,13 @@ class UseAnotherMethod extends Component<Props> {
key: "duo_push" key: "duo_push"
} }
]; ];
const methodsComponents = methods const methodsComponents = methods
// Filter out security key if not supported by browser.
.filter(m => m.key !== "u2f" || (m.key === "u2f" && this.props.isSecurityKeySupported))
// Filter out the methods that are not supported by the server.
.filter(m => this.props.availableMethods && this.props.availableMethods.includes(m.key)) .filter(m => this.props.availableMethods && this.props.availableMethods.includes(m.key))
// Create the buttons
.map(m => <Button raised onClick={m.onClicked} key={m.key}>{m.name}</Button>); .map(m => <Button raised onClick={m.onClicked} key={m.key}>{m.name}</Button>);
return ( return (

View File

@ -5,9 +5,7 @@ import LogoutBehavior from '../../../behaviors/LogoutBehavior';
import { RootState } from '../../../reducers'; import { RootState } from '../../../reducers';
import { StateProps, DispatchProps } from '../../../components/SecondFactorForm/SecondFactorForm'; import { StateProps, DispatchProps } from '../../../components/SecondFactorForm/SecondFactorForm';
import FetchPrefered2faMethod from '../../../behaviors/FetchPrefered2faMethod'; import FetchPrefered2faMethod from '../../../behaviors/FetchPrefered2faMethod';
import SetPrefered2faMethod from '../../../behaviors/SetPrefered2faMethod'; import { setUseAnotherMethod } from '../../../reducers/Portal/SecondFactor/actions';
import { getPreferedMethodSuccess, setUseAnotherMethod } from '../../../reducers/Portal/SecondFactor/actions';
import Method2FA from '../../../types/Method2FA';
const mapStateToProps = (state: RootState): StateProps => { const mapStateToProps = (state: RootState): StateProps => {
return { return {
@ -16,15 +14,6 @@ const mapStateToProps = (state: RootState): StateProps => {
} }
} }
async function storeMethod(dispatch: Dispatch, method: Method2FA) {
// display the new option
dispatch(getPreferedMethodSuccess(method));
dispatch(setUseAnotherMethod(false));
// And save the method for next time.
await SetPrefered2faMethod(dispatch, method);
}
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => { const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => {
return { return {
onInit: () => FetchPrefered2faMethod(dispatch), onInit: () => FetchPrefered2faMethod(dispatch),

View File

@ -10,7 +10,6 @@ import {
securityKeySignSuccess, securityKeySignSuccess,
securityKeySign, securityKeySign,
securityKeySignFailure, securityKeySignFailure,
setSecurityKeySupported
} from '../../../reducers/Portal/SecondFactor/actions'; } from '../../../reducers/Portal/SecondFactor/actions';
import FetchStateBehavior from '../../../behaviors/FetchStateBehavior'; import FetchStateBehavior from '../../../behaviors/FetchStateBehavior';
@ -94,11 +93,7 @@ const mapDispatchToProps = (dispatch: Dispatch, ownProps: OwnProps) => {
await dispatch(push('/confirmation-sent')); await dispatch(push('/confirmation-sent'));
}, },
onInit: async () => { onInit: async () => {
const isU2FSupported = await u2fApi.isSupported();
if (isU2FSupported) {
await dispatch(setSecurityKeySupported(true));
await triggerSecurityKeySigning(dispatch, ownProps.redirectionUrl); await triggerSecurityKeySigning(dispatch, ownProps.redirectionUrl);
}
}, },
} }
} }

View File

@ -2,13 +2,16 @@ import { connect } from 'react-redux';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import { RootState } from '../../../reducers'; import { RootState } from '../../../reducers';
import SetPrefered2faMethod from '../../../behaviors/SetPrefered2faMethod'; import SetPrefered2faMethod from '../../../behaviors/SetPrefered2faMethod';
import { getPreferedMethodSuccess, setUseAnotherMethod } from '../../../reducers/Portal/SecondFactor/actions'; import { getPreferedMethodSuccess, setUseAnotherMethod, setSecurityKeySupported } from '../../../reducers/Portal/SecondFactor/actions';
import Method2FA from '../../../types/Method2FA'; import Method2FA from '../../../types/Method2FA';
import UseAnotherMethod, {StateProps, DispatchProps} from '../../../components/UseAnotherMethod/UseAnotherMethod'; import UseAnotherMethod, {StateProps, DispatchProps} from '../../../components/UseAnotherMethod/UseAnotherMethod';
import GetAvailable2faMethods from '../../../behaviors/GetAvailable2faMethods'; import GetAvailable2faMethods from '../../../behaviors/GetAvailable2faMethods';
import u2fApi from 'u2f-api';
const mapStateToProps = (state: RootState): StateProps => ({ const mapStateToProps = (state: RootState): StateProps => ({
availableMethods: state.secondFactor.getAvailableMethodResponse, availableMethods: state.secondFactor.getAvailableMethodResponse,
isSecurityKeySupported: state.secondFactor.securityKeySupported,
}) })
async function storeMethod(dispatch: Dispatch, method: Method2FA) { async function storeMethod(dispatch: Dispatch, method: Method2FA) {
@ -22,7 +25,10 @@ async function storeMethod(dispatch: Dispatch, method: Method2FA) {
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => { const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => {
return { return {
onInit: () => GetAvailable2faMethods(dispatch), onInit: async () => {
dispatch(setSecurityKeySupported(await u2fApi.isSupported()));
await GetAvailable2faMethods(dispatch);
},
onOneTimePasswordMethodClicked: () => storeMethod(dispatch, 'totp'), onOneTimePasswordMethodClicked: () => storeMethod(dispatch, 'totp'),
onSecurityKeyMethodClicked: () => storeMethod(dispatch, 'u2f'), onSecurityKeyMethodClicked: () => storeMethod(dispatch, 'u2f'),
onDuoPushMethodClicked: () => storeMethod(dispatch, "duo_push"), onDuoPushMethodClicked: () => storeMethod(dispatch, "duo_push"),