oidc-spa 8.1.15 → 8.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/core/BASE_URL.d.ts +4 -0
  2. package/core/BASE_URL.js +12 -0
  3. package/core/BASE_URL.js.map +1 -0
  4. package/core/OidcMetadata.d.ts +5 -0
  5. package/core/OidcMetadata.js +56 -0
  6. package/core/OidcMetadata.js.map +1 -1
  7. package/core/createOidc.d.ts +15 -8
  8. package/core/createOidc.js +207 -104
  9. package/core/createOidc.js.map +1 -1
  10. package/core/diagnostic.d.ts +0 -1
  11. package/core/diagnostic.js +18 -5
  12. package/core/diagnostic.js.map +1 -1
  13. package/core/earlyInit.d.ts +1 -0
  14. package/core/earlyInit.js +8 -8
  15. package/core/earlyInit.js.map +1 -1
  16. package/core/loginOrGoToAuthServer.d.ts +0 -1
  17. package/core/loginOrGoToAuthServer.js +1 -16
  18. package/core/loginOrGoToAuthServer.js.map +1 -1
  19. package/core/loginSilent.d.ts +1 -2
  20. package/core/loginSilent.js +3 -21
  21. package/core/loginSilent.js.map +1 -1
  22. package/core/prShouldLoadApp.d.ts +4 -0
  23. package/core/prShouldLoadApp.js +13 -0
  24. package/core/prShouldLoadApp.js.map +1 -0
  25. package/esm/core/BASE_URL.d.ts +4 -0
  26. package/esm/core/BASE_URL.js +8 -0
  27. package/esm/core/BASE_URL.js.map +1 -0
  28. package/esm/core/OidcMetadata.d.ts +5 -0
  29. package/esm/core/OidcMetadata.js +54 -0
  30. package/esm/core/OidcMetadata.js.map +1 -1
  31. package/esm/core/createOidc.d.ts +15 -8
  32. package/esm/core/createOidc.js +207 -104
  33. package/esm/core/createOidc.js.map +1 -1
  34. package/esm/core/diagnostic.d.ts +0 -1
  35. package/esm/core/diagnostic.js +15 -1
  36. package/esm/core/diagnostic.js.map +1 -1
  37. package/esm/core/earlyInit.d.ts +1 -0
  38. package/esm/core/earlyInit.js +8 -8
  39. package/esm/core/earlyInit.js.map +1 -1
  40. package/esm/core/loginOrGoToAuthServer.d.ts +0 -1
  41. package/esm/core/loginOrGoToAuthServer.js +1 -16
  42. package/esm/core/loginOrGoToAuthServer.js.map +1 -1
  43. package/esm/core/loginSilent.d.ts +1 -2
  44. package/esm/core/loginSilent.js +3 -21
  45. package/esm/core/loginSilent.js.map +1 -1
  46. package/esm/core/prShouldLoadApp.d.ts +4 -0
  47. package/esm/core/prShouldLoadApp.js +9 -0
  48. package/esm/core/prShouldLoadApp.js.map +1 -0
  49. package/esm/keycloak/keycloak-js/Keycloak.d.ts +1 -1
  50. package/esm/keycloak/keycloak-js/Keycloak.js +1 -1
  51. package/esm/keycloak/keycloak-js/Keycloak.js.map +1 -1
  52. package/esm/keycloak/keycloakIssuerUriParsed.js +8 -1
  53. package/esm/keycloak/keycloakIssuerUriParsed.js.map +1 -1
  54. package/esm/mock/oidc.d.ts +3 -1
  55. package/esm/mock/oidc.js +4 -2
  56. package/esm/mock/oidc.js.map +1 -1
  57. package/esm/react-spa/apiBuilder.d.ts +12 -0
  58. package/esm/react-spa/apiBuilder.js +26 -0
  59. package/esm/react-spa/apiBuilder.js.map +1 -0
  60. package/esm/react-spa/createOidcSpaApi.d.ts +8 -0
  61. package/esm/react-spa/createOidcSpaApi.js +387 -0
  62. package/esm/react-spa/createOidcSpaApi.js.map +1 -0
  63. package/esm/react-spa/index.d.ts +2 -0
  64. package/esm/react-spa/index.js +3 -0
  65. package/esm/react-spa/index.js.map +1 -0
  66. package/esm/react-spa/types.d.ts +279 -0
  67. package/esm/react-spa/types.js +2 -0
  68. package/esm/react-spa/types.js.map +1 -0
  69. package/esm/tanstack-start/react/apiBuilder.js.map +1 -1
  70. package/esm/tanstack-start/react/createOidcSpaApi.js +13 -9
  71. package/esm/tanstack-start/react/createOidcSpaApi.js.map +1 -1
  72. package/esm/tanstack-start/react/types.d.ts +5 -4
  73. package/esm/tools/isLikelyDevServer.d.ts +1 -0
  74. package/esm/tools/isLikelyDevServer.js +14 -0
  75. package/esm/tools/isLikelyDevServer.js.map +1 -0
  76. package/keycloak/keycloak-js/Keycloak.d.ts +1 -1
  77. package/keycloak/keycloak-js/Keycloak.js +1 -1
  78. package/keycloak/keycloak-js/Keycloak.js.map +1 -1
  79. package/keycloak/keycloakIssuerUriParsed.js +8 -1
  80. package/keycloak/keycloakIssuerUriParsed.js.map +1 -1
  81. package/mock/oidc.d.ts +3 -1
  82. package/mock/oidc.js +4 -2
  83. package/mock/oidc.js.map +1 -1
  84. package/package.json +5 -1
  85. package/react-spa/apiBuilder.d.ts +12 -0
  86. package/react-spa/apiBuilder.js +29 -0
  87. package/react-spa/apiBuilder.js.map +1 -0
  88. package/react-spa/createOidcSpaApi.d.ts +8 -0
  89. package/react-spa/createOidcSpaApi.js +423 -0
  90. package/react-spa/createOidcSpaApi.js.map +1 -0
  91. package/react-spa/index.d.ts +2 -0
  92. package/react-spa/index.js +6 -0
  93. package/react-spa/index.js.map +1 -0
  94. package/react-spa/types.d.ts +279 -0
  95. package/react-spa/types.js +3 -0
  96. package/react-spa/types.js.map +1 -0
  97. package/src/angular.ts +1 -1
  98. package/src/core/BASE_URL.ts +9 -0
  99. package/src/core/OidcMetadata.ts +75 -0
  100. package/src/core/createOidc.ts +273 -147
  101. package/src/core/diagnostic.ts +21 -2
  102. package/src/core/earlyInit.ts +14 -11
  103. package/src/core/loginOrGoToAuthServer.ts +0 -22
  104. package/src/core/loginSilent.ts +4 -27
  105. package/src/core/prShouldLoadApp.ts +11 -0
  106. package/src/keycloak/keycloak-js/Keycloak.ts +2 -2
  107. package/src/keycloak/keycloakIssuerUriParsed.ts +10 -1
  108. package/src/mock/oidc.ts +9 -3
  109. package/src/react-spa/apiBuilder.ts +70 -0
  110. package/src/react-spa/createOidcSpaApi.tsx +527 -0
  111. package/src/react-spa/index.ts +4 -0
  112. package/src/react-spa/types.tsx +308 -0
  113. package/src/tanstack-start/react/apiBuilder.ts +0 -1
  114. package/src/tanstack-start/react/createOidcSpaApi.tsx +24 -20
  115. package/src/tanstack-start/react/types.tsx +3 -4
  116. package/src/tools/isLikelyDevServer.ts +17 -0
  117. package/src/vite-plugin/handleClientEntrypoint.ts +5 -5
  118. package/src/vite-plugin/manageOptimizedDeps.ts +64 -0
  119. package/src/vite-plugin/projectType.ts +18 -0
  120. package/src/vite-plugin/vite-plugin.ts +40 -10
  121. package/tools/isLikelyDevServer.d.ts +1 -0
  122. package/tools/isLikelyDevServer.js +17 -0
  123. package/tools/isLikelyDevServer.js.map +1 -0
  124. package/vite-plugin/handleClientEntrypoint.d.ts +2 -0
  125. package/vite-plugin/handleClientEntrypoint.js +3 -4
  126. package/vite-plugin/handleClientEntrypoint.js.map +1 -1
  127. package/vite-plugin/manageOptimizedDeps.d.ts +6 -0
  128. package/vite-plugin/{excludeModuleExportFromOptimizedDeps.js → manageOptimizedDeps.js} +42 -7
  129. package/vite-plugin/manageOptimizedDeps.js.map +1 -0
  130. package/vite-plugin/projectType.d.ts +4 -0
  131. package/vite-plugin/projectType.js +15 -0
  132. package/vite-plugin/projectType.js.map +1 -0
  133. package/vite-plugin/{transformCreateFileRoute.js → transformTanstackRouterCreateFileRoute.js} +1 -1
  134. package/vite-plugin/transformTanstackRouterCreateFileRoute.js.map +1 -0
  135. package/vite-plugin/vite-plugin.d.ts +1 -1
  136. package/vite-plugin/vite-plugin.js +28 -8
  137. package/vite-plugin/vite-plugin.js.map +1 -1
  138. package/esm/tools/infer_import_meta_env_BASE_URL.d.ts +0 -1
  139. package/esm/tools/infer_import_meta_env_BASE_URL.js +0 -15
  140. package/esm/tools/infer_import_meta_env_BASE_URL.js.map +0 -1
  141. package/src/tools/infer_import_meta_env_BASE_URL.ts +0 -19
  142. package/src/vite-plugin/detectProjectType.ts +0 -20
  143. package/src/vite-plugin/excludeModuleExportFromOptimizedDeps.ts +0 -20
  144. package/vite-plugin/detectProjectType.d.ts +0 -10
  145. package/vite-plugin/detectProjectType.js +0 -15
  146. package/vite-plugin/detectProjectType.js.map +0 -1
  147. package/vite-plugin/excludeModuleExportFromOptimizedDeps.d.ts +0 -4
  148. package/vite-plugin/excludeModuleExportFromOptimizedDeps.js.map +0 -1
  149. package/vite-plugin/transformCreateFileRoute.js.map +0 -1
  150. /package/src/vite-plugin/{transformCreateFileRoute.ts → transformTanstackRouterCreateFileRoute.ts} +0 -0
  151. /package/vite-plugin/{transformCreateFileRoute.d.ts → transformTanstackRouterCreateFileRoute.d.ts} +0 -0
