@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 +155 -27
- package/dist/src/index.d.ts +1 -0
- package/dist/src/lib/components/AuthenticationContext/AuthenticationContext.d.ts +1 -0
- package/dist/src/lib/components/AuthenticationContext/index.d.ts +1 -1
- package/dist/src/lib/components/AuthenticationContext/types.d.ts +2 -0
- package/dist/src/lib/components/pages/Logout.d.ts +5 -1
- package/dist/src/lib/utils/silentLogin.d.ts +14 -0
- package/package.json +2 -2
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 =
|
|
921
|
+
_context.n = 3;
|
|
806
922
|
break;
|
|
807
923
|
}
|
|
808
924
|
if (!(!state || state !== sessionStorageProvider.getOauthState())) {
|
|
809
|
-
_context.n =
|
|
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
|
|
935
|
+
case 3:
|
|
820
936
|
if (!isPkceRequired) {
|
|
821
|
-
_context.n =
|
|
937
|
+
_context.n = 4;
|
|
822
938
|
break;
|
|
823
939
|
}
|
|
824
940
|
if (!(!code || !sessionStorageProvider.getOauthCodeVerifier())) {
|
|
825
|
-
_context.n =
|
|
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
|
|
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 =
|
|
855
|
-
_context.n =
|
|
970
|
+
_context.p = 5;
|
|
971
|
+
_context.n = 6;
|
|
856
972
|
return axiosInstance.post(authConfig.GW_AUTH_TOKEN_URL, data, config);
|
|
857
|
-
case
|
|
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 =
|
|
988
|
+
_context.n = 8;
|
|
871
989
|
break;
|
|
872
|
-
case
|
|
873
|
-
_context.p =
|
|
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
|
|
1010
|
+
case 8:
|
|
893
1011
|
return _context.a(2);
|
|
894
1012
|
}
|
|
895
|
-
}, _callee, null, [[
|
|
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
|
|
1031
|
-
|
|
1032
|
-
|
|
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 };
|
package/dist/src/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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.
|
|
29
|
+
"react-router": "^7.18.2"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"react": "19",
|