@adatechnology/keycloak-admin 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +6 -0
  2. package/dist/index.js +23 -20
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -35,6 +35,12 @@ const { id } = await keycloak.createUser({
35
35
  Operações de usuário: `createUser`, `findUserByEmail`, `listUsers`, `updateUser`, `setEnabled`,
36
36
  `updateAttributes`, `deleteUser`, `setPassword`, `setTemporaryPassword`.
37
37
 
38
+ ⚠️ `updateAttributes` e `setProfilePicture` **leem a conta antes de gravar** (`GET` + `PUT` da
39
+ representação completa). O Keycloak 26 com perfil de usuário declarativo trata o `PUT` com
40
+ `attributes` como a ficha inteira: só `{ attributes }` responde 400 "User name is missing", e
41
+ `{ username, attributes }` apaga e-mail e nome. `updateAttributes` substitui o conjunto de atributos;
42
+ `setProfilePicture` troca só o `picture`. `updateUser` e `setEnabled` seguem parciais, sem leitura.
43
+
38
44
  Foto de perfil: `setProfilePicture({ userId, pictureUrl })`. O atributo é `picture`, o nome que o
39
45
  OIDC reserva — com um mapeador no realm ele chega ao token, e a tela desenha o avatar sem uma
40
46
  consulta por pessoa.
package/dist/index.js CHANGED
@@ -262,6 +262,15 @@ function createKeycloakAdminClient({
262
262
  url: endpoints.userPassword(userId)
263
263
  });
264
264
  }
265
+ async function rewriteUser({ buildAttributes, userId }) {
266
+ const response = await adminRequest({ method: "GET", url: endpoints.user(userId) });
267
+ const current = await response.json();
268
+ await adminRequest({
269
+ body: { ...current, attributes: normalizeAttributes(buildAttributes(current.attributes ?? {})) },
270
+ method: "PUT",
271
+ url: endpoints.user(userId)
272
+ });
273
+ }
265
274
  return {
266
275
  async createUser({
267
276
  attributes,
@@ -348,23 +357,21 @@ function createKeycloakAdminClient({
348
357
  return { hasMore: found.length > limit, users: found.slice(0, limit) };
349
358
  },
350
359
  /**
351
- * A foto é atributo, e o Admin API **substitui o conjunto** quando recebe `attributes`. Por isso
352
- * esta operação lê o usuário antes: mandar só a foto apagaria `company_id`, `tax_id` e qualquer
353
- * outro atributo do produto — e o sintoma seria login entrando sem empresa, longe daqui.
360
+ * A foto é atributo, e o Admin API **substitui o conjunto** quando recebe `attributes`: mandar
361
+ * a foto apagaria `company_id`, `tax_id` e qualquer outro atributo do produto.
354
362
  */
355
363
  async setProfilePicture({ pictureUrl, userId }) {
356
- const response = await adminRequest({ method: "GET", url: endpoints.user(userId) });
357
- const current = await response.json();
358
- const attributes = { ...current.attributes ?? {} };
359
- if (pictureUrl === void 0 || pictureUrl === "") {
360
- delete attributes[PROFILE_PICTURE_ATTRIBUTE];
361
- } else {
362
- attributes[PROFILE_PICTURE_ATTRIBUTE] = pictureUrl;
363
- }
364
- await adminRequest({
365
- body: { attributes: normalizeAttributes(attributes) },
366
- method: "PUT",
367
- url: endpoints.user(userId)
364
+ await rewriteUser({
365
+ buildAttributes: (current) => {
366
+ const attributes = { ...current };
367
+ if (pictureUrl === void 0 || pictureUrl === "") {
368
+ delete attributes[PROFILE_PICTURE_ATTRIBUTE];
369
+ } else {
370
+ attributes[PROFILE_PICTURE_ATTRIBUTE] = pictureUrl;
371
+ }
372
+ return attributes;
373
+ },
374
+ userId
368
375
  });
369
376
  },
370
377
  async setEnabled({ enabled, userId }) {
@@ -375,11 +382,7 @@ function createKeycloakAdminClient({
375
382
  await setPassword({ password, temporary: true, userId });
376
383
  },
377
384
  async updateAttributes({ attributes, userId }) {
378
- await adminRequest({
379
- body: { attributes: normalizeAttributes(attributes) },
380
- method: "PUT",
381
- url: endpoints.user(userId)
382
- });
385
+ await rewriteUser({ buildAttributes: () => attributes, userId });
383
386
  },
384
387
  async updateUser({ user, userId }) {
385
388
  await adminRequest({ body: user, method: "PUT", url: endpoints.user(userId) });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adatechnology/keycloak-admin",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Agnostic Keycloak Admin API client authenticated as a service account (client_credentials)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",