@luizleon/sf.prefeiturasp.vuecomponents 0.0.66 → 4.0.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.
Files changed (78) hide show
  1. package/dist/sf.prefeiturasp.vuecomponents.cjs +423 -0
  2. package/dist/sf.prefeiturasp.vuecomponents.cjs.map +1 -0
  3. package/dist/sf.prefeiturasp.vuecomponents.js +8953 -0
  4. package/dist/sf.prefeiturasp.vuecomponents.js.map +1 -0
  5. package/dist/sf.prefeiturasp.vuecomponents.umd.cjs +423 -0
  6. package/dist/sf.prefeiturasp.vuecomponents.umd.cjs.map +1 -0
  7. package/dist/{axios → src/axios}/axiosClient.d.ts +7 -0
  8. package/dist/{components/button/Button.d.ts → src/components/button/Button.vue.d.ts} +16 -16
  9. package/dist/{components/content/Content.d.ts → src/components/content/Content.vue.d.ts} +7 -7
  10. package/dist/{components/drawer/Drawer.d.ts → src/components/drawer/Drawer.vue.d.ts} +15 -15
  11. package/dist/{components/icon/Icon.d.ts → src/components/icon/Icon.vue.d.ts} +23 -24
  12. package/dist/{components/internal/HeaderAvatar.d.ts → src/components/internal/HeaderAvatar.vue.d.ts} +2 -2
  13. package/dist/src/components/internal/LoadingCircle.vue.d.ts +2 -0
  14. package/dist/src/components/internal/MenuIcon.vue.d.ts +2 -0
  15. package/dist/src/components/internal/ScrollToTop.vue.d.ts +2 -0
  16. package/dist/src/components/internal/ThemeToggle.d.ts +10 -0
  17. package/dist/src/components/internal/ThemeToggle.vue.d.ts +2 -0
  18. package/dist/{components/layout/Layout.d.ts → src/components/layout/Layout.vue.d.ts} +9 -2
  19. package/dist/{components/message/Message.d.ts → src/components/message/Message.vue.d.ts} +14 -14
  20. package/dist/src/components/navmenu/NavMenu.vue.d.ts +15 -0
  21. package/dist/{components/tabnavigation/TabNavigation.d.ts → src/components/tabnavigation/TabNavigation.vue.d.ts} +9 -9
  22. package/dist/{components/tooltip/Tooltip.d.ts → src/components/tooltip/Tooltip.vue.d.ts} +7 -7
  23. package/dist/src/index.d.ts +17 -0
  24. package/dist/{types → src/types}/index.d.ts +11 -0
  25. package/dist/style.css +1 -1
  26. package/dist/tsconfig.tsbuildinfo +1 -0
  27. package/package.json +10 -9
  28. package/src/axios/axiosClient.ts +111 -3
  29. package/src/components/button/Button.vue +1 -1
  30. package/src/components/icon/Icon.vue +12 -16
  31. package/src/components/internal/getMaxZindex.ts +3 -2
  32. package/src/components/layout/Layout.vue +8 -1
  33. package/src/components/navmenu/NavMenu.vue +109 -0
  34. package/src/index.ts +2 -4
  35. package/src/keycloak.js +1485 -1890
  36. package/src/services/authService.ts +13 -4
  37. package/src/style/componentes.scss +5 -1
  38. package/src/style/src/_functions.scss +17 -2
  39. package/src/style/src/_mixins.scss +51 -29
  40. package/src/style/src/_variables.scss +11 -0
  41. package/src/style/src/components/_button.scss +8 -11
  42. package/src/style/src/components/_icon.scss +49 -47
  43. package/src/style/src/components/_tooltip.scss +6 -7
  44. package/src/types/index.ts +24 -0
  45. package/src/vite-env.d.ts +1 -0
  46. package/tsconfig.json +5 -3
  47. package/vite.config.js +2 -4
  48. package/dist/components/internal/LoadingCircle.d.ts +0 -2
  49. package/dist/components/internal/MenuIcon.d.ts +0 -2
  50. package/dist/components/internal/ScrollToTop.d.ts +0 -2
  51. package/dist/components/internal/ThemeToggle.d.ts +0 -2
  52. package/dist/components/navmenulink/NavMenuLink.d.ts +0 -18
  53. package/dist/components/panelmenu/PanelMenu.d.ts +0 -16
  54. package/dist/index.d.ts +0 -18
  55. package/dist/keycloak.d.ts +0 -671
  56. package/dist/sf.prefeiturasp.vuecomponents.es.js +0 -8685
  57. package/dist/sf.prefeiturasp.vuecomponents.es.js.map +0 -1
  58. package/dist/sf.prefeiturasp.vuecomponents.umd.js +0 -153
  59. package/dist/sf.prefeiturasp.vuecomponents.umd.js.map +0 -1
  60. package/src/components/button/Button.d.ts +0 -26
  61. package/src/components/content/Content.d.ts +0 -28
  62. package/src/components/drawer/Drawer.d.ts +0 -50
  63. package/src/components/icon/Icon.d.ts +0 -23
  64. package/src/components/layout/Layout.d.ts +0 -44
  65. package/src/components/message/Message.d.ts +0 -28
  66. package/src/components/navmenulink/NavMenuLink.d.ts +0 -29
  67. package/src/components/navmenulink/NavMenuLink.vue +0 -49
  68. package/src/components/panelmenu/PanelMenu.d.ts +0 -26
  69. package/src/components/panelmenu/PanelMenu.vue +0 -101
  70. package/src/components/tabnavigation/TabNavigation.d.ts +0 -34
  71. package/src/components/tooltip/Tooltip.d.ts +0 -23
  72. package/src/ts-helpers.d.ts +0 -57
  73. /package/dist/{common → src/common}/appResult.d.ts +0 -0
  74. /package/dist/{components → src/components}/internal/cssClassBuilder.d.ts +0 -0
  75. /package/dist/{components → src/components}/internal/getMaxZindex.d.ts +0 -0
  76. /package/dist/{services → src/services}/authService.d.ts +0 -0
  77. /package/dist/{services → src/services}/dialogService.d.ts +0 -0
  78. /package/dist/{services → src/services}/navMenuService.d.ts +0 -0
package/src/keycloak.js CHANGED
@@ -1,7 +1,3 @@
1
- /** 04/09/2024
2
- * https://github.com/keycloak/keycloak/blob/main/js/libs/keycloak-js/src/keycloak.js
3
- */
4
-
5
1
  /*
6
2
  * Copyright 2016 Red Hat, Inc. and/or its affiliates
7
3
  * and other contributors as indicated by the @author tags.
@@ -19,2118 +15,1717 @@
19
15
  * limitations under the License.
20
16
  */
21
17
 
22
- import { sha256 } from "@noble/hashes/sha256";
23
- import { jwtDecode } from "jwt-decode";
18
+ /**
19
+ *
20
+ * 24/11/2023
21
+ *
22
+ * https://github.com/keycloak/keycloak/blob/main/js/libs/keycloak-js/src/keycloak.js
23
+ *
24
+ * Adaptado para expor setToken.
25
+ *
26
+ * Adpatado para usar URL absoluta em configUrl (linha 829). *
27
+ */
28
+
29
+ import base64 from 'base64-js';
30
+ import sha256 from 'js-sha256';
31
+ import { jwtDecode } from 'jwt-decode';
24
32
 
