UNPKG

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
/* * 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> ); } }