@keycloak/keycloak-admin-client 26.4.7 → 26.5.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/README.md CHANGED
@@ -110,13 +110,19 @@ To build the source do a build:
110
110
  pnpm build
111
111
  ```
112
112
 
113
- Start the Keycloak server:
113
+ Start the Keycloak server in development mode using port 8180. See the instructions in the [Keycloak server app](../../apps/keycloak-server/README.md).
114
114
 
115
115
  ```bash
116
- pnpm server:start
116
+ cd ../../apps/keycloak-server
117
+ pnpm start --http-port 8180
118
+ ```
119
+
120
+ If you started your container manually make sure there is an admin user named `admin` with password `admin`, the server is started in development mode using port 8180 and the required features are enabled.
121
+
122
+ ```bash
123
+ ./kc.sh start-dev --http-port 8180 --features transient-users,oid4vc-vci,declarative-ui,quick-theme,spiffe,kubernetes-service-accounts,workflows,client-auth-federated,jwt-authorization-grant
117
124
  ```
118
125
 
119
- If you started your container manually make sure there is an admin user named 'admin' with password 'admin'.
120
126
  Then start the tests with:
121
127
 
122
128
  ```bash
package/lib/client.d.ts CHANGED
@@ -17,14 +17,16 @@ import { Users } from "./resources/users.js";
17
17
  import { UserStorageProvider } from "./resources/userStorageProvider.js";
18
18
  import { WhoAmI } from "./resources/whoAmI.js";
19
19
  import { Credentials } from "./utils/auth.js";
20
+ export type RequestOptions = Omit<RequestInit, "signal">;
20
21
  export interface TokenProvider {
21
22
  getAccessToken: () => Promise<string | undefined>;
22
23
  }
23
24
  export interface ConnectionConfig {
24
25
  baseUrl?: string;
25
26
  realmName?: string;
26
- requestOptions?: RequestInit;
27
+ requestOptions?: RequestOptions;
27
28
  requestArgOptions?: Pick<RequestArgs, "catchNotFound">;
29
+ timeout?: number;
28
30
  }
