Merge branch 'master' into develop

This commit is contained in:
Eduard Tihomirov 2025-03-21 11:54:46 +03:00
commit 198f01641f
148 changed files with 557 additions and 376 deletions

View file

@ -5,7 +5,7 @@
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; connect-src 'self' https://www.sberbank.ru; script-src 'self'; style-src 'unsafe-inline' 'self' data:; font-src 'self' data:; img-src 'self' data:"/>
content="default-src 'self'; connect-src 'self' https://xn--1-6tb.xn--b1afabzvcegckfhg.xn--p1ai/ https://xn--2-6tb.xn--b1afbulhcegckfhg.xn--p1ai/; script-src 'self'; style-src 'unsafe-inline' 'self' data:; font-src 'self' data:; img-src 'self' data:"/>
<meta name="referrer" content="strict-origin-when-cross-origin"/>
<link rel="icon" type="image/png" href="src/resources/img/logo.png"/>
</head>

View file

@ -1748,9 +1748,9 @@
}
},
"@webbpm/base-package": {
"version": "3.187.2",
"resolved": "https://repo.micord.ru/repository/npm-all/@webbpm/base-package/-/base-package-3.187.2.tgz",
"integrity": "sha512-qDW+Yjm/gyTIM/4N7uQasQR1zk2tGGAF6rJFpSUSb1A7PYreXPqSAShzWJJJ1YZ9CCz2dAXSQzm6JjUJKu2VUg==",
"version": "3.187.4",
"resolved": "https://repo.micord.ru/repository/npm-all/@webbpm/base-package/-/base-package-3.187.4.tgz",
"integrity": "sha512-2MrVersJ+No7/DMDxJPuBXGoy3NmLNPtTsa4Ua0kooZmR1er7w7YnrIUtkakEXrWSODt0ki7XB9w3f1RFVAGtg==",
"requires": {
"tslib": "^1.9.0"
}

View file

@ -26,7 +26,7 @@
"@angular/platform-browser-dynamic": "7.2.15",
"@angular/router": "7.2.15",
"@ng-bootstrap/ng-bootstrap": "4.2.2-micord.1",
"@webbpm/base-package": "3.187.2",
"@webbpm/base-package": "3.187.4",
"ag-grid-angular": "29.0.0-micord.4",
"ag-grid-community": "29.0.0-micord.4",
"angular-calendar": "0.28.28",

View file

@ -17,5 +17,6 @@
"password_pattern_error": "Пароль должен содержать заглавные или прописные буквы и как минимум 1 цифру",
"show.client.errors": false,
"available_task.single_fetch": true,
"cert_check_url": "https://lkrp-dev2.micord.ru"
"cert_check_url": "https://xn--1-6tb.xn--b1afabzvcegckfhg.xn--p1ai/",
"unknown.error.msg": "Система временно недоступна. Пожалуйста, повторите попытку позже."
}

View file

@ -211,6 +211,8 @@ body.webbpm.ervu_lkrp_fl {
}
.webbpm.ervu_lkrp_fl .container {
display: flex;
flex-direction: column;
padding-top: var(--h-header);
bottom: 0;
}
@ -226,6 +228,9 @@ body.webbpm.ervu_lkrp_fl {
flex: 1;
padding: var(--indent-huge) var(--w-screen);
}
.webbpm.ervu_lkrp_ul .container-inside home-landing + app-footer {
display: none;
}
/*@media ((max-width: 780px) or ((orientation: landscape) and (max-device-width : 1024px))) {*/
@media (max-width: 1024px) {

View file

@ -1,6 +1,7 @@
import {Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http";
import {Router} from "@angular/router";
import {AuthenticationService} from "../../modules/security/authentication.service";
@Injectable({
@ -8,26 +9,30 @@ import {Router} from "@angular/router";
})
export class AuditService {
constructor(private httpClient: HttpClient, private router: Router) {
constructor(private httpClient: HttpClient,
private router: Router,
private authService: AuthenticationService) {
}
public logActionAudit(eventType: string, fileName?: string): void {
const currentRoute = this.router.url;
const sourceUrl = window.location.href;
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
if (this.authService.isAuthenticated()) {
const currentRoute = this.router.url;
const sourceUrl = window.location.href;
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const data: AuditAction = {
eventType: eventType,
sourceUrl: sourceUrl,
route: currentRoute,
fileName: fileName
};
const data: AuditAction = {
eventType: eventType,
sourceUrl: sourceUrl,
route: currentRoute,
fileName: fileName
};
this.httpClient.post("audit/action", data, {
headers: {
"Client-Time-Zone": timeZone,
}
}).toPromise();
this.httpClient.post("audit/action", data, {
headers: {
"Client-Time-Zone": timeZone,
}
}).toPromise();
}
}
}

View file

@ -2,6 +2,7 @@ import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {CookieService} from "ngx-cookie";
import {AppConfigService} from "@webbpm/base-package";
import {map, tap} from "rxjs/operators";
@Injectable({providedIn: 'root'})
export class AuthenticationService {
@ -22,4 +23,13 @@ export class AuthenticationService {
public isAuthenticated(): boolean {
return this.cookieService.get('webbpm.ervu-lkrp-fl') != null;
}
public redirectToEsia() {
return this.http.get<string>("esia/url").pipe(
tap(url => {
window.open(url, "_self");
}),
map(() => true)
);
}
}

View file

@ -33,7 +33,7 @@ export abstract class AuthGuard implements CanActivate {
}
if (error) {
let errorMessage =
'Произошла неизвестная ошибка. Обратитесь к системному администратору';
this.messageService.getUnknowErrorMessage();
let errorCode = this.extractCode(errorDescription);
if (errorCode) {
errorMessage = EsiaErrorDetail.getDescription(errorCode);
@ -49,24 +49,28 @@ export abstract class AuthGuard implements CanActivate {
params: params,
responseType: 'text',
observe: 'response',
headers: {
"Error-intercept-skip":"true"
}
})
.toPromise()
.then(
() => {
window.open(url.origin + url.pathname, "_self");
});
})
.catch(reason => {
const json = JSON.parse(reason.error);
json.messages.forEach((errorMessage) => {
this.messageService.error(errorMessage, json);
})
});
return false;
}
else {
return this.httpClient.get<string>("esia/url")
.toPromise()
.then(url => {
window.open(url, "_self");
return true;
}).catch((reason)=> {
console.error(reason);
return false;
});
return this.authenticationService.redirectToEsia().toPromise().catch((reason) => {
console.error(reason);
return false;
});
}
}).catch((reason) => {
console.error(reason);

View file

@ -34,12 +34,7 @@ export class WebbpmComponent {
|| event instanceof NavigationError
|| event instanceof NavigationCancel) {
progressIndicationService.hideProgressBar();
if (event instanceof NavigationEnd
&& event.url != '/home'
&& event.url != '/access-denied') {
this.auditService.logActionAudit(AuditConstants.OPEN_PAGE_EVENT);
}
this.auditService.logActionAudit(AuditConstants.OPEN_PAGE_EVENT);
}
})
}

