@capgo/capacitor-social-login 8.2.6 → 8.2.8
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/android/build.gradle +1 -0
- package/android/src/main/java/ee/forgr/capacitor/social/login/SocialLoginPlugin.java +1 -1
- package/dist/esm/google-provider.js +92 -45
- package/dist/esm/google-provider.js.map +1 -1
- package/dist/esm/oauth2-provider.js +64 -21
- package/dist/esm/oauth2-provider.js.map +1 -1
- package/dist/esm/twitter-provider.js +54 -19
- package/dist/esm/twitter-provider.js.map +1 -1
- package/dist/esm/web.js +42 -5
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +252 -90
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +252 -90
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/SocialLoginPlugin/SocialLoginPlugin.swift +1 -1
- package/package.json +1 -1
package/android/build.gradle
CHANGED
|
@@ -18,7 +18,7 @@ import org.json.JSONObject;
|
|
|
18
18
|
@CapacitorPlugin(name = "SocialLogin")
|
|
19
19
|
public class SocialLoginPlugin extends Plugin {
|
|
20
20
|
|
|
21
|
-
private final String pluginVersion = "8.2.
|
|
21
|
+
private final String pluginVersion = "8.2.8";
|
|
22
22
|
|
|
23
23
|
public static String LOG_TAG = "CapgoSocialLogin";
|
|
24
24
|
|
|
@@ -304,77 +304,124 @@ export class GoogleSocialLogin extends BaseSocialLogin {
|
|
|
304
304
|
const popup = window.open(url, 'Google Sign In', `width=${width},height=${height},left=${left},top=${top},popup=1`);
|
|
305
305
|
let popupClosedInterval;
|
|
306
306
|
let timeoutHandle;
|
|
307
|
+
// Use BroadcastChannel for cross-origin communication (works when postMessage doesn't)
|
|
308
|
+
const channelName = `google_oauth_${nonce || Date.now()}`;
|
|
309
|
+
let broadcastChannel = null;
|
|
310
|
+
try {
|
|
311
|
+
broadcastChannel = new BroadcastChannel(channelName);
|
|
312
|
+
}
|
|
313
|
+
catch (_b) {
|
|
314
|
+
// BroadcastChannel not supported, fall back to postMessage only
|
|
315
|
+
}
|
|
307
316
|
// This may never return...
|
|
308
317
|
return new Promise((resolve, reject) => {
|
|
309
318
|
if (!popup) {
|
|
310
319
|
reject(new Error('Failed to open popup'));
|
|
311
320
|
return;
|
|
312
321
|
}
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if (
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
provider: 'google',
|
|
328
|
-
result: {
|
|
329
|
-
accessToken: {
|
|
330
|
-
token: accessToken.token,
|
|
331
|
-
},
|
|
332
|
-
idToken,
|
|
333
|
-
profile: {
|
|
334
|
-
email: profile.email || null,
|
|
335
|
-
familyName: profile.family_name || null,
|
|
336
|
-
givenName: profile.given_name || null,
|
|
337
|
-
id: profile.sub || null,
|
|
338
|
-
name: profile.name || null,
|
|
339
|
-
imageUrl: profile.picture || null,
|
|
340
|
-
},
|
|
341
|
-
responseType: 'online',
|
|
342
|
-
},
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
else {
|
|
347
|
-
const { serverAuthCode } = event.data;
|
|
322
|
+
const cleanup = () => {
|
|
323
|
+
window.removeEventListener('message', handleMessage);
|
|
324
|
+
clearInterval(popupClosedInterval);
|
|
325
|
+
clearTimeout(timeoutHandle);
|
|
326
|
+
if (broadcastChannel) {
|
|
327
|
+
broadcastChannel.close();
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
const processOAuthResponse = (data) => {
|
|
331
|
+
if (this.loginType === 'online') {
|
|
332
|
+
const { accessToken, idToken } = data;
|
|
333
|
+
if (accessToken && idToken) {
|
|
334
|
+
const profile = this.parseJwt(idToken);
|
|
335
|
+
this.persistStateGoogle(accessToken.token, idToken);
|
|
348
336
|
resolve({
|
|
349
337
|
provider: 'google',
|
|
350
338
|
result: {
|
|
351
|
-
|
|
352
|
-
|
|
339
|
+
accessToken: {
|
|
340
|
+
token: accessToken.token,
|
|
341
|
+
},
|
|
342
|
+
idToken,
|
|
343
|
+
profile: {
|
|
344
|
+
email: profile.email || null,
|
|
345
|
+
familyName: profile.family_name || null,
|
|
346
|
+
givenName: profile.given_name || null,
|
|
347
|
+
id: profile.sub || null,
|
|
348
|
+
name: profile.name || null,
|
|
349
|
+
imageUrl: profile.picture || null,
|
|
350
|
+
},
|
|
351
|
+
responseType: 'online',
|
|
353
352
|
},
|
|
354
353
|
});
|
|
355
354
|
}
|
|
356
355
|
}
|
|
356
|
+
else {
|
|
357
|
+
const { serverAuthCode } = data;
|
|
358
|
+
resolve({
|
|
359
|
+
provider: 'google',
|
|
360
|
+
result: {
|
|
361
|
+
responseType: 'offline',
|
|
362
|
+
serverAuthCode,
|
|
363
|
+
},
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
const handleMessage = (event) => {
|
|
368
|
+
var _a, _b, _c, _d;
|
|
369
|
+
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')))
|
|
370
|
+
return;
|
|
371
|
+
if (((_c = event.data) === null || _c === void 0 ? void 0 : _c.type) === 'oauth-response') {
|
|
372
|
+
cleanup();
|
|
373
|
+
processOAuthResponse(event.data);
|
|
374
|
+
}
|
|
357
375
|
else if (((_d = event.data) === null || _d === void 0 ? void 0 : _d.type) === 'oauth-error') {
|
|
358
|
-
|
|
359
|
-
clearInterval(popupClosedInterval);
|
|
360
|
-
clearTimeout(timeoutHandle);
|
|
376
|
+
cleanup();
|
|
361
377
|
const errorMessage = event.data.error || 'User cancelled the OAuth flow';
|
|
362
378
|
reject(new Error(errorMessage));
|
|
363
379
|
}
|
|
364
380
|
// Don't reject for non-OAuth messages, just ignore them
|
|
365
381
|
};
|
|
382
|
+
// Listen for BroadcastChannel messages
|
|
383
|
+
if (broadcastChannel) {
|
|
384
|
+
broadcastChannel.onmessage = (event) => {
|
|
385
|
+
var _a;
|
|
386
|
+
const data = event.data;
|
|
387
|
+
if ((_a = data === null || data === void 0 ? void 0 : data.source) === null || _a === void 0 ? void 0 : _a.toString().startsWith('angular'))
|
|
388
|
+
return;
|
|
389
|
+
if ((data === null || data === void 0 ? void 0 : data.type) === 'oauth-response') {
|
|
390
|
+
cleanup();
|
|
391
|
+
processOAuthResponse(data);
|
|
392
|
+
}
|
|
393
|
+
else if ((data === null || data === void 0 ? void 0 : data.type) === 'oauth-error') {
|
|
394
|
+
cleanup();
|
|
395
|
+
const errorMessage = data.error || 'User cancelled the OAuth flow';
|
|
396
|
+
reject(new Error(errorMessage));
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
}
|
|
366
400
|
window.addEventListener('message', handleMessage);
|
|
367
401
|
// Timeout after 5 minutes
|
|
368
402
|
timeoutHandle = setTimeout(() => {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
403
|
+
cleanup();
|
|
404
|
+
try {
|
|
405
|
+
popup.close();
|
|
406
|
+
}
|
|
407
|
+
catch (_a) {
|
|
408
|
+
// Ignore cross-origin errors when closing
|
|
409
|
+
}
|
|
372
410
|
reject(new Error('OAuth timeout'));
|
|
373
411
|
}, 300000);
|
|
374
412
|
popupClosedInterval = setInterval(() => {
|
|
375
|
-
|
|
413
|
+
try {
|
|
414
|
+
// Check if popup is closed - this may throw cross-origin errors for some providers
|
|
415
|
+
if (popup.closed) {
|
|
416
|
+
cleanup();
|
|
417
|
+
reject(new Error('Popup closed'));
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
catch (_a) {
|
|
421
|
+
// Cross-origin error when checking popup.closed - this happens when the popup
|
|
422
|
+
// navigates to a third-party OAuth provider with strict security settings.
|
|
423
|
+
// We can't detect if the window was closed, so we rely on timeout and message handlers.
|
|
376
424
|
clearInterval(popupClosedInterval);
|
|
377
|
-
reject(new Error('Popup closed'));
|
|
378
425
|
}
|
|
379
426
|
}, 1000);
|
|
380
427
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-provider.js","sourceRoot":"","sources":["../../src/google-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseSocialLogin } from './base';\nimport type { GoogleLoginOptions, LoginResult, ProviderResponseMap, AuthorizationCode } from './definitions';\n\nexport class GoogleSocialLogin extends BaseSocialLogin {\n private clientId: string | null = null;\n private hostedDomain?: string;\n private loginType: 'online' | 'offline' = 'online';\n private redirectUrl?: string;\n private GOOGLE_TOKEN_REQUEST_URL = 'https://www.googleapis.com/oauth2/v3/tokeninfo';\n private readonly GOOGLE_STATE_KEY = 'capgo_social_login_google_state';\n\n async initialize(\n clientId: string | null,\n mode?: 'online' | 'offline',\n hostedDomain?: string | null,\n redirectUrl?: string,\n ): Promise<void> {\n this.clientId = clientId;\n if (mode) {\n this.loginType = mode;\n }\n this.hostedDomain = hostedDomain as string | undefined;\n this.redirectUrl = redirectUrl;\n }\n\n async login<T extends 'google'>(\n options: GoogleLoginOptions,\n ): Promise<{ provider: T; result: ProviderResponseMap[T] }> {\n if (!this.clientId) {\n throw new Error('Google Client ID not set. Call initialize() first.');\n }\n\n let scopes = options.scopes || [];\n\n if (scopes.length > 0) {\n // If scopes are provided, directly use the traditional OAuth flow\n if (!scopes.includes('https://www.googleapis.com/auth/userinfo.email')) {\n scopes.push('https://www.googleapis.com/auth/userinfo.email');\n }\n if (!scopes.includes('https://www.googleapis.com/auth/userinfo.profile')) {\n scopes.push('https://www.googleapis.com/auth/userinfo.profile');\n }\n if (!scopes.includes('openid')) {\n scopes.push('openid');\n }\n } else {\n scopes = [\n 'https://www.googleapis.com/auth/userinfo.email',\n 'https://www.googleapis.com/auth/userinfo.profile',\n 'openid',\n ];\n }\n\n const nonce = options.nonce || Math.random().toString(36).substring(2);\n\n // If scopes are provided, directly use the traditional OAuth flow\n return this.traditionalOAuth({\n scopes,\n nonce,\n hostedDomain: this.hostedDomain,\n prompt: options.prompt,\n });\n }\n\n async logout(): Promise<void> {\n if (this.loginType === 'offline') {\n return Promise.reject(\"Offline login doesn't store tokens. logout is not available\");\n }\n // eslint-disable-next-line\n const state = this.getGoogleState();\n if (!state) return;\n await this.rawLogoutGoogle(state.accessToken);\n }\n\n async isLoggedIn(): Promise<{ isLoggedIn: boolean }> {\n if (this.loginType === 'offline') {\n return Promise.reject(\"Offline login doesn't store tokens. isLoggedIn is not available\");\n }\n // eslint-disable-next-line\n const state = this.getGoogleState();\n if (!state) return { isLoggedIn: false };\n\n try {\n const isValidAccessToken = await this.accessTokenIsValid(state.accessToken);\n const isValidIdToken = this.idTokenValid(state.idToken);\n if (isValidAccessToken && isValidIdToken) {\n return { isLoggedIn: true };\n } else {\n try {\n await this.rawLogoutGoogle(state.accessToken, false);\n } catch (e) {\n console.error('Access token is not valid, but cannot logout', e);\n }\n return { isLoggedIn: false };\n }\n } catch (e) {\n return Promise.reject(e);\n }\n }\n\n async getAuthorizationCode(): Promise<AuthorizationCode> {\n if (this.loginType === 'offline') {\n return Promise.reject(\"Offline login doesn't store tokens. getAuthorizationCode is not available\");\n }\n // eslint-disable-next-line\n const state = this.getGoogleState();\n if (!state) throw new Error('No Google authorization code available');\n\n try {\n const isValidAccessToken = await this.accessTokenIsValid(state.accessToken);\n const isValidIdToken = this.idTokenValid(state.idToken);\n if (isValidAccessToken && isValidIdToken) {\n return { accessToken: state.accessToken, jwt: state.idToken };\n } else {\n try {\n await this.rawLogoutGoogle(state.accessToken, false);\n } catch (e) {\n console.error('Access token is not valid, but cannot logout', e);\n }\n throw new Error('No Google authorization code available');\n }\n } catch (e) {\n return Promise.reject(e);\n }\n }\n\n async refresh(): Promise<void> {\n // For Google, we can prompt for re-authentication\n return Promise.reject('Not implemented');\n }\n\n handleOAuthRedirect(url: URL): LoginResult | { error: string } | null {\n const paramsRaw = url.searchParams;\n\n // Check for errors in search params first (for offline mode)\n const errorInParams = paramsRaw.get('error');\n if (errorInParams) {\n localStorage.removeItem(BaseSocialLogin.OAUTH_STATE_KEY);\n const errorDescription = paramsRaw.get('error_description') || errorInParams;\n return { error: errorDescription };\n }\n\n const code = paramsRaw.get('code');\n\n if (code && paramsRaw.has('scope')) {\n return {\n provider: 'google',\n result: {\n serverAuthCode: code,\n responseType: 'offline',\n },\n };\n }\n\n const hash = url.hash.substring(1);\n console.log('handleOAuthRedirect', url.hash);\n\n if (!hash) return null;\n\n const params = new URLSearchParams(hash);\n\n // Check for error cases in hash (e.g., user cancelled)\n const error = params.get('error');\n if (error) {\n localStorage.removeItem(BaseSocialLogin.OAUTH_STATE_KEY);\n const errorDescription = params.get('error_description') || error;\n return { error: errorDescription };\n }\n\n console.log('handleOAuthRedirect ok');\n\n const accessToken = params.get('access_token');\n const idToken = params.get('id_token');\n\n if (accessToken && idToken) {\n localStorage.removeItem(BaseSocialLogin.OAUTH_STATE_KEY);\n const profile = this.parseJwt(idToken);\n return {\n provider: 'google',\n result: {\n accessToken: {\n token: accessToken,\n },\n idToken,\n profile: {\n email: profile.email || null,\n familyName: profile.family_name || null,\n givenName: profile.given_name || null,\n id: profile.sub || null,\n name: profile.name || null,\n imageUrl: profile.picture || null,\n },\n responseType: 'online',\n },\n };\n }\n return null;\n }\n\n private async accessTokenIsValid(accessToken: string): Promise<boolean> {\n const url = `${this.GOOGLE_TOKEN_REQUEST_URL}?access_token=${encodeURIComponent(accessToken)}`;\n\n try {\n // Make the GET request using fetch\n const response = await fetch(url);\n\n // Check if the response is successful\n if (!response.ok) {\n console.log(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response not successful. Status code: ${response.status}. Assuming that the token is not valid`,\n );\n return false;\n }\n\n // Get the response body as text\n const responseBody = await response.text();\n\n if (!responseBody) {\n console.error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is null`);\n throw new Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is null`);\n }\n\n // Parse the response body as JSON\n let jsonObject: any;\n try {\n jsonObject = JSON.parse(responseBody);\n } catch (e) {\n console.error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is not valid JSON. Error: ${e}`,\n );\n throw new Error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is not valid JSON. Error: ${e}`,\n );\n }\n\n // Extract the 'expires_in' field\n const expiresInStr = jsonObject['expires_in'];\n\n if (expiresInStr === undefined || expiresInStr === null) {\n console.error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response JSON does not include 'expires_in'.`,\n );\n throw new Error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response JSON does not include 'expires_in'.`,\n );\n }\n\n // Parse 'expires_in' as an integer\n let expiresInInt: number;\n try {\n expiresInInt = parseInt(expiresInStr, 10);\n if (isNaN(expiresInInt)) {\n throw new Error(`'expires_in' is not a valid integer`);\n }\n } catch (e) {\n console.error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. 'expires_in': ${expiresInStr} is not a valid integer. Error: ${e}`,\n );\n throw new Error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. 'expires_in': ${expiresInStr} is not a valid integer. Error: ${e}`,\n );\n }\n\n // Determine if the access token is valid based on 'expires_in'\n return expiresInInt > 5;\n } catch (error) {\n console.error(error);\n throw error;\n }\n }\n\n private idTokenValid(idToken: string): boolean {\n try {\n const parsed = this.parseJwt(idToken);\n const currentTime = Math.ceil(Date.now() / 1000) + 5; // Convert current time to seconds since epoch\n return parsed.exp && currentTime < parsed.exp;\n } catch (e) {\n return false;\n }\n }\n\n private async rawLogoutGoogle(accessToken: string, tokenValid: boolean | null = null) {\n if (tokenValid === null) {\n tokenValid = await this.accessTokenIsValid(accessToken);\n }\n\n if (tokenValid === true) {\n try {\n await fetch(`https://accounts.google.com/o/oauth2/revoke?token=${encodeURIComponent(accessToken)}`);\n this.clearStateGoogle();\n } catch (e) {\n // ignore\n }\n return;\n } else {\n this.clearStateGoogle();\n return;\n }\n }\n\n private persistStateGoogle(accessToken: string, idToken: string) {\n try {\n window.localStorage.setItem(this.GOOGLE_STATE_KEY, JSON.stringify({ accessToken, idToken }));\n } catch (e) {\n console.error('Cannot persist state google', e);\n }\n }\n\n private clearStateGoogle() {\n try {\n window.localStorage.removeItem(this.GOOGLE_STATE_KEY);\n } catch (e) {\n console.error('Cannot clear state google', e);\n }\n }\n\n private getGoogleState(): { accessToken: string; idToken: string } | null {\n try {\n const state = window.localStorage.getItem(this.GOOGLE_STATE_KEY);\n if (!state) return null;\n const { accessToken, idToken } = JSON.parse(state);\n return { accessToken, idToken };\n } catch (e) {\n console.error('Cannot get state google', e);\n return null;\n }\n }\n\n private async traditionalOAuth<T extends 'google'>({\n scopes,\n hostedDomain,\n nonce,\n prompt,\n }: GoogleLoginOptions & { hostedDomain?: string }): Promise<{ provider: T; result: ProviderResponseMap[T] }> {\n const uniqueScopes = [...new Set([...(scopes || []), 'openid'])];\n\n const params = new URLSearchParams({\n client_id: this.clientId ?? '',\n redirect_uri: this.redirectUrl || window.location.origin + window.location.pathname,\n response_type: this.loginType === 'offline' ? 'code' : 'token id_token',\n scope: uniqueScopes.join(' '),\n ...(nonce && { nonce }),\n include_granted_scopes: 'true',\n state: 'popup',\n });\n if (hostedDomain !== undefined) {\n params.append('hd', hostedDomain);\n }\n if (prompt !== undefined) {\n params.append('prompt', prompt);\n }\n\n const url = `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;\n const width = 500;\n const height = 600;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n localStorage.setItem(\n BaseSocialLogin.OAUTH_STATE_KEY,\n JSON.stringify({ provider: 'google', loginType: this.loginType }),\n );\n const popup = window.open(url, 'Google Sign In', `width=${width},height=${height},left=${left},top=${top},popup=1`);\n\n let popupClosedInterval: number;\n let timeoutHandle: number;\n\n // This may never return...\n return new Promise((resolve, reject) => {\n if (!popup) {\n reject(new Error('Failed to open popup'));\n return;\n }\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== window.location.origin || event.data?.source?.startsWith('angular')) return;\n\n if (event.data?.type === 'oauth-response') {\n window.removeEventListener('message', handleMessage);\n clearInterval(popupClosedInterval);\n clearTimeout(timeoutHandle);\n\n if (this.loginType === 'online') {\n const { accessToken, idToken } = event.data;\n if (accessToken && idToken) {\n const profile = this.parseJwt(idToken);\n this.persistStateGoogle(accessToken.token, idToken);\n resolve({\n provider: 'google' as T,\n result: {\n accessToken: {\n token: accessToken.token,\n },\n idToken,\n profile: {\n email: profile.email || null,\n familyName: profile.family_name || null,\n givenName: profile.given_name || null,\n id: profile.sub || null,\n name: profile.name || null,\n imageUrl: profile.picture || null,\n },\n responseType: 'online',\n },\n });\n }\n } else {\n const { serverAuthCode } = event.data as {\n serverAuthCode: string;\n };\n resolve({\n provider: 'google' as T,\n result: {\n responseType: 'offline',\n serverAuthCode,\n },\n });\n }\n } else if (event.data?.type === 'oauth-error') {\n window.removeEventListener('message', handleMessage);\n clearInterval(popupClosedInterval);\n clearTimeout(timeoutHandle);\n const errorMessage = event.data.error || 'User cancelled the OAuth flow';\n reject(new Error(errorMessage));\n }\n // Don't reject for non-OAuth messages, just ignore them\n };\n\n window.addEventListener('message', handleMessage);\n\n // Timeout after 5 minutes\n timeoutHandle = setTimeout(() => {\n clearTimeout(timeoutHandle);\n window.removeEventListener('message', handleMessage);\n popup.close();\n reject(new Error('OAuth timeout'));\n }, 300000);\n\n popupClosedInterval = setInterval(() => {\n if (popup.closed) {\n clearInterval(popupClosedInterval);\n reject(new Error('Popup closed'));\n }\n }, 1000);\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"google-provider.js","sourceRoot":"","sources":["../../src/google-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseSocialLogin } from './base';\nimport type { GoogleLoginOptions, LoginResult, ProviderResponseMap, AuthorizationCode } from './definitions';\n\nexport class GoogleSocialLogin extends BaseSocialLogin {\n private clientId: string | null = null;\n private hostedDomain?: string;\n private loginType: 'online' | 'offline' = 'online';\n private redirectUrl?: string;\n private GOOGLE_TOKEN_REQUEST_URL = 'https://www.googleapis.com/oauth2/v3/tokeninfo';\n private readonly GOOGLE_STATE_KEY = 'capgo_social_login_google_state';\n\n async initialize(\n clientId: string | null,\n mode?: 'online' | 'offline',\n hostedDomain?: string | null,\n redirectUrl?: string,\n ): Promise<void> {\n this.clientId = clientId;\n if (mode) {\n this.loginType = mode;\n }\n this.hostedDomain = hostedDomain as string | undefined;\n this.redirectUrl = redirectUrl;\n }\n\n async login<T extends 'google'>(\n options: GoogleLoginOptions,\n ): Promise<{ provider: T; result: ProviderResponseMap[T] }> {\n if (!this.clientId) {\n throw new Error('Google Client ID not set. Call initialize() first.');\n }\n\n let scopes = options.scopes || [];\n\n if (scopes.length > 0) {\n // If scopes are provided, directly use the traditional OAuth flow\n if (!scopes.includes('https://www.googleapis.com/auth/userinfo.email')) {\n scopes.push('https://www.googleapis.com/auth/userinfo.email');\n }\n if (!scopes.includes('https://www.googleapis.com/auth/userinfo.profile')) {\n scopes.push('https://www.googleapis.com/auth/userinfo.profile');\n }\n if (!scopes.includes('openid')) {\n scopes.push('openid');\n }\n } else {\n scopes = [\n 'https://www.googleapis.com/auth/userinfo.email',\n 'https://www.googleapis.com/auth/userinfo.profile',\n 'openid',\n ];\n }\n\n const nonce = options.nonce || Math.random().toString(36).substring(2);\n\n // If scopes are provided, directly use the traditional OAuth flow\n return this.traditionalOAuth({\n scopes,\n nonce,\n hostedDomain: this.hostedDomain,\n prompt: options.prompt,\n });\n }\n\n async logout(): Promise<void> {\n if (this.loginType === 'offline') {\n return Promise.reject(\"Offline login doesn't store tokens. logout is not available\");\n }\n // eslint-disable-next-line\n const state = this.getGoogleState();\n if (!state) return;\n await this.rawLogoutGoogle(state.accessToken);\n }\n\n async isLoggedIn(): Promise<{ isLoggedIn: boolean }> {\n if (this.loginType === 'offline') {\n return Promise.reject(\"Offline login doesn't store tokens. isLoggedIn is not available\");\n }\n // eslint-disable-next-line\n const state = this.getGoogleState();\n if (!state) return { isLoggedIn: false };\n\n try {\n const isValidAccessToken = await this.accessTokenIsValid(state.accessToken);\n const isValidIdToken = this.idTokenValid(state.idToken);\n if (isValidAccessToken && isValidIdToken) {\n return { isLoggedIn: true };\n } else {\n try {\n await this.rawLogoutGoogle(state.accessToken, false);\n } catch (e) {\n console.error('Access token is not valid, but cannot logout', e);\n }\n return { isLoggedIn: false };\n }\n } catch (e) {\n return Promise.reject(e);\n }\n }\n\n async getAuthorizationCode(): Promise<AuthorizationCode> {\n if (this.loginType === 'offline') {\n return Promise.reject(\"Offline login doesn't store tokens. getAuthorizationCode is not available\");\n }\n // eslint-disable-next-line\n const state = this.getGoogleState();\n if (!state) throw new Error('No Google authorization code available');\n\n try {\n const isValidAccessToken = await this.accessTokenIsValid(state.accessToken);\n const isValidIdToken = this.idTokenValid(state.idToken);\n if (isValidAccessToken && isValidIdToken) {\n return { accessToken: state.accessToken, jwt: state.idToken };\n } else {\n try {\n await this.rawLogoutGoogle(state.accessToken, false);\n } catch (e) {\n console.error('Access token is not valid, but cannot logout', e);\n }\n throw new Error('No Google authorization code available');\n }\n } catch (e) {\n return Promise.reject(e);\n }\n }\n\n async refresh(): Promise<void> {\n // For Google, we can prompt for re-authentication\n return Promise.reject('Not implemented');\n }\n\n handleOAuthRedirect(url: URL): LoginResult | { error: string } | null {\n const paramsRaw = url.searchParams;\n\n // Check for errors in search params first (for offline mode)\n const errorInParams = paramsRaw.get('error');\n if (errorInParams) {\n localStorage.removeItem(BaseSocialLogin.OAUTH_STATE_KEY);\n const errorDescription = paramsRaw.get('error_description') || errorInParams;\n return { error: errorDescription };\n }\n\n const code = paramsRaw.get('code');\n\n if (code && paramsRaw.has('scope')) {\n return {\n provider: 'google',\n result: {\n serverAuthCode: code,\n responseType: 'offline',\n },\n };\n }\n\n const hash = url.hash.substring(1);\n console.log('handleOAuthRedirect', url.hash);\n\n if (!hash) return null;\n\n const params = new URLSearchParams(hash);\n\n // Check for error cases in hash (e.g., user cancelled)\n const error = params.get('error');\n if (error) {\n localStorage.removeItem(BaseSocialLogin.OAUTH_STATE_KEY);\n const errorDescription = params.get('error_description') || error;\n return { error: errorDescription };\n }\n\n console.log('handleOAuthRedirect ok');\n\n const accessToken = params.get('access_token');\n const idToken = params.get('id_token');\n\n if (accessToken && idToken) {\n localStorage.removeItem(BaseSocialLogin.OAUTH_STATE_KEY);\n const profile = this.parseJwt(idToken);\n return {\n provider: 'google',\n result: {\n accessToken: {\n token: accessToken,\n },\n idToken,\n profile: {\n email: profile.email || null,\n familyName: profile.family_name || null,\n givenName: profile.given_name || null,\n id: profile.sub || null,\n name: profile.name || null,\n imageUrl: profile.picture || null,\n },\n responseType: 'online',\n },\n };\n }\n return null;\n }\n\n private async accessTokenIsValid(accessToken: string): Promise<boolean> {\n const url = `${this.GOOGLE_TOKEN_REQUEST_URL}?access_token=${encodeURIComponent(accessToken)}`;\n\n try {\n // Make the GET request using fetch\n const response = await fetch(url);\n\n // Check if the response is successful\n if (!response.ok) {\n console.log(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response not successful. Status code: ${response.status}. Assuming that the token is not valid`,\n );\n return false;\n }\n\n // Get the response body as text\n const responseBody = await response.text();\n\n if (!responseBody) {\n console.error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is null`);\n throw new Error(`Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is null`);\n }\n\n // Parse the response body as JSON\n let jsonObject: any;\n try {\n jsonObject = JSON.parse(responseBody);\n } catch (e) {\n console.error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is not valid JSON. Error: ${e}`,\n );\n throw new Error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response body is not valid JSON. Error: ${e}`,\n );\n }\n\n // Extract the 'expires_in' field\n const expiresInStr = jsonObject['expires_in'];\n\n if (expiresInStr === undefined || expiresInStr === null) {\n console.error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response JSON does not include 'expires_in'.`,\n );\n throw new Error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. Response JSON does not include 'expires_in'.`,\n );\n }\n\n // Parse 'expires_in' as an integer\n let expiresInInt: number;\n try {\n expiresInInt = parseInt(expiresInStr, 10);\n if (isNaN(expiresInInt)) {\n throw new Error(`'expires_in' is not a valid integer`);\n }\n } catch (e) {\n console.error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. 'expires_in': ${expiresInStr} is not a valid integer. Error: ${e}`,\n );\n throw new Error(\n `Invalid response from ${this.GOOGLE_TOKEN_REQUEST_URL}. 'expires_in': ${expiresInStr} is not a valid integer. Error: ${e}`,\n );\n }\n\n // Determine if the access token is valid based on 'expires_in'\n return expiresInInt > 5;\n } catch (error) {\n console.error(error);\n throw error;\n }\n }\n\n private idTokenValid(idToken: string): boolean {\n try {\n const parsed = this.parseJwt(idToken);\n const currentTime = Math.ceil(Date.now() / 1000) + 5; // Convert current time to seconds since epoch\n return parsed.exp && currentTime < parsed.exp;\n } catch (e) {\n return false;\n }\n }\n\n private async rawLogoutGoogle(accessToken: string, tokenValid: boolean | null = null) {\n if (tokenValid === null) {\n tokenValid = await this.accessTokenIsValid(accessToken);\n }\n\n if (tokenValid === true) {\n try {\n await fetch(`https://accounts.google.com/o/oauth2/revoke?token=${encodeURIComponent(accessToken)}`);\n this.clearStateGoogle();\n } catch (e) {\n // ignore\n }\n return;\n } else {\n this.clearStateGoogle();\n return;\n }\n }\n\n private persistStateGoogle(accessToken: string, idToken: string) {\n try {\n window.localStorage.setItem(this.GOOGLE_STATE_KEY, JSON.stringify({ accessToken, idToken }));\n } catch (e) {\n console.error('Cannot persist state google', e);\n }\n }\n\n private clearStateGoogle() {\n try {\n window.localStorage.removeItem(this.GOOGLE_STATE_KEY);\n } catch (e) {\n console.error('Cannot clear state google', e);\n }\n }\n\n private getGoogleState(): { accessToken: string; idToken: string } | null {\n try {\n const state = window.localStorage.getItem(this.GOOGLE_STATE_KEY);\n if (!state) return null;\n const { accessToken, idToken } = JSON.parse(state);\n return { accessToken, idToken };\n } catch (e) {\n console.error('Cannot get state google', e);\n return null;\n }\n }\n\n private async traditionalOAuth<T extends 'google'>({\n scopes,\n hostedDomain,\n nonce,\n prompt,\n }: GoogleLoginOptions & { hostedDomain?: string }): Promise<{ provider: T; result: ProviderResponseMap[T] }> {\n const uniqueScopes = [...new Set([...(scopes || []), 'openid'])];\n\n const params = new URLSearchParams({\n client_id: this.clientId ?? '',\n redirect_uri: this.redirectUrl || window.location.origin + window.location.pathname,\n response_type: this.loginType === 'offline' ? 'code' : 'token id_token',\n scope: uniqueScopes.join(' '),\n ...(nonce && { nonce }),\n include_granted_scopes: 'true',\n state: 'popup',\n });\n if (hostedDomain !== undefined) {\n params.append('hd', hostedDomain);\n }\n if (prompt !== undefined) {\n params.append('prompt', prompt);\n }\n\n const url = `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;\n const width = 500;\n const height = 600;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n localStorage.setItem(\n BaseSocialLogin.OAUTH_STATE_KEY,\n JSON.stringify({ provider: 'google', loginType: this.loginType }),\n );\n const popup = window.open(url, 'Google Sign In', `width=${width},height=${height},left=${left},top=${top},popup=1`);\n\n let popupClosedInterval: number;\n let timeoutHandle: number;\n\n // Use BroadcastChannel for cross-origin communication (works when postMessage doesn't)\n const channelName = `google_oauth_${nonce || Date.now()}`;\n let broadcastChannel: BroadcastChannel | null = null;\n\n try {\n broadcastChannel = new BroadcastChannel(channelName);\n } catch {\n // BroadcastChannel not supported, fall back to postMessage only\n }\n\n // This may never return...\n return new Promise((resolve, reject) => {\n if (!popup) {\n reject(new Error('Failed to open popup'));\n return;\n }\n\n const cleanup = () => {\n window.removeEventListener('message', handleMessage);\n clearInterval(popupClosedInterval);\n clearTimeout(timeoutHandle);\n if (broadcastChannel) {\n broadcastChannel.close();\n }\n };\n\n const processOAuthResponse = (data: Record<string, unknown>) => {\n if (this.loginType === 'online') {\n const { accessToken, idToken } = data as { accessToken?: { token: string }; idToken?: string };\n if (accessToken && idToken) {\n const profile = this.parseJwt(idToken);\n this.persistStateGoogle(accessToken.token, idToken);\n resolve({\n provider: 'google' as T,\n result: {\n accessToken: {\n token: accessToken.token,\n },\n idToken,\n profile: {\n email: profile.email || null,\n familyName: profile.family_name || null,\n givenName: profile.given_name || null,\n id: profile.sub || null,\n name: profile.name || null,\n imageUrl: profile.picture || null,\n },\n responseType: 'online',\n },\n });\n }\n } else {\n const { serverAuthCode } = data as { serverAuthCode: string };\n resolve({\n provider: 'google' as T,\n result: {\n responseType: 'offline',\n serverAuthCode,\n },\n });\n }\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== window.location.origin || event.data?.source?.startsWith('angular')) return;\n\n if (event.data?.type === 'oauth-response') {\n cleanup();\n processOAuthResponse(event.data);\n } else if (event.data?.type === 'oauth-error') {\n cleanup();\n const errorMessage = event.data.error || 'User cancelled the OAuth flow';\n reject(new Error(errorMessage));\n }\n // Don't reject for non-OAuth messages, just ignore them\n };\n\n // Listen for BroadcastChannel messages\n if (broadcastChannel) {\n broadcastChannel.onmessage = (event: MessageEvent) => {\n const data = event.data;\n if (data?.source?.toString().startsWith('angular')) return;\n\n if (data?.type === 'oauth-response') {\n cleanup();\n processOAuthResponse(data);\n } else if (data?.type === 'oauth-error') {\n cleanup();\n const errorMessage = (data.error as string) || 'User cancelled the OAuth flow';\n reject(new Error(errorMessage));\n }\n };\n }\n\n window.addEventListener('message', handleMessage);\n\n // Timeout after 5 minutes\n timeoutHandle = setTimeout(() => {\n cleanup();\n try {\n popup.close();\n } catch {\n // Ignore cross-origin errors when closing\n }\n reject(new Error('OAuth timeout'));\n }, 300000);\n\n popupClosedInterval = setInterval(() => {\n try {\n // Check if popup is closed - this may throw cross-origin errors for some providers\n if (popup.closed) {\n cleanup();\n reject(new Error('Popup closed'));\n }\n } catch {\n // Cross-origin error when checking popup.closed - this happens when the popup\n // navigates to a third-party OAuth provider with strict security settings.\n // We can't detect if the window was closed, so we rely on timeout and message handlers.\n clearInterval(popupClosedInterval);\n }\n }, 1000);\n });\n }\n}\n"]}
|
|
@@ -112,52 +112,95 @@ export class OAuth2SocialLogin extends BaseSocialLogin {
|
|
|
112
112
|
reject(new Error('Unable to open login window. Please allow popups.'));
|
|
113
113
|
return;
|
|
114
114
|
}
|
|
115
|
+
// Use BroadcastChannel for cross-origin communication (works when postMessage doesn't)
|
|
116
|
+
const channelName = `oauth2_${state}`;
|
|
117
|
+
let broadcastChannel = null;
|
|
118
|
+
try {
|
|
119
|
+
broadcastChannel = new BroadcastChannel(channelName);
|
|
120
|
+
}
|
|
121
|
+
catch (_a) {
|
|
122
|
+
// BroadcastChannel not supported, fall back to postMessage only
|
|
123
|
+
if (config.logsEnabled) {
|
|
124
|
+
console.log(`[OAuth2:${providerId}] BroadcastChannel not supported, using postMessage only`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
115
127
|
const cleanup = (messageHandler, timeoutHandle, intervalHandle) => {
|
|
116
128
|
window.removeEventListener('message', messageHandler);
|
|
117
129
|
clearTimeout(timeoutHandle);
|
|
118
130
|
clearInterval(intervalHandle);
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
var _a, _b, _c, _d, _e;
|
|
122
|
-
if (event.origin !== window.location.origin) {
|
|
123
|
-
return;
|
|
131
|
+
if (broadcastChannel) {
|
|
132
|
+
broadcastChannel.close();
|
|
124
133
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
134
|
+
};
|
|
135
|
+
const handleOAuthMessage = (data) => {
|
|
136
|
+
if ((data === null || data === void 0 ? void 0 : data.type) === 'oauth-response') {
|
|
137
|
+
if ((data === null || data === void 0 ? void 0 : data.provider) && data.provider !== 'oauth2') {
|
|
138
|
+
return false;
|
|
128
139
|
}
|
|
129
140
|
// Check providerId matches if present
|
|
130
|
-
if ((
|
|
131
|
-
return;
|
|
141
|
+
if ((data === null || data === void 0 ? void 0 : data.providerId) && data.providerId !== providerId) {
|
|
142
|
+
return false;
|
|
132
143
|
}
|
|
133
144
|
cleanup(messageHandler, timeoutHandle, popupClosedInterval);
|
|
134
145
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
135
|
-
const
|
|
146
|
+
const _a = data, { provider: _ignoredProvider, type: _ignoredType } = _a, payload = __rest(_a, ["provider", "type"]);
|
|
136
147
|
resolve({
|
|
137
148
|
provider: 'oauth2',
|
|
138
149
|
result: payload,
|
|
139
150
|
});
|
|
151
|
+
return true;
|
|
140
152
|
}
|
|
141
|
-
else if ((
|
|
142
|
-
if ((
|
|
143
|
-
return;
|
|
153
|
+
else if ((data === null || data === void 0 ? void 0 : data.type) === 'oauth-error') {
|
|
154
|
+
if ((data === null || data === void 0 ? void 0 : data.provider) && data.provider !== 'oauth2') {
|
|
155
|
+
return false;
|
|
144
156
|
}
|
|
145
157
|
cleanup(messageHandler, timeoutHandle, popupClosedInterval);
|
|
146
|
-
reject(new Error(
|
|
158
|
+
reject(new Error(data.error || 'OAuth2 login was cancelled.'));
|
|
159
|
+
return true;
|
|
147
160
|
}
|
|
161
|
+
return false;
|
|
162
|
+
};
|
|
163
|
+
// Listen for BroadcastChannel messages
|
|
164
|
+
if (broadcastChannel) {
|
|
165
|
+
broadcastChannel.onmessage = (event) => {
|
|
166
|
+
handleOAuthMessage(event.data);
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
const messageHandler = (event) => {
|
|
170
|
+
if (event.origin !== window.location.origin) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
handleOAuthMessage(event.data);
|
|
148
174
|
};
|
|
149
175
|
window.addEventListener('message', messageHandler);
|
|
150
176
|
const timeoutHandle = window.setTimeout(() => {
|
|
151
|
-
|
|
152
|
-
|
|
177
|
+
cleanup(messageHandler, timeoutHandle, popupClosedInterval);
|
|
178
|
+
try {
|
|
179
|
+
popup.close();
|
|
180
|
+
}
|
|
181
|
+
catch (_a) {
|
|
182
|
+
// Ignore cross-origin errors when closing
|
|
183
|
+
}
|
|
153
184
|
reject(new Error('OAuth2 login timed out.'));
|
|
154
185
|
}, 300000);
|
|
155
186
|
const popupClosedInterval = window.setInterval(() => {
|
|
156
|
-
|
|
157
|
-
|
|
187
|
+
try {
|
|
188
|
+
// Check if popup is closed - this may throw cross-origin errors for some providers
|
|
189
|
+
if (popup.closed) {
|
|
190
|
+
cleanup(messageHandler, timeoutHandle, popupClosedInterval);
|
|
191
|
+
reject(new Error('OAuth2 login window was closed.'));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
catch (_a) {
|
|
195
|
+
// Cross-origin error when checking popup.closed - this happens when the popup
|
|
196
|
+
// navigates to a third-party OAuth provider with strict security settings.
|
|
197
|
+
// We can't detect if the window was closed, so we just rely on the timeout
|
|
198
|
+
// and message handlers. Clear the interval to avoid repeated errors.
|
|
158
199
|
clearInterval(popupClosedInterval);
|
|
159
|
-
|
|
160
|
-
|
|
200
|
+
if (config.logsEnabled) {
|
|
201
|
+
console.log(`[OAuth2:${providerId}] Cannot check popup.closed due to cross-origin restrictions. ` +
|
|
202
|
+
'Relying on message handlers and timeout.');
|
|
203
|
+
}
|
|
161
204
|
}
|
|
162
205
|
}, 1000);
|
|
163
206
|
});
|