oidc-spa 7.2.1 → 7.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/backend.js.map +1 -1
  2. package/core/AuthResponse.js.map +1 -1
  3. package/core/Oidc.js.map +1 -1
  4. package/core/OidcInitializationError.js.map +1 -1
  5. package/core/OidcMetadata.js.map +1 -1
  6. package/core/StateData.js.map +1 -1
  7. package/core/configId.js.map +1 -1
  8. package/core/createOidc.js +1 -1
  9. package/core/createOidc.js.map +1 -1
  10. package/core/diagnostic.js.map +1 -1
  11. package/core/evtIsUserActive.js.map +1 -1
  12. package/core/handleOidcCallback.js.map +1 -1
  13. package/core/iframeMessageProtection.js.map +1 -1
  14. package/core/index.js.map +1 -1
  15. package/core/initialLocationHref.js.map +1 -1
  16. package/core/isNewBrowserSession.js.map +1 -1
  17. package/core/loginOrGoToAuthServer.js.map +1 -1
  18. package/core/loginPropagationToOtherTabs.js.map +1 -1
  19. package/core/loginSilent.js.map +1 -1
  20. package/core/logoutPropagationToOtherTabs.js.map +1 -1
  21. package/core/oidcClientTsUserToTokens.js.map +1 -1
  22. package/core/ongoingLoginOrRefreshProcesses.js.map +1 -1
  23. package/core/persistedAuthState.js.map +1 -1
  24. package/entrypoint.js.map +1 -1
  25. package/esm/core/AuthResponse.js +2 -2
  26. package/esm/core/AuthResponse.js.map +1 -1
  27. package/esm/core/Oidc.d.ts +1 -1
  28. package/esm/core/Oidc.js.map +1 -1
  29. package/esm/core/OidcInitializationError.js.map +1 -1
  30. package/esm/core/OidcMetadata.js +2 -2
  31. package/esm/core/OidcMetadata.js.map +1 -1
  32. package/esm/core/StateData.js +3 -3
  33. package/esm/core/StateData.js.map +1 -1
  34. package/esm/core/configId.js.map +1 -1
  35. package/esm/core/createOidc.d.ts +2 -2
  36. package/esm/core/createOidc.js +33 -33
  37. package/esm/core/createOidc.js.map +1 -1
  38. package/esm/core/diagnostic.d.ts +1 -1
  39. package/esm/core/diagnostic.js +4 -4
  40. package/esm/core/diagnostic.js.map +1 -1
  41. package/esm/core/evtIsUserActive.d.ts +1 -1
  42. package/esm/core/evtIsUserActive.js +5 -5
  43. package/esm/core/evtIsUserActive.js.map +1 -1
  44. package/esm/core/handleOidcCallback.d.ts +2 -2
  45. package/esm/core/handleOidcCallback.js +5 -5
  46. package/esm/core/handleOidcCallback.js.map +1 -1
  47. package/esm/core/iframeMessageProtection.d.ts +1 -1
  48. package/esm/core/iframeMessageProtection.js +3 -3
  49. package/esm/core/iframeMessageProtection.js.map +1 -1
  50. package/esm/core/index.d.ts +4 -4
  51. package/esm/core/index.js +4 -4
  52. package/esm/core/index.js.map +1 -1
  53. package/esm/core/initialLocationHref.js.map +1 -1
  54. package/esm/core/isNewBrowserSession.d.ts +1 -1
  55. package/esm/core/isNewBrowserSession.js.map +1 -1
  56. package/esm/core/loginOrGoToAuthServer.d.ts +2 -2
  57. package/esm/core/loginOrGoToAuthServer.js +6 -6
  58. package/esm/core/loginOrGoToAuthServer.js.map +1 -1
  59. package/esm/core/loginPropagationToOtherTabs.js +3 -3
  60. package/esm/core/loginPropagationToOtherTabs.js.map +1 -1
  61. package/esm/core/loginSilent.d.ts +2 -2
  62. package/esm/core/loginSilent.js +8 -8
  63. package/esm/core/loginSilent.js.map +1 -1
  64. package/esm/core/logoutPropagationToOtherTabs.js +3 -3
  65. package/esm/core/logoutPropagationToOtherTabs.js.map +1 -1
  66. package/esm/core/oidcClientTsUserToTokens.d.ts +2 -2
  67. package/esm/core/oidcClientTsUserToTokens.js +4 -4
  68. package/esm/core/oidcClientTsUserToTokens.js.map +1 -1
  69. package/esm/core/ongoingLoginOrRefreshProcesses.js +3 -3
  70. package/esm/core/ongoingLoginOrRefreshProcesses.js.map +1 -1
  71. package/esm/core/persistedAuthState.js +2 -2
  72. package/esm/core/persistedAuthState.js.map +1 -1
  73. package/esm/entrypoint.js +3 -3
  74. package/esm/entrypoint.js.map +1 -1
  75. package/esm/index.d.ts +1 -1
  76. package/esm/index.js +2 -2
  77. package/esm/index.js.map +1 -1
  78. package/esm/keycloak/index.d.ts +3 -3
  79. package/esm/keycloak/index.js +3 -3
  80. package/esm/keycloak/index.js.map +1 -1
  81. package/esm/keycloak/isKeycloak.js.map +1 -1
  82. package/esm/keycloak/keycloak-js/Keycloak.d.ts +1 -1
  83. package/esm/keycloak/keycloak-js/Keycloak.js +9 -9
  84. package/esm/keycloak/keycloak-js/Keycloak.js.map +1 -1
  85. package/esm/keycloak/keycloak-js/index.d.ts +2 -2
  86. package/esm/keycloak/keycloak-js/index.js +2 -2
  87. package/esm/keycloak/keycloak-js/index.js.map +1 -1
  88. package/esm/keycloak/keycloak-js/types.js.map +1 -1
  89. package/esm/keycloak/keycloakIssuerUriParsed.js +3 -3
  90. package/esm/keycloak/keycloakIssuerUriParsed.js.map +1 -1
  91. package/esm/keycloak/keycloakUtils.d.ts +1 -1
  92. package/esm/keycloak/keycloakUtils.js +3 -3
  93. package/esm/keycloak/keycloakUtils.js.map +1 -1
  94. package/esm/keycloak-js.d.ts +1 -1
  95. package/esm/keycloak-js.js +2 -2
  96. package/esm/keycloak-js.js.map +1 -1
  97. package/esm/mock/index.d.ts +1 -1
  98. package/esm/mock/index.js +2 -2
  99. package/esm/mock/index.js.map +1 -1
  100. package/esm/mock/oidc.d.ts +1 -1
  101. package/esm/mock/oidc.js +6 -6
  102. package/esm/mock/oidc.js.map +1 -1
  103. package/esm/mock/react.d.ts +8 -8
  104. package/esm/mock/react.js +3 -3
  105. package/esm/mock/react.js.map +1 -1
  106. package/esm/react/index.d.ts +1 -1
  107. package/esm/react/index.js +2 -2
  108. package/esm/react/index.js.map +1 -1
  109. package/esm/react/react.d.ts +2 -2
  110. package/esm/react/react.js +6 -6
  111. package/esm/react/react.js.map +1 -1
  112. package/esm/tools/Deferred.js.map +1 -1
  113. package/esm/tools/EphemeralSessionStorage.js +2 -2
  114. package/esm/tools/EphemeralSessionStorage.js.map +1 -1
  115. package/esm/tools/Evt.js +3 -3
  116. package/esm/tools/Evt.js.map +1 -1
  117. package/esm/tools/StatefulEvt.js.map +1 -1
  118. package/esm/tools/ValueOrAsyncGetter.js.map +1 -1
  119. package/esm/tools/asymmetricEncryption.js.map +1 -1
  120. package/esm/tools/base64.js.map +1 -1
  121. package/esm/tools/createObjectThatThrowsIfAccessed.js.map +1 -1
  122. package/esm/tools/decodeJwt.js.map +1 -1
  123. package/esm/tools/generateUrlSafeRandom.js.map +1 -1
  124. package/esm/tools/getDownlinkAndRtt.js +2 -2
  125. package/esm/tools/getDownlinkAndRtt.js.map +1 -1
  126. package/esm/tools/getIsOnline.js +2 -2
  127. package/esm/tools/getIsOnline.js.map +1 -1
  128. package/esm/tools/getIsValidRemoteJson.js.map +1 -1
  129. package/esm/tools/getPrUserInteraction.js +2 -2
  130. package/esm/tools/getPrUserInteraction.js.map +1 -1
  131. package/esm/tools/getUserEnvironmentInfo.js.map +1 -1
  132. package/esm/tools/haveSharedParentDomain.js.map +1 -1
  133. package/esm/tools/isDev.js.map +1 -1
  134. package/esm/tools/parseKeycloakIssuerUri.js +2 -2
  135. package/esm/tools/parseKeycloakIssuerUri.js.map +1 -1
  136. package/esm/tools/readExpirationTimeInJwt.js +3 -3
  137. package/esm/tools/readExpirationTimeInJwt.js.map +1 -1
  138. package/esm/tools/startCountdown.js +2 -2
  139. package/esm/tools/startCountdown.js.map +1 -1
  140. package/esm/tools/subscribeToUserInteraction.js +2 -2
  141. package/esm/tools/subscribeToUserInteraction.js.map +1 -1
  142. package/esm/tools/toFullyQualifiedUrl.js.map +1 -1
  143. package/esm/tools/toHumanReadableDuration.js.map +1 -1
  144. package/esm/tools/urlSearchParams.js.map +1 -1
  145. package/esm/tools/workerTimers.js +2 -2
  146. package/esm/tools/workerTimers.js.map +1 -1
  147. package/index.js.map +1 -1
  148. package/keycloak/index.js.map +1 -1
  149. package/keycloak/isKeycloak.js.map +1 -1
  150. package/keycloak/keycloak-js/Keycloak.js.map +1 -1
  151. package/keycloak/keycloak-js/index.js.map +1 -1
  152. package/keycloak/keycloak-js/types.js.map +1 -1
  153. package/keycloak/keycloakIssuerUriParsed.js.map +1 -1
  154. package/keycloak/keycloakUtils.js.map +1 -1
  155. package/keycloak-js.js.map +1 -1
  156. package/mock/index.js.map +1 -1
  157. package/mock/oidc.js.map +1 -1
  158. package/mock/react.js.map +1 -1
  159. package/package.json +11 -33
  160. package/react/index.js.map +1 -1
  161. package/react/react.js.map +1 -1
  162. package/src/backend.ts +391 -0
  163. package/src/core/AuthResponse.ts +26 -0
  164. package/src/core/Oidc.ts +140 -0
  165. package/src/core/OidcInitializationError.ts +19 -0
  166. package/src/core/OidcMetadata.ts +271 -0
  167. package/src/core/StateData.ts +118 -0
  168. package/src/core/configId.ts +3 -0
  169. package/src/core/createOidc.ts +1576 -0
  170. package/src/core/diagnostic.ts +267 -0
  171. package/src/core/evtIsUserActive.ts +108 -0
  172. package/src/core/handleOidcCallback.ts +321 -0
  173. package/src/core/iframeMessageProtection.ts +100 -0
  174. package/src/core/index.ts +4 -0
  175. package/src/core/initialLocationHref.ts +5 -0
  176. package/src/core/isNewBrowserSession.ts +37 -0
  177. package/src/core/loginOrGoToAuthServer.ts +324 -0
  178. package/src/core/loginPropagationToOtherTabs.ts +51 -0
  179. package/src/core/loginSilent.ts +242 -0
  180. package/src/core/logoutPropagationToOtherTabs.ts +53 -0
  181. package/src/core/oidcClientTsUserToTokens.ts +229 -0
  182. package/src/core/ongoingLoginOrRefreshProcesses.ts +47 -0
  183. package/src/core/persistedAuthState.ts +122 -0
  184. package/src/entrypoint.ts +69 -0
  185. package/src/index.ts +1 -0
  186. package/src/keycloak/index.ts +8 -0
  187. package/src/keycloak/isKeycloak.ts +23 -0
  188. package/src/keycloak/keycloak-js/Keycloak.ts +1097 -0
  189. package/src/keycloak/keycloak-js/index.ts +2 -0
  190. package/src/keycloak/keycloak-js/types.ts +442 -0
  191. package/src/keycloak/keycloakIssuerUriParsed.ts +29 -0
  192. package/src/keycloak/keycloakUtils.ts +90 -0
  193. package/src/keycloak-js.ts +1 -0
  194. package/src/mock/index.ts +1 -0
  195. package/src/mock/oidc.ts +211 -0
  196. package/src/mock/react.tsx +11 -0
  197. package/src/react/index.ts +1 -0
  198. package/src/react/react.tsx +476 -0
  199. package/src/tools/Deferred.ts +33 -0
  200. package/src/tools/EphemeralSessionStorage.ts +223 -0
  201. package/src/tools/Evt.ts +56 -0
  202. package/src/tools/StatefulEvt.ts +38 -0
  203. package/src/tools/ValueOrAsyncGetter.ts +1 -0
  204. package/src/tools/asymmetricEncryption.ts +184 -0
  205. package/src/tools/base64.ts +7 -0
  206. package/src/tools/createObjectThatThrowsIfAccessed.ts +40 -0
  207. package/src/tools/decodeJwt.ts +95 -0
  208. package/src/tools/generateUrlSafeRandom.ts +26 -0
  209. package/src/tools/getDownlinkAndRtt.ts +22 -0
  210. package/src/tools/getIsOnline.ts +20 -0
  211. package/src/tools/getIsValidRemoteJson.ts +18 -0
  212. package/src/tools/getPrUserInteraction.ts +27 -0
  213. package/src/tools/getUserEnvironmentInfo.ts +42 -0
  214. package/src/tools/haveSharedParentDomain.ts +13 -0
  215. package/src/tools/isDev.ts +30 -0
  216. package/src/tools/parseKeycloakIssuerUri.ts +49 -0
  217. package/src/tools/readExpirationTimeInJwt.ts +16 -0
  218. package/src/tools/startCountdown.ts +36 -0
  219. package/src/tools/subscribeToUserInteraction.ts +33 -0
  220. package/src/tools/toFullyQualifiedUrl.ts +58 -0
  221. package/src/tools/toHumanReadableDuration.ts +21 -0
  222. package/src/tools/urlSearchParams.ts +130 -0
  223. package/src/tools/workerTimers.ts +57 -0
  224. package/src/vendor/backend/evt.ts +2 -0
  225. package/src/vendor/backend/jsonwebtoken.ts +1 -0
  226. package/src/vendor/backend/node-fetch.ts +2 -0
  227. package/src/vendor/backend/node-jose.ts +1 -0
  228. package/src/vendor/backend/tsafe.ts +5 -0
  229. package/src/vendor/backend/zod.ts +1 -0
  230. package/src/vendor/frontend/oidc-client-ts.ts +1 -0
  231. package/src/vendor/frontend/tsafe.ts +6 -0
  232. package/src/vendor/frontend/worker-timers.ts +2 -0
  233. package/tools/Deferred.js.map +1 -1
  234. package/tools/EphemeralSessionStorage.js.map +1 -1
  235. package/tools/Evt.js.map +1 -1
  236. package/tools/StatefulEvt.js.map +1 -1
  237. package/tools/ValueOrAsyncGetter.js.map +1 -1
  238. package/tools/asymmetricEncryption.js.map +1 -1
  239. package/tools/base64.js.map +1 -1
  240. package/tools/createObjectThatThrowsIfAccessed.js.map +1 -1
  241. package/tools/decodeJwt.js.map +1 -1
  242. package/tools/generateUrlSafeRandom.js.map +1 -1
  243. package/tools/getDownlinkAndRtt.js.map +1 -1
  244. package/tools/getIsOnline.js.map +1 -1
  245. package/tools/getIsValidRemoteJson.js.map +1 -1
  246. package/tools/getPrUserInteraction.js.map +1 -1
  247. package/tools/getUserEnvironmentInfo.js.map +1 -1
  248. package/tools/haveSharedParentDomain.js.map +1 -1
  249. package/tools/isDev.js.map +1 -1
  250. package/tools/parseKeycloakIssuerUri.js.map +1 -1
  251. package/tools/readExpirationTimeInJwt.js.map +1 -1
  252. package/tools/startCountdown.js.map +1 -1
  253. package/tools/subscribeToUserInteraction.js.map +1 -1
  254. package/tools/toFullyQualifiedUrl.js.map +1 -1
  255. package/tools/toHumanReadableDuration.js.map +1 -1
  256. package/tools/urlSearchParams.js.map +1 -1
  257. package/tools/workerTimers.js.map +1 -1
