@keycloakify/keycloak-account-ui 260200.2.1 → 260305.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.
@@ -22,6 +22,7 @@ credentialCreatedAt=<0>Создан</0> {{date}}.
22
22
  error-username-invalid-character='{{0}}' содержит недопустимый символ.
23
23
  usernamePlaceholder=Имя пользователя или email
24
24
  infoMessage=Нажав кнопку Удалить доступ, вы удалите предоставленные разрешения для этого приложения. Это приложение больше не будет использовать вашу информацию.
25
+ scopesHelp=Области, связанные с этим ресурсом.
25
26
  unknownOperatingSystem=Неизвестная операционная система
26
27
  deny=Запрещено
27
28
  edit=Редактировать
@@ -34,37 +35,47 @@ accept=Подтвердить
34
35
  error-invalid-length-too-short='{{0}}' должна иметь минимальную длину {{1}}.
35
36
  resourceSharedWith_one=Ресурс является общим для <0>{{username}}</0>
36
37
  error-number-out-of-range-too-big='{{0}}' должно иметь максимальное значение {{2}}.
38
+ updateEmail=Обновить e-mail
37
39
  two-factor=Двухфакторная аутентификация
38
40
  resourceSharedWith_zero=Этот ресурс не является общим.
39
41
  signedInDevicesExplanation=Выполните выход с незнакомых устройств.
42
+ addMultivaluedLabel=Добавить {{fieldLabel}}
40
43
  status=Статус
41
44
  error-number-out-of-range-too-small='{{0}}' должно иметь минимальное значение {{1}}.
45
+ invalidEmailMessage='{{0}}': Неверный адрес электронной почты.
42
46
  lastName=Фамилия
43
47
  removeModalMessage=Это приведет к удалению предоставленного в данный момент разрешения доступа для {{name}}. Вам нужно будет снова предоставить доступ, если вы хотите использовать это приложение.
44
48
  clients=Клиенты
49
+ createFlowHelp=Вы можете создать сценарий верхнего уровня в этом
45
50
  filterByName=Фильтровать по названию...
46
51
  refreshPage=Обновить страницу
47
52
  save=Сохранить
48
53
  error-user-attribute-required=Пожалуйста, уточните '{{0}}'.
49
54
  currentSession=Текущая сессия
55
+ clientDescriptionHelp=Указывает описание клиента. Например, "Мой клиент для расписаний". Поддерживает также ключи для локализованных значений. Например: ${my_client_description}
56
+ scopeTypeHelp=Клиентские области, которые будут добавлены в качестве областей по умолчанию для каждого созданного клиента
50
57
  error-empty=Пожалуйста, укажите значение '{{0}}'.
51
58
  error-invalid-uri-fragment='{{0}}' является недопустимым фрагментом URL-адреса.
52
59
  error-invalid-blank=Пожалуйста, укажите значение '{{0}}'.
60
+ missingFirstNameMessage='{{0}}': Укажите имя.
53
61
  signedOutSession=Сессия завершена {{browser}}/{{os}}
54
62
  share=Делиться
55
63
  close=Закрыть
56
64
  email=E-mail
57
65
  signOutWarning=Завершить сессию?
58
- removeConsentError=Не удалось удалить согласия из-за\: {{error}}
66
+ removeConsentError=Не удалось удалить согласия из-за: {{error}}
59
67
  signOutAllDevicesWarning=Это действие приведет к выходу из системы всех устройств, которые вошли в вашу учетную запись, включая текущее устройство, которое вы используете.
60
68
  unShareSuccess=Ресурс успешно удален из общего доступа.
61
69
  signingIn=Вход
62
70
  stopUsingCred=Остановить использование {{name}}?
71
+ groupsListHeader=Заголовок списка групп
63
72
  error-number-out-of-range='{{0}}' должно быть число в диапазоне от {{1}} до {{2}}.
64
73
  privacyPolicy=Политика конфиденциальности
65
74
  thirdPartyApp=Внешний
66
75
  started=Начата
67
76
  avatar=Аватар
77
+ scopeDescriptionHelp=Описание сферы деятельности клиента
78
+ confirm=Подтвердить
68
79
  updateSuccess=Ресурс успешно обновлен.
69
80
  selectOne=Выберите опцию
70
81
  unShare=Не делитесь всем
@@ -72,10 +83,11 @@ linkedAccounts=Связанные учетные записи
72
83
  personalInfoDescription=Управление данными о себе
73
84
  removeAccess=Удалить доступ
74
85
  signingInDescription=Настройте способы входа в систему.
