oidc-spa 8.1.9 → 8.1.11

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 (196) hide show
  1. package/backend.d.ts +27 -6
  2. package/backend.js +124 -139
  3. package/backend.js.map +1 -1
  4. package/core/Oidc.d.ts +28 -4
  5. package/core/createOidc.d.ts +12 -3
  6. package/core/createOidc.js +1 -1
  7. package/core/createOidc.js.map +1 -1
  8. package/core/earlyInit.d.ts +1 -0
  9. package/core/earlyInit.js +11 -4
  10. package/core/earlyInit.js.map +1 -1
  11. package/core/iframeMessageProtection.js +16 -18
  12. package/core/iframeMessageProtection.js.map +1 -1
  13. package/core/loginOrGoToAuthServer.js +8 -3
  14. package/core/loginOrGoToAuthServer.js.map +1 -1
  15. package/core/loginSilent.js +4 -0
  16. package/core/loginSilent.js.map +1 -1
  17. package/core/oidcClientTsUserToTokens.d.ts +1 -1
  18. package/core/oidcClientTsUserToTokens.js.map +1 -1
  19. package/core/requiredPostHydrationReplaceNavigationUrl.d.ts +6 -0
  20. package/core/requiredPostHydrationReplaceNavigationUrl.js +12 -0
  21. package/core/requiredPostHydrationReplaceNavigationUrl.js.map +1 -0
  22. package/entrypoint.d.ts +1 -0
  23. package/entrypoint.js +3 -1
  24. package/entrypoint.js.map +1 -1
  25. package/esm/angular.d.ts +14 -4
  26. package/esm/angular.js +155 -10
  27. package/esm/angular.js.map +1 -1
  28. package/esm/backend.d.ts +48 -0
  29. package/esm/backend.js +259 -0
  30. package/esm/backend.js.map +1 -0
  31. package/esm/core/Oidc.d.ts +28 -4
  32. package/esm/core/createOidc.d.ts +12 -3
  33. package/esm/core/createOidc.js +1 -1
  34. package/esm/core/createOidc.js.map +1 -1
  35. package/esm/core/earlyInit.d.ts +1 -0
  36. package/esm/core/earlyInit.js +11 -4
  37. package/esm/core/earlyInit.js.map +1 -1
  38. package/esm/core/iframeMessageProtection.js +16 -18
  39. package/esm/core/iframeMessageProtection.js.map +1 -1
  40. package/esm/core/loginOrGoToAuthServer.js +8 -3
  41. package/esm/core/loginOrGoToAuthServer.js.map +1 -1
  42. package/esm/core/loginSilent.js +4 -0
  43. package/esm/core/loginSilent.js.map +1 -1
  44. package/esm/core/oidcClientTsUserToTokens.d.ts +1 -1
  45. package/esm/core/oidcClientTsUserToTokens.js.map +1 -1
  46. package/esm/core/requiredPostHydrationReplaceNavigationUrl.d.ts +6 -0
  47. package/esm/core/requiredPostHydrationReplaceNavigationUrl.js +8 -0
  48. package/esm/core/requiredPostHydrationReplaceNavigationUrl.js.map +1 -0
  49. package/esm/entrypoint.d.ts +1 -0
  50. package/esm/entrypoint.js +1 -0
  51. package/esm/entrypoint.js.map +1 -1
  52. package/esm/mock/oidc.d.ts +1 -1
  53. package/esm/mock/oidc.js.map +1 -1
  54. package/esm/react/react.d.ts +1 -1
  55. package/esm/tanstack-start/react/accessTokenValidation_rfc9068.d.ts +12 -0
  56. package/esm/tanstack-start/react/accessTokenValidation_rfc9068.js +95 -0
  57. package/esm/tanstack-start/react/accessTokenValidation_rfc9068.js.map +1 -0
  58. package/esm/tanstack-start/react/apiBuilder.d.ts +27 -0
  59. package/esm/tanstack-start/react/apiBuilder.js +58 -0
  60. package/esm/tanstack-start/react/apiBuilder.js.map +1 -0
  61. package/esm/tanstack-start/react/createOidcSpaApi.d.ts +9 -0
  62. package/esm/tanstack-start/react/createOidcSpaApi.js +678 -0
  63. package/esm/tanstack-start/react/createOidcSpaApi.js.map +1 -0
  64. package/esm/tanstack-start/react/index.d.ts +3 -0
  65. package/esm/tanstack-start/react/index.js +4 -0
  66. package/esm/tanstack-start/react/index.js.map +1 -0
  67. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/UnifiedClientRetryForSsrLoadersError.d.ts +4 -0
  68. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/UnifiedClientRetryForSsrLoadersError.js +8 -0
  69. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/UnifiedClientRetryForSsrLoadersError.js.map +1 -0
  70. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/enableUnifiedClientRetryForSsrLoaders.d.ts +4 -0
  71. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/enableUnifiedClientRetryForSsrLoaders.js +76 -0
  72. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/enableUnifiedClientRetryForSsrLoaders.js.map +1 -0
  73. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/entrypoint.d.ts +1 -0
  74. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/entrypoint.js +11 -0
  75. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/entrypoint.js.map +1 -0
  76. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/index.d.ts +2 -0
  77. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/index.js +3 -0
  78. package/esm/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/index.js.map +1 -0
  79. package/esm/tanstack-start/react/types.d.ts +355 -0
  80. package/esm/tanstack-start/react/types.js +2 -0
  81. package/esm/tanstack-start/react/types.js.map +1 -0
  82. package/esm/tanstack-start/react/withHandlingOidcPostLoginNavigation.d.ts +2 -0
  83. package/esm/tanstack-start/react/withHandlingOidcPostLoginNavigation.js +25 -0
  84. package/esm/tanstack-start/react/withHandlingOidcPostLoginNavigation.js.map +1 -0
  85. package/esm/tools/GetterOrDirectValue.d.ts +1 -0
  86. package/esm/tools/GetterOrDirectValue.js +2 -0
  87. package/esm/tools/GetterOrDirectValue.js.map +1 -0
  88. package/esm/tools/ZodSchemaLike.d.ts +3 -0
  89. package/esm/tools/ZodSchemaLike.js +2 -0
  90. package/esm/tools/ZodSchemaLike.js.map +1 -0
  91. package/esm/tools/inferIsViteDev.d.ts +1 -0
  92. package/esm/tools/inferIsViteDev.js +6 -0
  93. package/esm/tools/inferIsViteDev.js.map +1 -0
  94. package/esm/tools/infer_import_meta_env_BASE_URL.d.ts +1 -0
  95. package/esm/tools/infer_import_meta_env_BASE_URL.js +15 -0
  96. package/esm/tools/infer_import_meta_env_BASE_URL.js.map +1 -0
  97. package/esm/tools/tsafe/uncapitalize.d.ts +2 -0
  98. package/esm/tools/tsafe/uncapitalize.js +5 -0
  99. package/esm/tools/tsafe/uncapitalize.js.map +1 -0
  100. package/esm/vendor/backend/evt.d.ts +2 -0
  101. package/esm/vendor/backend/evt.js +3286 -0
  102. package/esm/vendor/backend/jose.d.ts +1 -0
  103. package/esm/vendor/backend/jose.js +3546 -0
  104. package/esm/vendor/backend/tsafe.d.ts +5 -0
  105. package/esm/vendor/backend/tsafe.js +68 -0
  106. package/esm/vendor/backend/zod.d.ts +1 -0
  107. package/esm/vendor/backend/zod.js +4023 -0
  108. package/esm/vendor/frontend/worker-timers.js +261 -1
  109. package/mock/oidc.d.ts +1 -1
  110. package/mock/oidc.js.map +1 -1
  111. package/package.json +40 -4
  112. package/react/react.d.ts +1 -1
  113. package/src/angular.ts +224 -9
  114. package/src/backend.ts +201 -166
  115. package/src/core/Oidc.ts +41 -11
  116. package/src/core/createOidc.ts +12 -3
  117. package/src/core/earlyInit.ts +19 -4
  118. package/src/core/iframeMessageProtection.ts +14 -15
  119. package/src/core/loginOrGoToAuthServer.ts +11 -3
  120. package/src/core/loginSilent.ts +5 -0
  121. package/src/core/oidcClientTsUserToTokens.ts +2 -2
  122. package/src/core/requiredPostHydrationReplaceNavigationUrl.ts +11 -0
  123. package/src/entrypoint.ts +1 -0
  124. package/src/mock/oidc.ts +2 -2
  125. package/src/react/react.tsx +1 -1
  126. package/src/tanstack-start/react/accessTokenValidation_rfc9068.ts +135 -0
  127. package/src/tanstack-start/react/apiBuilder.ts +151 -0
  128. package/src/tanstack-start/react/createOidcSpaApi.tsx +1009 -0
  129. package/src/tanstack-start/react/index.ts +5 -0
  130. package/src/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/UnifiedClientRetryForSsrLoadersError.ts +8 -0
  131. package/src/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/enableUnifiedClientRetryForSsrLoaders.tsx +110 -0
  132. package/src/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/entrypoint.ts +13 -0
  133. package/src/tanstack-start/react/rfcUnifiedClientRetryForSsrLoaders/index.ts +2 -0
  134. package/src/tanstack-start/react/types.tsx +415 -0
  135. package/src/tanstack-start/react/withHandlingOidcPostLoginNavigation.tsx +35 -0
  136. package/src/tools/GetterOrDirectValue.ts +1 -0
  137. package/src/tools/ZodSchemaLike.ts +3 -0
  138. package/src/tools/getThisCodebaseRootDirPath_cjs.ts +19 -0
  139. package/src/tools/inferIsViteDev.ts +6 -0
  140. package/src/tools/infer_import_meta_env_BASE_URL.ts +19 -0
  141. package/src/tools/tsafe/uncapitalize.ts +4 -0
  142. package/src/vendor/backend/jose.ts +1 -0
  143. package/src/vendor/build-runtime/babel.ts +6 -0
  144. package/src/vendor/build-runtime/magic-string.ts +3 -0
  145. package/src/vite-plugin/detectProjectType.ts +20 -0
  146. package/src/vite-plugin/excludeModuleExportFromOptimizedDeps.ts +20 -0
  147. package/src/vite-plugin/handleClientEntrypoint.ts +260 -0
  148. package/src/vite-plugin/index.ts +1 -0
  149. package/src/vite-plugin/transformCreateFileRoute.ts +240 -0
  150. package/src/vite-plugin/vite-plugin.ts +54 -0
  151. package/tools/GetterOrDirectValue.d.ts +1 -0
  152. package/tools/GetterOrDirectValue.js +3 -0
  153. package/tools/GetterOrDirectValue.js.map +1 -0
  154. package/tools/ZodSchemaLike.d.ts +3 -0
  155. package/tools/ZodSchemaLike.js +3 -0
  156. package/tools/ZodSchemaLike.js.map +1 -0
  157. package/tools/getThisCodebaseRootDirPath_cjs.d.ts +2 -0
  158. package/tools/getThisCodebaseRootDirPath_cjs.js +53 -0
  159. package/tools/getThisCodebaseRootDirPath_cjs.js.map +1 -0
  160. package/tools/tsafe/uncapitalize.d.ts +2 -0
  161. package/tools/tsafe/uncapitalize.js +8 -0
  162. package/tools/tsafe/uncapitalize.js.map +1 -0
  163. package/vendor/backend/jose.d.ts +1 -0
  164. package/vendor/backend/jose.js +3 -0
  165. package/vendor/build-runtime/babel.d.ts +6 -0
  166. package/vendor/build-runtime/babel.js +3 -0
  167. package/vendor/build-runtime/magic-string.d.ts +2 -0
  168. package/vendor/build-runtime/magic-string.js +2 -0
  169. package/vendor/frontend/oidc-client-ts.js +0 -2
  170. package/vite-plugin/detectProjectType.d.ts +10 -0
  171. package/vite-plugin/detectProjectType.js +15 -0
  172. package/vite-plugin/detectProjectType.js.map +1 -0
  173. package/vite-plugin/excludeModuleExportFromOptimizedDeps.d.ts +4 -0
  174. package/vite-plugin/excludeModuleExportFromOptimizedDeps.js +50 -0
  175. package/vite-plugin/excludeModuleExportFromOptimizedDeps.js.map +1 -0
  176. package/vite-plugin/handleClientEntrypoint.d.ts +10 -0
  177. package/vite-plugin/handleClientEntrypoint.js +211 -0
  178. package/vite-plugin/handleClientEntrypoint.js.map +1 -0
  179. package/vite-plugin/index.d.ts +1 -0
  180. package/vite-plugin/index.js +6 -0
  181. package/vite-plugin/index.js.map +1 -0
  182. package/vite-plugin/transformCreateFileRoute.d.ts +10 -0
  183. package/vite-plugin/transformCreateFileRoute.js +173 -0
  184. package/vite-plugin/transformCreateFileRoute.js.map +1 -0
  185. package/vite-plugin/vite-plugin.d.ts +5 -0
  186. package/vite-plugin/vite-plugin.js +46 -0
  187. package/vite-plugin/vite-plugin.js.map +1 -0
  188. package/src/vendor/backend/jsonwebtoken.ts +0 -1
  189. package/src/vendor/backend/node-fetch.ts +0 -2
  190. package/src/vendor/backend/node-jose.ts +0 -1
  191. package/vendor/backend/jsonwebtoken.d.ts +0 -1
  192. package/vendor/backend/jsonwebtoken.js +0 -3
  193. package/vendor/backend/node-fetch.d.ts +0 -2
  194. package/vendor/backend/node-fetch.js +0 -2
  195. package/vendor/backend/node-jose.d.ts +0 -1
  196. package/vendor/backend/node-jose.js +0 -3
