oidc-spa 6.15.1 β†’ 7.0.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 (43) hide show
  1. package/README.md +12 -13
  2. package/core/Oidc.d.ts +24 -12
  3. package/core/createOidc.d.ts +15 -30
  4. package/core/createOidc.js +184 -146
  5. package/core/createOidc.js.map +1 -1
  6. package/core/handleOidcCallback.js +2 -29
  7. package/core/handleOidcCallback.js.map +1 -1
  8. package/core/loginOrGoToAuthServer.d.ts +1 -2
  9. package/core/loginOrGoToAuthServer.js +10 -10
  10. package/core/loginOrGoToAuthServer.js.map +1 -1
  11. package/core/loginSilent.d.ts +1 -1
  12. package/core/loginSilent.js +4 -4
  13. package/core/loginSilent.js.map +1 -1
  14. package/core/oidcClientTsUserToTokens.d.ts +1 -2
  15. package/core/oidcClientTsUserToTokens.js +93 -58
  16. package/core/oidcClientTsUserToTokens.js.map +1 -1
  17. package/mock/oidc.d.ts +1 -1
  18. package/mock/oidc.js +29 -19
  19. package/mock/oidc.js.map +1 -1
  20. package/package.json +1 -5
  21. package/react/react.d.ts +9 -14
  22. package/react/react.js +32 -60
  23. package/react/react.js.map +1 -1
  24. package/src/core/Oidc.ts +27 -14
  25. package/src/core/createOidc.ts +189 -149
  26. package/src/core/handleOidcCallback.ts +2 -55
  27. package/src/core/loginOrGoToAuthServer.ts +10 -11
  28. package/src/core/loginSilent.ts +4 -4
  29. package/src/core/oidcClientTsUserToTokens.ts +129 -82
  30. package/src/mock/oidc.ts +16 -6
  31. package/src/react/react.tsx +52 -80
  32. package/src/tools/readExpirationTimeInJwt.ts +4 -5
  33. package/src/tools/startCountdown.ts +4 -5
  34. package/tools/readExpirationTimeInJwt.js +4 -4
  35. package/tools/readExpirationTimeInJwt.js.map +1 -1
  36. package/tools/startCountdown.d.ts +3 -2
  37. package/tools/startCountdown.js +4 -4
  38. package/tools/startCountdown.js.map +1 -1
  39. package/vendor/frontend/oidc-client-ts-and-jwt-decode.js +1 -1
  40. package/core/debug966975.d.ts +0 -7
  41. package/core/debug966975.js +0 -88
  42. package/core/debug966975.js.map +0 -1
  43. package/src/core/debug966975.ts +0 -85
package/README.md CHANGED
@@ -5,9 +5,6 @@
5
5
  <a href="https://github.com/keycloakify/oidc-spa/actions">
6
6
  <img src="https://github.com/keycloakify/oidc-spa/actions/workflows/ci.yaml/badge.svg?branch=main">
7
7
  </a>
8
- <a href="https://bundlephobia.com/package/oidc-spa">
9
- <img src="https://img.shields.io/bundlephobia/minzip/oidc-spa">
10
- </a>
11
8
  <a href="https://www.npmjs.com/package/oidc-spa">
12
9
  <img src="https://img.shields.io/npm/dw/oidc-spa">
13
10
  </a>
@@ -27,9 +24,11 @@
27
24
  <a href="https://docs.oidc-spa.dev">Documentation</a>
28
25
  </p>
29
26
 