@@ -0,0 +1,1097 @@
1
+ import type {
2
+ KeycloakServerConfig,
3
+ KeycloakInitOptions,
4
+ KeycloakError,
5
+ KeycloakLogoutOptions,
6
+ KeycloakRoles,
7
+ KeycloakTokenParsed,
8
+ KeycloakResourceAccess,
9
+ KeycloakProfile,
10
+ KeycloakUserInfo,
11
+ KeycloakLoginOptions,
12
+ KeycloakRegisterOptions,
13
+ KeycloakAccountOptions
14
+ } from "./types";
15
+ import { assert, is, isAmong } from "../../vendor/frontend/tsafe";
16
+ import { createOidc, type Oidc, OidcInitializationError } from "../../core";
17
+ import { Deferred } from "../../tools/Deferred";
18
+ import { decodeJwt } from "../../tools/decodeJwt";
19
+ import { type KeycloakUtils, createKeycloakUtils } from "../keycloakUtils";
20
+ import { workerTimers } from "../../vendor/frontend/worker-timers";
21
+ import { type StatefulEvt, createStatefulEvt } from "../../tools/StatefulEvt";
22
+ import { readExpirationTimeInJwt } from "../../tools/readExpirationTimeInJwt";
23
+
24
+ type ConstructorParams = KeycloakServerConfig & {
25
+ homeUrl: string;
26
+ };
27
+
28
+ type InternalState = {
29
+ constructorParams: ConstructorParams;
30
+ keycloakUtils: KeycloakUtils;
31
+ issuerUri: string;
32
+ dInitialized: Deferred<void>;
33
+ initOptions: KeycloakInitOptions | undefined;
34
+ oidc: Oidc<Record<string, unknown>> | undefined;
35
+ tokens: Oidc.Tokens<Record<string, unknown>> | undefined;
36
+ profile: KeycloakProfile | undefined;
37
+ userInfo: KeycloakUserInfo | undefined;
38
+ $onTokenExpired: StatefulEvt<(() => void) | undefined>;
39
+ };
40
+
41
+ const internalStateByInstance = new WeakMap<Keycloak, InternalState>();
42
+
43
+ /**
44
+ * This module provides a drop-in replacement for `keycloak-js`,
45
+ * designed for teams migrating to `oidc-spa` with minimal changes.
46
+ *
47
+ * ⚠️ While the import path is `oidc-spa/keycloak-js`, this is *not* a re-export or patch —
48
+ * it is a full alternative implementation aligned with the `keycloak-js` API.
49
+ */
50
+ export class Keycloak {
51
+ /**
52
+ * Creates a new Keycloak client instance.
53
+ * @param config A configuration object or path to a JSON config file.
54
+ *
55
+ * NOTE oidc-spa: Currently not supporting GenericOidcConfig (providing explicitly authorization_endpoint ect)
56
+ * But we could if with the __metadata parameter of oidc-spa.
57
+ * I'm not seeing the usecase when ran against keycloak right now so not doing it.
58
+ */
59
+ constructor(params: ConstructorParams) {
60
+ const issuerUri = `${params.url.replace(/\/$/, "")}/realms/${params.realm}`;
61
+
62
+ internalStateByInstance.set(this, {
63
+ constructorParams: params,
64
+ dInitialized: new Deferred(),
65
+ initOptions: undefined,
66
+ oidc: undefined,
67
+ tokens: undefined,
68
+ keycloakUtils: createKeycloakUtils({ issuerUri }),
69
+ issuerUri,
70
+ profile: undefined,
71
+ userInfo: undefined,
72
+ $onTokenExpired: createStatefulEvt(() => undefined)
73
+ });
74
+ }
75
+
76
+ /**
77
+ * Called to initialize the adapter.
78
+ * @param initOptions Initialization options.
79
+ * @returns A promise to set functions to be invoked on success or error.
80
+ */
81
+ async init(initOptions: KeycloakInitOptions = {}): Promise<boolean> {
82
+ const { onLoad = "check-sso", redirectUri, enableLogging, scope, locale } = initOptions;
83
+
84
+ const internalState = internalStateByInstance.get(this);
85
+
86
+ assert(internalState !== undefined);
87
+
88
+ if (internalState.initOptions !== undefined) {
89
+ if (JSON.stringify(internalState.initOptions) !== JSON.stringify(initOptions)) {
90
+ throw new Error("Can't call init() multiple time with different params");
91
+ }
92
+ await internalState.dInitialized.pr;
93
+ const { oidc } = internalState;
94
+ assert(oidc !== undefined);
95
+ return oidc.isUserLoggedIn;
96
+ }
97
+
98
+ internalState.initOptions = initOptions;
99
+
100
+ const { constructorParams, issuerUri } = internalState;
101
+
102
+ const autoLogin = onLoad === "login-required";
103
+
104
+ let hasCreateResolved = false;
105
+
106
+ const oidcOrError = await createOidc({
107
+ homeUrl: constructorParams.homeUrl,
108
+ issuerUri,
109
+ clientId: internalState.constructorParams.clientId,
110
+ autoLogin,
111
+ postLoginRedirectUrl: redirectUri,
112
+ debugLogs: enableLogging,
113
+ scopes: scope?.split(" "),
114
+ extraQueryParams:
115
+ !autoLogin || locale === undefined
116
+ ? undefined
117
+ : () => {
118
+ if (hasCreateResolved) {
119
+ return {};
120
+ }
121
+
122
+ return {
123
+ ui_locales: locale
124
+ };
125
+ }
126
+ })
127
+ // NOTE: This can only happen when autoLogin is true, otherwise the error
128
+ // is in oidc.initializationError
129
+ .catch((error: OidcInitializationError) => error);
130
+
131
+ hasCreateResolved = true;
132
+
133
+ if (oidcOrError instanceof OidcInitializationError) {
134
+ this.onAuthError?.({
135
+ error: oidcOrError.name,
136
+ error_description: oidcOrError.message
137
+ });
138
+
139
+ await new Promise<never>(() => {});
140
+ assert(false);
141
+ }
142
+
143
+ const oidc = oidcOrError;
144
+
145
+ internalState.oidc = oidc;
146
+
147
+ if (oidc.isUserLoggedIn) {
148
+ {
149
+ const tokens = await oidc.getTokens();
150
+
151
+ const onNewToken = (tokens_new: Oidc.Tokens<Record<string, unknown>>) => {
152
+ internalState.tokens = tokens_new;
153
+ this.onAuthRefreshSuccess?.();
154
+ };
155
+
156
+ onNewToken(tokens);
157
+
158
+ oidc.subscribeToTokensChange(onNewToken);
159
+ }
160
+
161
+ {
162
+ const { $onTokenExpired } = internalState;
163
+
164
+ let clear: (() => void) | undefined = undefined;
165
+
166
+ $onTokenExpired.subscribe(onTokenExpired => {
167
+ clear?.();
168
+
169
+ if (onTokenExpired === undefined) {
170
+ return;
171
+ }
172
+
173
+ let timer: ReturnType<typeof workerTimers.setTimeout> | undefined = undefined;
174
+
175
+ const onNewToken = () => {
176
+ if (timer !== undefined) {
177
+ workerTimers.clearTimeout(timer);
178
+ }
179
+
180
+ const { tokens } = internalState;
181
+ assert(tokens !== undefined);
182
+
183
+ timer = workerTimers.setTimeout(() => {
184
+ onTokenExpired.call(this);
185
+ }, Math.max(tokens.accessTokenExpirationTime - Date.now() - 3_000, 0));
186
+ };
187
+
188
+ onNewToken();
189
+
190
+ const { unsubscribe } = oidc.subscribeToTokensChange(onNewToken);
191
+
192
+ clear = () => {
193
+ if (timer !== undefined) {
194
+ workerTimers.clearTimeout(timer);
195
+ }
196
+ unsubscribe();
197
+ };
198
+ });
199
+ }
200
+
201
+ onActionUpdate_call: {
202
+ if (this.onActionUpdate === undefined) {
203
+ break onActionUpdate_call;
204
+ }
205
+
206
+ const { backFromAuthServer } = oidc;
207
+
208
+ if (backFromAuthServer === undefined) {
209
+ break onActionUpdate_call;
210
+ }
211
+
212
+ const status = backFromAuthServer.result.kc_action_status;
213
+
214
+ if (!isAmong(["success", "cancelled", "error"], status)) {
215
+ break onActionUpdate_call;
216
+ }
217
+
218
+ const action = backFromAuthServer.extraQueryParams.kc_action;
219
+
220
+ if (action === undefined) {
221
+ break onActionUpdate_call;
222
+ }
223
+
224
+ this.onActionUpdate(status, action);
225
+ }
226
+ }
227
+
228
+ if (!oidc.isUserLoggedIn && oidc.initializationError !== undefined) {
229
+ this.onAuthError?.({
230
+ error: oidc.initializationError.name,
231
+ error_description: oidc.initializationError.message
232
+ });
233
+ }
234
+
235
+ internalState.dInitialized.resolve();
236
+
237
+ this.onReady?.(oidc.isUserLoggedIn);
238
+ if (oidc.isUserLoggedIn) {
239
+ this.onAuthSuccess?.();
240
+ }
241
+
242
+ return oidc.isUserLoggedIn;
243
+ }
244
+
245
+ /**
246
+ * Is true if the user is authenticated, false otherwise.
247
+ */
248
+ get authenticated(): boolean {
249
+ if (!this.didInitialize) {
250
+ return false;
251
+ }
252
+
253
+ const internalState = internalStateByInstance.get(this);
254
+
255
+ assert(internalState !== undefined);
256
+
257
+ const { oidc } = internalState;
258
+
259
+ assert(oidc !== undefined);
260
+
261
+ return oidc.isUserLoggedIn;
262
+ }
263
+
264
+ /**
265
+ * The user id.
266
+ */
267
+ get subject(): string | undefined {
268
+ if (!this.didInitialize) {
269
+ return undefined;
270
+ }
271
+
272
+ const internalState = internalStateByInstance.get(this);
273
+
274
+ assert(internalState !== undefined);
275
+
276
+ const { oidc, tokens } = internalState;
277
+
278
+ assert(oidc !== undefined);
279
+
280
+ if (!oidc.isUserLoggedIn) {
281
+ console.warn(
282
+ "Trying to read keycloak.subject when keycloak.authenticated is false is a logical error in your application"
283
+ );
284
+ return undefined;
285
+ }
286
+
287
+ assert(tokens !== undefined);
288
+
289
+ return tokens.decodedIdToken_original.sub;
290
+ }
291
+
292
+ /**
293
+ * Response mode passed in init (default value is `'fragment'`).
294
+ *
295
+ * NOTE oidc-spa: Can only be fragment.
296
+ */
297
+ responseMode = "fragment";
298
+
299
+ /**
300
+ * Response type sent to Keycloak with login requests. This is determined
301
+ * based on the flow value used during initialization, but can be overridden
302
+ * by setting this value.
303
+ *
304
+ * NOTE oidc-spa: Can only be 'code'
305
+ */
306
+ responseType = "code";
307
+
308
+ /**
309
+ * Flow passed in init.
310
+ *
311
+ * NOTE oidc-spa: Can only be 'standard'
312
+ */
313
+ flow = "standard";
314
+
315
+ /**
316
+ * The realm roles associated with the token.
317
+ */
318
+ get realmAccess(): KeycloakRoles | undefined {
319
+ if (!this.didInitialize) {
320
+ return undefined;
321
+ }
322
+
323
+ const internalState = internalStateByInstance.get(this);
324
+
325
+ assert(internalState !== undefined);
326
+
327
+ const { oidc, tokens } = internalState;
328
+
329
+ assert(oidc !== undefined);
330
+
331
+ if (!oidc.isUserLoggedIn) {
332
+ console.warn(
333
+ "Trying to read keycloak.realAccess when keycloak.realmAccess is false is a logical error in your application"
334
+ );
335
+ return undefined;
336
+ }
337
+
338
+ assert(tokens !== undefined);
339
+ assert(is<KeycloakTokenParsed>(tokens.decodedIdToken_original));
340
+
341
+ return tokens.decodedIdToken_original.realm_access;
342
+ }
343
+
344
+ /**
345
+ * The resource roles associated with the token.
346
+ */
347
+ get resourceAccess(): KeycloakResourceAccess | undefined {
348
+ if (!this.didInitialize) {
349
+ return undefined;
350
+ }
351
+
352
+ const internalState = internalStateByInstance.get(this);
353
+
354
+ assert(internalState !== undefined);
355
+
356
+ const { oidc, tokens } = internalState;
357
+
358
+ assert(oidc !== undefined);
359
+
360
+ if (!oidc.isUserLoggedIn) {
361
+ console.warn(
362
+ "Trying to read keycloak.resourceAccess when keycloak.authenticated is false is a logical error in your application"
363
+ );
364
+ return undefined;
365
+ }
366
+
367
+ assert(tokens !== undefined);
368
+ assert(is<KeycloakTokenParsed>(tokens.decodedIdToken_original));
369
+
370
+ return tokens.decodedIdToken_original.resource_access;
371
+ }
372
+
373
+ /**
374
+ * The base64 encoded token that can be sent in the Authorization header in
375
+ * requests to services.
376
+ */
377
+ get token(): string | undefined {
378
+ const internalState = internalStateByInstance.get(this);
379
+
380
+ assert(internalState !== undefined);
381
+
382
+ if (!this.didInitialize) {
383
+ return internalState.initOptions?.token;
384
+ }
385
+
386
+ const { oidc, tokens } = internalState;
387
+
388
+ assert(oidc !== undefined);
389
+
390
+ if (!oidc.isUserLoggedIn) {
391
+ console.warn(
392
+ "Trying to read keycloak.token when keycloak.token is false is a logical error in your application"
393
+ );
394
+ return undefined;
395
+ }
396
+
397
+ assert(tokens !== undefined);
398
+
399
+ return tokens.accessToken;
400
+ }
401
+
402
+ /**
403
+ * The parsed token as a JavaScript object.
404
+ */
405
+ get tokenParsed(): KeycloakTokenParsed | undefined {
406
+ const internalState = internalStateByInstance.get(this);
407
+
408
+ assert(internalState !== undefined);
409
+
410
+ if (!this.didInitialize) {
411
+ const { token } = internalState.initOptions ?? {};
412
+
413
+ if (token === undefined) {
414
+ return undefined;
415
+ }
416
+
417
+ return decodeJwt(token) as KeycloakTokenParsed;
418
+ }
419
+
420
+ const { oidc, tokens } = internalState;
421
+
422
+ assert(oidc !== undefined);
423
+
424
+ if (!oidc.isUserLoggedIn) {
425
+ console.warn(
426
+ "Trying to read keycloak.token when keycloak.tokenParsed is false is a logical error in your application"
427
+ );
428
+ return undefined;
429
+ }
430
+
431
+ assert(tokens !== undefined);
432
+
433
+ return decodeJwt(tokens.accessToken);
434
+ }
435
+
436
+ /**
437
+ * The base64 encoded refresh token that can be used to retrieve a new token.
438
+ */
439
+ get refreshToken(): string | undefined {
440
+ const internalState = internalStateByInstance.get(this);
441
+
442
+ assert(internalState !== undefined);
443
+
444
+ if (!this.didInitialize) {
445
+ return internalState.initOptions?.refreshToken;
446
+ }
447
+
448
+ const { oidc, tokens } = internalState;
449
+
450
+ assert(oidc !== undefined);
451
+
452
+ if (!oidc.isUserLoggedIn) {
453
+ console.warn(
454
+ "Trying to read keycloak.token when keycloak.refreshToken is false is a logical error in your application"
455
+ );
456
+ return undefined;
457
+ }
458
+
459
+ assert(tokens !== undefined);
460
+
461
+ return tokens.refreshToken;
462
+ }
463
+
464
+ /**
465
+ * The parsed refresh token as a JavaScript object.
466
+ */
467
+ get refreshTokenParsed(): KeycloakTokenParsed | undefined {
468
+ const internalState = internalStateByInstance.get(this);
469
+
470
+ assert(internalState !== undefined);
471
+
472
+ if (!this.didInitialize) {
473
+ const { refreshToken } = internalState.initOptions ?? {};
474
+
475
+ if (refreshToken === undefined) {
476
+ return undefined;
477
+ }
478
+
479
+ return decodeJwt(refreshToken) as KeycloakTokenParsed;
480
+ }
481
+
482
+ const { oidc, tokens } = internalState;
483
+
484
+ assert(oidc !== undefined);
485
+
486
+ if (!oidc.isUserLoggedIn) {
487
+ console.warn(
488
+ "Trying to read keycloak.token when keycloak.refreshTokenParsed is false is a logical error in your application"
489
+ );
490
+ return undefined;
491
+ }
492
+
493
+ assert(tokens !== undefined);
494
+
495
+ if (tokens.refreshToken === undefined) {
496
+ return undefined;
497
+ }
498
+
499
+ return decodeJwt(tokens.refreshToken) as KeycloakTokenParsed;
500
+ }
501
+
502
+ /**
503
+ * The base64 encoded ID token.
504
+ */
505
+ get idToken(): string | undefined {
506
+ const internalState = internalStateByInstance.get(this);
507
+
508
+ assert(internalState !== undefined);
509
+
510
+ if (!this.didInitialize) {
511
+ return internalState.initOptions?.idToken;
512
+ }
513
+
514
+ const { oidc, tokens } = internalState;
515
+
516
+ assert(oidc !== undefined);
517
+
518
+ if (!oidc.isUserLoggedIn) {
519
+ console.warn(
520
+ "Trying to read keycloak.token when keycloak.token is false is a logical error in your application"
521
+ );
522
+ return undefined;
523
+ }
524
+
525
+ assert(tokens !== undefined);
526
+
527
+ return tokens.idToken;
528
+ }
529
+
530
+ /**
531
+ * The parsed id token as a JavaScript object.
532
+ */
533
+ get idTokenParsed(): KeycloakTokenParsed | undefined {
534
+ const internalState = internalStateByInstance.get(this);
535
+
536
+ assert(internalState !== undefined);
537
+
538
+ if (!this.didInitialize) {
539
+ const { idToken } = internalState.initOptions ?? {};
540
+
541
+ if (idToken === undefined) {
542
+ return undefined;
543
+ }
544
+
545
+ return decodeJwt(idToken) as KeycloakTokenParsed;
546
+ }
547
+
548
+ const { oidc, tokens } = internalState;
549
+
550
+ assert(oidc !== undefined);
551
+
552
+ if (!oidc.isUserLoggedIn) {
553
+ console.warn(
554
+ "Trying to read keycloak.token when keycloak.refreshTokenParsed is false is a logical error in your application"
555
+ );
556
+ return undefined;
557
+ }
558
+
559
+ assert(tokens !== undefined);
560
+ assert(is<KeycloakTokenParsed>(tokens.decodedIdToken_original));
561
+
562
+ return tokens.decodedIdToken_original;
563
+ }
564
+
565
+ /**
566
+ * The estimated time difference between the browser time and the Keycloak
567
+ * server in seconds. This value is just an estimation, but is accurate
568
+ * enough when determining if a token is expired or not.
569
+ *
570
+ * NOTE oidc-spa: Not supported.
571
+ */
572
+ timeSkew = null;
573
+
574
+ /**
575
+ * Whether the instance has been initialized by calling `.init()`.
576
+ */
577
+ get didInitialize(): boolean {
578
+ const internalState = internalStateByInstance.get(this);
579
+ assert(internalState !== undefined);
580
+ return internalState.oidc !== undefined;
581
+ }
582
+
583
+ /**
584
+ * @private Undocumented.
585
+ */
586
+ get loginRequired(): boolean {
587
+ const internalState = internalStateByInstance.get(this);
588
+ assert(internalState !== undefined);
589
+
590
+ const { initOptions } = internalState;
591
+
592
+ if (initOptions === undefined) {
593
+ return false;
594
+ }
595
+
596
+ return initOptions.onLoad === "login-required";
597
+ }
598
+
599
+ /**
600
+ * @private Undocumented.
601
+ */
602
+ get authServerUrl(): string {
603
+ const internalState = internalStateByInstance.get(this);
604
+ assert(internalState !== undefined);
605
+ const {
606
+ keycloakUtils: { issuerUriParsed }
607
+ } = internalState;
608
+
609
+ return `${issuerUriParsed.origin}${issuerUriParsed.kcHttpRelativePath}`;
610
+ }
611
+
612
+ /**
613
+ * @private Undocumented.
614
+ */
615
+ get realm(): string {
616
+ const internalState = internalStateByInstance.get(this);
617
+ assert(internalState !== undefined);
618
+ const {
619
+ keycloakUtils: { issuerUriParsed }
620
+ } = internalState;
621
+
622
+ return issuerUriParsed.realm;
623
+ }
624
+
625
+ /**
626
+ * @private Undocumented.
627
+ */
628
+ get clientId(): string {
629
+ const internalState = internalStateByInstance.get(this);
630
+ assert(internalState !== undefined);
631
+ const { constructorParams } = internalState;
632
+ return constructorParams.clientId;
633
+ }
634
+
635
+ /**
636
+ * @private Undocumented.
637
+ */
638
+ get redirectUri(): string | undefined {
639
+ const internalState = internalStateByInstance.get(this);
640
+ assert(internalState !== undefined);
641
+ const { initOptions } = internalState;
642
+ if (initOptions === undefined) {
643
+ return undefined;
644
+ }
645
+ return initOptions.redirectUri;
646
+ }
647
+
648
+ /**
649
+ * @private Undocumented.
650
+ */
651
+ get sessionId(): string | undefined {
652
+ if (!this.didInitialize) {
653
+ return undefined;
654
+ }
655
+
656
+ const internalState = internalStateByInstance.get(this);
657
+ assert(internalState !== undefined);
658
+ const { oidc, tokens } = internalState;
659
+
660
+ assert(oidc !== undefined);
661
+
662
+ if (!oidc.isUserLoggedIn) {
663
+ console.warn(
664
+ "Trying to read keycloak.sessionId when keycloak.authenticated is false is a logical error in your application"
665
+ );
666
+ return undefined;
667
+ }
668
+
669
+ assert(tokens !== undefined);
670
+
671
+ const { sid } = tokens.decodedIdToken_original;
672
+
673
+ assert(typeof sid === "string");
674
+
675
+ return sid;
676
+ }
677
+
678
+ /**
679
+ * @private Undocumented.
680
+ */
681
+ get profile(): KeycloakProfile | undefined {
682
+ const internalState = internalStateByInstance.get(this);
683
+ assert(internalState !== undefined);
684
+ const { profile } = internalState;
685
+ return profile;
686
+ }
687
+
688
+ /**
689
+ * @private Undocumented.
690
+ */
691
+ get userInfo(): KeycloakUserInfo | undefined {
692
+ const internalState = internalStateByInstance.get(this);
693
+ assert(internalState !== undefined);
694
+ const { userInfo } = internalState;
695
+ return userInfo;
696
+ }
697
+
698
+ /**
699
+ * Called when the adapter is initialized.
700
+ */
701
+ onReady?(authenticated: boolean): void;
702
+
703
+ /**
704
+ * Called when a user is successfully authenticated.
705
+ */
706
+ onAuthSuccess?(): void;
707
+
708
+ /**
709
+ * Called if there was an error during authentication.
710
+ */
711
+ onAuthError?(errorData: KeycloakError): void;
712
+
713
+ /**
714
+ * Called when the token is refreshed.
715
+ */
716
+ onAuthRefreshSuccess?(): void;
717
+
718
+ /**
719
+ * Called if there was an error while trying to refresh the token.
720
+ *
721
+ * NOTE oidc-spa: In oidc-spa an auth refresh error always triggers a page refresh.
722
+ */
723
+ //onAuthRefreshError?(): void;
724
+
725
+ /**
726
+ * Called if the user is logged out (will only be called if the session
727
+ * status iframe is enabled, or in Cordova mode).
728
+ *
729
+ * NOTE oidc-spa: In oidc-spa a logout always triggers a page refresh.
730
+ */
731
+ //onAuthLogout?(): void;
732
+
733
+ /**
734
+ * Called when the access token is expired. If a refresh token is available
735
+ * the token can be refreshed with Keycloak#updateToken, or in cases where
736
+ * it's not (ie. with implicit flow) you can redirect to login screen to
737
+ * obtain a new access token.
738
+ */
739
+ set onTokenExpired(value: (() => void) | undefined) {
740
+ const internalState = internalStateByInstance.get(this);
741
+ assert(internalState !== undefined);
742
+ const { $onTokenExpired } = internalState;
743
+ $onTokenExpired.current = value;
744
+ }
745
+ get onTokenExpired() {
746
+ const internalState = internalStateByInstance.get(this);
747
+ assert(internalState !== undefined);
748
+ const { $onTokenExpired } = internalState;
749
+ return $onTokenExpired.current;
750
+ }
751
+
752
+ /**
753
+ * Called when a AIA has been requested by the application.
754
+ * @param status the outcome of the required action
755
+ * @param action the alias name of the required action, e.g. UPDATE_PASSWORD, CONFIGURE_TOTP etc.
756
+ */
757
+ onActionUpdate?(status: "success" | "cancelled" | "error", action?: string): void;
758
+
759
+ /**
760
+ * Redirects to login form.
761
+ * @param options Login options.
762
+ */
763
+ async login(
764
+ options?: KeycloakLoginOptions & { doesCurrentHrefRequiresAuth?: boolean }
765
+ ): Promise<never> {
766
+ const {
767
+ redirectUri,
768
+ action,
769
+ loginHint,
770
+ acr,
771
+ acrValues,
772
+ idpHint,
773
+ locale,
774
+ doesCurrentHrefRequiresAuth
775
+ } = options ?? {};
776
+
777
+ const internalState = internalStateByInstance.get(this);
778
+ assert(internalState !== undefined);
779
+
780
+ if (!this.didInitialize) {
781
+ await internalState.dInitialized.pr;
782
+ }
783
+
784
+ const { oidc, keycloakUtils } = internalState;
785
+
786
+ assert(oidc !== undefined);
787
+
788
+ const extraQueryParams_commons: Record<string, string | undefined> = {
789
+ claims:
790
+ acr === undefined
791
+ ? undefined
792
+ : JSON.stringify({
793
+ id_token: {
794
+ acr
795
+ }
796
+ }),
797
+ acr_values: acrValues,
798
+ ui_locales: locale
799
+ };
800
+
801
+ if (oidc.isUserLoggedIn) {
802
+ assert(action !== "register");
803
+ assert(loginHint === undefined);
804
+ assert(idpHint === undefined);
805
+ assert(doesCurrentHrefRequiresAuth === undefined);
806
+
807
+ await oidc.goToAuthServer({
808
+ redirectUrl: redirectUri,
809
+ extraQueryParams: {
810
+ ...extraQueryParams_commons,
811
+ kc_action: action,
812
+ ui_locales: locale
813
+ }
814
+ });
815
+ assert(false);
816
+ }
817
+
818
+ assert(action === undefined || action === "register");
819
+
820
+ await oidc.login({
821
+ redirectUrl: redirectUri,
822
+ doesCurrentHrefRequiresAuth: doesCurrentHrefRequiresAuth ?? false,
823
+ extraQueryParams: {
824
+ ...extraQueryParams_commons,
825
+ login_hint: loginHint,
826
+ kc_idp_hint: idpHint
827
+ },
828
+ transformUrlBeforeRedirect:
829
+ action !== "register" ? undefined : keycloakUtils.transformUrlBeforeRedirectForRegister
830
+ });
831
+ assert(false);
832
+ }
833
+
834
+ /**
835
+ * Redirects to logout.
836
+ * @param options Logout options.
837
+ */
838
+ async logout(options?: KeycloakLogoutOptions): Promise<never> {
839
+ const internalState = internalStateByInstance.get(this);
840
+
841
+ assert(internalState !== undefined);
842
+
843
+ if (!this.didInitialize) {
844
+ await internalState.dInitialized.pr;
845
+ }
846
+
847
+ const { oidc, initOptions } = internalState;
848
+
849
+ assert(oidc !== undefined);
850
+ assert(initOptions !== undefined);
851
+
852
+ assert(oidc.isUserLoggedIn, "The user is not currently logged in");
853
+
854
+ const redirectUri = options?.redirectUri ?? initOptions.redirectUri;
855
+
856
+ await oidc.logout({
857
+ ...(redirectUri === undefined
858
+ ? { redirectTo: "current page" }
859
+ : { redirectTo: "specific url", url: redirectUri })
860
+ });
861
+ assert(false);
862
+ }
863
+
864
+ /**
865
+ * Redirects to registration form.
866
+ * @param options The options used for the registration.
867
+ */
868
+ async register(options?: KeycloakRegisterOptions): Promise<never> {
869
+ return this.login({
870
+ ...options,
871
+ action: "register"
872
+ });
873
+ }
874
+
875
+ /**
876
+ * Redirects to the Account Management Console.
877
+ */
878
+ async accountManagement(options?: {
879
+ /**
880
+ * Specifies the uri to redirect to when redirecting back to the application.
881
+ */
882
+ redirectUri?: string;
883
+ locale?: string;
884
+ }): Promise<never> {
885
+ const { redirectUri, locale } = options ?? {};
886
+
887
+ window.location.href = this.createAccountUrl({
888
+ redirectUri,
889
+ locale
890
+ });
891
+ return new Promise<never>(() => {});
892
+ }
893
+
894
+ /**
895
+ * Returns the URL to login form.
896
+ * @param options Supports same options as Keycloak#login.
897
+ *
898
+ * NOTE oidc-spa: Not supported, please use login() method.
899
+ */
900
+ //createLoginUrl(options?: KeycloakLoginOptions): Promise<string>;
901
+
902
+ /**
903
+ * Returns the URL to logout the user.
904
+ * @param options Logout options.
905
+ *
906
+ * NOTE oidc-spa: Not supported, please use logout() method.
907
+ */
908
+ //createLogoutUrl(options?: KeycloakLogoutOptions): string;
909
+
910
+ /**
911
+ * Returns the URL to registration page.
912
+ * @param options The options used for creating the registration URL.
913
+ *
914
+ * NOTE oidc-spa: Not supported please user login({ action: "register" })
915
+ */
916
+ //createRegisterUrl(options?: KeycloakRegisterOptions): Promise<string>;
917
+
918
+ /**
919
+ * Returns the URL to the Account Management Console.
920
+ * @param options The options used for creating the account URL.
921
+ */
922
+ createAccountUrl(options?: KeycloakAccountOptions & { locale?: string }): string {
923
+ const { locale, redirectUri } = options ?? {};
924
+
925
+ const internalState = internalStateByInstance.get(this);
926
+
927
+ assert(internalState !== undefined);
928
+
929
+ const { keycloakUtils } = internalState;
930
+
931
+ return keycloakUtils.getAccountUrl({
932
+ clientId: this.clientId,
933
+ backToAppFromAccountUrl: redirectUri ?? location.href,
934
+ locale
935
+ });
936
+ }
937
+
938
+ /**
939
+ * Returns true if the token has less than `minValidity` seconds left before
940
+ * it expires.
941
+ * @param minValidity If not specified, `0` is used.
942
+ */
943
+ isTokenExpired(minValidity: number = 0): boolean {
944
+ const internalState = internalStateByInstance.get(this);
945
+ assert(internalState !== undefined);
946
+
947
+ let accessTokenExpirationTime: number;
948
+
949
+ if (!this.didInitialize) {
950
+ const fakeAccessToken = this.token;
951
+ if (fakeAccessToken === undefined) {
952
+ throw new Error("isTokenExpired was called too early");
953
+ }
954
+
955
+ const time = readExpirationTimeInJwt(fakeAccessToken);
956
+
957
+ assert(time !== undefined, "The initial token is not a JWT");
958
+
959
+ accessTokenExpirationTime = time;
960
+ } else {
961
+ const { tokens } = internalState;
962
+ assert(tokens !== undefined);
963
+
964
+ accessTokenExpirationTime = tokens.accessTokenExpirationTime;
965
+ }
966
+
967
+ if (accessTokenExpirationTime > Date.now() + minValidity * 1_000) {
968
+ return false;
969
+ }
970
+
971
+ return true;
972
+ }
973
+
974
+ /**
975
+ * If the token expires within `minValidity` seconds, the token is refreshed.
976
+ * If the session status iframe is enabled, the session status is also
977
+ * checked.
978
+ * @param minValidity If not specified, `5` is used.
979
+ * @returns A promise to set functions that can be invoked if the token is
980
+ * still valid, or if the token is no longer valid.
981
+ * @example
982
+ * ```js
983
+ * keycloak.updateToken(5).then(function(refreshed) {
984
+ * if (refreshed) {
985
+ * alert('Token was successfully refreshed');
986
+ * } else {
987
+ * alert('Token is still valid');
988
+ * }
989
+ * }).catch(function() {
990
+ * alert('Failed to refresh the token, or the session has expired');
991
+ * });
992
+ */
993
+ async updateToken(minValidity: number = 5): Promise<boolean> {
994
+ const internalState = internalStateByInstance.get(this);
995
+
996
+ assert(internalState !== undefined);
997
+
998
+ if (!this.didInitialize) {
999
+ await internalState.dInitialized.pr;
1000
+ }
1001
+
1002
+ const { oidc } = internalState;
1003
+
1004
+ assert(oidc !== undefined);
1005
+
1006
+ assert(oidc.isUserLoggedIn, "updateToken called too early");
1007
+
1008
+ if (!this.isTokenExpired(minValidity)) {
1009
+ return false;
1010
+ }
1011
+
1012
+ await oidc.renewTokens();
1013
+
1014
+ return true;
1015
+ }
1016
+
1017
+ /**
1018
+ * Clears authentication state, including tokens. This can be useful if
1019
+ * the application has detected the session was expired, for example if
1020
+ * updating token fails. Invoking this results in Keycloak#onAuthLogout
1021
+ * callback listener being invoked.
1022
+ *
1023
+ * NOTE oidc-spa: In this implementation we never end up in the kind of
1024
+ * state where calling this makes sense.
1025
+ * oidc-spa take more control and exposes less complexity to the user of the
1026
+ * adapter.
1027
+ */
1028
+ //clearToken(): void;
1029
+
1030
+ /**
1031
+ * Returns true if the token has the given realm role.
1032
+ * @param role A realm role name.
1033
+ */
1034
+ hasRealmRole(role: string): boolean {
1035
+ const access = this.realmAccess;
1036
+ return access !== undefined && access.roles.indexOf(role) >= 0;
1037
+ }
1038
+
1039
+ /**
1040
+ * Returns true if the token has the given role for the resource.
1041
+ * @param role A role name.
1042
+ * @param resource If not specified, `clientId` is used.
1043
+ */
1044
+ hasResourceRole(role: string, resource?: string): boolean {
1045
+ if (this.resourceAccess === undefined) {
1046
+ return false;
1047
+ }
1048
+
1049
+ const access = this.resourceAccess[resource || this.clientId];
1050
+ return access !== undefined && access.roles.indexOf(role) >= 0;
1051
+ }
1052
+
1053
+ /**
1054
+ * Loads the user's profile.
1055
+ * @returns A promise to set functions to be invoked on success or error.
1056
+ */
1057
+ async loadUserProfile(): Promise<KeycloakProfile> {
1058
+ const internalState = internalStateByInstance.get(this);
1059
+ assert(internalState !== undefined);
1060
+
1061
+ if (!this.didInitialize) {
1062
+ await internalState.dInitialized.pr;
1063
+ }
1064
+
1065
+ const { oidc, keycloakUtils } = internalState;
1066
+
1067
+ assert(oidc !== undefined);
1068
+
1069
+ assert(oidc.isUserLoggedIn, "Can't load userProfile if user not authenticated");
1070
+
1071
+ const { accessToken } = await oidc.getTokens();
1072
+
1073
+ return (internalState.profile = await keycloakUtils.fetchUserProfile({ accessToken }));
1074
+ }
1075
+
1076
+ /**
1077
+ * @private Undocumented.
1078
+ */
1079
+ async loadUserInfo(): Promise<KeycloakUserInfo> {
1080
+ const internalState = internalStateByInstance.get(this);
1081
+ assert(internalState !== undefined);
1082
+
1083
+ if (!this.didInitialize) {
1084
+ await internalState.dInitialized.pr;
1085
+ }
1086
+
1087
+ const { oidc, keycloakUtils } = internalState;
1088
+
1089
+ assert(oidc !== undefined);
1090
+
1091
+ assert(oidc.isUserLoggedIn, "Can't load userInfo if user not authenticated");
1092
+
1093
+ const { accessToken } = await oidc.getTokens();
1094
+
1095
+ return (internalState.userInfo = await keycloakUtils.fetchUserInfo({ accessToken }));
1096
+ }
1097
+ }