@luizleon/sf.prefeiturasp.vuecomponents 0.0.64 → 0.0.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/axios/axiosClient.d.ts +0 -7
- package/dist/components/button/Button.d.ts +7 -7
- package/dist/components/content/Content.d.ts +1 -1
- package/dist/components/drawer/Drawer.d.ts +6 -6
- package/dist/components/icon/Icon.d.ts +7 -7
- package/dist/components/internal/HeaderAvatar.d.ts +2 -2
- package/dist/components/internal/LoadingCircle.d.ts +1 -1
- package/dist/components/internal/MenuIcon.d.ts +1 -1
- package/dist/components/internal/ScrollToTop.d.ts +1 -1
- package/dist/components/internal/ThemeToggle.d.ts +1 -1
- package/dist/components/layout/Layout.d.ts +2 -2
- package/dist/components/message/Message.d.ts +5 -5
- package/dist/components/navmenulink/NavMenuLink.d.ts +1 -1
- package/dist/components/panelmenu/PanelMenu.d.ts +3 -3
- package/dist/components/tabnavigation/TabNavigation.d.ts +1 -1
- package/dist/components/tooltip/Tooltip.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/sf.prefeiturasp.vuecomponents.es.js +4181 -3299
- package/dist/sf.prefeiturasp.vuecomponents.es.js.map +1 -1
- package/dist/sf.prefeiturasp.vuecomponents.umd.js +58 -60
- package/dist/sf.prefeiturasp.vuecomponents.umd.js.map +1 -1
- package/package.json +2 -1
- package/src/axios/axiosClient.ts +3 -111
- package/src/index.ts +5 -1
- package/src/keycloak.js +1890 -1485
package/src/keycloak.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/** 04/09/2024
|
|
2
|
+
* https://github.com/keycloak/keycloak/blob/main/js/libs/keycloak-js/src/keycloak.js
|
|
3
|
+
*/
|
|
4
|
+
|
|
1
5
|
/*
|
|
2
6
|
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
|
3
7
|
* and other contributors as indicated by the @author tags.
|
|
@@ -15,1717 +19,2118 @@
|
|
|
15
19
|
* limitations under the License.
|
|
16
20
|
*/
|
|
17
21
|
|
|
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';
|
|
22
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
23
|
+
import { jwtDecode } from "jwt-decode";
|
|
32
24
|
|
|
33
|
-
if (typeof Promise ===
|
|
34
|
-
|
|
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
|
+
);
|
|
35
29
|
}
|
|
36
30
|
|
|
37
|
-
function Keycloak
|
|
38
|
-
|
|
39
|
-
|
|
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];
|
|
40
61
|
}
|
|
62
|
+
}
|
|
41
63
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
var callbackStorage;
|
|
64
|
+
var useNonce = true;
|
|
65
|
+
var logInfo = createLogger(console.info);
|
|
66
|
+
var logWarn = createLogger(console.warn);
|
|
46
67
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
}
|
|
68
|
+
kc.init = function (initOptions) {
|
|
69
|
+
if (kc.didInitialize) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
"A 'Keycloak' instance can only be initialized once."
|
|
72
|
+
);
|
|
58
73
|
}
|
|
59
74
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
+
}
|
|
95
|
+
}
|
|
75
96
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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;
|
|
80
120
|
} else {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
+
}
|
|
141
206
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
207
|
+
if (!kc.responseMode) {
|
|
208
|
+
kc.responseMode = "fragment";
|
|
209
|
+
}
|
|
210
|
+
if (!kc.responseType) {
|
|
211
|
+
kc.responseType = "code";
|
|
212
|
+
kc.flow = "standard";
|
|
213
|
+
}
|
|
147
214
|
|
|
148
|
-
|
|
149
|
-
if (initOptions.pkceMethod !== "S256") {
|
|
150
|
-
throw 'Invalid value for pkceMethod';
|
|
151
|
-
}
|
|
152
|
-
kc.pkceMethod = initOptions.pkceMethod;
|
|
153
|
-
}
|
|
215
|
+
var promise = createPromise();
|
|
154
216
|
|
|
155
|
-
|
|
156
|
-
kc.enableLogging = initOptions.enableLogging;
|
|
157
|
-
} else {
|
|
158
|
-
kc.enableLogging = false;
|
|
159
|
-
}
|
|
217
|
+
var initPromise = createPromise();
|
|
160
218
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
+
});
|
|
164
227
|
|
|
165
|
-
|
|
166
|
-
kc.acrValues = initOptions.acrValues;
|
|
167
|
-
}
|
|
228
|
+
var configPromise = loadConfig(config);
|
|
168
229
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
230
|
+
function onLoad() {
|
|
231
|
+
var doLogin = function (prompt) {
|
|
232
|
+
if (!prompt) {
|
|
233
|
+
options.prompt = "none";
|
|
174
234
|
}
|
|
175
235
|
|
|
176
|
-
if (
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
if (!kc.responseType) {
|
|
180
|
-
kc.responseType = 'code';
|
|
181
|
-
kc.flow = 'standard';
|
|
236
|
+
if (initOptions && initOptions.locale) {
|
|
237
|
+
options.locale = initOptions.locale;
|
|
182
238
|
}
|
|
239
|
+
kc.login(options)
|
|
240
|
+
.then(function () {
|
|
241
|
+
initPromise.setSuccess();
|
|
242
|
+
})
|
|
243
|
+
.catch(function (error) {
|
|
244
|
+
initPromise.setError(error);
|
|
245
|
+
});
|
|
246
|
+
};
|
|
183
247
|
|
|
184
|
-
|
|
248
|
+
var checkSsoSilently = function () {
|
|
249
|
+
var ifrm = document.createElement("iframe");
|
|
185
250
|
|
|
186
|
-
var
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
promise.setSuccess(kc.authenticated);
|
|
190
|
-
}).catch(function(error) {
|
|
191
|
-
promise.setError(error);
|
|
251
|
+
var src = kc.createLoginUrl({
|
|
252
|
+
prompt: "none",
|
|
253
|
+
redirectUri: kc.silentCheckSsoRedirectUri,
|
|
192
254
|
});
|
|
193
255
|
|
|
194
|
-
|
|
256
|
+
ifrm.setAttribute("src", src);
|
|
195
257
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
258
|
+
ifrm.setAttribute(
|
|
259
|
+
"sandbox",
|
|
260
|
+
"allow-storage-access-by-user-activation allow-scripts allow-same-origin"
|
|
261
|
+
);
|
|
201
262
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
kc.login(options).then(function () {
|
|
206
|
-
initPromise.setSuccess();
|
|
207
|
-
}).catch(function (error) {
|
|
208
|
-
initPromise.setError(error);
|
|
209
|
-
});
|
|
210
|
-
}
|
|
263
|
+
ifrm.setAttribute("title", "keycloak-silent-check-sso");
|
|
264
|
+
ifrm.style.display = "none";
|
|
265
|
+
document.body.appendChild(ifrm);
|
|
211
266
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
}
|
|
267
|
+
var messageCallback = function (event) {
|
|
268
|
+
if (
|
|
269
|
+
event.origin !== window.location.origin ||
|
|
270
|
+
ifrm.contentWindow !== event.source
|
|
271
|
+
) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
262
274
|
|
|
263
|
-
|
|
264
|
-
|
|
275
|
+
var oauth = parseCallback(event.data);
|
|
276
|
+
processCallback(oauth, initPromise);
|
|
265
277
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
278
|
+
document.body.removeChild(ifrm);
|
|
279
|
+
window.removeEventListener("message", messageCallback);
|
|
280
|
+
};
|
|
269
281
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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 {
|
|
297
|
+
initPromise.setSuccess();
|
|
298
|
+
}
|
|
299
|
+
})
|
|
300
|
+
.catch(function (error) {
|
|
301
|
+
initPromise.setError(error);
|
|
275
302
|
});
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
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
|
+
}
|
|
317
|
+
|
|
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();
|
|
310
351
|
initPromise.setSuccess();
|
|
311
|
-
|
|
312
|
-
|
|
352
|
+
scheduleCheckIframe();
|
|
353
|
+
} else {
|
|
354
|
+
initPromise.setSuccess();
|
|
355
|
+
}
|
|
356
|
+
})
|
|
357
|
+
.catch(function (error) {
|
|
358
|
+
initPromise.setError(error);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
} else {
|
|
362
|
+
kc.updateToken(-1)
|
|
363
|
+
.then(function () {
|
|
364
|
+
kc.onAuthSuccess && kc.onAuthSuccess();
|
|
313
365
|
initPromise.setSuccess();
|
|
314
|
-
|
|
366
|
+
})
|
|
367
|
+
.catch(function (error) {
|
|
368
|
+
kc.onAuthError && kc.onAuthError();
|
|
369
|
+
if (initOptions.onLoad) {
|
|
370
|
+
onLoad();
|
|
371
|
+
} else {
|
|
372
|
+
initPromise.setError(error);
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
} else if (initOptions.onLoad) {
|
|
377
|
+
onLoad();
|
|
378
|
+
} else {
|
|
379
|
+
initPromise.setSuccess();
|
|
315
380
|
}
|
|
381
|
+
} else {
|
|
382
|
+
initPromise.setSuccess();
|
|
383
|
+
}
|
|
384
|
+
}
|
|
316
385
|
|
|
317
|
-
|
|
318
|
-
|
|
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);
|
|
386
|
+
function domReady() {
|
|
387
|
+
var promise = createPromise();
|
|
327
388
|
|
|
328
|
-
|
|
389
|
+
var checkReadyState = function () {
|
|
390
|
+
if (
|
|
391
|
+
document.readyState === "interactive" ||
|
|
392
|
+
document.readyState === "complete"
|
|
393
|
+
) {
|
|
394
|
+
document.removeEventListener(
|
|
395
|
+
"readystatechange",
|
|
396
|
+
checkReadyState
|
|
397
|
+
);
|
|
329
398
|
|
|
330
|
-
|
|
399
|
+
promise.setSuccess();
|
|
331
400
|
}
|
|
401
|
+
};
|
|
332
402
|
|
|
333
|
-
|
|
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
|
-
});
|
|
403
|
+
document.addEventListener("readystatechange", checkReadyState);
|
|
344
404
|
|
|
345
|
-
|
|
346
|
-
}
|
|
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)
|
|
347
406
|
|
|
348
|
-
|
|
349
|
-
return adapter.login(options);
|
|
407
|
+
return promise.promise;
|
|
350
408
|
}
|
|
351
409
|
|
|
352
|
-
function
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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;
|
|
368
437
|
}
|
|
369
438
|
|
|
370
|
-
|
|
371
|
-
|
|
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());
|
|
372
443
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
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
|
-
}
|
|
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);
|
|
397
459
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
|
|
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
|
+
);
|
|
406
468
|
}
|
|
407
469
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
baseUrl = kc.endpoints.register();
|
|
427
|
-
} else {
|
|
428
|
-
baseUrl = kc.endpoints.authorize();
|
|
429
|
-
}
|
|
430
|
-
|
|
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
|
-
}
|
|
439
|
-
|
|
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
|
-
}
|
|
450
|
-
|
|
451
|
-
if (options && options.prompt) {
|
|
452
|
-
url += '&prompt=' + encodeURIComponent(options.prompt);
|
|
453
|
-
}
|
|
454
|
-
|
|
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
|
-
}
|
|
470
|
-
|
|
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
|
-
}
|
|
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
|
+
}
|
|
479
488
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
489
|
+
kc.createLoginUrl = function (options) {
|
|
490
|
+
var state = createUUID();
|
|
491
|
+
var nonce = createUUID();
|
|
483
492
|
|
|
484
|
-
|
|
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
|
-
}
|
|
493
|
+
var redirectUri = adapter.redirectUri(options);
|
|
491
494
|
|
|
492
|
-
|
|
495
|
+
var callbackState = {
|
|
496
|
+
state: state,
|
|
497
|
+
nonce: nonce,
|
|
498
|
+
redirectUri: encodeURIComponent(redirectUri),
|
|
499
|
+
loginOptions: options,
|
|
500
|
+
};
|
|
493
501
|
|
|
494
|
-
|
|
502
|
+
if (options && options.prompt) {
|
|
503
|
+
callbackState.prompt = options.prompt;
|
|
495
504
|
}
|
|
496
505
|
|
|
497
|
-
|
|
498
|
-
|
|
506
|
+
var baseUrl;
|
|
507
|
+
if (options && options.action == "register") {
|
|
508
|
+
baseUrl = kc.endpoints.register();
|
|
509
|
+
} else {
|
|
510
|
+
baseUrl = kc.endpoints.authorize();
|
|
499
511
|
}
|
|
500
512
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
return url;
|
|
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;
|
|
511
520
|
}
|
|
512
521
|
|
|
513
|
-
|
|
514
|
-
|
|
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);
|
|
515
538
|
}
|
|
516
539
|
|
|
517
|
-
|
|
518
|
-
|
|
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;
|
|
540
|
+
if (options && options.prompt) {
|
|
541
|
+
url += "&prompt=" + encodeURIComponent(options.prompt);
|
|
535
542
|
}
|
|
536
543
|
|
|
537
|
-
|
|
538
|
-
|
|
544
|
+
if (options && options.maxAge) {
|
|
545
|
+
url += "&max_age=" + encodeURIComponent(options.maxAge);
|
|
539
546
|
}
|
|
540
547
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
return !!access && access.roles.indexOf(role) >= 0;
|
|
548
|
+
if (options && options.loginHint) {
|
|
549
|
+
url += "&login_hint=" + encodeURIComponent(options.loginHint);
|
|
544
550
|
}
|
|
545
551
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
}
|
|
552
|
+
if (options && options.idpHint) {
|
|
553
|
+
url += "&kc_idp_hint=" + encodeURIComponent(options.idpHint);
|
|
554
|
+
}
|
|
550
555
|
|
|
551
|
-
|
|
552
|
-
|
|
556
|
+
if (options && options.action && options.action != "register") {
|
|
557
|
+
url += "&kc_action=" + encodeURIComponent(options.action);
|
|
553
558
|
}
|
|
554
559
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
req.open('GET', url, true);
|
|
559
|
-
req.setRequestHeader('Accept', 'application/json');
|
|
560
|
-
req.setRequestHeader('Authorization', 'bearer ' + kc.token);
|
|
560
|
+
if (options && options.locale) {
|
|
561
|
+
url += "&ui_locales=" + encodeURIComponent(options.locale);
|
|
562
|
+
}
|
|
561
563
|
|
|
562
|
-
|
|
564
|
+
if (options && options.acr) {
|
|
565
|
+
var claimsParameter = buildClaimsParameter(options.acr);
|
|
566
|
+
url += "&claims=" + encodeURIComponent(claimsParameter);
|
|
567
|
+
}
|
|
563
568
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
} else {
|
|
570
|
-
promise.setError();
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
}
|
|
569
|
+
if ((options && options.acrValues) || kc.acrValues) {
|
|
570
|
+
url +=
|
|
571
|
+
"&acr_values=" +
|
|
572
|
+
encodeURIComponent(options.acrValues || kc.acrValues);
|
|
573
|
+
}
|
|
574
574
|
|
|
575
|
-
|
|
575
|
+
if (kc.pkceMethod) {
|
|
576
|
+
var codeVerifier = generateCodeVerifier(96);
|
|
577
|
+
callbackState.pkceCodeVerifier = codeVerifier;
|
|
578
|
+
var pkceChallenge = generatePkceChallenge(
|
|
579
|
+
kc.pkceMethod,
|
|
580
|
+
codeVerifier
|
|
581
|
+
);
|
|
576
582
|
|
|
577
|
-
|
|
583
|
+
url += "&code_challenge=" + pkceChallenge;
|
|
584
|
+
url += "&code_challenge_method=" + kc.pkceMethod;
|
|
578
585
|
}
|
|
579
586
|
|
|
580
|
-
|
|
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);
|
|
587
|
+
callbackStorage.add(callbackState);
|
|
586
588
|
|
|
587
|
-
|
|
589
|
+
return url;
|
|
590
|
+
};
|
|
588
591
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
kc.userInfo = JSON.parse(req.responseText);
|
|
593
|
-
promise.setSuccess(kc.userInfo);
|
|
594
|
-
} else {
|
|
595
|
-
promise.setError();
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
req.send();
|
|
592
|
+
kc.logout = function (options) {
|
|
593
|
+
return adapter.logout(options);
|
|
594
|
+
};
|
|
601
595
|
|
|
602
|
-
|
|
596
|
+
kc.createLogoutUrl = function (options) {
|
|
597
|
+
const logoutMethod = options?.logoutMethod ?? kc.logoutMethod;
|
|
598
|
+
if (logoutMethod === "POST") {
|
|
599
|
+
return kc.endpoints.logout();
|
|
603
600
|
}
|
|
604
601
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
logInfo('[KEYCLOAK] Unable to determine if token is expired as timeskew is not set');
|
|
612
|
-
return true;
|
|
613
|
-
}
|
|
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));
|
|
614
608
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
if (isNaN(minValidity)) {
|
|
618
|
-
throw 'Invalid minValidity';
|
|
619
|
-
}
|
|
620
|
-
expiresIn -= minValidity;
|
|
621
|
-
}
|
|
622
|
-
return expiresIn < 0;
|
|
609
|
+
if (kc.idToken) {
|
|
610
|
+
url += "&id_token_hint=" + encodeURIComponent(kc.idToken);
|
|
623
611
|
}
|
|
624
612
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
if (!kc.refreshToken) {
|
|
629
|
-
promise.setError();
|
|
630
|
-
return promise.promise;
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
minValidity = minValidity || 5;
|
|
613
|
+
return url;
|
|
614
|
+
};
|
|
634
615
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
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
|
-
}
|
|
644
|
-
|
|
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();
|
|
616
|
+
kc.register = function (options) {
|
|
617
|
+
return adapter.register(options);
|
|
618
|
+
};
|
|
650
619
|
|
|
651
|
-
|
|
620
|
+
kc.createRegisterUrl = function (options) {
|
|
621
|
+
if (!options) {
|
|
622
|
+
options = {};
|
|
623
|
+
}
|
|
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
|
+
};
|
|
652
642
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
|
657
|
-
req.withCredentials = true;
|
|
643
|
+
kc.accountManagement = function () {
|
|
644
|
+
return adapter.accountManagement();
|
|
645
|
+
};
|
|
658
646
|
|
|
659
|
-
|
|
647
|
+
kc.hasRealmRole = function (role) {
|
|
648
|
+
var access = kc.realmAccess;
|
|
649
|
+
return !!access && access.roles.indexOf(role) >= 0;
|
|
650
|
+
};
|
|
660
651
|
|
|
661
|
-
|
|
652
|
+
kc.hasResourceRole = function (role, resource) {
|
|
653
|
+
if (!kc.resourceAccess) {
|
|
654
|
+
return false;
|
|
655
|
+
}
|
|
662
656
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
logInfo('[KEYCLOAK] Token refreshed');
|
|
657
|
+
var access = kc.resourceAccess[resource || kc.clientId];
|
|
658
|
+
return !!access && access.roles.indexOf(role) >= 0;
|
|
659
|
+
};
|
|
667
660
|
|
|
668
|
-
|
|
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);
|
|
669
667
|
|
|
670
|
-
|
|
668
|
+
var promise = createPromise();
|
|
671
669
|
|
|
672
|
-
|
|
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
|
+
};
|
|
673
680
|
|
|
674
|
-
|
|
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');
|
|
681
|
+
req.send();
|
|
680
682
|
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
}
|
|
683
|
+
return promise.promise;
|
|
684
|
+
};
|
|
684
685
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
};
|
|
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);
|
|
692
692
|
|
|
693
|
-
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
}
|
|
693
|
+
var promise = createPromise();
|
|
697
694
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
promise.setError(error);
|
|
704
|
-
});
|
|
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);
|
|
705
700
|
} else {
|
|
706
|
-
|
|
701
|
+
promise.setError();
|
|
707
702
|
}
|
|
703
|
+
}
|
|
704
|
+
};
|
|
708
705
|
|
|
709
|
-
|
|
710
|
-
}
|
|
711
|
-
|
|
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
|
-
}
|
|
720
|
-
}
|
|
706
|
+
req.send();
|
|
721
707
|
|
|
722
|
-
|
|
708
|
+
return promise.promise;
|
|
709
|
+
};
|
|
723
710
|
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
}
|
|
731
|
-
} else {
|
|
732
|
-
return undefined;
|
|
733
|
-
}
|
|
711
|
+
kc.isTokenExpired = function (minValidity) {
|
|
712
|
+
if (
|
|
713
|
+
!kc.tokenParsed ||
|
|
714
|
+
(!kc.refreshToken && kc.flow != "implicit")
|
|
715
|
+
) {
|
|
716
|
+
throw "Not authenticated";
|
|
734
717
|
}
|
|
735
718
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
719
|
+
if (kc.timeSkew == null) {
|
|
720
|
+
logInfo(
|
|
721
|
+
"[KEYCLOAK] Unable to determine if token is expired as timeskew is not set"
|
|
722
|
+
);
|
|
723
|
+
|
|
724
|
+
return true;
|
|
742
725
|
}
|
|
743
726
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
727
|
+
var expiresIn =
|
|
728
|
+
kc.tokenParsed["exp"] -
|
|
729
|
+
Math.ceil(new Date().getTime() / 1000) +
|
|
730
|
+
kc.timeSkew;
|
|
748
731
|
|
|
749
|
-
|
|
732
|
+
if (minValidity) {
|
|
733
|
+
if (isNaN(minValidity)) {
|
|
734
|
+
throw "Invalid minValidity";
|
|
735
|
+
}
|
|
736
|
+
expiresIn -= minValidity;
|
|
737
|
+
}
|
|
738
|
+
return expiresIn < 0;
|
|
739
|
+
};
|
|
750
740
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
}
|
|
741
|
+
kc.updateToken = function (minValidity) {
|
|
742
|
+
var promise = createPromise();
|
|
754
743
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
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
|
-
}
|
|
744
|
+
if (!kc.refreshToken) {
|
|
745
|
+
promise.setError();
|
|
746
|
+
return promise.promise;
|
|
747
|
+
}
|
|
767
748
|
|
|
768
|
-
|
|
769
|
-
var params = 'code=' + code + '&grant_type=authorization_code';
|
|
770
|
-
var url = kc.endpoints.token();
|
|
749
|
+
minValidity = minValidity || 5;
|
|
771
750
|
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
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
|
+
}
|
|
775
760
|
|
|
776
|
-
|
|
777
|
-
|
|
761
|
+
if (!refreshToken) {
|
|
762
|
+
promise.setSuccess(false);
|
|
763
|
+
} else {
|
|
764
|
+
var params =
|
|
765
|
+
"grant_type=refresh_token&" +
|
|
766
|
+
"refresh_token=" +
|
|
767
|
+
kc.refreshToken;
|
|
778
768
|
|
|
779
|
-
|
|
780
|
-
params += '&code_verifier=' + oauth.pkceCodeVerifier;
|
|
781
|
-
}
|
|
769
|
+
var url = kc.endpoints.token();
|
|
782
770
|
|
|
783
|
-
|
|
771
|
+
refreshQueue.push(promise);
|
|
784
772
|
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
773
|
+
if (refreshQueue.length == 1) {
|
|
774
|
+
var req = new XMLHttpRequest();
|
|
775
|
+
req.open("POST", url, true);
|
|
788
776
|
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
kc.onAuthError && kc.onAuthError();
|
|
794
|
-
promise && promise.setError();
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
};
|
|
777
|
+
req.setRequestHeader(
|
|
778
|
+
"Content-type",
|
|
779
|
+
"application/x-www-form-urlencoded"
|
|
780
|
+
);
|
|
798
781
|
|
|
799
|
-
|
|
800
|
-
}
|
|
782
|
+
req.withCredentials = true;
|
|
801
783
|
|
|
802
|
-
|
|
803
|
-
timeLocal = (timeLocal + new Date().getTime()) / 2;
|
|
784
|
+
params += "&client_id=" + encodeURIComponent(kc.clientId);
|
|
804
785
|
|
|
805
|
-
|
|
786
|
+
var timeLocal = new Date().getTime();
|
|
806
787
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
788
|
+
req.onreadystatechange = function () {
|
|
789
|
+
if (req.readyState == 4) {
|
|
790
|
+
if (req.status == 200) {
|
|
791
|
+
logInfo("[KEYCLOAK] Token refreshed");
|
|
810
792
|
|
|
811
|
-
|
|
812
|
-
kc.clearToken();
|
|
813
|
-
promise && promise.setError();
|
|
814
|
-
} else {
|
|
815
|
-
if (fulfillPromise) {
|
|
816
|
-
kc.onAuthSuccess && kc.onAuthSuccess();
|
|
817
|
-
promise && promise.setSuccess();
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
}
|
|
793
|
+
timeLocal = (timeLocal + new Date().getTime()) / 2;
|
|
821
794
|
|
|
822
|
-
|
|
795
|
+
var tokenResponse = JSON.parse(req.responseText);
|
|
823
796
|
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
797
|
+
setToken(
|
|
798
|
+
tokenResponse["access_token"],
|
|
799
|
+
tokenResponse["refresh_token"],
|
|
800
|
+
tokenResponse["id_token"],
|
|
801
|
+
timeLocal
|
|
802
|
+
);
|
|
827
803
|
|
|
828
|
-
|
|
829
|
-
configUrl = location.origin + '/keycloak.json';
|
|
830
|
-
} else if (typeof config === 'string') {
|
|
831
|
-
configUrl = config;
|
|
832
|
-
}
|
|
804
|
+
kc.onAuthRefreshSuccess && kc.onAuthRefreshSuccess();
|
|
833
805
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
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
|
-
}
|
|
806
|
+
for (
|
|
807
|
+
var p = refreshQueue.pop();
|
|
808
|
+
p != null;
|
|
809
|
+
p = refreshQueue.pop()
|
|
810
|
+
) {
|
|
811
|
+
p.setSuccess(true);
|
|
896
812
|
}
|
|
897
|
-
|
|
898
|
-
|
|
813
|
+
} else {
|
|
814
|
+
logWarn("[KEYCLOAK] Failed to refresh token");
|
|
899
815
|
|
|
900
|
-
|
|
901
|
-
|
|
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
|
-
}
|
|
816
|
+
if (req.status == 400) {
|
|
817
|
+
kc.clearToken();
|
|
918
818
|
}
|
|
919
|
-
};
|
|
920
|
-
|
|
921
|
-
req.send();
|
|
922
|
-
} else {
|
|
923
|
-
if (!config.clientId) {
|
|
924
|
-
throw 'clientId missing';
|
|
925
|
-
}
|
|
926
819
|
|
|
927
|
-
|
|
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
|
-
}
|
|
820
|
+
kc.onAuthRefreshError && kc.onAuthRefreshError();
|
|
943
821
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
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();
|
|
822
|
+
for (
|
|
823
|
+
var p = refreshQueue.pop();
|
|
824
|
+
p != null;
|
|
825
|
+
p = refreshQueue.pop()
|
|
826
|
+
) {
|
|
827
|
+
p.setError(true);
|
|
976
828
|
}
|
|
829
|
+
}
|
|
977
830
|
}
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
req.send(params);
|
|
978
834
|
}
|
|
835
|
+
}
|
|
836
|
+
};
|
|
979
837
|
|
|
980
|
-
|
|
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();
|
|
981
849
|
}
|
|
982
850
|
|
|
983
|
-
|
|
984
|
-
|
|
851
|
+
return promise.promise;
|
|
852
|
+
};
|
|
853
|
+
|
|
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;
|
|
985
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
|
+
}
|
|
986
894
|
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
}
|
|
895
|
+
function processCallback(oauth, promise) {
|
|
896
|
+
var code = oauth.code;
|
|
897
|
+
var error = oauth.error;
|
|
898
|
+
var prompt = oauth.prompt;
|
|
992
899
|
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
900
|
+
var timeLocal = new Date().getTime();
|
|
901
|
+
|
|
902
|
+
if (oauth["kc_action_status"]) {
|
|
903
|
+
kc.onActionUpdate &&
|
|
904
|
+
kc.onActionUpdate(
|
|
905
|
+
oauth["kc_action_status"],
|
|
906
|
+
oauth["kc_action"]
|
|
907
|
+
);
|
|
908
|
+
}
|
|
1000
909
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
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);
|
|
1004
917
|
} else {
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
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
|
+
}
|
|
1008
936
|
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
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
|
-
}
|
|
937
|
+
if (kc.flow != "implicit" && code) {
|
|
938
|
+
var params = "code=" + code + "&grant_type=authorization_code";
|
|
939
|
+
var url = kc.endpoints.token();
|
|
1021
940
|
|
|
1022
|
-
|
|
1023
|
-
|
|
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;
|
|
941
|
+
var req = new XMLHttpRequest();
|
|
942
|
+
req.open("POST", url, true);
|
|
1041
943
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
944
|
+
req.setRequestHeader(
|
|
945
|
+
"Content-type",
|
|
946
|
+
"application/x-www-form-urlencoded"
|
|
947
|
+
);
|
|
1045
948
|
|
|
1046
|
-
|
|
1047
|
-
|
|
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
|
-
}
|
|
949
|
+
params += "&client_id=" + encodeURIComponent(kc.clientId);
|
|
950
|
+
params += "&redirect_uri=" + oauth.redirectUri;
|
|
1055
951
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
return;
|
|
1060
|
-
}
|
|
952
|
+
if (oauth.pkceCodeVerifier) {
|
|
953
|
+
params += "&code_verifier=" + oauth.pkceCodeVerifier;
|
|
954
|
+
}
|
|
1061
955
|
|
|
1062
|
-
|
|
956
|
+
req.withCredentials = true;
|
|
1063
957
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
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
|
+
);
|
|
1071
968
|
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
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;
|
|
969
|
+
scheduleCheckIframe();
|
|
970
|
+
} else {
|
|
971
|
+
kc.onAuthError && kc.onAuthError();
|
|
972
|
+
promise && promise.setError();
|
|
973
|
+
}
|
|
1087
974
|
}
|
|
975
|
+
};
|
|
1088
976
|
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
977
|
+
req.send(params);
|
|
978
|
+
}
|
|
979
|
+
|
|
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
|
+
}
|
|
1092
1006
|
|
|
1093
|
-
|
|
1094
|
-
|
|
1007
|
+
function loadConfig(url) {
|
|
1008
|
+
var promise = createPromise();
|
|
1009
|
+
var configUrl;
|
|
1095
1010
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1011
|
+
if (!config) {
|
|
1012
|
+
configUrl = "keycloak.json";
|
|
1013
|
+
} else if (typeof config === "string") {
|
|
1014
|
+
configUrl = config;
|
|
1015
|
+
}
|
|
1098
1016
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
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;
|
|
1104
1035
|
}
|
|
1105
|
-
|
|
1106
|
-
|
|
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;
|
|
1107
1044
|
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
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";
|
|
1113
1069
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
if (
|
|
1118
|
-
|
|
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
|
-
}
|
|
1070
|
+
return oidcConfiguration.end_session_endpoint;
|
|
1071
|
+
},
|
|
1072
|
+
checkSessionIframe: function () {
|
|
1073
|
+
if (!oidcConfiguration.check_session_iframe) {
|
|
1074
|
+
throw "Not supported by the OIDC server";
|
|
1127
1075
|
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
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];
|
|
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";
|
|
1147
1084
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
1085
|
+
return oidcConfiguration.userinfo_endpoint;
|
|
1086
|
+
},
|
|
1087
|
+
};
|
|
1088
|
+
}
|
|
1150
1089
|
}
|
|
1151
1090
|
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
setSuccess: function(result) {
|
|
1157
|
-
p.resolve(result);
|
|
1158
|
-
},
|
|
1091
|
+
if (configUrl) {
|
|
1092
|
+
var req = new XMLHttpRequest();
|
|
1093
|
+
req.open("GET", configUrl, true);
|
|
1094
|
+
req.setRequestHeader("Accept", "application/json");
|
|
1159
1095
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1096
|
+
req.onreadystatechange = function () {
|
|
1097
|
+
if (req.readyState == 4) {
|
|
1098
|
+
if (req.status == 200 || fileLoaded(req)) {
|
|
1099
|
+
var config = JSON.parse(req.responseText);
|
|
1100
|
+
|
|
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;
|
|
1162
1132
|
}
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
}
|
|
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
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
};
|
|
1168
1168
|
|
|
1169
|
-
|
|
1169
|
+
req.send();
|
|
1170
|
+
} else {
|
|
1171
|
+
setupOidcEndoints(oidcProvider);
|
|
1172
|
+
promise.setSuccess();
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1170
1175
|
}
|
|
1171
1176
|
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
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;
|
|
1192
|
+
}
|
|
1180
1193
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1194
|
+
if (refreshToken) {
|
|
1195
|
+
kc.refreshToken = refreshToken;
|
|
1196
|
+
kc.refreshTokenParsed = jwtDecode(refreshToken);
|
|
1197
|
+
} else {
|
|
1198
|
+
delete kc.refreshToken;
|
|
1199
|
+
delete kc.refreshTokenParsed;
|
|
1184
1200
|
}
|
|
1185
1201
|
|
|
1186
|
-
|
|
1187
|
-
|
|
1202
|
+
if (idToken) {
|
|
1203
|
+
kc.idToken = idToken;
|
|
1204
|
+
kc.idTokenParsed = jwtDecode(idToken);
|
|
1205
|
+
} else {
|
|
1206
|
+
delete kc.idToken;
|
|
1207
|
+
delete kc.idTokenParsed;
|
|
1208
|
+
}
|
|
1188
1209
|
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
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;
|
|
1279
|
+
}
|
|
1193
1280
|
|
|
1194
|
-
|
|
1195
|
-
promise.setSuccess();
|
|
1196
|
-
return promise.promise;
|
|
1197
|
-
}
|
|
1281
|
+
var oauthState = callbackStorage.get(oauth.state);
|
|
1198
1282
|
|
|
1199
|
-
|
|
1200
|
-
|
|
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;
|
|
1290
|
+
}
|
|
1201
1291
|
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
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
|
+
}
|
|
1211
1339
|
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
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
|
+
}
|
|
1218
1382
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
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
|
+
}
|
|
1223
1404
|
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
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
|
+
}
|
|
1227
1475
|
|
|
1476
|
+
if (loginIframe.iframe) {
|
|
1477
|
+
promise.setSuccess();
|
|
1478
|
+
return promise.promise;
|
|
1479
|
+
}
|
|
1228
1480
|
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
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
|
+
};
|
|
1232
1496
|
|
|
1233
|
-
|
|
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
|
+
};
|
|
1234
1545
|
|
|
1235
|
-
|
|
1236
|
-
var promise = callbacks[i];
|
|
1237
|
-
if (event.data == 'error') {
|
|
1238
|
-
promise.setError();
|
|
1239
|
-
} else {
|
|
1240
|
-
promise.setSuccess(event.data == 'unchanged');
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
};
|
|
1546
|
+
window.addEventListener("message", messageCallback, false);
|
|
1244
1547
|
|
|
1245
|
-
|
|
1548
|
+
return promise.promise;
|
|
1549
|
+
}
|
|
1246
1550
|
|
|
1247
|
-
|
|
1551
|
+
function scheduleCheckIframe() {
|
|
1552
|
+
if (loginIframe.enable) {
|
|
1553
|
+
if (kc.token) {
|
|
1554
|
+
setTimeout(function () {
|
|
1555
|
+
checkLoginIframe().then(function (unchanged) {
|
|
1556
|
+
if (unchanged) {
|
|
1557
|
+
scheduleCheckIframe();
|
|
1558
|
+
}
|
|
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();
|
|
1248
1578
|
}
|
|
1249
1579
|
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
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();
|
|
1262
1635
|
}
|
|
1263
1636
|
|
|
1264
|
-
|
|
1265
|
-
|
|
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
|
+
}
|
|
1266
1659
|
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
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
|
+
}
|
|
1277
1680
|
|
|
1278
|
-
|
|
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
|
+
};
|
|
1279
1720
|
}
|
|
1280
1721
|
|
|
1281
|
-
|
|
1282
|
-
|
|
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);
|
|
1738
|
+
}
|
|
1739
|
+
};
|
|
1283
1740
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
document.body.appendChild(iframe);
|
|
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];
|
|
1291
1747
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
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
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
});
|
|
1296
1824
|
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
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
|
-
}
|
|
1825
|
+
ref.addEventListener("exit", function (event) {
|
|
1826
|
+
if (!closed) {
|
|
1827
|
+
promise.setError({
|
|
1828
|
+
reason: "closed_by_user",
|
|
1829
|
+
});
|
|
1830
|
+
}
|
|
1831
|
+
});
|
|
1312
1832
|
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
promise.setSuccess();
|
|
1316
|
-
};
|
|
1833
|
+
return promise.promise;
|
|
1834
|
+
},
|
|
1317
1835
|
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
promise.setSuccess();
|
|
1321
|
-
}
|
|
1836
|
+
logout: function (options) {
|
|
1837
|
+
var promise = createPromise();
|
|
1322
1838
|
|
|
1323
|
-
|
|
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
|
-
}
|
|
1839
|
+
var logoutUrl = kc.createLogoutUrl(options);
|
|
1369
1840
|
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
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
|
-
};
|
|
1841
|
+
var ref = cordovaOpenWindowWrapper(
|
|
1842
|
+
logoutUrl,
|
|
1843
|
+
"_blank",
|
|
1844
|
+
"location=no,hidden=yes,clearcache=yes"
|
|
1845
|
+
);
|
|
1407
1846
|
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
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
|
-
}
|
|
1847
|
+
var error;
|
|
1848
|
+
|
|
1849
|
+
ref.addEventListener("loadstart", function (event) {
|
|
1850
|
+
if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
|
|
1851
|
+
ref.close();
|
|
1528
1852
|
}
|
|
1529
|
-
|
|
1853
|
+
});
|
|
1530
1854
|
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
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
|
-
}
|
|
1855
|
+
ref.addEventListener("loaderror", function (event) {
|
|
1856
|
+
if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
|
|
1857
|
+
ref.close();
|
|
1858
|
+
} else {
|
|
1859
|
+
error = true;
|
|
1860
|
+
ref.close();
|
|
1597
1861
|
}
|
|
1598
|
-
|
|
1862
|
+
});
|
|
1599
1863
|
|
|
1600
|
-
|
|
1864
|
+
ref.addEventListener("exit", function (event) {
|
|
1865
|
+
if (error) {
|
|
1866
|
+
promise.setError();
|
|
1867
|
+
} else {
|
|
1868
|
+
kc.clearToken();
|
|
1869
|
+
promise.setSuccess();
|
|
1870
|
+
}
|
|
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);
|
|
1891
|
+
}
|
|
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
|
+
};
|
|
1601
1919
|
}
|
|
1602
1920
|
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
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
|
+
};
|
|
1987
|
+
}
|
|
1607
1988
|
|
|
1608
|
-
|
|
1609
|
-
|
|
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
|
-
}
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1989
|
+
throw "invalid adapter type: " + type;
|
|
1990
|
+
}
|
|
1632
1991
|
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1992
|
+
var LocalStorage = function () {
|
|
1993
|
+
if (!(this instanceof LocalStorage)) {
|
|
1994
|
+
return new LocalStorage();
|
|
1995
|
+
}
|
|
1637
1996
|
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
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) {
|
|
1641
2012
|
localStorage.removeItem(key);
|
|
1642
|
-
|
|
2013
|
+
}
|
|
2014
|
+
} catch (err) {
|
|
2015
|
+
localStorage.removeItem(key);
|
|
1643
2016
|
}
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
1644
2021
|
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
2022
|
+
cs.get = function (state) {
|
|
2023
|
+
if (!state) {
|
|
2024
|
+
return;
|
|
2025
|
+
}
|
|
1648
2026
|
|
|
1649
|
-
|
|
1650
|
-
|
|
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
|
+
}
|
|
1651
2033
|
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
localStorage.setItem(key, JSON.stringify(state));
|
|
1655
|
-
};
|
|
2034
|
+
clearExpired();
|
|
2035
|
+
return value;
|
|
1656
2036
|
};
|
|
1657
2037
|
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
return new CookieStorage();
|
|
1661
|
-
}
|
|
2038
|
+
cs.add = function (state) {
|
|
2039
|
+
clearExpired();
|
|
1662
2040
|
|
|
1663
|
-
|
|
2041
|
+
var key = "kc-callback-" + state.state;
|
|
2042
|
+
state.expires = new Date().getTime() + 60 * 60 * 1000;
|
|
2043
|
+
localStorage.setItem(key, JSON.stringify(state));
|
|
2044
|
+
};
|
|
2045
|
+
};
|
|
1664
2046
|
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
2047
|
+
var CookieStorage = function () {
|
|
2048
|
+
if (!(this instanceof CookieStorage)) {
|
|
2049
|
+
return new CookieStorage();
|
|
2050
|
+
}
|
|
1669
2051
|
|
|
1670
|
-
|
|
1671
|
-
setCookie('kc-callback-' + state, '', cookieExpiration(-100));
|
|
1672
|
-
if (value) {
|
|
1673
|
-
return JSON.parse(value);
|
|
1674
|
-
}
|
|
1675
|
-
};
|
|
2052
|
+
var cs = this;
|
|
1676
2053
|
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
2054
|
+
cs.get = function (state) {
|
|
2055
|
+
if (!state) {
|
|
2056
|
+
return;
|
|
2057
|
+
}
|
|
1680
2058
|
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
2059
|
+
var value = getCookie("kc-callback-" + state);
|
|
2060
|
+
setCookie("kc-callback-" + state, "", cookieExpiration(-100));
|
|
2061
|
+
if (value) {
|
|
2062
|
+
return JSON.parse(value);
|
|
2063
|
+
}
|
|
2064
|
+
};
|
|
1684
2065
|
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
2066
|
+
cs.add = function (state) {
|
|
2067
|
+
setCookie(
|
|
2068
|
+
"kc-callback-" + state.state,
|
|
2069
|
+
JSON.stringify(state),
|
|
2070
|
+
cookieExpiration(60)
|
|
2071
|
+
);
|
|
2072
|
+
};
|
|
1690
2073
|
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
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
|
-
};
|
|
2074
|
+
cs.removeItem = function (key) {
|
|
2075
|
+
setCookie(key, "", cookieExpiration(-100));
|
|
2076
|
+
};
|
|
1705
2077
|
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
}
|
|
2078
|
+
var cookieExpiration = function (minutes) {
|
|
2079
|
+
var exp = new Date();
|
|
2080
|
+
exp.setTime(exp.getTime() + minutes * 60 * 1000);
|
|
2081
|
+
return exp;
|
|
1711
2082
|
};
|
|
1712
2083
|
|
|
1713
|
-
function
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
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);
|
|
1717
2091
|
}
|
|
2092
|
+
if (c.indexOf(name) == 0) {
|
|
2093
|
+
return c.substring(name.length, c.length);
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
return "";
|
|
2097
|
+
};
|
|
1718
2098
|
|
|
1719
|
-
|
|
1720
|
-
|
|
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;
|
|
2110
|
+
};
|
|
2111
|
+
};
|
|
1721
2112
|
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
2113
|
+
function createCallbackStorage() {
|
|
2114
|
+
try {
|
|
2115
|
+
return new LocalStorage();
|
|
2116
|
+
} catch (err) {}
|
|
2117
|
+
|
|
2118
|
+
return new CookieStorage();
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
function createLogger(fn) {
|
|
2122
|
+
return function () {
|
|
2123
|
+
if (kc.enableLogging) {
|
|
2124
|
+
fn.apply(console, Array.prototype.slice.call(arguments));
|
|
2125
|
+
}
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
1729
2128
|
}
|
|
1730
2129
|
|
|
1731
|
-
export default Keycloak;
|
|
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
|
+
}
|