@opengeoweb/authentication 19.5.1 → 19.6.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/index.esm.js CHANGED
@@ -192,6 +192,67 @@ function _regeneratorDefine(e, r, n, t) {
192
192
  }, _regeneratorDefine(e, r, n, t);
193
193
  }
194
194
 
195
+ /* *
196
+ * Licensed under the Apache License, Version 2.0 (the "License");
197
+ * you may not use this file except in compliance with the License.
198
+ * You may obtain a copy of the License at
199
+ *
200
+ * http://www.apache.org/licenses/LICENSE-2.0
201
+ *
202
+ * Unless required by applicable law or agreed to in writing, software
203
+ * distributed under the License is distributed on an "AS IS" BASIS,
204
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
205
+ * See the License for the specific language governing permissions and
206
+ * limitations under the License.
207
+ *
208
+ * Copyright 2026 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
209
+ * Copyright 2026 - Finnish Meteorological Institute (FMI)
210
+ * Copyright 2026 - The Norwegian Meteorological Institute (MET Norway)
211
+ * */
212
+ // OIDC error codes for "prompt=none couldn't be honoured silently"
213
+ var OIDC_NO_INTERACTION_ERROR_CODES = ['login_required', 'interaction_required', 'consent_required'];
214
+ var buildSilentLoginUrl = function buildSilentLoginUrl(loginUrl) {
215
+ return "" + loginUrl + (loginUrl.includes('?') ? '&' : '?') + "prompt=none";
216
+ };
217
+ // Force-auth already redirects to /login on a live IdP session, so silent login is redundant there. Keep them mutually exclusive
218
+ var isSilentLoginEnabled = function isSilentLoginEnabled(config) {
219
+ return Boolean((config == null ? void 0 : config.GW_FEATURE_SILENT_LOGIN) && !(config != null && config.GW_FEATURE_FORCE_AUTHENTICATION));
220
+ };
221
+ var SILENT_LOGIN_ATTEMPT_STORAGE_KEY = 'gw_silent_login_attempted_at';
222
+ var SILENT_LOGIN_COOLDOWN_MS = 5 * 60 * 1000;
223
+ // Limits retries if the IdP doesn't honour prompt=none
224
+ var hasRecentSilentLoginAttempt = function hasRecentSilentLoginAttempt() {
225
+ var lastAttempt = Number(localStorage.getItem(SILENT_LOGIN_ATTEMPT_STORAGE_KEY));
226
+ return Boolean(lastAttempt) && Date.now() - lastAttempt < SILENT_LOGIN_COOLDOWN_MS;
227
+ };
228
+ var recordSilentLoginAttempt = function recordSilentLoginAttempt() {
229
+ localStorage.setItem(SILENT_LOGIN_ATTEMPT_STORAGE_KEY, String(Date.now()));
230
+ };
231
+ var clearSilentLoginAttempt = function clearSilentLoginAttempt() {
232
+ localStorage.removeItem(SILENT_LOGIN_ATTEMPT_STORAGE_KEY);
233
+ };
234
+ var SILENT_LOGIN_SUPPRESSED_STORAGE_KEY = 'gw_silent_login_suppressed';
235
+ // Set on logout; never expires on its own (unlike the cooldown above), only clearSilentLoginSuppression lifts it
236
+ var suppressSilentLogin = function suppressSilentLogin() {
237
+ localStorage.setItem(SILENT_LOGIN_SUPPRESSED_STORAGE_KEY, 'true');
238
+ };
239
+ var isSilentLoginSuppressed = function isSilentLoginSuppressed() {
240
+ return localStorage.getItem(SILENT_LOGIN_SUPPRESSED_STORAGE_KEY) === 'true';
241
+ };
242
+ var clearSilentLoginSuppression = function clearSilentLoginSuppression() {
243
+ localStorage.removeItem(SILENT_LOGIN_SUPPRESSED_STORAGE_KEY);
244
+ };
245
+ // Tells tabs already open to log out now (suppressSilentLogin only blocks future attempts)
246
+ var LOGOUT_BROADCAST_CHANNEL_NAME = 'gw_auth_logout';
247
+ var broadcastLogout = function broadcastLogout() {
248
+ var channel = new BroadcastChannel(LOGOUT_BROADCAST_CHANNEL_NAME);
249
+ channel.postMessage('logout');
250
+ channel.close();
251
+ };
252
+ var createLogoutBroadcastChannel = function createLogoutBroadcastChannel() {
253
+ return new BroadcastChannel(LOGOUT_BROADCAST_CHANNEL_NAME);
254
+ };
255
+
195
256
  var DEFAULT_TIMEOUT = 15000;
