/* * 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 React from 'react'; import { Keyboard } from 'react-native'; import { Auth, Logger, I18n } from 'aws-amplify'; import { isEmpty } from '@aws-amplify/core'; import AmplifyTheme, { AmplifyThemeType } from '../AmplifyTheme'; import AmplifyMessageMap from '../AmplifyMessageMap'; import { FormField, PhoneField } from '../AmplifyUI'; import TEST_ID from '../AmplifyTestIDs'; import { OnStateChangeType, UsernameAttributesType } from '../../types'; import { setTestId } from '../Utils'; const logger = new Logger('AuthPiece'); const labelMap = { email: 'Email', phone_number: 'Phone Number', username: 'Username', }; export interface IAuthPieceProps { authData?: any; authState?: string; errorMessage?: string; messageMap?: any; onStateChange?: OnStateChangeType; theme?: AmplifyThemeType; track?: () => void; usernameAttributes?: UsernameAttributesType; } export interface IAuthPieceState { email?: string; error?: string | null; phone_number?: string; username?: string; } export default class AuthPiece extends React.Component< Props, State > { _isHidden: boolean; _validAuthStates: String[]; constructor(props) { super(props); this._isHidden = true; this._validAuthStates = []; this.changeState = this.changeState.bind(this); this.error = this.error.bind(this); this.getUsernameFromInput = this.getUsernameFromInput.bind(this); this.renderUsernameField = this.renderUsernameField.bind(this); } getUsernameFromInput() { const { usernameAttributes = 'username' } = this.props; switch (usernameAttributes) { case 'email': return this.state.email; case 'phone_number': return this.state.phone_number; default: return this.state.username; } } renderUsernameField(theme: AmplifyThemeType) { const value = this.getUsernameFromInput(); const { usernameAttributes = [] } = this.props; if (usernameAttributes === 'email') { return ( this.setState({ email: text })} label={I18n.get('Email')} placeholder={I18n.get('Enter your email')} required={true} {...setTestId(TEST_ID.AUTH.EMAIL_INPUT)} value={value} /> ); } else if (usernameAttributes === 'phone_number') { return ( this.setState({ phone_number: text })} label={I18n.get('Phone Number')} placeholder={I18n.get('Enter your phone number')} keyboardType="phone-pad" required={true} {...setTestId(TEST_ID.AUTH.PHONE_INPUT)} value={value} /> ); } else { return ( this.setState({ username: text })} label={I18n.get(this.getUsernameLabel())} placeholder={I18n.get('Enter your username')} required={true} {...setTestId(TEST_ID.AUTH.USERNAME_INPUT)} value={value} /> ); } } getUsernameLabel() { const { usernameAttributes = 'username' } = this.props; return labelMap[usernameAttributes] || usernameAttributes; } changeState(state: string, data?: any) { if (this.props.onStateChange) { this.props.onStateChange(state, data); } } checkContact(user: any) { Auth.verifiedContact(user).then((data) => { logger.debug('verified user attributes', data); if (!isEmpty(data.verified)) { this.changeState('signedIn', user); } else { user = Object.assign(user, data); this.changeState('verifyContact', user); } }); } error(err: any) { logger.debug(err); let msg = ''; if (typeof err === 'string') { msg = err; } else if (err.message) { msg = err.message; } else { msg = JSON.stringify(err); } const map = this.props.errorMessage || this.props.messageMap || AmplifyMessageMap; msg = typeof map === 'string' ? map : map(msg); this.setState({ error: msg }); Keyboard.dismiss(); } render() { if (!this._validAuthStates.includes(this.props.authState)) { this._isHidden = true; return null; } if (this._isHidden) { const { track } = this.props; if (track) track(); } this._isHidden = false; return this.showComponent(this.props.theme || AmplifyTheme); } showComponent(theme): any { throw "You must implement showComponent(theme) and don't forget to set this._validAuthStates."; } }