@baukit/auth-node 0.5.0 → 0.5.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/README.md +32 -0
- package/dist/keycloak-testing.d.ts +65 -0
- package/dist/keycloak-testing.d.ts.map +1 -0
- package/dist/keycloak-testing.js +129 -0
- package/dist/keycloak-testing.js.map +1 -0
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -66,6 +66,38 @@ const apiUrl = parseApiOrigin(process.env['PRODUCT_API_URL'] ?? 'http://localhos
|
|
|
66
66
|
|
|
67
67
|
It throws `ApiOriginError`, a `TypeError`, with a `reason` of `invalid_url`, `insecure_scheme`, or `not_an_origin`. Credentials, a path, a query, or a fragment count as `not_an_origin`. `allowLoopbackHttp` defaults to false. The message names the label and the broken rule, never the value, so it is safe to log.
|
|
68
68
|
|
|
69
|
+
## Keycloak test helpers
|
|
70
|
+
|
|
71
|
+
`@baukit/auth-node/keycloak-testing` sets up users for end-to-end tests against a disposable development Keycloak. It runs on Node 24, uses the global `fetch`, and needs no Playwright dependency.
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import {
|
|
75
|
+
allowKeycloakWebOrigin,
|
|
76
|
+
createKeycloakTestUser,
|
|
77
|
+
keycloakStack,
|
|
78
|
+
signInWithKeycloak,
|
|
79
|
+
} from '@baukit/auth-node/keycloak-testing';
|
|
80
|
+
|
|
81
|
+
const stack = keycloakStack({
|
|
82
|
+
url: 'http://localhost:8081',
|
|
83
|
+
realm: 'notes',
|
|
84
|
+
webClientId: 'notes-web',
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
await allowKeycloakWebOrigin(stack, 'http://localhost:5183');
|
|
88
|
+
const user = await createKeycloakTestUser(stack);
|
|
89
|
+
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
90
|
+
await signInWithKeycloak(page, user, stack);
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`keycloakStack(defaults, environment = process.env)` returns the product's defaults unless `E2E_KEYCLOAK_URL`, `E2E_KEYCLOAK_REALM`, `E2E_KEYCLOAK_ADMIN_USERNAME`, `E2E_KEYCLOAK_ADMIN_PASSWORD`, or `E2E_KEYCLOAK_WEB_CLIENT_ID` is set. The admin credentials default to `admin` and `admin`, and trailing slashes are removed from the URL.
|
|
94
|
+
|
|
95
|
+
`createKeycloakTestUser(stack, user?, options?)` signs in to the master realm's `admin-cli` and creates a verified, enabled user with a permanent password. Without `user`, the username is `e2e-<uuid>` and the password is random, so parallel tests never share an identity. Pass `username`, `email`, or `password` when the realm signs in by email. It returns `{ username, password, email, subject }`; `subject` is the Keycloak user ID, which becomes the `sub` claim.
|
|
96
|
+
|
|
97
|
+
`revokeKeycloakUserSessions(stack, subject)` ends every session of the user, so the app's next refresh fails. `allowKeycloakWebOrigin(stack, origin)` adds `<origin>/*` to the web client's redirect URIs and `origin` to its web origins, and does nothing when both are present. `signInWithKeycloak(page, user, stack, { timeoutMs })` waits until the page is on the Keycloak origin, fills `#username` and `#password`, and clicks `#kc-login`; those IDs do not change with the login locale. `page` is any object with Playwright's `waitForURL` and `locator`, such as a `Page` or a sign-in popup.
|
|
98
|
+
|
|
99
|
+
Every admin call takes `{ fetch, timeoutMs }`; the timeout defaults to `DEFAULT_KEYCLOAK_REQUEST_TIMEOUT_MS` (30 seconds). A failure throws an `Error` that names the step and HTTP status and never includes a response body or the admin password. Created users and added origins stay in the realm, so point the helpers only at a development realm.
|
|
100
|
+
|
|
69
101
|
## Cache contract
|
|
70
102
|
|
|
71
103
|
The JSON cache holds named profiles under one namespace. `defaultTokenCachePath(namespace)` resolves to `$XDG_CONFIG_HOME/<namespace>/tokens.json`, or `~/.config/<namespace>/tokens.json` when `XDG_CONFIG_HOME` is unset.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** Where a disposable development Keycloak runs and how to administer it. */
|
|
2
|
+
export interface KeycloakStack {
|
|
3
|
+
readonly url: string;
|
|
4
|
+
readonly realm: string;
|
|
5
|
+
readonly adminUsername: string;
|
|
6
|
+
readonly adminPassword: string;
|
|
7
|
+
readonly webClientId: string;
|
|
8
|
+
}
|
|
9
|
+
/** The product's development defaults; `E2E_KEYCLOAK_*` variables override each one. */
|
|
10
|
+
export interface KeycloakStackDefaults {
|
|
11
|
+
readonly url: string;
|
|
12
|
+
readonly realm: string;
|
|
13
|
+
readonly webClientId: string;
|
|
14
|
+
/** Defaults to `admin`. */
|
|
15
|
+
readonly adminUsername?: string;
|
|
16
|
+
/** Defaults to `admin`. */
|
|
17
|
+
readonly adminPassword?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface KeycloakTestUser {
|
|
20
|
+
readonly username: string;
|
|
21
|
+
readonly password: string;
|
|
22
|
+
readonly email: string;
|
|
23
|
+
/** Keycloak user ID, which becomes the `sub` claim of the user's tokens. */
|
|
24
|
+
readonly subject: string;
|
|
25
|
+
}
|
|
26
|
+
export interface KeycloakTestUserOptions {
|
|
27
|
+
/** Defaults to `e2e-<uuid>`, so parallel tests never share an identity. */
|
|
28
|
+
readonly username?: string;
|
|
29
|
+
/** Defaults to a random password. */
|
|
30
|
+
readonly password?: string;
|
|
31
|
+
/** Defaults to `<username>@example.test`. */
|
|
32
|
+
readonly email?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface KeycloakRequestOptions {
|
|
35
|
+
/** Defaults to the global `fetch`. */
|
|
36
|
+
readonly fetch?: typeof fetch;
|
|
37
|
+
/** Per-request timeout. Defaults to {@link DEFAULT_KEYCLOAK_REQUEST_TIMEOUT_MS}. */
|
|
38
|
+
readonly timeoutMs?: number;
|
|
39
|
+
}
|
|
40
|
+
/** The part of a Playwright `Page` that {@link signInWithKeycloak} uses. */
|
|
41
|
+
export interface KeycloakLoginPage {
|
|
42
|
+
waitForURL(url: (url: URL) => boolean, options?: {
|
|
43
|
+
timeout?: number;
|
|
44
|
+
}): Promise<unknown>;
|
|
45
|
+
locator(selector: string): {
|
|
46
|
+
fill(value: string): Promise<unknown>;
|
|
47
|
+
click(): Promise<unknown>;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export interface KeycloakSignInOptions {
|
|
51
|
+
/** How long to wait for the login page. Defaults to the page's own timeout. */
|
|
52
|
+
readonly timeoutMs?: number;
|
|
53
|
+
}
|
|
54
|
+
export declare const DEFAULT_KEYCLOAK_REQUEST_TIMEOUT_MS = 30000;
|
|
55
|
+
/** Returns the stack from `E2E_KEYCLOAK_*` variables, falling back to the defaults. */
|
|
56
|
+
export declare function keycloakStack(defaults: KeycloakStackDefaults, environment?: NodeJS.ProcessEnv): KeycloakStack;
|
|
57
|
+
/** Creates a verified user with a password in the stack's realm. */
|
|
58
|
+
export declare function createKeycloakTestUser(stack: KeycloakStack, user?: KeycloakTestUserOptions, options?: KeycloakRequestOptions): Promise<KeycloakTestUser>;
|
|
59
|
+
/** Ends every Keycloak session of the user, so the next token refresh fails. */
|
|
60
|
+
export declare function revokeKeycloakUserSessions(stack: KeycloakStack, subject: string, options?: KeycloakRequestOptions): Promise<void>;
|
|
61
|
+
/** Adds the origin to the web client's redirect URIs and web origins when the client lacks it. */
|
|
62
|
+
export declare function allowKeycloakWebOrigin(stack: KeycloakStack, origin: string, options?: KeycloakRequestOptions): Promise<void>;
|
|
63
|
+
/** Waits for the Keycloak login page, fills it by its stable `keycloak.v2` IDs, and submits. */
|
|
64
|
+
export declare function signInWithKeycloak(loginPage: KeycloakLoginPage, user: Pick<KeycloakTestUser, 'username' | 'password'>, stack: KeycloakStack, options?: KeycloakSignInOptions): Promise<void>;
|
|
65
|
+
//# sourceMappingURL=keycloak-testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keycloak-testing.d.ts","sourceRoot":"","sources":["../src/keycloak-testing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
export const DEFAULT_KEYCLOAK_REQUEST_TIMEOUT_MS = 30_000;
|
|
3
|
+
const HTTP_CREATED = 201;
|
|
4
|
+
const DEFAULT_ADMIN = 'admin';
|
|
5
|
+
/** Returns the stack from `E2E_KEYCLOAK_*` variables, falling back to the defaults. */
|
|
6
|
+
export function keycloakStack(defaults, environment = process.env) {
|
|
7
|
+
const url = environment['E2E_KEYCLOAK_URL'] ?? defaults.url;
|
|
8
|
+
return {
|
|
9
|
+
url: url.replace(/\/+$/u, ''),
|
|
10
|
+
realm: environment['E2E_KEYCLOAK_REALM'] ?? defaults.realm,
|
|
11
|
+
adminUsername: environment['E2E_KEYCLOAK_ADMIN_USERNAME'] ?? defaults.adminUsername ?? DEFAULT_ADMIN,
|
|
12
|
+
adminPassword: environment['E2E_KEYCLOAK_ADMIN_PASSWORD'] ?? defaults.adminPassword ?? DEFAULT_ADMIN,
|
|
13
|
+
webClientId: environment['E2E_KEYCLOAK_WEB_CLIENT_ID'] ?? defaults.webClientId,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/** Creates a verified user with a password in the stack's realm. */
|
|
17
|
+
export async function createKeycloakTestUser(stack, user = {}, options = {}) {
|
|
18
|
+
const username = user.username ?? `e2e-${randomUUID()}`;
|
|
19
|
+
const password = user.password ?? `E2e-${randomUUID()}`;
|
|
20
|
+
const email = user.email ?? `${username}@example.test`;
|
|
21
|
+
const admin = await adminRequester(stack, options);
|
|
22
|
+
const response = await admin('users', {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
body: {
|
|
25
|
+
username,
|
|
26
|
+
email,
|
|
27
|
+
emailVerified: true,
|
|
28
|
+
enabled: true,
|
|
29
|
+
firstName: 'E2E',
|
|
30
|
+
lastName: 'User',
|
|
31
|
+
credentials: [{ type: 'password', value: password, temporary: false }],
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
if (response.status !== HTTP_CREATED) {
|
|
35
|
+
throw new Error(`Keycloak user creation failed with HTTP ${String(response.status)}.`);
|
|
36
|
+
}
|
|
37
|
+
const subject = response.headers.get('location')?.match(/\/([^/]+)$/u)?.[1];
|
|
38
|
+
if (subject === undefined) {
|
|
39
|
+
throw new Error('Keycloak user creation returned no user location.');
|
|
40
|
+
}
|
|
41
|
+
return { username, password, email, subject: decodeURIComponent(subject) };
|
|
42
|
+
}
|
|
43
|
+
/** Ends every Keycloak session of the user, so the next token refresh fails. */
|
|
44
|
+
export async function revokeKeycloakUserSessions(stack, subject, options = {}) {
|
|
45
|
+
const admin = await adminRequester(stack, options);
|
|
46
|
+
const response = await admin(`users/${encodeURIComponent(subject)}/logout`, { method: 'POST' });
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
throw new Error(`Keycloak session revocation failed with HTTP ${String(response.status)}.`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Adds the origin to the web client's redirect URIs and web origins when the client lacks it. */
|
|
52
|
+
export async function allowKeycloakWebOrigin(stack, origin, options = {}) {
|
|
53
|
+
const admin = await adminRequester(stack, options);
|
|
54
|
+
const lookup = await admin(`clients?clientId=${encodeURIComponent(stack.webClientId)}`);
|
|
55
|
+
if (!lookup.ok) {
|
|
56
|
+
throw new Error(`Keycloak client lookup failed with HTTP ${String(lookup.status)}.`);
|
|
57
|
+
}
|
|
58
|
+
const [client] = (await lookup.json());
|
|
59
|
+
if (client === undefined) {
|
|
60
|
+
throw new Error(`Keycloak realm ${stack.realm} has no ${stack.webClientId} client.`);
|
|
61
|
+
}
|
|
62
|
+
const redirectUri = `${origin}/*`;
|
|
63
|
+
if (client.redirectUris?.includes(redirectUri) && client.webOrigins?.includes(origin)) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const update = await admin(`clients/${encodeURIComponent(client.id)}`, {
|
|
67
|
+
method: 'PUT',
|
|
68
|
+
body: {
|
|
69
|
+
...client,
|
|
70
|
+
redirectUris: withEntry(client.redirectUris, redirectUri),
|
|
71
|
+
webOrigins: withEntry(client.webOrigins, origin),
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
if (!update.ok) {
|
|
75
|
+
throw new Error(`Keycloak client update failed with HTTP ${String(update.status)}.`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Waits for the Keycloak login page, fills it by its stable `keycloak.v2` IDs, and submits. */
|
|
79
|
+
export async function signInWithKeycloak(loginPage, user, stack, options = {}) {
|
|
80
|
+
const origin = new URL(stack.url).origin;
|
|
81
|
+
const isKeycloak = (url) => url.origin === origin;
|
|
82
|
+
await (options.timeoutMs === undefined
|
|
83
|
+
? loginPage.waitForURL(isKeycloak)
|
|
84
|
+
: loginPage.waitForURL(isKeycloak, { timeout: options.timeoutMs }));
|
|
85
|
+
await loginPage.locator('#username').fill(user.username);
|
|
86
|
+
await loginPage.locator('#password').fill(user.password);
|
|
87
|
+
await loginPage.locator('#kc-login').click();
|
|
88
|
+
}
|
|
89
|
+
async function adminRequester(stack, options) {
|
|
90
|
+
const fetcher = options.fetch ?? fetch;
|
|
91
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_KEYCLOAK_REQUEST_TIMEOUT_MS;
|
|
92
|
+
const token = await adminAccessToken(stack, fetcher, timeoutMs);
|
|
93
|
+
const realmUrl = `${stack.url}/admin/realms/${encodeURIComponent(stack.realm)}`;
|
|
94
|
+
return (path, request = {}) => fetcher(`${realmUrl}/${path}`, {
|
|
95
|
+
method: request.method ?? 'GET',
|
|
96
|
+
headers: {
|
|
97
|
+
authorization: `Bearer ${token}`,
|
|
98
|
+
...(request.body === undefined ? {} : { 'content-type': 'application/json' }),
|
|
99
|
+
},
|
|
100
|
+
...(request.body === undefined ? {} : { body: JSON.stringify(request.body) }),
|
|
101
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async function adminAccessToken(stack, fetcher, timeoutMs) {
|
|
105
|
+
const response = await fetcher(`${stack.url}/realms/master/protocol/openid-connect/token`, {
|
|
106
|
+
method: 'POST',
|
|
107
|
+
headers: { 'content-type': 'application/x-www-form-urlencoded' },
|
|
108
|
+
body: new URLSearchParams({
|
|
109
|
+
client_id: 'admin-cli',
|
|
110
|
+
grant_type: 'password',
|
|
111
|
+
username: stack.adminUsername,
|
|
112
|
+
password: stack.adminPassword,
|
|
113
|
+
}),
|
|
114
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
115
|
+
});
|
|
116
|
+
if (!response.ok) {
|
|
117
|
+
throw new Error(`Keycloak admin sign-in failed with HTTP ${String(response.status)}.`);
|
|
118
|
+
}
|
|
119
|
+
const body = (await response.json());
|
|
120
|
+
if (typeof body.access_token !== 'string') {
|
|
121
|
+
throw new Error('Keycloak admin sign-in returned no access token.');
|
|
122
|
+
}
|
|
123
|
+
return body.access_token;
|
|
124
|
+
}
|
|
125
|
+
function withEntry(entries, entry) {
|
|
126
|
+
const current = entries ?? [];
|
|
127
|
+
return current.includes(entry) ? [...current] : [...current, entry];
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=keycloak-testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keycloak-testing.js","sourceRoot":"","sources":["../src/keycloak-testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA4DzC,MAAM,CAAC,MAAM,mCAAmC,GAAG,MAAM,CAAC;AAE1D,MAAM,YAAY,GAAG,GAAG,CAAC;AACzB,MAAM,aAAa,GAAG,OAAO,CAAC;AAE9B,uFAAuF;AACvF,MAAM,UAAU,aAAa,CAC3B,QAA+B,EAC/B,cAAiC,OAAO,CAAC,GAAG;IAE5C,MAAM,GAAG,GAAG,WAAW,CAAC,kBAAkB,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC;IAC5D,OAAO;QACL,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QAC7B,KAAK,EAAE,WAAW,CAAC,oBAAoB,CAAC,IAAI,QAAQ,CAAC,KAAK;QAC1D,aAAa,EACX,WAAW,CAAC,6BAA6B,CAAC,IAAI,QAAQ,CAAC,aAAa,IAAI,aAAa;QACvF,aAAa,EACX,WAAW,CAAC,6BAA6B,CAAC,IAAI,QAAQ,CAAC,aAAa,IAAI,aAAa;QACvF,WAAW,EAAE,WAAW,CAAC,4BAA4B,CAAC,IAAI,QAAQ,CAAC,WAAW;KAC/E,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAoB,EACpB,OAAgC,EAAE,EAClC,UAAkC,EAAE;IAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,UAAU,EAAE,EAAE,CAAC;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,UAAU,EAAE,EAAE,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,QAAQ,eAAe,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE;QACpC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;YACJ,QAAQ;YACR,KAAK;YACL,aAAa,EAAE,IAAI;YACnB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,KAAK;YAChB,QAAQ,EAAE,MAAM;YAChB,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;SACvE;KACF,CAAC,CAAC;IACH,IAAI,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,2CAA2C,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzF,CAAC;IACD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5E,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,KAAoB,EACpB,OAAe,EACf,UAAkC,EAAE;IAEpC,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,kBAAkB,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAChG,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,gDAAgD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9F,CAAC;AACH,CAAC;AAQD,kGAAkG;AAClG,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAoB,EACpB,MAAc,EACd,UAAkC,EAAE;IAEpC,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,oBAAoB,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACxF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,2CAA2C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAA0D,CAAC;IAChG,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,CAAC,KAAK,WAAW,KAAK,CAAC,WAAW,UAAU,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,WAAW,GAAG,GAAG,MAAM,IAAI,CAAC;IAClC,IAAI,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtF,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE;QACrE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE;YACJ,GAAG,MAAM;YACT,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC;YACzD,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC;SACjD;KACF,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,2CAA2C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvF,CAAC;AACH,CAAC;AAED,gGAAgG;AAChG,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAA4B,EAC5B,IAAqD,EACrD,KAAoB,EACpB,UAAiC,EAAE;IAEnC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,MAAM,UAAU,GAAG,CAAC,GAAQ,EAAW,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC;IAChE,MAAM,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS;QACpC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC;QAClC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC;AAC/C,CAAC;AASD,KAAK,UAAU,cAAc,CAC3B,KAAoB,EACpB,OAA+B;IAE/B,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;IACvC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,mCAAmC,CAAC;IAC3E,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,GAAG,iBAAiB,kBAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;IAChF,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,EAAE,EAAE,EAAE,CAC5B,OAAO,CAAC,GAAG,QAAQ,IAAI,IAAI,EAAE,EAAE;QAC7B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;QAC/B,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;SAC9E;QACD,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7E,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC;KACvC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,KAAoB,EACpB,OAAqB,EACrB,SAAiB;IAEjB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,KAAK,CAAC,GAAG,8CAA8C,EAAE;QACzF,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI,EAAE,IAAI,eAAe,CAAC;YACxB,SAAS,EAAE,WAAW;YACtB,UAAU,EAAE,UAAU;YACtB,QAAQ,EAAE,KAAK,CAAC,aAAa;YAC7B,QAAQ,EAAE,KAAK,CAAC,aAAa;SAC9B,CAAC;QACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC;KACvC,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,2CAA2C,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzF,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwC,CAAC;IAC5E,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,IAAI,CAAC,YAAY,CAAC;AAC3B,CAAC;AAED,SAAS,SAAS,CAAC,OAAsC,EAAE,KAAa;IACtE,MAAM,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;IAC9B,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,CAAC;AACtE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@baukit/auth-node",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Node OIDC device authorization with S256 PKCE, refresh rotation, and a locked token cache.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Patrick Koss",
|
|
@@ -31,6 +31,11 @@
|
|
|
31
31
|
"types": "./dist/device-flow.d.ts",
|
|
32
32
|
"import": "./dist/device-flow.js",
|
|
33
33
|
"default": "./dist/device-flow.js"
|
|
34
|
+
},
|
|
35
|
+
"./keycloak-testing": {
|
|
36
|
+
"types": "./dist/keycloak-testing.d.ts",
|
|
37
|
+
"import": "./dist/keycloak-testing.js",
|
|
38
|
+
"default": "./dist/keycloak-testing.js"
|
|
34
39
|
}
|
|
35
40
|
},
|
|
36
41
|
"files": [
|