27
+ > πŸ—£οΈ oidc-spa will be introduced at [KeyConf 2025](https://keyconf.dev/) on the 28 of August.
28
+
30
29
  A full-featured OpenID Connect / OAuth2 client for single-page applications (SPAs).
31
30
 
32
- With `oidc-spa`, you can seamlessly integrate authentication providers like [Keycloak](https://www.keycloak.org/), [Auth0](https://auth0.com/), or [Microsoft Entra ID](https://www.microsoft.com/en-us/security/business/identity-access/microsoft-entra-id) into your application, purely on the client sideβ€”
31
+ With `oidc-spa`, you can seamlessly integrate authentication providers like [Keycloak](https://www.keycloak.org/), [Auth0](https://auth0.com/), or [Microsoft Entra ID](https://www.microsoft.com/en-us/security/business/identity-access/microsoft-entra-id) into your application, purely on the client side,
33
32
  [without involving your backend in the token exchange](https://docs.oidc-spa.dev/resources/why-no-client-secret).
34
33
 
35
34
  In **simple terms**, `oidc-spa` is a library that makes it easy to **add authentication** to your Vite or Create-React-App project.
@@ -60,12 +59,12 @@ These libraries are **tied to a specific provider**. But what if you need to:
60
59
 
61
60
  And besides, not all SDKs are equal in terms of setup simplicity, performance, and API quality.
62
61
 
63
- We wanted a **universal solution**β€”one that is as good or better than all existing SDKs in every aspect.
62
+ We wanted a **universal solution**, one that is as good or better than all existing SDKs in every aspect.
64
63
 
65
64
  ## Features
66
65
 
67
66
  - πŸŽ“ **No OIDC/OAuth2 expertise required**: Easy to setup and use. We're here to help [on Discord](https://discord.gg/mJdYJSdcm4)!
68
- - πŸ› οΈ **Simple setup**: No need to define `/login` or `/logout` routesβ€”token refreshing is automatic, it just works.
67
+ - πŸ› οΈ **Simple setup**: No need to define `/login` or `/logout` routes, token refreshing is automatic, it just works.
69
68
  - ✨ **React integration**: Expose a framework agnostic API but also a React adapter `oidc-spa/react`.
70
69
  - πŸ”₯ **No limitation**- For example, everything you could do with `keycloak-js`, you can do with `oidc-spa`.
71
70
  - πŸ’¬ **Detailed debug messages**: If your OIDC server is not properly configured, it tells you precisely what’s wrong and what you need to do to fix it.
@@ -73,23 +72,23 @@ We wanted a **universal solution**β€”one that is as good or better than all exis
73
72
  - πŸšͺ **Logout propagation**: Logging out in one tab logs out all others.
74
73
  - πŸ“– **Comprehensive documentation**: Guides and examples for common scenarios.
75
74
  - βœ… **Type safety**: Strong TypeScript support with optional [Zod](https://zod.dev/) integration validating the expected shape of the ID token.
76
- - πŸ”’ **Security-first**: Uses [**Authorization Code Flow + PKCE**](https://docs.oidc-spa.dev/resources/why-no-client-secret#id-2.-authorization-code-flow--pkce-used-by-oidc-spa)β€”No token persistence in `localStorage` or `sessionStorage`.
75
+ - πŸ”’ **Security-first**: Uses [**Authorization Code Flow + PKCE**](https://docs.oidc-spa.dev/resources/why-no-client-secret#id-2.-authorization-code-flow--pkce-used-by-oidc-spa), No token persistence in `localStorage` or `sessionStorage`.
77
76
  - πŸ–₯️ **Optional backend utilities**: Provides tools for token validation in JavaScript backends (Node.js, Deno, Web Workers).
78
- - πŸ”— **Multi-instance support**: Run multiple `oidc-spa` instancesβ€”for example, to offer **Login with Google OR Microsoft** in the same app.
79
- - πŸͺ **No third-party cookie issues**: Third-party cookies blocked? No problemβ€”`oidc-spa` works around it automatically with no special measures needed on your side.
77
+ - πŸͺ **No third-party cookie issues**: Third-party cookies blocked? No problem, `oidc-spa` works around it automatically with no special measures needed on your side.
78
+ - πŸ”— **Multi-instance support**: Run multiple `oidc-spa` instances in the same app without conflict.
80
79
 
81
80
  ## Comparison with Existing Libraries
82
81
 
83
82
  ### [oidc-client-ts](https://github.com/authts/oidc-client-ts)
84
83
 
85
84
  While `oidc-client-ts` is a comprehensive toolkit designed for various applications, `oidc-spa` is specifically built for SPAs with an easy-to-set-up API.
86
- But **ease of use** isn't the only differenceβ€”`oidc-spa` also provides **out-of-the-box** solutions for features that `oidc-client-ts` leaves up to you to implement, such as:
85
+ But **ease of use** isn't the only difference, `oidc-spa` also provides **out-of-the-box** solutions for features that `oidc-client-ts` leaves up to you to implement, such as:
87
86
 
88
87
  - **Login/logout propagation** across tabs
89
88
  - **Graceful fallback when third-party cookies are blocked**
90
89
  - **Seamless browser back/forward cache (bfcache) management**
91
90
  - **Auto logout countdown** so users can be automatically logged out after a set period of inactivity.
92
- - **Ensuring you never get an expired access token error**β€”even after the computer wakes up from sleep.
91
+ - **Ensuring you never get an expired access token error**, even after the computer wakes up from sleep.
93
92
  - **Gracefully handles scenarios where the provider does not issue a refresh token or lacks a logout endpoint** (e.g., Google OAuth)
94
93
 
95
94
  ### [react-oidc-context](https://github.com/authts/react-oidc-context)
@@ -100,7 +99,7 @@ But **ease of use** isn't the only differenceβ€”`oidc-spa` also provides **out-o
100
99
  ### [keycloak-js](https://www.npmjs.com/package/keycloak-js)
101
100
 
102
101
  The official OIDC Client for Keycloak. It only works with Keycloak and [will eventually be deprecated](https://www.keycloak.org/2023/03/adapter-deprecation-update).
103
- Beyond that, achieving the same seamless user experience as `oidc-spa` with `keycloak-js` requires writing a lot of custom codeβ€”code that really **shouldn’t** be handled at the application level.
102
+ Beyond that, achieving the same seamless user experience as `oidc-spa` with `keycloak-js` requires writing a lot of custom code, code that really **shouldn’t** be handled at the application level.
104
103
 
105
104
  ### [NextAuth.js](https://next-auth.js.org/)
106
105
 
@@ -164,7 +163,7 @@ Project backers, we trust and recommend their services.
164
163
 
165
164
  This library isn't a theoretical exercise or a tool for hobby projects.
166
165
  We developed it to solve real-world problems we faced ourselves.
167
- Today, it powers authentication for [Onyxia](https://onyxia.sh)β€”
166
+ Today, it powers authentication for [Onyxia](https://onyxia.sh),
168
167
  a data science platform deployed across multiple large organizations.
169
168
 
170
169
  ### Onyxia
package/core/Oidc.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { OidcInitializationError } from "./OidcInitializationError";
2
- export declare type Oidc<DecodedIdToken extends Record<string, unknown> = Record<string, unknown>> = Oidc.LoggedIn<DecodedIdToken> | Oidc.NotLoggedIn;
2
+ export declare type Oidc<DecodedIdToken extends Record<string, unknown> = Oidc.Tokens.DecodedIdToken_base> = Oidc.LoggedIn<DecodedIdToken> | Oidc.NotLoggedIn;
3
3
  export declare namespace Oidc {
4
4
  type Common = {
5
5
  params: {
@@ -35,16 +35,7 @@ export declare namespace Oidc {
35
35
  renewTokens(params?: {
36
36
  extraTokenParams?: Record<string, string | undefined>;
37
37
  }): Promise<void>;
38
- /**
39
- * Prefer using getTokens_next(), in the next major getTokens() will be be async.
40
- *
41
- * The problem is that When the computer wakes up from sleep, the tokens might have expired so
42
- * there is a window of time where the tokens are not valid.
43
- *
44
- * This potential issue do not affect you if you are using "oidc-spa/react" as in the documentation.
45
- * */
46
- getTokens: () => Tokens<DecodedIdToken>;
47
- getTokens_next: () => Promise<Tokens<DecodedIdToken>>;
38
+ getTokens: () => Promise<Tokens<DecodedIdToken>>;
48
39
  subscribeToTokensChange: (onTokenChange: (tokens: Tokens<DecodedIdToken>) => void) => {
49
40
  unsubscribe: () => void;
50
41
  };
@@ -93,13 +84,26 @@ export declare namespace Oidc {
93
84
  */
94
85
  isNewBrowserSession: boolean;
95
86
  };
96
- type Tokens<DecodedIdToken extends Record<string, unknown> = Record<string, unknown>> = Tokens.WithRefreshToken<DecodedIdToken> | Tokens.WithoutRefreshToken<DecodedIdToken>;
87
+ type Tokens<DecodedIdToken extends Record<string, unknown> = Tokens.DecodedIdToken_base> = Tokens.WithRefreshToken<DecodedIdToken> | Tokens.WithoutRefreshToken<DecodedIdToken>;
97
88
  namespace Tokens {
98
89
  type Common<DecodedIdToken> = {
99
90
  accessToken: string;
100
91
  accessTokenExpirationTime: number;
101
92
  idToken: string;
102
93
  decodedIdToken: DecodedIdToken;
94
+ /**
95
+ * decodedIdToken_original = decodeJwt(idToken);
96
+ * decodedIdToken = decodedIdTokenSchema.parse(decodedIdToken_original)
97
+ *
98
+ * The idea here is that if you have provided a zod schema as `decodedIdTokenSchema`
99
+ * it will strip out every claim that you haven't specified.
100
+ * You might even be applying some transformation.
101
+ *
102
+ * `decodedIdToken_original` is the actual decoded payload of the id_token, untransformed.
103
+ * */
104
+ decodedIdToken_original: DecodedIdToken_base;
105
+ /** Read from id_token's JWT, iat claim value, it's a JavaScript timestamp (millisecond epoch) */
106
+ issuedAtTime: number;
103
107
  };
104
108
  type WithRefreshToken<DecodedIdToken> = Common<DecodedIdToken> & {
105
109
  hasRefreshToken: true;
@@ -111,5 +115,13 @@ export declare namespace Oidc {
111
115
  refreshToken?: never;
112
116
  refreshTokenExpirationTime?: never;
113
117
  };
118
+ type DecodedIdToken_base = {
119
+ iss: string;
120
+ sub: string;
121
+ aud: string | string[];
122
+ exp: number;
123
+ iat: number;
124
+ [claimName: string]: unknown;
125
+ };
114
126
  }
115
127
  }
@@ -9,18 +9,12 @@ export type ParamsOfCreateOidc<DecodedIdToken extends Record<string, unknown> =
9
9
  **/
10
10
  scopes?: string[];
11
11
  /**
12
- * Transform the url of the authorization endpoint before redirecting to the login pages.
13
- */
14
- transformUrlBeforeRedirect?: (url: string) => string;
15
- /**
16
- * NOTE: Will replace transformUrlBeforeRedirect in the next major version.
17
- *
18
12
  * Transform the url (authorization endpoint) before redirecting to the login pages.
19
13
  *
20
14
  * The isSilent parameter is true when the redirect is initiated in the background iframe for silent signin.
21
15
  * This can be used to omit ui related query parameters (like `ui_locales`).
22
16
  */
23
- transformUrlBeforeRedirect_next?: (params: {
17
+ transformUrlBeforeRedirect?: (params: {
24
18
  authorizationUrl: string;
25
19
  isSilent: boolean;
26
20
  }) => string;
@@ -65,31 +59,9 @@ export type ParamsOfCreateOidc<DecodedIdToken extends Record<string, unknown> =
65
59
  * - Other: `BASE_URL: "/"` (Usually, or `/dashboard` if your app is not at the root of the domain)
66
60
  */
67
61
  homeUrl: string;
68
- /**
69
- * WARNING: If you are deploying on the web, you should not set this parameter.
70
- * The callbackUrl is the homeURl.
71
- *
72
- * This is only useful for when you also shipping your app as a Desktop App with Electron.
73
- * NOTE that even in this case, it's not automatic, you still need to handle the response
74
- * in the electron node process.
75
- *
76
- * Example: __callbackUri: "myapp://oidc-callback/"
77
- */
78
- __callbackUri?: string;
79
62
  decodedIdTokenSchema?: {
80
- parse: (data: unknown) => DecodedIdToken;
63
+ parse: (decodedIdToken_original: Oidc.Tokens.DecodedIdToken_base) => DecodedIdToken;
81
64
  };
82
- /**
83
- * @deprecated: Use idleSessionLifetimeInSeconds instead
84
- *
85
- * This parameter defines after how many seconds of inactivity the user should be
86
- * logged out automatically.
87
- *
88
- * WARNING: It should be configured on the identity server side
89
- * as it's the authoritative source for security policies and not the client.
90
- * If you don't provide this parameter it will be inferred from the refresh token expiration time.
91
- * */
92
- __unsafe_ssoSessionIdleSeconds?: number;
93
65
  /**
94
66
  * This parameter defines after how many seconds of inactivity the user should be
95
67
  * logged out automatically.
@@ -99,6 +71,9 @@ export type ParamsOfCreateOidc<DecodedIdToken extends Record<string, unknown> =
99
71
  * If you don't provide this parameter it will be inferred from the refresh token expiration time.
100
72
  * */
101
73
  idleSessionLifetimeInSeconds?: number;
74
+ /**
75
+ * Default: { redirectTo: "current page" }
76
+ */
102
77
  autoLogoutParams?: Parameters<Oidc.LoggedIn<any>["logout"]>[0];
103
78
  autoLogin?: AutoLogin;
104
79
  /**
@@ -108,6 +83,16 @@ export type ParamsOfCreateOidc<DecodedIdToken extends Record<string, unknown> =
108
83
  */
109
84
  noIframe?: boolean;
110
85
  debugLogs?: boolean;
86
+ /**
87
+ * WARNING: This option exists solely as a workaround
88
+ * for limitations in the Google OAuth API.
89
+ * See: https://docs.oidc-spa.dev/providers-configuration/google-oauth
90
+ *
91
+ * Do not use this for other providers.
92
+ * If you think you need a client secret in a SPA, you are likely
93
+ * trying to use a confidential (private) client in the browser,
94
+ * which is insecure and not supported.
95
+ */
111
96
  __unsafe_clientSecret?: string;
112
97
  /**
113
98
  * WARNING: Setting this to true is a workaround for provider