29
31
  export declare class KeycloakAdminClient {
30
32
  #private;
@@ -50,12 +52,13 @@ export declare class KeycloakAdminClient {
50
52
  scope?: string;
51
53
  accessToken?: string;
52
54
  refreshToken?: string;
55
+ timeout?: number;
53
56
  constructor(connectionConfig?: ConnectionConfig);
54
57
  auth(credentials: Credentials): Promise<void>;
55
58
  registerTokenProvider(provider: TokenProvider): void;
56
59
  setAccessToken(token: string): void;
57
60
  getAccessToken(): Promise<string | undefined>;
58
- getRequestOptions(): RequestInit | undefined;
61
+ getRequestOptions(): RequestOptions | undefined;
59
62
  getGlobalRequestArgOptions(): Pick<RequestArgs, "catchNotFound"> | undefined;
60
63
  setConfig(connectionConfig: ConnectionConfig): void;
61
64
  }
package/lib/client.js CHANGED
@@ -42,12 +42,14 @@ export class KeycloakAdminClient {
42
42
  scope;
43
43
  accessToken;
44
44
  refreshToken;
45
+ timeout;
45
46
  #requestOptions;
46
47
  #globalRequestArgOptions;
47
48
  #tokenProvider;
48
49
  constructor(connectionConfig) {
49
50
  this.baseUrl = connectionConfig?.baseUrl || defaultBaseUrl;
50
51
  this.realmName = connectionConfig?.realmName || defaultRealm;
52
+ this.timeout = connectionConfig?.timeout;
51
53
  this.#requestOptions = connectionConfig?.requestOptions;
52
54
  this.#globalRequestArgOptions = connectionConfig?.requestArgOptions;
53
55
  // Initialize resources
@@ -75,7 +77,10 @@ export class KeycloakAdminClient {
75
77
  realmName: this.realmName,
76
78
  scope: this.scope,
77
79
  credentials,
78
- requestOptions: this.#requestOptions,
80
+ requestOptions: {
81
+ ...this.#requestOptions,
82
+ ...(this.timeout ? { signal: AbortSignal.timeout(this.timeout) } : {}),
83
+ },
79
84
  });
80
85
  this.accessToken = accessToken;
81
86
  this.refreshToken = refreshToken;
@@ -6,4 +6,5 @@ export default interface CertificateRepresentation {
6
6
  publicKey?: string;
7
7
  certificate?: string;
8
8
  kid?: string;
9
+ jwks?: string;
9
10
  }
@@ -1,6 +1,13 @@
1
1
  /**
2
2
  * https://www.keycloak.org/docs-api/11.0/rest-api/index.html#_identityproviderrepresentation
3
3
  */
4
+ export declare enum IdentityProviderType {
5
+ ANY = "ANY",
6
+ USER_AUTHENTICATION = "USER_AUTHENTICATION",
7
+ CLIENT_ASSERTION = "CLIENT_ASSERTION",
8
+ EXCHANGE_EXTERNAL_TOKEN = "EXCHANGE_EXTERNAL_TOKEN",
9
+ JWT_AUTHORIZATION_GRANT = "JWT_AUTHORIZATION_GRANT"
10
+ }
4
11
  export default interface IdentityProviderRepresentation {
5
12
  addReadTokenRoleOnCreate?: boolean;
6
13
  alias?: string;
@@ -16,4 +23,5 @@ export default interface IdentityProviderRepresentation {
16
23
  storeToken?: boolean;
17
24
  trustEmail?: boolean;
18
25
  organizationId?: string;
26
+ types?: string[];
19
27
  }
@@ -1,4 +1,11 @@
1
1
  /**
2
2
  * https://www.keycloak.org/docs-api/11.0/rest-api/index.html#_identityproviderrepresentation
3
3
  */
4
- export {};
4
+ export var IdentityProviderType;
5
+ (function (IdentityProviderType) {
6
+ IdentityProviderType["ANY"] = "ANY";
7
+ IdentityProviderType["USER_AUTHENTICATION"] = "USER_AUTHENTICATION";
8
+ IdentityProviderType["CLIENT_ASSERTION"] = "CLIENT_ASSERTION";
9
+ IdentityProviderType["EXCHANGE_EXTERNAL_TOKEN"] = "EXCHANGE_EXTERNAL_TOKEN";
10
+ IdentityProviderType["JWT_AUTHORIZATION_GRANT"] = "JWT_AUTHORIZATION_GRANT";
11
+ })(IdentityProviderType || (IdentityProviderType = {}));
@@ -0,0 +1,15 @@
1
+ export declare enum OrganizationInvitationStatus {
2
+ PENDING = "PENDING",
3
+ EXPIRED = "EXPIRED"
4
+ }
5
+ export default interface OrganizationInvitationRepresentation {
6
+ id?: string;
7
+ email?: string;
8
+ organizationId?: string;
9
+ firstName?: string;
10
+ lastName?: string;
11
+ sentDate?: number;
12
+ expiresAt?: number;
13
+ status?: OrganizationInvitationStatus;
14
+ inviteLink?: string;
15
+ }
@@ -0,0 +1,5 @@
1
+ export var OrganizationInvitationStatus;
2
+ (function (OrganizationInvitationStatus) {
3
+ OrganizationInvitationStatus["PENDING"] = "PENDING";
4
+ OrganizationInvitationStatus["EXPIRED"] = "EXPIRED";
5
+ })(OrganizationInvitationStatus || (OrganizationInvitationStatus = {}));
package/lib/index.d.ts CHANGED
@@ -4,3 +4,5 @@ export declare const requiredAction: typeof RequiredActionAlias;
4
4
  export default KeycloakAdminClient;
5
5
  export { NetworkError, fetchWithError } from "./utils/fetchWithError.js";
6
6
  export type { NetworkErrorOptions } from "./utils/fetchWithError.js";
7
+ export type { default as OrganizationInvitationRepresentation } from "./defs/organizationInvitationRepresentation.js";
8
+ export { OrganizationInvitationStatus } from "./defs/organizationInvitationRepresentation.js";
package/lib/index.js CHANGED
@@ -3,3 +3,4 @@ import { RequiredActionAlias } from "./defs/requiredActionProviderRepresentation
3
3
  export const requiredAction = RequiredActionAlias;
4
4
  export default KeycloakAdminClient;
5
5
  export { NetworkError, fetchWithError } from "./utils/fetchWithError.js";
6
+ export { OrganizationInvitationStatus } from "./defs/organizationInvitationRepresentation.js";
@@ -128,6 +128,9 @@ export class Agent {
128
128
  ...requestOptions,
129
129
  headers: requestHeaders,
130
130
  method,
131
+ ...(this.#client.timeout
132
+ ? { signal: AbortSignal.timeout(this.#client.timeout) }
133
+ : {}),
131
134
  });
132
135
  // now we get the response of the http request
133
136
  // if `resourceIdInLocationHeader` is true, we'll get the resourceId from the location header field
@@ -3,6 +3,7 @@ import type IdentityProviderMapperRepresentation from "../defs/identityProviderM
3
3
  import type { IdentityProviderMapperTypeRepresentation } from "../defs/identityProviderMapperTypeRepresentation.js";
4
4
  import type IdentityProviderRepresentation from "../defs/identityProviderRepresentation.js";
5
5
  import type { ManagementPermissionReference } from "../defs/managementPermissionReference.js";
6
+ import type CertificateRepresentation from "../defs/certificateRepresentation.js";
6
7
  import Resource from "./resource.js";
7
8
  export interface PaginatedQuery {
8
9
  first?: number;
@@ -11,6 +12,8 @@ export interface PaginatedQuery {
11
12
  export interface IdentityProvidersQuery extends PaginatedQuery {
12
13
  search?: string;
13
14
  realmOnly?: boolean;
15
+ type?: string;
16
+ capability?: string;
14
17
  }
15
18
  export declare class IdentityProviders extends Resource<{
16
19
  realm?: string;
@@ -32,6 +35,9 @@ export declare class IdentityProviders extends Resource<{
32
35
  } & {
33
36
  realm?: string;
34
37
  }) | undefined, options?: Pick<import("./agent.js").RequestArgs, "catchNotFound">) => Promise<IdentityProviderRepresentation | undefined>;
38
+ uploadCertificate: (query: {
39
+ realm?: string;
40
+ }, payload: FormData) => Promise<CertificateRepresentation>;
35
41
  update: (query: {
36
42
  alias: string;
37
43
  } & {
@@ -19,6 +19,10 @@ export class IdentityProviders extends Resource {
19
19
  urlParamKeys: ["alias"],
20
20
  catchNotFound: true,
21
21
  });
22
+ uploadCertificate = this.makeUpdateRequest({
23
+ method: "POST",
24
+ path: "/upload-certificate",
25
+ });
22
26
  update = this.makeUpdateRequest({
23
27
  method: "PUT",
24
28
  path: "/instances/{alias}",
@@ -1,6 +1,7 @@
1
1
  import type { KeycloakAdminClient } from "../client.js";
2
2
  import IdentityProviderRepresentation from "../defs/identityProviderRepresentation.js";
3
3
  import type OrganizationRepresentation from "../defs/organizationRepresentation.js";
4
+ import type OrganizationInvitationRepresentation from "../defs/organizationInvitationRepresentation.js";
4
5
  import UserRepresentation from "../defs/userRepresentation.js";
5
6
  import Resource from "./resource.js";
6
7
  interface PaginatedQuery {
@@ -16,6 +17,14 @@ interface MemberQuery extends PaginatedQuery {
16
17
  orgId: string;
17
18
  membershipType?: string;
18
19
  }
20
+ interface InvitationQuery extends PaginatedQuery {
21
+ orgId: string;
22
+ status?: string;
23
+ email?: string;
24
+ search?: string;
25
+ firstName?: string;
26
+ lastName?: string;
27
+ }
19
28
  export declare class Organizations extends Resource<{
20
29
  realm?: string;
21
30
  }> {
@@ -93,5 +102,26 @@ export declare class Organizations extends Resource<{
93
102
  } & {
94
103
  realm?: string;
95
104
  }) | undefined, options?: Pick<import("./agent.js").RequestArgs, "catchNotFound">) => Promise<string>;
105
+ listInvitations: (payload?: (InvitationQuery & {
106
+ realm?: string;
107
+ }) | undefined, options?: Pick<import("./agent.js").RequestArgs, "catchNotFound">) => Promise<OrganizationInvitationRepresentation[]>;
108
+ findInvitation: (payload?: ({
109
+ orgId: string;
110
+ invitationId: string;
111
+ } & {
112
+ realm?: string;
113
+ }) | undefined, options?: Pick<import("./agent.js").RequestArgs, "catchNotFound">) => Promise<OrganizationInvitationRepresentation>;
114
+ resendInvitation: (payload?: ({
115
+ orgId: string;
116
+ invitationId: string;
117
+ } & {
118
+ realm?: string;
119
+ }) | undefined, options?: Pick<import("./agent.js").RequestArgs, "catchNotFound">) => Promise<void>;
120
+ deleteInvitation: (payload?: ({
121
+ orgId: string;
122
+ invitationId: string;
123
+ } & {
124
+ realm?: string;
125
+ }) | undefined, options?: Pick<import("./agent.js").RequestArgs, "catchNotFound">) => Promise<void>;
96
126
  }
97
127
  export {};
@@ -82,4 +82,25 @@ export class Organizations extends Resource {
82
82
  path: "/{orgId}/identity-providers/{alias}",
83
83
  urlParamKeys: ["orgId", "alias"],
84
84
  });
85
+ // Organization Invitations Management
86
+ listInvitations = this.makeRequest({
87
+ method: "GET",
88
+ path: "/{orgId}/invitations",
89
+ urlParamKeys: ["orgId"],
90
+ });
91
+ findInvitation = this.makeRequest({
92
+ method: "GET",
93
+ path: "/{orgId}/invitations/{invitationId}",
94
+ urlParamKeys: ["orgId", "invitationId"],
95
+ });
96
+ resendInvitation = this.makeRequest({
97
+ method: "POST",
98
+ path: "/{orgId}/invitations/{invitationId}/resend",
99
+ urlParamKeys: ["orgId", "invitationId"],
100
+ });
101
+ deleteInvitation = this.makeRequest({
102
+ method: "DELETE",
103
+ path: "/{orgId}/invitations/{invitationId}",
104
+ urlParamKeys: ["orgId", "invitationId"],
105
+ });
85
106
  }
@@ -6,11 +6,30 @@ export declare class Workflows extends Resource<{
6
6
  }> {
7
7
  constructor(client: KeycloakAdminClient);
8
8
  find: (payload?: any, options?: Pick<import("./agent.js").RequestArgs, "catchNotFound">) => Promise<any>;
9
+ findOne: (payload?: ({
10
+ id: string;
11
+ includeId: boolean;
12
+ } & {
13
+ realm?: string;
14
+ }) | undefined, options?: Pick<import("./agent.js").RequestArgs, "catchNotFound">) => Promise<WorkflowRepresentation | undefined>;
15
+ update: (query: {
16
+ id: string;
17
+ } & {
18
+ realm?: string;
19
+ }, payload: WorkflowRepresentation) => Promise<void>;
9
20
  create: (payload?: (WorkflowRepresentation & {
10
21
  realm?: string;
11
22
  }) | undefined, options?: Pick<import("./agent.js").RequestArgs, "catchNotFound">) => Promise<{
12
23
  id: string;
13
24
  }>;
25
+ createAsYaml: (payload?: ({
26
+ realm: string;
27
+ yaml: string;
28
+ } & {
29
+ realm?: string;
30
+ }) | undefined, options?: Pick<import("./agent.js").RequestArgs, "catchNotFound">) => Promise<{
31
+ id: string;
32
+ }>;
14
33
  delById: (payload?: ({
15
34
  id: string;
16
35
  } & {
@@ -13,9 +13,28 @@ export class Workflows extends Resource {
13
13
  method: "GET",
14
14
  path: "/",
15
15
  });
16
+ findOne = this.makeRequest({
17
+ method: "GET",
18
+ path: "/{id}",
19
+ urlParamKeys: ["id"],
20
+ queryParamKeys: ["includeId"],
21
+ catchNotFound: true,
22
+ });
23
+ update = this.makeUpdateRequest({
24
+ method: "PUT",
25
+ path: "/{id}",
26
+ urlParamKeys: ["id"],
27
+ });
16
28
  create = this.makeRequest({
17
29
  method: "POST",
30
+ headers: { "Content-Type": "application/json" },
31
+ returnResourceIdInLocationHeader: { field: "id" },
32
+ });
33
+ createAsYaml = this.makeRequest({
34
+ method: "POST",
35
+ headers: { "Content-Type": "application/yaml", Accept: "application/yaml" },
18
36
  returnResourceIdInLocationHeader: { field: "id" },
37
+ payloadKey: "yaml",
19
38
  });
20
39
  delById = this.makeRequest({
21
40
  method: "DELETE",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keycloak/keycloak-admin-client",
3
- "version": "26.4.7",
3
+ "version": "26.5.0",
4
4
  "description": "A client to interact with Keycloak's Administration API",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -37,14 +37,14 @@
37
37
  "url-template": "^3.1.1"
38
38
  },
39
39
  "devDependencies": {
40
- "@faker-js/faker": "^10.0.0",
40
+ "@faker-js/faker": "^10.2.0",
41
41
  "@types/chai": "^5.2.2",
42
42
  "@types/lodash-es": "^4.17.12",
43
43
  "@types/mocha": "^10.0.10",
44
- "@types/node": "^24.5.2",
45
- "chai": "^6.0.1",
46
- "lodash-es": "^4.17.21",
47
- "mocha": "^11.7.2",
44
+ "@types/node": "^24.9.1",
45
+ "chai": "^6.2.2",
46
+ "lodash-es": "^4.17.22",
47
+ "mocha": "^11.7.5",
48
48
  "ts-node": "^10.9.2"
49
49
  },
50
50
  "author": {