@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.
- package/fesm2022/kuzntsv-uikit-interceptors.mjs +0 -2
- package/fesm2022/kuzntsv-uikit-interceptors.mjs.map +1 -1
- package/fesm2022/kuzntsv-uikit-ui.mjs +170 -75
- package/fesm2022/kuzntsv-uikit-ui.mjs.map +1 -1
- package/fesm2022/kuzntsv-uikit.mjs +108 -99
- package/fesm2022/kuzntsv-uikit.mjs.map +1 -1
- package/package.json +1 -1
- package/types/kuzntsv-uikit-ui.d.ts +79 -29
- package/types/kuzntsv-uikit.d.ts +64 -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,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
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
-
|
|
172
|
+
params = params.set('idcas', idCas.toString());
|
|
187
173
|
}
|
|
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
|
-
});
|
|
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
|
|
184
|
+
let params = new HttpParams().set('permit', permit);
|
|
207
185
|
if (idCas) {
|
|
208
|
-
|
|
186
|
+
params = params.set('idcas', idCas.toString());
|
|
209
187
|
}
|
|
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
|
-
});
|
|
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(
|
|
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,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,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
|
|
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
|
+
* По умолчанию пункт меню ВИДИМ. Скрывается, если у пользователя есть запрещенная роль
|
|
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
|
|
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, { "
|
|
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
|
|
585
|
-
readonly
|
|
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<
|
|
591
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<
|
|
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,
|
|
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 };
|