@@ -0,0 +1,678 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect, createContext, useContext } from "react";
3
+ import { OidcInitializationError } from "../../core/OidcInitializationError";
4
+ import { Deferred } from "../../tools/Deferred";
5
+ import { isBrowser } from "../../tools/isBrowser";
6
+ import { assert, is } from "../../tools/tsafe/assert";
7
+ import { infer_import_meta_env_BASE_URL } from "../../tools/infer_import_meta_env_BASE_URL";
8
+ import { createObjectThatThrowsIfAccessed } from "../../tools/createObjectThatThrowsIfAccessed";
9
+ import { createStatefulEvt } from "../../tools/StatefulEvt";
10
+ import { id } from "../../tools/tsafe/id";
11
+ import { typeGuard } from "../../tools/tsafe/typeGuard";
12
+ import { createServerFn, createMiddleware } from "@tanstack/react-start";
13
+ // @ts-expect-error: Since our module is not labeled as ESM we don't have the types here.
14
+ import { getRequest, setResponseHeader, setResponseStatus } from "@tanstack/react-start/server";
15
+ import { toFullyQualifiedUrl } from "../../tools/toFullyQualifiedUrl";
16
+ import { UnifiedClientRetryForSsrLoadersError } from "./rfcUnifiedClientRetryForSsrLoaders/UnifiedClientRetryForSsrLoadersError";
17
+ export function createOidcSpaApi(params) {
18
+ const { autoLogin, decodedIdTokenSchema, decodedIdToken_mock, createValidateAndGetAccessTokenClaims } = params;
19
+ const dParamsOfBootstrap = new Deferred();
20
+ const dOidcCoreOrInitializationError = new Deferred();
21
+ const evtAutoLogoutState = createStatefulEvt(() => ({
22
+ shouldDisplayWarning: false
23
+ }));
24
+ dOidcCoreOrInitializationError.pr.then(oidcCoreOrInitializationError => {
25
+ const { hasResolved, value: paramsOfBootstrap } = dParamsOfBootstrap.getState();
26
+ assert(hasResolved);
27
+ if (paramsOfBootstrap.implementation === "mock") {
28
+ return;
29
+ }
30
+ assert;
31
+ const { startCountdownSecondsBeforeAutoLogout = 45 } = paramsOfBootstrap;
32
+ if (oidcCoreOrInitializationError === undefined ||
33
+ oidcCoreOrInitializationError instanceof OidcInitializationError) {
34
+ return;
35
+ }
36
+ const oidcCore = oidcCoreOrInitializationError;
37
+ if (!oidcCore.isUserLoggedIn) {
38
+ return;
39
+ }
40
+ oidcCore.subscribeToAutoLogoutCountdown(({ secondsLeft }) => {
41
+ const newState = (() => {
42
+ if (secondsLeft === undefined) {
43
+ return {
44
+ shouldDisplayWarning: false
45
+ };
46
+ }
47
+ if (secondsLeft > startCountdownSecondsBeforeAutoLogout) {
48
+ return {
49
+ shouldDisplayWarning: false
50
+ };
51
+ }
52
+ return {
53
+ shouldDisplayWarning: true,
54
+ secondsLeftBeforeAutoLogout: secondsLeft
55
+ };
56
+ })();
57
+ if (!newState.shouldDisplayWarning && !evtAutoLogoutState.current.shouldDisplayWarning) {
58
+ return;
59
+ }
60
+ evtAutoLogoutState.current = newState;
61
+ });
62
+ });
63
+ function useOidc() {
64
+ const { hasResolved, value: oidcCore } = dOidcCoreOrInitializationError.getState();
65
+ assert(hasResolved);
66
+ assert(!(oidcCore instanceof OidcInitializationError));
67
+ const [, reRenderIfDecodedIdTokenChanged] = useState(() => {
68
+ if (!oidcCore.isUserLoggedIn) {
69
+ return undefined;
70
+ }
71
+ return oidcCore.getDecodedIdToken();
72
+ });
73
+ const [evtIsDecodedIdTokenUsed] = useState(() => createStatefulEvt(() => false));
74
+ useEffect(() => {
75
+ if (!oidcCore.isUserLoggedIn) {
76
+ return;
77
+ }
78
+ let isActive = true;
79
+ let unsubscribe = undefined;
80
+ (async () => {
81
+ if (!evtIsDecodedIdTokenUsed.current) {
82
+ const dDecodedIdTokenUsed = new Deferred();
83
+ const { unsubscribe: unsubscribe_scope } = evtIsDecodedIdTokenUsed.subscribe(() => {
84
+ unsubscribe_scope();
85
+ dDecodedIdTokenUsed.resolve();
86
+ });
87
+ unsubscribe = unsubscribe_scope;
88
+ await dDecodedIdTokenUsed.pr;
89
+ if (!isActive) {
90
+ return;
91
+ }
92
+ }
93
+ reRenderIfDecodedIdTokenChanged(oidcCore.getDecodedIdToken());
94
+ unsubscribe = oidcCore.subscribeToTokensChange(() => {
95
+ reRenderIfDecodedIdTokenChanged(oidcCore.getDecodedIdToken());
96
+ }).unsubscribe;
97
+ })();
98
+ return () => {
99
+ isActive = false;
100
+ unsubscribe?.();
101
+ };
102
+ }, []);
103
+ const [evtIsAutoLogoutStateUsed] = useState(() => createStatefulEvt(() => false));
104
+ const [, reRenderIfAutoLogoutStateChanged] = useState(() => evtAutoLogoutState.current);
105
+ useEffect(() => {
106
+ let isActive = true;
107
+ let unsubscribe = undefined;
108
+ (async () => {
109
+ if (!evtIsAutoLogoutStateUsed.current) {
110
+ const dAutoLogoutStateUsed = new Deferred();
111
+ const { unsubscribe: unsubscribe_scope } = evtIsAutoLogoutStateUsed.subscribe(() => {
112
+ unsubscribe_scope();
113
+ dAutoLogoutStateUsed.resolve();
114
+ });
115
+ unsubscribe = unsubscribe_scope;
116
+ await dAutoLogoutStateUsed.pr;
117
+ if (!isActive) {
118
+ return;
119
+ }
120
+ }
121
+ reRenderIfAutoLogoutStateChanged(evtAutoLogoutState.current);
122
+ unsubscribe = evtAutoLogoutState.subscribe(reRenderIfAutoLogoutStateChanged).unsubscribe;
123
+ })();
124
+ return () => {
125
+ isActive = false;
126
+ unsubscribe?.();
127
+ };
128
+ }, []);
129
+ if (!oidcCore.isUserLoggedIn) {
130
+ return id({
131
+ isUserLoggedIn: false,
132
+ initializationError: oidcCore.initializationError,
133
+ issuerUri: oidcCore.params.issuerUri,
134
+ clientId: oidcCore.params.clientId,
135
+ autoLogoutState: { shouldDisplayWarning: false },
136
+ login: params => oidcCore.login({
137
+ doesCurrentHrefRequiresAuth: false,
138
+ ...params
139
+ })
140
+ });
141
+ }
142
+ return id({
143
+ isUserLoggedIn: true,
144
+ get decodedIdToken() {
145
+ evtIsDecodedIdTokenUsed.current = true;
146
+ return oidcCore.getDecodedIdToken();
147
+ },
148
+ logout: oidcCore.logout,
149
+ renewTokens: oidcCore.renewTokens,
150
+ goToAuthServer: oidcCore.goToAuthServer,
151
+ backFromAuthServer: oidcCore.backFromAuthServer,
152
+ isNewBrowserSession: oidcCore.isNewBrowserSession,
153
+ get autoLogoutState() {
154
+ evtIsAutoLogoutStateUsed.current = true;
155
+ return evtAutoLogoutState.current;
156
+ },
157
+ issuerUri: oidcCore.params.issuerUri,
158
+ clientId: oidcCore.params.clientId
159
+ });
160
+ }
161
+ const context_isFreeOfSsrHydrationConcern = createContext(false);
162
+ function createOidcComponent(params) {
163
+ const { assert: assert_params, pendingComponent: PendingComponent, component: Component } = params;
164
+ const checkAssertion = assert_params === undefined
165
+ ? undefined
166
+ : (params) => {
167
+ const { isUserLoggedIn } = params;
168
+ switch (assert_params) {
169
+ case "user not logged in":
170
+ if (isUserLoggedIn) {
171
+ throw new Error([
172
+ "oidc-spa: Asserted the user should not be logged in",
173
+ "but they are. Check your control flow."
174
+ ].join(" "));
175
+ }
176
+ break;
177
+ case "user logged in":
178
+ if (!isUserLoggedIn) {
179
+ throw new Error([
180
+ "oidc-spa: Asserted the user should be logged in",
181
+ "but they arn't. Check your control flow."
182
+ ].join(" "));
183
+ }
184
+ break;
185
+ default:
186
+ assert;
187
+ }
188
+ };
189
+ function ComponentWithOidc(props) {
190
+ const renderFallback = () => PendingComponent === undefined ? null : _jsx(PendingComponent, { ...props });
191
+ if (!isBrowser) {
192
+ return renderFallback();
193
+ }
194
+ // NOTE: When the user assert that the user is logged in or not, they know.
195
+ // if they knows it means that they learned it somewhere so we are post SSR.
196
+ // Additionally, in autoLogin mode, the typedef don't allow this param to be provided.
197
+ const isFreeOfSsrHydrationConcern = useContext(context_isFreeOfSsrHydrationConcern) || assert_params !== undefined;
198
+ const [oidcCore, setOidcCore] = useState(() => {
199
+ if (!isFreeOfSsrHydrationConcern) {
200
+ return undefined;
201
+ }
202
+ const { hasResolved, value: oidcCore } = dOidcCoreOrInitializationError.getState();
203
+ if (!hasResolved) {
204
+ return undefined;
205
+ }
206
+ if (oidcCore instanceof OidcInitializationError) {
207
+ return undefined;
208
+ }
209
+ checkAssertion?.({
210
+ isUserLoggedIn: oidcCore.isUserLoggedIn
211
+ });
212
+ return oidcCore;
213
+ });
214
+ useEffect(() => {
215
+ if (oidcCore !== undefined) {
216
+ return;
217
+ }
218
+ let isActive = true;
219
+ dOidcCoreOrInitializationError.pr.then(oidcCore => {
220
+ if (!isActive) {
221
+ return;
222
+ }
223
+ if (oidcCore instanceof OidcInitializationError) {
224
+ return;
225
+ }
226
+ checkAssertion?.({
227
+ isUserLoggedIn: oidcCore.isUserLoggedIn
228
+ });
229
+ setOidcCore(oidcCore);
230
+ });
231
+ return () => {
232
+ isActive = false;
233
+ };
234
+ }, []);
235
+ if (oidcCore === undefined) {
236
+ return PendingComponent === undefined ? null : _jsx(PendingComponent, { ...props });
237
+ }
238
+ return (_jsx(context_isFreeOfSsrHydrationConcern.Provider, { value: true, children: _jsx(Component, { ...props }) }));
239
+ }
240
+ ComponentWithOidc.displayName = `${Component.displayName ?? Component.name ?? "Component"}WithOidc`;
241
+ ComponentWithOidc.useOidc = useOidc;
242
+ return ComponentWithOidc;
243
+ }
244
+ async function getOidc(params) {
245
+ if (!isBrowser) {
246
+ throw new UnifiedClientRetryForSsrLoadersError([
247
+ "oidc-spa: getOidc() can't be used on the server",
248
+ "if you use it in a loader, make sure to mark the route",
249
+ "as `ssr: false`."
250
+ ].join(" "));
251
+ }
252
+ const oidcCore = await dOidcCoreOrInitializationError.pr;
253
+ if (oidcCore instanceof OidcInitializationError) {
254
+ return new Promise(() => { });
255
+ }
256
+ if (params?.assert === "user logged in" && !oidcCore.isUserLoggedIn) {
257
+ throw new Error([
258
+ "oidc-spa: Called getOidc({ assert: 'user logged in' })",
259
+ "but the user is not currently logged in."
260
+ ].join(" "));
261
+ }
262
+ if (params?.assert === "user not logged in" && oidcCore.isUserLoggedIn) {
263
+ throw new Error([
264
+ "oidc-spa: Called getOidc({ assert: 'user not logged in' })",
265
+ "but the user is currently logged in."
266
+ ].join(" "));
267
+ }
268
+ return oidcCore.isUserLoggedIn
269
+ ? id({
270
+ issuerUri: oidcCore.params.issuerUri,
271
+ clientId: oidcCore.params.clientId,
272
+ isUserLoggedIn: true,
273
+ getAccessToken: async () => {
274
+ const { accessToken } = await oidcCore.getTokens();
275
+ return accessToken;
276
+ },
277
+ getDecodedIdToken: oidcCore.getDecodedIdToken,
278
+ logout: oidcCore.logout,
279
+ renewTokens: oidcCore.renewTokens,
280
+ goToAuthServer: oidcCore.goToAuthServer,
281
+ backFromAuthServer: oidcCore.backFromAuthServer,
282
+ isNewBrowserSession: oidcCore.isNewBrowserSession,
283
+ subscribeToAutoLogoutState: next => {
284
+ next(evtAutoLogoutState.current);
285
+ const { unsubscribe } = evtAutoLogoutState.subscribe(next);
286
+ return { unsubscribeFromAutoLogoutState: unsubscribe };
287
+ }
288
+ })
289
+ : id({
290
+ issuerUri: oidcCore.params.issuerUri,
291
+ clientId: oidcCore.params.clientId,
292
+ isUserLoggedIn: false,
293
+ initializationError: oidcCore.initializationError,
294
+ login: oidcCore.login
295
+ });
296
+ }
297
+ let hasBootstrapBeenCalled = false;
298
+ const prModuleCore = !isBrowser ? undefined : import("../../core");
299
+ const bootstrapOidc = (getParamsOfBootstrapOrDirectValue) => {
300
+ if (hasBootstrapBeenCalled) {
301
+ return;
302
+ }
303
+ hasBootstrapBeenCalled = true;
304
+ (async () => {
305
+ const getParamsOfBootstrap = typeof getParamsOfBootstrapOrDirectValue === "function"
306
+ ? getParamsOfBootstrapOrDirectValue
307
+ : () => getParamsOfBootstrapOrDirectValue;
308
+ if (!isBrowser) {
309
+ const missingEnvNames = new Set();
310
+ const env_proxy = new Proxy({}, {
311
+ get: (...[, envName]) => {
312
+ assert(typeof envName === "string");
313
+ const value = process.env[envName];
314
+ if (value === undefined) {
315
+ missingEnvNames.add(envName);
316
+ return "";
317
+ }
318
+ return value;
319
+ },
320
+ has: (...[, envName]) => {
321
+ assert(typeof envName === "string");
322
+ return true;
323
+ }
324
+ });
325
+ const paramsOfBootstrap = getParamsOfBootstrap({ process: { env: env_proxy } });
326
+ if (paramsOfBootstrap.implementation === "real" &&
327
+ (!paramsOfBootstrap.issuerUri || !paramsOfBootstrap.clientId)) {
328
+ throw new Error([
329
+ "oidc-spa: Incorrect configuration provided:\n",
330
+ JSON.stringify(paramsOfBootstrap, null, 2),
331
+ ...(missingEnvNames.size === 0
332
+ ? []
333
+ : [
334
+ "\nYou probably forgot to define the environnement variables:",
335
+ Array.from(missingEnvNames).join(", ")
336
+ ])
337
+ ].join(" "));
338
+ }
339
+ dParamsOfBootstrap.resolve(paramsOfBootstrap);
340
+ return;
341
+ }
342
+ assert(prModuleCore !== undefined);
343
+ const paramsOfBootstrap = await (async () => {
344
+ let envNamesToPullFromServer = new Set();
345
+ const env = {};
346
+ const env_proxy = new Proxy(env, {
347
+ get: (...[, envName]) => {
348
+ assert(typeof envName === "string");
349
+ if (envName in env) {
350
+ return env[envName];
351
+ }
352
+ envNamesToPullFromServer.add(envName);
353
+ return "oidc_spa_probe";
354
+ },
355
+ has: (...[, envName]) => {
356
+ assert(typeof envName === "string");
357
+ if (envName in env) {
358
+ return true;
359
+ }
360
+ envNamesToPullFromServer.add(envName);
361
+ return true;
362
+ }
363
+ });
364
+ let result = undefined;
365
+ while (true) {
366
+ envNamesToPullFromServer = new Set();
367
+ result = undefined;
368
+ try {
369
+ const paramsOfBootstrap = getParamsOfBootstrap({ process: { env: env_proxy } });
370
+ result = {
371
+ hasThrown: false,
372
+ paramsOfBootstrap
373
+ };
374
+ }
375
+ catch (error) {
376
+ result = {
377
+ hasThrown: true,
378
+ error
379
+ };
380
+ }
381
+ if (envNamesToPullFromServer.size === 0) {
382
+ break;
383
+ }
384
+ Object.entries(await fetchServerEnvVariableValues({
385
+ data: {
386
+ envVarNames: Array.from(envNamesToPullFromServer)
387
+ }
388
+ })).forEach(([envName, value]) => {
389
+ env[envName] = value;
390
+ });
391
+ }
392
+ if (result.hasThrown) {
393
+ throw new Error([
394
+ "oidc-spa: The function argument passed to bootstrapOidc",
395
+ "has thrown when invoked."
396
+ ].join(" "),
397
+ //@ts-expect-error
398
+ { cause: result.error });
399
+ }
400
+ return result.paramsOfBootstrap;
401
+ })();
402
+ dParamsOfBootstrap.resolve(paramsOfBootstrap);
403
+ switch (paramsOfBootstrap.implementation) {
404
+ case "mock":
405
+ {
406
+ const { createMockOidc } = await import("../../mock/oidc");
407
+ const oidcCore = await createMockOidc({
408
+ homeUrl: infer_import_meta_env_BASE_URL(),
409
+ // NOTE: The `as false` is lying here, it's just to preserve some level of type-safety.
410
+ autoLogin: autoLogin,
411
+ // NOTE: Same here, the nullish coalescing is lying.
412
+ isUserInitiallyLoggedIn: paramsOfBootstrap.isUserInitiallyLoggedIn,
413
+ mockedParams: {
414
+ clientId: paramsOfBootstrap.clientId_mock,
415
+ issuerUri: paramsOfBootstrap.issuerUri_mock
416
+ },
417
+ mockedTokens: {
418
+ decodedIdToken: paramsOfBootstrap.decodedIdToken_mock ??
419
+ decodedIdToken_mock ??
420
+ createObjectThatThrowsIfAccessed({
421
+ debugMessage: [
422
+ "oidc-spa: You didn't provide any mock for the decodedIdToken",
423
+ "Either provide a default one by specifying decodedIdToken_mock",
424
+ "as parameter of .withExpectedDecodedIdTokenShape() or",
425
+ "specify decodedIdToken_mock when calling bootstrapOidc()"
426
+ ].join(" ")
427
+ })
428
+ }
429
+ });
430
+ dOidcCoreOrInitializationError.resolve(oidcCore);
431
+ }
432
+ break;
433
+ case "real":
434
+ {
435
+ const { createOidc } = await prModuleCore;
436
+ const homeUrl = infer_import_meta_env_BASE_URL();
437
+ let oidcCoreOrInitializationError;
438
+ try {
439
+ oidcCoreOrInitializationError = await createOidc({
440
+ homeUrl,
441
+ autoLogin,
442
+ decodedIdTokenSchema,
443
+ issuerUri: paramsOfBootstrap.issuerUri,
444
+ clientId: paramsOfBootstrap.clientId,
445
+ idleSessionLifetimeInSeconds: paramsOfBootstrap.idleSessionLifetimeInSeconds,
446
+ scopes: paramsOfBootstrap.scopes,
447
+ transformUrlBeforeRedirect: paramsOfBootstrap.transformUrlBeforeRedirect,
448
+ extraQueryParams: paramsOfBootstrap.extraQueryParams,
449
+ extraTokenParams: paramsOfBootstrap.extraTokenParams,
450
+ noIframe: paramsOfBootstrap.noIframe,
451
+ debugLogs: paramsOfBootstrap.debugLogs,
452
+ __unsafe_clientSecret: paramsOfBootstrap.__unsafe_clientSecret,
453
+ __metadata: paramsOfBootstrap.__metadata
454
+ });
455
+ }
456
+ catch (error) {
457
+ if (!(error instanceof OidcInitializationError)) {
458
+ throw error;
459
+ }
460
+ dOidcCoreOrInitializationError.resolve(error);
461
+ return;
462
+ }
463
+ dOidcCoreOrInitializationError.resolve(oidcCoreOrInitializationError);
464
+ }
465
+ break;
466
+ }
467
+ })();
468
+ };
469
+ async function enforceLogin(loaderContext) {
470
+ if (!isBrowser) {
471
+ throw new UnifiedClientRetryForSsrLoadersError([
472
+ "oidc-spa: enforceLogin cannot be used on the server",
473
+ "make sure to mark any route that uses it as ssr: false"
474
+ ].join(" "));
475
+ }
476
+ const { cause } = loaderContext;
477
+ const redirectUrl = (() => {
478
+ if (loaderContext.location?.href !== undefined) {
479
+ return toFullyQualifiedUrl({
480
+ urlish: loaderContext.location.href,
481
+ doAssertNoQueryParams: false
482
+ });
483
+ }
484
+ return location.href;
485
+ })();
486
+ const oidc = await getOidc();
487
+ if (!oidc.isUserLoggedIn) {
488
+ if (cause === "preload") {
489
+ throw new Error([
490
+ "oidc-spa: User is not yet logged in.",
491
+ "This is not an error, this is an expected case.",
492
+ "It's only TanStack Router using exception as control flow."
493
+ ].join(" "));
494
+ }
495
+ const doesCurrentHrefRequiresAuth = location.href.replace(/\/$/, "") === redirectUrl.replace(/\/$/, "");
496
+ await oidc.login({
497
+ redirectUrl,
498
+ doesCurrentHrefRequiresAuth
499
+ });
500
+ }
501
+ }
502
+ function OidcInitializationGate(props) {
503
+ const { renderFallback, children } = props;
504
+ const [oidcCoreOrInitializationError, setOidcCoreOrInitializationError] = useState(undefined);
505
+ useEffect(() => {
506
+ let isActive = true;
507
+ dOidcCoreOrInitializationError.pr.then(oidcCoreOrInitializationError => {
508
+ if (!isActive) {
509
+ return;
510
+ }
511
+ setOidcCoreOrInitializationError(oidcCoreOrInitializationError);
512
+ });
513
+ return () => {
514
+ isActive = false;
515
+ };
516
+ }, []);
517
+ if (oidcCoreOrInitializationError === undefined ||
518
+ oidcCoreOrInitializationError instanceof OidcInitializationError) {
519
+ return renderFallback({ initializationError: oidcCoreOrInitializationError });
520
+ }
521
+ return (_jsx(context_isFreeOfSsrHydrationConcern.Provider, { value: true, children: children }));
522
+ }
523
+ const prValidateAndGetAccessTokenClaims = createValidateAndGetAccessTokenClaims === undefined
524
+ ? undefined
525
+ : dParamsOfBootstrap.pr.then(paramsOfBootstrap => createValidateAndGetAccessTokenClaims({
526
+ // @ts-expect-error
527
+ paramsOfBootstrap
528
+ }));
529
+ function createFunctionMiddlewareServerFn(params) {
530
+ return async (options) => {
531
+ const { next } = options;
532
+ const unauthorized = (params) => {
533
+ const { errorMessage, wwwAuthenticateHeaderErrorDescription } = params;
534
+ setResponseHeader("WWW-Authenticate", `Bearer error="invalid_token", error_description="${wwwAuthenticateHeaderErrorDescription}"`);
535
+ setResponseStatus(401, "Unauthorized");
536
+ return new Error(`oidc-spa: ${errorMessage}`);
537
+ };
538
+ const { headers } = getRequest();
539
+ const authorizationHeaderValue = headers.get("Authorization");
540
+ if (authorizationHeaderValue === null) {
541
+ if (params?.assert === "user logged in") {
542
+ const errorMessage = [
543
+ "Asserted user logged in for that serverFn request",
544
+ "but no access token was attached to the request"
545
+ ].join(" ");
546
+ throw unauthorized({
547
+ errorMessage,
548
+ wwwAuthenticateHeaderErrorDescription: errorMessage
549
+ });
550
+ }
551
+ return next({
552
+ context: {
553
+ oidc: id(id({
554
+ isUserLoggedIn: false
555
+ }))
556
+ }
557
+ });
558
+ }
559
+ const accessToken = (() => {
560
+ const prefix = "Bearer ";
561
+ if (!authorizationHeaderValue.startsWith(prefix)) {
562
+ return undefined;
563
+ }
564
+ return authorizationHeaderValue.slice(prefix.length);
565
+ })();
566
+ if (accessToken === undefined) {
567
+ const errorMessage = "Missing well formed Authorization header with Bearer <access_token>";
568
+ throw unauthorized({
569
+ errorMessage,
570
+ wwwAuthenticateHeaderErrorDescription: errorMessage
571
+ });
572
+ }
573
+ assert(prValidateAndGetAccessTokenClaims !== undefined);
574
+ const { validateAndGetAccessTokenClaims } = await prValidateAndGetAccessTokenClaims;
575
+ const resultOfValidate = await validateAndGetAccessTokenClaims({ accessToken });
576
+ if (!resultOfValidate.isValid) {
577
+ const { errorMessage, wwwAuthenticateHeaderErrorDescription } = resultOfValidate;
578
+ throw unauthorized({
579
+ errorMessage,
580
+ wwwAuthenticateHeaderErrorDescription
581
+ });
582
+ }
583
+ const { accessTokenClaims } = resultOfValidate;
584
+ assert(is(accessTokenClaims));
585
+ check_required_claims: {
586
+ const getHasRequiredClaims = params?.hasRequiredClaims;
587
+ if (getHasRequiredClaims === undefined) {
588
+ break check_required_claims;
589
+ }
590
+ const accessedClaimNames = new Set();
591
+ const accessTokenClaims_proxy = new Proxy(accessTokenClaims, {
592
+ get(...args) {
593
+ const [, claimName] = args;
594
+ record_claim_access: {
595
+ if (typeof claimName !== "string") {
596
+ break record_claim_access;
597
+ }
598
+ accessedClaimNames.add(claimName);
599
+ }
600
+ return Reflect.get(...args);
601
+ }
602
+ });
603
+ const hasRequiredClaims = await getHasRequiredClaims({
604
+ accessTokenClaims: accessTokenClaims_proxy
605
+ });
606
+ if (hasRequiredClaims) {
607
+ break check_required_claims;
608
+ }
609
+ const errorMessage = [
610
+ "Missing or invalid required access token claim.",
611
+ `Related to claims: ${Array.from(accessedClaimNames).join(" and/or ")}`
612
+ ].join(" ");
613
+ throw unauthorized({
614
+ errorMessage,
615
+ wwwAuthenticateHeaderErrorDescription: errorMessage
616
+ });
617
+ }
618
+ return next({
619
+ context: {
620
+ oidc: id(id({
621
+ isUserLoggedIn: true,
622
+ accessToken,
623
+ accessTokenClaims
624
+ }))
625
+ }
626
+ });
627
+ };
628
+ }
629
+ function oidcRequestMiddleware(params) {
630
+ return createMiddleware({ type: "request" }).server(createFunctionMiddlewareServerFn(params));
631
+ }
632
+ function oidcFnMiddleware(params) {
633
+ return createMiddleware({ type: "function" })
634
+ .client(async ({ next }) => {
635
+ const oidc = await getOidc();
636
+ if (params?.assert === "user logged in" && !oidc.isUserLoggedIn) {
637
+ throw new Error([
638
+ "oidc-spa: You used oidcFnMiddleware({ assert: 'user logged in' })",
639
+ "but the server function the middleware was attached to was called",
640
+ "while the user is not logged in."
641
+ ].join(" "));
642
+ }
643
+ if (!oidc.isUserLoggedIn) {
644
+ return next();
645
+ }
646
+ return next({
647
+ headers: {
648
+ Authorization: `Bearer ${await oidc.getAccessToken()}`
649
+ }
650
+ });
651
+ })
652
+ .server(createFunctionMiddlewareServerFn(params));
653
+ }
654
+ // @ts-expect-error
655
+ return {
656
+ createOidcComponent,
657
+ getOidc,
658
+ bootstrapOidc,
659
+ enforceLogin,
660
+ OidcInitializationGate,
661
+ oidcFnMiddleware,
662
+ oidcRequestMiddleware
663
+ };
664
+ }
665
+ const fetchServerEnvVariableValues = createServerFn({ method: "GET" })
666
+ .inputValidator((data) => {
667
+ if (typeof data !== "object" || data === null) {
668
+ throw new Error("Expected an object");
669
+ }
670
+ const { envVarNames } = data;
671
+ assert(typeGuard(envVarNames, Array.isArray(envVarNames) && envVarNames.every(name => typeof name === "string")));
672
+ return { envVarNames };
673
+ })
674
+ .handler(async ({ data }) => {
675
+ const { envVarNames } = data;
676
+ return Object.fromEntries(envVarNames.map(envVarName => [envVarName, process.env[envVarName] ?? ""]));
677
+ });
678
+ //# sourceMappingURL=createOidcSpaApi.js.map