oidc-spa 8.1.14 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/BASE_URL.d.ts +4 -0
- package/core/BASE_URL.js +12 -0
- package/core/BASE_URL.js.map +1 -0
- package/core/createOidc.d.ts +14 -7
- package/core/createOidc.js +38 -3
- package/core/createOidc.js.map +1 -1
- package/core/earlyInit.d.ts +1 -0
- package/core/earlyInit.js +8 -8
- package/core/earlyInit.js.map +1 -1
- package/core/prShouldLoadApp.d.ts +4 -0
- package/core/prShouldLoadApp.js +13 -0
- package/core/prShouldLoadApp.js.map +1 -0
- package/esm/core/BASE_URL.d.ts +4 -0
- package/esm/core/BASE_URL.js +8 -0
- package/esm/core/BASE_URL.js.map +1 -0
- package/esm/core/createOidc.d.ts +14 -7
- package/esm/core/createOidc.js +38 -3
- package/esm/core/createOidc.js.map +1 -1
- package/esm/core/earlyInit.d.ts +1 -0
- package/esm/core/earlyInit.js +8 -8
- package/esm/core/earlyInit.js.map +1 -1
- package/esm/core/prShouldLoadApp.d.ts +4 -0
- package/esm/core/prShouldLoadApp.js +9 -0
- package/esm/core/prShouldLoadApp.js.map +1 -0
- package/esm/keycloak/keycloak-js/Keycloak.d.ts +1 -1
- package/esm/keycloak/keycloak-js/Keycloak.js +1 -1
- package/esm/keycloak/keycloak-js/Keycloak.js.map +1 -1
- package/esm/mock/oidc.d.ts +3 -1
- package/esm/mock/oidc.js +4 -2
- package/esm/mock/oidc.js.map +1 -1
- package/esm/react-spa/apiBuilder.d.ts +12 -0
- package/esm/react-spa/apiBuilder.js +26 -0
- package/esm/react-spa/apiBuilder.js.map +1 -0
- package/esm/react-spa/createOidcSpaApi.d.ts +8 -0
- package/esm/react-spa/createOidcSpaApi.js +387 -0
- package/esm/react-spa/createOidcSpaApi.js.map +1 -0
- package/esm/react-spa/index.d.ts +2 -0
- package/esm/react-spa/index.js +3 -0
- package/esm/react-spa/index.js.map +1 -0
- package/esm/react-spa/types.d.ts +279 -0
- package/esm/react-spa/types.js +2 -0
- package/esm/react-spa/types.js.map +1 -0
- package/esm/tanstack-start/react/apiBuilder.js.map +1 -1
- package/esm/tanstack-start/react/createOidcSpaApi.js +13 -9
- package/esm/tanstack-start/react/createOidcSpaApi.js.map +1 -1
- package/esm/tanstack-start/react/types.d.ts +5 -4
- package/keycloak/keycloak-js/Keycloak.d.ts +1 -1
- package/keycloak/keycloak-js/Keycloak.js +1 -1
- package/keycloak/keycloak-js/Keycloak.js.map +1 -1
- package/mock/oidc.d.ts +3 -1
- package/mock/oidc.js +4 -2
- package/mock/oidc.js.map +1 -1
- package/package.json +5 -1
- package/react-spa/apiBuilder.d.ts +12 -0
- package/react-spa/apiBuilder.js +29 -0
- package/react-spa/apiBuilder.js.map +1 -0
- package/react-spa/createOidcSpaApi.d.ts +8 -0
- package/react-spa/createOidcSpaApi.js +423 -0
- package/react-spa/createOidcSpaApi.js.map +1 -0
- package/react-spa/index.d.ts +2 -0
- package/react-spa/index.js +6 -0
- package/react-spa/index.js.map +1 -0
- package/react-spa/types.d.ts +279 -0
- package/react-spa/types.js +3 -0
- package/react-spa/types.js.map +1 -0
- package/src/angular.ts +1 -1
- package/src/core/BASE_URL.ts +9 -0
- package/src/core/createOidc.ts +64 -10
- package/src/core/earlyInit.ts +14 -11
- package/src/core/prShouldLoadApp.ts +11 -0
- package/src/keycloak/keycloak-js/Keycloak.ts +2 -2
- package/src/mock/oidc.ts +9 -3
- package/src/react-spa/apiBuilder.ts +70 -0
- package/src/react-spa/createOidcSpaApi.tsx +527 -0
- package/src/react-spa/index.ts +4 -0
- package/src/react-spa/types.tsx +308 -0
- package/src/tanstack-start/react/apiBuilder.ts +0 -1
- package/src/tanstack-start/react/createOidcSpaApi.tsx +24 -20
- package/src/tanstack-start/react/types.tsx +3 -4
- package/src/vite-plugin/handleClientEntrypoint.ts +5 -5
- package/src/vite-plugin/manageOptimizedDeps.ts +64 -0
- package/src/vite-plugin/projectType.ts +18 -0
- package/src/vite-plugin/vite-plugin.ts +47 -11
- package/vite-plugin/handleClientEntrypoint.d.ts +2 -0
- package/vite-plugin/handleClientEntrypoint.js +3 -4
- package/vite-plugin/handleClientEntrypoint.js.map +1 -1
- package/vite-plugin/manageOptimizedDeps.d.ts +6 -0
- package/vite-plugin/{excludeModuleExportFromOptimizedDeps.js → manageOptimizedDeps.js} +42 -7
- package/vite-plugin/manageOptimizedDeps.js.map +1 -0
- package/vite-plugin/projectType.d.ts +4 -0
- package/vite-plugin/projectType.js +15 -0
- package/vite-plugin/projectType.js.map +1 -0
- package/vite-plugin/{transformCreateFileRoute.js → transformTanstackRouterCreateFileRoute.js} +1 -1
- package/vite-plugin/transformTanstackRouterCreateFileRoute.js.map +1 -0
- package/vite-plugin/vite-plugin.d.ts +2 -2
- package/vite-plugin/vite-plugin.js +33 -9
- package/vite-plugin/vite-plugin.js.map +1 -1
- package/esm/tools/infer_import_meta_env_BASE_URL.d.ts +0 -1
- package/esm/tools/infer_import_meta_env_BASE_URL.js +0 -15
- package/esm/tools/infer_import_meta_env_BASE_URL.js.map +0 -1
- package/src/tools/infer_import_meta_env_BASE_URL.ts +0 -19
- package/src/vite-plugin/detectProjectType.ts +0 -20
- package/src/vite-plugin/excludeModuleExportFromOptimizedDeps.ts +0 -20
- package/vite-plugin/detectProjectType.d.ts +0 -10
- package/vite-plugin/detectProjectType.js +0 -15
- package/vite-plugin/detectProjectType.js.map +0 -1
- package/vite-plugin/excludeModuleExportFromOptimizedDeps.d.ts +0 -4
- package/vite-plugin/excludeModuleExportFromOptimizedDeps.js.map +0 -1
- package/vite-plugin/transformCreateFileRoute.js.map +0 -1
- /package/src/vite-plugin/{transformCreateFileRoute.ts → transformTanstackRouterCreateFileRoute.ts} +0 -0
- /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 @@
|
|
|
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
|
|
package/src/core/createOidc.ts
CHANGED
|
@@ -51,6 +51,8 @@ import { isKeycloak } from "../keycloak/isKeycloak";
|
|
|
51
51
|
import { INFINITY_TIME } from "../tools/INFINITY_TIME";
|
|
52
52
|
import type { WELL_KNOWN_PATH } from "./diagnostic";
|
|
53
53
|
import { getIsValidRemoteJson } from "../tools/getIsValidRemoteJson";
|
|
54
|
+
import { prShouldLoadApp } from "./prShouldLoadApp";
|
|
55
|
+
import { getBASE_URL } from "./BASE_URL";
|
|
54
56
|
|
|
55
57
|
// NOTE: Replaced at build time
|
|
56
58
|
const VERSION = "{{OIDC_SPA_VERSION}}";
|
|
@@ -59,14 +61,6 @@ export type ParamsOfCreateOidc<
|
|
|
59
61
|
DecodedIdToken extends Record<string, unknown> = Oidc.Tokens.DecodedIdToken_OidcCoreSpec,
|
|
60
62
|
AutoLogin extends boolean = false
|
|
61
63
|
> = {
|
|
62
|
-
/**
|
|
63
|
-
* What should you put in this parameter?
|
|
64
|
-
* - Vite project: `BASE_URL: import.meta.env.BASE_URL`
|
|
65
|
-
* - Create React App project: `BASE_URL: process.env.PUBLIC_URL`
|
|
66
|
-
* - Other: `BASE_URL: "/"` (Usually, or `/dashboard` if your app is not at the root of the domain)
|
|
67
|
-
*/
|
|
68
|
-
homeUrl: string;
|
|
69
|
-
|
|
70
64
|
/**
|
|
71
65
|
* See: https://docs.oidc-spa.dev/v/v8/providers-configuration/provider-configuration
|
|
72
66
|
*/
|
|
@@ -194,6 +188,22 @@ export type ParamsOfCreateOidc<
|
|
|
194
188
|
* or non-standard deployments), and you cannot fix the server-side configuration.
|
|
195
189
|
*/
|
|
196
190
|
__metadata?: Partial<OidcMetadata>;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* NOTE: This parameter is optional if you use the Vite plugin.
|
|
194
|
+
*
|
|
195
|
+
* This parameter let's you overwrite the value provided in
|
|
196
|
+
* oidcEarlyInit({ BASE_URL: xxx });
|
|
197
|
+
*
|
|
198
|
+
* What should you put in this parameter?
|
|
199
|
+
* - Vite project: `BASE_URL: import.meta.env.BASE_URL`
|
|
200
|
+
* - Create React App project: `BASE_URL: process.env.PUBLIC_URL`
|
|
201
|
+
* - Other: `BASE_URL: "/"` (Usually, or `/dashboard` if your app is not at the root of the domain)
|
|
202
|
+
*/
|
|
203
|
+
BASE_URL?: string;
|
|
204
|
+
|
|
205
|
+
/** @deprecated: Use BASE_URL (same thing, just renamed). */
|
|
206
|
+
homeUrl?: string;
|
|
197
207
|
};
|
|
198
208
|
|
|
199
209
|
const globalContext = {
|
|
@@ -314,11 +324,31 @@ export async function createOidc_nonMemoized<
|
|
|
314
324
|
log: typeof console.log | undefined;
|
|
315
325
|
}
|
|
316
326
|
): Promise<AutoLogin extends true ? Oidc.LoggedIn<DecodedIdToken> : Oidc<DecodedIdToken>> {
|
|
327
|
+
{
|
|
328
|
+
const timer = window.setTimeout(() => {
|
|
329
|
+
console.warn(
|
|
330
|
+
[
|
|
331
|
+
"oidc-spa: Setup error.",
|
|
332
|
+
"oidcEarlyInit() wasn't called.",
|
|
333
|
+
"This is supposed to be handled by the oidc-spa Vite plugin",
|
|
334
|
+
"or manually in other environments."
|
|
335
|
+
].join(" ")
|
|
336
|
+
);
|
|
337
|
+
}, 3_000);
|
|
338
|
+
|
|
339
|
+
const shouldLoadApp = await prShouldLoadApp;
|
|
340
|
+
|
|
341
|
+
window.clearTimeout(timer);
|
|
342
|
+
|
|
343
|
+
if (!shouldLoadApp) {
|
|
344
|
+
return new Promise<never>(() => {});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
317
348
|
const {
|
|
318
349
|
transformUrlBeforeRedirect,
|
|
319
350
|
extraQueryParams: extraQueryParamsOrGetter,
|
|
320
351
|
extraTokenParams: extraTokenParamsOrGetter,
|
|
321
|
-
homeUrl: homeUrl_params,
|
|
322
352
|
decodedIdTokenSchema,
|
|
323
353
|
idleSessionLifetimeInSeconds,
|
|
324
354
|
autoLogoutParams = { redirectTo: "current page" },
|
|
@@ -330,6 +360,8 @@ export async function createOidc_nonMemoized<
|
|
|
330
360
|
noIframe = false
|
|
331
361
|
} = params;
|
|
332
362
|
|
|
363
|
+
const BASE_URL_params = params.BASE_URL ?? params.homeUrl;
|
|
364
|
+
|
|
333
365
|
const { issuerUri, clientId, scopes, configId, log } = preProcessedParams;
|
|
334
366
|
|
|
335
367
|
const getExtraQueryParams = (() => {
|
|
@@ -357,7 +389,29 @@ export async function createOidc_nonMemoized<
|
|
|
357
389
|
})();
|
|
358
390
|
|
|
359
391
|
const homeUrlAndRedirectUri = toFullyQualifiedUrl({
|
|
360
|
-
urlish:
|
|
392
|
+
urlish: (() => {
|
|
393
|
+
if (BASE_URL_params !== undefined) {
|
|
394
|
+
return BASE_URL_params;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
const BASE_URL = getBASE_URL();
|
|
398
|
+
|
|
399
|
+
if (BASE_URL === undefined) {
|
|
400
|
+
throw new Error(
|
|
401
|
+
[
|
|
402
|
+
"oidc-spa: If you do not use the oidc-spa Vite plugin",
|
|
403
|
+
"you must provide the BASE_URL to the earlyInit() examples:",
|
|
404
|
+
"oidcSpaEarlyInit({ BASE_URL: import.meta.env.BASE_URL })",
|
|
405
|
+
"oidcSpaEarlyInit({ BASE_URL: '/' })",
|
|
406
|
+
"",
|
|
407
|
+
"You can also pass this parameter to createOidc({ BASE_URL: '...' })",
|
|
408
|
+
"or bootstrapOidc({ BASE_URL: '...' })"
|
|
409
|
+
].join("\n")
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
return BASE_URL;
|
|
414
|
+
})(),
|
|
361
415
|
doAssertNoQueryParams: true,
|
|
362
416
|
doOutputWithTrailingSlash: true
|
|
363
417
|
});
|
package/src/core/earlyInit.ts
CHANGED
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
preventSessionStorageSetItemOfPublicKeyByThirdParty
|
|
8
8
|
} from "./iframeMessageProtection";
|
|
9
9
|
import { setOidcRequiredPostHydrationReplaceNavigationUrl } from "./requiredPostHydrationReplaceNavigationUrl";
|
|
10
|
+
import { setBASE_URL } from "./BASE_URL";
|
|
11
|
+
import { resolvePrShouldLoadApp } from "./prShouldLoadApp";
|
|
10
12
|
import { isBrowser } from "../tools/isBrowser";
|
|
11
13
|
|
|
12
14
|
let hasEarlyInitBeenCalled = false;
|
|
@@ -18,6 +20,7 @@ export function oidcEarlyInit(params: {
|
|
|
18
20
|
// Will be made mandatory next major.
|
|
19
21
|
freezeWebSocket?: boolean;
|
|
20
22
|
isPostLoginRedirectManual?: boolean;
|
|
23
|
+
BASE_URL?: string;
|
|
21
24
|
}) {
|
|
22
25
|
if (hasEarlyInitBeenCalled) {
|
|
23
26
|
throw new Error("oidc-spa: oidcEarlyInit() Should be called only once");
|
|
@@ -35,8 +38,9 @@ export function oidcEarlyInit(params: {
|
|
|
35
38
|
freezeFetch,
|
|
36
39
|
freezeXMLHttpRequest,
|
|
37
40
|
freezeWebSocket = false,
|
|
38
|
-
isPostLoginRedirectManual = false
|
|
39
|
-
|
|
41
|
+
isPostLoginRedirectManual = false,
|
|
42
|
+
BASE_URL
|
|
43
|
+
} = params;
|
|
40
44
|
|
|
41
45
|
const { shouldLoadApp } = handleOidcCallback({ isPostLoginRedirectManual });
|
|
42
46
|
|
|
@@ -83,8 +87,14 @@ export function oidcEarlyInit(params: {
|
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
preventSessionStorageSetItemOfPublicKeyByThirdParty();
|
|
90
|
+
|
|
91
|
+
if (BASE_URL !== undefined) {
|
|
92
|
+
setBASE_URL({ BASE_URL });
|
|
93
|
+
}
|
|
86
94
|
}
|
|
87
95
|
|
|
96
|
+
resolvePrShouldLoadApp({ shouldLoadApp });
|
|
97
|
+
|
|
88
98
|
return { shouldLoadApp };
|
|
89
99
|
}
|
|
90
100
|
|
|
@@ -93,15 +103,8 @@ let redirectAuthResponse: AuthResponse | undefined = undefined;
|
|
|
93
103
|
export function getRedirectAuthResponse():
|
|
94
104
|
| { authResponse: AuthResponse; clearAuthResponse: () => void }
|
|
95
105
|
| { authResponse: undefined; clearAuthResponse?: never } {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
[
|
|
99
|
-
"oidc-spa setup error.",
|
|
100
|
-
"oidcEarlyInit() wasn't called.",
|
|
101
|
-
"In newer version, using oidc-spa/entrypoint is no longer optional."
|
|
102
|
-
].join(" ")
|
|
103
|
-
);
|
|
104
|
-
}
|
|
106
|
+
assert(hasEarlyInitBeenCalled, "34933395");
|
|
107
|
+
|
|
105
108
|
return redirectAuthResponse === undefined
|
|
106
109
|
? { authResponse: undefined }
|
|
107
110
|
: {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { assert } from "../tools/tsafe/assert";
|
|
2
|
+
|
|
3
|
+
let prShouldLoadApp_resolve: (shouldLoadApp: boolean) => void | undefined;
|
|
4
|
+
|
|
5
|
+
export const prShouldLoadApp = new Promise<boolean>(resolve => (prShouldLoadApp_resolve = resolve));
|
|
6
|
+
|
|
7
|
+
export function resolvePrShouldLoadApp(params: { shouldLoadApp: boolean }) {
|
|
8
|
+
const { shouldLoadApp } = params;
|
|
9
|
+
assert(prShouldLoadApp_resolve !== undefined);
|
|
10
|
+
prShouldLoadApp_resolve(shouldLoadApp);
|
|
11
|
+
}
|
|
@@ -23,7 +23,7 @@ import { type StatefulEvt, createStatefulEvt } from "../../tools/StatefulEvt";
|
|
|
23
23
|
import { readExpirationTimeInJwt } from "../../tools/readExpirationTimeInJwt";
|
|
24
24
|
|
|
25
25
|
type ConstructorParams = KeycloakServerConfig & {
|
|
26
|
-
|
|
26
|
+
BASE_URL?: string;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -99,7 +99,7 @@ export class Keycloak {
|
|
|
99
99
|
let hasCreateResolved = false;
|
|
100
100
|
|
|
101
101
|
const oidcOrError = await createOidc({
|
|
102
|
-
homeUrl: constructorParams.
|
|
102
|
+
homeUrl: constructorParams.BASE_URL,
|
|
103
103
|
issuerUri,
|
|
104
104
|
clientId: this.#state.constructorParams.clientId,
|
|
105
105
|
autoLogin,
|
package/src/mock/oidc.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { toFullyQualifiedUrl } from "../tools/toFullyQualifiedUrl";
|
|
|
5
5
|
import { getSearchParam, addOrUpdateSearchParam } from "../tools/urlSearchParams";
|
|
6
6
|
import { getRootRelativeOriginalLocationHref } from "../core/earlyInit";
|
|
7
7
|
import { INFINITY_TIME } from "../tools/INFINITY_TIME";
|
|
8
|
+
import { getBASE_URL } from "../core/BASE_URL";
|
|
8
9
|
|
|
9
10
|
export type ParamsOfCreateMockOidc<
|
|
10
11
|
DecodedIdToken extends Record<string, unknown> = Record<string, unknown>,
|
|
@@ -18,7 +19,11 @@ export type ParamsOfCreateMockOidc<
|
|
|
18
19
|
* In the majority of cases it should be `homeUrl: "/"` but it could aso be something like `homeUrl: "/dashboard"`
|
|
19
20
|
* if your web app isn't hosted at the root of the domain.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
+
BASE_URL?: string;
|
|
23
|
+
|
|
24
|
+
/** @deprecated: Use BASE_URL (same thing, just renamed). */
|
|
25
|
+
homeUrl?: string;
|
|
26
|
+
|
|
22
27
|
autoLogin?: AutoLogin;
|
|
23
28
|
postLoginRedirectUrl?: string;
|
|
24
29
|
} & (AutoLogin extends true
|
|
@@ -41,11 +46,12 @@ export async function createMockOidc<
|
|
|
41
46
|
isUserInitiallyLoggedIn = true,
|
|
42
47
|
mockedParams = {},
|
|
43
48
|
mockedTokens = {},
|
|
44
|
-
homeUrl: homeUrl_params,
|
|
45
49
|
autoLogin = false,
|
|
46
50
|
postLoginRedirectUrl
|
|
47
51
|
} = params;
|
|
48
52
|
|
|
53
|
+
const BASE_URL_params = params.BASE_URL ?? params.homeUrl;
|
|
54
|
+
|
|
49
55
|
const isUserLoggedIn = (() => {
|
|
50
56
|
const { wasPresent, value } = getSearchParam({
|
|
51
57
|
url: toFullyQualifiedUrl({
|
|
@@ -82,7 +88,7 @@ export async function createMockOidc<
|
|
|
82
88
|
})();
|
|
83
89
|
|
|
84
90
|
const homeUrl = toFullyQualifiedUrl({
|
|
85
|
-
urlish:
|
|
91
|
+
urlish: BASE_URL_params ?? getBASE_URL() ?? "/",
|
|
86
92
|
doAssertNoQueryParams: true,
|
|
87
93
|
doOutputWithTrailingSlash: true
|
|
88
94
|
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { OidcSpaApi } from "./types";
|
|
2
|
+
import type { Oidc as Oidc_core } from "../core";
|
|
3
|
+
import type { ZodSchemaLike } from "../tools/ZodSchemaLike";
|
|
4
|
+
import { createOidcSpaApi } from "./createOidcSpaApi";
|
|
5
|
+
|
|
6
|
+
export type OidcSpaApiBuilder<
|
|
7
|
+
AutoLogin extends boolean = false,
|
|
8
|
+
DecodedIdToken extends Record<string, unknown> = Oidc_core.Tokens.DecodedIdToken_OidcCoreSpec,
|
|
9
|
+
ExcludedMethod extends
|
|
10
|
+
| "withAutoLogin"
|
|
11
|
+
| "withExpectedDecodedIdTokenShape"
|
|
12
|
+
| "withAccessTokenValidation"
|
|
13
|
+
| "finalize" = never
|
|
14
|
+
> = Omit<
|
|
15
|
+
{
|
|
16
|
+
withAutoLogin: () => OidcSpaApiBuilder<true, DecodedIdToken, ExcludedMethod | "withAutoLogin">;
|
|
17
|
+
withExpectedDecodedIdTokenShape: <DecodedIdToken extends Record<string, unknown>>(params: {
|
|
18
|
+
decodedIdTokenSchema: ZodSchemaLike<
|
|
19
|
+
Oidc_core.Tokens.DecodedIdToken_OidcCoreSpec,
|
|
20
|
+
DecodedIdToken
|
|
21
|
+
>;
|
|
22
|
+
decodedIdToken_mock?: NoInfer<DecodedIdToken>;
|
|
23
|
+
}) => OidcSpaApiBuilder<
|
|
24
|
+
AutoLogin,
|
|
25
|
+
DecodedIdToken,
|
|
26
|
+
ExcludedMethod | "withExpectedDecodedIdTokenShape"
|
|
27
|
+
>;
|
|
28
|
+
|
|
29
|
+
finalize: () => OidcSpaApi<AutoLogin, DecodedIdToken>;
|
|
30
|
+
},
|
|
31
|
+
ExcludedMethod
|
|
32
|
+
>;
|
|
33
|
+
|
|
34
|
+
function createOidcSpaApiBuilder<
|
|
35
|
+
AutoLogin extends boolean = false,
|
|
36
|
+
DecodedIdToken extends Record<string, unknown> = Oidc_core.Tokens.DecodedIdToken_OidcCoreSpec
|
|
37
|
+
>(params: {
|
|
38
|
+
autoLogin: AutoLogin;
|
|
39
|
+
decodedIdTokenSchema:
|
|
40
|
+
| ZodSchemaLike<Oidc_core.Tokens.DecodedIdToken_OidcCoreSpec, DecodedIdToken>
|
|
41
|
+
| undefined;
|
|
42
|
+
decodedIdToken_mock: DecodedIdToken | undefined;
|
|
43
|
+
}): OidcSpaApiBuilder<AutoLogin, DecodedIdToken> {
|
|
44
|
+
return {
|
|
45
|
+
withAutoLogin: () =>
|
|
46
|
+
createOidcSpaApiBuilder({
|
|
47
|
+
autoLogin: true,
|
|
48
|
+
decodedIdTokenSchema: params.decodedIdTokenSchema,
|
|
49
|
+
decodedIdToken_mock: params.decodedIdToken_mock
|
|
50
|
+
}),
|
|
51
|
+
withExpectedDecodedIdTokenShape: ({ decodedIdTokenSchema, decodedIdToken_mock }) =>
|
|
52
|
+
createOidcSpaApiBuilder({
|
|
53
|
+
autoLogin: params.autoLogin,
|
|
54
|
+
decodedIdTokenSchema,
|
|
55
|
+
decodedIdToken_mock: decodedIdToken_mock
|
|
56
|
+
}),
|
|
57
|
+
finalize: () =>
|
|
58
|
+
createOidcSpaApi<AutoLogin, DecodedIdToken>({
|
|
59
|
+
autoLogin: params.autoLogin,
|
|
60
|
+
decodedIdTokenSchema: params.decodedIdTokenSchema,
|
|
61
|
+
decodedIdToken_mock: params.decodedIdToken_mock
|
|
62
|
+
})
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const oidcSpaApiBuilder = createOidcSpaApiBuilder({
|
|
67
|
+
autoLogin: false,
|
|
68
|
+
decodedIdToken_mock: undefined,
|
|
69
|
+
decodedIdTokenSchema: undefined
|
|
70
|
+
});
|