@adatechnology/keycloak-admin 0.1.1 → 0.1.3

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.
@@ -0,0 +1,91 @@
1
+ import { DynamicModule } from "@nestjs/common";
2
+
3
+ export interface KeycloakAdminConfig {
4
+ baseUrl: string;
5
+ realm: string;
6
+ adminUser: string;
7
+ adminPassword: string;
8
+ }
9
+
10
+ export interface GetAdminTokenResult {
11
+ accessToken: string;
12
+ expiresIn: number;
13
+ tokenType: string;
14
+ }
15
+
16
+ export interface UpdateUserParams {
17
+ userId: string;
18
+ userData: Record<string, unknown>;
19
+ adminToken: string;
20
+ }
21
+
22
+ export interface ResetPasswordParams {
23
+ userId: string;
24
+ password: string;
25
+ temporary: boolean;
26
+ adminToken: string;
27
+ }
28
+
29
+ export interface ToggleUserEnabledParams {
30
+ userId: string;
31
+ enabled: boolean;
32
+ adminToken: string;
33
+ }
34
+
35
+ export interface DeleteUserParams {
36
+ userId: string;
37
+ adminToken: string;
38
+ }
39
+
40
+ export interface UpdateUserAttributesParams {
41
+ userId: string;
42
+ attributes: Record<string, string | string[]>;
43
+ adminToken: string;
44
+ }
45
+
46
+ export interface SendVerifyEmailParams {
47
+ userId: string;
48
+ adminToken: string;
49
+ }
50
+
51
+ export interface KeycloakAdminClientInterface {
52
+ getAdminToken(): Promise<GetAdminTokenResult>;
53
+ updateUser(params: UpdateUserParams): Promise<void>;
54
+ resetPassword(params: ResetPasswordParams): Promise<void>;
55
+ toggleUserEnabled(params: ToggleUserEnabledParams): Promise<void>;
56
+ deleteUser(params: DeleteUserParams): Promise<void>;
57
+ updateUserAttributes(params: UpdateUserAttributesParams): Promise<void>;
58
+ sendVerifyEmail(params: SendVerifyEmailParams): Promise<void>;
59
+ }
60
+
61
+ export class KeycloakAdminError extends Error {
62
+ readonly statusCode?: number;
63
+ readonly code?: string;
64
+ readonly context?: Record<string, unknown>;
65
+ constructor(params: {
66
+ message: string;
67
+ statusCode?: number;
68
+ code?: string;
69
+ context?: Record<string, unknown>;
70
+ });
71
+ }
72
+
73
+ export class KeycloakAdminClient implements KeycloakAdminClientInterface {
74
+ getAdminToken(): Promise<GetAdminTokenResult>;
75
+ updateUser(params: UpdateUserParams): Promise<void>;
76
+ resetPassword(params: ResetPasswordParams): Promise<void>;
77
+ toggleUserEnabled(params: ToggleUserEnabledParams): Promise<void>;
78
+ deleteUser(params: DeleteUserParams): Promise<void>;
79
+ updateUserAttributes(params: UpdateUserAttributesParams): Promise<void>;
80
+ sendVerifyEmail(params: SendVerifyEmailParams): Promise<void>;
81
+ }
82
+
83
+ export class KeycloakAdminModule {
84
+ static forRoot(config: KeycloakAdminConfig): DynamicModule;
85
+ }
86
+
87
+ export function validateKeycloakAdminConfig(config: KeycloakAdminConfig): void;
88
+
89
+ export const KEYCLOAK_ADMIN_CLIENT = "KEYCLOAK_ADMIN_CLIENT";
90
+ export const KEYCLOAK_ADMIN_CONFIG = "KEYCLOAK_ADMIN_CONFIG";
91
+ export const KEYCLOAK_ADMIN_PROVIDER = "KEYCLOAK_ADMIN_PROVIDER";
package/dist/index.js ADDED
@@ -0,0 +1,601 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ KEYCLOAK_ADMIN_CLIENT: () => KEYCLOAK_ADMIN_CLIENT,
24
+ KEYCLOAK_ADMIN_CONFIG: () => KEYCLOAK_ADMIN_CONFIG,
25
+ KEYCLOAK_ADMIN_PROVIDER: () => KEYCLOAK_ADMIN_PROVIDER,
26
+ KeycloakAdminClient: () => KeycloakAdminClient,
27
+ KeycloakAdminError: () => KeycloakAdminError,
28
+ KeycloakAdminModule: () => KeycloakAdminModule,
29
+ validateKeycloakAdminConfig: () => validateKeycloakAdminConfig
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+
33
+ // src/keycloak-admin.module.ts
34
+ var import_common2 = require("@nestjs/common");
35
+ var import_http_client2 = require("@adatechnology/http-client");
36
+
37
+ // src/keycloak-admin.token.ts
38
+ var KEYCLOAK_ADMIN_CLIENT = "KEYCLOAK_ADMIN_CLIENT";
39
+ var KEYCLOAK_ADMIN_CONFIG = "KEYCLOAK_ADMIN_CONFIG";
40
+ var KEYCLOAK_ADMIN_PROVIDER = "KEYCLOAK_ADMIN_PROVIDER";
41
+
42
+ // src/keycloak-admin.client.ts
43
+ var import_common = require("@nestjs/common");
44
+ var import_http_client = require("@adatechnology/http-client");
45
+ var import_logger = require("@adatechnology/logger");
46
+
47
+ // src/errors/keycloak-admin.error.ts
48
+ var _KeycloakAdminError = class _KeycloakAdminError extends Error {
49
+ statusCode;
50
+ code;
51
+ context;
52
+ constructor(params) {
53
+ super(params.message);
54
+ this.name = "KeycloakAdminError";
55
+ this.statusCode = params.statusCode;
56
+ this.code = params.code;
57
+ this.context = params.context;
58
+ Object.setPrototypeOf(this, _KeycloakAdminError.prototype);
59
+ }
60
+ };
61
+ __name(_KeycloakAdminError, "KeycloakAdminError");
62
+ var KeycloakAdminError = _KeycloakAdminError;
63
+
64
+ // src/constants/keycloak-admin.constants.ts
65
+ var KEYCLOAK_ADMIN_LIB_NAME = "@adatechnology/keycloak-admin";
66
+ var KEYCLOAK_ADMIN_LIB_VERSION = "0.1.2";
67
+ var KEYCLOAK_ADMIN_GRANT_TYPE_PASSWORD = "password";
68
+ var KEYCLOAK_ADMIN_CLIENT_ID_ADMIN_CLI = "admin-cli";
69
+ var KEYCLOAK_ADMIN_CONTENT_TYPE_FORM = "application/x-www-form-urlencoded";
70
+ var KEYCLOAK_ADMIN_CONTENT_TYPE_JSON = "application/json";
71
+ var KEYCLOAK_ADMIN_AUTHORIZATION_HEADER = "Authorization";
72
+ var KEYCLOAK_ADMIN_BEARER_PREFIX = "Bearer ";
73
+ var KEYCLOAK_ADMIN_ENDPOINTS = {
74
+ MASTER_TOKEN: "/realms/master/protocol/openid-connect/token",
75
+ ADMIN_USERS: /* @__PURE__ */ __name((baseUrl, realm, userId) => `${baseUrl}/admin/realms/${realm}/users/${userId}`, "ADMIN_USERS"),
76
+ ADMIN_RESET_PASSWORD: /* @__PURE__ */ __name((baseUrl, realm, userId) => `${baseUrl}/admin/realms/${realm}/users/${userId}/reset-password`, "ADMIN_RESET_PASSWORD"),
77
+ ADMIN_SEND_VERIFY_EMAIL: /* @__PURE__ */ __name((baseUrl, realm, userId) => `${baseUrl}/admin/realms/${realm}/users/${userId}/send-verify-email`, "ADMIN_SEND_VERIFY_EMAIL")
78
+ };
79
+ var KEYCLOAK_ADMIN_ERROR_CODES = {
80
+ ADMIN_TOKEN_ERROR: "KEYCLOAK_ADMIN_TOKEN_ERROR",
81
+ UPDATE_USER_ERROR: "KEYCLOAK_UPDATE_USER_ERROR",
82
+ RESET_PASSWORD_ERROR: "KEYCLOAK_RESET_PASSWORD_ERROR",
83
+ TOGGLE_ENABLED_ERROR: "KEYCLOAK_TOGGLE_ENABLED_ERROR",
84
+ DELETE_USER_ERROR: "KEYCLOAK_DELETE_USER_ERROR",
85
+ UPDATE_ATTRIBUTES_ERROR: "KEYCLOAK_UPDATE_ATTRIBUTES_ERROR",
86
+ SEND_VERIFY_EMAIL_ERROR: "KEYCLOAK_SEND_VERIFY_EMAIL_ERROR"
87
+ };
88
+
89
+ // src/utils/extract-http-error.ts
90
+ function extractHttpError(err) {
91
+ const unknownErr = err;
92
+ const response = unknownErr == null ? void 0 : unknownErr.response;
93
+ const responseData = response == null ? void 0 : response.data;
94
+ let statusCode = void 0;
95
+ if (typeof (unknownErr == null ? void 0 : unknownErr.status) === "number") {
96
+ statusCode = unknownErr.status;
97
+ } else if (typeof (response == null ? void 0 : response.status) === "number") {
98
+ statusCode = response.status;
99
+ }
100
+ const details = responseData ?? (unknownErr == null ? void 0 : unknownErr.message);
101
+ const rawError = (responseData == null ? void 0 : responseData.error) ?? (responseData == null ? void 0 : responseData.errorMessage);
102
+ const errorCode = typeof rawError === "string" ? rawError : typeof (unknownErr == null ? void 0 : unknownErr.code) === "string" ? unknownErr.code : void 0;
103
+ return {
104
+ statusCode,
105
+ details,
106
+ errorCode
107
+ };
108
+ }
109
+ __name(extractHttpError, "extractHttpError");
110
+
111
+ // src/keycloak-admin.client.ts
112
+ function _ts_decorate(decorators, target, key, desc) {
113
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
114
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
115
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
116
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
117
+ }
118
+ __name(_ts_decorate, "_ts_decorate");
119
+ function _ts_metadata(k, v) {
120
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
121
+ }
122
+ __name(_ts_metadata, "_ts_metadata");
123
+ function _ts_param(paramIndex, decorator) {
124
+ return function(target, key) {
125
+ decorator(target, key, paramIndex);
126
+ };
127
+ }
128
+ __name(_ts_param, "_ts_param");
129
+ var _KeycloakAdminClient = class _KeycloakAdminClient {
130
+ config;
131
+ httpProvider;
132
+ logger;
133
+ className = this.constructor.name;
134
+ constructor(config, httpProvider, logger) {
135
+ this.config = config;
136
+ this.httpProvider = httpProvider;
137
+ this.logger = logger;
138
+ }
139
+ log(level, message, libMethod, meta) {
140
+ if (!this.logger) return;
141
+ const payload = {
142
+ message,
143
+ context: this.className,
144
+ lib: KEYCLOAK_ADMIN_LIB_NAME,
145
+ libVersion: KEYCLOAK_ADMIN_LIB_VERSION,
146
+ libMethod,
147
+ meta
148
+ };
149
+ if (level === "info") this.logger.info(payload);
150
+ else if (level === "warn") this.logger.warn(payload);
151
+ else if (level === "error") this.logger.error(payload);
152
+ }
153
+ async getAdminToken() {
154
+ const method = "getAdminToken";
155
+ this.log("info", `${method} - Start`, method, {
156
+ realm: this.config.realm
157
+ });
158
+ const url = `${this.config.baseUrl}${KEYCLOAK_ADMIN_ENDPOINTS.MASTER_TOKEN}`;
159
+ const body = new URLSearchParams();
160
+ body.append("grant_type", KEYCLOAK_ADMIN_GRANT_TYPE_PASSWORD);
161
+ body.append("client_id", KEYCLOAK_ADMIN_CLIENT_ID_ADMIN_CLI);
162
+ body.append("username", this.config.adminUser);
163
+ body.append("password", this.config.adminPassword);
164
+ try {
165
+ const response = await this.httpProvider.post({
166
+ url,
167
+ data: body,
168
+ config: {
169
+ headers: {
170
+ "Content-Type": KEYCLOAK_ADMIN_CONTENT_TYPE_FORM
171
+ }
172
+ }
173
+ });
174
+ const result = {
175
+ accessToken: response.data.access_token,
176
+ expiresIn: response.data.expires_in,
177
+ tokenType: response.data.token_type
178
+ };
179
+ this.log("info", `${method} - Success`, method);
180
+ return result;
181
+ } catch (err) {
182
+ const { statusCode, details, errorCode } = extractHttpError(err);
183
+ this.log("error", `${method} - Failed`, method, {
184
+ statusCode,
185
+ errorCode
186
+ });
187
+ throw new KeycloakAdminError({
188
+ message: "Keycloak admin token request failed",
189
+ statusCode: statusCode ?? 502,
190
+ code: KEYCLOAK_ADMIN_ERROR_CODES.ADMIN_TOKEN_ERROR,
191
+ context: {
192
+ url,
193
+ method: "POST",
194
+ details,
195
+ errorCode
196
+ }
197
+ });
198
+ }
199
+ }
200
+ async updateUser(params) {
201
+ const method = "updateUser";
202
+ const { userId, userData, adminToken } = params;
203
+ this.log("info", `${method} - Start`, method, {
204
+ userId
205
+ });
206
+ const url = KEYCLOAK_ADMIN_ENDPOINTS.ADMIN_USERS(this.config.baseUrl, this.config.realm, userId);
207
+ try {
208
+ await this.httpProvider.put({
209
+ url,
210
+ data: userData,
211
+ config: {
212
+ headers: {
213
+ [KEYCLOAK_ADMIN_AUTHORIZATION_HEADER]: `${KEYCLOAK_ADMIN_BEARER_PREFIX}${adminToken}`,
214
+ "Content-Type": KEYCLOAK_ADMIN_CONTENT_TYPE_JSON
215
+ }
216
+ }
217
+ });
218
+ this.log("info", `${method} - Success`, method, {
219
+ userId
220
+ });
221
+ } catch (err) {
222
+ const { statusCode, details, errorCode } = extractHttpError(err);
223
+ this.log("error", `${method} - Failed`, method, {
224
+ userId,
225
+ statusCode,
226
+ errorCode
227
+ });
228
+ throw new KeycloakAdminError({
229
+ message: "Keycloak update user failed",
230
+ statusCode: statusCode ?? 502,
231
+ code: KEYCLOAK_ADMIN_ERROR_CODES.UPDATE_USER_ERROR,
232
+ context: {
233
+ url,
234
+ method: "PUT",
235
+ userId,
236
+ details,
237
+ errorCode
238
+ }
239
+ });
240
+ }
241
+ }
242
+ async resetPassword(params) {
243
+ const method = "resetPassword";
244
+ const { userId, password, temporary, adminToken } = params;
245
+ this.log("info", `${method} - Start`, method, {
246
+ userId,
247
+ temporary
248
+ });
249
+ const url = KEYCLOAK_ADMIN_ENDPOINTS.ADMIN_RESET_PASSWORD(this.config.baseUrl, this.config.realm, userId);
250
+ try {
251
+ await this.httpProvider.put({
252
+ url,
253
+ data: {
254
+ type: "password",
255
+ value: password,
256
+ temporary
257
+ },
258
+ config: {
259
+ headers: {
260
+ [KEYCLOAK_ADMIN_AUTHORIZATION_HEADER]: `${KEYCLOAK_ADMIN_BEARER_PREFIX}${adminToken}`,
261
+ "Content-Type": KEYCLOAK_ADMIN_CONTENT_TYPE_JSON
262
+ }
263
+ }
264
+ });
265
+ this.log("info", `${method} - Success`, method, {
266
+ userId
267
+ });
268
+ } catch (err) {
269
+ const { statusCode, details, errorCode } = extractHttpError(err);
270
+ this.log("error", `${method} - Failed`, method, {
271
+ userId,
272
+ statusCode,
273
+ errorCode
274
+ });
275
+ throw new KeycloakAdminError({
276
+ message: "Keycloak reset password failed",
277
+ statusCode: statusCode ?? 502,
278
+ code: KEYCLOAK_ADMIN_ERROR_CODES.RESET_PASSWORD_ERROR,
279
+ context: {
280
+ url,
281
+ method: "PUT",
282
+ userId,
283
+ details,
284
+ errorCode
285
+ }
286
+ });
287
+ }
288
+ }
289
+ async toggleUserEnabled(params) {
290
+ const method = "toggleUserEnabled";
291
+ const { userId, enabled, adminToken } = params;
292
+ this.log("info", `${method} - Start`, method, {
293
+ userId,
294
+ enabled
295
+ });
296
+ const url = KEYCLOAK_ADMIN_ENDPOINTS.ADMIN_USERS(this.config.baseUrl, this.config.realm, userId);
297
+ try {
298
+ await this.httpProvider.put({
299
+ url,
300
+ data: {
301
+ enabled
302
+ },
303
+ config: {
304
+ headers: {
305
+ [KEYCLOAK_ADMIN_AUTHORIZATION_HEADER]: `${KEYCLOAK_ADMIN_BEARER_PREFIX}${adminToken}`,
306
+ "Content-Type": KEYCLOAK_ADMIN_CONTENT_TYPE_JSON
307
+ }
308
+ }
309
+ });
310
+ this.log("info", `${method} - Success`, method, {
311
+ userId,
312
+ enabled
313
+ });
314
+ } catch (err) {
315
+ const { statusCode, details, errorCode } = extractHttpError(err);
316
+ this.log("error", `${method} - Failed`, method, {
317
+ userId,
318
+ enabled,
319
+ statusCode,
320
+ errorCode
321
+ });
322
+ throw new KeycloakAdminError({
323
+ message: "Keycloak toggle user enabled failed",
324
+ statusCode: statusCode ?? 502,
325
+ code: KEYCLOAK_ADMIN_ERROR_CODES.TOGGLE_ENABLED_ERROR,
326
+ context: {
327
+ url,
328
+ method: "PUT",
329
+ userId,
330
+ enabled,
331
+ details,
332
+ errorCode
333
+ }
334
+ });
335
+ }
336
+ }
337
+ async deleteUser(params) {
338
+ const method = "deleteUser";
339
+ const { userId, adminToken } = params;
340
+ this.log("info", `${method} - Start`, method, {
341
+ userId
342
+ });
343
+ const url = KEYCLOAK_ADMIN_ENDPOINTS.ADMIN_USERS(this.config.baseUrl, this.config.realm, userId);
344
+ try {
345
+ await this.httpProvider.delete({
346
+ url,
347
+ config: {
348
+ headers: {
349
+ [KEYCLOAK_ADMIN_AUTHORIZATION_HEADER]: `${KEYCLOAK_ADMIN_BEARER_PREFIX}${adminToken}`
350
+ }
351
+ }
352
+ });
353
+ this.log("info", `${method} - Success`, method, {
354
+ userId
355
+ });
356
+ } catch (err) {
357
+ const { statusCode, details, errorCode } = extractHttpError(err);
358
+ this.log("error", `${method} - Failed`, method, {
359
+ userId,
360
+ statusCode,
361
+ errorCode
362
+ });
363
+ throw new KeycloakAdminError({
364
+ message: "Keycloak delete user failed",
365
+ statusCode: statusCode ?? 502,
366
+ code: KEYCLOAK_ADMIN_ERROR_CODES.DELETE_USER_ERROR,
367
+ context: {
368
+ url,
369
+ method: "DELETE",
370
+ userId,
371
+ details,
372
+ errorCode
373
+ }
374
+ });
375
+ }
376
+ }
377
+ async updateUserAttributes(params) {
378
+ const method = "updateUserAttributes";
379
+ const { userId, attributes, adminToken } = params;
380
+ this.log("info", `${method} - Start`, method, {
381
+ userId,
382
+ attributeKeys: Object.keys(attributes)
383
+ });
384
+ const url = KEYCLOAK_ADMIN_ENDPOINTS.ADMIN_USERS(this.config.baseUrl, this.config.realm, userId);
385
+ try {
386
+ await this.httpProvider.put({
387
+ url,
388
+ data: {
389
+ attributes
390
+ },
391
+ config: {
392
+ headers: {
393
+ [KEYCLOAK_ADMIN_AUTHORIZATION_HEADER]: `${KEYCLOAK_ADMIN_BEARER_PREFIX}${adminToken}`,
394
+ "Content-Type": KEYCLOAK_ADMIN_CONTENT_TYPE_JSON
395
+ }
396
+ }
397
+ });
398
+ this.log("info", `${method} - Success`, method, {
399
+ userId
400
+ });
401
+ } catch (err) {
402
+ const { statusCode, details, errorCode } = extractHttpError(err);
403
+ this.log("error", `${method} - Failed`, method, {
404
+ userId,
405
+ statusCode,
406
+ errorCode
407
+ });
408
+ throw new KeycloakAdminError({
409
+ message: "Keycloak update user attributes failed",
410
+ statusCode: statusCode ?? 502,
411
+ code: KEYCLOAK_ADMIN_ERROR_CODES.UPDATE_ATTRIBUTES_ERROR,
412
+ context: {
413
+ url,
414
+ method: "PUT",
415
+ userId,
416
+ details,
417
+ errorCode
418
+ }
419
+ });
420
+ }
421
+ }
422
+ async sendVerifyEmail(params) {
423
+ const method = "sendVerifyEmail";
424
+ const { userId, adminToken } = params;
425
+ this.log("info", `${method} - Start`, method, {
426
+ userId
427
+ });
428
+ const url = KEYCLOAK_ADMIN_ENDPOINTS.ADMIN_SEND_VERIFY_EMAIL(this.config.baseUrl, this.config.realm, userId);
429
+ try {
430
+ await this.httpProvider.put({
431
+ url,
432
+ data: {},
433
+ config: {
434
+ headers: {
435
+ [KEYCLOAK_ADMIN_AUTHORIZATION_HEADER]: `${KEYCLOAK_ADMIN_BEARER_PREFIX}${adminToken}`,
436
+ "Content-Type": KEYCLOAK_ADMIN_CONTENT_TYPE_JSON
437
+ }
438
+ }
439
+ });
440
+ this.log("info", `${method} - Success`, method, {
441
+ userId
442
+ });
443
+ } catch (err) {
444
+ const { statusCode, details, errorCode } = extractHttpError(err);
445
+ this.log("error", `${method} - Failed`, method, {
446
+ userId,
447
+ statusCode,
448
+ errorCode
449
+ });
450
+ throw new KeycloakAdminError({
451
+ message: "Keycloak send verify email failed",
452
+ statusCode: statusCode ?? 502,
453
+ code: KEYCLOAK_ADMIN_ERROR_CODES.SEND_VERIFY_EMAIL_ERROR,
454
+ context: {
455
+ url,
456
+ method: "PUT",
457
+ userId,
458
+ details,
459
+ errorCode
460
+ }
461
+ });
462
+ }
463
+ }
464
+ };
465
+ __name(_KeycloakAdminClient, "KeycloakAdminClient");
466
+ var KeycloakAdminClient = _KeycloakAdminClient;
467
+ KeycloakAdminClient = _ts_decorate([
468
+ (0, import_common.Injectable)(),
469
+ _ts_param(0, (0, import_common.Inject)(KEYCLOAK_ADMIN_CONFIG)),
470
+ _ts_param(1, (0, import_common.Inject)(import_http_client.HTTP_PROVIDER)),
471
+ _ts_param(2, (0, import_common.Optional)()),
472
+ _ts_param(2, (0, import_common.Inject)(import_logger.LOGGER_PROVIDER)),
473
+ _ts_metadata("design:type", Function),
474
+ _ts_metadata("design:paramtypes", [
475
+ typeof KeycloakAdminConfig === "undefined" ? Object : KeycloakAdminConfig,
476
+ typeof HttpProviderInterface === "undefined" ? Object : HttpProviderInterface,
477
+ typeof LoggerProviderInterface === "undefined" ? Object : LoggerProviderInterface
478
+ ])
479
+ ], KeycloakAdminClient);
480
+
481
+ // src/utils/validate-config.ts
482
+ function validateKeycloakAdminConfig(config) {
483
+ const issues = [];
484
+ if (!config) {
485
+ throw new KeycloakAdminError({
486
+ message: "KeycloakAdminConfig is required. Provide an object with baseUrl, realm, adminUser and adminPassword.",
487
+ statusCode: 400,
488
+ code: "KEYCLOAK_ADMIN_CONFIG_MISSING"
489
+ });
490
+ }
491
+ if (typeof config.baseUrl !== "string" || config.baseUrl.trim() === "") {
492
+ issues.push({
493
+ field: "baseUrl",
494
+ message: "baseUrl is required and must be a non-empty string (e.g. 'http://localhost:8081')"
495
+ });
496
+ } else if (!config.baseUrl.startsWith("http://") && !config.baseUrl.startsWith("https://")) {
497
+ issues.push({
498
+ field: "baseUrl",
499
+ message: `baseUrl must start with 'http://' or 'https://'. Received: '${config.baseUrl}'`
500
+ });
501
+ }
502
+ if (typeof config.realm !== "string" || config.realm.trim() === "") {
503
+ issues.push({
504
+ field: "realm",
505
+ message: "realm is required and must be a non-empty string (e.g. 'BACKEND')"
506
+ });
507
+ }
508
+ if (typeof config.adminUser !== "string" || config.adminUser.trim() === "") {
509
+ issues.push({
510
+ field: "adminUser",
511
+ message: "adminUser is required and must be a non-empty string"
512
+ });
513
+ }
514
+ if (typeof config.adminPassword !== "string" || config.adminPassword.trim() === "") {
515
+ issues.push({
516
+ field: "adminPassword",
517
+ message: "adminPassword is required and must be a non-empty string"
518
+ });
519
+ }
520
+ if (issues.length > 0) {
521
+ const summary = issues.map((i) => ` - ${i.field}: ${i.message}`).join("\n");
522
+ throw new KeycloakAdminError({
523
+ message: `KeycloakAdminConfig validation failed:
524
+ ${summary}`,
525
+ statusCode: 400,
526
+ code: "KEYCLOAK_ADMIN_CONFIG_INVALID",
527
+ context: {
528
+ issues
529
+ }
530
+ });
531
+ }
532
+ }
533
+ __name(validateKeycloakAdminConfig, "validateKeycloakAdminConfig");
534
+
535
+ // src/keycloak-admin.module.ts
536
+ function _ts_decorate2(decorators, target, key, desc) {
537
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
538
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
539
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
540
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
541
+ }
542
+ __name(_ts_decorate2, "_ts_decorate");
543
+ var _KeycloakAdminModule = class _KeycloakAdminModule {
544
+ static forRoot(config) {
545
+ validateKeycloakAdminConfig(config);
546
+ return {
547
+ module: _KeycloakAdminModule,
548
+ global: true,
549
+ imports: [
550
+ import_http_client2.HttpModule.forRoot({
551
+ baseURL: config.baseUrl,
552
+ timeout: 5e3
553
+ }, {
554
+ logging: {
555
+ enabled: true,
556
+ includeBody: true,
557
+ context: "KeycloakAdminHttpClient",
558
+ environments: [
559
+ "development",
560
+ "test"
561
+ ]
562
+ }
563
+ })
564
+ ],
565
+ providers: [
566
+ {
567
+ provide: KEYCLOAK_ADMIN_CONFIG,
568
+ useValue: config
569
+ },
570
+ {
571
+ provide: KEYCLOAK_ADMIN_CLIENT,
572
+ useClass: KeycloakAdminClient
573
+ },
574
+ {
575
+ provide: KEYCLOAK_ADMIN_PROVIDER,
576
+ useExisting: KEYCLOAK_ADMIN_CLIENT
577
+ }
578
+ ],
579
+ exports: [
580
+ KEYCLOAK_ADMIN_CLIENT,
581
+ KEYCLOAK_ADMIN_PROVIDER,
582
+ KEYCLOAK_ADMIN_CONFIG
583
+ ]
584
+ };
585
+ }
586
+ };
587
+ __name(_KeycloakAdminModule, "KeycloakAdminModule");
588
+ var KeycloakAdminModule = _KeycloakAdminModule;
589
+ KeycloakAdminModule = _ts_decorate2([
590
+ (0, import_common2.Module)({})
591
+ ], KeycloakAdminModule);
592
+ // Annotate the CommonJS export names for ESM import in node:
593
+ 0 && (module.exports = {
594
+ KEYCLOAK_ADMIN_CLIENT,
595
+ KEYCLOAK_ADMIN_CONFIG,
596
+ KEYCLOAK_ADMIN_PROVIDER,
597
+ KeycloakAdminClient,
598
+ KeycloakAdminError,
599
+ KeycloakAdminModule,
600
+ validateKeycloakAdminConfig
601
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adatechnology/keycloak-admin",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -11,7 +11,7 @@
11
11
  "dist"
12
12
  ],
13
13
  "dependencies": {
14
- "@adatechnology/http-client": "0.0.10",
14
+ "@adatechnology/http-client": "0.0.11",
15
15
  "@adatechnology/logger": "0.0.10"
16
16
  },
17
17
  "peerDependencies": {