@kuzntsv/uikit 1.0.12 → 1.0.15

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.
@@ -1,13 +1,24 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, inject, Injectable, signal, DestroyRef } from '@angular/core';
3
- import { HttpContextToken, HttpHeaders, HttpClient } from '@angular/common/http';
4
- import { Subject } from 'rxjs';
3
+ import { HttpContextToken, HttpHeaders, HttpClient, HttpParams } from '@angular/common/http';
4
+ import { Subject, tap, catchError, throwError } from 'rxjs';
5
5
  import { Router } from '@angular/router';
6
6
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
7
+ import { hasArrayIntersection as hasArrayIntersection$1 } from 'src/utils/array.utils';
7
8
  import { MatSnackBar } from '@angular/material/snack-bar';
8
9
 
9
10
  const UIKIT_CONFIG = new InjectionToken('UIKIT_CONFIG');
10
11
 
12
+ /**
13
+ * Специальный маркер-роль в массиве ограничений,
14
+ * который полностью скрывает элемент от обычных пользователей.
15
+ */
16
+ const HIDE_ROLE_MARKER = 'HIDE';
17
+ /**
18
+ * Системная роль Администратора, которая игнорирует любые ограничения прав.
19
+ */
20
+ const ADMIN_ROLE = 'ADMIN';
21
+
11
22
  // Токен, в который мы будем передавать строку-идентификатор нужного API
12
23
  // По умолчанию пустая строка означает "использовать дефолтное (основное) API"
13
24
  const API_NAME = new HttpContextToken(() => '');
@@ -33,13 +44,22 @@ const APP_ENVIRONMENT = new InjectionToken('ApplicationEnvironment');
33
44
  const UIKIT_NOTIFICATION_TOKEN = new InjectionToken('UikitNotificationToken');
34
45
 
35
46
  class AuthEventService {
47
+ // Ошибки авторизации
36
48
  authErrorSource = new Subject();
37
- // Стрим для прослушивания ошибок (экспортируется наружу)
49
+ // Новое событие для триггера навигации на страницу логина
50
+ logoutSource = new Subject();
51
+ // Стрим для прослушивания ошибок авторизации (экспортируется наружу)
38
52
  authError$ = this.authErrorSource.asObservable();
39
- // Метод для генерации события (вызовется в интерцепторе)
53
+ // Передает URL, с которого выходим
54
+ logout$ = this.logoutSource.asObservable();
55
+ /** Вызывается в интерцепторе при 401 ошибке */
40
56
  notify401() {
41
57
  this.authErrorSource.next();
42
58
  }
59
+ /** Вызывается, когда нужно принудительно перенаправить на логин */
60
+ emitLogout(currentUrl) {
61
+ this.logoutSource.next(currentUrl);
62
+ }
43
63
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AuthEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
44
64
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AuthEventService, providedIn: 'root' });
45
65
  }
@@ -48,45 +68,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
48
68
  args: [{ providedIn: 'root' }]
49
69
  }] });
50
70
 
51
- class RoleService {
52
- // Вычисление разрешений по ролям
53
- // Роль для скрытия элементов.
54
- hideRole = 'HIDE';
55
- /** Проверка массива ролей */
56
- hasRoles(roles, checkRoles) {
57
- if (roles) {
58
- for (const checkRole of checkRoles) {
59
- if (roles.find(role => (role === checkRole || role === 'ADMIN'))) {
60
- return true;
61
- }
62
- }
63
- }
64
- return false;
65
- }
66
- /** Элемент скрывается, если у пользователя нет ни одной роли из перереданных в "roles"
67
- или в списке "roles" есть роль "hideRole". */
68
- isHideElement(roles, checkRoles) {
69
- if (!roles || roles.length === 0)
70
- return false;
71
- if (roles.indexOf(this.hideRole) !== -1)
72
- return true;
73
- for (const role of roles) {
74
- if (role && (role.length !== 0) && this.hasRoles(checkRoles, [role])) {
75
- return false;
76
- }
77
- }
78
- return true;
79
- }
80
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: RoleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
81
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: RoleService, providedIn: 'root' });
82
- }
83
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: RoleService, decorators: [{
84
- type: Injectable,
85
- args: [{
86
- providedIn: 'root'
87
- }]
88
- }] });
89
-
90
71
  /**
91
72
  * Сущность пользователя из API
92
73
  */
@@ -156,7 +137,8 @@ class AuthService {
156
137
  _loggedIn = signal(false, ...(ngDevMode ? [{ debugName: "_loggedIn" }] : /* istanbul ignore next */ []));
157
138
  roles = this._roles.asReadonly();
158
139
  loggedIn = this._loggedIn.asReadonly();
159
- defaultHeader = {
140
+ // Заголовки для URL-encoded формы
141
+ defaultOptions = {
160
142
  headers: new HttpHeaders().set('content-type', 'application/x-www-form-urlencoded'),
161
143
  };
162
144
  notificationService = inject(UIKIT_NOTIFICATION_TOKEN);
@@ -168,62 +150,52 @@ class AuthService {
168
150
  // Внедряем роутер опционально, чтобы библиотека не падала, если роутера нет в приложении
169
151
  router = inject(Router, { optional: true });
170
152
  constructor() {
171
- if (this.userService.userData?.roleList)
172
- this._roles.set(this.userService.userData?.roleList);
173
- this._loggedIn.set(!!this.userService.userData && !!this.userService.userData.token);
153
+ const initialUser = this.userService.userData;
154
+ if (initialUser?.token) {
155
+ this._loggedIn.set(true);
156
+ this._roles.set(initialUser.roleList ?? []);
157
+ }
174
158
  // Слушаем шину событий: если интерцептор поймал 401, сбрасываем сессию
175
159
  this.eventService.authError$
176
160
  .pipe(takeUntilDestroyed(this.destroyRef))
177
- .subscribe(() => {
178
- this.logout();
179
- });
161
+ .subscribe(() => this.logout());
180
162
  }
181
- /** Запрос авторизации */
182
- login(username, password, idCas, onErrorFn) {
183
- const passwordEncoded = encodeURIComponent(password);
184
- let body = `username=${username}&password=${passwordEncoded}`;
163
+ /**
164
+ * Запрос авторизации
165
+ * Возвращает Observable, позволяя компоненту реагировать на статус запроса.
166
+ */
167
+ login(username, password, idCas) {
168
+ let params = new HttpParams()
169
+ .set('username', username)
170
+ .set('password', password); // HttpParams закодирует спецсимволы сам!
185
171
  if (idCas) {
186
- body += `&idcas=${idCas}`;
172
+ params = params.set('idcas', idCas.toString());
187
173
  }
188
- this.http
189
- .post(this.config.apiUrls.auth + this.config.auth.tokenRoute, body, this.defaultHeader)
190
- .subscribe({
191
- next: (data) => {
192
- this.successLoginAction(data);
193
- this.notificationService.success('Успешная авторизация');
194
- },
195
- error: (error) => {
196
- console.log(error);
197
- this.notificationService.error('Ошибка при авторизации: ' + error, 0);
198
- if (onErrorFn) {
199
- onErrorFn();
200
- }
201
- },
202
- });
174
+ const url = `${this.config.apiUrls.auth}${this.config.auth.tokenRoute}`;
175
+ return this.http
176
+ .post(url, params.toString(), this.defaultOptions)
177
+ .pipe(tap((data) => this.successLoginAction(data)), catchError((error) => {
178
+ console.log('Login error:', error);
179
+ return throwError(() => error);
180
+ }));
203
181
  }
204
182
  /** Aвторизация по пропуску */
205
183
  loginByPermit(permit, idCas) {
206
- let body = `permit=${permit}`;
184
+ let params = new HttpParams().set('permit', permit);
207
185
  if (idCas) {
208
- body += `&idcas=${idCas}`;
186
+ params = params.set('idcas', idCas.toString());
209
187
  }
210
- return this.http
211
- .post(this.config.apiUrls.auth + this.config.auth.tokenRoute, body, this.defaultHeader)
212
- .subscribe({
213
- next: (data) => {
214
- this.successLoginAction(data);
215
- this.notificationService.success('Успешная авторизация');
216
- },
217
- error: (error) => {
218
- console.log(error);
219
- this.notificationService.error('Ошибка при авторизации: ' + error, 0);
220
- },
221
- });
188
+ const url = `${this.config.apiUrls.auth}${this.config.auth.tokenRoute}`;
189
+ return this.http.post(url, params.toString(), this.defaultOptions).pipe(tap((data) => this.successLoginAction(data)), catchError((error) => {
190
+ console.log('Permit login error:', error);
191
+ return throwError(() => error);
192
+ }));
222
193
  }
223
194
  logout() {
224
195
  // Убирает(удаляет) пользователя из локального хранилища когда он разлогинивается
225
196
  this.userService.removeUser();
226
197
  this._loggedIn.set(false);
198
+ this._roles.set([]);
227
199
  // localStorage.removeItem(this.config.auth.userStorageKey);
228
200
  // localStorage.removeItem(this.config.auth.refreshTokenStorageKey);
229
201
  // ЛОГИКА СОХРАНЕНИЯ URL ПРИ РАЗЛОГИНЕ (Ваш улучшенный кусок кода)
@@ -243,20 +215,7 @@ class AuthService {
243
215
  successLoginAction(user) {
244
216
  this.userService.userData = user;
245
217
  this._loggedIn.set(true);
246
- this._roles.set(this.userService.userData.roleList);
247
- // ЛОГИКА ВОЗВРАТА ПОСЛЕ УСПЕШНОГО ЛОГИНА
248
- if (this.router) {
249
- // Извлекаем returnUrl из текущего query-параметра текущего маршрута
250
- const currentUrlTree = this.router.parseUrl(this.router.url);
251
- const returnUrl = currentUrlTree.queryParamMap.get('returnUrl');
252
- if (returnUrl) {
253
- // Декодируем и перенаправляем пользователя туда, где он был
254
- this.router.navigateByUrl(decodeURIComponent(returnUrl));
255
- return;
256
- }
257
- // Если returnUrl нет, идем на главную
258
- this.router.navigate(['/']);
259
- }
218
+ this._roles.set(user.roleList ?? []);
260
219
  }
261
220
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
262
221
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AuthService, providedIn: 'root' });
@@ -266,6 +225,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
266
225
  args: [{ providedIn: 'root' }]
267
226
  }], ctorParameters: () => [] });