25
- if (typeof Promise === "undefined") {
26
- throw Error(
27
- "Keycloak requires an environment that supports Promises. Make sure that you include the appropriate polyfill."
28
- );
33
+ if (typeof Promise === 'undefined') {
34
+ throw Error('Keycloak requires an environment that supports Promises. Make sure that you include the appropriate polyfill.');
29
35
  }
30
36
 
31
- function Keycloak(config) {
32
- if (!(this instanceof Keycloak)) {
33
- throw new Error(
34
- "The 'Keycloak' constructor must be invoked with 'new'."
35
- );
36
- }
37
-
38
- var kc = this;
39
- var adapter;
40
- var refreshQueue = [];
41
- var callbackStorage;
42
-
43
- var loginIframe = {
44
- enable: true,
45
- callbackList: [],
46
- interval: 5,
47
- };
48
-
49
- kc.didInitialize = false;
50
-
51
- var scripts = document.getElementsByTagName("script");
52
- for (var i = 0; i < scripts.length; i++) {
53
- if (
54
- (scripts[i].src.indexOf("keycloak.js") !== -1 ||
55
- scripts[i].src.indexOf("keycloak.min.js") !== -1) &&
56
- scripts[i].src.indexOf("version=") !== -1
57
- ) {
58
- kc.iframeVersion = scripts[i].src
59
- .substring(scripts[i].src.indexOf("version=") + 8)
60
- .split("&")[0];
37
+ function Keycloak (config) {
38
+ if (!(this instanceof Keycloak)) {
39
+ throw new Error("The 'Keycloak' constructor must be invoked with 'new'.")
61
40
  }
62
- }
63
41
 
64
- var useNonce = true;
65
- var logInfo = createLogger(console.info);
66
- var logWarn = createLogger(console.warn);
42
+ var kc = this;
43
+ var adapter;
44
+ var refreshQueue = [];
45
+ var callbackStorage;
67
46
 
68
- kc.init = function (initOptions) {
69
- if (kc.didInitialize) {
70
- throw new Error(
71
- "A 'Keycloak' instance can only be initialized once."
72
- );
73
- }
47
+ var loginIframe = {
48
+ enable: true,
49
+ callbackList: [],
50
+ interval: 5
51
+ };
74
52
 
75
- kc.didInitialize = true;
76
-
77
- kc.authenticated = false;
78
-
79
- callbackStorage = createCallbackStorage();
80
- var adapters = ["default", "cordova", "cordova-native"];
81
-
82
- if (initOptions && adapters.indexOf(initOptions.adapter) > -1) {
83
- adapter = loadAdapter(initOptions.adapter);
84
- } else if (
85
- initOptions &&
86
- typeof initOptions.adapter === "object"
87
- ) {
88
- adapter = initOptions.adapter;
89
- } else {
90
- if (window.Cordova || window.cordova) {
91
- adapter = loadAdapter("cordova");
92
- } else {
93
- adapter = loadAdapter();
94
- }
53
+ var scripts = document.getElementsByTagName('script');
54
+ for (var i = 0; i < scripts.length; i++) {
55
+ if ((scripts[i].src.indexOf('keycloak.js') !== -1 || scripts[i].src.indexOf('keycloak.min.js') !== -1) && scripts[i].src.indexOf('version=') !== -1) {
56
+ kc.iframeVersion = scripts[i].src.substring(scripts[i].src.indexOf('version=') + 8).split('&')[0];
57
+ }
95
58
  }
96
59
 
97
- if (initOptions) {
98
- if (typeof initOptions.useNonce !== "undefined") {
99
- useNonce = initOptions.useNonce;
100
- }
101
-
102
- if (typeof initOptions.checkLoginIframe !== "undefined") {
103
- loginIframe.enable = initOptions.checkLoginIframe;
104
- }
105
-
106
- if (initOptions.checkLoginIframeInterval) {
107
- loginIframe.interval = initOptions.checkLoginIframeInterval;
108
- }
109
-
110
- if (initOptions.onLoad === "login-required") {
111
- kc.loginRequired = true;
112
- }
113
-
114
- if (initOptions.responseMode) {
115
- if (
116
- initOptions.responseMode === "query" ||
117
- initOptions.responseMode === "fragment"
118
- ) {
119
- kc.responseMode = initOptions.responseMode;
60
+ var useNonce = true;
61
+ var logInfo = createLogger(console.info);
62
+ var logWarn = createLogger(console.warn);
63
+
64
+ kc.init = function (initOptions) {
65
+ if (kc.didInitialize) {
66
+ throw new Error("A 'Keycloak' instance can only be initialized once.");
67
+ }
68
+
69
+ kc.didInitialize = true;
70
+
71
+ kc.authenticated = false;
72
+
73
+ callbackStorage = createCallbackStorage();
74
+ var adapters = ['default', 'cordova', 'cordova-native'];
75
+
76
+ if (initOptions && adapters.indexOf(initOptions.adapter) > -1) {
77
+ adapter = loadAdapter(initOptions.adapter);
78
+ } else if (initOptions && typeof initOptions.adapter === "object") {
79
+ adapter = initOptions.adapter;
120
80
  } else {
121
- throw "Invalid value for responseMode";
122
- }
123
- }
124
-
125
- if (initOptions.flow) {
126
- switch (initOptions.flow) {
127
- case "standard":
128
- kc.responseType = "code";
129
- break;
130
- case "implicit":
131
- kc.responseType = "id_token token";
132
- break;
133
- case "hybrid":
134
- kc.responseType = "code id_token token";
135
- break;
136
- default:
137
- throw "Invalid value for flow";
138
- }
139
- kc.flow = initOptions.flow;
140
- }
141
-
142
- if (initOptions.timeSkew != null) {
143
- kc.timeSkew = initOptions.timeSkew;
144
- }
145
-
146
- if (initOptions.redirectUri) {
147
- kc.redirectUri = initOptions.redirectUri;
148
- }
149
-
150
- if (initOptions.silentCheckSsoRedirectUri) {
151
- kc.silentCheckSsoRedirectUri =
152
- initOptions.silentCheckSsoRedirectUri;
153
- }
154
-
155
- if (typeof initOptions.silentCheckSsoFallback === "boolean") {
156
- kc.silentCheckSsoFallback =
157
- initOptions.silentCheckSsoFallback;
158
- } else {
159
- kc.silentCheckSsoFallback = true;
160
- }
161
-
162
- if (typeof initOptions.pkceMethod !== "undefined") {
163
- if (
164
- initOptions.pkceMethod !== "S256" &&
165
- initOptions.pkceMethod !== false
166
- ) {
167
- throw new TypeError(
168
- `Invalid value for pkceMethod', expected 'S256' or false but got ${initOptions.pkceMethod}.`
169
- );
170
- }
171
-
172
- kc.pkceMethod = initOptions.pkceMethod;
173
- } else {
174
- kc.pkceMethod = "S256";
175
- }
176
-
177
- if (typeof initOptions.enableLogging === "boolean") {
178
- kc.enableLogging = initOptions.enableLogging;
179
- } else {
180
- kc.enableLogging = false;
181
- }
182
-
183
- if (initOptions.logoutMethod === "POST") {
184
- kc.logoutMethod = "POST";
185
- } else {
186
- kc.logoutMethod = "GET";
187
- }
188
-
189
- if (typeof initOptions.scope === "string") {
190
- kc.scope = initOptions.scope;
191
- }
192
-
193
- if (typeof initOptions.acrValues === "string") {
194
- kc.acrValues = initOptions.acrValues;
195
- }
196
-
197
- if (
198
- typeof initOptions.messageReceiveTimeout === "number" &&
199
- initOptions.messageReceiveTimeout > 0
200
- ) {
201
- kc.messageReceiveTimeout = initOptions.messageReceiveTimeout;
202
- } else {
203
- kc.messageReceiveTimeout = 10000;
204
- }
205
- }
81
+ if (window.Cordova || window.cordova) {
82
+ adapter = loadAdapter('cordova');
83
+ } else {
84
+ adapter = loadAdapter();
85
+ }
86
+ }
206
87
 
207
- if (!kc.responseMode) {
208
- kc.responseMode = "fragment";
209
- }
210
- if (!kc.responseType) {
211
- kc.responseType = "code";
212
- kc.flow = "standard";
213
- }
88
+ if (initOptions) {
89
+ if (typeof initOptions.useNonce !== 'undefined') {
90
+ useNonce = initOptions.useNonce;
91
+ }
214
92
 
215
- var promise = createPromise();
93
+ if (typeof initOptions.checkLoginIframe !== 'undefined') {
94
+ loginIframe.enable = initOptions.checkLoginIframe;
95
+ }
216
96
 
217
- var initPromise = createPromise();
97
+ if (initOptions.checkLoginIframeInterval) {
98
+ loginIframe.interval = initOptions.checkLoginIframeInterval;
99
+ }
218
100
 
219
- initPromise.promise
220
- .then(function () {
221
- kc.onReady && kc.onReady(kc.authenticated);
222
- promise.setSuccess(kc.authenticated);
223
- })
224
- .catch(function (error) {
225
- promise.setError(error);
226
- });
101
+ if (initOptions.onLoad === 'login-required') {
102
+ kc.loginRequired = true;
103
+ }
227
104
 
228
- var configPromise = loadConfig(config);
105
+ if (initOptions.responseMode) {
106
+ if (initOptions.responseMode === 'query' || initOptions.responseMode === 'fragment') {
107
+ kc.responseMode = initOptions.responseMode;
108
+ } else {
109
+ throw 'Invalid value for responseMode';
110
+ }
111
+ }
229
112
 
230
- function onLoad() {
231
- var doLogin = function (prompt) {
232
- if (!prompt) {
233
- options.prompt = "none";
234
- }
113
+ if (initOptions.flow) {
114
+ switch (initOptions.flow) {
115
+ case 'standard':
116
+ kc.responseType = 'code';
117
+ break;
118
+ case 'implicit':
119
+ kc.responseType = 'id_token token';
120
+ break;
121
+ case 'hybrid':
122
+ kc.responseType = 'code id_token token';
123
+ break;
124
+ default:
125
+ throw 'Invalid value for flow';
126
+ }
127
+ kc.flow = initOptions.flow;
128
+ }
235
129
 
236
- if (initOptions && initOptions.locale) {
237
- options.locale = initOptions.locale;
238
- }
239
- kc.login(options)
240
- .then(function () {
241
- initPromise.setSuccess();
242
- })
243
- .catch(function (error) {
244
- initPromise.setError(error);
245
- });
246
- };
130
+ if (initOptions.timeSkew != null) {
131
+ kc.timeSkew = initOptions.timeSkew;
132
+ }
247
133
 
248
- var checkSsoSilently = function () {
249
- var ifrm = document.createElement("iframe");
134
+ if(initOptions.redirectUri) {
135
+ kc.redirectUri = initOptions.redirectUri;
136
+ }
250
137
 
251
- var src = kc.createLoginUrl({
252
- prompt: "none",
253
- redirectUri: kc.silentCheckSsoRedirectUri,
254
- });
138
+ if (initOptions.silentCheckSsoRedirectUri) {
139
+ kc.silentCheckSsoRedirectUri = initOptions.silentCheckSsoRedirectUri;
140
+ }
255
141
 
256
- ifrm.setAttribute("src", src);
142
+ if (typeof initOptions.silentCheckSsoFallback === 'boolean') {
143
+ kc.silentCheckSsoFallback = initOptions.silentCheckSsoFallback;
144
+ } else {
145
+ kc.silentCheckSsoFallback = true;
146
+ }
257
147
 
258
- ifrm.setAttribute(
259
- "sandbox",
260
- "allow-storage-access-by-user-activation allow-scripts allow-same-origin"
261
- );
148
+ if (initOptions.pkceMethod) {
149
+ if (initOptions.pkceMethod !== "S256") {
150
+ throw 'Invalid value for pkceMethod';
151
+ }
152
+ kc.pkceMethod = initOptions.pkceMethod;
153
+ }
262
154
 
263
- ifrm.setAttribute("title", "keycloak-silent-check-sso");
264
- ifrm.style.display = "none";
265
- document.body.appendChild(ifrm);
155
+ if (typeof initOptions.enableLogging === 'boolean') {
156
+ kc.enableLogging = initOptions.enableLogging;
157
+ } else {
158
+ kc.enableLogging = false;
159
+ }
266
160
 
267
- var messageCallback = function (event) {
268
- if (
269
- event.origin !== window.location.origin ||
270
- ifrm.contentWindow !== event.source
271
- ) {
272
- return;
273
- }
161
+ if (typeof initOptions.scope === 'string') {
162
+ kc.scope = initOptions.scope;
163
+ }
274
164
 
275
- var oauth = parseCallback(event.data);
276
- processCallback(oauth, initPromise);
165
+ if (typeof initOptions.acrValues === 'string') {
166
+ kc.acrValues = initOptions.acrValues;
167
+ }
277
168
 
278
- document.body.removeChild(ifrm);
279
- window.removeEventListener("message", messageCallback);
280
- };
169
+ if (typeof initOptions.messageReceiveTimeout === 'number' && initOptions.messageReceiveTimeout > 0) {
170
+ kc.messageReceiveTimeout = initOptions.messageReceiveTimeout;
171
+ } else {
172
+ kc.messageReceiveTimeout = 10000;
173
+ }
174
+ }
175
+
176
+ if (!kc.responseMode) {
177
+ kc.responseMode = 'fragment';
178
+ }
179
+ if (!kc.responseType) {
180
+ kc.responseType = 'code';
181
+ kc.flow = 'standard';
182
+ }
183
+
184
+ var promise = createPromise();
185
+
186
+ var initPromise = createPromise();
187
+ initPromise.promise.then(function() {
188
+ kc.onReady && kc.onReady(kc.authenticated);
189
+ promise.setSuccess(kc.authenticated);
190
+ }).catch(function(error) {
191
+ promise.setError(error);
192
+ });
193
+
194
+ var configPromise = loadConfig(config);
195
+
196
+ function onLoad() {
197
+ var doLogin = function(prompt) {
198
+ if (!prompt) {
199
+ options.prompt = 'none';
200
+ }
281
201
 
282
- window.addEventListener("message", messageCallback);
283
- };
284
-
285
- var options = {};
286
- switch (initOptions.onLoad) {
287
- case "check-sso":
288
- if (loginIframe.enable) {
289
- setupCheckLoginIframe().then(function () {
290
- checkLoginIframe()
291
- .then(function (unchanged) {
292
- if (!unchanged) {
293
- kc.silentCheckSsoRedirectUri
294
- ? checkSsoSilently()
295
- : doLogin(false);
296
- } else {
202
+ if (initOptions && initOptions.locale) {
203
+ options.locale = initOptions.locale;
204
+ }
205
+ kc.login(options).then(function () {
297
206
  initPromise.setSuccess();
298
- }
299
- })
300
- .catch(function (error) {
301
- initPromise.setError(error);
207
+ }).catch(function (error) {
208
+ initPromise.setError(error);
302
209
  });
303
- });
304
- } else {
305
- kc.silentCheckSsoRedirectUri
306
- ? checkSsoSilently()
307
- : doLogin(false);
308
- }
309
- break;
310
- case "login-required":
311
- doLogin(true);
312
- break;
313
- default:
314
- throw "Invalid value for onLoad";
315
- }
316
- }
210
+ }
317
211
 
318
- function processInit() {
319
- var callback = parseCallback(window.location.href);
320
-
321
- if (callback) {
322
- window.history.replaceState(
323
- window.history.state,
324
- null,
325
- callback.newUrl
326
- );
327
- }
328
-
329
- if (callback && callback.valid) {
330
- return setupCheckLoginIframe()
331
- .then(function () {
332
- processCallback(callback, initPromise);
333
- })
334
- .catch(function (error) {
335
- initPromise.setError(error);
336
- });
337
- } else if (initOptions) {
338
- if (initOptions.token && initOptions.refreshToken) {
339
- setToken(
340
- initOptions.token,
341
- initOptions.refreshToken,
342
- initOptions.idToken
343
- );
344
-
345
- if (loginIframe.enable) {
346
- setupCheckLoginIframe().then(function () {
347
- checkLoginIframe()
348
- .then(function (unchanged) {
349
- if (unchanged) {
350
- kc.onAuthSuccess && kc.onAuthSuccess();
351
- initPromise.setSuccess();
352
- scheduleCheckIframe();
353
- } else {
354
- initPromise.setSuccess();
355
- }
356
- })
357
- .catch(function (error) {
358
- initPromise.setError(error);
212
+ var checkSsoSilently = function() {
213
+ var ifrm = document.createElement("iframe");
214
+ var src = kc.createLoginUrl({prompt: 'none', redirectUri: kc.silentCheckSsoRedirectUri});
215
+ ifrm.setAttribute("src", src);
216
+ ifrm.setAttribute("sandbox", "allow-scripts allow-same-origin");
217
+ ifrm.setAttribute("title", "keycloak-silent-check-sso");
218
+ ifrm.style.display = "none";
219
+ document.body.appendChild(ifrm);
220
+
221
+ var messageCallback = function(event) {
222
+ if (event.origin !== window.location.origin || ifrm.contentWindow !== event.source) {
223
+ return;
224
+ }
225
+
226
+ var oauth = parseCallback(event.data);
227
+ processCallback(oauth, initPromise);
228
+
229
+ document.body.removeChild(ifrm);
230
+ window.removeEventListener("message", messageCallback);
231
+ };
232
+
233
+ window.addEventListener("message", messageCallback);
234
+ };
235
+
236
+ var options = {};
237
+ switch (initOptions.onLoad) {
238
+ case 'check-sso':
239
+ if (loginIframe.enable) {
240
+ setupCheckLoginIframe().then(function() {
241
+ checkLoginIframe().then(function (unchanged) {
242
+ if (!unchanged) {
243
+ kc.silentCheckSsoRedirectUri ? checkSsoSilently() : doLogin(false);
244
+ } else {
245
+ initPromise.setSuccess();
246
+ }
247
+ }).catch(function (error) {
248
+ initPromise.setError(error);
249
+ });
250
+ });
251
+ } else {
252
+ kc.silentCheckSsoRedirectUri ? checkSsoSilently() : doLogin(false);
253
+ }
254
+ break;
255
+ case 'login-required':
256
+ doLogin(true);
257
+ break;
258
+ default:
259
+ throw 'Invalid value for onLoad';
260
+ }
261
+ }
262
+
263
+ function processInit() {
264
+ var callback = parseCallback(window.location.href);
265
+
266
+ if (callback) {
267
+ window.history.replaceState(window.history.state, null, callback.newUrl);
268
+ }
269
+
270
+ if (callback && callback.valid) {
271
+ return setupCheckLoginIframe().then(function() {
272
+ processCallback(callback, initPromise);
273
+ }).catch(function (error) {
274
+ initPromise.setError(error);
359
275
  });
360
- });
361
- } else {
362
- kc.updateToken(-1)
363
- .then(function () {
364
- kc.onAuthSuccess && kc.onAuthSuccess();
365
- initPromise.setSuccess();
366
- })
367
- .catch(function (error) {
368
- kc.onAuthError && kc.onAuthError();
369
- if (initOptions.onLoad) {
370
- onLoad();
276
+ } else if (initOptions) {
277
+ if (initOptions.token && initOptions.refreshToken) {
278
+ setToken(initOptions.token, initOptions.refreshToken, initOptions.idToken);
279
+
280
+ if (loginIframe.enable) {
281
+ setupCheckLoginIframe().then(function() {
282
+ checkLoginIframe().then(function (unchanged) {
283
+ if (unchanged) {
284
+ kc.onAuthSuccess && kc.onAuthSuccess();
285
+ initPromise.setSuccess();
286
+ scheduleCheckIframe();
287
+ } else {
288
+ initPromise.setSuccess();
289
+ }
290
+ }).catch(function (error) {
291
+ initPromise.setError(error);
292
+ });
293
+ });
294
+ } else {
295
+ kc.updateToken(-1).then(function() {
296
+ kc.onAuthSuccess && kc.onAuthSuccess();
297
+ initPromise.setSuccess();
298
+ }).catch(function(error) {
299
+ kc.onAuthError && kc.onAuthError();
300
+ if (initOptions.onLoad) {
301
+ onLoad();
302
+ } else {
303
+ initPromise.setError(error);
304
+ }
305
+ });
306
+ }
307
+ } else if (initOptions.onLoad) {
308
+ onLoad();
371
309
  } else {
372
- initPromise.setError(error);
310
+ initPromise.setSuccess();
373
311
  }
374
- });
375
- }
376
- } else if (initOptions.onLoad) {
377
- onLoad();
378
- } else {
379
- initPromise.setSuccess();
312
+ } else {
313
+ initPromise.setSuccess();
314
+ }
380
315
  }
381
- } else {
382
- initPromise.setSuccess();
383
- }
384
- }
385
316
 
386
- function domReady() {
387
- var promise = createPromise();
317
+ function domReady() {
318
+ var promise = createPromise();
319
+
320
+ var checkReadyState = function () {
321
+ if (document.readyState === 'interactive' || document.readyState === 'complete') {
322
+ document.removeEventListener('readystatechange', checkReadyState);
323
+ promise.setSuccess();
324
+ }
325
+ }
326
+ document.addEventListener('readystatechange', checkReadyState);
388
327
 
389
- var checkReadyState = function () {
390
- if (
391
- document.readyState === "interactive" ||
392
- document.readyState === "complete"
393
- ) {
394
- document.removeEventListener(
395
- "readystatechange",
396
- checkReadyState
397
- );
328
+ checkReadyState(); // just in case the event was already fired and we missed it (in case the init is done later than at the load time, i.e. it's done from code)
398
329
 
399
- promise.setSuccess();
330
+ return promise.promise;
400
331
  }
401
- };
402
332
 
403
- document.addEventListener("readystatechange", checkReadyState);
333
+ configPromise.then(function () {
334
+ domReady()
335
+ .then(check3pCookiesSupported)
336
+ .then(processInit)
337
+ .catch(function (error) {
338
+ promise.setError(error);
339
+ });
340
+ });
341
+ configPromise.catch(function (error) {
342
+ promise.setError(error);
343
+ });
404
344
 
405
- checkReadyState(); // just in case the event was already fired and we missed it (in case the init is done later than at the load time, i.e. it's done from code)
345
+ return promise.promise;
346
+ }
406
347
 
407
- return promise.promise;
348
+ kc.login = function (options) {
349
+ return adapter.login(options);
408
350
  }
409
351
 
410
- configPromise.then(function () {
411
- domReady()
412
- .then(check3pCookiesSupported)
413
- .then(processInit)
414
- .catch(function (error) {
415
- promise.setError(error);
416
- });
417
- });
418
- configPromise.catch(function (error) {
419
- promise.setError(error);
420
- });
421
-
422
- return promise.promise;
423
- };
424
-
425
- kc.login = function (options) {
426
- return adapter.login(options);
427
- };
428
-
429
- function generateRandomData(len) {
430
- // use web crypto APIs if possible
431
- var array = null;
432
- var crypto = window.crypto || window.msCrypto;
433
- if (crypto && crypto.getRandomValues && window.Uint8Array) {
434
- array = new Uint8Array(len);
435
- crypto.getRandomValues(array);
436
- return array;
352
+ function generateRandomData(len) {
353
+ // use web crypto APIs if possible
354
+ var array = null;
355
+ var crypto = window.crypto || window.msCrypto;
356
+ if (crypto && crypto.getRandomValues && window.Uint8Array) {
357
+ array = new Uint8Array(len);
358
+ crypto.getRandomValues(array);
359
+ return array;
360
+ }
361
+
362
+ // fallback to Math random
363
+ array = new Array(len);
364
+ for (var j = 0; j < array.length; j++) {
365
+ array[j] = Math.floor(256 * Math.random());
366
+ }
367
+ return array;
437
368
  }
438
369
 
439
- // fallback to Math random
440
- array = new Array(len);
441
- for (var j = 0; j < array.length; j++) {
442
- array[j] = Math.floor(256 * Math.random());
370
+ function generateCodeVerifier(len) {
371
+ return generateRandomString(len, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
443
372
  }
444
- return array;
445
- }
446
-
447
- function generateCodeVerifier(len) {
448
- return generateRandomString(
449
- len,
450
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
451
- );
452
- }
453
-
454
- function generateRandomString(len, alphabet) {
455
- var randomData = generateRandomData(len);
456
- var chars = new Array(len);
457
- for (var i = 0; i < len; i++) {
458
- chars[i] = alphabet.charCodeAt(randomData[i] % alphabet.length);
373
+
374
+ function generateRandomString(len, alphabet){
375
+ var randomData = generateRandomData(len);
376
+ var chars = new Array(len);
377
+ for (var i = 0; i < len; i++) {
378
+ chars[i] = alphabet.charCodeAt(randomData[i] % alphabet.length);
379
+ }
380
+ return String.fromCharCode.apply(null, chars);
381
+ }
382
+
383
+ function generatePkceChallenge(pkceMethod, codeVerifier) {
384
+ switch (pkceMethod) {
385
+ // The use of the "plain" method is considered insecure and therefore not supported.
386
+ case "S256":
387
+ // hash codeVerifier, then encode as url-safe base64 without padding
388
+ var hashBytes = new Uint8Array(sha256.arrayBuffer(codeVerifier));
389
+ var encodedHash = base64.fromByteArray(hashBytes)
390
+ .replace(/\+/g, '-')
391
+ .replace(/\//g, '_')
392
+ .replace(/\=/g, '');
393
+ return encodedHash;
394
+ default:
395
+ throw 'Invalid value for pkceMethod';
396
+ }
459
397
  }
460
- return String.fromCharCode.apply(null, chars);
461
- }
462
-
463
- function generatePkceChallenge(pkceMethod, codeVerifier) {
464
- if (pkceMethod !== "S256") {
465
- throw new TypeError(
466
- `Invalid value for 'pkceMethod', expected 'S256' but got '${pkceMethod}'.`
467
- );
398
+
399
+ function buildClaimsParameter(requestedAcr){
400
+ var claims = {
401
+ id_token: {
402
+ acr: requestedAcr
403
+ }
404
+ }
405
+ return JSON.stringify(claims);
468
406
  }
469
407
 
470
- // hash codeVerifier, then encode as url-safe base64 without padding
471
- const hashBytes = sha256(codeVerifier);
472
- const encodedHash = bytesToBase64(hashBytes)
473
- .replace(/\+/g, "-")
474
- .replace(/\//g, "_")
475
- .replace(/\=/g, "");
476
-
477
- return encodedHash;
478
- }
479
-
480
- function buildClaimsParameter(requestedAcr) {
481
- var claims = {
482
- id_token: {
483
- acr: requestedAcr,
484
- },
485
- };
486
- return JSON.stringify(claims);
487
- }
408
+ kc.createLoginUrl = function(options) {
409
+ var state = createUUID();
410
+ var nonce = createUUID();
488
411
 
489
- kc.createLoginUrl = function (options) {
490
- var state = createUUID();
491
- var nonce = createUUID();
412
+ var redirectUri = adapter.redirectUri(options);
492
413
 
493
- var redirectUri = adapter.redirectUri(options);
414
+ var callbackState = {
415
+ state: state,
416
+ nonce: nonce,
417
+ redirectUri: encodeURIComponent(redirectUri)
418
+ };
494
419
 
495
- var callbackState = {
496
- state: state,
497
- nonce: nonce,
498
- redirectUri: encodeURIComponent(redirectUri),
499
- loginOptions: options,
500
- };
420
+ if (options && options.prompt) {
421
+ callbackState.prompt = options.prompt;
422
+ }
501
423
 
502
- if (options && options.prompt) {
503
- callbackState.prompt = options.prompt;
504
- }
424
+ var baseUrl;
425
+ if (options && options.action == 'register') {
426
+ baseUrl = kc.endpoints.register();
427
+ } else {
428
+ baseUrl = kc.endpoints.authorize();
429
+ }
505
430
 
506
- var baseUrl;
507
- if (options && options.action == "register") {
508
- baseUrl = kc.endpoints.register();
509
- } else {
510
- baseUrl = kc.endpoints.authorize();
511
- }
431
+ var scope = options && options.scope || kc.scope;
432
+ if (!scope) {
433
+ // if scope is not set, default to "openid"
434
+ scope = "openid";
435
+ } else if (scope.indexOf("openid") === -1) {
436
+ // if openid scope is missing, prefix the given scopes with it
437
+ scope = "openid " + scope;
438
+ }
512
439
 
513
- var scope = (options && options.scope) || kc.scope;
514
- if (!scope) {
515
- // if scope is not set, default to "openid"
516
- scope = "openid";
517
- } else if (scope.indexOf("openid") === -1) {
518
- // if openid scope is missing, prefix the given scopes with it
519
- scope = "openid " + scope;
520
- }
440
+ var url = baseUrl
441
+ + '?client_id=' + encodeURIComponent(kc.clientId)
442
+ + '&redirect_uri=' + encodeURIComponent(redirectUri)
443
+ + '&state=' + encodeURIComponent(state)
444
+ + '&response_mode=' + encodeURIComponent(kc.responseMode)
445
+ + '&response_type=' + encodeURIComponent(kc.responseType)
446
+ + '&scope=' + encodeURIComponent(scope);
447
+ if (useNonce) {
448
+ url = url + '&nonce=' + encodeURIComponent(nonce);
449
+ }
521
450
 
522
- var url =
523
- baseUrl +
524
- "?client_id=" +
525
- encodeURIComponent(kc.clientId) +
526
- "&redirect_uri=" +
527
- encodeURIComponent(redirectUri) +
528
- "&state=" +
529
- encodeURIComponent(state) +
530
- "&response_mode=" +
531
- encodeURIComponent(kc.responseMode) +
532
- "&response_type=" +
533
- encodeURIComponent(kc.responseType) +
534
- "&scope=" +
535
- encodeURIComponent(scope);
536
- if (useNonce) {
537
- url = url + "&nonce=" + encodeURIComponent(nonce);
538
- }
451
+ if (options && options.prompt) {
452
+ url += '&prompt=' + encodeURIComponent(options.prompt);
453
+ }
539
454
 
540
- if (options && options.prompt) {
541
- url += "&prompt=" + encodeURIComponent(options.prompt);
542
- }
455
+ if (options && options.maxAge) {
456
+ url += '&max_age=' + encodeURIComponent(options.maxAge);
457
+ }
458
+
459
+ if (options && options.loginHint) {
460
+ url += '&login_hint=' + encodeURIComponent(options.loginHint);
461
+ }
462
+
463
+ if (options && options.idpHint) {
464
+ url += '&kc_idp_hint=' + encodeURIComponent(options.idpHint);
465
+ }
466
+
467
+ if (options && options.action && options.action != 'register') {
468
+ url += '&kc_action=' + encodeURIComponent(options.action);
469
+ }
543
470
 
544
- if (options && options.maxAge) {
545
- url += "&max_age=" + encodeURIComponent(options.maxAge);
471
+ if (options && options.locale) {
472
+ url += '&ui_locales=' + encodeURIComponent(options.locale);
473
+ }
474
+
475
+ if (options && options.acr) {
476
+ var claimsParameter = buildClaimsParameter(options.acr);
477
+ url += '&claims=' + encodeURIComponent(claimsParameter);
478
+ }
479
+
480
+ if ((options && options.acrValues) || kc.acrValues) {
481
+ url += '&acr_values=' + encodeURIComponent(options.acrValues || kc.acrValues);
482
+ }
483
+
484
+ if (kc.pkceMethod) {
485
+ var codeVerifier = generateCodeVerifier(96);
486
+ callbackState.pkceCodeVerifier = codeVerifier;
487
+ var pkceChallenge = generatePkceChallenge(kc.pkceMethod, codeVerifier);
488
+ url += '&code_challenge=' + pkceChallenge;
489
+ url += '&code_challenge_method=' + kc.pkceMethod;
490
+ }
491
+
492
+ callbackStorage.add(callbackState);
493
+
494
+ return url;
546
495
  }
547
496
 
548
- if (options && options.loginHint) {
549
- url += "&login_hint=" + encodeURIComponent(options.loginHint);
497
+ kc.logout = function(options) {
498
+ return adapter.logout(options);
550
499
  }
551
500
 
552
- if (options && options.idpHint) {
553
- url += "&kc_idp_hint=" + encodeURIComponent(options.idpHint);
501
+ kc.createLogoutUrl = function(options) {
502
+ var url = kc.endpoints.logout()
503
+ + '?client_id=' + encodeURIComponent(kc.clientId)
504
+ + '&post_logout_redirect_uri=' + encodeURIComponent(adapter.redirectUri(options, false));
505
+
506
+ if (kc.idToken) {
507
+ url += '&id_token_hint=' + encodeURIComponent(kc.idToken);
508
+ }
509
+
510
+ return url;
554
511
  }
555
512
 
556
- if (options && options.action && options.action != "register") {
557
- url += "&kc_action=" + encodeURIComponent(options.action);
513
+ kc.register = function (options) {
514
+ return adapter.register(options);
558
515
  }
559
516
 
560
- if (options && options.locale) {
561
- url += "&ui_locales=" + encodeURIComponent(options.locale);
517
+ kc.createRegisterUrl = function(options) {
518
+ if (!options) {
519
+ options = {};
520
+ }
521
+ options.action = 'register';
522
+ return kc.createLoginUrl(options);
523
+ }
524
+
525
+ kc.createAccountUrl = function(options) {
526
+ var realm = getRealmUrl();
527
+ var url = undefined;
528
+ if (typeof realm !== 'undefined') {
529
+ url = realm
530
+ + '/account'
531
+ + '?referrer=' + encodeURIComponent(kc.clientId)
532
+ + '&referrer_uri=' + encodeURIComponent(adapter.redirectUri(options));
533
+ }
534
+ return url;
562
535
  }
563
536
 
564
- if (options && options.acr) {
565
- var claimsParameter = buildClaimsParameter(options.acr);
566
- url += "&claims=" + encodeURIComponent(claimsParameter);
537
+ kc.accountManagement = function() {
538
+ return adapter.accountManagement();
567
539
  }
568
540
 
569
- if ((options && options.acrValues) || kc.acrValues) {
570
- url +=
571
- "&acr_values=" +
572
- encodeURIComponent(options.acrValues || kc.acrValues);
541
+ kc.hasRealmRole = function (role) {
542
+ var access = kc.realmAccess;
543
+ return !!access && access.roles.indexOf(role) >= 0;
573
544
  }
574
545
 
575
- if (kc.pkceMethod) {
576
- var codeVerifier = generateCodeVerifier(96);
577
- callbackState.pkceCodeVerifier = codeVerifier;
578
- var pkceChallenge = generatePkceChallenge(
579
- kc.pkceMethod,
580
- codeVerifier
581
- );
546
+ kc.hasResourceRole = function(role, resource) {
547
+ if (!kc.resourceAccess) {
548
+ return false;
549
+ }
582
550
 
583
- url += "&code_challenge=" + pkceChallenge;
584
- url += "&code_challenge_method=" + kc.pkceMethod;
551
+ var access = kc.resourceAccess[resource || kc.clientId];
552
+ return !!access && access.roles.indexOf(role) >= 0;
585
553
  }
586
554
 
587
- callbackStorage.add(callbackState);
555
+ kc.loadUserProfile = function() {
556
+ var url = getRealmUrl() + '/account';
557
+ var req = new XMLHttpRequest();
558
+ req.open('GET', url, true);
559
+ req.setRequestHeader('Accept', 'application/json');
560
+ req.setRequestHeader('Authorization', 'bearer ' + kc.token);
588
561
 
589
- return url;
590
- };
562
+ var promise = createPromise();
563
+
564
+ req.onreadystatechange = function () {
565
+ if (req.readyState == 4) {
566
+ if (req.status == 200) {
567
+ kc.profile = JSON.parse(req.responseText);
568
+ promise.setSuccess(kc.profile);
569
+ } else {
570
+ promise.setError();
571
+ }
572
+ }
573
+ }
591
574
 
592
- kc.logout = function (options) {
593
- return adapter.logout(options);
594
- };
575
+ req.send();
595
576
 
596
- kc.createLogoutUrl = function (options) {
597
- const logoutMethod = options?.logoutMethod ?? kc.logoutMethod;
598
- if (logoutMethod === "POST") {
599
- return kc.endpoints.logout();
577
+ return promise.promise;
600
578
  }
601
579
 
602
- var url =
603
- kc.endpoints.logout() +
604
- "?client_id=" +
605
- encodeURIComponent(kc.clientId) +
606
- "&post_logout_redirect_uri=" +
607
- encodeURIComponent(adapter.redirectUri(options, false));
580
+ kc.loadUserInfo = function() {
581
+ var url = kc.endpoints.userinfo();
582
+ var req = new XMLHttpRequest();
583
+ req.open('GET', url, true);
584
+ req.setRequestHeader('Accept', 'application/json');
585
+ req.setRequestHeader('Authorization', 'bearer ' + kc.token);
608
586
 
609
- if (kc.idToken) {
610
- url += "&id_token_hint=" + encodeURIComponent(kc.idToken);
611
- }
587
+ var promise = createPromise();
612
588
 
613
- return url;
614
- };
589
+ req.onreadystatechange = function () {
590
+ if (req.readyState == 4) {
591
+ if (req.status == 200) {
592
+ kc.userInfo = JSON.parse(req.responseText);
593
+ promise.setSuccess(kc.userInfo);
594
+ } else {
595
+ promise.setError();
596
+ }
597
+ }
598
+ }
615
599
 
616
- kc.register = function (options) {
617
- return adapter.register(options);
618
- };
600
+ req.send();
619
601
 
620
- kc.createRegisterUrl = function (options) {
621
- if (!options) {
622
- options = {};
602
+ return promise.promise;
623
603
  }
624
- options.action = "register";
625
- return kc.createLoginUrl(options);
626
- };
627
-
628
- kc.createAccountUrl = function (options) {
629
- var realm = getRealmUrl();
630
- var url = undefined;
631
- if (typeof realm !== "undefined") {
632
- url =
633
- realm +
634
- "/account" +
635
- "?referrer=" +
636
- encodeURIComponent(kc.clientId) +
637
- "&referrer_uri=" +
638
- encodeURIComponent(adapter.redirectUri(options));
639
- }
640
- return url;
641
- };
642
604
 
643
- kc.accountManagement = function () {
644
- return adapter.accountManagement();
645
- };
605
+ kc.isTokenExpired = function(minValidity) {
606
+ if (!kc.tokenParsed || (!kc.refreshToken && kc.flow != 'implicit' )) {
607
+ throw 'Not authenticated';
608
+ }
646
609
 
647
- kc.hasRealmRole = function (role) {
648
- var access = kc.realmAccess;
649
- return !!access && access.roles.indexOf(role) >= 0;
650
- };
610
+ if (kc.timeSkew == null) {
611
+ logInfo('[KEYCLOAK] Unable to determine if token is expired as timeskew is not set');
612
+ return true;
613
+ }
651
614
 
652
- kc.hasResourceRole = function (role, resource) {
653
- if (!kc.resourceAccess) {
654
- return false;
615
+ var expiresIn = kc.tokenParsed['exp'] - Math.ceil(new Date().getTime() / 1000) + kc.timeSkew;
616
+ if (minValidity) {
617
+ if (isNaN(minValidity)) {
618
+ throw 'Invalid minValidity';
619
+ }
620
+ expiresIn -= minValidity;
621
+ }
622
+ return expiresIn < 0;
655
623
  }
656
624
 
657
- var access = kc.resourceAccess[resource || kc.clientId];
658
- return !!access && access.roles.indexOf(role) >= 0;
659
- };
625
+ kc.updateToken = function(minValidity) {
626
+ var promise = createPromise();
660
627
 
661
- kc.loadUserProfile = function () {
662
- var url = getRealmUrl() + "/account";
663
- var req = new XMLHttpRequest();
664
- req.open("GET", url, true);
665
- req.setRequestHeader("Accept", "application/json");
666
- req.setRequestHeader("Authorization", "bearer " + kc.token);
628
+ if (!kc.refreshToken) {
629
+ promise.setError();
630
+ return promise.promise;
631
+ }
667
632
 
668
- var promise = createPromise();
633
+ minValidity = minValidity || 5;
669
634
 
670
- req.onreadystatechange = function () {
671
- if (req.readyState == 4) {
672
- if (req.status == 200) {
673
- kc.profile = JSON.parse(req.responseText);
674
- promise.setSuccess(kc.profile);
675
- } else {
676
- promise.setError();
677
- }
678
- }
679
- };
635
+ var exec = function() {
636
+ var refreshToken = false;
637
+ if (minValidity == -1) {
638
+ refreshToken = true;
639
+ logInfo('[KEYCLOAK] Refreshing token: forced refresh');
640
+ } else if (!kc.tokenParsed || kc.isTokenExpired(minValidity)) {
641
+ refreshToken = true;
642
+ logInfo('[KEYCLOAK] Refreshing token: token expired');
643
+ }
680
644
 
681
- req.send();
645
+ if (!refreshToken) {
646
+ promise.setSuccess(false);
647
+ } else {
648
+ var params = 'grant_type=refresh_token&' + 'refresh_token=' + kc.refreshToken;
649
+ var url = kc.endpoints.token();
682
650
 
683
- return promise.promise;
684
- };
651
+ refreshQueue.push(promise);
685
652
 
686
- kc.loadUserInfo = function () {
687
- var url = kc.endpoints.userinfo();
688
- var req = new XMLHttpRequest();
689
- req.open("GET", url, true);
690
- req.setRequestHeader("Accept", "application/json");
691
- req.setRequestHeader("Authorization", "bearer " + kc.token);
653
+ if (refreshQueue.length == 1) {
654
+ var req = new XMLHttpRequest();
655
+ req.open('POST', url, true);
656
+ req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
657
+ req.withCredentials = true;
692
658
 
693
- var promise = createPromise();
659
+ params += '&client_id=' + encodeURIComponent(kc.clientId);
694
660
 
695
- req.onreadystatechange = function () {
696
- if (req.readyState == 4) {
697
- if (req.status == 200) {
698
- kc.userInfo = JSON.parse(req.responseText);
699
- promise.setSuccess(kc.userInfo);
700
- } else {
701
- promise.setError();
702
- }
703
- }
704
- };
661
+ var timeLocal = new Date().getTime();
705
662
 
706
- req.send();
663
+ req.onreadystatechange = function () {
664
+ if (req.readyState == 4) {
665
+ if (req.status == 200) {
666
+ logInfo('[KEYCLOAK] Token refreshed');
707
667
 
708
- return promise.promise;
709
- };
668
+ timeLocal = (timeLocal + new Date().getTime()) / 2;
710
669
 
711
- kc.isTokenExpired = function (minValidity) {
712
- if (
713
- !kc.tokenParsed ||
714
- (!kc.refreshToken && kc.flow != "implicit")
715
- ) {
716
- throw "Not authenticated";
717
- }
670
+ var tokenResponse = JSON.parse(req.responseText);
718
671
 
719
- if (kc.timeSkew == null) {
720
- logInfo(
721
- "[KEYCLOAK] Unable to determine if token is expired as timeskew is not set"
722
- );
672
+ setToken(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token'], timeLocal);
723
673
 
724
- return true;
725
- }
674
+ kc.onAuthRefreshSuccess && kc.onAuthRefreshSuccess();
675
+ for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) {
676
+ p.setSuccess(true);
677
+ }
678
+ } else {
679
+ logWarn('[KEYCLOAK] Failed to refresh token');
680
+
681
+ if (req.status == 400) {
682
+ kc.clearToken();
683
+ }
684
+
685
+ kc.onAuthRefreshError && kc.onAuthRefreshError();
686
+ for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) {
687
+ p.setError(true);
688
+ }
689
+ }
690
+ }
691
+ };
692
+
693
+ req.send(params);
694
+ }
695
+ }
696
+ }
697
+
698
+ if (loginIframe.enable) {
699
+ var iframePromise = checkLoginIframe();
700
+ iframePromise.then(function() {
701
+ exec();
702
+ }).catch(function(error) {
703
+ promise.setError(error);
704
+ });
705
+ } else {
706
+ exec();
707
+ }
726
708
 
727
- var expiresIn =
728
- kc.tokenParsed["exp"] -
729
- Math.ceil(new Date().getTime() / 1000) +
730
- kc.timeSkew;
709
+ return promise.promise;
710
+ }
731
711
 
732
- if (minValidity) {
733
- if (isNaN(minValidity)) {
734
- throw "Invalid minValidity";
735
- }
736
- expiresIn -= minValidity;
712
+ kc.clearToken = function() {
713
+ if (kc.token) {
714
+ setToken(null, null, null);
715
+ kc.onAuthLogout && kc.onAuthLogout();
716
+ if (kc.loginRequired) {
717
+ kc.login();
718
+ }
719
+ }
737
720
  }
738
- return expiresIn < 0;
739
- };
740
721
 
741
- kc.updateToken = function (minValidity) {
742
- var promise = createPromise();
722
+ kc.setToken = setToken;
723
+
724
+ function getRealmUrl() {
725
+ if (typeof kc.authServerUrl !== 'undefined') {
726
+ if (kc.authServerUrl.charAt(kc.authServerUrl.length - 1) == '/') {
727
+ return kc.authServerUrl + 'realms/' + encodeURIComponent(kc.realm);
728
+ } else {
729
+ return kc.authServerUrl + '/realms/' + encodeURIComponent(kc.realm);
730
+ }
731
+ } else {
732
+ return undefined;
733
+ }
734
+ }
743
735
 
744
- if (!kc.refreshToken) {
745
- promise.setError();
746
- return promise.promise;
736
+ function getOrigin() {
737
+ if (!window.location.origin) {
738
+ return window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
739
+ } else {
740
+ return window.location.origin;
741
+ }
747
742
  }
748
743
 
749
- minValidity = minValidity || 5;
744
+ function processCallback(oauth, promise) {
745
+ var code = oauth.code;
746
+ var error = oauth.error;
747
+ var prompt = oauth.prompt;
750
748
 
751
- var exec = function () {
752
- var refreshToken = false;
753
- if (minValidity == -1) {
754
- refreshToken = true;
755
- logInfo("[KEYCLOAK] Refreshing token: forced refresh");
756
- } else if (!kc.tokenParsed || kc.isTokenExpired(minValidity)) {
757
- refreshToken = true;
758
- logInfo("[KEYCLOAK] Refreshing token: token expired");
759
- }
749
+ var timeLocal = new Date().getTime();
760
750
 
761
- if (!refreshToken) {
762
- promise.setSuccess(false);
763
- } else {
764
- var params =
765
- "grant_type=refresh_token&" +
766
- "refresh_token=" +
767
- kc.refreshToken;
751
+ if (oauth['kc_action_status']) {
752
+ kc.onActionUpdate && kc.onActionUpdate(oauth['kc_action_status']);
753
+ }
768
754
 
769
- var url = kc.endpoints.token();
755
+ if (error) {
756
+ if (prompt != 'none') {
757
+ var errorData = { error: error, error_description: oauth.error_description };
758
+ kc.onAuthError && kc.onAuthError(errorData);
759
+ promise && promise.setError(errorData);
760
+ } else {
761
+ promise && promise.setSuccess();
762
+ }
763
+ return;
764
+ } else if ((kc.flow != 'standard') && (oauth.access_token || oauth.id_token)) {
765
+ authSuccess(oauth.access_token, null, oauth.id_token, true);
766
+ }
770
767
 
771
- refreshQueue.push(promise);
768
+ if ((kc.flow != 'implicit') && code) {
769
+ var params = 'code=' + code + '&grant_type=authorization_code';
770
+ var url = kc.endpoints.token();
772
771
 
773
- if (refreshQueue.length == 1) {
774
- var req = new XMLHttpRequest();
775
- req.open("POST", url, true);
772
+ var req = new XMLHttpRequest();
773
+ req.open('POST', url, true);
774
+ req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
776
775
 
777
- req.setRequestHeader(
778
- "Content-type",
779
- "application/x-www-form-urlencoded"
780
- );
776
+ params += '&client_id=' + encodeURIComponent(kc.clientId);
777
+ params += '&redirect_uri=' + oauth.redirectUri;
781
778
 
782
- req.withCredentials = true;
779
+ if (oauth.pkceCodeVerifier) {
780
+ params += '&code_verifier=' + oauth.pkceCodeVerifier;
781
+ }
783
782
 
784
- params += "&client_id=" + encodeURIComponent(kc.clientId);
783
+ req.withCredentials = true;
785
784
 
786
- var timeLocal = new Date().getTime();
785
+ req.onreadystatechange = function() {
786
+ if (req.readyState == 4) {
787
+ if (req.status == 200) {
787
788
 
788
- req.onreadystatechange = function () {
789
- if (req.readyState == 4) {
790
- if (req.status == 200) {
791
- logInfo("[KEYCLOAK] Token refreshed");
789
+ var tokenResponse = JSON.parse(req.responseText);
790
+ authSuccess(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token'], kc.flow === 'standard');
791
+ scheduleCheckIframe();
792
+ } else {
793
+ kc.onAuthError && kc.onAuthError();
794
+ promise && promise.setError();
795
+ }
796
+ }
797
+ };
792
798
 
793
- timeLocal = (timeLocal + new Date().getTime()) / 2;
799
+ req.send(params);
800
+ }
794
801
 
795
- var tokenResponse = JSON.parse(req.responseText);
802
+ function authSuccess(accessToken, refreshToken, idToken, fulfillPromise) {
803
+ timeLocal = (timeLocal + new Date().getTime()) / 2;
796
804
 
797
- setToken(
798
- tokenResponse["access_token"],
799
- tokenResponse["refresh_token"],
800
- tokenResponse["id_token"],
801
- timeLocal
802
- );
805
+ setToken(accessToken, refreshToken, idToken, timeLocal);
803
806
 
804
- kc.onAuthRefreshSuccess && kc.onAuthRefreshSuccess();
807
+ if (useNonce && ((kc.tokenParsed && kc.tokenParsed.nonce != oauth.storedNonce) ||
808
+ (kc.refreshTokenParsed && kc.refreshTokenParsed.nonce != oauth.storedNonce) ||
809
+ (kc.idTokenParsed && kc.idTokenParsed.nonce != oauth.storedNonce))) {
805
810
 
806
- for (
807
- var p = refreshQueue.pop();
808
- p != null;
809
- p = refreshQueue.pop()
810
- ) {
811
- p.setSuccess(true);
811
+ logInfo('[KEYCLOAK] Invalid nonce, clearing token');
812
+ kc.clearToken();
813
+ promise && promise.setError();
814
+ } else {
815
+ if (fulfillPromise) {
816
+ kc.onAuthSuccess && kc.onAuthSuccess();
817
+ promise && promise.setSuccess();
812
818
  }
813
- } else {
814
- logWarn("[KEYCLOAK] Failed to refresh token");
819
+ }
820
+ }
815
821
 
816
- if (req.status == 400) {
817
- kc.clearToken();
818
- }
822
+ }
823
+
824
+ function loadConfig(url) {
825
+ var promise = createPromise();
826
+ var configUrl;
819
827
 
820
- kc.onAuthRefreshError && kc.onAuthRefreshError();
828
+ if (!config) {
829
+ configUrl = location.origin + '/keycloak.json';
830
+ } else if (typeof config === 'string') {
831
+ configUrl = config;
832
+ }
821
833
 
822
- for (
823
- var p = refreshQueue.pop();
824
- p != null;
825
- p = refreshQueue.pop()
826
- ) {
827
- p.setError(true);
834
+ function setupOidcEndoints(oidcConfiguration) {
835
+ if (! oidcConfiguration) {
836
+ kc.endpoints = {
837
+ authorize: function() {
838
+ return getRealmUrl() + '/protocol/openid-connect/auth';
839
+ },
840
+ token: function() {
841
+ return getRealmUrl() + '/protocol/openid-connect/token';
842
+ },
843
+ logout: function() {
844
+ return getRealmUrl() + '/protocol/openid-connect/logout';
845
+ },
846
+ checkSessionIframe: function() {
847
+ var src = getRealmUrl() + '/protocol/openid-connect/login-status-iframe.html';
848
+ if (kc.iframeVersion) {
849
+ src = src + '?version=' + kc.iframeVersion;
850
+ }
851
+ return src;
852
+ },
853
+ thirdPartyCookiesIframe: function() {
854
+ var src = getRealmUrl() + '/protocol/openid-connect/3p-cookies/step1.html';
855
+ if (kc.iframeVersion) {
856
+ src = src + '?version=' + kc.iframeVersion;
857
+ }
858
+ return src;
859
+ },
860
+ register: function() {
861
+ return getRealmUrl() + '/protocol/openid-connect/registrations';
862
+ },
863
+ userinfo: function() {
864
+ return getRealmUrl() + '/protocol/openid-connect/userinfo';
865
+ }
866
+ };
867
+ } else {
868
+ kc.endpoints = {
869
+ authorize: function() {
870
+ return oidcConfiguration.authorization_endpoint;
871
+ },
872
+ token: function() {
873
+ return oidcConfiguration.token_endpoint;
874
+ },
875
+ logout: function() {
876
+ if (!oidcConfiguration.end_session_endpoint) {
877
+ throw "Not supported by the OIDC server";
878
+ }
879
+ return oidcConfiguration.end_session_endpoint;
880
+ },
881
+ checkSessionIframe: function() {
882
+ if (!oidcConfiguration.check_session_iframe) {
883
+ throw "Not supported by the OIDC server";
884
+ }
885
+ return oidcConfiguration.check_session_iframe;
886
+ },
887
+ register: function() {
888
+ throw 'Redirection to "Register user" page not supported in standard OIDC mode';
889
+ },
890
+ userinfo: function() {
891
+ if (!oidcConfiguration.userinfo_endpoint) {
892
+ throw "Not supported by the OIDC server";
893
+ }
894
+ return oidcConfiguration.userinfo_endpoint;
895
+ }
828
896
  }
829
- }
830
897
  }
831
- };
832
-
833
- req.send(params);
834
898
  }
835
- }
836
- };
837
899
 
838
- if (loginIframe.enable) {
839
- var iframePromise = checkLoginIframe();
840
- iframePromise
841
- .then(function () {
842
- exec();
843
- })
844
- .catch(function (error) {
845
- promise.setError(error);
846
- });
847
- } else {
848
- exec();
849
- }
900
+ if (configUrl) {
901
+ var req = new XMLHttpRequest();
902
+ req.open('GET', configUrl, true);
903
+ req.setRequestHeader('Accept', 'application/json');
904
+
905
+ req.onreadystatechange = function () {
906
+ if (req.readyState == 4) {
907
+ if (req.status == 200 || fileLoaded(req)) {
908
+ var config = JSON.parse(req.responseText);
909
+
910
+ kc.authServerUrl = config['auth-server-url'];
911
+ kc.realm = config['realm'];
912
+ kc.clientId = config['resource'];
913
+ setupOidcEndoints(null);
914
+ promise.setSuccess();
915
+ } else {
916
+ promise.setError();
917
+ }
918
+ }
919
+ };
850
920
 
851
- return promise.promise;
852
- };
921
+ req.send();
922
+ } else {
923
+ if (!config.clientId) {
924
+ throw 'clientId missing';
925
+ }
853
926
 
854
- kc.clearToken = function () {
855
- if (kc.token) {
856
- setToken(null, null, null);
857
- kc.onAuthLogout && kc.onAuthLogout();
858
- if (kc.loginRequired) {
859
- kc.login();
860
- }
861
- }
862
- };
863
-
864
- function getRealmUrl() {
865
- if (typeof kc.authServerUrl !== "undefined") {
866
- if (
867
- kc.authServerUrl.charAt(kc.authServerUrl.length - 1) == "/"
868
- ) {
869
- return (
870
- kc.authServerUrl + "realms/" + encodeURIComponent(kc.realm)
871
- );
872
- } else {
873
- return (
874
- kc.authServerUrl + "/realms/" + encodeURIComponent(kc.realm)
875
- );
876
- }
877
- } else {
878
- return undefined;
879
- }
880
- }
881
-
882
- function getOrigin() {
883
- if (!window.location.origin) {
884
- return (
885
- window.location.protocol +
886
- "//" +
887
- window.location.hostname +
888
- (window.location.port ? ":" + window.location.port : "")
889
- );
890
- } else {
891
- return window.location.origin;
892
- }
893
- }
927
+ kc.clientId = config.clientId;
928
+
929
+ var oidcProvider = config['oidcProvider'];
930
+ if (!oidcProvider) {
931
+ if (!config['url']) {
932
+ var scripts = document.getElementsByTagName('script');
933
+ for (var i = 0; i < scripts.length; i++) {
934
+ if (scripts[i].src.match(/.*keycloak\.js/)) {
935
+ config.url = scripts[i].src.substr(0, scripts[i].src.indexOf('/js/keycloak.js'));
936
+ break;
937
+ }
938
+ }
939
+ }
940
+ if (!config.realm) {
941
+ throw 'realm missing';
942
+ }
894
943
 
895
- function processCallback(oauth, promise) {
896
- var code = oauth.code;
897
- var error = oauth.error;
898
- var prompt = oauth.prompt;
944
+ kc.authServerUrl = config.url;
945
+ kc.realm = config.realm;
946
+ setupOidcEndoints(null);
947
+ promise.setSuccess();
948
+ } else {
949
+ if (typeof oidcProvider === 'string') {
950
+ var oidcProviderConfigUrl;
951
+ if (oidcProvider.charAt(oidcProvider.length - 1) == '/') {
952
+ oidcProviderConfigUrl = oidcProvider + '.well-known/openid-configuration';
953
+ } else {
954
+ oidcProviderConfigUrl = oidcProvider + '/.well-known/openid-configuration';
955
+ }
956
+ var req = new XMLHttpRequest();
957
+ req.open('GET', oidcProviderConfigUrl, true);
958
+ req.setRequestHeader('Accept', 'application/json');
959
+
960
+ req.onreadystatechange = function () {
961
+ if (req.readyState == 4) {
962
+ if (req.status == 200 || fileLoaded(req)) {
963
+ var oidcProviderConfig = JSON.parse(req.responseText);
964
+ setupOidcEndoints(oidcProviderConfig);
965
+ promise.setSuccess();
966
+ } else {
967
+ promise.setError();
968
+ }
969
+ }
970
+ };
971
+
972
+ req.send();
973
+ } else {
974
+ setupOidcEndoints(oidcProvider);
975
+ promise.setSuccess();
976
+ }
977
+ }
978
+ }
899
979
 
900
- var timeLocal = new Date().getTime();
980
+ return promise.promise;
981
+ }
901
982
 
902
- if (oauth["kc_action_status"]) {
903
- kc.onActionUpdate &&
904
- kc.onActionUpdate(
905
- oauth["kc_action_status"],
906
- oauth["kc_action"]
907
- );
983
+ function fileLoaded(xhr) {
984
+ return xhr.status == 0 && xhr.responseText && xhr.responseURL.startsWith('file:');
908
985
  }
909
986
 
910
- if (error) {
911
- if (prompt != "none") {
912
- if (
913
- oauth.error_description &&
914
- oauth.error_description === "authentication_expired"
915
- ) {
916
- kc.login(oauth.loginOptions);
987
+ function setToken(token, refreshToken, idToken, timeLocal) {
988
+ if (kc.tokenTimeoutHandle) {
989
+ clearTimeout(kc.tokenTimeoutHandle);
990
+ kc.tokenTimeoutHandle = null;
991
+ }
992
+
993
+ if (refreshToken) {
994
+ kc.refreshToken = refreshToken;
995
+ kc.refreshTokenParsed = jwtDecode(refreshToken);
917
996
  } else {
918
- var errorData = {
919
- error: error,
920
- error_description: oauth.error_description,
921
- };
922
-
923
- kc.onAuthError && kc.onAuthError(errorData);
924
- promise && promise.setError(errorData);
925
- }
926
- } else {
927
- promise && promise.setSuccess();
928
- }
929
- return;
930
- } else if (
931
- kc.flow != "standard" &&
932
- (oauth.access_token || oauth.id_token)
933
- ) {
934
- authSuccess(oauth.access_token, null, oauth.id_token, true);
935
- }
997
+ delete kc.refreshToken;
998
+ delete kc.refreshTokenParsed;
999
+ }
936
1000
 
937
- if (kc.flow != "implicit" && code) {
938
- var params = "code=" + code + "&grant_type=authorization_code";
939
- var url = kc.endpoints.token();
1001
+ if (idToken) {
1002
+ kc.idToken = idToken;
1003
+ kc.idTokenParsed = jwtDecode(idToken);
1004
+ } else {
1005
+ delete kc.idToken;
1006
+ delete kc.idTokenParsed;
1007
+ }
940
1008
 
941
- var req = new XMLHttpRequest();
942
- req.open("POST", url, true);
1009
+ if (token) {
1010
+ kc.token = token;
1011
+ kc.tokenParsed = jwtDecode(token);
1012
+ kc.sessionId = kc.tokenParsed.session_state;
1013
+ kc.authenticated = true;
1014
+ kc.subject = kc.tokenParsed.sub;
1015
+ kc.realmAccess = kc.tokenParsed.realm_access;
1016
+ kc.resourceAccess = kc.tokenParsed.resource_access;
1017
+
1018
+ if (timeLocal) {
1019
+ kc.timeSkew = Math.floor(timeLocal / 1000) - kc.tokenParsed.iat;
1020
+ }
943
1021
 
944
- req.setRequestHeader(
945
- "Content-type",
946
- "application/x-www-form-urlencoded"
947
- );
1022
+ if (kc.timeSkew != null) {
1023
+ logInfo('[KEYCLOAK] Estimated time difference between browser and server is ' + kc.timeSkew + ' seconds');
1024
+
1025
+ if (kc.onTokenExpired) {
1026
+ var expiresIn = (kc.tokenParsed['exp'] - (new Date().getTime() / 1000) + kc.timeSkew) * 1000;
1027
+ logInfo('[KEYCLOAK] Token expires in ' + Math.round(expiresIn / 1000) + ' s');
1028
+ if (expiresIn <= 0) {
1029
+ kc.onTokenExpired();
1030
+ } else {
1031
+ kc.tokenTimeoutHandle = setTimeout(kc.onTokenExpired, expiresIn);
1032
+ }
1033
+ }
1034
+ }
1035
+ } else {
1036
+ delete kc.token;
1037
+ delete kc.tokenParsed;
1038
+ delete kc.subject;
1039
+ delete kc.realmAccess;
1040
+ delete kc.resourceAccess;
948
1041
 
949
- params += "&client_id=" + encodeURIComponent(kc.clientId);
950
- params += "&redirect_uri=" + oauth.redirectUri;
1042
+ kc.authenticated = false;
1043
+ }
1044
+ }
951
1045
 
952
- if (oauth.pkceCodeVerifier) {
953
- params += "&code_verifier=" + oauth.pkceCodeVerifier;
954
- }
1046
+ function createUUID() {
1047
+ var hexDigits = '0123456789abcdef';
1048
+ var s = generateRandomString(36, hexDigits).split("");
1049
+ s[14] = '4';
1050
+ s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
1051
+ s[8] = s[13] = s[18] = s[23] = '-';
1052
+ var uuid = s.join('');
1053
+ return uuid;
1054
+ }
955
1055
 
956
- req.withCredentials = true;
1056
+ function parseCallback(url) {
1057
+ var oauth = parseCallbackUrl(url);
1058
+ if (!oauth) {
1059
+ return;
1060
+ }
957
1061
 
958
- req.onreadystatechange = function () {
959
- if (req.readyState == 4) {
960
- if (req.status == 200) {
961
- var tokenResponse = JSON.parse(req.responseText);
962
- authSuccess(
963
- tokenResponse["access_token"],
964
- tokenResponse["refresh_token"],
965
- tokenResponse["id_token"],
966
- kc.flow === "standard"
967
- );
1062
+ var oauthState = callbackStorage.get(oauth.state);
968
1063
 
969
- scheduleCheckIframe();
970
- } else {
971
- kc.onAuthError && kc.onAuthError();
972
- promise && promise.setError();
973
- }
1064
+ if (oauthState) {
1065
+ oauth.valid = true;
1066
+ oauth.redirectUri = oauthState.redirectUri;
1067
+ oauth.storedNonce = oauthState.nonce;
1068
+ oauth.prompt = oauthState.prompt;
1069
+ oauth.pkceCodeVerifier = oauthState.pkceCodeVerifier;
974
1070
  }
975
- };
976
1071
 
977
- req.send(params);
978
- }
1072
+ return oauth;
1073
+ }
1074
+
1075
+ function parseCallbackUrl(url) {
1076
+ var supportedParams;
1077
+ switch (kc.flow) {
1078
+ case 'standard':
1079
+ supportedParams = ['code', 'state', 'session_state', 'kc_action_status', 'iss'];
1080
+ break;
1081
+ case 'implicit':
1082
+ supportedParams = ['access_token', 'token_type', 'id_token', 'state', 'session_state', 'expires_in', 'kc_action_status', 'iss'];
1083
+ break;
1084
+ case 'hybrid':
1085
+ supportedParams = ['access_token', 'token_type', 'id_token', 'code', 'state', 'session_state', 'expires_in', 'kc_action_status', 'iss'];
1086
+ break;
1087
+ }
979
1088
 
980
- function authSuccess(
981
- accessToken,
982
- refreshToken,
983
- idToken,
984
- fulfillPromise
985
- ) {
986
- timeLocal = (timeLocal + new Date().getTime()) / 2;
987
-
988
- setToken(accessToken, refreshToken, idToken, timeLocal);
989
-
990
- if (
991
- useNonce &&
992
- kc.idTokenParsed &&
993
- kc.idTokenParsed.nonce != oauth.storedNonce
994
- ) {
995
- logInfo("[KEYCLOAK] Invalid nonce, clearing token");
996
- kc.clearToken();
997
- promise && promise.setError();
998
- } else {
999
- if (fulfillPromise) {
1000
- kc.onAuthSuccess && kc.onAuthSuccess();
1001
- promise && promise.setSuccess();
1002
- }
1003
- }
1004
- }
1005
- }
1089
+ supportedParams.push('error');
1090
+ supportedParams.push('error_description');
1091
+ supportedParams.push('error_uri');
1006
1092
 
1007
- function loadConfig(url) {
1008
- var promise = createPromise();
1009
- var configUrl;
1093
+ var queryIndex = url.indexOf('?');
1094
+ var fragmentIndex = url.indexOf('#');
1010
1095
 
1011
- if (!config) {
1012
- configUrl = "keycloak.json";
1013
- } else if (typeof config === "string") {
1014
- configUrl = config;
1015
- }
1096
+ var newUrl;
1097
+ var parsed;
1016
1098
 
1017
- function setupOidcEndoints(oidcConfiguration) {
1018
- if (!oidcConfiguration) {
1019
- kc.endpoints = {
1020
- authorize: function () {
1021
- return getRealmUrl() + "/protocol/openid-connect/auth";
1022
- },
1023
- token: function () {
1024
- return getRealmUrl() + "/protocol/openid-connect/token";
1025
- },
1026
- logout: function () {
1027
- return getRealmUrl() + "/protocol/openid-connect/logout";
1028
- },
1029
- checkSessionIframe: function () {
1030
- var src =
1031
- getRealmUrl() +
1032
- "/protocol/openid-connect/login-status-iframe.html";
1033
- if (kc.iframeVersion) {
1034
- src = src + "?version=" + kc.iframeVersion;
1035
- }
1036
- return src;
1037
- },
1038
- thirdPartyCookiesIframe: function () {
1039
- var src =
1040
- getRealmUrl() +
1041
- "/protocol/openid-connect/3p-cookies/step1.html";
1042
- if (kc.iframeVersion) {
1043
- src = src + "?version=" + kc.iframeVersion;
1044
- }
1045
- return src;
1046
- },
1047
- register: function () {
1048
- return (
1049
- getRealmUrl() + "/protocol/openid-connect/registrations"
1050
- );
1051
- },
1052
- userinfo: function () {
1053
- return (
1054
- getRealmUrl() + "/protocol/openid-connect/userinfo"
1055
- );
1056
- },
1057
- };
1058
- } else {
1059
- kc.endpoints = {
1060
- authorize: function () {
1061
- return oidcConfiguration.authorization_endpoint;
1062
- },
1063
- token: function () {
1064
- return oidcConfiguration.token_endpoint;
1065
- },
1066
- logout: function () {
1067
- if (!oidcConfiguration.end_session_endpoint) {
1068
- throw "Not supported by the OIDC server";
1099
+ if (kc.responseMode === 'query' && queryIndex !== -1) {
1100
+ newUrl = url.substring(0, queryIndex);
1101
+ parsed = parseCallbackParams(url.substring(queryIndex + 1, fragmentIndex !== -1 ? fragmentIndex : url.length), supportedParams);
1102
+ if (parsed.paramsString !== '') {
1103
+ newUrl += '?' + parsed.paramsString;
1069
1104
  }
1070
- return oidcConfiguration.end_session_endpoint;
1071
- },
1072
- checkSessionIframe: function () {
1073
- if (!oidcConfiguration.check_session_iframe) {
1074
- throw "Not supported by the OIDC server";
1105
+ if (fragmentIndex !== -1) {
1106
+ newUrl += url.substring(fragmentIndex);
1075
1107
  }
1076
- return oidcConfiguration.check_session_iframe;
1077
- },
1078
- register: function () {
1079
- throw 'Redirection to "Register user" page not supported in standard OIDC mode';
1080
- },
1081
- userinfo: function () {
1082
- if (!oidcConfiguration.userinfo_endpoint) {
1083
- throw "Not supported by the OIDC server";
1108
+ } else if (kc.responseMode === 'fragment' && fragmentIndex !== -1) {
1109
+ newUrl = url.substring(0, fragmentIndex);
1110
+ parsed = parseCallbackParams(url.substring(fragmentIndex + 1), supportedParams);
1111
+ if (parsed.paramsString !== '') {
1112
+ newUrl += '#' + parsed.paramsString;
1084
1113
  }
1085
- return oidcConfiguration.userinfo_endpoint;
1086
- },
1087
- };
1088
- }
1089
- }
1090
-
1091
- if (configUrl) {
1092
- var req = new XMLHttpRequest();
1093
- req.open("GET", configUrl, true);
1094
- req.setRequestHeader("Accept", "application/json");
1095
-
1096
- req.onreadystatechange = function () {
1097
- if (req.readyState == 4) {
1098
- if (req.status == 200 || fileLoaded(req)) {
1099
- var config = JSON.parse(req.responseText);
1114
+ }
1100
1115
 
1101
- kc.authServerUrl = config["auth-server-url"];
1102
- kc.realm = config["realm"];
1103
- kc.clientId = config["resource"];
1104
- setupOidcEndoints(null);
1105
- promise.setSuccess();
1106
- } else {
1107
- promise.setError();
1108
- }
1109
- }
1110
- };
1111
-
1112
- req.send();
1113
- } else {
1114
- if (!config.clientId) {
1115
- throw "clientId missing";
1116
- }
1117
-
1118
- kc.clientId = config.clientId;
1119
-
1120
- var oidcProvider = config["oidcProvider"];
1121
- if (!oidcProvider) {
1122
- if (!config["url"]) {
1123
- var scripts = document.getElementsByTagName("script");
1124
- for (var i = 0; i < scripts.length; i++) {
1125
- if (scripts[i].src.match(/.*keycloak\.js/)) {
1126
- config.url = scripts[i].src.substr(
1127
- 0,
1128
- scripts[i].src.indexOf("/js/keycloak.js")
1129
- );
1130
-
1131
- break;
1132
- }
1133
- }
1134
- }
1135
- if (!config.realm) {
1136
- throw "realm missing";
1137
- }
1138
-
1139
- kc.authServerUrl = config.url;
1140
- kc.realm = config.realm;
1141
- setupOidcEndoints(null);
1142
- promise.setSuccess();
1143
- } else {
1144
- if (typeof oidcProvider === "string") {
1145
- var oidcProviderConfigUrl;
1146
- if (oidcProvider.charAt(oidcProvider.length - 1) == "/") {
1147
- oidcProviderConfigUrl =
1148
- oidcProvider + ".well-known/openid-configuration";
1149
- } else {
1150
- oidcProviderConfigUrl =
1151
- oidcProvider + "/.well-known/openid-configuration";
1152
- }
1153
- var req = new XMLHttpRequest();
1154
- req.open("GET", oidcProviderConfigUrl, true);
1155
- req.setRequestHeader("Accept", "application/json");
1156
-
1157
- req.onreadystatechange = function () {
1158
- if (req.readyState == 4) {
1159
- if (req.status == 200 || fileLoaded(req)) {
1160
- var oidcProviderConfig = JSON.parse(req.responseText);
1161
- setupOidcEndoints(oidcProviderConfig);
1162
- promise.setSuccess();
1163
- } else {
1164
- promise.setError();
1165
- }
1116
+ if (parsed && parsed.oauthParams) {
1117
+ if (kc.flow === 'standard' || kc.flow === 'hybrid') {
1118
+ if ((parsed.oauthParams.code || parsed.oauthParams.error) && parsed.oauthParams.state) {
1119
+ parsed.oauthParams.newUrl = newUrl;
1120
+ return parsed.oauthParams;
1121
+ }
1122
+ } else if (kc.flow === 'implicit') {
1123
+ if ((parsed.oauthParams.access_token || parsed.oauthParams.error) && parsed.oauthParams.state) {
1124
+ parsed.oauthParams.newUrl = newUrl;
1125
+ return parsed.oauthParams;
1126
+ }
1166
1127
  }
1167
- };
1168
-
1169
- req.send();
1170
- } else {
1171
- setupOidcEndoints(oidcProvider);
1172
- promise.setSuccess();
1173
1128
  }
1174
- }
1175
1129
  }
1176
1130
 
1177
- return promise.promise;
1178
- }
1179
-
1180
- function fileLoaded(xhr) {
1181
- return (
1182
- xhr.status == 0 &&
1183
- xhr.responseText &&
1184
- xhr.responseURL.startsWith("file:")
1185
- );
1186
- }
1187
-
1188
- function setToken(token, refreshToken, idToken, timeLocal) {
1189
- if (kc.tokenTimeoutHandle) {
1190
- clearTimeout(kc.tokenTimeoutHandle);
1191
- kc.tokenTimeoutHandle = null;
1131
+ function parseCallbackParams(paramsString, supportedParams) {
1132
+ var p = paramsString.split('&');
1133
+ var result = {
1134
+ paramsString: '',
1135
+ oauthParams: {}
1136
+ }
1137
+ for (var i = 0; i < p.length; i++) {
1138
+ var split = p[i].indexOf("=");
1139
+ var key = p[i].slice(0, split);
1140
+ if (supportedParams.indexOf(key) !== -1) {
1141
+ result.oauthParams[key] = p[i].slice(split + 1);
1142
+ } else {
1143
+ if (result.paramsString !== '') {
1144
+ result.paramsString += '&';
1145
+ }
1146
+ result.paramsString += p[i];
1147
+ }
1148
+ }
1149
+ return result;
1192
1150
  }
1193
1151
 
1194
- if (refreshToken) {
1195
- kc.refreshToken = refreshToken;
1196
- kc.refreshTokenParsed = jwtDecode(refreshToken);
1197
- } else {
1198
- delete kc.refreshToken;
1199
- delete kc.refreshTokenParsed;
1200
- }
1152
+ function createPromise() {
1153
+ // Need to create a native Promise which also preserves the
1154
+ // interface of the custom promise type previously used by the API
1155
+ var p = {
1156
+ setSuccess: function(result) {
1157
+ p.resolve(result);
1158
+ },
1201
1159
 
1202
- if (idToken) {
1203
- kc.idToken = idToken;
1204
- kc.idTokenParsed = jwtDecode(idToken);
1205
- } else {
1206
- delete kc.idToken;
1207
- delete kc.idTokenParsed;
1208
- }
1160
+ setError: function(result) {
1161
+ p.reject(result);
1162
+ }
1163
+ };
1164
+ p.promise = new Promise(function(resolve, reject) {
1165
+ p.resolve = resolve;
1166
+ p.reject = reject;
1167
+ });
1209
1168
 
1210
- if (token) {
1211
- kc.token = token;
1212
- kc.tokenParsed = jwtDecode(token);
1213
- kc.sessionId = kc.tokenParsed.sid;
1214
- kc.authenticated = true;
1215
- kc.subject = kc.tokenParsed.sub;
1216
- kc.realmAccess = kc.tokenParsed.realm_access;
1217
- kc.resourceAccess = kc.tokenParsed.resource_access;
1218
-
1219
- if (timeLocal) {
1220
- kc.timeSkew =
1221
- Math.floor(timeLocal / 1000) - kc.tokenParsed.iat;
1222
- }
1223
-
1224
- if (kc.timeSkew != null) {
1225
- logInfo(
1226
- "[KEYCLOAK] Estimated time difference between browser and server is " +
1227
- kc.timeSkew +
1228
- " seconds"
1229
- );
1230
-
1231
- if (kc.onTokenExpired) {
1232
- var expiresIn =
1233
- (kc.tokenParsed["exp"] -
1234
- new Date().getTime() / 1000 +
1235
- kc.timeSkew) *
1236
- 1000;
1237
-
1238
- logInfo(
1239
- "[KEYCLOAK] Token expires in " +
1240
- Math.round(expiresIn / 1000) +
1241
- " s"
1242
- );
1243
-
1244
- if (expiresIn <= 0) {
1245
- kc.onTokenExpired();
1246
- } else {
1247
- kc.tokenTimeoutHandle = setTimeout(
1248
- kc.onTokenExpired,
1249
- expiresIn
1250
- );
1251
- }
1252
- }
1253
- }
1254
- } else {
1255
- delete kc.token;
1256
- delete kc.tokenParsed;
1257
- delete kc.subject;
1258
- delete kc.realmAccess;
1259
- delete kc.resourceAccess;
1260
-
1261
- kc.authenticated = false;
1262
- }
1263
- }
1264
-
1265
- function createUUID() {
1266
- var hexDigits = "0123456789abcdef";
1267
- var s = generateRandomString(36, hexDigits).split("");
1268
- s[14] = "4";
1269
- s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
1270
- s[8] = s[13] = s[18] = s[23] = "-";
1271
- var uuid = s.join("");
1272
- return uuid;
1273
- }
1274
-
1275
- function parseCallback(url) {
1276
- var oauth = parseCallbackUrl(url);
1277
- if (!oauth) {
1278
- return;
1169
+ return p;
1279
1170
  }
1280
1171
 
1281
- var oauthState = callbackStorage.get(oauth.state);
1172
+ // Function to extend existing native Promise with timeout
1173
+ function applyTimeoutToPromise(promise, timeout, errorMessage) {
1174
+ var timeoutHandle = null;
1175
+ var timeoutPromise = new Promise(function (resolve, reject) {
1176
+ timeoutHandle = setTimeout(function () {
1177
+ reject({ "error": errorMessage || "Promise is not settled within timeout of " + timeout + "ms" });
1178
+ }, timeout);
1179
+ });
1282
1180
 
1283
- if (oauthState) {
1284
- oauth.valid = true;
1285
- oauth.redirectUri = oauthState.redirectUri;
1286
- oauth.storedNonce = oauthState.nonce;
1287
- oauth.prompt = oauthState.prompt;
1288
- oauth.pkceCodeVerifier = oauthState.pkceCodeVerifier;
1289
- oauth.loginOptions = oauthState.loginOptions;
1181
+ return Promise.race([promise, timeoutPromise]).finally(function () {
1182
+ clearTimeout(timeoutHandle);
1183
+ });
1290
1184
  }
1291
1185
 
1292
- return oauth;
1293
- }
1294
-
1295
- function parseCallbackUrl(url) {
1296
- var supportedParams;
1297
- switch (kc.flow) {
1298
- case "standard":
1299
- supportedParams = [
1300
- "code",
1301
- "state",
1302
- "session_state",
1303
- "kc_action_status",
1304
- "kc_action",
1305
- "iss",
1306
- ];
1307
-
1308
- break;
1309
- case "implicit":
1310
- supportedParams = [
1311
- "access_token",
1312
- "token_type",
1313
- "id_token",
1314
- "state",
1315
- "session_state",
1316
- "expires_in",
1317
- "kc_action_status",
1318
- "kc_action",
1319
- "iss",
1320
- ];
1321
-
1322
- break;
1323
- case "hybrid":
1324
- supportedParams = [
1325
- "access_token",
1326
- "token_type",
1327
- "id_token",
1328
- "code",
1329
- "state",
1330
- "session_state",
1331
- "expires_in",
1332
- "kc_action_status",
1333
- "kc_action",
1334
- "iss",
1335
- ];
1336
-
1337
- break;
1338
- }
1186
+ function setupCheckLoginIframe() {
1187
+ var promise = createPromise();
1339
1188
 
1340
- supportedParams.push("error");
1341
- supportedParams.push("error_description");
1342
- supportedParams.push("error_uri");
1343
-
1344
- var queryIndex = url.indexOf("?");
1345
- var fragmentIndex = url.indexOf("#");
1346
-
1347
- var newUrl;
1348
- var parsed;
1349
-
1350
- if (kc.responseMode === "query" && queryIndex !== -1) {
1351
- newUrl = url.substring(0, queryIndex);
1352
-
1353
- parsed = parseCallbackParams(
1354
- url.substring(
1355
- queryIndex + 1,
1356
- fragmentIndex !== -1 ? fragmentIndex : url.length
1357
- ),
1358
- supportedParams
1359
- );
1360
-
1361
- if (parsed.paramsString !== "") {
1362
- newUrl += "?" + parsed.paramsString;
1363
- }
1364
- if (fragmentIndex !== -1) {
1365
- newUrl += url.substring(fragmentIndex);
1366
- }
1367
- } else if (
1368
- kc.responseMode === "fragment" &&
1369
- fragmentIndex !== -1
1370
- ) {
1371
- newUrl = url.substring(0, fragmentIndex);
1372
-
1373
- parsed = parseCallbackParams(
1374
- url.substring(fragmentIndex + 1),
1375
- supportedParams
1376
- );
1377
-
1378
- if (parsed.paramsString !== "") {
1379
- newUrl += "#" + parsed.paramsString;
1380
- }
1381
- }
1189
+ if (!loginIframe.enable) {
1190
+ promise.setSuccess();
1191
+ return promise.promise;
1192
+ }
1382
1193
 
1383
- if (parsed && parsed.oauthParams) {
1384
- if (kc.flow === "standard" || kc.flow === "hybrid") {
1385
- if (
1386
- (parsed.oauthParams.code || parsed.oauthParams.error) &&
1387
- parsed.oauthParams.state
1388
- ) {
1389
- parsed.oauthParams.newUrl = newUrl;
1390
- return parsed.oauthParams;
1391
- }
1392
- } else if (kc.flow === "implicit") {
1393
- if (
1394
- (parsed.oauthParams.access_token ||
1395
- parsed.oauthParams.error) &&
1396
- parsed.oauthParams.state
1397
- ) {
1398
- parsed.oauthParams.newUrl = newUrl;
1399
- return parsed.oauthParams;
1400
- }
1401
- }
1402
- }
1403
- }
1194
+ if (loginIframe.iframe) {
1195
+ promise.setSuccess();
1196
+ return promise.promise;
1197
+ }
1404
1198
 
1405
- function parseCallbackParams(paramsString, supportedParams) {
1406
- var p = paramsString.split("&");
1407
- var result = {
1408
- paramsString: "",
1409
- oauthParams: {},
1410
- };
1411
- for (var i = 0; i < p.length; i++) {
1412
- var split = p[i].indexOf("=");
1413
- var key = p[i].slice(0, split);
1414
- if (supportedParams.indexOf(key) !== -1) {
1415
- result.oauthParams[key] = p[i].slice(split + 1);
1416
- } else {
1417
- if (result.paramsString !== "") {
1418
- result.paramsString += "&";
1419
- }
1420
- result.paramsString += p[i];
1421
- }
1422
- }
1423
- return result;
1424
- }
1425
-
1426
- function createPromise() {
1427
- // Need to create a native Promise which also preserves the
1428
- // interface of the custom promise type previously used by the API
1429
- var p = {
1430
- setSuccess: function (result) {
1431
- p.resolve(result);
1432
- },
1433
-
1434
- setError: function (result) {
1435
- p.reject(result);
1436
- },
1437
- };
1438
- p.promise = new Promise(function (resolve, reject) {
1439
- p.resolve = resolve;
1440
- p.reject = reject;
1441
- });
1442
-
1443
- return p;
1444
- }
1445
-
1446
- // Function to extend existing native Promise with timeout
1447
- function applyTimeoutToPromise(promise, timeout, errorMessage) {
1448
- var timeoutHandle = null;
1449
- var timeoutPromise = new Promise(function (resolve, reject) {
1450
- timeoutHandle = setTimeout(function () {
1451
- reject({
1452
- error:
1453
- errorMessage ||
1454
- "Promise is not settled within timeout of " +
1455
- timeout +
1456
- "ms",
1457
- });
1458
- }, timeout);
1459
- });
1460
-
1461
- return Promise.race([promise, timeoutPromise]).finally(
1462
- function () {
1463
- clearTimeout(timeoutHandle);
1464
- }
1465
- );
1466
- }
1467
-
1468
- function setupCheckLoginIframe() {
1469
- var promise = createPromise();
1470
-
1471
- if (!loginIframe.enable) {
1472
- promise.setSuccess();
1473
- return promise.promise;
1474
- }
1199
+ var iframe = document.createElement('iframe');
1200
+ loginIframe.iframe = iframe;
1475
1201
 
1476
- if (loginIframe.iframe) {
1477
- promise.setSuccess();
1478
- return promise.promise;
1479
- }
1202
+ iframe.onload = function() {
1203
+ var authUrl = kc.endpoints.authorize();
1204
+ if (authUrl.charAt(0) === '/') {
1205
+ loginIframe.iframeOrigin = getOrigin();
1206
+ } else {
1207
+ loginIframe.iframeOrigin = authUrl.substring(0, authUrl.indexOf('/', 8));
1208
+ }
1209
+ promise.setSuccess();
1210
+ }
1480
1211
 
1481
- var iframe = document.createElement("iframe");
1482
- loginIframe.iframe = iframe;
1483
-
1484
- iframe.onload = function () {
1485
- var authUrl = kc.endpoints.authorize();
1486
- if (authUrl.charAt(0) === "/") {
1487
- loginIframe.iframeOrigin = getOrigin();
1488
- } else {
1489
- loginIframe.iframeOrigin = authUrl.substring(
1490
- 0,
1491
- authUrl.indexOf("/", 8)
1492
- );
1493
- }
1494
- promise.setSuccess();
1495
- };
1212
+ var src = kc.endpoints.checkSessionIframe();
1213
+ iframe.setAttribute('src', src );
1214
+ iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
1215
+ iframe.setAttribute('title', 'keycloak-session-iframe' );
1216
+ iframe.style.display = 'none';
1217
+ document.body.appendChild(iframe);
1496
1218
 
1497
- var src = kc.endpoints.checkSessionIframe();
1498
- iframe.setAttribute("src", src);
1499
-
1500
- iframe.setAttribute(
1501
- "sandbox",
1502
- "allow-storage-access-by-user-activation allow-scripts allow-same-origin"
1503
- );
1504
-
1505
- iframe.setAttribute("title", "keycloak-session-iframe");
1506
- iframe.style.display = "none";
1507
- document.body.appendChild(iframe);
1508
-
1509
- var messageCallback = function (event) {
1510
- if (
1511
- event.origin !== loginIframe.iframeOrigin ||
1512
- loginIframe.iframe.contentWindow !== event.source
1513
- ) {
1514
- return;
1515
- }
1516
-
1517
- if (
1518
- !(
1519
- event.data == "unchanged" ||
1520
- event.data == "changed" ||
1521
- event.data == "error"
1522
- )
1523
- ) {
1524
- return;
1525
- }
1526
-
1527
- if (event.data != "unchanged") {
1528
- kc.clearToken();
1529
- }
1530
-
1531
- var callbacks = loginIframe.callbackList.splice(
1532
- 0,
1533
- loginIframe.callbackList.length
1534
- );
1535
-
1536
- for (var i = callbacks.length - 1; i >= 0; --i) {
1537
- var promise = callbacks[i];
1538
- if (event.data == "error") {
1539
- promise.setError();
1540
- } else {
1541
- promise.setSuccess(event.data == "unchanged");
1542
- }
1543
- }
1544
- };
1219
+ var messageCallback = function(event) {
1220
+ if ((event.origin !== loginIframe.iframeOrigin) || (loginIframe.iframe.contentWindow !== event.source)) {
1221
+ return;
1222
+ }
1545
1223
 
1546
- window.addEventListener("message", messageCallback, false);
1224
+ if (!(event.data == 'unchanged' || event.data == 'changed' || event.data == 'error')) {
1225
+ return;
1226
+ }
1547
1227
 
1548
- return promise.promise;
1549
- }
1550
1228
 
1551
- function scheduleCheckIframe() {
1552
- if (loginIframe.enable) {
1553
- if (kc.token) {
1554
- setTimeout(function () {
1555
- checkLoginIframe().then(function (unchanged) {
1556
- if (unchanged) {
1557
- scheduleCheckIframe();
1229
+ if (event.data != 'unchanged') {
1230
+ kc.clearToken();
1558
1231
  }
1559
- });
1560
- }, loginIframe.interval * 1000);
1561
- }
1562
- }
1563
- }
1564
-
1565
- function checkLoginIframe() {
1566
- var promise = createPromise();
1567
-
1568
- if (loginIframe.iframe && loginIframe.iframeOrigin) {
1569
- var msg =
1570
- kc.clientId + " " + (kc.sessionId ? kc.sessionId : "");
1571
- loginIframe.callbackList.push(promise);
1572
- var origin = loginIframe.iframeOrigin;
1573
- if (loginIframe.callbackList.length == 1) {
1574
- loginIframe.iframe.contentWindow.postMessage(msg, origin);
1575
- }
1576
- } else {
1577
- promise.setSuccess();
1578
- }
1579
1232
 
1580
- return promise.promise;
1581
- }
1582
-
1583
- function check3pCookiesSupported() {
1584
- var promise = createPromise();
1585
-
1586
- if (loginIframe.enable || kc.silentCheckSsoRedirectUri) {
1587
- var iframe = document.createElement("iframe");
1588
-
1589
- iframe.setAttribute(
1590
- "src",
1591
- kc.endpoints.thirdPartyCookiesIframe()
1592
- );
1593
-
1594
- iframe.setAttribute(
1595
- "sandbox",
1596
- "allow-storage-access-by-user-activation allow-scripts allow-same-origin"
1597
- );
1598
-
1599
- iframe.setAttribute("title", "keycloak-3p-check-iframe");
1600
- iframe.style.display = "none";
1601
- document.body.appendChild(iframe);
1602
-
1603
- var messageCallback = function (event) {
1604
- if (iframe.contentWindow !== event.source) {
1605
- return;
1606
- }
1607
-
1608
- if (
1609
- event.data !== "supported" &&
1610
- event.data !== "unsupported"
1611
- ) {
1612
- return;
1613
- } else if (event.data === "unsupported") {
1614
- logWarn(
1615
- "[KEYCLOAK] Your browser is blocking access to 3rd-party cookies, this means:\n\n" +
1616
- " - It is not possible to retrieve tokens without redirecting to the Keycloak server (a.k.a. no support for silent authentication).\n" +
1617
- " - It is not possible to automatically detect changes to the session status (such as the user logging out in another tab).\n\n" +
1618
- "For more information see: https://www.keycloak.org/docs/latest/securing_apps/#_modern_browsers"
1619
- );
1620
-
1621
- loginIframe.enable = false;
1622
- if (kc.silentCheckSsoFallback) {
1623
- kc.silentCheckSsoRedirectUri = false;
1624
- }
1625
- }
1626
-
1627
- document.body.removeChild(iframe);
1628
- window.removeEventListener("message", messageCallback);
1629
- promise.setSuccess();
1630
- };
1631
-
1632
- window.addEventListener("message", messageCallback, false);
1633
- } else {
1634
- promise.setSuccess();
1635
- }
1233
+ var callbacks = loginIframe.callbackList.splice(0, loginIframe.callbackList.length);
1636
1234
 
1637
- return applyTimeoutToPromise(
1638
- promise.promise,
1639
- kc.messageReceiveTimeout,
1640
- "Timeout when waiting for 3rd party check iframe message."
1641
- );
1642
- }
1643
-
1644
- function loadAdapter(type) {
1645
- if (!type || type == "default") {
1646
- return {
1647
- login: function (options) {
1648
- window.location.assign(kc.createLoginUrl(options));
1649
- return createPromise().promise;
1650
- },
1651
-
1652
- logout: async function (options) {
1653
- const logoutMethod =
1654
- options?.logoutMethod ?? kc.logoutMethod;
1655
- if (logoutMethod === "GET") {
1656
- window.location.replace(kc.createLogoutUrl(options));
1657
- return;
1658
- }
1235
+ for (var i = callbacks.length - 1; i >= 0; --i) {
1236
+ var promise = callbacks[i];
1237
+ if (event.data == 'error') {
1238
+ promise.setError();
1239
+ } else {
1240
+ promise.setSuccess(event.data == 'unchanged');
1241
+ }
1242
+ }
1243
+ };
1659
1244
 
1660
- const logoutUrl = kc.createLogoutUrl(options);
1661
- const response = await fetch(logoutUrl, {
1662
- method: "POST",
1663
- headers: {
1664
- "Content-Type": "application/x-www-form-urlencoded",
1665
- },
1666
- body: new URLSearchParams({
1667
- id_token_hint: kc.idToken,
1668
- client_id: kc.clientId,
1669
- post_logout_redirect_uri: adapter.redirectUri(
1670
- options,
1671
- false
1672
- ),
1673
- }),
1674
- });
1675
-
1676
- if (response.redirected) {
1677
- window.location.href = response.url;
1678
- return;
1679
- }
1245
+ window.addEventListener('message', messageCallback, false);
1680
1246
 
1681
- if (response.ok) {
1682
- window.location.reload();
1683
- return;
1684
- }
1685
-
1686
- throw new Error(
1687
- "Logout failed, request returned an error code."
1688
- );
1689
- },
1690
-
1691
- register: function (options) {
1692
- window.location.assign(kc.createRegisterUrl(options));
1693
- return createPromise().promise;
1694
- },
1695
-
1696
- accountManagement: function () {
1697
- var accountUrl = kc.createAccountUrl();
1698
- if (typeof accountUrl !== "undefined") {
1699
- window.location.href = accountUrl;
1700
- } else {
1701
- throw "Not supported by the OIDC server";
1702
- }
1703
- return createPromise().promise;
1704
- },
1705
-
1706
- redirectUri: function (options, encodeHash) {
1707
- if (arguments.length == 1) {
1708
- encodeHash = true;
1709
- }
1710
-
1711
- if (options && options.redirectUri) {
1712
- return options.redirectUri;
1713
- } else if (kc.redirectUri) {
1714
- return kc.redirectUri;
1715
- } else {
1716
- return location.href;
1717
- }
1718
- },
1719
- };
1247
+ return promise.promise;
1720
1248
  }
1721
1249
 
1722
- if (type == "cordova") {
1723
- loginIframe.enable = false;
1724
- var cordovaOpenWindowWrapper = function (
1725
- loginUrl,
1726
- target,
1727
- options
1728
- ) {
1729
- if (window.cordova && window.cordova.InAppBrowser) {
1730
- // Use inappbrowser for IOS and Android if available
1731
- return window.cordova.InAppBrowser.open(
1732
- loginUrl,
1733
- target,
1734
- options
1735
- );
1736
- } else {
1737
- return window.open(loginUrl, target, options);
1250
+ function scheduleCheckIframe() {
1251
+ if (loginIframe.enable) {
1252
+ if (kc.token) {
1253
+ setTimeout(function() {
1254
+ checkLoginIframe().then(function(unchanged) {
1255
+ if (unchanged) {
1256
+ scheduleCheckIframe();
1257
+ }
1258
+ });
1259
+ }, loginIframe.interval * 1000);
1260
+ }
1738
1261
  }
1739
- };
1262
+ }
1740
1263
 
1741
- var shallowCloneCordovaOptions = function (userOptions) {
1742
- if (userOptions && userOptions.cordovaOptions) {
1743
- return Object.keys(userOptions.cordovaOptions).reduce(
1744
- function (options, optionName) {
1745
- options[optionName] =
1746
- userOptions.cordovaOptions[optionName];
1264
+ function checkLoginIframe() {
1265
+ var promise = createPromise();
1747
1266
 
1748
- return options;
1749
- },
1750
- {}
1751
- );
1752
- } else {
1753
- return {};
1754
- }
1755
- };
1756
-
1757
- var formatCordovaOptions = function (cordovaOptions) {
1758
- return Object.keys(cordovaOptions)
1759
- .reduce(function (options, optionName) {
1760
- options.push(
1761
- optionName + "=" + cordovaOptions[optionName]
1762
- );
1763
-
1764
- return options;
1765
- }, [])
1766
- .join(",");
1767
- };
1768
-
1769
- var createCordovaOptions = function (userOptions) {
1770
- var cordovaOptions = shallowCloneCordovaOptions(userOptions);
1771
- cordovaOptions.location = "no";
1772
- if (userOptions && userOptions.prompt == "none") {
1773
- cordovaOptions.hidden = "yes";
1774
- }
1775
- return formatCordovaOptions(cordovaOptions);
1776
- };
1777
-
1778
- var getCordovaRedirectUri = function () {
1779
- return kc.redirectUri || "http://localhost";
1780
- };
1781
-
1782
- return {
1783
- login: function (options) {
1784
- var promise = createPromise();
1785
-
1786
- var cordovaOptions = createCordovaOptions(options);
1787
- var loginUrl = kc.createLoginUrl(options);
1788
- var ref = cordovaOpenWindowWrapper(
1789
- loginUrl,
1790
- "_blank",
1791
- cordovaOptions
1792
- );
1793
-
1794
- var completed = false;
1795
-
1796
- var closed = false;
1797
- var closeBrowser = function () {
1798
- closed = true;
1799
- ref.close();
1800
- };
1801
-
1802
- ref.addEventListener("loadstart", function (event) {
1803
- if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1804
- var callback = parseCallback(event.url);
1805
- processCallback(callback, promise);
1806
- closeBrowser();
1807
- completed = true;
1808
- }
1809
- });
1810
-
1811
- ref.addEventListener("loaderror", function (event) {
1812
- if (!completed) {
1813
- if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1814
- var callback = parseCallback(event.url);
1815
- processCallback(callback, promise);
1816
- closeBrowser();
1817
- completed = true;
1818
- } else {
1819
- promise.setError();
1820
- closeBrowser();
1821
- }
1267
+ if (loginIframe.iframe && loginIframe.iframeOrigin ) {
1268
+ var msg = kc.clientId + ' ' + (kc.sessionId ? kc.sessionId : '');
1269
+ loginIframe.callbackList.push(promise);
1270
+ var origin = loginIframe.iframeOrigin;
1271
+ if (loginIframe.callbackList.length == 1) {
1272
+ loginIframe.iframe.contentWindow.postMessage(msg, origin);
1822
1273
  }
1823
- });
1274
+ } else {
1275
+ promise.setSuccess();
1276
+ }
1824
1277
 
1825
- ref.addEventListener("exit", function (event) {
1826
- if (!closed) {
1827
- promise.setError({
1828
- reason: "closed_by_user",
1829
- });
1830
- }
1831
- });
1278
+ return promise.promise;
1279
+ }
1832
1280
 
1833
- return promise.promise;
1834
- },
1281
+ function check3pCookiesSupported() {
1282
+ var promise = createPromise();
1835
1283
 
1836
- logout: function (options) {
1837
- var promise = createPromise();
1284
+ if (loginIframe.enable || kc.silentCheckSsoRedirectUri) {
1285
+ var iframe = document.createElement('iframe');
1286
+ iframe.setAttribute('src', kc.endpoints.thirdPartyCookiesIframe());
1287
+ iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
1288
+ iframe.setAttribute('title', 'keycloak-3p-check-iframe' );
1289
+ iframe.style.display = 'none';
1290
+ document.body.appendChild(iframe);
1838
1291
 
1839
- var logoutUrl = kc.createLogoutUrl(options);
1292
+ var messageCallback = function(event) {
1293
+ if (iframe.contentWindow !== event.source) {
1294
+ return;
1295
+ }
1840
1296
 
1841
- var ref = cordovaOpenWindowWrapper(
1842
- logoutUrl,
1843
- "_blank",
1844
- "location=no,hidden=yes,clearcache=yes"
1845
- );
1297
+ if (event.data !== "supported" && event.data !== "unsupported") {
1298
+ return;
1299
+ } else if (event.data === "unsupported") {
1300
+ logWarn(
1301
+ "[KEYCLOAK] Your browser is blocking access to 3rd-party cookies, this means:\n\n" +
1302
+ " - It is not possible to retrieve tokens without redirecting to the Keycloak server (a.k.a. no support for silent authentication).\n" +
1303
+ " - It is not possible to automatically detect changes to the session status (such as the user logging out in another tab).\n\n" +
1304
+ "For more information see: https://www.keycloak.org/docs/latest/securing_apps/#_modern_browsers"
1305
+ );
1306
+
1307
+ loginIframe.enable = false;
1308
+ if (kc.silentCheckSsoFallback) {
1309
+ kc.silentCheckSsoRedirectUri = false;
1310
+ }
1311
+ }
1846
1312
 
1847
- var error;
1313
+ document.body.removeChild(iframe);
1314
+ window.removeEventListener("message", messageCallback);
1315
+ promise.setSuccess();
1316
+ };
1848
1317
 
1849
- ref.addEventListener("loadstart", function (event) {
1850
- if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1851
- ref.close();
1852
- }
1853
- });
1318
+ window.addEventListener('message', messageCallback, false);
1319
+ } else {
1320
+ promise.setSuccess();
1321
+ }
1854
1322
 
1855
- ref.addEventListener("loaderror", function (event) {
1856
- if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1857
- ref.close();
1858
- } else {
1859
- error = true;
1860
- ref.close();
1861
- }
1862
- });
1323
+ return applyTimeoutToPromise(promise.promise, kc.messageReceiveTimeout, "Timeout when waiting for 3rd party check iframe message.");
1324
+ }
1325
+
1326
+ function loadAdapter(type) {
1327
+ if (!type || type == 'default') {
1328
+ return {
1329
+ login: function(options) {
1330
+ window.location.assign(kc.createLoginUrl(options));
1331
+ return createPromise().promise;
1332
+ },
1333
+
1334
+ logout: function(options) {
1335
+ window.location.replace(kc.createLogoutUrl(options));
1336
+ return createPromise().promise;
1337
+ },
1338
+
1339
+ register: function(options) {
1340
+ window.location.assign(kc.createRegisterUrl(options));
1341
+ return createPromise().promise;
1342
+ },
1343
+
1344
+ accountManagement : function() {
1345
+ var accountUrl = kc.createAccountUrl();
1346
+ if (typeof accountUrl !== 'undefined') {
1347
+ window.location.href = accountUrl;
1348
+ } else {
1349
+ throw "Not supported by the OIDC server";
1350
+ }
1351
+ return createPromise().promise;
1352
+ },
1353
+
1354
+ redirectUri: function(options, encodeHash) {
1355
+ if (arguments.length == 1) {
1356
+ encodeHash = true;
1357
+ }
1358
+
1359
+ if (options && options.redirectUri) {
1360
+ return options.redirectUri;
1361
+ } else if (kc.redirectUri) {
1362
+ return kc.redirectUri;
1363
+ } else {
1364
+ return location.href;
1365
+ }
1366
+ }
1367
+ };
1368
+ }
1863
1369
 
1864
- ref.addEventListener("exit", function (event) {
1865
- if (error) {
1866
- promise.setError();
1867
- } else {
1868
- kc.clearToken();
1869
- promise.setSuccess();
1370
+ if (type == 'cordova') {
1371
+ loginIframe.enable = false;
1372
+ var cordovaOpenWindowWrapper = function(loginUrl, target, options) {
1373
+ if (window.cordova && window.cordova.InAppBrowser) {
1374
+ // Use inappbrowser for IOS and Android if available
1375
+ return window.cordova.InAppBrowser.open(loginUrl, target, options);
1376
+ } else {
1377
+ return window.open(loginUrl, target, options);
1378
+ }
1379
+ };
1380
+
1381
+ var shallowCloneCordovaOptions = function (userOptions) {
1382
+ if (userOptions && userOptions.cordovaOptions) {
1383
+ return Object.keys(userOptions.cordovaOptions).reduce(function (options, optionName) {
1384
+ options[optionName] = userOptions.cordovaOptions[optionName];
1385
+ return options;
1386
+ }, {});
1387
+ } else {
1388
+ return {};
1389
+ }
1390
+ };
1391
+
1392
+ var formatCordovaOptions = function (cordovaOptions) {
1393
+ return Object.keys(cordovaOptions).reduce(function (options, optionName) {
1394
+ options.push(optionName+"="+cordovaOptions[optionName]);
1395
+ return options;
1396
+ }, []).join(",");
1397
+ };
1398
+
1399
+ var createCordovaOptions = function (userOptions) {
1400
+ var cordovaOptions = shallowCloneCordovaOptions(userOptions);
1401
+ cordovaOptions.location = 'no';
1402
+ if (userOptions && userOptions.prompt == 'none') {
1403
+ cordovaOptions.hidden = 'yes';
1404
+ }
1405
+ return formatCordovaOptions(cordovaOptions);
1406
+ };
1407
+
1408
+ var getCordovaRedirectUri = function() {
1409
+ return kc.redirectUri || 'http://localhost';
1410
+ }
1411
+
1412
+ return {
1413
+ login: function(options) {
1414
+ var promise = createPromise();
1415
+
1416
+ var cordovaOptions = createCordovaOptions(options);
1417
+ var loginUrl = kc.createLoginUrl(options);
1418
+ var ref = cordovaOpenWindowWrapper(loginUrl, '_blank', cordovaOptions);
1419
+ var completed = false;
1420
+
1421
+ var closed = false;
1422
+ var closeBrowser = function() {
1423
+ closed = true;
1424
+ ref.close();
1425
+ };
1426
+
1427
+ ref.addEventListener('loadstart', function(event) {
1428
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1429
+ var callback = parseCallback(event.url);
1430
+ processCallback(callback, promise);
1431
+ closeBrowser();
1432
+ completed = true;
1433
+ }
1434
+ });
1435
+
1436
+ ref.addEventListener('loaderror', function(event) {
1437
+ if (!completed) {
1438
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1439
+ var callback = parseCallback(event.url);
1440
+ processCallback(callback, promise);
1441
+ closeBrowser();
1442
+ completed = true;
1443
+ } else {
1444
+ promise.setError();
1445
+ closeBrowser();
1446
+ }
1447
+ }
1448
+ });
1449
+
1450
+ ref.addEventListener('exit', function(event) {
1451
+ if (!closed) {
1452
+ promise.setError({
1453
+ reason: "closed_by_user"
1454
+ });
1455
+ }
1456
+ });
1457
+
1458
+ return promise.promise;
1459
+ },
1460
+
1461
+ logout: function(options) {
1462
+ var promise = createPromise();
1463
+
1464
+ var logoutUrl = kc.createLogoutUrl(options);
1465
+ var ref = cordovaOpenWindowWrapper(logoutUrl, '_blank', 'location=no,hidden=yes,clearcache=yes');
1466
+
1467
+ var error;
1468
+
1469
+ ref.addEventListener('loadstart', function(event) {
1470
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1471
+ ref.close();
1472
+ }
1473
+ });
1474
+
1475
+ ref.addEventListener('loaderror', function(event) {
1476
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1477
+ ref.close();
1478
+ } else {
1479
+ error = true;
1480
+ ref.close();
1481
+ }
1482
+ });
1483
+
1484
+ ref.addEventListener('exit', function(event) {
1485
+ if (error) {
1486
+ promise.setError();
1487
+ } else {
1488
+ kc.clearToken();
1489
+ promise.setSuccess();
1490
+ }
1491
+ });
1492
+
1493
+ return promise.promise;
1494
+ },
1495
+
1496
+ register : function(options) {
1497
+ var promise = createPromise();
1498
+ var registerUrl = kc.createRegisterUrl();
1499
+ var cordovaOptions = createCordovaOptions(options);
1500
+ var ref = cordovaOpenWindowWrapper(registerUrl, '_blank', cordovaOptions);
1501
+ ref.addEventListener('loadstart', function(event) {
1502
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1503
+ ref.close();
1504
+ var oauth = parseCallback(event.url);
1505
+ processCallback(oauth, promise);
1506
+ }
1507
+ });
1508
+ return promise.promise;
1509
+ },
1510
+
1511
+ accountManagement : function() {
1512
+ var accountUrl = kc.createAccountUrl();
1513
+ if (typeof accountUrl !== 'undefined') {
1514
+ var ref = cordovaOpenWindowWrapper(accountUrl, '_blank', 'location=no');
1515
+ ref.addEventListener('loadstart', function(event) {
1516
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1517
+ ref.close();
1518
+ }
1519
+ });
1520
+ } else {
1521
+ throw "Not supported by the OIDC server";
1522
+ }
1523
+ },
1524
+
1525
+ redirectUri: function(options) {
1526
+ return getCordovaRedirectUri();
1527
+ }
1870
1528
  }
1871
- });
1872
-
1873
- return promise.promise;
1874
- },
1875
-
1876
- register: function (options) {
1877
- var promise = createPromise();
1878
- var registerUrl = kc.createRegisterUrl();
1879
- var cordovaOptions = createCordovaOptions(options);
1880
- var ref = cordovaOpenWindowWrapper(
1881
- registerUrl,
1882
- "_blank",
1883
- cordovaOptions
1884
- );
1885
-
1886
- ref.addEventListener("loadstart", function (event) {
1887
- if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1888
- ref.close();
1889
- var oauth = parseCallback(event.url);
1890
- processCallback(oauth, promise);
1529
+ }
1530
+
1531
+ if (type == 'cordova-native') {
1532
+ loginIframe.enable = false;
1533
+
1534
+ return {
1535
+ login: function(options) {
1536
+ var promise = createPromise();
1537
+ var loginUrl = kc.createLoginUrl(options);
1538
+
1539
+ universalLinks.subscribe('keycloak', function(event) {
1540
+ universalLinks.unsubscribe('keycloak');
1541
+ window.cordova.plugins.browsertab.close();
1542
+ var oauth = parseCallback(event.url);
1543
+ processCallback(oauth, promise);
1544
+ });
1545
+
1546
+ window.cordova.plugins.browsertab.openUrl(loginUrl);
1547
+ return promise.promise;
1548
+ },
1549
+
1550
+ logout: function(options) {
1551
+ var promise = createPromise();
1552
+ var logoutUrl = kc.createLogoutUrl(options);
1553
+
1554
+ universalLinks.subscribe('keycloak', function(event) {
1555
+ universalLinks.unsubscribe('keycloak');
1556
+ window.cordova.plugins.browsertab.close();
1557
+ kc.clearToken();
1558
+ promise.setSuccess();
1559
+ });
1560
+
1561
+ window.cordova.plugins.browsertab.openUrl(logoutUrl);
1562
+ return promise.promise;
1563
+ },
1564
+
1565
+ register : function(options) {
1566
+ var promise = createPromise();
1567
+ var registerUrl = kc.createRegisterUrl(options);
1568
+ universalLinks.subscribe('keycloak' , function(event) {
1569
+ universalLinks.unsubscribe('keycloak');
1570
+ window.cordova.plugins.browsertab.close();
1571
+ var oauth = parseCallback(event.url);
1572
+ processCallback(oauth, promise);
1573
+ });
1574
+ window.cordova.plugins.browsertab.openUrl(registerUrl);
1575
+ return promise.promise;
1576
+
1577
+ },
1578
+
1579
+ accountManagement : function() {
1580
+ var accountUrl = kc.createAccountUrl();
1581
+ if (typeof accountUrl !== 'undefined') {
1582
+ window.cordova.plugins.browsertab.openUrl(accountUrl);
1583
+ } else {
1584
+ throw "Not supported by the OIDC server";
1585
+ }
1586
+ },
1587
+
1588
+ redirectUri: function(options) {
1589
+ if (options && options.redirectUri) {
1590
+ return options.redirectUri;
1591
+ } else if (kc.redirectUri) {
1592
+ return kc.redirectUri;
1593
+ } else {
1594
+ return "http://localhost";
1595
+ }
1596
+ }
1891
1597
  }
1892
- });
1893
- return promise.promise;
1894
- },
1895
-
1896
- accountManagement: function () {
1897
- var accountUrl = kc.createAccountUrl();
1898
- if (typeof accountUrl !== "undefined") {
1899
- var ref = cordovaOpenWindowWrapper(
1900
- accountUrl,
1901
- "_blank",
1902
- "location=no"
1903
- );
1904
-
1905
- ref.addEventListener("loadstart", function (event) {
1906
- if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1907
- ref.close();
1908
- }
1909
- });
1910
- } else {
1911
- throw "Not supported by the OIDC server";
1912
- }
1913
- },
1914
-
1915
- redirectUri: function (options) {
1916
- return getCordovaRedirectUri();
1917
- },
1918
- };
1919
- }
1598
+ }
1920
1599
 
1921
- if (type == "cordova-native") {
1922
- loginIframe.enable = false;
1923
-
1924
- return {
1925
- login: function (options) {
1926
- var promise = createPromise();
1927
- var loginUrl = kc.createLoginUrl(options);
1928
-
1929
- universalLinks.subscribe("keycloak", function (event) {
1930
- universalLinks.unsubscribe("keycloak");
1931
- window.cordova.plugins.browsertab.close();
1932
- var oauth = parseCallback(event.url);
1933
- processCallback(oauth, promise);
1934
- });
1935
-
1936
- window.cordova.plugins.browsertab.openUrl(loginUrl);
1937
- return promise.promise;
1938
- },
1939
-
1940
- logout: function (options) {
1941
- var promise = createPromise();
1942
- var logoutUrl = kc.createLogoutUrl(options);
1943
-
1944
- universalLinks.subscribe("keycloak", function (event) {
1945
- universalLinks.unsubscribe("keycloak");
1946
- window.cordova.plugins.browsertab.close();
1947
- kc.clearToken();
1948
- promise.setSuccess();
1949
- });
1950
-
1951
- window.cordova.plugins.browsertab.openUrl(logoutUrl);
1952
- return promise.promise;
1953
- },
1954
-
1955
- register: function (options) {
1956
- var promise = createPromise();
1957
- var registerUrl = kc.createRegisterUrl(options);
1958
- universalLinks.subscribe("keycloak", function (event) {
1959
- universalLinks.unsubscribe("keycloak");
1960
- window.cordova.plugins.browsertab.close();
1961
- var oauth = parseCallback(event.url);
1962
- processCallback(oauth, promise);
1963
- });
1964
- window.cordova.plugins.browsertab.openUrl(registerUrl);
1965
- return promise.promise;
1966
- },
1967
-
1968
- accountManagement: function () {
1969
- var accountUrl = kc.createAccountUrl();
1970
- if (typeof accountUrl !== "undefined") {
1971
- window.cordova.plugins.browsertab.openUrl(accountUrl);
1972
- } else {
1973
- throw "Not supported by the OIDC server";
1974
- }
1975
- },
1976
-
1977
- redirectUri: function (options) {
1978
- if (options && options.redirectUri) {
1979
- return options.redirectUri;
1980
- } else if (kc.redirectUri) {
1981
- return kc.redirectUri;
1982
- } else {
1983
- return "http://localhost";
1984
- }
1985
- },
1986
- };
1600
+ throw 'invalid adapter type: ' + type;
1987
1601
  }
1988
1602
 
1989
- throw "invalid adapter type: " + type;
1990
- }
1991
-
1992
- var LocalStorage = function () {
1993
- if (!(this instanceof LocalStorage)) {
1994
- return new LocalStorage();
1995
- }
1603
+ var LocalStorage = function() {
1604
+ if (!(this instanceof LocalStorage)) {
1605
+ return new LocalStorage();
1606
+ }
1996
1607
 
1997
- localStorage.setItem("kc-test", "test");
1998
- localStorage.removeItem("kc-test");
1999
-
2000
- var cs = this;
2001
-
2002
- function clearExpired() {
2003
- var time = new Date().getTime();
2004
- for (var i = 0; i < localStorage.length; i++) {
2005
- var key = localStorage.key(i);
2006
- if (key && key.indexOf("kc-callback-") == 0) {
2007
- var value = localStorage.getItem(key);
2008
- if (value) {
2009
- try {
2010
- var expires = JSON.parse(value).expires;
2011
- if (!expires || expires < time) {
2012
- localStorage.removeItem(key);
2013
- }
2014
- } catch (err) {
2015
- localStorage.removeItem(key);
1608
+ localStorage.setItem('kc-test', 'test');
1609
+ localStorage.removeItem('kc-test');
1610
+
1611
+ var cs = this;
1612
+
1613
+ function clearExpired() {
1614
+ var time = new Date().getTime();
1615
+ for (var i = 0; i < localStorage.length; i++) {
1616
+ var key = localStorage.key(i);
1617
+ if (key && key.indexOf('kc-callback-') == 0) {
1618
+ var value = localStorage.getItem(key);
1619
+ if (value) {
1620
+ try {
1621
+ var expires = JSON.parse(value).expires;
1622
+ if (!expires || expires < time) {
1623
+ localStorage.removeItem(key);
1624
+ }
1625
+ } catch (err) {
1626
+ localStorage.removeItem(key);
1627
+ }
1628
+ }
1629
+ }
2016
1630
  }
2017
- }
2018
1631
  }
2019
- }
2020
- }
2021
1632
 
2022
- cs.get = function (state) {
2023
- if (!state) {
2024
- return;
2025
- }
1633
+ cs.get = function(state) {
1634
+ if (!state) {
1635
+ return;
1636
+ }
2026
1637
 
2027
- var key = "kc-callback-" + state;
2028
- var value = localStorage.getItem(key);
2029
- if (value) {
2030
- localStorage.removeItem(key);
2031
- value = JSON.parse(value);
2032
- }
1638
+ var key = 'kc-callback-' + state;
1639
+ var value = localStorage.getItem(key);
1640
+ if (value) {
1641
+ localStorage.removeItem(key);
1642
+ value = JSON.parse(value);
1643
+ }
2033
1644
 
2034
- clearExpired();
2035
- return value;
2036
- };
1645
+ clearExpired();
1646
+ return value;
1647
+ };
2037
1648
 
2038
- cs.add = function (state) {
2039
- clearExpired();
1649
+ cs.add = function(state) {
1650
+ clearExpired();
2040
1651
 
2041
- var key = "kc-callback-" + state.state;
2042
- state.expires = new Date().getTime() + 60 * 60 * 1000;
2043
- localStorage.setItem(key, JSON.stringify(state));
1652
+ var key = 'kc-callback-' + state.state;
1653
+ state.expires = new Date().getTime() + (60 * 60 * 1000);
1654
+ localStorage.setItem(key, JSON.stringify(state));
1655
+ };
2044
1656
  };
2045
- };
2046
1657
 
2047
- var CookieStorage = function () {
2048
- if (!(this instanceof CookieStorage)) {
2049
- return new CookieStorage();
2050
- }
1658
+ var CookieStorage = function() {
1659
+ if (!(this instanceof CookieStorage)) {
1660
+ return new CookieStorage();
1661
+ }
2051
1662
 
2052
- var cs = this;
1663
+ var cs = this;
2053
1664
 
2054
- cs.get = function (state) {
2055
- if (!state) {
2056
- return;
2057
- }
1665
+ cs.get = function(state) {
1666
+ if (!state) {
1667
+ return;
1668
+ }
2058
1669
 
2059
- var value = getCookie("kc-callback-" + state);
2060
- setCookie("kc-callback-" + state, "", cookieExpiration(-100));
2061
- if (value) {
2062
- return JSON.parse(value);
2063
- }
2064
- };
1670
+ var value = getCookie('kc-callback-' + state);
1671
+ setCookie('kc-callback-' + state, '', cookieExpiration(-100));
1672
+ if (value) {
1673
+ return JSON.parse(value);
1674
+ }
1675
+ };
2065
1676
 
2066
- cs.add = function (state) {
2067
- setCookie(
2068
- "kc-callback-" + state.state,
2069
- JSON.stringify(state),
2070
- cookieExpiration(60)
2071
- );
2072
- };
1677
+ cs.add = function(state) {
1678
+ setCookie('kc-callback-' + state.state, JSON.stringify(state), cookieExpiration(60));
1679
+ };
2073
1680
 
2074
- cs.removeItem = function (key) {
2075
- setCookie(key, "", cookieExpiration(-100));
2076
- };
1681
+ cs.removeItem = function(key) {
1682
+ setCookie(key, '', cookieExpiration(-100));
1683
+ };
2077
1684
 
2078
- var cookieExpiration = function (minutes) {
2079
- var exp = new Date();
2080
- exp.setTime(exp.getTime() + minutes * 60 * 1000);
2081
- return exp;
2082
- };
1685
+ var cookieExpiration = function (minutes) {
1686
+ var exp = new Date();
1687
+ exp.setTime(exp.getTime() + (minutes*60*1000));
1688
+ return exp;
1689
+ };
2083
1690
 
2084
- var getCookie = function (key) {
2085
- var name = key + "=";
2086
- var ca = document.cookie.split(";");
2087
- for (var i = 0; i < ca.length; i++) {
2088
- var c = ca[i];
2089
- while (c.charAt(0) == " ") {
2090
- c = c.substring(1);
2091
- }
2092
- if (c.indexOf(name) == 0) {
2093
- return c.substring(name.length, c.length);
2094
- }
2095
- }
2096
- return "";
2097
- };
1691
+ var getCookie = function (key) {
1692
+ var name = key + '=';
1693
+ var ca = document.cookie.split(';');
1694
+ for (var i = 0; i < ca.length; i++) {
1695
+ var c = ca[i];
1696
+ while (c.charAt(0) == ' ') {
1697
+ c = c.substring(1);
1698
+ }
1699
+ if (c.indexOf(name) == 0) {
1700
+ return c.substring(name.length, c.length);
1701
+ }
1702
+ }
1703
+ return '';
1704
+ };
2098
1705
 
2099
- var setCookie = function (key, value, expirationDate) {
2100
- var cookie =
2101
- key +
2102
- "=" +
2103
- value +
2104
- "; " +
2105
- "expires=" +
2106
- expirationDate.toUTCString() +
2107
- "; ";
2108
-
2109
- document.cookie = cookie;
1706
+ var setCookie = function (key, value, expirationDate) {
1707
+ var cookie = key + '=' + value + '; '
1708
+ + 'expires=' + expirationDate.toUTCString() + '; ';
1709
+ document.cookie = cookie;
1710
+ }
2110
1711
  };
2111
- };
2112
1712
 
2113
- function createCallbackStorage() {
2114
- try {
2115
- return new LocalStorage();
2116
- } catch (err) {}
1713
+ function createCallbackStorage() {
1714
+ try {
1715
+ return new LocalStorage();
1716
+ } catch (err) {
1717
+ }
2117
1718
 
2118
- return new CookieStorage();
2119
- }
1719
+ return new CookieStorage();
1720
+ }
2120
1721
 
2121
- function createLogger(fn) {
2122
- return function () {
2123
- if (kc.enableLogging) {
2124
- fn.apply(console, Array.prototype.slice.call(arguments));
2125
- }
2126
- };
2127
- }
1722
+ function createLogger(fn) {
1723
+ return function() {
1724
+ if (kc.enableLogging) {
1725
+ fn.apply(console, Array.prototype.slice.call(arguments));
1726
+ }
1727
+ };
1728
+ }
2128
1729
  }
2129
1730
 
2130
- export default Keycloak;
2131
-
2132
- // See: https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem
2133
- function bytesToBase64(bytes) {
2134
- const binString = String.fromCodePoint(...bytes);
2135
- return btoa(binString);
2136
- }
1731
+ export default Keycloak;