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