@capgo/capacitor-social-login 8.2.25 → 8.3.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/plugin.js CHANGED
@@ -903,26 +903,106 @@ var capacitorCapacitorUpdater = (function (exports, core) {
903
903
  this.TOKENS_KEY_PREFIX = 'capgo_social_login_oauth2_tokens_';
904
904
  this.STATE_PREFIX = 'capgo_social_login_oauth2_state_';
905
905
  }
906
+ normalizeScopeValue(scope) {
907
+ if (!scope)
908
+ return '';
909
+ if (typeof scope === 'string')
910
+ return scope;
911
+ if (Array.isArray(scope))
912
+ return scope.filter(Boolean).join(' ');
913
+ return '';
914
+ }
915
+ normalizeConfig(providerId, config) {
916
+ var _a, _b, _c, _d, _e, _f, _g, _h;
917
+ const appId = (_a = config.appId) !== null && _a !== void 0 ? _a : config.clientId;
918
+ const authorizationBaseUrl = (_b = config.authorizationBaseUrl) !== null && _b !== void 0 ? _b : config.authorizationEndpoint;
919
+ const accessTokenEndpoint = (_c = config.accessTokenEndpoint) !== null && _c !== void 0 ? _c : config.tokenEndpoint;
920
+ const logoutUrl = (_d = config.logoutUrl) !== null && _d !== void 0 ? _d : config.endSessionEndpoint;
921
+ const scopeSource = (_e = config.scope) !== null && _e !== void 0 ? _e : config.scopes;
922
+ if (!appId) {
923
+ throw new Error(`OAuth2 provider '${providerId}' requires appId (or clientId).`);
924
+ }
925
+ if (!config.redirectUrl) {
926
+ throw new Error(`OAuth2 provider '${providerId}' requires redirectUrl.`);
927
+ }
928
+ if (!authorizationBaseUrl && !config.issuerUrl) {
929
+ throw new Error(`OAuth2 provider '${providerId}' requires authorizationBaseUrl (or authorizationEndpoint) or issuerUrl.`);
930
+ }
931
+ return {
932
+ appId,
933
+ issuerUrl: config.issuerUrl,
934
+ authorizationBaseUrl,
935
+ accessTokenEndpoint,
936
+ redirectUrl: config.redirectUrl,
937
+ resourceUrl: config.resourceUrl,
938
+ responseType: ((_f = config.responseType) !== null && _f !== void 0 ? _f : 'code'),
939
+ pkceEnabled: (_g = config.pkceEnabled) !== null && _g !== void 0 ? _g : true,
940
+ scope: this.normalizeScopeValue(scopeSource),
941
+ additionalParameters: config.additionalParameters,
942
+ loginHint: config.loginHint,
943
+ prompt: config.prompt,
944
+ additionalTokenParameters: config.additionalTokenParameters,
945
+ additionalResourceHeaders: config.additionalResourceHeaders,
946
+ logoutUrl,
947
+ postLogoutRedirectUrl: config.postLogoutRedirectUrl,
948
+ additionalLogoutParameters: config.additionalLogoutParameters,
949
+ logsEnabled: (_h = config.logsEnabled) !== null && _h !== void 0 ? _h : false,
950
+ };
951
+ }
952
+ async ensureDiscovered(providerId) {
953
+ const config = this.providers.get(providerId);
954
+ if (!(config === null || config === void 0 ? void 0 : config.issuerUrl))
955
+ return;
956
+ // Resolve endpoints lazily.
957
+ if (config.authorizationBaseUrl && config.accessTokenEndpoint)
958
+ return;
959
+ const issuer = config.issuerUrl.replace(/\/+$/, '');
960
+ const discoveryUrl = `${issuer}/.well-known/openid-configuration`;
961
+ const resp = await fetch(discoveryUrl);
962
+ if (!resp.ok) {
963
+ const text = await resp.text().catch(() => '');
964
+ throw new Error(`OAuth2 discovery failed (${resp.status}): ${text || discoveryUrl}`);
965
+ }
966
+ const payload = (await resp.json());
967
+ const authorizationEndpoint = payload['authorization_endpoint'];
968
+ const tokenEndpoint = payload['token_endpoint'];
969
+ const endSessionEndpoint = payload['end_session_endpoint'];
970
+ if (!config.authorizationBaseUrl && typeof authorizationEndpoint === 'string') {
971
+ config.authorizationBaseUrl = authorizationEndpoint;
972
+ }
973
+ if (!config.accessTokenEndpoint && typeof tokenEndpoint === 'string') {
974
+ config.accessTokenEndpoint = tokenEndpoint;
975
+ }
976
+ if (!config.logoutUrl && typeof endSessionEndpoint === 'string') {
977
+ config.logoutUrl = endSessionEndpoint;
978
+ }
979
+ if (config.logsEnabled) {
980
+ console.log(`[OAuth2:${providerId}] Discovery resolved`, {
981
+ authorizationBaseUrl: config.authorizationBaseUrl,
982
+ accessTokenEndpoint: config.accessTokenEndpoint,
983
+ logoutUrl: config.logoutUrl,
984
+ });
985
+ }
986
+ }
906
987
  /**
907
988
  * Initialize multiple OAuth2 providers
908
989
  */
909
990
  async initializeProviders(configs) {
910
- var _a, _b, _c, _d;
911
991
  for (const [providerId, config] of Object.entries(configs)) {
912
- if (!config.appId || !config.authorizationBaseUrl || !config.redirectUrl) {
913
- throw new Error(`OAuth2 provider '${providerId}' requires appId, authorizationBaseUrl, and redirectUrl`);
914
- }
915
- const internalConfig = Object.assign(Object.assign({}, config), { responseType: (_a = config.responseType) !== null && _a !== void 0 ? _a : 'code', pkceEnabled: (_b = config.pkceEnabled) !== null && _b !== void 0 ? _b : true, scope: (_c = config.scope) !== null && _c !== void 0 ? _c : '', logsEnabled: (_d = config.logsEnabled) !== null && _d !== void 0 ? _d : false });
992
+ const internalConfig = this.normalizeConfig(providerId, config);
916
993
  this.providers.set(providerId, internalConfig);
917
994
  if (internalConfig.logsEnabled) {
918
995
  console.log(`[OAuth2:${providerId}] Initialized with config:`, {
919
- appId: config.appId,
920
- authorizationBaseUrl: config.authorizationBaseUrl,
921
- redirectUrl: config.redirectUrl,
996
+ appId: internalConfig.appId,
997
+ issuerUrl: internalConfig.issuerUrl,
998
+ authorizationBaseUrl: internalConfig.authorizationBaseUrl,
999
+ redirectUrl: internalConfig.redirectUrl,
922
1000
  responseType: internalConfig.responseType,
923
1001
  pkceEnabled: internalConfig.pkceEnabled,
924
1002
  });
925
1003
  }
1004
+ // Pre-resolve discovery on web if issuerUrl is provided.
1005
+ await this.ensureDiscovered(providerId);
926
1006
  }
927
1007
  }
928
1008
  getProvider(providerId) {
@@ -936,13 +1016,14 @@ var capacitorCapacitorUpdater = (function (exports, core) {
936
1016
  return `${this.TOKENS_KEY_PREFIX}${providerId}`;
937
1017
  }
938
1018
  async login(options) {
939
- var _a, _b, _c, _d;
1019
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
940
1020
  const { providerId } = options;
941
1021
  const config = this.getProvider(providerId);
1022
+ await this.ensureDiscovered(providerId);
942
1023
  const redirectUri = (_a = options.redirectUrl) !== null && _a !== void 0 ? _a : config.redirectUrl;
943
- const scope = (_b = options.scope) !== null && _b !== void 0 ? _b : config.scope;
944
- const state = (_c = options.state) !== null && _c !== void 0 ? _c : this.generateState();
945
- const codeVerifier = (_d = options.codeVerifier) !== null && _d !== void 0 ? _d : this.generateCodeVerifier();
1024
+ const scope = this.normalizeScopeValue((_c = (_b = options.scope) !== null && _b !== void 0 ? _b : options.scopes) !== null && _c !== void 0 ? _c : config.scope);
1025
+ const state = (_d = options.state) !== null && _d !== void 0 ? _d : this.generateState();
1026
+ const codeVerifier = (_e = options.codeVerifier) !== null && _e !== void 0 ? _e : this.generateCodeVerifier();
946
1027
  // Build authorization URL
947
1028
  const params = new URLSearchParams({
948
1029
  response_type: config.responseType,
@@ -953,21 +1034,25 @@ var capacitorCapacitorUpdater = (function (exports, core) {
953
1034
  if (scope) {
954
1035
  params.set('scope', scope);
955
1036
  }
1037
+ // Convenience OIDC options
1038
+ const mergedAdditionalParams = Object.assign(Object.assign({}, ((_f = config.additionalParameters) !== null && _f !== void 0 ? _f : {})), ((_g = options.additionalParameters) !== null && _g !== void 0 ? _g : {}));
1039
+ const loginHint = (_h = options.loginHint) !== null && _h !== void 0 ? _h : config.loginHint;
1040
+ const prompt = (_j = options.prompt) !== null && _j !== void 0 ? _j : config.prompt;
1041
+ if (loginHint && !('login_hint' in mergedAdditionalParams)) {
1042
+ mergedAdditionalParams.login_hint = loginHint;
1043
+ }
1044
+ if (prompt && !('prompt' in mergedAdditionalParams)) {
1045
+ mergedAdditionalParams.prompt = prompt;
1046
+ }
956
1047
  // Add PKCE for code flow
957
1048
  if (config.responseType === 'code' && config.pkceEnabled) {
958
1049
  const codeChallenge = await this.generateCodeChallenge(codeVerifier);
959
1050
  params.set('code_challenge', codeChallenge);
960
1051
  params.set('code_challenge_method', 'S256');
961
1052
  }
962
- // Add additional parameters from config
963
- if (config.additionalParameters) {
964
- for (const [key, value] of Object.entries(config.additionalParameters)) {
965
- params.set(key, value);
966
- }
967
- }
968
- // Add additional parameters from login options
969
- if (options.additionalParameters) {
970
- for (const [key, value] of Object.entries(options.additionalParameters)) {
1053
+ // Add merged additional parameters
1054
+ for (const [key, value] of Object.entries(mergedAdditionalParams)) {
1055
+ if (value !== undefined) {
971
1056
  params.set(key, value);
972
1057
  }
973
1058
  }
@@ -979,10 +1064,19 @@ var capacitorCapacitorUpdater = (function (exports, core) {
979
1064
  scope,
980
1065
  });
981
1066
  localStorage.setItem(BaseSocialLogin.OAUTH_STATE_KEY, JSON.stringify({ provider: 'oauth2', providerId, state }));
1067
+ if (!config.authorizationBaseUrl) {
1068
+ throw new Error(`OAuth2 provider '${providerId}' is missing authorizationBaseUrl (discovery may have failed).`);
1069
+ }
982
1070
  const authUrl = `${config.authorizationBaseUrl}?${params.toString()}`;
983
1071
  if (config.logsEnabled) {
984
1072
  console.log(`[OAuth2:${providerId}] Opening authorization URL:`, authUrl);
985
1073
  }
1074
+ if (options.flow === 'redirect') {
1075
+ // Trigger a full-page redirect. The promise will not resolve because the page navigates away.
1076
+ window.location.assign(authUrl);
1077
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1078
+ return new Promise(() => { });
1079
+ }
986
1080
  // Open popup window
987
1081
  const width = 500;
988
1082
  const height = 650;
@@ -1088,11 +1182,31 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1088
1182
  });
1089
1183
  }
1090
1184
  async logout(providerId) {
1185
+ await this.ensureDiscovered(providerId);
1091
1186
  const config = this.providers.get(providerId);
1187
+ const stored = this.getStoredTokens(providerId);
1092
1188
  localStorage.removeItem(this.getTokensKey(providerId));
1093
- // If logout URL is configured, redirect to it
1189
+ // If logout URL is configured, build an end-session URL (OIDC) when possible.
1094
1190
  if (config === null || config === void 0 ? void 0 : config.logoutUrl) {
1095
- window.open(config.logoutUrl, '_blank');
1191
+ try {
1192
+ const url = new URL(config.logoutUrl);
1193
+ if (stored === null || stored === void 0 ? void 0 : stored.idToken) {
1194
+ url.searchParams.set('id_token_hint', stored.idToken);
1195
+ }
1196
+ const postLogout = config.postLogoutRedirectUrl;
1197
+ if (postLogout) {
1198
+ url.searchParams.set('post_logout_redirect_uri', postLogout);
1199
+ }
1200
+ if (config.additionalLogoutParameters) {
1201
+ for (const [k, v] of Object.entries(config.additionalLogoutParameters)) {
1202
+ url.searchParams.set(k, v);
1203
+ }
1204
+ }
1205
+ window.open(url.toString(), '_blank');
1206
+ }
1207
+ catch (_a) {
1208
+ window.open(config.logoutUrl, '_blank');
1209
+ }
1096
1210
  }
1097
1211
  }
1098
1212
  async isLoggedIn(providerId) {
@@ -1117,15 +1231,52 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1117
1231
  };
1118
1232
  }
1119
1233
  async refresh(providerId) {
1120
- const tokens = this.getStoredTokens(providerId);
1121
- if (!(tokens === null || tokens === void 0 ? void 0 : tokens.refreshToken)) {
1234
+ await this.refreshToken(providerId);
1235
+ }
1236
+ async refreshToken(providerId, refreshToken, additionalParameters) {
1237
+ var _a, _b, _c, _d, _e, _f;
1238
+ await this.ensureDiscovered(providerId);
1239
+ const config = this.getProvider(providerId);
1240
+ const stored = this.getStoredTokens(providerId);
1241
+ const effectiveRefreshToken = refreshToken !== null && refreshToken !== void 0 ? refreshToken : stored === null || stored === void 0 ? void 0 : stored.refreshToken;
1242
+ if (!effectiveRefreshToken) {
1122
1243
  throw new Error(`No OAuth2 refresh token is available for provider '${providerId}'. Include offline_access scope to receive one.`);
1123
1244
  }
1124
- const config = this.getProvider(providerId);
1125
1245
  if (!config.accessTokenEndpoint) {
1126
1246
  throw new Error(`No accessTokenEndpoint configured for provider '${providerId}'.`);
1127
1247
  }
1128
- await this.refreshWithRefreshToken(providerId, tokens.refreshToken);
1248
+ const tokenResponse = await this.refreshWithRefreshToken(providerId, effectiveRefreshToken, additionalParameters);
1249
+ const expiresAt = tokenResponse.expires_in ? Date.now() + tokenResponse.expires_in * 1000 : Date.now() + 3600000;
1250
+ const scopeArray = (_c = (_b = (_a = tokenResponse.scope) === null || _a === void 0 ? void 0 : _a.split(' ').filter(Boolean)) !== null && _b !== void 0 ? _b : stored === null || stored === void 0 ? void 0 : stored.scope) !== null && _c !== void 0 ? _c : [];
1251
+ // Fetch resource data if configured
1252
+ let resourceData = null;
1253
+ if (config.resourceUrl) {
1254
+ resourceData = await this.fetchResource(providerId, tokenResponse.access_token);
1255
+ }
1256
+ const nextRefreshToken = (_d = tokenResponse.refresh_token) !== null && _d !== void 0 ? _d : effectiveRefreshToken;
1257
+ this.persistTokens(providerId, {
1258
+ accessToken: tokenResponse.access_token,
1259
+ refreshToken: nextRefreshToken,
1260
+ idToken: tokenResponse.id_token,
1261
+ expiresAt,
1262
+ scope: scopeArray,
1263
+ tokenType: tokenResponse.token_type,
1264
+ });
1265
+ return {
1266
+ providerId,
1267
+ accessToken: {
1268
+ token: tokenResponse.access_token,
1269
+ tokenType: tokenResponse.token_type,
1270
+ expires: new Date(expiresAt).toISOString(),
1271
+ refreshToken: nextRefreshToken,
1272
+ },
1273
+ idToken: (_e = tokenResponse.id_token) !== null && _e !== void 0 ? _e : null,
1274
+ refreshToken: nextRefreshToken !== null && nextRefreshToken !== void 0 ? nextRefreshToken : null,
1275
+ resourceData,
1276
+ scope: scopeArray,
1277
+ tokenType: tokenResponse.token_type,
1278
+ expiresIn: (_f = tokenResponse.expires_in) !== null && _f !== void 0 ? _f : null,
1279
+ };
1129
1280
  }
1130
1281
  async handleOAuthRedirect(url, expectedState) {
1131
1282
  var _a, _b, _c, _d, _e;
@@ -1146,6 +1297,7 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1146
1297
  return { error: 'OAuth2 login session expired or state mismatch.' };
1147
1298
  }
1148
1299
  const { providerId } = pending;
1300
+ await this.ensureDiscovered(providerId);
1149
1301
  const config = this.providers.get(providerId);
1150
1302
  if (!config) {
1151
1303
  localStorage.removeItem(BaseSocialLogin.OAUTH_STATE_KEY);
@@ -1240,6 +1392,11 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1240
1392
  if (config.pkceEnabled) {
1241
1393
  params.set('code_verifier', pending.codeVerifier);
1242
1394
  }
1395
+ if (config.additionalTokenParameters) {
1396
+ for (const [k, v] of Object.entries(config.additionalTokenParameters)) {
1397
+ params.set(k, v);
1398
+ }
1399
+ }
1243
1400
  if (config.logsEnabled) {
1244
1401
  console.log(`[OAuth2:${providerId}] Exchanging code at:`, config.accessTokenEndpoint);
1245
1402
  }
@@ -1256,8 +1413,7 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1256
1413
  }
1257
1414
  return (await response.json());
1258
1415
  }
1259
- async refreshWithRefreshToken(providerId, refreshToken) {
1260
- var _a, _b, _c;
1416
+ async refreshWithRefreshToken(providerId, refreshToken, additionalParameters) {
1261
1417
  const config = this.getProvider(providerId);
1262
1418
  if (!config.accessTokenEndpoint) {
1263
1419
  throw new Error(`No accessTokenEndpoint configured for provider '${providerId}'.`);
@@ -1267,6 +1423,16 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1267
1423
  refresh_token: refreshToken,
1268
1424
  client_id: config.appId,
1269
1425
  });
1426
+ if (config.additionalTokenParameters) {
1427
+ for (const [k, v] of Object.entries(config.additionalTokenParameters)) {
1428
+ params.set(k, v);
1429
+ }
1430
+ }
1431
+ if (additionalParameters) {
1432
+ for (const [k, v] of Object.entries(additionalParameters)) {
1433
+ params.set(k, v);
1434
+ }
1435
+ }
1270
1436
  const response = await fetch(config.accessTokenEndpoint, {
1271
1437
  method: 'POST',
1272
1438
  headers: {
@@ -1278,17 +1444,7 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1278
1444
  const text = await response.text();
1279
1445
  throw new Error(`OAuth2 refresh failed (${response.status}): ${text}`);
1280
1446
  }
1281
- const tokens = (await response.json());
1282
- const expiresAt = tokens.expires_in ? Date.now() + tokens.expires_in * 1000 : Date.now() + 3600000;
1283
- const scopeArray = (_b = (_a = tokens.scope) === null || _a === void 0 ? void 0 : _a.split(' ').filter(Boolean)) !== null && _b !== void 0 ? _b : [];
1284
- this.persistTokens(providerId, {
1285
- accessToken: tokens.access_token,
1286
- refreshToken: (_c = tokens.refresh_token) !== null && _c !== void 0 ? _c : refreshToken,
1287
- idToken: tokens.id_token,
1288
- expiresAt,
1289
- scope: scopeArray,
1290
- tokenType: tokens.token_type,
1291
- });
1447
+ return (await response.json());
1292
1448
  }
1293
1449
  async fetchResource(providerId, accessToken) {
1294
1450
  const config = this.getProvider(providerId);
@@ -1365,6 +1521,37 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1365
1521
  buffer.forEach((b) => (binary += String.fromCharCode(b)));
1366
1522
  return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
1367
1523
  }
1524
+ decodeIdToken(idToken) {
1525
+ const parts = idToken.split('.');
1526
+ if (parts.length < 2) {
1527
+ throw new Error('Invalid JWT: missing parts');
1528
+ }
1529
+ const payload = parts[1];
1530
+ const normalized = payload.replace(/-/g, '+').replace(/_/g, '/');
1531
+ const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);
1532
+ const json = atob(padded);
1533
+ return JSON.parse(json);
1534
+ }
1535
+ getAccessTokenExpirationDate(providerId) {
1536
+ const tokens = this.getStoredTokens(providerId);
1537
+ if (!(tokens === null || tokens === void 0 ? void 0 : tokens.expiresAt))
1538
+ return { expirationDate: null };
1539
+ return { expirationDate: new Date(tokens.expiresAt).toISOString() };
1540
+ }
1541
+ isAccessTokenAvailable(providerId) {
1542
+ const tokens = this.getStoredTokens(providerId);
1543
+ return { isAvailable: !!(tokens === null || tokens === void 0 ? void 0 : tokens.accessToken) };
1544
+ }
1545
+ isAccessTokenExpired(providerId) {
1546
+ const tokens = this.getStoredTokens(providerId);
1547
+ if (!(tokens === null || tokens === void 0 ? void 0 : tokens.expiresAt))
1548
+ return { isExpired: true };
1549
+ return { isExpired: tokens.expiresAt <= Date.now() };
1550
+ }
1551
+ isRefreshTokenAvailable(providerId) {
1552
+ const tokens = this.getStoredTokens(providerId);
1553
+ return { isAvailable: !!(tokens === null || tokens === void 0 ? void 0 : tokens.refreshToken) };
1554
+ }
1368
1555
  }
1369
1556
 
1370
1557
  var __rest = (undefined && undefined.__rest) || function (s, e) {
@@ -1756,16 +1943,23 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1756
1943
  this.facebookProvider = new FacebookSocialLogin();
1757
1944
  this.twitterProvider = new TwitterSocialLogin();
1758
1945
  this.oauth2Provider = new OAuth2SocialLogin();
1759
- // Set up listener for OAuth redirects if we have a pending OAuth flow
1760
- if (localStorage.getItem(SocialLoginWeb.OAUTH_STATE_KEY)) {
1761
- console.log('OAUTH_STATE_KEY found');
1762
- this.handleOAuthRedirect().catch((error) => {
1946
+ // Auto-finish OAuth redirects only when running inside a popup window.
1947
+ // For redirect-based flows (full page navigation), the app should call `handleRedirectCallback()` explicitly.
1948
+ const hasPending = !!localStorage.getItem(SocialLoginWeb.OAUTH_STATE_KEY);
1949
+ const isPopup = !!window.opener || SocialLoginWeb.POPUP_WINDOW_NAMES.has(window.name);
1950
+ if (hasPending && isPopup) {
1951
+ this.finishOAuthRedirectInPopup().catch((error) => {
1763
1952
  console.error('Failed to finish OAuth redirect', error);
1764
- window.close();
1953
+ try {
1954
+ window.close();
1955
+ }
1956
+ catch (_a) {
1957
+ // ignore
1958
+ }
1765
1959
  });
1766
1960
  }
1767
1961
  }
1768
- async handleOAuthRedirect() {
1962
+ async parseRedirectResult() {
1769
1963
  var _a;
1770
1964
  const url = new URL(window.location.href);
1771
1965
  const stateRaw = localStorage.getItem(SocialLoginWeb.OAUTH_STATE_KEY);
@@ -1796,13 +1990,18 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1796
1990
  result = this.googleProvider.handleOAuthRedirect(url);
1797
1991
  break;
1798
1992
  }
1799
- if (!result) {
1993
+ return { provider, state, nonce, result };
1994
+ }
1995
+ async finishOAuthRedirectInPopup() {
1996
+ var _a;
1997
+ const parsed = await this.parseRedirectResult();
1998
+ const result = parsed.result;
1999
+ if (!result)
1800
2000
  return;
1801
- }
1802
2001
  // Build the message to send
1803
2002
  let message;
1804
2003
  if ('error' in result) {
1805
- const resolvedProvider = provider !== null && provider !== void 0 ? provider : null;
2004
+ const resolvedProvider = (_a = parsed.provider) !== null && _a !== void 0 ? _a : null;
1806
2005
  message = {
1807
2006
  type: 'oauth-error',
1808
2007
  provider: resolvedProvider,
@@ -1818,7 +2017,7 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1818
2017
  window.opener.postMessage(message, window.location.origin);
1819
2018
  }
1820
2019
  }
1821
- catch (_c) {
2020
+ catch (_b) {
1822
2021
  // Cross-origin error - window.opener may not be accessible
1823
2022
  console.log('postMessage to opener failed, using BroadcastChannel');
1824
2023
  }
@@ -1827,14 +2026,14 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1827
2026
  try {
1828
2027
  // Determine the channel name based on provider and state/nonce
1829
2028
  let channelName = null;
1830
- if (provider === 'oauth2' && state) {
1831
- channelName = `oauth2_${state}`;
2029
+ if (parsed.provider === 'oauth2' && parsed.state) {
2030
+ channelName = `oauth2_${parsed.state}`;
1832
2031
  }
1833
- else if (provider === 'twitter' && state) {
1834
- channelName = `twitter_oauth_${state}`;
2032
+ else if (parsed.provider === 'twitter' && parsed.state) {
2033
+ channelName = `twitter_oauth_${parsed.state}`;
1835
2034
  }
1836
- else if (provider === 'google' && nonce) {
1837
- channelName = `google_oauth_${nonce}`;
2035
+ else if (parsed.provider === 'google' && parsed.nonce) {
2036
+ channelName = `google_oauth_${parsed.nonce}`;
1838
2037
  }
1839
2038
  if (channelName) {
1840
2039
  const channel = new BroadcastChannel(channelName);
@@ -1842,7 +2041,7 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1842
2041
  channel.close();
1843
2042
  }
1844
2043
  }
1845
- catch (_d) {
2044
+ catch (_c) {
1846
2045
  // BroadcastChannel not supported or other error
1847
2046
  console.log('BroadcastChannel not available');
1848
2047
  }
@@ -1965,6 +2164,53 @@ var capacitorCapacitorUpdater = (function (exports, core) {
1965
2164
  async providerSpecificCall(options) {
1966
2165
  throw new Error(`Provider specific call for ${options.call} is not implemented`);
1967
2166
  }
2167
+ async refreshToken(options) {
2168
+ if (options.provider !== 'oauth2') {
2169
+ throw new Error('refreshToken is only implemented for oauth2 on web');
2170
+ }
2171
+ return this.oauth2Provider.refreshToken(options.providerId, options.refreshToken, options.additionalParameters);
2172
+ }
2173
+ async handleRedirectCallback() {
2174
+ const parsed = await this.parseRedirectResult();
2175
+ const result = parsed.result;
2176
+ if (!result)
2177
+ return null;
2178
+ if ('error' in result) {
2179
+ throw new Error(result.error);
2180
+ }
2181
+ return result;
2182
+ }
2183
+ async decodeIdToken(options) {
2184
+ var _a;
2185
+ const token = (_a = options === null || options === void 0 ? void 0 : options.idToken) !== null && _a !== void 0 ? _a : options === null || options === void 0 ? void 0 : options.token;
2186
+ if (!token) {
2187
+ throw new Error('idToken (or token) is required');
2188
+ }
2189
+ const claims = this.oauth2Provider.decodeIdToken(token);
2190
+ return { claims };
2191
+ }
2192
+ async getAccessTokenExpirationDate(options) {
2193
+ if (typeof (options === null || options === void 0 ? void 0 : options.accessTokenExpirationDate) !== 'number') {
2194
+ throw new Error('accessTokenExpirationDate is required');
2195
+ }
2196
+ return { date: new Date(options.accessTokenExpirationDate).toISOString() };
2197
+ }
2198
+ async isAccessTokenAvailable(options) {
2199
+ var _a;
2200
+ const token = (_a = options === null || options === void 0 ? void 0 : options.accessToken) !== null && _a !== void 0 ? _a : null;
2201
+ return { isAvailable: typeof token === 'string' && token.length > 0 };
2202
+ }
2203
+ async isAccessTokenExpired(options) {
2204
+ if (typeof (options === null || options === void 0 ? void 0 : options.accessTokenExpirationDate) !== 'number') {
2205
+ throw new Error('accessTokenExpirationDate is required');
2206
+ }
2207
+ return { isExpired: options.accessTokenExpirationDate <= Date.now() };
2208
+ }
2209
+ async isRefreshTokenAvailable(options) {
2210
+ var _a;
2211
+ const token = (_a = options === null || options === void 0 ? void 0 : options.refreshToken) !== null && _a !== void 0 ? _a : null;
2212
+ return { isAvailable: typeof token === 'string' && token.length > 0 };
2213
+ }
1968
2214
  async getPluginVersion() {
1969
2215
  return { version: 'web' };
1970
2216
  }
@@ -2003,6 +2249,7 @@ var capacitorCapacitorUpdater = (function (exports, core) {
2003
2249
  }
2004
2250
  }
2005
2251
  SocialLoginWeb.OAUTH_STATE_KEY = 'social_login_oauth_pending';
2252
+ SocialLoginWeb.POPUP_WINDOW_NAMES = new Set(['OAuth2Login', 'XLogin', 'Google Sign In', 'Authorization']);
2006
2253
 
2007
2254
  var web = /*#__PURE__*/Object.freeze({
2008
2255
  __proto__: null,