196
257
  var KEEP_ALIVE_POLLER_IN_SECONDS = 60; // Number of seconds between the checks if the token should be refreshed.
197
258
  var REFRESH_TOKEN_WHEN_PCT_EXPIRED = 75; // Refresh token when 75% expired. Set to (10 / 3600) * 100 = 0.2777778% to test with 10 second interval (assuming 1 hour token expiration).
@@ -579,7 +640,9 @@ var authConfigKeys = {
579
640
  GW_BE_VERSION_BASE_URL: null,
580
641
  GW_AUTH_CLIENT_ID: null,
581
642
  GW_AUTH_ROLE_CLAIM_NAME: null,
582
- GW_AUTH_ROLE_CLAIM_VALUE_PRESETS_ADMIN: null
643
+ GW_AUTH_ROLE_CLAIM_VALUE_PRESETS_ADMIN: null,
644
+ GW_FEATURE_SILENT_LOGIN: false,
645
+ GW_FEATURE_FORCE_AUTHENTICATION: false
583
646
  };
584
647
  var getRandomString = function getRandomString() {
585
648
  var array = new Uint32Array(8);
@@ -620,7 +683,9 @@ var getAuthConfig = function getAuthConfig(_configUrls) {
620
683
  GW_BE_VERSION_BASE_URL = _configUrls.GW_BE_VERSION_BASE_URL,
621
684
  GW_AUTH_CLIENT_ID = _configUrls.GW_AUTH_CLIENT_ID,
622
685
  GW_AUTH_ROLE_CLAIM_NAME = _configUrls.GW_AUTH_ROLE_CLAIM_NAME,
623
- GW_AUTH_ROLE_CLAIM_VALUE_PRESETS_ADMIN = _configUrls.GW_AUTH_ROLE_CLAIM_VALUE_PRESETS_ADMIN;
686
+ GW_AUTH_ROLE_CLAIM_VALUE_PRESETS_ADMIN = _configUrls.GW_AUTH_ROLE_CLAIM_VALUE_PRESETS_ADMIN,
687
+ GW_FEATURE_SILENT_LOGIN = _configUrls.GW_FEATURE_SILENT_LOGIN,
688
+ GW_FEATURE_FORCE_AUTHENTICATION = _configUrls.GW_FEATURE_FORCE_AUTHENTICATION;
624
689
  var loginUrl = replaceTemplateKeys(GW_AUTH_LOGIN_URL, GW_AUTH_CLIENT_ID, GW_APP_URL, sessionStorageProvider.getOauthState(), sessionStorageProvider.getOauthCodeChallenge());
625
690
  var logOutUrl = replaceTemplateKeys(GW_AUTH_LOGOUT_URL, GW_AUTH_CLIENT_ID, GW_APP_URL);
626
691
  return {
@@ -631,7 +696,9 @@ var getAuthConfig = function getAuthConfig(_configUrls) {
631
696
  GW_BE_VERSION_BASE_URL: GW_BE_VERSION_BASE_URL,
632
697
  GW_AUTH_CLIENT_ID: GW_AUTH_CLIENT_ID,
633
698
  GW_AUTH_ROLE_CLAIM_NAME: GW_AUTH_ROLE_CLAIM_NAME,
634
- GW_AUTH_ROLE_CLAIM_VALUE_PRESETS_ADMIN: GW_AUTH_ROLE_CLAIM_VALUE_PRESETS_ADMIN
699
+ GW_AUTH_ROLE_CLAIM_VALUE_PRESETS_ADMIN: GW_AUTH_ROLE_CLAIM_VALUE_PRESETS_ADMIN,
700
+ GW_FEATURE_SILENT_LOGIN: GW_FEATURE_SILENT_LOGIN,
701
+ GW_FEATURE_FORCE_AUTHENTICATION: GW_FEATURE_FORCE_AUTHENTICATION
635
702
  };
636
703
  };
637
704
  var AuthenticationContext = /*#__PURE__*/React.createContext({
@@ -647,6 +714,11 @@ var authChangeListener = null;
647
714
  var setAuthChangeListener = function setAuthChangeListener(listener) {
648
715
  authChangeListener = listener;
649
716
  };
717
+ var clearSession = function clearSession(onSetAuth, onLogin, sessionStorageProviderArg) {
718
+ onSetAuth(null);
719
+ onLogin(false);
720
+ sessionStorageProviderArg.removeHasAuthenticated();
721
+ };
650
722
  var useAuthenticationDefaultProps = function useAuthenticationDefaultProps() {
651
723
  var _auth$roles$, _auth$roles;
652
724
  var _React$useState = React.useState(false),
@@ -756,6 +828,20 @@ var AuthenticationProvider = function AuthenticationProvider(_ref2) {
756
828
  clearInterval(interval.current);
757
829
  };
758
830
  }, [auth, configURLS.GW_APP_URL, configURLS.GW_AUTH_CLIENT_ID, configURLS.GW_AUTH_TOKEN_URL, onSetAuth, configURLS, onLogin]);
831
+ // Propagates an explicit logout (see Logout.tsx) to every other open tab.
832
+ var silentLoginEnabled = isSilentLoginEnabled(authConfig);
833
+ React.useEffect(function () {
834
+ if (!silentLoginEnabled) {
835
+ return undefined;
836
+ }
837
+ var channel = createLogoutBroadcastChannel();
838
+ channel.onmessage = function () {
839
+ clearSession(onSetAuth, onLogin, sessionStorageProvider);
840
+ };
841
+ return function () {
842
+ channel.close();
843
+ };
844
+ }, [silentLoginEnabled, onSetAuth, onLogin, sessionStorageProvider]);
759
845
  var contextValue = React.useMemo(function () {
760
846
  return {
761
847
  isLoggedIn: isLoggedIn,
@@ -790,23 +876,53 @@ var HandleOAuth2Code = function HandleOAuth2Code() {
790
876
  var _React$useState = React.useState(null),
791
877
  error = _React$useState[0],
792
878
  setError = _React$useState[1];
879
+ // Set when an automatic silent-login attempt (see Workspace.tsx) comes back
880
+ // with an OIDC "no interaction possible" error — i.e. "you're just not
881
+ // logged in", not a real failure, so this returns quietly instead of
882
+ // showing the /error page.
883
+ var _React$useState2 = React.useState(false),
884
+ returnWithoutLogin = _React$useState2[0],
885
+ setReturnWithoutLogin = _React$useState2[1];
793
886
  var _useIsMounted = useIsMounted(),
794
887
  isMounted = _useIsMounted.isMounted;
795
888
  var loginInProgress = React.useRef(false);
796
889
  var authenticate = React.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
797
- var _Object$fromEntries, code, state, isStateRequired, isPkceRequired, payload, useDefaultContentType, data, config, res, newAuth, _t;
890
+ var _Object$fromEntries, code, state, oidcError, isStateRequired, isPkceRequired, payload, useDefaultContentType, data, config, res, newAuth, _t;
798
891
  return _regenerator().w(function (_context) {
799
892
  while (1) switch (_context.p = _context.n) {
800
893
  case 0:
801
- _Object$fromEntries = Object.fromEntries(new URLSearchParams(window.location.search)), code = _Object$fromEntries.code, state = _Object$fromEntries.state;
894
+ _Object$fromEntries = Object.fromEntries(new URLSearchParams(window.location.search)), code = _Object$fromEntries.code, state = _Object$fromEntries.state, oidcError = _Object$fromEntries.error;
895
+ if (!oidcError) {
896
+ _context.n = 2;
897
+ break;
898
+ }
899
+ // Arm the cooldown for any IdP error, not just the whitelisted ones, so Workspace.tsx doesn't immediately retry
900
+ recordSilentLoginAttempt();
901
+ if (!OIDC_NO_INTERACTION_ERROR_CODES.includes(oidcError)) {
902
+ _context.n = 1;
903
+ break;
904
+ }
905
+ if (isMounted.current) {
906
+ setReturnWithoutLogin(true);
907
+ }
908
+ return _context.a(2);
909
+ case 1:
910
+ setError(function () {
911
+ return {
912
+ message: 'Login failed',
913
+ stack: "OIDC error: " + oidcError
914
+ };
915
+ });
916
+ return _context.a(2);
917
+ case 2:
802
918
  isStateRequired = authConfig.GW_AUTH_LOGIN_URL.includes('&state=');
803
919
  isPkceRequired = authConfig.GW_AUTH_LOGIN_URL.includes('&code_challenge=');
804
920
  if (!isStateRequired) {
805
- _context.n = 1;
921
+ _context.n = 3;
806
922
  break;
807
923
  }
808
924
  if (!(!state || state !== sessionStorageProvider.getOauthState())) {
809
- _context.n = 1;
925
+ _context.n = 3;
810
926
  break;
811
927
  }
812
928
  setError(function () {
@@ -816,13 +932,13 @@ var HandleOAuth2Code = function HandleOAuth2Code() {
816
932
  };
817
933
  });
818
934
  return _context.a(2);
819
- case 1:
935
+ case 3:
820
936
  if (!isPkceRequired) {
821
- _context.n = 2;
937
+ _context.n = 4;
822
938
  break;
823
939
  }
824
940
  if (!(!code || !sessionStorageProvider.getOauthCodeVerifier())) {
825
- _context.n = 2;
941
+ _context.n = 4;
826
942
  break;
827
943
  }
828
944
  setError(function () {
@@ -832,7 +948,7 @@ var HandleOAuth2Code = function HandleOAuth2Code() {
832
948
  };
833
949
  });
834
950
  return _context.a(2);
835
- case 2:
951
+ case 4:
836
952
  payload = Object.assign({
837
953
  client_id: authConfig.GW_AUTH_CLIENT_ID,
838
954
  code: code,
@@ -851,26 +967,28 @@ var HandleOAuth2Code = function HandleOAuth2Code() {
851
967
  },
852
968
  timeout: 30000
853
969
  };
854
- _context.p = 3;
855
- _context.n = 4;
970
+ _context.p = 5;
971
+ _context.n = 6;
856
972
  return axiosInstance.post(authConfig.GW_AUTH_TOKEN_URL, data, config);
857
- case 4:
973
+ case 6:
858
974
  res = _context.v;
859
975
  newAuth = makeCredentialsFromTokenResponse(res, authConfig);
860
976
  if (isMounted.current) {
861
977
  onSetAuth(newAuth);
862
978
  onLogin(true);
863
979
  sessionStorageProvider.setHasAuthenticated('true');
980
+ clearSilentLoginSuppression();
981
+ clearSilentLoginAttempt();
864
982
  if (sessionStorageProvider) {
865
983
  sessionStorageProvider.removeOauthState();
866
984
  sessionStorageProvider.removeOauthCodeVerifier();
867
985
  sessionStorageProvider.removeOauthCodeChallenge();
868
986
  }
869
987
  }
870
- _context.n = 6;
988
+ _context.n = 8;
871
989
  break;
872
- case 5:
873
- _context.p = 5;
990
+ case 7:
991
+ _context.p = 7;
874
992
  _t = _context.v;
875
993
  if (isMounted.current) {
876
994
  if (_t instanceof Error) {
@@ -889,10 +1007,10 @@ var HandleOAuth2Code = function HandleOAuth2Code() {
889
1007
  sessionStorageProvider.removeHasAuthenticated();
890
1008
  }
891
1009
  }
892
- case 6:
1010
+ case 8:
893
1011
  return _context.a(2);
894
1012
  }
895
- }, _callee, null, [[3, 5]]);
1013
+ }, _callee, null, [[5, 7]]);
896
1014
  })), [authConfig, isMounted, onLogin, onSetAuth, sessionStorageProvider]);
897
1015
  React.useEffect(function () {
898
1016
  var authenticateWithLock = /*#__PURE__*/function () {
@@ -932,7 +1050,7 @@ var HandleOAuth2Code = function HandleOAuth2Code() {
932
1050
  }
933
1051
  },
934
1052
  to: "/error"
935
- }) : null, isLoggedIn ? jsx(Navigate, {
1053
+ }) : null, isLoggedIn || returnWithoutLogin ? jsx(Navigate, {
936
1054
  replace: true,
937
1055
  to: sessionStorageProvider.getCallbackUrl()
938
1056
  }) : null]
@@ -984,7 +1102,10 @@ var OAuth2Login = function OAuth2Login() {
984
1102
  var callbackUrl = getCurrentUrlLocation(sessionStorageProvider.getCallbackUrl(), authConfig.GW_APP_URL);
985
1103
  sessionStorageProvider.setCallbackUrl(callbackUrl);
986
1104
  window.location.assign(authConfig.GW_AUTH_LOGIN_URL);
987
- });
1105
+ // Runs once and navigates away immediately; doesn't need to re-fire if
1106
+ // authConfig happens to change before that navigation completes.
1107
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1108
+ }, []);
988
1109
  return null;