268
227
 
228
+ // Вычисление разрешений по ролям
229
+ class RoleService {
230
+ authService = inject(AuthService);
231
+ /**
232
+ * Проверяет, заблокирован ли доступ к элементу на основе списка ограничений.
233
+ * Возвращает true, если у пользователя есть запрещенная роль или передан маркер 'HIDE'.
234
+ * Администратор (ADMIN) всегда игнорирует любые запреты и маркер 'HIDE'.
235
+ */
236
+ hasForbiddenRole(forbiddenRoles) {
237
+ if (!forbiddenRoles || forbiddenRoles.length === 0)
238
+ return false;
239
+ const userRoles = this.authService.roles() ?? [];
240
+ // Если пользователь ADMIN — он игнорирует списки запретов
241
+ if (userRoles.includes(ADMIN_ROLE))
242
+ return false;
243
+ // Если в условиях зашит маркер 'HIDE' — скрываем элемент от обычного пользователя
244
+ if (forbiddenRoles.includes(HIDE_ROLE_MARKER))
245
+ return true;
246
+ // В остальных случаях проверяем стандартное пересечение ролей
247
+ return hasArrayIntersection$1(userRoles, forbiddenRoles);
248
+ }
249
+ /**
250
+ * Проверяет, есть ли у пользователя хотя бы одна из разрешенных ролей.
251
+ * ADMIN всегда возвращает true.
252
+ */
253
+ hasAnyRole(allowedRoles) {
254
+ const userRoles = this.authService.roles() ?? [];
255
+ if (userRoles.includes(ADMIN_ROLE))
256
+ return true;
257
+ return hasArrayIntersection$1(userRoles, allowedRoles);
258
+ }
259
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: RoleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
260
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: RoleService, providedIn: 'root' });
261
+ }
262
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: RoleService, decorators: [{
263
+ type: Injectable,
264
+ args: [{
265
+ providedIn: 'root',
266
+ }]
267
+ }] });
268
+
269
269
  // Сервис для вывода сообщений(ошибки, успеха)
270
270
  class NotificationService {
271
271
  // eslint-disable-next-line no-magic-numbers
@@ -302,9 +302,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
302
302
  }]
303
303
  }] });
304
304
 
305
+ /**
306
+ * Проверяет, пересекаются ли два массива (есть ли хотя бы один общий элемент).
307
+ */
308
+ function hasArrayIntersection(arrayA, arrayB) {
309
+ if (!arrayA || !arrayB)
310
+ return false;
311
+ return arrayA.some(item => arrayB.includes(item));
312
+ }
313
+
305
314
  /**
306
315
  * Generated bundle index. Do not edit.
307
316
  */
308
317
 
