UNPKG

aws-amplify-react

Version:

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

191 lines (165 loc) • 6.97 kB
/* * Copyright 2017-2018 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 { facebookSignInButton } from '@aws-amplify/ui'; import { SignInButton, SignInButtonIcon, SignInButtonContent } from '../../Amplify-UI/Amplify-UI-Components-React'; import Constants from '../common/constants'; const logger = new Logger('withFacebook'); export default function withFacebook(Comp) { return class extends Component { constructor(props) { super(props); this.fbAsyncInit = this.fbAsyncInit.bind(this); this.initFB = this.initFB.bind(this); this.signIn = this.signIn.bind(this); this.signOut = this.signOut.bind(this); this.federatedSignIn = this.federatedSignIn.bind(this); this.state = {}; } signIn() { const fb = window.FB; fb.getLoginStatus(response => { const payload = { provider: Constants.FACEBOOK }; try { localStorage.setItem(Constants.AUTH_SOURCE_KEY, JSON.stringify(payload)); } catch (e) { logger.debug('Failed to cache auth source into localStorage', e); } if (response.status === 'connected') { this.federatedSignIn(response.authResponse); } else { fb.login( response => { if (!response || !response.authResponse) { return; } this.federatedSignIn(response.authResponse); }, { scope: 'public_profile,email' } ); } }); } federatedSignIn(response) { logger.debug(response); const { onStateChange } = this.props; const { accessToken, expiresIn } = response; const date = new Date(); const expires_at = expiresIn * 1000 + date.getTime(); if (!accessToken) { return; } const fb = window.FB; fb.api('/me', { fields: 'name,email' }, response => { const user = { name: response.name, email: response.email }; if (!Auth || typeof Auth.federatedSignIn !== 'function' || typeof Auth.currentAuthenticatedUser !== 'function') { throw new Error('No Auth module found, please ensure @aws-amplify/auth is imported'); } Auth.federatedSignIn('facebook', { token: accessToken, expires_at }, user) .then(credentials => { return Auth.currentAuthenticatedUser(); }).then(authUser => { if (onStateChange) { onStateChange('signedIn', authUser); } }); }); } signOut() { const fb = window.FB; if (!fb) { logger.debug('FB sdk undefined'); return Promise.resolve(); } fb.getLoginStatus(response => { if (response.status === 'connected') { return new Promise((res, rej) => { logger.debug('facebook signing out'); fb.logout(response => { res(response); }); }); } else { return Promise.resolve(); } }); } componentDidMount() { const { facebook_app_id } = this.props; if (facebook_app_id && !window.FB) this.createScript(); } fbAsyncInit() { logger.debug('init FB'); const { facebook_app_id } = this.props; const fb = window.FB; fb.init({ appId : facebook_app_id, cookie : true, xfbml : true, version : 'v2.11' }); fb.getLoginStatus(response => logger.debug(response)); } initFB() { const fb = window.FB; logger.debug('FB inited'); } createScript() { window.fbAsyncInit = this.fbAsyncInit; const script = document.createElement('script'); script.src = 'https://connect.facebook.net/en_US/sdk.js'; script.async = true; script.onload = this.initFB; document.body.appendChild(script); } render() { const fb = window.FB; return ( <Comp {...this.props} fb={fb} facebookSignIn={this.signIn} facebookSignOut={this.signOut}/> ); } }; } const Button = (props) => ( <SignInButton id={facebookSignInButton} onClick={props.facebookSignIn} theme={props.theme || AmplifyTheme} variant={'facebookSignInButton'} > <SignInButtonIcon theme={props.theme || AmplifyTheme}> <svg viewBox='0 0 279 538' xmlns='http://www.w3.org/2000/svg'><g id='Page-1' fill='none' fillRule='evenodd'><g id='Artboard' fill='#FFF'><path d='M82.3409742,538 L82.3409742,292.936652 L0,292.936652 L0,196.990154 L82.2410458,196.990154 L82.2410458,126.4295 C82.2410458,44.575144 132.205229,0 205.252865,0 C240.227794,0 270.306232,2.59855099 279,3.79788222 L279,89.2502322 L228.536175,89.2502322 C188.964542,89.2502322 181.270057,108.139699 181.270057,135.824262 L181.270057,196.89021 L276.202006,196.89021 L263.810888,292.836708 L181.16913,292.836708 L181.16913,538 L82.3409742,538 Z'id='Fill-1' /></g></g></svg> </SignInButtonIcon> <SignInButtonContent theme={props.theme || AmplifyTheme}> {I18n.get('Sign In with Facebook')} </SignInButtonContent> </SignInButton> ); export const FacebookButton = withFacebook(Button);