@capgo/capacitor-social-login 7.2.2 → 7.4.5

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