309
- export { API_NAME, APP_ENVIRONMENT, AuthEventService, AuthService, BYPASS_AUTH, DEFAULT_TIMEOUT, NotificationService, REQUEST_TIMEOUT, RoleService, UIKIT_CONFIG, UIKIT_NOTIFICATION_TOKEN, User, UserService };
318
+ export { ADMIN_ROLE, API_NAME, APP_ENVIRONMENT, AuthEventService, AuthService, BYPASS_AUTH, DEFAULT_TIMEOUT, HIDE_ROLE_MARKER, NotificationService, REQUEST_TIMEOUT, RoleService, UIKIT_CONFIG, UIKIT_NOTIFICATION_TOKEN, User, UserService, hasArrayIntersection };
310
319
  //# sourceMappingURL=kuzntsv-uikit.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"kuzntsv-uikit.mjs","sources":["../../src/config/lib-config.ts","../../src/http/http-context-tokens.ts","../../src/models/interfaces/environment.interface.ts","../../src/models/interfaces/notification-service.interface.ts","../../src/services/auth-event.service.ts","../../src/services/auth-role.service.ts","../../src/services/auth-user.service.ts","../../src/services/auth.service.ts","../../src/services/notification.service.ts","../../src/kuzntsv-uikit.ts"],"sourcesContent":["import { InjectionToken } from \"@angular/core\";\r\n\r\nexport interface UikitConfig {\r\n apiUrls: {\r\n default: string;\r\n auth: string;\r\n [key: string]: string;\r\n };\r\n auth: {\r\n disabled?: boolean; // true = авторизация полностью отключена\r\n userStorageKey: string; // Например, 'app_user_jwt'\r\n tokenRoute: string; // Например, '/jwt'\r\n // refreshTokenStorageKey: string; // Ключ для Refresh токена (например, 'refresh_token')\r\n // refreshEndpoint: string; // Относительный путь (например, '/auth/refresh')\r\n loginRoute: string; // Например, '/auth/login'\r\n publicUrls: string[]; // Относительные пути, которые не требуют токена (например, '/login', '/assets')\r\n };\r\n}\r\n\r\nexport const UIKIT_CONFIG = new InjectionToken<UikitConfig>('UIKIT_CONFIG');\r\n","import { HttpContextToken } from '@angular/common/http';\r\nimport { inject, InjectionToken } from '@angular/core';\r\n\r\n// Токен, в который мы будем передавать строку-идентификатор нужного API\r\n// По умолчанию пустая строка означает \"использовать дефолтное (основное) API\"\r\nexport const API_NAME = new HttpContextToken<string>(() => '');\r\n\r\n// Иногда внутри сервиса нужно сделать один специфический запрос (например, стянуть публичный JSON-файл конфигурации), не добавляя его глобально в publicUrls.\r\n// Используя подход с HttpContext, мы можем добавить в библиотеку маркер пропуска авторизации:\r\n// А в коде приложения вызывать так:\r\n// this.http.get('/assets/config.json', { \r\n// context: new HttpContext().set(BYPASS_AUTH, true) \r\n// });\r\nexport const BYPASS_AUTH = new HttpContextToken<boolean>(() => false);\r\n\r\n// DI-токен, который переопределяем в appConfig\r\nexport const DEFAULT_TIMEOUT = new InjectionToken<number>('DEFAULT_TIMEOUT', {\r\n providedIn: 'root',\r\n factory: () => 10000 // Запасной дефолт (10 сек), если в appConfig ничего не указали\r\n});\r\n\r\n// Если для каких-то тяжелых запросов (например, загрузка больших файлов или генерация отчетов) \r\n// вам нужно увеличить таймаут, вы можете передавать его значение прямо в запросе через HttpContext.\r\nexport const REQUEST_TIMEOUT = new HttpContextToken<number>(() => inject(DEFAULT_TIMEOUT));","import { InjectionToken } from \"@angular/core\";\r\n\r\nexport interface AppEnvironment {\r\n appVersion: string;\r\n production: boolean;\r\n \r\n // Объявляем словарь адресов. \r\n // Ключ default — обязательный, остальные — любые строки.\r\n apiUrls: {\r\n default: string;\r\n [key: string]: string; // <-- Это позволяет писать billing, analytics, crm и т.д.\r\n };\r\n};\r\n\r\nexport const APP_ENVIRONMENT = new InjectionToken<AppEnvironment>('ApplicationEnvironment');","import { InjectionToken } from \"@angular/core\";\r\n\r\nexport interface INotificationService {\r\n /**\r\n * Показ всплывашки с сообщением\r\n *\r\n * @param message сообщение\r\n * @param duration задержка в миллисекундах\r\n */\r\n openSnackBar(message: string, action: string, duration?: number): void;\r\n\r\n /**\r\n * Уведомление о успехе\r\n *\r\n * @param message сообщение\r\n * @param duration задержка в миллисекундах\r\n */\r\n success(message: string, duration?: number): void;\r\n\r\n /**\r\n * Уведомление о информации\r\n *\r\n * @param message сообщение\r\n * @param duration задержка в миллисекундах\r\n */\r\n info(message: string, duration?: number): void;\r\n\r\n /**\r\n * Уведомление о сообщения помощи\r\n *\r\n * @param message сообщение\r\n * @param duration задержка в миллисекундах\r\n */\r\n helper(message: string, duration?: number): void;\r\n\r\n /**\r\n * Уведомление о предупреждении\r\n *\r\n * @param message сообщение\r\n * @param duration задержка в миллисекундах\r\n */\r\n warning(message: string, duration?: number): void;\r\n\r\n /**\r\n * Уведомление об ошибке\r\n *\r\n * @param message сообщение\r\n * @param duration задержка в миллисекундах\r\n */\r\n error(message: string, duration?: number): void;\r\n}\r\n\r\nexport const UIKIT_NOTIFICATION_TOKEN = new InjectionToken<INotificationService>('UikitNotificationToken');\r\n","import { Injectable } from '@angular/core';\r\nimport { Subject } from 'rxjs';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class AuthEventService {\r\n private readonly authErrorSource = new Subject<void>();\r\n \r\n // Стрим для прослушивания ошибок (экспортируется наружу)\r\n readonly authError$ = this.authErrorSource.asObservable();\r\n\r\n // Метод для генерации события (вызовется в интерцепторе)\r\n notify401(): void {\r\n this.authErrorSource.next();\r\n }\r\n}","import { Injectable } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\n\r\nexport class RoleService {\r\n // Вычисление разрешений по ролям \r\n\r\n // Роль для скрытия элементов.\r\n private readonly hideRole = 'HIDE';\r\n\r\n /** Проверка массива ролей */\r\n public hasRoles(roles: string[], checkRoles: string[]): boolean {\r\n if (roles) {\r\n for (const checkRole of checkRoles) {\r\n if (roles.find(role => (role === checkRole || role === 'ADMIN'))) {\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /** Элемент скрывается, если у пользователя нет ни одной роли из перереданных в \"roles\"\r\n или в списке \"roles\" есть роль \"hideRole\". */\r\n public isHideElement(roles: string[], checkRoles: string[]): boolean {\r\n if (!roles || roles.length === 0)\r\n return false;\r\n if (roles.indexOf(this.hideRole) !== -1)\r\n return true;\r\n for (const role of roles) {\r\n if (role && (role.length !== 0) && this.hasRoles(checkRoles, [role])) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { UIKIT_CONFIG } from '../config';\r\n/**\r\n * Сущность пользователя из API\r\n */\r\nexport class User {\r\n id: number = 0;\r\n username: string = '';\r\n firstName: string = '';\r\n lastName: string = '';\r\n prof: string = '';\r\n depart: number = 0;\r\n area: string = '';\r\n tabnum: string = '';\r\n mail: string = '';\r\n phone: string = '';\r\n roles: string = '';\r\n rolesArray: string[] = [];\r\n roleList: string[] = [];\r\n idHuman: string = '';\r\n token: string = '';\r\n // Время действия токена\r\n expires_in: number = 0;\r\n}\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\n/**\r\n * Сервис для работы с объектом в local Storage\r\n */\r\nexport class UserService {\r\n private user: User;\r\n\r\n private config = inject(UIKIT_CONFIG);\r\n\r\n constructor() {\r\n const saved = localStorage.getItem(this.config.auth.userStorageKey);\r\n this.user = saved ? JSON.parse(saved) : new User();\r\n }\r\n\r\n get dept(): number {\r\n return this.user?.depart;\r\n }\r\n\r\n /** Получить данные о пользователе */\r\n get userData(): User {\r\n return this.user;\r\n }\r\n\r\n /** Изменить данные пользователя в localStorage */\r\n set userData(user: User) {\r\n this.user = user;\r\n localStorage.setItem(this.config.auth.userStorageKey, JSON.stringify(user));\r\n }\r\n\r\n /** Удаляет данные о пользователе из localStorage. */\r\n removeUser() {\r\n localStorage.removeItem(this.config.auth.userStorageKey);\r\n }\r\n}\r\n","import { DestroyRef, Injectable, inject, signal } from '@angular/core';\r\nimport { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { Router } from '@angular/router';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\n\r\nimport { AuthEventService } from './auth-event.service';\r\nimport { UserService } from './auth-user.service';\r\nimport { UIKIT_CONFIG } from '../config';\r\nimport { UIKIT_NOTIFICATION_TOKEN } from '../models';\r\n\r\n// interface RefreshResponse {\r\n// accessToken: string;\r\n// refreshToken: string;\r\n// }\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class AuthService {\r\n // Хранит роли пользователя\r\n private readonly _roles = signal<string[]>([]);\r\n // Состояние авторизации\r\n private readonly _loggedIn = signal<boolean>(false);\r\n\r\n readonly roles = this._roles.asReadonly();\r\n readonly loggedIn = this._loggedIn.asReadonly();\r\n\r\n private readonly defaultHeader = {\r\n headers: new HttpHeaders().set(\r\n 'content-type',\r\n 'application/x-www-form-urlencoded',\r\n ),\r\n };\r\n\r\n private readonly notificationService = inject(UIKIT_NOTIFICATION_TOKEN);\r\n private readonly userService = inject(UserService);\r\n private readonly eventService = inject(AuthEventService);\r\n private readonly destroyRef = inject(DestroyRef);\r\n\r\n private http = inject(HttpClient);\r\n private config = inject(UIKIT_CONFIG);\r\n // Внедряем роутер опционально, чтобы библиотека не падала, если роутера нет в приложении\r\n private router = inject(Router, { optional: true });\r\n\r\n constructor() {\r\n if (this.userService.userData?.roleList)\r\n this._roles.set(this.userService.userData?.roleList);\r\n\r\n this._loggedIn.set(!!this.userService.userData && !!this.userService.userData.token);\r\n\r\n // Слушаем шину событий: если интерцептор поймал 401, сбрасываем сессию\r\n this.eventService.authError$\r\n .pipe(takeUntilDestroyed(this.destroyRef))\r\n .subscribe(() => {\r\n this.logout();\r\n });\r\n }\r\n\r\n /** Запрос авторизации */\r\n login(\r\n username: string,\r\n password: string,\r\n idCas: number,\r\n onErrorFn: () => void,\r\n ) {\r\n const passwordEncoded = encodeURIComponent(password);\r\n let body = `username=${username}&password=${passwordEncoded}`;\r\n\r\n if (idCas) {\r\n body += `&idcas=${idCas}`;\r\n }\r\n\r\n this.http\r\n .post(this.config.apiUrls.auth + this.config.auth.tokenRoute, body, this.defaultHeader)\r\n .subscribe({\r\n next: (data) => {\r\n this.successLoginAction(data);\r\n this.notificationService.success('Успешная авторизация');\r\n },\r\n error: (error: any) => {\r\n console.log(error);\r\n this.notificationService.error('Ошибка при авторизации: ' + error, 0);\r\n if (onErrorFn) {\r\n onErrorFn();\r\n }\r\n },\r\n });\r\n }\r\n\r\n /** Aвторизация по пропуску */\r\n loginByPermit(permit: string, idCas: number) {\r\n let body = `permit=${permit}`;\r\n\r\n if (idCas) {\r\n body += `&idcas=${idCas}`;\r\n }\r\n\r\n return this.http\r\n .post(this.config.apiUrls.auth + this.config.auth.tokenRoute, body, this.defaultHeader)\r\n .subscribe({\r\n next: (data) => {\r\n this.successLoginAction(data);\r\n this.notificationService.success('Успешная авторизация');\r\n },\r\n error: (error: any) => {\r\n console.log(error);\r\n this.notificationService.error('Ошибка при авторизации: ' + error, 0);\r\n },\r\n });\r\n }\r\n\r\n logout(): void {\r\n // Убирает(удаляет) пользователя из локального хранилища когда он разлогинивается\r\n this.userService.removeUser();\r\n this._loggedIn.set(false);\r\n // localStorage.removeItem(this.config.auth.userStorageKey);\r\n // localStorage.removeItem(this.config.auth.refreshTokenStorageKey);\r\n // ЛОГИКА СОХРАНЕНИЯ URL ПРИ РАЗЛОГИНЕ (Ваш улучшенный кусок кода)\r\n if (this.router) {\r\n const currentUrl = this.router.url;\r\n\r\n // Проверяем, не находимся ли мы уже на странице логина, чтобы избежать зацикливания\r\n if (currentUrl.includes(this.config.auth.loginRoute)) {\r\n return;\r\n }\r\n\r\n // Безопасное формирование query-параметров через Router\r\n this.router.navigate([this.config.auth.loginRoute], {\r\n queryParams: { returnUrl: encodeURIComponent(currentUrl) },\r\n });\r\n }\r\n }\r\n\r\n /** При успешной авторизации */\r\n private successLoginAction(user: any) {\r\n this.userService.userData = user;\r\n this._loggedIn.set(true);\r\n this._roles.set(this.userService.userData.roleList);\r\n\r\n // ЛОГИКА ВОЗВРАТА ПОСЛЕ УСПЕШНОГО ЛОГИНА\r\n if (this.router) {\r\n // Извлекаем returnUrl из текущего query-параметра текущего маршрута\r\n const currentUrlTree = this.router.parseUrl(this.router.url);\r\n const returnUrl = currentUrlTree.queryParamMap.get('returnUrl');\r\n\r\n if (returnUrl) {\r\n // Декодируем и перенаправляем пользователя туда, где он был\r\n this.router.navigateByUrl(decodeURIComponent(returnUrl));\r\n return;\r\n }\r\n\r\n // Если returnUrl нет, идем на главную\r\n this.router.navigate(['/']);\r\n }\r\n }\r\n\r\n // // Метод отправляет старый refresh-токен на сервер\r\n // refreshToken(): Observable<RefreshResponse> {\r\n // const refreshToken = localStorage.getItem(this.config.auth.refreshTokenStorageKey);\r\n\r\n // if (!refreshToken) {\r\n // this.logout();\r\n // return throwError(() => new Error('No refresh token available'));\r\n // }\r\n\r\n // // Собираем абсолютный урл (берем default baseUrl + эндпоинт рефреша)\r\n // const baseUrl = this.config.apiUrls.default.replace(/\\/\\$/, '');\r\n // const url = `${baseUrl}${this.config.auth.refreshEndpoint}`;\r\n\r\n // // Передаем токен (в зависимости от вашего бэкенда: в body или в куках/заголовках)\r\n // return this.http.post<RefreshResponse>(url, { refreshToken }).pipe(\r\n // tap(response => {\r\n // // Сохраняем новые токены в локалсторадж\r\n // localStorage.setItem(this.config.auth.tokenStorageKey, response.accessToken);\r\n // localStorage.setItem(this.config.auth.refreshTokenStorageKey, response.refreshToken);\r\n // }),\r\n // catchError(err => {\r\n // // Если даже рефреш-токен невалиден (истек) — принудительный разлогин\r\n // this.logout();\r\n // return throwError(() => err);\r\n // })\r\n // );\r\n // }\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { MatSnackBar } from '@angular/material/snack-bar';\r\n\r\nimport { INotificationService } from '../models';\r\n\r\n// Сервис для вывода сообщений(ошибки, успеха)\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class NotificationService implements INotificationService {\r\n // eslint-disable-next-line no-magic-numbers\r\n private readonly duration = 5000;\r\n\r\n private readonly _snackBar = inject(MatSnackBar);\r\n\r\n openSnackBar(message: string, action: string, duration: number = this.duration) {\r\n this._snackBar.open(message, action, {\r\n duration,\r\n panelClass: ['red-snackbar'],\r\n });\r\n }\r\n\r\n success(message: string, duration: number = this.duration) {\r\n this.openSnackBar(message, 'Закрыть', duration);\r\n }\r\n\r\n info(message: string, duration: number = this.duration) {\r\n this.openSnackBar(message, 'Закрыть', duration);\r\n }\r\n\r\n helper(message: string, duration: number = this.duration) {\r\n this.openSnackBar(message, 'Закрыть', duration);\r\n }\r\n\r\n warning(message: string, duration: number = this.duration) {\r\n this.openSnackBar(message, 'Закрыть', duration);\r\n }\r\n\r\n error(message: string, duration: number = this.duration) {\r\n this.openSnackBar(message, 'Закрыть', duration);\r\n }\r\n\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"kuzntsv-uikit.mjs","sources":["../../src/config/lib-config.ts","../../src/constants/auth.constants.ts","../../src/http/http-context-tokens.ts","../../src/models/interfaces/environment.interface.ts","../../src/models/interfaces/notification-service.interface.ts","../../src/services/auth-event.service.ts","../../src/services/auth-user.service.ts","../../src/services/auth.service.ts","../../src/services/auth-role.service.ts","../../src/services/notification.service.ts","../../src/utils/array.utils.ts","../../src/kuzntsv-uikit.ts"],"sourcesContent":["import { InjectionToken } from \"@angular/core\";\r\n\r\nexport interface UikitConfig {\r\n apiUrls: {\r\n default: string;\r\n auth: string;\r\n [key: string]: string;\r\n };\r\n auth: {\r\n disabled?: boolean; // true = авторизация полностью отключена\r\n userStorageKey: string; // Например, 'app_user_jwt'\r\n tokenRoute: string; // Например, '/jwt'\r\n // refreshTokenStorageKey: string; // Ключ для Refresh токена (например, 'refresh_token')\r\n // refreshEndpoint: string; // Относительный путь (например, '/auth/refresh')\r\n loginRoute: string; // Например, '/auth/login'\r\n publicUrls: string[]; // Относительные пути, которые не требуют токена (например, '/login', '/assets')\r\n };\r\n}\r\n\r\nexport const UIKIT_CONFIG = new InjectionToken<UikitConfig>('UIKIT_CONFIG');\r\n","/**\r\n * Специальный маркер-роль в массиве ограничений, \r\n * который полностью скрывает элемент от обычных пользователей.\r\n */\r\nexport const HIDE_ROLE_MARKER = 'HIDE';\r\n\r\n/**\r\n * Системная роль Администратора, которая игнорирует любые ограничения прав.\r\n */\r\nexport const ADMIN_ROLE = 'ADMIN';\r\n","import { HttpContextToken } from '@angular/common/http';\r\nimport { inject, InjectionToken } from '@angular/core';\r\n\r\n// Токен, в который мы будем передавать строку-идентификатор нужного API\r\n// По умолчанию пустая строка означает \"использовать дефолтное (основное) API\"\r\nexport const API_NAME = new HttpContextToken<string>(() => '');\r\n\r\n// Иногда внутри сервиса нужно сделать один специфический запрос (например, стянуть публичный JSON-файл конфигурации), не добавляя его глобально в publicUrls.\r\n// Используя подход с HttpContext, мы можем добавить в библиотеку маркер пропуска авторизации:\r\n// А в коде приложения вызывать так:\r\n// this.http.get('/assets/config.json', { \r\n// context: new HttpContext().set(BYPASS_AUTH, true) \r\n// });\r\nexport const BYPASS_AUTH = new HttpContextToken<boolean>(() => false);\r\n\r\n// DI-токен, который переопределяем в appConfig\r\nexport const DEFAULT_TIMEOUT = new InjectionToken<number>('DEFAULT_TIMEOUT', {\r\n providedIn: 'root',\r\n factory: () => 10000 // Запасной дефолт (10 сек), если в appConfig ничего не указали\r\n});\r\n\r\n// Если для каких-то тяжелых запросов (например, загрузка больших файлов или генерация отчетов) \r\n// вам нужно увеличить таймаут, вы можете передавать его значение прямо в запросе через HttpContext.\r\nexport const REQUEST_TIMEOUT = new HttpContextToken<number>(() => inject(DEFAULT_TIMEOUT));","import { InjectionToken } from \"@angular/core\";\r\n\r\nexport interface AppEnvironment {\r\n appVersion: string;\r\n production: boolean;\r\n \r\n // Объявляем словарь адресов. \r\n // Ключи default и auth — обязательные, остальные — любые строки.\r\n apiUrls: {\r\n default: string;\r\n auth: string;\r\n [key: string]: string; // <-- Это позволяет писать billing, analytics, crm и т.д.\r\n };\r\n};\r\n\r\nexport const APP_ENVIRONMENT = new InjectionToken<AppEnvironment>('ApplicationEnvironment');","import { InjectionToken } from \"@angular/core\";\r\n\r\n/**\r\n * Сервис уведомлений.\r\n */\r\nexport interface INotificationService {\r\n /**\r\n * Показ всплывашки с сообщением.\r\n *\r\n * @param message сообщение.\r\n * @param duration задержка в миллисекундах.\r\n */\r\n openSnackBar(message: string, action: string, duration?: number): void;\r\n\r\n /**\r\n * Уведомление о успехе.\r\n *\r\n * @param message сообщение\r\n * @param duration задержка в миллисекундах\r\n */\r\n success(message: string, duration?: number): void;\r\n\r\n /**\r\n * Уведомление о информации.\r\n *\r\n * @param message сообщение.\r\n * @param duration задержка в миллисекундах.\r\n */\r\n info(message: string, duration?: number): void;\r\n\r\n /**\r\n * Уведомление о сообщения помощи.\r\n *\r\n * @param message сообщение.\r\n * @param duration задержка в миллисекундах.\r\n */\r\n helper(message: string, duration?: number): void;\r\n\r\n /**\r\n * Уведомление о предупреждении.\r\n *\r\n * @param message сообщение.\r\n * @param duration задержка в миллисекундах.\r\n */\r\n warning(message: string, duration?: number): void;\r\n\r\n /**\r\n * Уведомление об ошибке.\r\n *\r\n * @param message сообщение.\r\n * @param duration задержка в миллисекундах.\r\n */\r\n error(message: string, duration?: number): void;\r\n}\r\n\r\nexport const UIKIT_NOTIFICATION_TOKEN = new InjectionToken<INotificationService>('UikitNotificationToken');\r\n","import { Injectable } from '@angular/core';\r\nimport { Subject } from 'rxjs';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class AuthEventService {\r\n // Ошибки авторизации\r\n private readonly authErrorSource = new Subject<void>();\r\n // Новое событие для триггера навигации на страницу логина\r\n private readonly logoutSource = new Subject<string>(); \r\n\r\n // Стрим для прослушивания ошибок авторизации (экспортируется наружу)\r\n readonly authError$ = this.authErrorSource.asObservable();\r\n // Передает URL, с которого выходим\r\n readonly logout$ = this.logoutSource.asObservable(); \r\n\r\n /** Вызывается в интерцепторе при 401 ошибке */\r\n notify401(): void {\r\n this.authErrorSource.next();\r\n }\r\n\r\n /** Вызывается, когда нужно принудительно перенаправить на логин */\r\n emitLogout(currentUrl: string): void {\r\n this.logoutSource.next(currentUrl);\r\n }\r\n}","import { inject, Injectable } from '@angular/core';\r\nimport { UIKIT_CONFIG } from '../config';\r\n/**\r\n * Сущность пользователя из API\r\n */\r\nexport class User {\r\n id: number = 0;\r\n username: string = '';\r\n firstName: string = '';\r\n lastName: string = '';\r\n prof: string = '';\r\n depart: number = 0;\r\n area: string = '';\r\n tabnum: string = '';\r\n mail: string = '';\r\n phone: string = '';\r\n roles: string = '';\r\n rolesArray: string[] = [];\r\n roleList: string[] = [];\r\n idHuman: string = '';\r\n token: string = '';\r\n // Время действия токена\r\n expires_in: number = 0;\r\n}\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\n/**\r\n * Сервис для работы с объектом в local Storage\r\n */\r\nexport class UserService {\r\n private user: User;\r\n\r\n private config = inject(UIKIT_CONFIG);\r\n\r\n constructor() {\r\n const saved = localStorage.getItem(this.config.auth.userStorageKey);\r\n this.user = saved ? JSON.parse(saved) : new User();\r\n }\r\n\r\n get dept(): number {\r\n return this.user?.depart;\r\n }\r\n\r\n /** Получить данные о пользователе */\r\n get userData(): User {\r\n return this.user;\r\n }\r\n\r\n /** Изменить данные пользователя в localStorage */\r\n set userData(user: User) {\r\n this.user = user;\r\n localStorage.setItem(this.config.auth.userStorageKey, JSON.stringify(user));\r\n }\r\n\r\n /** Удаляет данные о пользователе из localStorage. */\r\n removeUser() {\r\n localStorage.removeItem(this.config.auth.userStorageKey);\r\n }\r\n}\r\n","import { DestroyRef, Injectable, inject, signal } from '@angular/core';\r\nimport { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';\r\nimport { Router } from '@angular/router';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\n\r\nimport { AuthEventService } from './auth-event.service';\r\nimport { User, UserService } from './auth-user.service';\r\nimport { UIKIT_CONFIG } from '../config';\r\nimport { UIKIT_NOTIFICATION_TOKEN } from '../models';\r\nimport { catchError, Observable, tap, throwError } from 'rxjs';\r\n\r\n// interface RefreshResponse {\r\n// accessToken: string;\r\n// refreshToken: string;\r\n// }\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class AuthService {\r\n // Хранит роли пользователя\r\n private readonly _roles = signal<string[]>([]);\r\n // Состояние авторизации\r\n private readonly _loggedIn = signal<boolean>(false);\r\n\r\n readonly roles = this._roles.asReadonly();\r\n readonly loggedIn = this._loggedIn.asReadonly();\r\n\r\n // Заголовки для URL-encoded формы\r\n private readonly defaultOptions = {\r\n headers: new HttpHeaders().set(\r\n 'content-type',\r\n 'application/x-www-form-urlencoded',\r\n ),\r\n };\r\n\r\n private readonly notificationService = inject(UIKIT_NOTIFICATION_TOKEN);\r\n private readonly userService = inject(UserService);\r\n private readonly eventService = inject(AuthEventService);\r\n private readonly destroyRef = inject(DestroyRef);\r\n private readonly http = inject(HttpClient);\r\n private readonly config = inject(UIKIT_CONFIG);\r\n // Внедряем роутер опционально, чтобы библиотека не падала, если роутера нет в приложении\r\n private readonly router = inject(Router, { optional: true });\r\n\r\n constructor() {\r\n const initialUser = this.userService.userData as User | null;\r\n\r\n if (initialUser?.token) {\r\n this._loggedIn.set(true);\r\n this._roles.set(initialUser.roleList ?? []);\r\n }\r\n\r\n // Слушаем шину событий: если интерцептор поймал 401, сбрасываем сессию\r\n this.eventService.authError$\r\n .pipe(takeUntilDestroyed(this.destroyRef))\r\n .subscribe(() => this.logout());\r\n }\r\n\r\n /**\r\n * Запрос авторизации\r\n * Возвращает Observable, позволяя компоненту реагировать на статус запроса.\r\n */\r\n login(username: string, password: string, idCas: number): Observable<User> {\r\n let params = new HttpParams()\r\n .set('username', username)\r\n .set('password', password); // HttpParams закодирует спецсимволы сам!\r\n\r\n if (idCas) {\r\n params = params.set('idcas', idCas.toString());\r\n }\r\n\r\n const url = `${this.config.apiUrls.auth}${this.config.auth.tokenRoute}`;\r\n\r\n return this.http\r\n .post<User>(url, params.toString(), this.defaultOptions)\r\n .pipe(\r\n tap((data) => this.successLoginAction(data)),\r\n catchError((error) => {\r\n console.log('Login error:', error);\r\n return throwError(() => error);\r\n }),\r\n );\r\n }\r\n\r\n /** Aвторизация по пропуску */\r\n loginByPermit(permit: string, idCas: number): Observable<User> {\r\n let params = new HttpParams().set('permit', permit);\r\n if (idCas) {\r\n params = params.set('idcas', idCas.toString());\r\n }\r\n\r\n const url = `${this.config.apiUrls.auth}${this.config.auth.tokenRoute}`;\r\n\r\n return this.http.post<User>(url, params.toString(), this.defaultOptions).pipe(\r\n tap((data) => this.successLoginAction(data)),\r\n catchError((error) => {\r\n console.log('Permit login error:', error); \r\n return throwError(() => error);\r\n }),\r\n );\r\n }\r\n\r\n logout(): void {\r\n // Убирает(удаляет) пользователя из локального хранилища когда он разлогинивается\r\n this.userService.removeUser();\r\n this._loggedIn.set(false);\r\n this._roles.set([]);\r\n\r\n // localStorage.removeItem(this.config.auth.userStorageKey);\r\n // localStorage.removeItem(this.config.auth.refreshTokenStorageKey);\r\n // ЛОГИКА СОХРАНЕНИЯ URL ПРИ РАЗЛОГИНЕ (Ваш улучшенный кусок кода)\r\n if (this.router) {\r\n const currentUrl = this.router.url;\r\n\r\n // Проверяем, не находимся ли мы уже на странице логина, чтобы избежать зацикливания\r\n if (currentUrl.includes(this.config.auth.loginRoute)) {\r\n return;\r\n }\r\n\r\n // Безопасное формирование query-параметров через Router\r\n this.router.navigate([this.config.auth.loginRoute], {\r\n queryParams: { returnUrl: encodeURIComponent(currentUrl) },\r\n });\r\n }\r\n }\r\n\r\n /** При успешной авторизации */\r\n private successLoginAction(user: User) {\r\n this.userService.userData = user;\r\n this._loggedIn.set(true);\r\n this._roles.set(user.roleList ?? []);\r\n }\r\n\r\n // // Метод отправляет старый refresh-токен на сервер\r\n // refreshToken(): Observable<RefreshResponse> {\r\n // const refreshToken = localStorage.getItem(this.config.auth.refreshTokenStorageKey);\r\n\r\n // if (!refreshToken) {\r\n // this.logout();\r\n // return throwError(() => new Error('No refresh token available'));\r\n // }\r\n\r\n // // Собираем абсолютный урл (берем default baseUrl + эндпоинт рефреша)\r\n // const baseUrl = this.config.apiUrls.default.replace(/\\/\\$/, '');\r\n // const url = `${baseUrl}${this.config.auth.refreshEndpoint}`;\r\n\r\n // // Передаем токен (в зависимости от вашего бэкенда: в body или в куках/заголовках)\r\n // return this.http.post<RefreshResponse>(url, { refreshToken }).pipe(\r\n // tap(response => {\r\n // // Сохраняем новые токены в локалсторадж\r\n // localStorage.setItem(this.config.auth.tokenStorageKey, response.accessToken);\r\n // localStorage.setItem(this.config.auth.refreshTokenStorageKey, response.refreshToken);\r\n // }),\r\n // catchError(err => {\r\n // // Если даже рефреш-токен невалиден (истек) — принудительный разлогин\r\n // this.logout();\r\n // return throwError(() => err);\r\n // })\r\n // );\r\n // }\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\n\r\nimport { AuthService } from './auth.service';\r\nimport { hasArrayIntersection } from 'src/utils/array.utils';\r\nimport { ADMIN_ROLE, HIDE_ROLE_MARKER } from '../constants';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\n// Вычисление разрешений по ролям\r\nexport class RoleService {\r\n private readonly authService = inject(AuthService);\r\n\r\n /**\r\n * Проверяет, заблокирован ли доступ к элементу на основе списка ограничений.\r\n * Возвращает true, если у пользователя есть запрещенная роль или передан маркер 'HIDE'.\r\n * Администратор (ADMIN) всегда игнорирует любые запреты и маркер 'HIDE'.\r\n */\r\n public hasForbiddenRole(forbiddenRoles: string[]): boolean {\r\n if (!forbiddenRoles || forbiddenRoles.length === 0) return false;\r\n\r\n const userRoles = this.authService.roles() ?? [];\r\n\r\n // Если пользователь ADMIN — он игнорирует списки запретов\r\n if (userRoles.includes(ADMIN_ROLE)) return false;\r\n\r\n // Если в условиях зашит маркер 'HIDE' — скрываем элемент от обычного пользователя\r\n if (forbiddenRoles.includes(HIDE_ROLE_MARKER)) return true;\r\n\r\n // В остальных случаях проверяем стандартное пересечение ролей\r\n return hasArrayIntersection(userRoles, forbiddenRoles);\r\n }\r\n\r\n /**\r\n * Проверяет, есть ли у пользователя хотя бы одна из разрешенных ролей.\r\n * ADMIN всегда возвращает true.\r\n */\r\npublic hasAnyRole(allowedRoles: string[]): boolean {\r\n const userRoles = this.authService.roles() ?? [];\r\n if (userRoles.includes(ADMIN_ROLE)) return true;\r\n \r\n return hasArrayIntersection(userRoles, allowedRoles);\r\n}\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { MatSnackBar } from '@angular/material/snack-bar';\r\n\r\nimport { INotificationService } from '../models';\r\n\r\n// Сервис для вывода сообщений(ошибки, успеха)\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class NotificationService implements INotificationService {\r\n // eslint-disable-next-line no-magic-numbers\r\n private readonly duration = 5000;\r\n\r\n private readonly _snackBar = inject(MatSnackBar);\r\n\r\n openSnackBar(message: string, action: string, duration: number = this.duration) {\r\n this._snackBar.open(message, action, {\r\n duration,\r\n panelClass: ['red-snackbar'],\r\n });\r\n }\r\n\r\n success(message: string, duration: number = this.duration) {\r\n this.openSnackBar(message, 'Закрыть', duration);\r\n }\r\n\r\n info(message: string, duration: number = this.duration) {\r\n this.openSnackBar(message, 'Закрыть', duration);\r\n }\r\n\r\n helper(message: string, duration: number = this.duration) {\r\n this.openSnackBar(message, 'Закрыть', duration);\r\n }\r\n\r\n warning(message: string, duration: number = this.duration) {\r\n this.openSnackBar(message, 'Закрыть', duration);\r\n }\r\n\r\n error(message: string, duration: number = this.duration) {\r\n this.openSnackBar(message, 'Закрыть', duration);\r\n }\r\n\r\n}\r\n","/**\r\n * Проверяет, пересекаются ли два массива (есть ли хотя бы один общий элемент).\r\n */\r\nexport function hasArrayIntersection<T>(arrayA: T[], arrayB: T[]): boolean {\r\n if (!arrayA || !arrayB) return false;\r\n return arrayA.some(item => arrayB.includes(item));\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["hasArrayIntersection"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kuzntsv/uikit",