75
- somethingWentWrongDescription=Извините, произошла непредвиденная ошибка.
76
86
  personalInfo=Личная информация
77
87
  removeCred=Удалить {{name}}
78
88
  signOutAllDevices=Выход на всех устройствах
89
+ scopeNameHelp=Имя клиентской области. Должно быть уникальным в realm. Имя не должно содержать пробелов, так как оно используется как значение параметра области
90
+ flowTypeHelp=Какой это сценарий
79
91
  error-invalid-email=Неверный адрес электронной почты.
80
92
  myResources=Мои ресурсы
81
93
  linkedAccountsIntroMessage=Управляйте входами в систему через сторонние учетные записи.
@@ -83,9 +95,9 @@ accountSecurity=Безопасность
83
95
  groupDescriptionLabel=Просмотр групп, в которых вы состоите
84
96
  manageAccount=Управление учетной записью
85
97
  resourceAlreadyShared=Ресурс уже является общим для этого пользователя.
86
- accountUpdatedMessage=Ваша учетная запись была обновлена.
87
98
  error-invalid-length-too-long='{{0}}' должна иметь максимальную длину {{2}}.
88
- shareError=Не удалось предоставить общий доступ к ресурсу из-за\: {{error}}
99
+ accountUpdatedMessage=Ваша учетная запись была обновлена.
100
+ shareError=Не удалось предоставить общий доступ к ресурсу из-за: {{error}}
89
101
  logo=Logo
90
102
  password-help-text=Вход с использованием ввода пароля.
91
103
  deleteAccount=Удалить аккаунт
@@ -93,18 +105,22 @@ permissionRequest=Запросы на разрешение - {{name}}
93
105
  add=Добавить
94
106
  error-invalid-value='{{0}}' имеет недопустимое значение.
95
107
  somethingWentWrong=Что-то пошло не так
96
- unShareError=Не удалось отключить общий доступ к ресурсу из-за\: {{error}}
108
+ somethingWentWrongDescription=Извините, произошла непредвиденная ошибка.
109
+ tryAgain=Попробовать снова
110
+ rolesScope=Если сопоставление области действия ролей не определено, каждому пользователю разрешено использовать эту клиентскую область действия. Если сопоставления области действия ролей определены, пользователь должен быть членом хотя бы одной из ролей.
111
+ unShareError=Не удалось отключить общий доступ к ресурсу из-за: {{error}}
97
112
  ipAddress=IP адрес
98
- tryAgain=Пробовать снова
99
113
  resourceName=Имя ресурса
100
114
  unlinkedEmpty=Нет несвязанных поставщиков
101
115
  done=Выполнено
102
116
  basic-authentication=Базовая аутентификация
103
117
  socialLogin=Вход в социальную сеть
104
118
  notInUse=Не используется
119
+ unShareAllConfirm=Вы уверены, что хотите отменить все общие доступы?
105
120
  firstName=Имя
106
121
  name=Имя
107
- unknownUser=Anonymous
122
+ clientTypeHelp=Тип этого ресурса. Может использоваться для группировки различных экземпляров ресурсов с одинаковым типом.
123
+ unknownUser=Анонимный
108
124
  offlineAccess=Offline доступ
109
125
  password-display-name=Пароль
110
126
  expires=Истекает
@@ -118,14 +134,20 @@ update=Обновить
118
134
  choose=Выбрать...
119
135
  signedInDevices=Выполнен вход на устройствах
120
136
  delete=Удалить
137
+ missingPasswordMessage='{{0}}': Укажите пароль.
121
138
  otp-help-text=Ввод проверочного кода из приложения аутентификатора.
139
+ groupsListColumnsNames=Имена колонок списка групп
122
140
  error-invalid-uri-scheme='{{0}}' имеет недопустимую схему URL-адресов.
141
+ error-user-attribute-read-only=Поле {{0}} доступно только для чтения.
142
+ general=Общий
123
143
  error-invalid-date='{{0}}' неверная дата.
144
+ missingEmailMessage='{{0}}': Укажите адрес электронной почты.
124
145
  accountUpdatedError=Не удалось обновить учетную запись из-за ошибок проверки
125
- unLinkError=Не удалось отключить связь из-за\: {{error}}
146
+ unLinkError=Не удалось отключить связь из-за: {{error}}
126
147
  applicationsIntroMessage=Отслеживайте разрешения ваших приложений на доступ к вашей учетной записи и управляйте ими
127
148
  error-invalid-length='{{0}}' должен иметь длину от {{1}} до {{2}}.
