@kuzntsv/uikit 1.0.13 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/kuzntsv-uikit-interceptors.mjs +0 -2
- package/fesm2022/kuzntsv-uikit-interceptors.mjs.map +1 -1
- package/fesm2022/kuzntsv-uikit-ui.mjs +181 -74
- package/fesm2022/kuzntsv-uikit-ui.mjs.map +1 -1
- package/fesm2022/kuzntsv-uikit.mjs +100 -99
- package/fesm2022/kuzntsv-uikit.mjs.map +1 -1
- package/package.json +1 -1
- package/types/kuzntsv-uikit-ui.d.ts +85 -29
- package/types/kuzntsv-uikit.d.ts +59 -30
|
@@ -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,10 +44,11 @@ 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
|
+
// Стрим для прослушивания ошибок авторизации (экспортируется наружу)
|
|
38
50
|
authError$ = this.authErrorSource.asObservable();
|
|
39
|
-
|
|
51
|
+
/** Вызывается в интерцепторе при 401 ошибке */
|
|
40
52
|
notify401() {
|
|
41
53
|
this.authErrorSource.next();
|
|
42
54
|
}
|
|
@@ -48,45 +60,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
48
60
|
args: [{ providedIn: 'root' }]
|
|
49
61
|
}] });
|
|
50
62
|
|
|
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
63
|
/**
|
|
91
64
|
* Сущность пользователя из API
|
|
92
65
|
*/
|
|
@@ -156,7 +129,8 @@ class AuthService {
|
|
|
156
129
|
_loggedIn = signal(false, ...(ngDevMode ? [{ debugName: "_loggedIn" }] : /* istanbul ignore next */ []));
|
|
157
130
|
roles = this._roles.asReadonly();
|
|
158
131
|
loggedIn = this._loggedIn.asReadonly();
|
|
159
|
-
|
|
132
|
+
// Заголовки для URL-encoded формы
|
|
133
|
+
defaultOptions = {
|
|
160
134
|
headers: new HttpHeaders().set('content-type', 'application/x-www-form-urlencoded'),
|
|
161
135
|
};
|
|
162
136
|
notificationService = inject(UIKIT_NOTIFICATION_TOKEN);
|
|
@@ -168,62 +142,52 @@ class AuthService {
|
|
|
168
142
|
// Внедряем роутер опционально, чтобы библиотека не падала, если роутера нет в приложении
|
|
169
143
|
router = inject(Router, { optional: true });
|
|
170
144
|
constructor() {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
145
|
+
const initialUser = this.userService.userData;
|
|
146
|
+
if (initialUser?.token) {
|
|
147
|
+
this._loggedIn.set(true);
|
|
148
|
+
this._roles.set(initialUser.roleList ?? []);
|
|
149
|
+
}
|
|
174
150
|
// Слушаем шину событий: если интерцептор поймал 401, сбрасываем сессию
|
|
175
151
|
this.eventService.authError$
|
|
176
152
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
177
|
-
.subscribe(() =>
|
|
178
|
-
this.logout();
|
|
179
|
-
});
|
|
153
|
+
.subscribe(() => this.logout());
|
|
180
154
|
}
|
|
181
|
-
/**
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
155
|
+
/**
|
|
156
|
+
* Запрос авторизации
|
|
157
|
+
* Возвращает Observable, позволяя компоненту реагировать на статус запроса.
|
|
158
|
+
*/
|
|
159
|
+
login(username, password, idCas) {
|
|
160
|
+
let params = new HttpParams()
|
|
161
|
+
.set('username', username)
|
|
162
|
+
.set('password', password); // HttpParams закодирует спецсимволы сам!
|
|
185
163
|
if (idCas) {
|
|
186
|
-
|
|
164
|
+
params = params.set('idcas', idCas.toString());
|
|
187
165
|
}
|
|
188
|
-
this.
|
|
189
|
-
|
|
190
|
-
.
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
error: (error) => {
|
|
196
|
-
console.log(error);
|
|
197
|
-
this.notificationService.error('Ошибка при авторизации: ' + error, 0);
|
|
198
|
-
if (onErrorFn) {
|
|
199
|
-
onErrorFn();
|
|
200
|
-
}
|
|
201
|
-
},
|
|
202
|
-
});
|
|
166
|
+
const url = `${this.config.apiUrls.auth}${this.config.auth.tokenRoute}`;
|
|
167
|
+
return this.http
|
|
168
|
+
.post(url, params.toString(), this.defaultOptions)
|
|
169
|
+
.pipe(tap((data) => this.successLoginAction(data)), catchError((error) => {
|
|
170
|
+
console.log('Login error:', error);
|
|
171
|
+
return throwError(() => error);
|
|
172
|
+
}));
|
|
203
173
|
}
|
|
204
174
|
/** Aвторизация по пропуску */
|
|
205
175
|
loginByPermit(permit, idCas) {
|
|
206
|
-
let
|
|
176
|
+
let params = new HttpParams().set('permit', permit);
|
|
207
177
|
if (idCas) {
|
|
208
|
-
|
|
178
|
+
params = params.set('idcas', idCas.toString());
|
|
209
179
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
.
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
this.notificationService.success('Успешная авторизация');
|
|
216
|
-
},
|
|
217
|
-
error: (error) => {
|
|
218
|
-
console.log(error);
|
|
219
|
-
this.notificationService.error('Ошибка при авторизации: ' + error, 0);
|
|
220
|
-
},
|
|
221
|
-
});
|
|
180
|
+
const url = `${this.config.apiUrls.auth}${this.config.auth.tokenRoute}`;
|
|
181
|
+
return this.http.post(url, params.toString(), this.defaultOptions).pipe(tap((data) => this.successLoginAction(data)), catchError((error) => {
|
|
182
|
+
console.log('Permit login error:', error);
|
|
183
|
+
return throwError(() => error);
|
|
184
|
+
}));
|
|
222
185
|
}
|
|
223
186
|
logout() {
|
|
224
187
|
// Убирает(удаляет) пользователя из локального хранилища когда он разлогинивается
|
|
225
188
|
this.userService.removeUser();
|
|
226
189
|
this._loggedIn.set(false);
|
|
190
|
+
this._roles.set([]);
|
|
227
191
|
// localStorage.removeItem(this.config.auth.userStorageKey);
|
|
228
192
|
// localStorage.removeItem(this.config.auth.refreshTokenStorageKey);
|
|
229
193
|
// ЛОГИКА СОХРАНЕНИЯ URL ПРИ РАЗЛОГИНЕ (Ваш улучшенный кусок кода)
|
|
@@ -243,20 +207,7 @@ class AuthService {
|
|
|
243
207
|
successLoginAction(user) {
|
|
244
208
|
this.userService.userData = user;
|
|
245
209
|
this._loggedIn.set(true);
|
|
246
|
-
this._roles.set(
|
|
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
|
-
}
|
|
210
|
+
this._roles.set(user.roleList ?? []);
|
|
260
211
|
}
|
|
261
212
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
262
213
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AuthService, providedIn: 'root' });
|
|
@@ -266,6 +217,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
266
217
|
args: [{ providedIn: 'root' }]
|
|
267
218
|
}], ctorParameters: () => [] });
|
|
268
219
|
|
|
220
|
+
// Вычисление разрешений по ролям
|
|
221
|
+
class RoleService {
|
|
222
|
+
authService = inject(AuthService);
|
|
223
|
+
/**
|
|
224
|
+
* Проверяет, заблокирован ли доступ к элементу на основе списка ограничений.
|
|
225
|
+
* Возвращает true, если у пользователя есть запрещенная роль или передан маркер 'HIDE'.
|
|
226
|
+
* Администратор (ADMIN) всегда игнорирует любые запреты и маркер 'HIDE'.
|
|
227
|
+
*/
|
|
228
|
+
hasForbiddenRole(forbiddenRoles) {
|
|
229
|
+
if (!forbiddenRoles || forbiddenRoles.length === 0)
|
|
230
|
+
return false;
|
|
231
|
+
const userRoles = this.authService.roles() ?? [];
|
|
232
|
+
// Если пользователь ADMIN — он игнорирует списки запретов
|
|
233
|
+
if (userRoles.includes(ADMIN_ROLE))
|
|
234
|
+
return false;
|
|
235
|
+
// Если в условиях зашит маркер 'HIDE' — скрываем элемент от обычного пользователя
|
|
236
|
+
if (forbiddenRoles.includes(HIDE_ROLE_MARKER))
|
|
237
|
+
return true;
|
|
238
|
+
// В остальных случаях проверяем стандартное пересечение ролей
|
|
239
|
+
return hasArrayIntersection$1(userRoles, forbiddenRoles);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Проверяет, есть ли у пользователя хотя бы одна из разрешенных ролей.
|
|
243
|
+
* ADMIN всегда возвращает true.
|
|
244
|
+
*/
|
|
245
|
+
hasAnyRole(allowedRoles) {
|
|
246
|
+
const userRoles = this.authService.roles() ?? [];
|
|
247
|
+
if (userRoles.includes(ADMIN_ROLE))
|
|
248
|
+
return true;
|
|
249
|
+
return hasArrayIntersection$1(userRoles, allowedRoles);
|
|
250
|
+
}
|
|
251
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: RoleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
252
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: RoleService, providedIn: 'root' });
|
|
253
|
+
}
|
|
254
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: RoleService, decorators: [{
|
|
255
|
+
type: Injectable,
|
|
256
|
+
args: [{
|
|
257
|
+
providedIn: 'root',
|
|
258
|
+
}]
|
|
259
|
+
}] });
|
|
260
|
+
|
|
269
261
|
// Сервис для вывода сообщений(ошибки, успеха)
|
|
270
262
|
class NotificationService {
|
|
271
263
|
// eslint-disable-next-line no-magic-numbers
|
|
@@ -302,9 +294,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
|
|
|
302
294
|
}]
|
|
303
295
|
}] });
|
|
304
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Проверяет, пересекаются ли два массива (есть ли хотя бы один общий элемент).
|
|
299
|
+
*/
|
|
300
|
+
function hasArrayIntersection(arrayA, arrayB) {
|
|
301
|
+
if (!arrayA || !arrayB)
|
|
302
|
+
return false;
|
|
303
|
+
return arrayA.some(item => arrayB.includes(item));
|
|
304
|
+
}
|
|
305
|
+
|
|
305
306
|
/**
|
|
306
307
|
* Generated bundle index. Do not edit.
|
|
307
308
|
*/
|
|
308
309
|
|
|
309
|
-
export { API_NAME, APP_ENVIRONMENT, AuthEventService, AuthService, BYPASS_AUTH, DEFAULT_TIMEOUT, NotificationService, REQUEST_TIMEOUT, RoleService, UIKIT_CONFIG, UIKIT_NOTIFICATION_TOKEN, User, UserService };
|
|
310
|
+
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
311
|
//# 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 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\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 // Стрим для прослушивания ошибок авторизации (экспортируется наружу)\r\n readonly authError$ = this.authErrorSource.asObservable();\r\n\r\n /** Вызывается в интерцепторе при 401 ошибке */\r\n notify401(): void {\r\n this.authErrorSource.next();\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":";;;;;;;;;MAmBa,YAAY,GAAG,IAAI,cAAc,CAAc,cAAc;;ACnB1E;;;AAGG;AACI,MAAM,gBAAgB,GAAG;AAEhC;;AAEG;AACI,MAAM,UAAU,GAAG;;ACN1B;AACA;AACO,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAS,MAAM,EAAE;AAE7D;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,WAAW,GAAG,IAAI,gBAAgB,CAAU,MAAM,KAAK;AAEpE;MACa,eAAe,GAAG,IAAI,cAAc,CAAS,iBAAiB,EAAE;AAC3E,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,KAAK;AACrB,CAAA;AAED;AACA;AACO,MAAM,eAAe,GAAG,IAAI,gBAAgB,CAAS,MAAM,MAAM,CAAC,eAAe,CAAC;;ACVxF;MAEY,eAAe,GAAG,IAAI,cAAc,CAAiB,wBAAwB;;MCwC7E,wBAAwB,GAAG,IAAI,cAAc,CAAuB,wBAAwB;;MCnD5F,gBAAgB,CAAA;;AAEV,IAAA,eAAe,GAAG,IAAI,OAAO,EAAQ;;AAG7C,IAAA,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE;;IAGzD,SAAS,GAAA;AACP,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE;IAC7B;wGAVW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cADH,MAAM,EAAA,CAAA;;4FACnB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACDlC;;AAEG;MACU,IAAI,CAAA;IACf,EAAE,GAAW,CAAC;IACd,QAAQ,GAAW,EAAE;IACrB,SAAS,GAAW,EAAE;IACtB,QAAQ,GAAW,EAAE;IACrB,IAAI,GAAW,EAAE;IACjB,MAAM,GAAW,CAAC;IAClB,IAAI,GAAW,EAAE;IACjB,MAAM,GAAW,EAAE;IACnB,IAAI,GAAW,EAAE;IACjB,KAAK,GAAW,EAAE;IAClB,KAAK,GAAW,EAAE;IAClB,UAAU,GAAa,EAAE;IACzB,QAAQ,GAAa,EAAE;IACvB,OAAO,GAAW,EAAE;IACpB,KAAK,GAAW,EAAE;;IAElB,UAAU,GAAW,CAAC;AACvB;AAID;;AAEG;MACU,WAAW,CAAA;AACd,IAAA,IAAI;AAEJ,IAAA,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC;AAErC,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;AACnE,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,EAAE;IACpD;AAEA,IAAA,IAAI,IAAI,GAAA;AACN,QAAA,OAAO,IAAI,CAAC,IAAI,EAAE,MAAM;IAC1B;;AAGA,IAAA,IAAI,QAAQ,GAAA;QACV,OAAO,IAAI,CAAC,IAAI;IAClB;;IAGA,IAAI,QAAQ,CAAC,IAAU,EAAA;AACrB,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAChB,QAAA,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7E;;IAGA,UAAU,GAAA;QACR,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;IAC1D;wGA5BW,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAX,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAW,cALV,MAAM,EAAA,CAAA;;4FAKP,WAAW,EAAA,UAAA,EAAA,CAAA;kBANvB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE;AACb,iBAAA;;;ACfD;AACA;AACA;AACA;MAGa,WAAW,CAAA;;AAEL,IAAA,MAAM,GAAG,MAAM,CAAW,EAAE,6EAAC;;AAE7B,IAAA,SAAS,GAAG,MAAM,CAAU,KAAK,gFAAC;AAE1C,IAAA,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;AAChC,IAAA,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;;AAG9B,IAAA,cAAc,GAAG;QAChC,OAAO,EAAE,IAAI,WAAW,EAAE,CAAC,GAAG,CAC5B,cAAc,EACd,mCAAmC,CACpC;KACF;AAEgB,IAAA,mBAAmB,GAAG,MAAM,CAAC,wBAAwB,CAAC;AACtD,IAAA,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AACjC,IAAA,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACvC,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,IAAA,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;AACzB,IAAA,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC;;IAE7B,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAE5D,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,QAAuB;AAE5D,QAAA,IAAI,WAAW,EAAE,KAAK,EAAE;AACtB,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC7C;;QAGA,IAAI,CAAC,YAAY,CAAC;AACf,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;aACxC,SAAS,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;IACnC;AAEA;;;AAGG;AACH,IAAA,KAAK,CAAC,QAAgB,EAAE,QAAgB,EAAE,KAAa,EAAA;AACrD,QAAA,IAAI,MAAM,GAAG,IAAI,UAAU;AACxB,aAAA,GAAG,CAAC,UAAU,EAAE,QAAQ;AACxB,aAAA,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAE7B,IAAI,KAAK,EAAE;AACT,YAAA,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChD;AAEA,QAAA,MAAM,GAAG,GAAG,CAAA,EAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAA,EAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE;QAEvE,OAAO,IAAI,CAAC;aACT,IAAI,CAAO,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,cAAc;aACtD,IAAI,CACH,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,EAC5C,UAAU,CAAC,CAAC,KAAK,KAAI;AACnB,YAAA,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC;AAClC,YAAA,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC;QAChC,CAAC,CAAC,CACH;IACL;;IAGA,aAAa,CAAC,MAAc,EAAE,KAAa,EAAA;AACzC,QAAA,IAAI,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC;QACnD,IAAI,KAAK,EAAE;AACT,YAAA,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChD;AAEA,QAAA,MAAM,GAAG,GAAG,CAAA,EAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAA,EAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE;AAEvE,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAO,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAC3E,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,EAC5C,UAAU,CAAC,CAAC,KAAK,KAAI;AACnB,YAAA,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,KAAK,CAAC;AACzC,YAAA,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC;QAChC,CAAC,CAAC,CACH;IACH;IAEA,MAAM,GAAA;;AAEJ,QAAA,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;AAC7B,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACzB,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;;;;AAKnB,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG;;AAGlC,YAAA,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;gBACpD;YACF;;AAGA,YAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;gBAClD,WAAW,EAAE,EAAE,SAAS,EAAE,kBAAkB,CAAC,UAAU,CAAC,EAAE;AAC3D,aAAA,CAAC;QACJ;IACF;;AAGQ,IAAA,kBAAkB,CAAC,IAAU,EAAA;AACnC,QAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,GAAG,IAAI;AAChC,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;IACtC;wGAjHW,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAX,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAW,cADE,MAAM,EAAA,CAAA;;4FACnB,WAAW,EAAA,UAAA,EAAA,CAAA;kBADvB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACPlC;MACa,WAAW,CAAA;AACL,IAAA,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AAElD;;;;AAIG;AACI,IAAA,gBAAgB,CAAC,cAAwB,EAAA;AAC9C,QAAA,IAAI,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;AAAE,YAAA,OAAO,KAAK;QAEhE,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE;;AAGhD,QAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC;AAAE,YAAA,OAAO,KAAK;;AAGhD,QAAA,IAAI,cAAc,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AAAE,YAAA,OAAO,IAAI;;AAG1D,QAAA,OAAOA,sBAAoB,CAAC,SAAS,EAAE,cAAc,CAAC;IACxD;AAEA;;;AAGC;AACI,IAAA,UAAU,CAAC,YAAsB,EAAA;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE;AAChD,QAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC;AAAE,YAAA,OAAO,IAAI;AAE/C,QAAA,OAAOA,sBAAoB,CAAC,SAAS,EAAE,YAAY,CAAC;IACtD;wGAhCa,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAX,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAW,cAHV,MAAM,EAAA,CAAA;;4FAGP,WAAW,EAAA,UAAA,EAAA,CAAA;kBAJvB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;ACHD;MAIa,mBAAmB,CAAA;;IAEb,QAAQ,GAAG,IAAI;AAEf,IAAA,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC;IAEhD,YAAY,CAAC,OAAe,EAAE,MAAc,EAAE,QAAA,GAAmB,IAAI,CAAC,QAAQ,EAAA;QAC5E,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE;YACnC,QAAQ;YACR,UAAU,EAAE,CAAC,cAAc,CAAC;AAC7B,SAAA,CAAC;IACJ;AAEA,IAAA,OAAO,CAAC,OAAe,EAAE,QAAA,GAAmB,IAAI,CAAC,QAAQ,EAAA;QACvD,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;IACjD;AAEA,IAAA,IAAI,CAAC,OAAe,EAAE,QAAA,GAAmB,IAAI,CAAC,QAAQ,EAAA;QACpD,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;IACjD;AAEA,IAAA,MAAM,CAAC,OAAe,EAAE,QAAA,GAAmB,IAAI,CAAC,QAAQ,EAAA;QACtD,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;IACjD;AAEA,IAAA,OAAO,CAAC,OAAe,EAAE,QAAA,GAAmB,IAAI,CAAC,QAAQ,EAAA;QACvD,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;IACjD;AAEA,IAAA,KAAK,CAAC,OAAe,EAAE,QAAA,GAAmB,IAAI,CAAC,QAAQ,EAAA;QACrD,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;IACjD;wGA/BW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,mBAAmB,cAFlB,MAAM,EAAA,CAAA;;4FAEP,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAH/B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE;AACb,iBAAA;;;ACRD;;AAEG;AACG,SAAU,oBAAoB,CAAI,MAAW,EAAE,MAAW,EAAA;AAC9D,IAAA,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM;AAAE,QAAA,OAAO,KAAK;AACpC,IAAA,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACnD;;ACNA;;AAEG;;;;"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { OnInit,
|
|
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 {
|
|
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
|
|
23
|
+
declare class LoginPageComponent implements OnInit {
|
|
24
24
|
pending: boolean;
|
|
25
25
|
error: string;
|
|
26
26
|
isKiosk: boolean;
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Идентификатор АС получаем автоматически из ActivatedRoute Data!
|
|
29
|
+
* (Для этого в настройках роутера должен быть включен withComponentInputBinding())
|
|
30
|
+
*/
|
|
31
|
+
idCas: _angular_core.InputSignal<number>;
|
|
31
32
|
private readonly authService;
|
|
32
|
-
private readonly
|
|
33
|
+
private readonly router;
|
|
33
34
|
private readonly loaderService;
|
|
34
|
-
|
|
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
|
-
|
|
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,21 @@ 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
|
|
403
|
-
protected subscription: Subscription;
|
|
404
|
-
protected authService: AuthService;
|
|
448
|
+
declare class BaseNavBarMenuClass {
|
|
405
449
|
protected roleService: RoleService;
|
|
406
450
|
protected router: Router;
|
|
407
|
-
|
|
408
|
-
|
|
451
|
+
/**
|
|
452
|
+
* Определяет видимость пункта меню на основе ЧЕРНОГО списка ролей.
|
|
453
|
+
* По умолчанию пункт меню ВИДИМ. Скрывается (возвращает false), если у пользователя
|
|
454
|
+
* есть запрещенная роль или если передан маркер скрытия фичи HIDE_ROLE_MARKER.
|
|
455
|
+
*/
|
|
456
|
+
protected isMenuVisibleForForbiddenRoles(forbiddenRoles: string[]): boolean;
|
|
457
|
+
/**
|
|
458
|
+
* Определяет видимость пункта меню на основе БЕЛОГО списка ролей.
|
|
459
|
+
* По умолчанию пункт меню СКРЫТ. Показывается (возвращает true), только если у пользователя
|
|
460
|
+
* есть хотя бы одна из разрешенных ролей. Администратор (ADMIN) всегда видит элемент.
|
|
461
|
+
*/
|
|
462
|
+
protected isMenuVisibleForAllowedRoles(allowedRoles: string[]): boolean;
|
|
409
463
|
/** Нажата средняя кнопка (открыть ссылку в новой вкладке). */
|
|
410
464
|
onMiddleClick(event: MouseEvent, baseUrl: string, menu: MatMenuTrigger): void;
|
|
411
465
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseNavBarMenuClass, never>;
|
|
@@ -572,23 +626,21 @@ declare abstract class BaseServiceClass<T extends BaseClass> {
|
|
|
572
626
|
}
|
|
573
627
|
|
|
574
628
|
declare class DisableIfRoleDirective {
|
|
575
|
-
readonly
|
|
629
|
+
readonly forbiddenRoles: _angular_core.InputSignal<string[]>;
|
|
576
630
|
private readonly el;
|
|
577
|
-
private readonly authService;
|
|
578
631
|
private readonly roleService;
|
|
579
632
|
constructor();
|
|
580
633
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DisableIfRoleDirective, never>;
|
|
581
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DisableIfRoleDirective, "[ngxUikDisableIfRole]", never, { "
|
|
634
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DisableIfRoleDirective, "[ngxUikDisableIfRole]", never, { "forbiddenRoles": { "alias": "ngxUikDisableIfRole"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
582
635
|
}
|
|
583
636
|
|
|
584
|
-
declare class
|
|
585
|
-
readonly
|
|
637
|
+
declare class HideIfForbiddenRoleDirective {
|
|
638
|
+
readonly forbiddenRoles: _angular_core.InputSignal<string[]>;
|
|
586
639
|
private readonly el;
|
|
587
|
-
private readonly authService;
|
|
588
640
|
private readonly roleService;
|
|
589
641
|
constructor();
|
|
590
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<
|
|
591
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<
|
|
642
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<HideIfForbiddenRoleDirective, never>;
|
|
643
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<HideIfForbiddenRoleDirective, "[ngxUikHideIfForbiddenRole]", never, { "forbiddenRoles": { "alias": "ngxUikHideIfForbiddenRole"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
592
644
|
}
|
|
593
645
|
|
|
594
646
|
declare class SetValueDirective {
|
|
@@ -603,6 +655,10 @@ declare const authGuard: (allowedRoles: string[]) => CanActivateFn;
|
|
|
603
655
|
|
|
604
656
|
declare const redirectGuard: CanActivateFn;
|
|
605
657
|
|
|
658
|
+
/**
|
|
659
|
+
* Пускает на роут только тех пользователей, у которых есть роли из списка allowedRoles.
|
|
660
|
+
* ADMIN всегда имеет доступ.
|
|
661
|
+
*/
|
|
606
662
|
declare const roleGuard: (allowedRoles: string[]) => CanActivateFn;
|
|
607
663
|
|
|
608
664
|
declare class LoggerService {
|
|
@@ -832,5 +888,5 @@ declare class BaseSelectWithGroupComponent {
|
|
|
832
888
|
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
889
|
}
|
|
834
890
|
|
|
835
|
-
export { Action, AvatarService, BaseEditClass, BaseFilterClass, BaseMatChipComponent, BaseNavBarMenuClass, BasePageClass, BaseSelectAutocompleteWithVsComponent, BaseSelectWithGroupComponent, BaseServiceClass, BaseToolbarComponent, DateRangeInputComponent, DialogAction, DialogComponent, DisableIfRoleDirective, EmptyComponent, EntityAction, ExportService,
|
|
891
|
+
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
892
|
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 };
|