3
- "version": "1.0.12",
3
+ "version": "1.0.15",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.1.0",
6
6
  "@angular/core": "^21.1.0"
@@ -1,11 +1,11 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { OnInit, OnDestroy, AfterViewInit, InjectionToken, EnvironmentProviders, PipeTransform, ElementRef } from '@angular/core';
3
- import { Subscription, Observable, Subject } from 'rxjs';
2
+ import { OnInit, AfterViewInit, OnDestroy, InjectionToken, EnvironmentProviders, PipeTransform, ElementRef } from '@angular/core';
4
3
  import * as _kuzntsv_uikit from '@kuzntsv/uikit';
5
- import { AuthService, RoleService, NotificationService } from '@kuzntsv/uikit';
4
+ import { RoleService, NotificationService } from '@kuzntsv/uikit';
6
5
  import { MatMenuTrigger } from '@angular/material/menu';
7
6
  import { FormGroup, FormControl } from '@angular/forms';
8
7
  import { MatDialogRef, MatDialog } from '@angular/material/dialog';
8
+ import { Observable, Subscription, Subject } from 'rxjs';
9
9
  import { Router, CanActivateFn } from '@angular/router';
10
10
  import { HttpClient, HttpParams } from '@angular/common/http';
11
11
  import * as _angular_platform_browser from '@angular/platform-browser';
