1
/*
2
 * Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
5
 * the License. A copy of the License is located at
6
 *
7
 *     http://aws.amazon.com/apache2.0/
8
 *
9
 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
10
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
11
 * and limitations under the License.
12
 */
13

14 1
import * as React from 'react';
15

16 1
import { I18n, ConsoleLogger as Logger } from '@aws-amplify/core';
17 1
import { Auth } from '@aws-amplify/auth';
18 1
import AmplifyTheme from '../../Amplify-UI/Amplify-UI-Theme';
19 1
import { googleSignInButton } from '@aws-amplify/ui';
20 1
import {
21
	SignInButton,
22
	SignInButtonIcon,
23
	SignInButtonContent,
24
} from '../../Amplify-UI/Amplify-UI-Components-React';
25 1
import { Constants } from '../common/constants';
26

27 1
const logger = new Logger('withGoogle');
28

29 1
export function withGoogle(Comp) {
30 1
	return class extends React.Component<any, any> {
31
		constructor(props: any) {
32 1
			super(props);
33

34 1
			this.initGapi = this.initGapi.bind(this);
35 1
			this.signIn = this.signIn.bind(this);
36 1
			this.signOut = this.signOut.bind(this);
37 1
			this.federatedSignIn = this.federatedSignIn.bind(this);
38

39 1
			this.state = {};
40
		}
41

42 1
		signIn() {
43 1
			const ga = window.gapi.auth2.getAuthInstance();
44 1
			const { onError } = this.props;
45 1
			ga.signIn().then(
46
				googleUser => {
47 1
					this.federatedSignIn(googleUser);
48 1
					const payload = {
49
						provider: Constants.GOOGLE,
50
					};
51

52 1
					try {
53 1
						localStorage.setItem(
54
							Constants.AUTH_SOURCE_KEY,
55
							JSON.stringify(payload)
56
						);
57
					} catch (e) {
58 0
						logger.debug('Failed to cache auth source into localStorage', e);
59
					}
60
				},
61
				error => {
62 1
					if (onError) onError(error);
63 1
					else throw error;
64
				}
65
			);
66
		}
67

68 1
		async federatedSignIn(googleUser) {
69 1
			const { id_token, expires_at } = googleUser.getAuthResponse();
70 1
			const profile = googleUser.getBasicProfile();
71 1
			let user = {
72
				email: profile.getEmail(),
73
				name: profile.getName(),
74
				picture: profile.getImageUrl(),
75
			};
76

77 1
			const { onStateChange } = this.props;
78 1
			if (
79 1
				!Auth ||
80
				typeof Auth.federatedSignIn !== 'function' ||
81
				typeof Auth.currentAuthenticatedUser !== 'function'
82
			) {
83 0
				throw new Error(
84
					'No Auth module found, please ensure @aws-amplify/auth is imported'
85
				);
86
			}
87

88 1
			await Auth.federatedSignIn(
89
				'google',
90
				{ token: id_token, expires_at },
91
				user
92
			);
93

94 1
			user = await Auth.currentAuthenticatedUser();
95

96 1
			if (onStateChange) {
97 1
				onStateChange('signedIn', user);
98
			}
99
		}
100

101 1
		signOut() {
102
			const authInstance =
103 1
				window.gapi && window.gapi.auth2
104 1
					? window.gapi.auth2.getAuthInstance()
105
					: null;
106 1
			if (!authInstance) {
107 1
				return Promise.resolve();
108
			}
109

110 1
			authInstance.then(googleAuth => {
111 1
				if (!googleAuth) {
112 0
					logger.debug('google Auth undefined');
113 0
					return Promise.resolve();
114
				}
115

116 1
				logger.debug('google signing out');
117 1
				return googleAuth.signOut();
118
			});
119
		}
120

121 1
		componentDidMount() {
122 1
			const { google_client_id } = this.props;
123
			const ga =
124 1
				window.gapi && window.gapi.auth2
125 1
					? window.gapi.auth2.getAuthInstance()
126
					: null;
127 1
			if (google_client_id && !ga) this.createScript();
128
		}
129

130 1
		createScript() {
131 0
			const script = document.createElement('script');
132 0
			script.src = 'https://apis.google.com/js/platform.js';
133 0
			script.async = true;
134 0
			script.onload = this.initGapi;
135 0
			document.body.appendChild(script);
136
		}
137

138 1
		initGapi() {
139 1
			logger.debug('init gapi');
140

141 1
			const that = this;
142 1
			const { google_client_id } = this.props;
143 1
			const g = window.gapi;
144 1
			g.load('auth2', function() {
145 1
				g.auth2.init({
146
					client_id: google_client_id,
147
					scope: 'profile email openid',
148
				});
149
			});
150
		}
151

152 1
		render(): React.ReactNode {
153
			const ga =
154 1
				window.gapi && window.gapi.auth2
155 1
					? window.gapi.auth2.getAuthInstance()
156
					: null;
157 1
			return (
158
				<Comp
159
					{...this.props}
160
					ga={ga}
161
					googleSignIn={this.signIn}
162
					googleSignOut={this.signOut}
163
				/>
164
			);
165
		}
166 1
	};
167
}
168

169 1
const Button = props => (
170
	<SignInButton
171
		id={googleSignInButton}
172
		onClick={props.googleSignIn}
173 1
		theme={props.theme || AmplifyTheme}
174
		variant="googleSignInButton"
175
	>
176 1
		<SignInButtonIcon theme={props.theme || AmplifyTheme}>
177
			<svg
178
				viewBox="0 0 256 262"
179
				xmlns="http://ww0w.w3.org/2000/svg"
180
				preserveAspectRatio="xMidYMid"
181
			>
182
				<path
183
					d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622 38.755 30.023 2.685.268c24.659-22.774 38.875-56.282 38.875-96.027"
184
					fill="#4285F4"
185
				/>
186
				<path
187
					d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055-34.523 0-63.824-22.773-74.269-54.25l-1.531.13-40.298 31.187-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1"
188
					fill="#34A853"
189
				/>
190
				<path
191
					d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82 0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602l42.356-32.782"
192
					fill="#FBBC05"
193
				/>
194
				<path
195
					d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0 79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251"
196
					fill="#EB4335"
197
				/>
198
			</svg>
199
		</SignInButtonIcon>
200 1
		<SignInButtonContent theme={props.theme || AmplifyTheme}>
201
			{I18n.get('Sign In with Google')}
202
		</SignInButtonContent>
203
	</SignInButton>
204
);
205

206 1
export const GoogleButton = withGoogle(Button);
207

208
/**
209
 * @deprecated use named import
210
 */
211 1
export default withGoogle;

Read our documentation on viewing source code .

Loading