@@ -0,0 +1,279 @@
1
+ import type { ReactNode, ComponentType } from "react";
2
+ import type { Oidc as Oidc_core, OidcInitializationError } from "../core";
3
+ import type { OidcMetadata } from "../core/OidcMetadata";
4
+ export type UseOidc<DecodedIdToken> = {
5
+ (params?: {
6
+ assert?: undefined;
7
+ }): UseOidc.Oidc<DecodedIdToken>;
8
+ (params: {
9
+ assert: "user logged in";
10
+ }): UseOidc.Oidc.LoggedIn<DecodedIdToken>;
11
+ (params: {
12
+ assert: "user not logged in";
13
+ }): UseOidc.Oidc.NotLoggedIn;
14
+ };
15
+ export declare namespace UseOidc {
16
+ type WithAutoLogin<DecodedIdToken> = (params?: {
17
+ assert: "user logged in";
18
+ }) => Oidc.LoggedIn<DecodedIdToken>;
19
+ type Oidc<DecodedIdToken> = (Oidc.NotLoggedIn & {
20
+ decodedIdToken?: never;
21
+ logout?: never;
22
+ renewTokens?: never;
23
+ goToAuthServer?: never;
24
+ backFromAuthServer?: never;
25
+ isNewBrowserSession?: never;
26
+ }) | (Oidc.LoggedIn<DecodedIdToken> & {
27
+ login?: never;
28
+ initializationError?: never;
29
+ });
30
+ namespace Oidc {
31
+ type Common = {
32
+ issuerUri: string;
33
+ clientId: string;
34
+ };
35
+ export type NotLoggedIn = Common & {
36
+ login: (params?: {
37
+ extraQueryParams?: Record<string, string | undefined>;
38
+ redirectUrl?: string;
39
+ transformUrlBeforeRedirect?: (url: string) => string;
40
+ }) => Promise<never>;
41
+ autoLogoutState: {
42
+ shouldDisplayWarning: false;
43
+ };
44
+ isUserLoggedIn: false;
45
+ initializationError: OidcInitializationError | undefined;
46
+ };
47
+ export type LoggedIn<DecodedIdToken> = Common & {
48
+ isUserLoggedIn: true;
49
+ decodedIdToken: DecodedIdToken;
50
+ logout: Oidc_core.LoggedIn["logout"];
51
+ renewTokens: Oidc_core.LoggedIn["renewTokens"];
52
+ goToAuthServer: Oidc_core.LoggedIn["goToAuthServer"];
53
+ backFromAuthServer: Oidc_core.LoggedIn["backFromAuthServer"];
54
+ isNewBrowserSession: boolean;
55
+ autoLogoutState: {
56
+ shouldDisplayWarning: true;
57
+ secondsLeftBeforeAutoLogout: number;
58
+ } | {
59
+ shouldDisplayWarning: false;
60
+ };
61
+ };
62
+ export {};
63
+ }
64
+ }
65
+ export type GetOidc<DecodedIdToken> = {
66
+ (params?: {
67
+ assert?: undefined;
68
+ }): Promise<GetOidc.Oidc<DecodedIdToken>>;
69
+ (params: {
70
+ assert: "user logged in";
71
+ }): Promise<GetOidc.Oidc.LoggedIn<DecodedIdToken>>;
72
+ (params: {
73
+ assert: "user not logged in";
74
+ }): Promise<GetOidc.Oidc.NotLoggedIn>;
75
+ };
76
+ export declare namespace GetOidc {
77
+ type WithAutoLogin<DecodedIdToken> = (params?: {
78
+ assert: "user logged in";
79
+ }) => Promise<Oidc.LoggedIn<DecodedIdToken>>;
80
+ type Oidc<DecodedIdToken> = (Oidc.NotLoggedIn & {
81
+ getAccessToken?: never;
82
+ getDecodedIdToken?: never;
83
+ logout?: never;
84
+ renewTokens?: never;
85
+ goToAuthServer?: never;
86
+ backFromAuthServer?: never;
87
+ isNewBrowserSession?: never;
88
+ subscribeToAutoLogoutState?: never;
89
+ }) | (Oidc.LoggedIn<DecodedIdToken> & {
90
+ initializationError?: never;
91
+ login?: never;
92
+ });
93
+ namespace Oidc {
94
+ type Common = {
95
+ issuerUri: string;
96
+ clientId: string;
97
+ };
98
+ export type NotLoggedIn = Common & {
99
+ isUserLoggedIn: false;
100
+ initializationError: OidcInitializationError | undefined;
101
+ login: Oidc_core.NotLoggedIn["login"];
102
+ };
103
+ export type LoggedIn<DecodedIdToken> = Common & {
104
+ isUserLoggedIn: true;
105
+ getAccessToken: () => Promise<string>;
106
+ getDecodedIdToken: () => DecodedIdToken;
107
+ logout: Oidc_core.LoggedIn["logout"];
108
+ renewTokens: Oidc_core.LoggedIn["renewTokens"];
109
+ goToAuthServer: Oidc_core.LoggedIn["goToAuthServer"];
110
+ backFromAuthServer: Oidc_core.LoggedIn["backFromAuthServer"];
111
+ isNewBrowserSession: boolean;
112
+ subscribeToAutoLogoutState: (next: (autoLogoutState: {
113
+ shouldDisplayWarning: true;
114
+ secondsLeftBeforeAutoLogout: number;
115
+ } | {
116
+ shouldDisplayWarning: false;
117
+ }) => void) => {
118
+ unsubscribeFromAutoLogoutState: () => void;
119
+ };
120
+ };
121
+ export {};
122
+ }
123
+ }
124
+ export type ParamsOfBootstrap<AutoLogin, DecodedIdToken> = ParamsOfBootstrap.Real<AutoLogin> | ParamsOfBootstrap.Mock<AutoLogin, DecodedIdToken>;
125
+ export declare namespace ParamsOfBootstrap {
126
+ type Real<AutoLogin> = {
127
+ implementation: "real";
128
+ /**
129
+ * See: https://docs.oidc-spa.dev/v/v8/providers-configuration/provider-configuration
130
+ */
131
+ issuerUri: string;
132
+ /**
133
+ * See: https://docs.oidc-spa.dev/v/v8/providers-configuration/provider-configuration
134
+ */
135
+ clientId: string;
136
+ /**
137
+ * Default: 45 second.
138
+ * It defines how long before the auto logout we should start
139
+ * displaying an overlay message to the user alerting them
140
+ * like: "Are you still there? You'll be disconnected in 45...44..."
141
+ * NOTE: This parameter is only UI related! It does not defines
142
+ * after how much time of inactivity the user should be auto logged out.
143
+ * This is a server policy (that can be overwrote by idleSessionLifetimeInSeconds)
144
+ * See: https://docs.oidc-spa.dev/v/v8/auto-logout
145
+ */
146
+ startCountdownSecondsBeforeAutoLogout?: number;
147
+ /**
148
+ * This parameter defines after how many seconds of inactivity the user should be
149
+ * logged out automatically.
150
+ *
151
+ * WARNING: It should be configured on the identity server side
152
+ * as it's the authoritative source for security policies and not the client.
153
+ * If you don't provide this parameter it will be inferred from the refresh token expiration time.
154
+ * Some provider however don't issue a refresh token or do not correctly set the
155
+ * expiration time. This parameter enable you to hard code the value to compensate
156
+ * the shortcoming of your auth server.
157
+ * */
158
+ idleSessionLifetimeInSeconds?: number;
159
+ /**
160
+ * The scopes being requested from the OIDC/OAuth2 provider (default: `["profile"]`
161
+ * (the scope "openid" is added automatically as it's mandatory)
162
+ **/
163
+ scopes?: string[];
164
+ /**
165
+ * Transform the url (authorization endpoint) before redirecting to the login pages.
166
+ *
167
+ * The isSilent parameter is true when the redirect is initiated in the background iframe for silent signin.
168
+ * This can be used to omit ui related query parameters (like `ui_locales`).
169
+ */
170
+ transformUrlBeforeRedirect?: (params: {
171
+ authorizationUrl: string;
172
+ isSilent: boolean;
173
+ }) => string;
174
+ /**
175
+ * Extra query params to be added to the authorization endpoint url before redirecting or silent signing in.
176
+ * You can provide a function that returns those extra query params, it will be called
177
+ * when login() is called.
178
+ *
179
+ * Example: extraQueryParams: ()=> ({ ui_locales: "fr" })
180
+ *
181
+ * This parameter can also be passed to login() directly.
182
+ */
183
+ extraQueryParams?: Record<string, string | undefined> | ((params: {
184
+ isSilent: boolean;
185
+ url: string;
186
+ }) => Record<string, string | undefined>);
187
+ /**
188
+ * Extra body params to be added to the /token POST request.
189
+ *
190
+ * It will be used when for the initial request, whenever the token is getting refreshed and if you call `renewTokens()`.
191
+ * You can also provide this parameter directly to the `renewTokens()` method.
192
+ *
193
+ * It can be either a string to string record or a function that returns a string to string record.
194
+ *
195
+ * Example: extraTokenParams: ()=> ({ selectedCustomer: "xxx" })
196
+ * extraTokenParams: { selectedCustomer: "xxx" }
197
+ */
198
+ extraTokenParams?: Record<string, string | undefined> | (() => Record<string, string | undefined>);
199
+ /**
200
+ * Default: false
201
+ *
202
+ * See: https://docs.oidc-spa.dev/v/v8/resources/iframe-related-issues
203
+ */
204
+ noIframe?: boolean;
205
+ debugLogs?: boolean;
206
+ /**
207
+ * WARNING: This option exists solely as a workaround
208
+ * for limitations in the Google OAuth API.
209
+ * See: https://docs.oidc-spa.dev/providers-configuration/google-oauth
210
+ *
211
+ * Do not use this for other providers.
212
+ * If you think you need a client secret in a SPA, you are likely
213
+ * trying to use a confidential (private) client in the browser,
214
+ * which is insecure and not supported.
215
+ */
216
+ __unsafe_clientSecret?: string;
217
+ /**
218
+ * This option should only be used as a last resort.
219
+ *
220
+ * If your OIDC provider is correctly configured, this should not be necessary.
221
+ *
222
+ * The metadata is normally retrieved automatically from:
223
+ * `${issuerUri}/.well-known/openid-configuration`
224
+ *
225
+ * Use this only if that endpoint is not accessible (e.g. due to missing CORS headers
226
+ * or non-standard deployments), and you cannot fix the server-side configuration.
227
+ */
228
+ __metadata?: Partial<OidcMetadata>;
229
+ /**
230
+ * WARNING: Setting this to true is a workaround for provider
231
+ * like Google OAuth that don't support JWT access token.
232
+ * Use at your own risk, this is a hack.
233
+ */
234
+ __unsafe_useIdTokenAsAccessToken?: boolean;
235
+ /**
236
+ * Let's you override the params passed to
237
+ * (if you weren't able to provide it)
238
+ */
239
+ BASE_URL?: string;
240
+ } & (AutoLogin extends true ? {} : {});
241
+ type Mock<AutoLogin, DecodedIdToken> = {
242
+ implementation: "mock";
243
+ issuerUri_mock?: string;
244
+ clientId_mock?: string;
245
+ decodedIdToken_mock?: DecodedIdToken;
246
+ /**
247
+ * Let's you override the params passed to
248
+ * (if you weren't able to provide it)
249
+ */
250
+ BASE_URL?: string;
251
+ } & (AutoLogin extends true ? {
252
+ isUserInitiallyLoggedIn?: true;
253
+ } : {
254
+ isUserInitiallyLoggedIn: boolean;
255
+ });
256
+ }
257
+ export type OidcSpaApi<AutoLogin, DecodedIdToken> = {
258
+ bootstrapOidc: (params: ParamsOfBootstrap<AutoLogin, DecodedIdToken>) => void;
259
+ useOidc: AutoLogin extends true ? UseOidc.WithAutoLogin<DecodedIdToken> : UseOidc<DecodedIdToken>;
260
+ getOidc: AutoLogin extends true ? GetOidc.WithAutoLogin<DecodedIdToken> : GetOidc<DecodedIdToken>;
261
+ } & (AutoLogin extends true ? {
262
+ OidcInitializationErrorGate: (props: {
263
+ errorComponent: ComponentType<{
264
+ oidcInitializationError: OidcInitializationError;
265
+ }>;
266
+ children: ReactNode;
267
+ }) => ReactNode;
268
+ } : {
269
+ enforceLogin: (loaderContext: {
270
+ request?: {
271
+ url?: string;
272
+ };
273
+ cause?: "preload" | string;
274
+ location?: {
275
+ href?: string;
276
+ };
277
+ }) => Promise<void | never>;
278
+ withLoginEnforced: <Props extends Record<string, unknown>>(component: ComponentType<Props>) => (props: Props) => ReactNode;
279
+ });
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/react-spa/types.tsx"],"names":[],"mappings":""}
package/src/angular.ts CHANGED
@@ -150,7 +150,7 @@ export type ParamsOfProvide = {
150
150
  assert<
151
151
  Equals<
152
152
  Omit<ParamsOfProvide, "autoLogoutWarningDurationSeconds">,
153
- Omit<ParamsOfCreateOidc<any, boolean>, "homeUrl" | "decodedIdTokenSchema">
153
+ Omit<ParamsOfCreateOidc<any, boolean>, "homeUrl" | "BASE_URL" | "decodedIdTokenSchema">
154
154
  >
155
155
  >;
156
156
 
@@ -0,0 +1,9 @@
1
+ let BASE_URL: string | undefined = undefined;
2
+
3
+ export function getBASE_URL() {
4
+ return BASE_URL;
5
+ }
6
+
7
+ export function setBASE_URL(params: { BASE_URL: string }) {
8
+ BASE_URL = params.BASE_URL;
9
+ }
@@ -1,5 +1,6 @@
1
1
  import { type OidcMetadata as OidcClientTsOidcMetadata } from "../vendor/frontend/oidc-client-ts";
2
2
  import { assert, type Equals } from "../tools/tsafe/assert";
3
+ import { getIsLikelyDevServer } from "../tools/isLikelyDevServer";
3
4
 
4
5
  /**
5
6
  * OpenID Providers have metadata describing their configuration.
@@ -269,3 +270,77 @@ export type OidcMetadata = {
269
270
  };
270
271
 
271
272
  assert<Equals<OidcMetadata, OidcClientTsOidcMetadata>>;
273
+
274
+ export const WELL_KNOWN_PATH = "/.well-known/openid-configuration";
275
+
276
+ function getSessionStorageKey(params: { issuerUri: string }) {
277
+ const { issuerUri } = params;
278
+
279
+ return `oidc-spa:openid-configuration:${issuerUri}`;
280
+ }
281
+
282
+ function readSessionStorage(params: { issuerUri: string }) {
283
+ const { issuerUri } = params;
284
+
285
+ const value = sessionStorage.getItem(getSessionStorageKey({ issuerUri }));
286
+
287
+ if (value === null) {
288
+ return undefined;
289
+ }
290
+
291
+ return JSON.parse(value) as Partial<OidcClientTsOidcMetadata>;
292
+ }
293
+
294
+ function setSessionStorage(params: { issuerUri: string; oidcMetadata: Partial<OidcMetadata> }): void {
295
+ const { issuerUri, oidcMetadata } = params;
296
+
297
+ sessionStorage.setItem(getSessionStorageKey({ issuerUri }), JSON.stringify(oidcMetadata));
298
+ }
299
+
300
+ export async function fetchOidcMetadata(params: { issuerUri: string }) {
301
+ const { issuerUri } = params;
302
+
303
+ from_cache: {
304
+ const oidcMetadata = readSessionStorage({ issuerUri });
305
+
306
+ if (oidcMetadata === undefined) {
307
+ break from_cache;
308
+ }
309
+
310
+ return oidcMetadata;
311
+ }
312
+
313
+ let oidcMetadata: Partial<OidcMetadata>;
314
+
315
+ try {
316
+ const response = await fetch(`${issuerUri}${WELL_KNOWN_PATH}`, {
317
+ headers: {
318
+ Accept: "application/jwk-set+json, application/json"
319
+ }
320
+ });
321
+
322
+ if (!response.ok) {
323
+ throw new Error();
324
+ }
325
+
326
+ const obj = await response.json();
327
+
328
+ {
329
+ const { authorization_endpoint } = obj;
330
+
331
+ if (typeof authorization_endpoint !== "string") {
332
+ throw new Error();
333
+ }
334
+ }
335
+
336
+ oidcMetadata = obj;
337
+ } catch {
338
+ return undefined;
339
+ }
340
+
341
+ if (!getIsLikelyDevServer()) {
342
+ setSessionStorage({ issuerUri, oidcMetadata });
343
+ }
344
+
345
+ return oidcMetadata;
346
+ }