@capgo/capacitor-social-login 1.2.5 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/web.js CHANGED
@@ -1,17 +1,14 @@
1
1
  import { WebPlugin } from '@capacitor/core';
2
+ import { AppleSocialLogin } from './apple-provider';
3
+ import { FacebookSocialLogin } from './facebook-provider';
4
+ import { GoogleSocialLogin } from './google-provider';
2
5
  export class SocialLoginWeb extends WebPlugin {
3
6
  constructor() {
4
7
  var _a;
5
8
  super();
6
- this.googleClientId = null;
7
- this.appleClientId = null;
8
- this.googleScriptLoaded = false;
9
- this.googleLoginType = 'online';
10
- this.appleScriptLoaded = false;
11
- this.appleScriptUrl = 'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';
12
- this.GOOGLE_TOKEN_REQUEST_URL = 'https://www.googleapis.com/oauth2/v3/tokeninfo';
13
- this.facebookAppId = null;
14
- this.facebookScriptLoaded = false;
9
+ this.googleProvider = new GoogleSocialLogin();
10
+ this.appleProvider = new AppleSocialLogin();
11
+ this.facebookProvider = new FacebookSocialLogin();
15
12
  // Set up listener for OAuth redirects if we have a pending OAuth flow
16
13
  if (localStorage.getItem(SocialLoginWeb.OAUTH_STATE_KEY)) {
17
14
  console.log('OAUTH_STATE_KEY found');
@@ -23,83 +20,31 @@ export class SocialLoginWeb extends WebPlugin {
23
20
  }
24
21
  }
25
22
  handleOAuthRedirect() {
26
- const paramsRaw = new URL(window.location.href).searchParams;
27
- const code = paramsRaw.get('code');
28
- if (code && paramsRaw.has('scope')) {
29
- return {
30
- provider: 'google',
31
- result: {
32
- provider: 'google',
33
- result: {
34
- serverAuthCode: code,
35
- },
36
- },
37
- };
38
- }
39
- const hash = window.location.hash.substring(1);
40
- console.log('handleOAuthRedirect', window.location.hash);
41
- if (!hash)
42
- return;
43
- console.log('handleOAuthRedirect ok');
44
- const params = new URLSearchParams(hash);
45
- const accessToken = params.get('access_token');
46
- const idToken = params.get('id_token');
47
- if (accessToken && idToken) {
48
- localStorage.removeItem(SocialLoginWeb.OAUTH_STATE_KEY);
49
- const profile = this.parseJwt(idToken);
50
- return {
51
- provider: 'google',
52
- result: {
53
- accessToken: {
54
- token: accessToken,
55
- },
56
- idToken,
57
- profile: {
58
- email: profile.email || null,
59
- familyName: profile.family_name || null,
60
- givenName: profile.given_name || null,
61
- id: profile.sub || null,
62
- name: profile.name || null,
63
- imageUrl: profile.picture || null,
64
- },
65
- },
66
- };
67
- }
68
- return null;
23
+ const url = new URL(window.location.href);
24
+ return this.googleProvider.handleOAuthRedirect(url);
69
25
  }
70
26
  async initialize(options) {
71
27
  var _a, _b, _c;
28
+ const initPromises = [];
72
29
  if ((_a = options.google) === null || _a === void 0 ? void 0 : _a.webClientId) {
73
- this.googleClientId = options.google.webClientId;
74
- if (options.google.mode) {
75
- this.googleLoginType = options.google.mode;
76
- }
77
- await this.loadGoogleScript();
30
+ initPromises.push(this.googleProvider.initialize(options.google.webClientId, options.google.mode, options.google.hostedDomain));
78
31
  }
79
32
  if ((_b = options.apple) === null || _b === void 0 ? void 0 : _b.clientId) {
80
- this.appleClientId = options.apple.clientId;
81
- await this.loadAppleScript();
33
+ initPromises.push(this.appleProvider.initialize(options.apple.clientId, options.apple.redirectUrl));
82
34
  }
83
35
  if ((_c = options.facebook) === null || _c === void 0 ? void 0 : _c.appId) {
84
- this.facebookAppId = options.facebook.appId;
85
- await this.loadFacebookScript();
86
- FB.init({
87
- appId: this.facebookAppId,
88
- version: 'v17.0',
89
- xfbml: true,
90
- cookie: true,
91
- });
36
+ initPromises.push(this.facebookProvider.initialize(options.facebook.appId));
92
37
  }
93
- // Implement initialization for other providers if needed
38
+ await Promise.all(initPromises);
94
39
  }
95
40
  async login(options) {
96
41
  switch (options.provider) {
97
42
  case 'google':
98
- return this.loginWithGoogle(options.options);
43
+ return this.googleProvider.login(options.options);
99
44
  case 'apple':
100
- return this.loginWithApple(options.options);
45
+ return this.appleProvider.login(options.options);
101
46
  case 'facebook':
102
- return this.loginWithFacebook(options.options);
47
+ return this.facebookProvider.login(options.options);
103
48
  default:
104
49
  throw new Error(`Login for ${options.provider} is not implemented on web`);
105
50
  }
@@ -107,154 +52,23 @@ export class SocialLoginWeb extends WebPlugin {
107
52
  async logout(options) {
108
53
  switch (options.provider) {
109
54
  case 'google':
110
- if (this.googleLoginType === 'offline') {
111
- return Promise.reject("Offline login doesn't store tokens. logout is not available");
112
- }
113
- // Google doesn't have a specific logout method for web
114
- // We can revoke the token if we have it stored
115
- console.log('Google logout: Id token should be revoked on the client side if stored');
116
- // eslint-disable-next-line
117
- const state = this.getGoogleState();
118
- if (!state)
119
- return;
120
- await this.rawLogoutGoogle(state.accessToken);
121
- break;
55
+ return this.googleProvider.logout();
122
56
  case 'apple':
123
- // Apple doesn't provide a logout method for web
124
- console.log('Apple logout: Session should be managed on the client side');
125
- break;
57
+ return this.appleProvider.logout();
126
58
  case 'facebook':
127
- return new Promise((resolve) => {
128
- FB.logout(() => resolve());
129
- });
59
+ return this.facebookProvider.logout();
130
60
  default:
131
61
  throw new Error(`Logout for ${options.provider} is not implemented`);
132
62
  }
133
63
  }
134
- async accessTokenIsValid(accessToken) {
135
- const url = `${this.GOOGLE_TOKEN_REQUEST_URL}?access_token=${encodeURIComponent(accessToken)}`;
136
- try {
137
- // Make the GET request using fetch
138
- const response = await fetch(url);
139
- // Check if the response is successful
140
- if (!response.ok) {
141
- console.log(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response not successful. Status code: ${response.status}. Assuming that the token is not valid`);
142
- return false;
143
- }
144
- // Get the response body as text
145
- const responseBody = await response.text();
146
- if (!responseBody) {
147
- console.error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is null`);
148
- throw new Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is null`);
149
- }
150
- // Parse the response body as JSON
151
- let jsonObject;
152
- try {
153
- jsonObject = JSON.parse(responseBody);
154
- }
155
- catch (e) {
156
- console.error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is not valid JSON. Error: ${e}`);
157
- throw new Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is not valid JSON. Error: ${e}`);
158
- }
159
- // Extract the 'expires_in' field
160
- const expiresInStr = jsonObject['expires_in'];
161
- if (expiresInStr === undefined || expiresInStr === null) {
162
- console.error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response JSON does not include 'expires_in'.`);
163
- throw new Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response JSON does not include 'expires_in'.`);
164
- }
165
- // Parse 'expires_in' as an integer
166
- let expiresInInt;
167
- try {
168
- expiresInInt = parseInt(expiresInStr, 10);
169
- if (isNaN(expiresInInt)) {
170
- throw new Error(`'expires_in' is not a valid integer`);
171
- }
172
- }
173
- catch (e) {
174
- console.error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. 'expires_in': ${expiresInStr} is not a valid integer. Error: ${e}`);
175
- throw new Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. 'expires_in': ${expiresInStr} is not a valid integer. Error: ${e}`);
176
- }
177
- // Determine if the access token is valid based on 'expires_in'
178
- return expiresInInt > 5;
179
- }
180
- catch (error) {
181
- console.error(error);
182
- throw error;
183
- }
184
- }
185
- idTokenValid(idToken) {
186
- try {
187
- const parsed = this.parseJwt(idToken);
188
- const currentTime = Math.ceil(Date.now() / 1000) + 5; // Convert current time to seconds since epoch
189
- return parsed.exp && currentTime < parsed.exp;
190
- }
191
- catch (e) {
192
- return false;
193
- }
194
- }
195
- async rawLogoutGoogle(accessToken, tokenValid = null) {
196
- if (tokenValid === null) {
197
- tokenValid = await this.accessTokenIsValid(accessToken);
198
- }
199
- if (tokenValid === true) {
200
- return new Promise((resolve, reject) => {
201
- try {
202
- google.accounts.oauth2.revoke(accessToken, async () => {
203
- this.clearStateGoogle();
204
- resolve();
205
- });
206
- }
207
- catch (e) {
208
- reject(e);
209
- }
210
- });
211
- }
212
- else {
213
- this.clearStateGoogle();
214
- return;
215
- }
216
- }
217
64
  async isLoggedIn(options) {
218
65
  switch (options.provider) {
219
66
  case 'google':
220
- if (this.googleLoginType === 'offline') {
221
- return Promise.reject("Offline login doesn't store tokens. isLoggedIn is not available");
222
- }
223
- // For Google, we can check if there's a valid token
224
- // eslint-disable-next-line
225
- const state = this.getGoogleState();
226
- if (!state)
227
- return { isLoggedIn: false };
228
- try {
229
- // todo: cache accessTokenIsValid calls
230
- const isValidAccessToken = await this.accessTokenIsValid(state.accessToken);
231
- const isValidIdToken = this.idTokenValid(state.idToken);
232
- if (isValidAccessToken && isValidIdToken) {
233
- return { isLoggedIn: true };
234
- }
235
- else {
236
- try {
237
- await this.rawLogoutGoogle(state.accessToken, false);
238
- }
239
- catch (e) {
240
- console.error('Access token is not valid, but cannot logout', e);
241
- }
242
- return { isLoggedIn: false };
243
- }
244
- }
245
- catch (e) {
246
- return Promise.reject(e);
247
- }
67
+ return this.googleProvider.isLoggedIn();
248
68
  case 'apple':
249
- // Apple doesn't provide a method to check login status on web
250
- console.log('Apple login status should be managed on the client side');
251
- return { isLoggedIn: false };
69
+ return this.appleProvider.isLoggedIn();
252
70
  case 'facebook':
253
- return new Promise((resolve) => {
254
- FB.getLoginStatus((response) => {
255
- resolve({ isLoggedIn: response.status === 'connected' });
256
- });
257
- });
71
+ return this.facebookProvider.isLoggedIn();
258
72
  default:
259
73
  throw new Error(`isLoggedIn for ${options.provider} is not implemented`);
260
74
  }
@@ -262,50 +76,11 @@ export class SocialLoginWeb extends WebPlugin {
262
76
  async getAuthorizationCode(options) {
263
77
  switch (options.provider) {
264
78
  case 'google':
265
- if (this.googleLoginType === 'offline') {
266
- return Promise.reject("Offline login doesn't store tokens. getAuthorizationCode is not available");
267
- }
268
- // For Google, we can use the id_token as the authorization code
269
- // eslint-disable-next-line
270
- const state = this.getGoogleState();
271
- if (!state)
272
- throw new Error('No Google authorization code available');
273
- try {
274
- // todo: cache accessTokenIsValid calls
275
- const isValidAccessToken = await this.accessTokenIsValid(state.accessToken);
276
- const isValidIdToken = this.idTokenValid(state.idToken);
277
- if (isValidAccessToken && isValidIdToken) {
278
- return { accessToken: state.accessToken, jwt: state.idToken };
279
- }
280
- else {
281
- try {
282
- await this.rawLogoutGoogle(state.accessToken, false);
283
- }
284
- catch (e) {
285
- console.error('Access token is not valid, but cannot logout', e);
286
- }
287
- throw new Error('No Google authorization code available');
288
- }
289
- }
290
- catch (e) {
291
- return Promise.reject(e);
292
- }
79
+ return this.googleProvider.getAuthorizationCode();
293
80
  case 'apple':
294
- // Apple authorization code should be obtained during login
295
- console.log('Apple authorization code should be stored during login');
296
- throw new Error('Apple authorization code not available');
81
+ return this.appleProvider.getAuthorizationCode();
297
82
  case 'facebook':
298
- return new Promise((resolve, reject) => {
299
- FB.getLoginStatus((response) => {
300
- var _a;
301
- if (response.status === 'connected') {
302
- resolve({ jwt: ((_a = response.authResponse) === null || _a === void 0 ? void 0 : _a.accessToken) || '' });
303
- }
304
- else {
305
- reject(new Error('No Facebook authorization code available'));
306
- }
307
- });
308
- });
83
+ return this.facebookProvider.getAuthorizationCode();
309
84
  default:
310
85
  throw new Error(`getAuthorizationCode for ${options.provider} is not implemented`);
311
86
  }
@@ -313,333 +88,15 @@ export class SocialLoginWeb extends WebPlugin {
313
88
  async refresh(options) {
314
89
  switch (options.provider) {
315
90
  case 'google':
316
- // For Google, we can prompt for re-authentication
317
- return Promise.reject('Not implemented');
91
+ return this.googleProvider.refresh();
318
92
  case 'apple':
319
- // Apple doesn't provide a refresh method for web
320
- console.log('Apple refresh not available on web');
321
- break;
93
+ return this.appleProvider.refresh();
322
94
  case 'facebook':
323
- await this.loginWithFacebook(options.options);
324
- break;
95
+ return this.facebookProvider.refresh(options.options);
325
96
  default:
326
97
  throw new Error(`Refresh for ${options.provider} is not implemented`);
327
98
  }
328
99
  }
329
- loginWithGoogle(options) {
330
- if (!this.googleClientId) {
331
- throw new Error('Google Client ID not set. Call initialize() first.');
332
- }
333
- let scopes = options.scopes || [];
334
- if (scopes.length > 0) {
335
- // If scopes are provided, directly use the traditional OAuth flow
336
- if (!scopes.includes('https://www.googleapis.com/auth/userinfo.email')) {
337
- scopes.push('https://www.googleapis.com/auth/userinfo.email');
338
- }
339
- if (!scopes.includes('https://www.googleapis.com/auth/userinfo.profile')) {
340
- scopes.push('https://www.googleapis.com/auth/userinfo.profile');
341
- }
342
- if (!scopes.includes('openid')) {
343
- scopes.push('openid');
344
- }
345
- }
346
- else {
347
- scopes = [
348
- 'https://www.googleapis.com/auth/userinfo.email',
349
- 'https://www.googleapis.com/auth/userinfo.profile',
350
- 'openid',
351
- ];
352
- }
353
- if (scopes.length > 3 || this.googleLoginType === 'offline' || options.disableOneTap) {
354
- // If scopes are provided, directly use the traditional OAuth flow
355
- return this.fallbackToTraditionalOAuth(scopes);
356
- }
357
- return new Promise((resolve, reject) => {
358
- google.accounts.id.initialize({
359
- client_id: this.googleClientId,
360
- callback: (response) => {
361
- console.log('google.accounts.id.initialize callback', response);
362
- if (response.error) {
363
- // we use any because type fail but we need to double check if that works
364
- reject(response.error);
365
- }
366
- else {
367
- const payload = this.parseJwt(response.credential);
368
- const result = {
369
- accessToken: null,
370
- responseType: 'online',
371
- idToken: response.credential,
372
- profile: {
373
- email: payload.email || null,
374
- familyName: payload.family_name || null,
375
- givenName: payload.given_name || null,
376
- id: payload.sub || null,
377
- name: payload.name || null,
378
- imageUrl: payload.picture || null,
379
- },
380
- };
381
- resolve({ provider: 'google', result });
382
- }
383
- },
384
- auto_select: true,
385
- });
386
- google.accounts.id.prompt((notification) => {
387
- if (notification.isNotDisplayed() || notification.isSkippedMoment()) {
388
- console.log('OneTap is not displayed or skipped');
389
- // Fallback to traditional OAuth if One Tap is not available
390
- this.fallbackToTraditionalOAuth(scopes)
391
- .then((r) => resolve({ provider: 'google', result: r.result }))
392
- .catch(reject);
393
- }
394
- else {
395
- console.log('OneTap is displayed');
396
- }
397
- });
398
- });
399
- }
400
- parseJwt(token) {
401
- const base64Url = token.split('.')[1];
402
- const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
403
- const jsonPayload = decodeURIComponent(atob(base64)
404
- .split('')
405
- .map((c) => {
406
- return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
407
- })
408
- .join(''));
409
- return JSON.parse(jsonPayload);
410
- }
411
- async loadGoogleScript() {
412
- if (this.googleScriptLoaded)
413
- return;
414
- return new Promise((resolve, reject) => {
415
- const script = document.createElement('script');
416
- script.src = 'https://accounts.google.com/gsi/client';
417
- script.async = true;
418
- script.onload = () => {
419
- this.googleScriptLoaded = true;
420
- resolve();
421
- };
422
- script.onerror = reject;
423
- document.body.appendChild(script);
424
- });
425
- }
426
- async loginWithApple(options) {
427
- if (!this.appleClientId) {
428
- throw new Error('Apple Client ID not set. Call initialize() first.');
429
- }
430
- if (!this.appleScriptLoaded) {
431
- throw new Error('Apple Sign-In script not loaded.');
432
- }
433
- return new Promise((resolve, reject) => {
434
- var _a;
435
- AppleID.auth.init({
436
- clientId: this.appleClientId,
437
- scope: ((_a = options.scopes) === null || _a === void 0 ? void 0 : _a.join(' ')) || 'name email',
438
- redirectURI: options.redirectUrl || window.location.href,
439
- state: options.state,
440
- nonce: options.nonce,
441
- usePopup: true,
442
- });
443
- AppleID.auth
444
- .signIn()
445
- .then((res) => {
446
- var _a, _b, _c, _d, _e, _f, _g;
447
- const result = {
448
- profile: {
449
- user: ((_b = (_a = res.user) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.firstName) ? `${res.user.name.firstName} ${res.user.name.lastName}` : '',
450
- email: ((_c = res.user) === null || _c === void 0 ? void 0 : _c.email) || null,
451
- givenName: ((_e = (_d = res.user) === null || _d === void 0 ? void 0 : _d.name) === null || _e === void 0 ? void 0 : _e.firstName) || null,
452
- familyName: ((_g = (_f = res.user) === null || _f === void 0 ? void 0 : _f.name) === null || _g === void 0 ? void 0 : _g.lastName) || null,
453
- },
454
- accessToken: {
455
- token: res.authorization.code, // TODO: to fix and find the correct token
456
- },
457
- idToken: res.authorization.id_token || null,
458
- };
459
- resolve({ provider: 'apple', result });
460
- })
461
- .catch((error) => {
462
- reject(error);
463
- });
464
- });
465
- }
466
- async loadAppleScript() {
467
- if (this.appleScriptLoaded)
468
- return;
469
- return new Promise((resolve, reject) => {
470
- const script = document.createElement('script');
471
- script.src = this.appleScriptUrl;
472
- script.async = true;
473
- script.onload = () => {
474
- this.appleScriptLoaded = true;
475
- resolve();
476
- };
477
- script.onerror = reject;
478
- document.body.appendChild(script);
479
- });
480
- }
481
- persistStateGoogle(accessToken, idToken) {
482
- try {
483
- window.localStorage.setItem('capgo_social_login_google_state', JSON.stringify({ accessToken, idToken }));
484
- }
485
- catch (e) {
486
- console.error('Cannot persist state google', e);
487
- }
488
- }
489
- clearStateGoogle() {
490
- try {
491
- window.localStorage.removeItem('capgo_social_login_google_state');
492
- }
493
- catch (e) {
494
- console.error('Cannot clear state google', e);
495
- }
496
- }
497
- getGoogleState() {
498
- try {
499
- const state = window.localStorage.getItem('capgo_social_login_google_state');
500
- if (!state)
501
- return null;
502
- const { accessToken, idToken } = JSON.parse(state);
503
- return { accessToken, idToken };
504
- }
505
- catch (e) {
506
- console.error('Cannot get state google', e);
507
- return null;
508
- }
509
- }
510
- async loadFacebookScript() {
511
- if (this.facebookScriptLoaded)
512
- return;
513
- return new Promise((resolve, reject) => {
514
- const script = document.createElement('script');
515
- script.src = 'https://connect.facebook.net/en_US/sdk.js';
516
- script.async = true;
517
- script.defer = true;
518
- script.onload = () => {
519
- this.facebookScriptLoaded = true;
520
- resolve();
521
- };
522
- script.onerror = reject;
523
- document.body.appendChild(script);
524
- });
525
- }
526
- async loginWithFacebook(options) {
527
- if (!this.facebookAppId) {
528
- throw new Error('Facebook App ID not set. Call initialize() first.');
529
- }
530
- return new Promise((resolve, reject) => {
531
- FB.login((response) => {
532
- if (response.status === 'connected') {
533
- FB.api('/me', { fields: 'id,name,email,picture' }, (userInfo) => {
534
- var _a, _b;
535
- const result = {
536
- accessToken: {
537
- token: response.authResponse.accessToken,
538
- userId: response.authResponse.userID,
539
- },
540
- profile: {
541
- userID: userInfo.id,
542
- name: userInfo.name,
543
- email: userInfo.email || null,
544
- imageURL: ((_b = (_a = userInfo.picture) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.url) || null,
545
- friendIDs: [],
546
- birthday: null,
547
- ageRange: null,
548
- gender: null,
549
- location: null,
550
- hometown: null,
551
- profileURL: null,
552
- },
553
- idToken: null,
554
- };
555
- resolve({ provider: 'facebook', result });
556
- });
557
- }
558
- else {
559
- reject(new Error('Facebook login failed'));
560
- }
561
- }, { scope: options.permissions.join(',') });
562
- });
563
- }
564
- async fallbackToTraditionalOAuth(scopes) {
565
- const uniqueScopes = [...new Set([...scopes, 'openid'])];
566
- const params = new URLSearchParams({
567
- client_id: this.googleClientId,
568
- redirect_uri: window.location.href,
569
- response_type: this.googleLoginType === 'offline' ? 'code' : 'token id_token',
570
- scope: uniqueScopes.join(' '),
571
- nonce: Math.random().toString(36).substring(2),
572
- include_granted_scopes: 'true',
573
- state: 'popup',
574
- });
575
- const url = `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
576
- const width = 500;
577
- const height = 600;
578
- const left = window.screenX + (window.outerWidth - width) / 2;
579
- const top = window.screenY + (window.outerHeight - height) / 2;
580
- localStorage.setItem(SocialLoginWeb.OAUTH_STATE_KEY, 'true');
581
- const popup = window.open(url, 'Google Sign In', `width=${width},height=${height},left=${left},top=${top},popup=1`);
582
- // This may never return...
583
- return new Promise((resolve, reject) => {
584
- if (!popup) {
585
- reject(new Error('Failed to open popup'));
586
- return;
587
- }
588
- const handleMessage = (event) => {
589
- var _a;
590
- if (event.origin !== window.location.origin)
591
- return;
592
- if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.type) === 'oauth-response') {
593
- window.removeEventListener('message', handleMessage);
594
- if (this.googleLoginType === 'online') {
595
- const { accessToken, idToken } = event.data;
596
- if (accessToken && idToken) {
597
- const profile = this.parseJwt(idToken);
598
- this.persistStateGoogle(accessToken.token, idToken);
599
- resolve({
600
- provider: 'google',
601
- result: {
602
- accessToken: {
603
- token: accessToken.token,
604
- },
605
- idToken,
606
- profile: {
607
- email: profile.email || null,
608
- familyName: profile.family_name || null,
609
- givenName: profile.given_name || null,
610
- id: profile.sub || null,
611
- name: profile.name || null,
612
- imageUrl: profile.picture || null,
613
- },
614
- responseType: 'online',
615
- },
616
- });
617
- }
618
- }
619
- else {
620
- const { serverAuthCode } = event.data.result;
621
- resolve({
622
- provider: 'google',
623
- result: {
624
- responseType: 'offline',
625
- serverAuthCode,
626
- },
627
- });
628
- }
629
- }
630
- else {
631
- reject(new Error('Login failed'));
632
- }
633
- };
634
- window.addEventListener('message', handleMessage);
635
- // Timeout after 5 minutes
636
- setTimeout(() => {
637
- window.removeEventListener('message', handleMessage);
638
- popup.close();
639
- reject(new Error('OAuth timeout'));
640
- }, 300000);
641
- });
642
- }
643
100
  }
644
101
  SocialLoginWeb.OAUTH_STATE_KEY = 'social_login_oauth_pending';
645
102
  //# sourceMappingURL=web.js.map