UNPKG

aws-amplify-react

Version:

AWS Amplify is a JavaScript library for Frontend and mobile developers building cloud-enabled applications.

287 lines (259 loc) • 11.6 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 { I18n, ConsoleLogger as Logger } from '@aws-amplify/core'; import Auth from '@aws-amplify/auth'; import AuthPiece from './AuthPiece'; import { FormSection, SectionHeader, SectionBody, SectionFooter, FormField, Input, InputLabel, SelectInput, Button, Link, SectionFooterPrimaryContent, SectionFooterSecondaryContent, } from '../Amplify-UI/Amplify-UI-Components-React'; import countryDialCodes from './common/country-dial-codes.js'; import defaultSignUpFields from './common/default-sign-in-fields' import { valid } from 'semver'; const logger = new Logger('SignUp'); export default class SignUp extends AuthPiece { constructor(props) { super(props); this._validAuthStates = ['signUp']; this.signUp = this.signUp.bind(this); this.sortFields = this.sortFields.bind(this); this.getDefaultDialCode = this.getDefaultDialCode.bind(this); this.checkCustomSignUpFields = this.checkCustomSignUpFields.bind(this); this.defaultSignUpFields = defaultSignUpFields; this.needPrefix = this.needPrefix.bind(this); this.header = (this.props && this.props.signUpConfig && this.props.signUpConfig.header) ? this.props.signUpConfig.header : 'Create a new account'; } validate() { const invalids = []; this.signUpFields.map((el) => { if (el.key !== 'phone_number') { if (el.required && !this.inputs[el.key]) { el.invalid = true; invalids.push(el.label); } else { el.invalid = false; } } else { if (el.required && (!this.inputs.dial_code || !this.inputs.phone_line_number)) { el.invalid = true; invalids.push(el.label); } else { el.invalid = false; } } }); return invalids; } sortFields() { if (this.props.signUpConfig && this.props.signUpConfig.hiddenDefaults && this.props.signUpConfig.hiddenDefaults.length > 0){ this.defaultSignUpFields = this.defaultSignUpFields.filter((d) => { return !this.props.signUpConfig.hiddenDefaults.includes(d.key); }); } if (this.checkCustomSignUpFields()) { if (!this.props.signUpConfig || !this.props.signUpConfig.hideAllDefaults) { // see if fields passed to component should override defaults this.defaultSignUpFields.forEach((f, i) => { const matchKey = this.signUpFields.findIndex((d) => { return d.key === f.key; }); if (matchKey === -1) { this.signUpFields.push(f); } }); } /* sort fields based on following rules: 1. Fields with displayOrder are sorted before those without displayOrder 2. Fields with conflicting displayOrder are sorted alphabetically by key 3. Fields without displayOrder are sorted alphabetically by key */ this.signUpFields.sort((a, b) => { if (a.displayOrder && b.displayOrder) { if (a.displayOrder < b.displayOrder) { return -1; } else if (a.displayOrder > b.displayOrder) { return 1; } else { if (a.key < b.key) { return -1; } else { return 1; } } } else if (!a.displayOrder && b.displayOrder) { return 1; } else if (a.displayOrder && !b.displayOrder) { return -1; } else if (!a.displayOrder && !b.displayOrder) { if (a.key < b.key) { return -1; } else { return 1; } } }); } else { this.signUpFields = this.defaultSignUpFields; } } needPrefix(key) { const field = this.signUpFields.find(e => e.key === key); if (key.indexOf('custom:') !== 0) { return field.custom ; } else if (key.indexOf('custom:') === 0 && field.custom === false) { logger.warn('Custom prefix prepended to key but custom field flag is set to false; retaining manually entered prefix'); } return null; } getDefaultDialCode() { return this.props.signUpConfig && this.props.signUpConfig.defaultCountryCode && countryDialCodes.indexOf(`+${this.props.signUpConfig.defaultCountryCode}`) !== '-1' ? `+${this.props.signUpConfig.defaultCountryCode}` : "+1" } checkCustomSignUpFields() { return this.props.signUpConfig && this.props.signUpConfig.signUpFields && this.props.signUpConfig.signUpFields.length > 0 } signUp() { if (!this.inputs.dial_code) { this.inputs.dial_code = this.getDefaultDialCode(); } const validation = this.validate(); if (validation && validation.length > 0) { return this.error(`The following fields need to be filled out: ${validation.join(', ')}`); } if (!Auth || typeof Auth.signUp !== 'function') { throw new Error('No Auth module found, please ensure @aws-amplify/auth is imported'); } let signup_info = { username: this.inputs.username, password: this.inputs.password, attributes: { } }; const inputKeys = Object.keys(this.inputs); const inputVals = Object.values(this.inputs); inputKeys.forEach((key, index) => { if (!['username', 'password', 'checkedValue', 'dial_code'].includes(key)) { if (key !== 'phone_line_number' && key !== 'dial_code' && key !== 'error') { const newKey = `${this.needPrefix(key) ? 'custom:' : ''}${key}`; signup_info.attributes[newKey] = inputVals[index]; } else if (inputVals[index]) { signup_info.attributes['phone_number'] = `${this.inputs.dial_code}${this.inputs.phone_line_number.replace(/[-()]/g, '')}` } } }); Auth.signUp(signup_info).then((data) => { this.changeState('confirmSignUp', data.user.username) }) .catch(err => this.error(err)); } showComponent(theme) { const { hide } = this.props; if (hide && hide.includes(SignUp)) { return null; } if (this.checkCustomSignUpFields()) { this.signUpFields = this.props.signUpConfig.signUpFields; } this.sortFields(); return ( <FormSection theme={theme}> <SectionHeader theme={theme}>{I18n.get(this.header)}</SectionHeader> <SectionBody theme={theme}> { this.signUpFields.map((field) => { return field.key !== 'phone_number' ? ( <FormField theme={theme} key={field.key}> { field.required ? <InputLabel theme={theme}>{I18n.get(field.label)} *</InputLabel> : <InputLabel theme={theme}>{I18n.get(field.label)}</InputLabel> } <Input autoFocus={ this.signUpFields.findIndex((f) => { return f.key === field.key }) === 0 ? true : false } placeholder={I18n.get(field.placeholder)} theme={theme} type={field.type} name={field.key} key={field.key} onChange={this.handleInputChange} /> </FormField> ) : ( <FormField theme={theme} key="phone_number"> { field.required ? <InputLabel theme={theme}>{I18n.get(field.label)} *</InputLabel> : <InputLabel theme={theme}>{I18n.get(field.label)}</InputLabel> } <SelectInput theme={theme}> <select name="dial_code" defaultValue={this.getDefaultDialCode()} onChange={this.handleInputChange}> {countryDialCodes.map(dialCode => <option key={dialCode} value={dialCode}> {dialCode} </option> )} </select> <Input placeholder={I18n.get(field.placeholder)} theme={theme} type="tel" id="phone_line_number" key="phone_line_number" name="phone_line_number" onChange={this.handleInputChange} /> </SelectInput> </FormField> ) }) } </SectionBody> <SectionFooter theme={theme}> <SectionFooterPrimaryContent theme={theme}> <Button onClick={this.signUp} theme={theme}> {I18n.get('Create Account')} </Button> </SectionFooterPrimaryContent> <SectionFooterSecondaryContent theme={theme}> {I18n.get('Have an account? ')} <Link theme={theme} onClick={() => this.changeState('signIn')}> {I18n.get('Sign in')} </Link> </SectionFooterSecondaryContent> </SectionFooter> </FormSection> ); } }