989
1110
  };
990
1111
 
@@ -1012,7 +1133,8 @@ var useAuthenticationTranslation = function useAuthenticationTranslation() {
1012
1133
  return useTranslation(ns);
1013
1134
  };
1014
1135
 
1015
- var OAuth2Logout = function OAuth2Logout() {
1136
+ var OAuth2Logout = function OAuth2Logout(_ref) {
1137
+ var config = _ref.config;
1016
1138
  var _useAuthenticationCon = useAuthenticationContext(),
1017
1139
  onSetAuth = _useAuthenticationCon.onSetAuth,
1018
1140
  authConfig = _useAuthenticationCon.authConfig,
@@ -1024,15 +1146,21 @@ var OAuth2Logout = function OAuth2Logout() {
1024
1146
  setShowAlert = _React$useState[1];
1025
1147
  var _useAuthenticationTra = useAuthenticationTranslation(),
1026
1148
  t = _useAuthenticationTra.t;
1149
+ var silentLoginEnabled = isSilentLoginEnabled(config);
1027
1150
  React.useEffect(function () {
1028
1151
  if (isLoggedIn) {
1029
1152
  setShowAlert(false);
1030
- onSetAuth(null);
1031
- onLogin(false);
1032
- sessionStorageProvider.removeHasAuthenticated();
1153
+ clearSession(onSetAuth, onLogin, sessionStorageProvider);
1154
+ if (silentLoginEnabled) {
1155
+ // GW_AUTH_LOGOUT_URL doesn't necessarily end the IdP's own session
1156
+ // (e.g. it's just the app's own URL), so without these, silent login
1157
+ // will immediately log the user back in.
1158
+ suppressSilentLogin();
1159
+ broadcastLogout();
1160
+ }
1033
1161
  window.location.assign(authConfig.GW_AUTH_LOGOUT_URL);
1034
1162
  }
1035
- }, [isLoggedIn, onSetAuth, onLogin, sessionStorageProvider, authConfig.GW_AUTH_LOGOUT_URL]);
1163
+ }, [isLoggedIn, onSetAuth, onLogin, sessionStorageProvider, authConfig.GW_AUTH_LOGOUT_URL, silentLoginEnabled]);
1036
1164
  return showAlert ? jsx(ThemeWrapper, {
1037
1165
  children: jsx(AlertBanner, {
1038
1166
  info: jsx("p", {
@@ -1187,4 +1315,4 @@ params, callbacks) {
1187
1315
  };
1188
1316
  };
1189
1317
 
1190
- export { AUTH_NAMESPACE, AuthenticationContext, AuthenticationProvider, HandleOAuth2Code as Code, GEOWEB_ROLE_PRESETS_ADMIN, GEOWEB_ROLE_USER, KEEP_ALIVE_POLLER_IN_SECONDS, OAuth2Login as Login, OAuth2Logout as Logout, MILLISECOND_TO_SECOND, REFRESH_TOKEN_WHEN_PCT_EXPIRED, UserMenuRoles, apiTranslations, authTranslations, createApiInstance, createFakeApiInstance, createNonAuthApiInstance, fakeApiRequest, getAuthConfig, getCodeChallenge, getCurrentTimeInSeconds, getCurrentUrlLocation, getRandomString, groupsToRoles, makeCredentialsFromTokenResponse, refreshAccessToken, refreshAccessTokenAndSetAuthContext, setAuthChangeListener, useApi, useAuthenticationContext, useAuthenticationDefaultProps };
1318
+ export { AUTH_NAMESPACE, AuthenticationContext, AuthenticationProvider, HandleOAuth2Code as Code, GEOWEB_ROLE_PRESETS_ADMIN, GEOWEB_ROLE_USER, KEEP_ALIVE_POLLER_IN_SECONDS, OAuth2Login as Login, OAuth2Logout as Logout, MILLISECOND_TO_SECOND, OIDC_NO_INTERACTION_ERROR_CODES, REFRESH_TOKEN_WHEN_PCT_EXPIRED, UserMenuRoles, apiTranslations, authTranslations, broadcastLogout, buildSilentLoginUrl, clearSession, clearSilentLoginAttempt, clearSilentLoginSuppression, createApiInstance, createFakeApiInstance, createLogoutBroadcastChannel, createNonAuthApiInstance, fakeApiRequest, getAuthConfig, getCodeChallenge, getCurrentTimeInSeconds, getCurrentUrlLocation, getRandomString, groupsToRoles, hasRecentSilentLoginAttempt, isSilentLoginEnabled, isSilentLoginSuppressed, makeCredentialsFromTokenResponse, recordSilentLoginAttempt, refreshAccessToken, refreshAccessTokenAndSetAuthContext, setAuthChangeListener, suppressSilentLogin, useApi, useAuthenticationContext, useAuthenticationDefaultProps };
@@ -8,5 +8,6 @@ export * from './lib/components/AuthenticationContext';
8
8
  export * from './lib/components/ApiContext';
9
9
  export * from './lib/components/apiHooks';
10
10
  export * from './lib/utils/utils';
11
+ export * from './lib/utils/silentLogin';
11
12
  export { AUTH_NAMESPACE } from './lib/utils/i18n';
12
13
  export { authTranslations, apiTranslations };
@@ -8,6 +8,7 @@ export declare const getAuthConfig: (_configUrls: AuthenticationConfig) => Authe
8
8
  export declare const AuthenticationContext: React.Context<AuthenticationContextProps>;
9
9
  type OnAuthChange = (isLoggedIn: boolean, auth: Credentials | null) => void;
10
10
  export declare const setAuthChangeListener: (listener: OnAuthChange) => void;
11
+ export declare const clearSession: (onSetAuth: AuthenticationDefaultStateProps["onSetAuth"], onLogin: AuthenticationDefaultStateProps["onLogin"], sessionStorageProviderArg: AuthenticationDefaultStateProps["sessionStorageProvider"]) => void;
11
12
  export declare const useAuthenticationDefaultProps: () => AuthenticationDefaultStateProps;
12
13
  export interface AuthenticationProviderProps {
13
14
  children: React.ReactNode;
@@ -1,2 +1,2 @@
1
- export { useAuthenticationContext, AuthenticationProvider, useAuthenticationDefaultProps, AuthenticationContext, getAuthConfig, getRandomString, getCodeChallenge, setAuthChangeListener, } from './AuthenticationContext';
1
+ export { useAuthenticationContext, AuthenticationProvider, useAuthenticationDefaultProps, AuthenticationContext, clearSession, getAuthConfig, getRandomString, getCodeChallenge, setAuthChangeListener, } from './AuthenticationContext';
2
2
  export type * from './types';
@@ -9,6 +9,8 @@ export interface AuthenticationConfig {
9
9
  GW_APP_URL: string;
10
10
  GW_BE_VERSION_BASE_URL?: string;
11
11
  GW_AUTH_CLIENT_ID: string;
12
+ GW_FEATURE_SILENT_LOGIN?: boolean;
13
+ GW_FEATURE_FORCE_AUTHENTICATION?: boolean;
12
14
  }
13
15
  export interface AuthenticationDefaultStateProps {
14
16
  isLoggedIn: boolean;
@@ -1,3 +1,7 @@
1
1
  import React from 'react';
2
- declare const OAuth2Logout: React.FC;
2
+ import type { ConfigType } from '@opengeoweb/shared';
3
+ interface OAuth2LogoutProps {
4
+ config?: ConfigType;
5
+ }
6
+ declare const OAuth2Logout: React.FC<OAuth2LogoutProps>;
3
7
  export default OAuth2Logout;
@@ -0,0 +1,14 @@
1
+ export declare const OIDC_NO_INTERACTION_ERROR_CODES: string[];
2
+ export declare const buildSilentLoginUrl: (loginUrl: string) => string;
3
+ export declare const isSilentLoginEnabled: (config?: {
4
+ GW_FEATURE_SILENT_LOGIN?: boolean;
5
+ GW_FEATURE_FORCE_AUTHENTICATION?: boolean;
6
+ }) => boolean;
7
+ export declare const hasRecentSilentLoginAttempt: () => boolean;
8
+ export declare const recordSilentLoginAttempt: () => void;
9
+ export declare const clearSilentLoginAttempt: () => void;
10
+ export declare const suppressSilentLogin: () => void;
11
+ export declare const isSilentLoginSuppressed: () => boolean;
12
+ export declare const clearSilentLoginSuppression: () => void;
13
+ export declare const broadcastLogout: () => void;
14
+ export declare const createLogoutBroadcastChannel: () => BroadcastChannel;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/authentication",
3
- "version": "19.5.1",
3
+ "version": "19.6.1",
4
4
  "description": "GeoWeb authentication library for the opengeoweb project",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -26,7 +26,7 @@
26
26
  "i18next": "^25.0.1",
27
27
  "react-i18next": "^15.1.1",
28
28
  "@mui/material": "^9.0.1",
29
- "react-router": "^7.15.1"
29
+ "react-router": "^7.18.2"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": "19",