128
- errorSignOutMessage=Не удалось выйти из системы\: {{error}}
149
+ missingLastNameMessage='{{0}}': Укажите фамилию.
150
+ errorSignOutMessage=Не удалось выйти из системы: {{error}}
129
151
  linkedLoginProviders=Связанные поставщики идентификации
130
152
  inUse=Используется
131
153
  client=Клиент
@@ -133,28 +155,30 @@ error-invalid-uri='{{0}}' является недопустимым URL-адре
133
155
  systemDefined=Определенная система
134
156
  hasAccessTo=Имеет доступ к
135
157
  internalApp=Внутренний
136
- updateError=Не удалось обновить ресурс из-за\: {{error}}
137
- accessGrantedOn=Доступ, предоставленный на\:
158
+ updateError=Не удалось обновить ресурс из-за: {{error}}
159
+ accessGrantedOn=Доступ, предоставленный на:
138
160
  editTheResource=Редактировать ресурс - {{name}}
139
161
  permissionRequests=Запросы на разрешение
140
162
  shareSuccess=Ресурсу успешно предоставлен общий доступ.
163
+ missingUsernameMessage='{{0}}': Укажите имя пользователя.
164
+ aliasHelp=Название конфигурации
141
165
  fullName={{givenName}} {{familyName}}
142
166
  groups=Группы
143
167
  resources=Ресурсы
144
168
  resourceIntroMessage=Делитесь своими ресурсами с членами команды
145
169
  unLink=Отсоединить учетную запись
146
- errorRemovedMessage=Не удалось удалить {{userLabel}} из-за\: {{error}}
170
+ errorRemovedMessage=Не удалось удалить {{userLabel}} из-за: {{error}}
147
171
  termsOfService=Условия обслуживания
172
+ jumpToSection=Перейти к разделу
148
173
  linkError=Не удалось установить связь из-за {{error}}
149
174
  requestor=Запрашивающий
150
- shareWith=Делитесь с
175
+ shareWith=Поделиться с
151
176
  updateCredAriaLabel=Обновить учетные данные
152
177
  error-pattern-no-match='{{0}}' не соответствует требуемому формату.
153
178
  application=Приложения
154
179
  unlinkedLoginProviders=Несвязанные поставщики идентификации
155
180
  applicationDetails=Детали приложения
156
181
  successRemovedMessage={{userLabel}} был удалён.
157
- middleName=Отчество
158
182
  deleteAccountWarning=Это необратимо. Все ваши данные будут безвозвратно уничтожены.
159
183
  resourceSharedWith_other=Ресурс является общим для <0>{{username}}</0> и <1>{{other}}</1> других пользователей
160
184
  error-person-name-invalid-character='{{0}}' содержит недопустимый символ.
@@ -164,3 +188,39 @@ unLinkSuccess=Учетная запись успешно отсоединена
164
188
  applications=Приложения
165
189
  sharedWithMe=Поделился со мной
166
190
  username=Имя пользователя
191
+ webauthn-display-name=Ключ доступа
192
+ webauthn-help-text=Для входа используйте свой ключ доступа.
193
+ webauthn-passwordless-display-name=Ключ доступа
194
+ webauthn-passwordless-help-text=Используйте свой ключ доступа для входа без пароля.
195
+ passwordless=Без пароля
196
+ error-invalid-multivalued-size=Атрибут {{0}} должен иметь не менее {{1}} и не более {{2}} значений.
197
+ recovery-authn-code=Мои коды аутентификации восстановления
198
+ recovery-authn-codes-display-name=Восстановление кодов аутентификации
199
+ recovery-authn-codes-help-text=Эти коды можно использовать для восстановления доступа в случае, если другие средства двухфакторной аутентификации недоступны.
200
+ recovery-codes-number-used={{0}} использовано кодов восстановления
201
+ recovery-codes-number-remaining={{0}} оставшихся кодов восстановления
202
+ recovery-codes-generate-new-codes=Сгенерируйте новые коды, чтобы обеспечить доступ к вашей учетной записи
203
+ oid4vci=Проверяемые учетные данные
204
+ verifiableCredentialsTitle=Проверяемые учетные данные
205
+ verifiableCredentialsDescription=Выберите учетные данные для импорта в ваш кошелек.
206
+ verifiableCredentialsIssuerAlert=Не удалось получить информацию об эмитенте.
207
+ verifiableCredentialsConfigAlert=Не удалось получить конфигурацию учетных данных.
208
+ verifiableCredentialsOfferAlert=Не удалось получить предложение.
209
+ verifiableCredentialsSelectionDefault=Выберите конфигурацию учетных данных.
210
+ profileScopeConsentText=Профиль пользователя
211
+ emailScopeConsentText=Адрес электронной почты
212
+ addressScopeConsentText=Адрес
213
+ phoneScopeConsentText=Номер телефона
214
+ offlineAccessScopeConsentText=Оффлайн доступ
215
+ samlRoleListScopeConsentText=Мои роли (SAML)
216
+ rolesScopeConsentText=Роли пользователей
217
+ organizations=Организации
218
+ organizationDescription=Просмотр организаций, к которым вы присоединились
219
+ emptyUserOrganizations=Нет организаций
220
+ emptyUserOrganizationsInstructions=Вы пока не вступили ни в одну организацию.
221
+ searchOrganization=Поиск организации
222
+ organizationList=Список организаций
223
+ domains=Домены
224
+ refresh=Обновить
225
+ termsAndConditionsDeclined=Чтобы продолжить, вам необходимо принять Условия и Положения
226
+ defaultLocale=Выбрать...
@@ -75,13 +75,14 @@ export const PersonalInfo = () => {
75
75
  );
