aws-amplify-react
Version:
AWS Amplify is a JavaScript library for Frontend and mobile developers building cloud-enabled applications.
156 lines (137 loc) • 5.3 kB
JSX
/*
* Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
import * as React from 'react';
import { Component } from 'react';
import { I18n, ConsoleLogger as Logger } from '@aws-amplify/core';
import Auth from '@aws-amplify/auth';
import AmplifyTheme from '../Amplify-UI/Amplify-UI-Theme';
import {
FormSection,
SectionHeader,
SectionBody,
SectionFooter,
InputLabel,
Input,
Button,
Toast
} from '../Amplify-UI/Amplify-UI-Components-React';
import { totpQrcode } from '@aws-amplify/ui';
const QRCode = require('qrcode.react');
const logger = new Logger('TOTPSetupComp');
export default class TOTPSetupComp extends Component {
constructor(props) {
super(props);
this.setup = this.setup.bind(this);
this.showSecretCode = this.showSecretCode.bind(this);
this.verifyTotpToken= this.verifyTotpToken.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
this.triggerTOTPEvent = this.triggerTOTPEvent.bind(this);
this.state = {
code: null,
setupMessage: null
};
}
componentDidMount() {
this.setup();
}
triggerTOTPEvent(event, data, user) {
if (this.props.onTOTPEvent) {
this.props.onTOTPEvent(event, data, user);
}
}
handleInputChange(evt) {
this.setState({setupMessage: null});
this.inputs = {};
const { name, value, type, checked } = evt.target;
const check_type = ['radio', 'checkbox'].includes(type);
this.inputs[name] = check_type? checked : value;
}
setup() {
this.setState({setupMessage: null});
const user = this.props.authData;
if (!Auth || typeof Auth.setupTOTP !== 'function') {
throw new Error('No Auth module found, please ensure @aws-amplify/auth is imported');
}
Auth.setupTOTP(user).then((data) => {
logger.debug('secret key', data);
const code = "otpauth://totp/AWSCognito:"+ user.username + "?secret=" + data + "&issuer=AWSCognito";
this.setState({code});
}).catch((err) => logger.debug('totp setup failed', err));
}
verifyTotpToken() {
if (!this.inputs) {
logger.debug('no input');
return;
}
const user = this.props.authData;
const { totpCode } = this.inputs;
if (!Auth || typeof Auth.verifyTotpToken !== 'function' || typeof Auth.setPreferredMFA !== 'function') {
throw new Error('No Auth module found, please ensure @aws-amplify/auth is imported');
}
Auth.verifyTotpToken(user, totpCode)
.then(() => {
// set it to preferred mfa
Auth.setPreferredMFA(user, 'TOTP');
this.setState({setupMessage: 'Setup TOTP successfully!'});
logger.debug('set up totp success!');
this.triggerTOTPEvent('Setup TOTP', 'SUCCESS', user);
})
.catch(err => {
this.setState({setupMessage: 'Setup TOTP failed!'});
logger.error(err);
});
}
showSecretCode(code, theme) {
if (!code) return null;
return (
<div>
<div className={totpQrcode}>
<QRCode value={code} />
</div>
<InputLabel theme={theme}>{I18n.get('Enter Security Code:')}</InputLabel>
<Input
autoFocus
theme={theme}
key="totpCode"
name="totpCode"
onChange={this.handleInputChange}
/>
</div>
);
}
render() {
const theme = this.props.theme ? this.props.theme: AmplifyTheme;
const code = this.state.code;
return (
<FormSection theme={theme}>
{this.state.setupMessage &&
<Toast>
{ I18n.get(this.state.setupMessage) }
</Toast>
}
<SectionHeader theme={theme}>{I18n.get('Scan then enter verification code')}</SectionHeader>
<SectionBody theme={theme}>
{this.showSecretCode(code, theme)}
{this.state.setupMessage &&
I18n.get(this.state.setupMessage)
}
</SectionBody>
<SectionFooter theme={theme}>
<Button theme={theme} onClick={this.verifyTotpToken} style={{width: '100%'}}>
{I18n.get('Verify Security Token')}
</Button>
</SectionFooter>
</FormSection>
);
}
}