@lilaquadrat/frontend 0.1.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.
- package/LICENSE +21 -0
- package/README.md +132 -0
- package/dist/auth.d.ts +194 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +280 -0
- package/dist/auth.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/AuthCallbacks.d.ts +29 -0
- package/dist/interfaces/AuthCallbacks.d.ts.map +1 -0
- package/dist/interfaces/AuthCallbacks.js +2 -0
- package/dist/interfaces/AuthCallbacks.js.map +1 -0
- package/dist/interfaces/AuthInitOptions.d.ts +15 -0
- package/dist/interfaces/AuthInitOptions.d.ts.map +1 -0
- package/dist/interfaces/AuthInitOptions.js +2 -0
- package/dist/interfaces/AuthInitOptions.js.map +1 -0
- package/dist/interfaces/AuthOptions.d.ts +21 -0
- package/dist/interfaces/AuthOptions.d.ts.map +1 -0
- package/dist/interfaces/AuthOptions.js +2 -0
- package/dist/interfaces/AuthOptions.js.map +1 -0
- package/dist/interfaces/KeycloakClient.d.ts +36 -0
- package/dist/interfaces/KeycloakClient.d.ts.map +1 -0
- package/dist/interfaces/KeycloakClient.js +2 -0
- package/dist/interfaces/KeycloakClient.js.map +1 -0
- package/dist/interfaces/KeycloakRedirectOptions.d.ts +13 -0
- package/dist/interfaces/KeycloakRedirectOptions.d.ts.map +1 -0
- package/dist/interfaces/KeycloakRedirectOptions.js +2 -0
- package/dist/interfaces/KeycloakRedirectOptions.js.map +1 -0
- package/dist/interfaces/KeycloakSilentCheckOptions.d.ts +28 -0
- package/dist/interfaces/KeycloakSilentCheckOptions.d.ts.map +1 -0
- package/dist/interfaces/KeycloakSilentCheckOptions.js +2 -0
- package/dist/interfaces/KeycloakSilentCheckOptions.js.map +1 -0
- package/dist/resize.d.ts +165 -0
- package/dist/resize.d.ts.map +1 -0
- package/dist/resize.js +249 -0
- package/dist/resize.js.map +1 -0
- package/package.json +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 lilaquadrat
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# @lilaquadrat/frontend
|
|
2
|
+
|
|
3
|
+
Shared frontend libraries for lilaquadrat applications.
|
|
4
|
+
|
|
5
|
+
The package is ESM-only and ships TypeScript declarations. Its public API is
|
|
6
|
+
defined exclusively by exports from `src/index.ts`.
|
|
7
|
+
|
|
8
|
+
## Resize
|
|
9
|
+
|
|
10
|
+
The Vue-compatible resize singleton publishes `resized` and `media` events on
|
|
11
|
+
`window`, tracks the viewport height in `--vh`, and reads the active media name
|
|
12
|
+
from the visible child of `#mediadetection`.
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import resize, { useResize } from '@lilaquadrat/frontend/resize';
|
|
16
|
+
|
|
17
|
+
const { media, realHeight, resized } = useResize();
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Vue `2.7` and Vue `3` are supported as peer dependencies.
|
|
21
|
+
|
|
22
|
+
`resize` is the shared singleton and is also the default export. Importing it in
|
|
23
|
+
a browser immediately initializes viewport height and listens for native resize
|
|
24
|
+
events. `useResize()` returns Vue refs: `media` is the current visible media
|
|
25
|
+
class, `realHeight` is the visual viewport height, and `resized` changes after
|
|
26
|
+
each update so components can react to it. Its `plugin` property is the shared
|
|
27
|
+
singleton for advanced use such as setting `debounceTime` or calling `trigger`.
|
|
28
|
+
|
|
29
|
+
Add a `#mediadetection` element containing children whose class names are the
|
|
30
|
+
media labels. CSS must show exactly one child with `display: block`; that class
|
|
31
|
+
becomes `media`. The singleton sets `--vh` on `document.documentElement` and
|
|
32
|
+
dispatches `resized` after every update and `media` only when the media class
|
|
33
|
+
changes. Both events are dispatched on `window`.
|
|
34
|
+
|
|
35
|
+
## Auth
|
|
36
|
+
|
|
37
|
+
`auth` is framework-independent. It owns the Keycloak lifecycle and token
|
|
38
|
+
refreshing; the application owns its own user, permission, and routing state.
|
|
39
|
+
|
|
40
|
+
`keycloak-js` remains an application dependency. Its client instance conforms
|
|
41
|
+
to the exported `KeycloakClient` interface without this package importing it.
|
|
42
|
+
|
|
43
|
+
### Setup
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { createAuth } from '@lilaquadrat/frontend/auth';
|
|
47
|
+
import Keycloak from 'keycloak-js';
|
|
48
|
+
|
|
49
|
+
const auth = createAuth({
|
|
50
|
+
createKeycloak: (configuration) => new Keycloak(configuration),
|
|
51
|
+
callbacks: {
|
|
52
|
+
setToken: (token) => store.commit('setAuthToken', token),
|
|
53
|
+
isSessionLoaded: () => Boolean(store.state.authToken),
|
|
54
|
+
onAuthenticated: () => store.dispatch('loadCurrentUser'),
|
|
55
|
+
onUnauthenticated: () => store.dispatch('clearCurrentUser'),
|
|
56
|
+
onError: (error) => logger.error(error),
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
await auth.init({ development: false, keycloakConfig });
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`createAuth(options)` constructs the service and infers the type of
|
|
64
|
+
`keycloakConfig` from `createKeycloak`. Use `new Auth(options)` only when an
|
|
65
|
+
explicit class instance is required.
|
|
66
|
+
|
|
67
|
+
`AuthOptions.callbacks.setToken` is required and receives every token update,
|
|
68
|
+
including `null` after logout or a token failure. `isSessionLoaded` should
|
|
69
|
+
return `true` after the application has loaded the user and permissions. This
|
|
70
|
+
prevents `onAuthenticated` from loading the same session repeatedly.
|
|
71
|
+
|
|
72
|
+
`onAuthenticated` loads application-specific authenticated state. It is called
|
|
73
|
+
after a successful authentication check. `onUnauthenticated` clears that state.
|
|
74
|
+
`onError` receives failed automatic token refreshes triggered by Keycloak.
|
|
75
|
+
|
|
76
|
+
`AuthOptions.createKeycloak` builds a client from the value passed as
|
|
77
|
+
`keycloakConfig` to `init`. `origin` defaults to `window.location.origin` and
|
|
78
|
+
is used to create Keycloak redirect URLs. Provide it explicitly in tests or
|
|
79
|
+
non-browser environments. `developmentToken` defaults to `DEVTOKEN`.
|
|
80
|
+
|
|
81
|
+
### Lifecycle
|
|
82
|
+
|
|
83
|
+
`auth.init({ development, keycloakConfig })` must run before protected content
|
|
84
|
+
is displayed. In production it initializes Keycloak with silent SSO checking,
|
|
85
|
+
then calls `checkAuth`. Host `silent-check-sso.html` at the application origin.
|
|
86
|
+
In development mode no Keycloak client is created and `developmentToken` is
|
|
87
|
+
stored through `setToken`.
|
|
88
|
+
|
|
89
|
+
`auth.checkAuth()` verifies the active session, refreshes its token, and runs
|
|
90
|
+
`onAuthenticated` if `isSessionLoaded` is absent or returns `false`. Use it in
|
|
91
|
+
an app-specific route guard; redirect to the login route when it rejects.
|
|
92
|
+
|
|
93
|
+
`auth.refreshToken(force)` returns an access token and synchronizes it through
|
|
94
|
+
`setToken`. Concurrent refreshes share one request. Pass `true` after a 401 to
|
|
95
|
+
force a refresh even if the current token has more than 30 seconds remaining.
|
|
96
|
+
|
|
97
|
+
`auth.authorize()` starts Keycloak login, and `auth.register()` starts
|
|
98
|
+
registration. Both return to `/login/callback`. `auth.logout()` clears host
|
|
99
|
+
state before starting Keycloak logout. `auth.getAuthHeader()` returns the last
|
|
100
|
+
stored bearer token; `auth.getFreshAuthHeader()` refreshes before returning it.
|
|
101
|
+
|
|
102
|
+
`setAuthTokenRefresher(refresher)` registers an application-wide refresh
|
|
103
|
+
function. `refreshAuthToken(force)` invokes the function registered by the most
|
|
104
|
+
recent `auth.init`; use it only in HTTP helpers that cannot receive an `Auth`
|
|
105
|
+
instance. Prefer `auth.getFreshAuthHeader()` when an instance is available.
|
|
106
|
+
|
|
107
|
+
### Types
|
|
108
|
+
|
|
109
|
+
`AuthCallbacks` defines the host-state callbacks described above.
|
|
110
|
+
`AuthOptions<T>` defines service construction. `AuthInitOptions<T>` defines the
|
|
111
|
+
per-initialization development flag and Keycloak configuration. `KeycloakClient`
|
|
112
|
+
is the minimal client contract. `KeycloakRedirectOptions` and
|
|
113
|
+
`KeycloakSilentCheckOptions` describe the redirect and silent-session options
|
|
114
|
+
passed to that client. All type definitions are exported from the package root
|
|
115
|
+
and `@lilaquadrat/frontend/auth`.
|
|
116
|
+
|
|
117
|
+
## Install
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
yarn add @lilaquadrat/frontend
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Development
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
yarn build
|
|
127
|
+
yarn typecheck
|
|
128
|
+
yarn lint
|
|
129
|
+
yarn test
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`yarn prepack` runs all validation before the package is packed or published.
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import type { AuthInitOptions } from './interfaces/AuthInitOptions.js';
|
|
2
|
+
import type { AuthOptions } from './interfaces/AuthOptions.js';
|
|
3
|
+
import type { KeycloakClient } from './interfaces/KeycloakClient.js';
|
|
4
|
+
/**
|
|
5
|
+
* Framework-independent Keycloak authentication.
|
|
6
|
+
*
|
|
7
|
+
* The service manages Keycloak and tokens. The host application provides state
|
|
8
|
+
* callbacks, so this module works with Vue, React, Angular, or no UI framework.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import Keycloak from 'keycloak-js';
|
|
13
|
+
* import { createAuth } from '@lilaquadrat/frontend/auth';
|
|
14
|
+
*
|
|
15
|
+
* const auth = createAuth({
|
|
16
|
+
* createKeycloak: (configuration) => new Keycloak(configuration),
|
|
17
|
+
* callbacks: {
|
|
18
|
+
* setToken: (token) => apiClient.setToken(token),
|
|
19
|
+
* isSessionLoaded: () => session.loaded,
|
|
20
|
+
* onAuthenticated: () => session.loadCurrentUser(),
|
|
21
|
+
* onUnauthenticated: () => session.clear(),
|
|
22
|
+
* onError: (error) => logger.error(error),
|
|
23
|
+
* },
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* await auth.init({ development: false, keycloakConfig });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export type { AuthCallbacks, } from './interfaces/AuthCallbacks.js';
|
|
30
|
+
export type { AuthInitOptions, } from './interfaces/AuthInitOptions.js';
|
|
31
|
+
export type { AuthOptions, } from './interfaces/AuthOptions.js';
|
|
32
|
+
export type { KeycloakClient, } from './interfaces/KeycloakClient.js';
|
|
33
|
+
export type { KeycloakRedirectOptions } from './interfaces/KeycloakRedirectOptions.js';
|
|
34
|
+
export type { KeycloakSilentCheckOptions } from './interfaces/KeycloakSilentCheckOptions.js';
|
|
35
|
+
type AuthTokenRefresher = (force?: boolean) => Promise<string>;
|
|
36
|
+
/**
|
|
37
|
+
* Registers the function used by {@link refreshAuthToken} to obtain the current access token.
|
|
38
|
+
*
|
|
39
|
+
* Most applications do not call this directly: `Auth.init` registers its own
|
|
40
|
+
* refresh method. Register a custom refresher only when an HTTP integration is
|
|
41
|
+
* initialized before the `Auth` instance.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* setAuthTokenRefresher((force) => auth.refreshToken(force));
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function setAuthTokenRefresher(refresher: AuthTokenRefresher): void;
|
|
49
|
+
/**
|
|
50
|
+
* Refreshes the access token through the most recently initialized `Auth` instance.
|
|
51
|
+
*
|
|
52
|
+
* Use this in HTTP clients that cannot receive an `Auth` instance directly. Pass
|
|
53
|
+
* `true` only when a request was rejected and must force an immediate refresh.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* const token = await refreshAuthToken(response.status === 401);
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare function refreshAuthToken(force?: boolean): Promise<string | undefined>;
|
|
61
|
+
/**
|
|
62
|
+
* Framework-independent Keycloak authentication service.
|
|
63
|
+
*
|
|
64
|
+
* Construct it with {@link createAuth}, then call {@link Auth.init} before using
|
|
65
|
+
* route guards, API clients, or any other authenticated application feature.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const auth = new Auth({ callbacks, createKeycloak, origin: 'https://app.example.com' });
|
|
70
|
+
* await auth.init({ development: false, keycloakConfig });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare class Auth<KeycloakConfiguration = unknown> {
|
|
74
|
+
/** Indicates whether the service currently holds an authenticated token. */
|
|
75
|
+
authenticated: boolean;
|
|
76
|
+
/** Indicates whether `checkAuth` is currently checking or loading a session. */
|
|
77
|
+
inProgress: boolean;
|
|
78
|
+
/** The most recently acquired access token, if authentication succeeded. */
|
|
79
|
+
token?: string;
|
|
80
|
+
/** The initialized Keycloak client. It is available after production `init`. */
|
|
81
|
+
keycloak?: KeycloakClient;
|
|
82
|
+
private readonly callbacks;
|
|
83
|
+
private readonly createKeycloak?;
|
|
84
|
+
private readonly developmentToken;
|
|
85
|
+
private readonly origin?;
|
|
86
|
+
private development;
|
|
87
|
+
private refreshPromise?;
|
|
88
|
+
private refreshForced;
|
|
89
|
+
/** Creates an auth service. Prefer {@link createAuth} for inferred configuration types. */
|
|
90
|
+
constructor(options: AuthOptions<KeycloakConfiguration>);
|
|
91
|
+
/**
|
|
92
|
+
* Initializes development authentication or a Keycloak client, then verifies the session.
|
|
93
|
+
*
|
|
94
|
+
* Production mode requires both `keycloakConfig` and `createKeycloak`. The application must
|
|
95
|
+
* host `silent-check-sso.html` at its origin for Keycloak silent session checking.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* await auth.init({ development: import.meta.env.DEV, keycloakConfig });
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
init(options: AuthInitOptions<KeycloakConfiguration>): Promise<boolean>;
|
|
103
|
+
/**
|
|
104
|
+
* Refreshes the Keycloak token and stores it through `callbacks.setToken`.
|
|
105
|
+
*
|
|
106
|
+
* Concurrent calls share one request. A forced refresh waits for an active normal refresh,
|
|
107
|
+
* then starts an independent request with Keycloak's `-1` minimum validity.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* const token = await auth.refreshToken();
|
|
112
|
+
* const retryToken = await auth.refreshToken(true);
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
refreshToken(force?: boolean): Promise<string>;
|
|
116
|
+
/**
|
|
117
|
+
* Verifies the current session and runs `onAuthenticated` when host data is not loaded.
|
|
118
|
+
*
|
|
119
|
+
* Call this from application startup or an app-specific route guard. It rejects with
|
|
120
|
+
* `NOT_AUTHENTICATED` when no active Keycloak session exists.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* try {
|
|
125
|
+
* await auth.checkAuth();
|
|
126
|
+
* } catch {
|
|
127
|
+
* router.navigate('/login');
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
checkAuth(): Promise<boolean>;
|
|
132
|
+
/**
|
|
133
|
+
* Redirects the browser to Keycloak's login flow and returns to `/login/callback`.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* await auth.authorize();
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
authorize(): Promise<unknown> | unknown;
|
|
141
|
+
/**
|
|
142
|
+
* Redirects the browser to Keycloak's registration flow and returns to `/login/callback`.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* await auth.register();
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
register(): Promise<unknown> | unknown;
|
|
150
|
+
/**
|
|
151
|
+
* Clears host authentication state, then redirects the browser to Keycloak's logout flow.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```ts
|
|
155
|
+
* await auth.logout();
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
logout(): Promise<unknown> | unknown;
|
|
159
|
+
/**
|
|
160
|
+
* Returns an HTTP `Authorization` header using the most recently stored token.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* await fetch('/api/me', { headers: auth.getAuthHeader() });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
getAuthHeader(): {
|
|
168
|
+
Authorization: string;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Refreshes the token and returns an HTTP `Authorization` header with the fresh value.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* await fetch('/api/me', { headers: await auth.getFreshAuthHeader() });
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
getFreshAuthHeader(): Promise<{
|
|
179
|
+
Authorization: string;
|
|
180
|
+
}>;
|
|
181
|
+
private clearAuthentication;
|
|
182
|
+
private requireKeycloak;
|
|
183
|
+
private requireOrigin;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Creates a framework-independent `Auth` service with inferred Keycloak configuration types.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```ts
|
|
190
|
+
* const auth = createAuth({ callbacks, createKeycloak: (configuration) => new Keycloak(configuration) });
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
export declare function createAuth<KeycloakConfiguration>(options: AuthOptions<KeycloakConfiguration>): Auth<KeycloakConfiguration>;
|
|
194
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,YAAY,EACV,aAAa,GACd,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,eAAe,GAChB,MAAM,iCAAiC,CAAC;AACzC,YAAY,EACV,WAAW,GACZ,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,cAAc,GACf,MAAM,gCAAgC,CAAC;AACxC,YAAY,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AACvF,YAAY,EAAE,0BAA0B,EAAE,MAAM,4CAA4C,CAAC;AAE7F,KAAK,kBAAkB,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAI/D;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAEzE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE3E;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,IAAI,CAAC,qBAAqB,GAAG,OAAO;IAC/C,4EAA4E;IAC5E,aAAa,UAAS;IAEtB,gFAAgF;IAChF,UAAU,UAAS;IAEnB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,gFAAgF;IAChF,QAAQ,CAAC,EAAE,cAAc,CAAC;IAE1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAA2D;IAC3F,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAC,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAS;IAE9B,2FAA2F;gBAC/E,OAAO,EAAE,WAAW,CAAC,qBAAqB,CAAC;IAOvD;;;;;;;;;;OAUG;IACG,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAmC7E;;;;;;;;;;;OAWG;IACG,YAAY,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAwClD;;;;;;;;;;;;;;OAcG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IA0BnC;;;;;;;OAOG;IACH,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO;IAIvC;;;;;;;OAOG;IACH,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO;IAItC;;;;;;;OAOG;IACH,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO;IAMpC;;;;;;;OAOG;IACH,aAAa,IAAI;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE;IAI1C;;;;;;;OAOG;IACG,kBAAkB,IAAI,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IAI9D,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,aAAa;CAItB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,qBAAqB,EAAE,OAAO,EAAE,WAAW,CAAC,qBAAqB,CAAC,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAE1H"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
let authTokenRefresher;
|
|
2
|
+
/**
|
|
3
|
+
* Registers the function used by {@link refreshAuthToken} to obtain the current access token.
|
|
4
|
+
*
|
|
5
|
+
* Most applications do not call this directly: `Auth.init` registers its own
|
|
6
|
+
* refresh method. Register a custom refresher only when an HTTP integration is
|
|
7
|
+
* initialized before the `Auth` instance.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* setAuthTokenRefresher((force) => auth.refreshToken(force));
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export function setAuthTokenRefresher(refresher) {
|
|
15
|
+
authTokenRefresher = refresher;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Refreshes the access token through the most recently initialized `Auth` instance.
|
|
19
|
+
*
|
|
20
|
+
* Use this in HTTP clients that cannot receive an `Auth` instance directly. Pass
|
|
21
|
+
* `true` only when a request was rejected and must force an immediate refresh.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const token = await refreshAuthToken(response.status === 401);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function refreshAuthToken(force = false) {
|
|
29
|
+
return Promise.resolve(authTokenRefresher?.(force));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Framework-independent Keycloak authentication service.
|
|
33
|
+
*
|
|
34
|
+
* Construct it with {@link createAuth}, then call {@link Auth.init} before using
|
|
35
|
+
* route guards, API clients, or any other authenticated application feature.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const auth = new Auth({ callbacks, createKeycloak, origin: 'https://app.example.com' });
|
|
40
|
+
* await auth.init({ development: false, keycloakConfig });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export class Auth {
|
|
44
|
+
/** Indicates whether the service currently holds an authenticated token. */
|
|
45
|
+
authenticated = false;
|
|
46
|
+
/** Indicates whether `checkAuth` is currently checking or loading a session. */
|
|
47
|
+
inProgress = false;
|
|
48
|
+
/** The most recently acquired access token, if authentication succeeded. */
|
|
49
|
+
token;
|
|
50
|
+
/** The initialized Keycloak client. It is available after production `init`. */
|
|
51
|
+
keycloak;
|
|
52
|
+
callbacks;
|
|
53
|
+
createKeycloak;
|
|
54
|
+
developmentToken;
|
|
55
|
+
origin;
|
|
56
|
+
development = false;
|
|
57
|
+
refreshPromise;
|
|
58
|
+
refreshForced = false;
|
|
59
|
+
/** Creates an auth service. Prefer {@link createAuth} for inferred configuration types. */
|
|
60
|
+
constructor(options) {
|
|
61
|
+
this.callbacks = options.callbacks;
|
|
62
|
+
this.createKeycloak = options.createKeycloak;
|
|
63
|
+
this.developmentToken = options.developmentToken ?? 'DEVTOKEN';
|
|
64
|
+
this.origin = options.origin ?? (typeof window === 'undefined' ? undefined : window.location.origin);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Initializes development authentication or a Keycloak client, then verifies the session.
|
|
68
|
+
*
|
|
69
|
+
* Production mode requires both `keycloakConfig` and `createKeycloak`. The application must
|
|
70
|
+
* host `silent-check-sso.html` at its origin for Keycloak silent session checking.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* await auth.init({ development: import.meta.env.DEV, keycloakConfig });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
async init(options) {
|
|
78
|
+
this.development = options.development;
|
|
79
|
+
if (this.development) {
|
|
80
|
+
setAuthTokenRefresher((force) => this.refreshToken(force));
|
|
81
|
+
return this.checkAuth();
|
|
82
|
+
}
|
|
83
|
+
if (options.keycloakConfig === undefined)
|
|
84
|
+
throw new Error('KEYCLOAK_CONFIG_MISSING');
|
|
85
|
+
if (!this.createKeycloak)
|
|
86
|
+
throw new Error('KEYCLOAK_FACTORY_MISSING');
|
|
87
|
+
if (!this.origin)
|
|
88
|
+
throw new Error('BROWSER_ORIGIN_MISSING');
|
|
89
|
+
this.keycloak = this.createKeycloak(options.keycloakConfig);
|
|
90
|
+
this.keycloak.onAuthLogout = () => this.clearAuthentication();
|
|
91
|
+
this.keycloak.onTokenExpired = () => {
|
|
92
|
+
void this.refreshToken().catch((error) => {
|
|
93
|
+
this.callbacks.onError?.(error);
|
|
94
|
+
this.keycloak?.clearToken();
|
|
95
|
+
this.clearAuthentication();
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
setAuthTokenRefresher((force) => this.refreshToken(force));
|
|
99
|
+
await this.keycloak.init({
|
|
100
|
+
onLoad: 'check-sso',
|
|
101
|
+
flow: 'standard',
|
|
102
|
+
pkceMethod: 'S256',
|
|
103
|
+
scope: 'profile',
|
|
104
|
+
silentCheckSsoRedirectUri: `${this.origin}/silent-check-sso.html`,
|
|
105
|
+
silentCheckSsoFallback: true,
|
|
106
|
+
});
|
|
107
|
+
return this.checkAuth();
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Refreshes the Keycloak token and stores it through `callbacks.setToken`.
|
|
111
|
+
*
|
|
112
|
+
* Concurrent calls share one request. A forced refresh waits for an active normal refresh,
|
|
113
|
+
* then starts an independent request with Keycloak's `-1` minimum validity.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* const token = await auth.refreshToken();
|
|
118
|
+
* const retryToken = await auth.refreshToken(true);
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
async refreshToken(force = false) {
|
|
122
|
+
if (this.development)
|
|
123
|
+
return this.developmentToken;
|
|
124
|
+
const keycloak = this.keycloak;
|
|
125
|
+
if (!keycloak?.authenticated)
|
|
126
|
+
throw new Error('NOT_AUTHENTICATED');
|
|
127
|
+
if (this.refreshPromise) {
|
|
128
|
+
if (!force || this.refreshForced)
|
|
129
|
+
return this.refreshPromise;
|
|
130
|
+
try {
|
|
131
|
+
await this.refreshPromise;
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// A forced refresh gets an independent result after the active request settles.
|
|
135
|
+
}
|
|
136
|
+
return this.refreshToken(true);
|
|
137
|
+
}
|
|
138
|
+
const refreshPromise = keycloak.updateToken(force ? -1 : 30).then(() => {
|
|
139
|
+
if (!keycloak.token)
|
|
140
|
+
throw new Error('TOKEN_MISSING');
|
|
141
|
+
this.token = keycloak.token;
|
|
142
|
+
this.authenticated = true;
|
|
143
|
+
this.callbacks.setToken(keycloak.token);
|
|
144
|
+
return keycloak.token;
|
|
145
|
+
});
|
|
146
|
+
this.refreshPromise = refreshPromise;
|
|
147
|
+
this.refreshForced = force;
|
|
148
|
+
try {
|
|
149
|
+
return await refreshPromise;
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
if (this.refreshPromise === refreshPromise) {
|
|
153
|
+
this.refreshPromise = undefined;
|
|
154
|
+
this.refreshForced = false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Verifies the current session and runs `onAuthenticated` when host data is not loaded.
|
|
160
|
+
*
|
|
161
|
+
* Call this from application startup or an app-specific route guard. It rejects with
|
|
162
|
+
* `NOT_AUTHENTICATED` when no active Keycloak session exists.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```ts
|
|
166
|
+
* try {
|
|
167
|
+
* await auth.checkAuth();
|
|
168
|
+
* } catch {
|
|
169
|
+
* router.navigate('/login');
|
|
170
|
+
* }
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
async checkAuth() {
|
|
174
|
+
this.inProgress = true;
|
|
175
|
+
try {
|
|
176
|
+
if (this.development) {
|
|
177
|
+
this.token = this.developmentToken;
|
|
178
|
+
this.authenticated = true;
|
|
179
|
+
this.callbacks.setToken(this.developmentToken);
|
|
180
|
+
await this.callbacks.onAuthenticated?.();
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
if (!this.keycloak?.authenticated)
|
|
184
|
+
throw new Error('NOT_AUTHENTICATED');
|
|
185
|
+
await this.refreshToken();
|
|
186
|
+
if (!this.callbacks.isSessionLoaded?.()) {
|
|
187
|
+
await this.callbacks.onAuthenticated?.();
|
|
188
|
+
}
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
this.inProgress = false;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Redirects the browser to Keycloak's login flow and returns to `/login/callback`.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```ts
|
|
200
|
+
* await auth.authorize();
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
authorize() {
|
|
204
|
+
return this.requireKeycloak().login({ redirectUri: `${this.requireOrigin()}/login/callback` });
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Redirects the browser to Keycloak's registration flow and returns to `/login/callback`.
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```ts
|
|
211
|
+
* await auth.register();
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
register() {
|
|
215
|
+
return this.requireKeycloak().register({ redirectUri: `${this.requireOrigin()}/login/callback` });
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Clears host authentication state, then redirects the browser to Keycloak's logout flow.
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* await auth.logout();
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
logout() {
|
|
226
|
+
const keycloak = this.requireKeycloak();
|
|
227
|
+
this.clearAuthentication();
|
|
228
|
+
return keycloak.logout({ redirectUri: this.requireOrigin() });
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Returns an HTTP `Authorization` header using the most recently stored token.
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```ts
|
|
235
|
+
* await fetch('/api/me', { headers: auth.getAuthHeader() });
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
getAuthHeader() {
|
|
239
|
+
return { Authorization: `Bearer ${this.token ?? ''}` };
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Refreshes the token and returns an HTTP `Authorization` header with the fresh value.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```ts
|
|
246
|
+
* await fetch('/api/me', { headers: await auth.getFreshAuthHeader() });
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
async getFreshAuthHeader() {
|
|
250
|
+
return { Authorization: `Bearer ${await this.refreshToken()}` };
|
|
251
|
+
}
|
|
252
|
+
clearAuthentication() {
|
|
253
|
+
this.token = undefined;
|
|
254
|
+
this.authenticated = false;
|
|
255
|
+
this.callbacks.setToken(null);
|
|
256
|
+
void this.callbacks.onUnauthenticated?.();
|
|
257
|
+
}
|
|
258
|
+
requireKeycloak() {
|
|
259
|
+
if (!this.keycloak)
|
|
260
|
+
throw new Error('AUTH_NOT_INITIALIZED');
|
|
261
|
+
return this.keycloak;
|
|
262
|
+
}
|
|
263
|
+
requireOrigin() {
|
|
264
|
+
if (!this.origin)
|
|
265
|
+
throw new Error('BROWSER_ORIGIN_MISSING');
|
|
266
|
+
return this.origin;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Creates a framework-independent `Auth` service with inferred Keycloak configuration types.
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* ```ts
|
|
274
|
+
* const auth = createAuth({ callbacks, createKeycloak: (configuration) => new Keycloak(configuration) });
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
export function createAuth(options) {
|
|
278
|
+
return new Auth(options);
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as resize } from './resize.js';
|
|
2
|
+
export { Resize, useResize } from './resize.js';
|
|
3
|
+
export { Auth, createAuth, refreshAuthToken, setAuthTokenRefresher } from './auth.js';
|
|
4
|
+
export type { AuthCallbacks, AuthInitOptions, AuthOptions, KeycloakClient, KeycloakRedirectOptions, KeycloakSilentCheckOptions, } from './auth.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AACtF,YAAY,EACV,aAAa,EACb,eAAe,EACf,WAAW,EACX,cAAc,EACd,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
|