76
76
  await savePersonalInfo(context, { ...user, attributes });
77
77
  const locale = attributes["locale"]?.toString();
78
- if (locale)
79
- i18n.changeLanguage(locale, (error) => {
78
+ if (locale) {
79
+ await i18n.changeLanguage(locale, (error) => {
80
80
  if (error) {
81
81
  console.warn("Error(s) loading locale", locale, error);
82
82
  }
83
83
  });
84
- context.keycloak.updateToken();
84
+ }
85
+ await context.keycloak.updateToken();
85
86
  addAlert(t("accountUpdatedMessage"));
86
87
  } catch (error) {
87
88
  addAlert(t("accountUpdatedError"), AlertVariant.danger);
@@ -122,11 +123,15 @@ export const PersonalInfo = () => {
122
123
  ((key: unknown, params) =>
123
124
  t(key as TFuncKey, params as any)) as TFunction
124
125
  }
125
- renderer={(attribute) =>
126
- attribute.name === "email" &&
127
- updateEmailFeatureEnabled &&
128
- updateEmailActionEnabled &&
129
- (!isRegistrationEmailAsUsername || isEditUserNameAllowed) ? (
126
+ renderer={(attribute) => {
127
+ const annotations = attribute.annotations
128
+ ? attribute.annotations
129
+ : {};
130
+ return attribute.name === "email" &&
131
+ updateEmailFeatureEnabled &&
132
+ updateEmailActionEnabled &&
133
+ annotations["kc.required.action.supported"] &&
134
+ (!isRegistrationEmailAsUsername || isEditUserNameAllowed) ? (
130
135
  <Button
131
136
  id="update-email-btn"
132
137
  variant="link"
@@ -138,8 +143,8 @@ export const PersonalInfo = () => {
138
143
  >
139
144
  {t("updateEmail")}
140
145
  </Button>
141
- ) : undefined
142
- }
146
+ ) : undefined;
147
+ }}
143
148
  />
144
149
  {!allFieldsReadOnly() && (
145
150
  <ActionGroup>
@@ -2,7 +2,11 @@
2
2
 
3
3
  // @ts-nocheck
4
4
 
5
- import { ErrorPage, useEnvironment } from "../../shared/keycloak-ui-shared";
5
+ import {
6
+ ErrorPage,
7
+ useEnvironment,
8
+ KeycloakContext,
9
+ } from "../../shared/keycloak-ui-shared";
6
10
  import { Page, Spinner } from "../../shared/@patternfly/react-core";
7
11
  import { Suspense, useState } from "react";
8
12
  import {
@@ -18,12 +22,21 @@ import { Header } from "./Header";
18
22
  import { MenuItem, PageNav } from "./PageNav";
19
23
  import { routes } from "../routes";
20
24
 
21
- function mapRoutes(content: MenuItem[]): RouteObject[] {
25
+ function mapRoutes(
26
+ context: KeycloakContext<Environment>,
27
+ content: MenuItem[],
28
+ ): RouteObject[] {
22
29
  return content
23
30
  .map((item) => {
24
31
  if ("children" in item) {
25
- return mapRoutes(item.children);
32
+ return mapRoutes(context, item.children);
33
+ }
34
+
35
+ // Do not add route disabled via feature flags
36
+ if (item.isVisible && !context.environment.features[item.isVisible]) {
37
+ return null;
26
38
  }
39
+
27
40
  return {
28
41
  ...item,
29
42
  element:
@@ -32,6 +45,7 @@ function mapRoutes(content: MenuItem[]): RouteObject[] {
32
45
  : undefined,
33
46
  };
34
47
  })
48
+ .filter((item) => !!item)
35
49
  .flat();
36
50
  }
37
51
 
@@ -53,7 +67,7 @@ export const Root = () => {
53
67
  </Page>
54
68
  ),
55
69
  errorElement: <ErrorPage />,
56
- children: mapRoutes(content),
70
+ children: mapRoutes(context, content),
57
71
  },
58
72
  ]);
59
73
  },
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@keycloakify/keycloak-account-ui",
3
3
  "main": "index.js",
4
4
  "types": "index.d.ts",
5
- "version": "260200.2.1",
5
+ "version": "260305.0.1",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git://github.com/keycloakify/keycloak-account-ui.git"
@@ -23,15 +23,15 @@
23
23
  "@patternfly/react-core": "^5.4.14",
24
24
  "@patternfly/react-icons": "^5.4.2",
25
25
  "@patternfly/react-table": "^5.4.16",
26
- "i18next": "^24.2.3",
26
+ "i18next": "^25.2.1",
27
27
  "i18next-fetch-backend": "^6.0.0",
28
28
  "keycloak-js": "^26.2.0",
29
29
  "lodash-es": "^4.17.21",
30
30
  "react": "^18.3.1",
31
- "react-hook-form": "^7.54.2",
32
- "react-i18next": "^15.4.1",
33
- "react-router-dom": "^6.30.0",
34
- "@keycloakify/keycloak-ui-shared": "~260200.0.0",
31
+ "react-hook-form": "^7.59.0",
32
+ "react-i18next": "^15.5.3",
33
+ "react-router-dom": "^6.30.1",
34
+ "@keycloakify/keycloak-ui-shared": "~260305.0.0",
35
35
  "@types/lodash-es": "^4.17.12",
36
36
  "@types/react": "^18.3.18"
37
37
  }
@@ -93,6 +93,8 @@ export namespace KcContextLike {
93
93
  * — meaning dark mode is allowed, since the restriction option didn’t exist yet.
94
94
  */
95
95
  darkMode?: boolean;
96
+
97
+ referrerName?: string;
96
98
  };
97
99
 
98
100
  export type I18nApi = {
@@ -315,6 +317,8 @@ function init(params: {
315
317
  const referrerUrl = readQueryParamOrRestoreFromSessionStorage({
316
318
  name: "referrer_uri"
317
319
  });
320
+ // NOTE: Only to remove from the URL.
321
+ readQueryParamOrRestoreFromSessionStorage({ name: "referrer" });
318
322
 
319
323
  const environment = {
320
324
  serverBaseUrl,
@@ -327,7 +331,10 @@ function init(params: {
327
331
  logoUrl: referrerUrl === undefined ? "/" : referrerUrl.replace("_hash_", "#"),
328
332
  baseUrl: `${kcContext.baseUrl.scheme}:${kcContext.baseUrl.rawSchemeSpecificPart}`,
329
333
  locale: kcContext.locale,
330
- referrerName: readQueryParamOrRestoreFromSessionStorage({ name: "referrer" }) ?? "",
334
+ referrerName: valueOrSessionStoragePersistedValue({
335
+ key: "referrerName",
336
+ value: kcContext.referrerName
337
+ }),
331
338
  referrerUrl: referrerUrl ?? "",
332
339
  features: {
333
340
  isRegistrationEmailAsUsername: kcContext.realm.registrationEmailAsUsername,
@@ -654,3 +661,17 @@ function readQueryParamOrRestoreFromSessionStorage(params: { name: string }): st
654
661
 
655
662
  return sessionStorage.getItem(`${PREFIX}${name}`) ?? undefined;
656
663
  }
664
+
665
+ function valueOrSessionStoragePersistedValue(params: {
666
+ key: string;
667
+ value: string | undefined;
668
+ }): string | undefined {
669
+ const { key, value } = params;
670
+
671
+ if (value !== undefined) {
672
+ sessionStorage.setItem(key, value);
673
+ return value;
674
+ } else {
675
+ return sessionStorage.getItem(key) ?? undefined;
676
+ }
677
+ }
@@ -30,7 +30,8 @@ const zKcContextLikeCommon = (() => {
30
30
  updateEmailActionEnabled: z.boolean(),
31
31
  isViewOrganizationsEnabled: z.boolean().optional(),
32
32
  properties: z.record(z.string(), z.union([z.string(), z.undefined()])),
33
- darkMode: z.boolean().optional()
33
+ darkMode: z.boolean().optional(),
34
+ referrerName: z.string().optional()
34
35
  });
35
36
 
36
37
  assert<Equals<z.infer<typeof zTargetType>, TargetType>>();