@@ -20,25 +20,25 @@ interface Authenticate {
20
20
  password: string;
21
21
  }
22
22
 
23
- declare class LoginPageComponent implements OnInit, OnDestroy {
23
+ declare class LoginPageComponent implements OnInit {
24
24
  pending: boolean;
25
25
  error: string;
26
26
  isKiosk: boolean;
27
- /** Идентификатор АС */
28
- idCas: number;
29
- /** Подписка на Идентификатор АС */
30
- sub: Subscription;
27
+ /**
28
+ * Идентификатор АС получаем автоматически из ActivatedRoute Data!
29
+ * (Для этого в настройках роутера должен быть включен withComponentInputBinding())
30
+ */
31
+ idCas: _angular_core.InputSignal<number>;
31
32
  private readonly authService;
32
- private readonly route;
33
+ private readonly router;
33
34
  private readonly loaderService;
34
- constructor();
35
+ private readonly notificationService;
35
36
  ngOnInit(): void;
36
- ngOnDestroy(): void;
37
- onSubmitError(): () => void;
38
37
  onSubmit($event: Authenticate): void;
39
38
  onSubmitPermit($event: string): void;
39
+ private handleSuccessLogin;
40
40
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<LoginPageComponent, never>;
41
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<LoginPageComponent, "ngx-uik-login-page", never, {}, {}, never, never, true, never>;
41
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<LoginPageComponent, "ngx-uik-login-page", never, { "idCas": { "alias": "idCas"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
42
42
  }
43
43
 
44
44
  type ObjectKeys<T extends string | number | symbol = string, K = any> = {
@@ -220,15 +220,45 @@ declare class TableComponent<T> implements OnInit, AfterViewInit, OnDestroy {
220
220
  }
221
221
 
222
222
  declare class BaseToolbarComponent {
223
+ /**
224
+ * Список Ролей, для которых кнопка видна. Если в списке есть роль 'HIDE', то скрывается.
225
+ */
223
226
  rolesNewBtn: _angular_core.InputSignal<string[]>;
227
+ /**
228
+ * Список Ролей, для которых кнопка видна. Если в списке есть роль 'HIDE', то скрывается.
229
+ */
224
230
  rolesEditBtn: _angular_core.InputSignal<string[]>;
231
+ /**
232
+ * Список Ролей, для которых кнопка видна. Если в списке есть роль 'HIDE', то скрывается.
233
+ */
225
234
  rolesRemoveBtn: _angular_core.InputSignal<string[]>;
235
+ /**
236
+ * Список Ролей, для которых кнопка видна. Если в списке есть роль 'HIDE', то скрывается.
237
+ */
226
238
  rolesCopyBtn: _angular_core.InputSignal<string[]>;
239
+ /**
240
+ * Список Ролей, для которых кнопка видна. Если в списке есть роль 'HIDE', то скрывается.
241
+ */
227
242
  rolesExcelBtn: _angular_core.InputSignal<string[]>;
243
+ /**
244
+ * Список Ролей, для которых кнопка видна. Если в списке есть роль 'HIDE', то скрывается.
245
+ */
228
246
  rolesCsvBtn: _angular_core.InputSignal<string[]>;
247
+ /**
248
+ * Список Ролей, для которых кнопка видна. Если в списке есть роль 'HIDE', то скрывается.
249
+ */
229
250
  rolesPdfBtn: _angular_core.InputSignal<string[]>;
251
+ /**
252
+ * Список Ролей, для которых кнопка видна. Если в списке есть роль 'HIDE', то скрывается.
253
+ */
230
254
  rolesPrintBtn: _angular_core.InputSignal<string[]>;
255
+ /**
256
+ * Список Ролей, для которых кнопка видна. Если в списке есть роль 'HIDE', то скрывается.
257
+ */
231
258
  rolesRefreshBtn: _angular_core.InputSignal<string[]>;
259
+ /**
260
+ * Список Ролей, для которых кнопка видна. Если в списке есть роль 'HIDE', то скрывается.
261
+ */
232
262
  rolesClearBtn: _angular_core.InputSignal<string[]>;
233
263
  newBtnDisabled: _angular_core.InputSignal<boolean>;
234
264
  editBtnDisabled: _angular_core.InputSignal<boolean>;
@@ -262,9 +292,25 @@ declare class BaseToolbarComponent {
262
292
  clickedPrintBtn: _angular_core.OutputEmitterRef<void>;
263
293
  clickedRefreshBtn: _angular_core.OutputEmitterRef<void>;
264
294
  clickedClearBtn: _angular_core.OutputEmitterRef<void>;
265
- protected authService: AuthService;
266
295
  protected roleService: RoleService;
267
- isShow(roles: string[]): boolean;
296
+ readonly isNewBtnVisible: _angular_core.Signal<boolean>;
297
+ readonly isEditBtnVisible: _angular_core.Signal<boolean>;
298
+ readonly isRemoveBtnVisible: _angular_core.Signal<boolean>;
299
+ readonly isCopyBtnVisible: _angular_core.Signal<boolean>;
300
+ readonly isExcelBtnVisible: _angular_core.Signal<boolean>;
301
+ readonly isCsvBtnVisible: _angular_core.Signal<boolean>;
302
+ readonly isPdfBtnVisible: _angular_core.Signal<boolean>;
303
+ readonly isPrintBtnVisible: _angular_core.Signal<boolean>;
304
+ readonly isRefreshBtnVisible: _angular_core.Signal<boolean>;
305
+ readonly isClearBtnVisible: _angular_core.Signal<boolean>;
306
+ /**
307
+ * Внутренний метод для вычисления видимости.
308
+ * Не вызывается напрямую из шаблона, а служит хелпером для декларативных computed.
309
+ * Проверяет, заблокирован ли доступ к элементу на основе списка ограничений.
310
+ * Возвращает true, если у пользователя есть запрещенная роль или передан маркер 'HIDE'.
311
+ * Администратор (ADMIN) всегда игнорирует любые запреты и маркер 'HIDE'.
312
+ */
313
+ private checkVisibility;
268
314
  onNewClick(): void;
269
315
  onEditClick(): void;
270
316
  onRemoveClick(): void;
@@ -399,13 +445,15 @@ declare class BaseFilterClass implements OnDestroy {
399
445
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseFilterClass, never, never, {}, {}, never, never, true, never>;
400
446
  }
401
447
 
402
- declare class BaseNavBarMenuClass implements OnDestroy {
403
- protected subscription: Subscription;
404
- protected authService: AuthService;
448
+ declare class BaseNavBarMenuClass {
405
449
  protected roleService: RoleService;
406
450
  protected router: Router;
407
- ngOnDestroy(): void;
408
- isShow(roles: string[]): boolean;
451
+ /**
452
+ * Определяет видимость пункта меню.
453
+ * По умолчанию пункт меню ВИДИМ. Скрывается, если у пользователя есть запрещенная роль
454
+ * или если передан маркер скрытия фичи HIDE_ROLE_MARKER.
455
+ */
456
+ protected isMenuVisible(forbiddenRoles: string[]): boolean;
409
457
  /** Нажата средняя кнопка (открыть ссылку в новой вкладке). */
410
458
  onMiddleClick(event: MouseEvent, baseUrl: string, menu: MatMenuTrigger): void;
411
459
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseNavBarMenuClass, never>;
@@ -572,23 +620,21 @@ declare abstract class BaseServiceClass<T extends BaseClass> {
572
620
  }
573
621
 
574
622
  declare class DisableIfRoleDirective {
575
- readonly roles: _angular_core.InputSignal<string[]>;
623
+ readonly forbiddenRoles: _angular_core.InputSignal<string[]>;
576
624
  private readonly el;
577
- private readonly authService;
578
625
  private readonly roleService;
579
626
  constructor();
580
627
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<DisableIfRoleDirective, never>;
581
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DisableIfRoleDirective, "[ngxUikDisableIfRole]", never, { "roles": { "alias": "ngxUikDisableIfRole"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
628
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DisableIfRoleDirective, "[ngxUikDisableIfRole]", never, { "forbiddenRoles": { "alias": "ngxUikDisableIfRole"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
582
629
  }
583
630
 
584
- declare class HideIfRoleNotDirective {
585
- readonly roles: _angular_core.InputSignal<string[]>;
631
+ declare class HideIfForbiddenRoleDirective {
632
+ readonly forbiddenRoles: _angular_core.InputSignal<string[]>;
586
633
  private readonly el;
587
- private readonly authService;
588
634
  private readonly roleService;
589
635
  constructor();
590
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<HideIfRoleNotDirective, never>;
591
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<HideIfRoleNotDirective, "[ngxUikHideIfRoleNot]", never, { "roles": { "alias": "ngxUikHideIfRoleNot"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
636
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<HideIfForbiddenRoleDirective, never>;
637
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<HideIfForbiddenRoleDirective, "[ngxUikHideIfForbiddenRole]", never, { "forbiddenRoles": { "alias": "ngxUikHideIfForbiddenRole"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
592
638
  }
593
639
 
594
640
  declare class SetValueDirective {
@@ -603,6 +649,10 @@ declare const authGuard: (allowedRoles: string[]) => CanActivateFn;
603
649
 
604
650
  declare const redirectGuard: CanActivateFn;
605
651
 
652
+ /**
653
+ * Пускает на роут только тех пользователей, у которых есть роли из списка allowedRoles.
654
+ * ADMIN всегда имеет доступ.
655
+ */
606
656
  declare const roleGuard: (allowedRoles: string[]) => CanActivateFn;
607
657
 
608
658
  declare class LoggerService {
@@ -832,5 +882,5 @@ declare class BaseSelectWithGroupComponent {
832
882
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<BaseSelectWithGroupComponent, "ngx-uik-select-with-group", never, { "groups": { "alias": "groups"; "required": false; "isSignal": true; }; "selectedItems": { "alias": "selectedItems"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; }, { "selectedItemsChange": "selectedItemsChange"; }, never, never, true, never>;
833
883
  }
834
884
 
835
- export { Action, AvatarService, BaseEditClass, BaseFilterClass, BaseMatChipComponent, BaseNavBarMenuClass, BasePageClass, BaseSelectAutocompleteWithVsComponent, BaseSelectWithGroupComponent, BaseServiceClass, BaseToolbarComponent, DateRangeInputComponent, DialogAction, DialogComponent, DisableIfRoleDirective, EmptyComponent, EntityAction, ExportService, HideIfRoleNotDirective, LOGGER_CONFIG, LoaderService, LocalStorageService, LoggerService, LoginPageComponent, MY_FORMATS, NavBarComponent, NotFoundComponent, ProgressSpinnerComponent, SafePipe, SecUser, SetValueDirective, SseService, TableComponent, TimePipe, TruncatePipe, authGuard, dateFormat, provideLogger, redirectGuard, roleGuard };
885
+ export { Action, AvatarService, BaseEditClass, BaseFilterClass, BaseMatChipComponent, BaseNavBarMenuClass, BasePageClass, BaseSelectAutocompleteWithVsComponent, BaseSelectWithGroupComponent, BaseServiceClass, BaseToolbarComponent, DateRangeInputComponent, DialogAction, DialogComponent, DisableIfRoleDirective, EmptyComponent, EntityAction, ExportService, HideIfForbiddenRoleDirective, LOGGER_CONFIG, LoaderService, LocalStorageService, LoggerService, LoginPageComponent, MY_FORMATS, NavBarComponent, NotFoundComponent, ProgressSpinnerComponent, SafePipe, SecUser, SetValueDirective, SseService, TableComponent, TimePipe, TruncatePipe, authGuard, dateFormat, provideLogger, redirectGuard, roleGuard };
836
886
  export type { BaseClass, ChipItem, DateRange, Deserializable, DialogData, IColumnOptions, IContextMenuOptions, IEditDialogData, IEntityAction, IPageState, ISortState, ITableState, LoggerConfig, ObjectKeys, SelectGroup, SelectItem, SortDirection, SseUser, Topic, fnCbType, fnGetCountType, fnGetDataType, fnMapEntityType, fnType };