View file

@ -1,14 +1,14 @@
import {HTTP_INTERCEPTORS} from "@angular/common/http";
import {
FormDirtyInterceptor,
HttpSecurityErrorInterceptor,
HttpSecurityInterceptor
} from "@webbpm/base-package";
import {AbsoluteUrlCsrfInterceptor} from "./absolute-url-csrf.interceptor";
import {ErvuHttpSecurityErrorInterceptor} from "./ervu-http-security-error-interceptor";
export const DEFAULT_HTTP_INTERCEPTOR_PROVIDERS = [
{provide: HTTP_INTERCEPTORS, useClass: HttpSecurityInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: HttpSecurityErrorInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: ErvuHttpSecurityErrorInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: FormDirtyInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: AbsoluteUrlCsrfInterceptor, multi: true}
];

View file

@ -2,10 +2,11 @@ import {HTTP_INTERCEPTORS} from "@angular/common/http";
import {FormDirtyInterceptor, HttpSecurityInterceptor} from "@webbpm/base-package";
import {DevHttpSecurityErrorInterceptor} from "./http-security-error-interceptor.dev";
import {AbsoluteUrlCsrfInterceptor} from "./absolute-url-csrf.interceptor";
import {ErvuHttpSecurityErrorInterceptor} from "./ervu-http-security-error-interceptor";
export const DEFAULT_HTTP_INTERCEPTOR_PROVIDERS = [
{provide: HTTP_INTERCEPTORS, useClass: HttpSecurityInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: DevHttpSecurityErrorInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: ErvuHttpSecurityErrorInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: FormDirtyInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: AbsoluteUrlCsrfInterceptor, multi: true},
];

View file

@ -0,0 +1,43 @@
import {
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest, HttpResponse
} from "@angular/common/http";
import {
HttpSecurityErrorInterceptor,
MessagesService,
UserService
} from "@webbpm/base-package";
import {Injectable} from "@angular/core";
import {Router} from "@angular/router";
import {from, Observable} from "rxjs";
import {catchError, map} from "rxjs/operators";
import {AuthenticationService} from "../../security/authentication.service";
@Injectable()
export class ErvuHttpSecurityErrorInterceptor extends HttpSecurityErrorInterceptor
implements HttpInterceptor {
private authService: AuthenticationService;
constructor(router: Router, messagesService: MessagesService, userService: UserService,
authService: AuthenticationService) {
super(router, messagesService, userService);
this.authService = authService;
}
protected processAuthError(req: HttpRequest<any>, next: HttpHandler,
error: any): Observable<HttpEvent<any>> {
if (this.authService.isAuthenticated()) {
return super.processAuthError(req, next, error);
}
else {
return from(this.authService.redirectToEsia()).pipe(
map(() => new HttpResponse<any>()),
catchError((err) => {
throw err;
})
);
}
}
}

View file

@ -1,19 +1,20 @@
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from "@angular/common/http";
import {HttpSecurityErrorInterceptor, MessagesService, UserService} from "@webbpm/base-package";
import {MessagesService, UserService} from "@webbpm/base-package";
import {Injectable} from "@angular/core";
import {Router} from "@angular/router";
import {EMPTY, Observable} from "rxjs";
import {catchError} from "rxjs/operators";
import {ErvuHttpSecurityErrorInterceptor} from "./ervu-http-security-error-interceptor";
import {AuthenticationService} from "../../security/authentication.service";
@Injectable()
export class DevHttpSecurityErrorInterceptor extends HttpSecurityErrorInterceptor
export class DevHttpSecurityErrorInterceptor extends ErvuHttpSecurityErrorInterceptor
implements HttpInterceptor {
private router: Router;
constructor(router: Router, messagesService: MessagesService, userService: UserService) {
super(router, messagesService, userService);
this.router = router;
constructor(router: Router, messagesService: MessagesService, userService: UserService,
authService: AuthenticationService) {
super(router, messagesService, userService, authService);
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {