Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit 97fb0987 authored by Joze RIHTARSIC's avatar Joze RIHTARSIC
Browse files

Fix logout issue when session is expired on user settings pages.

parent 8757e8bc
No related branches found
No related tags found
No related merge requests found
Showing
with 111 additions and 19 deletions
......@@ -146,6 +146,7 @@ import {SubresourceDocumentPanelComponent} from "./edit/edit-resources/subresour
import {SubresourceDocumentWizardComponent} from "./edit/edit-resources/subresource-document-wizard-dialog/subresource-document-wizard.component";
import {SmpWarningPanelComponent} from "./common/components/smp-warning-panel/smp-warning-panel.component";
import {ManageMembersDialogComponent} from "./common/dialogs/manage-members-dialog/manage-members-dialog.component";
import {HttpErrorHandlerService} from "./common/error/http-error-handler.service";
@NgModule({
......@@ -293,6 +294,7 @@ import {ManageMembersDialogComponent} from "./common/dialogs/manage-members-dial
EditDomainService,
EditGroupService,
EditResourceService,
HttpErrorHandlerService,
ExtensionService,
GlobalLookups,
HttpEventService,
......
import {Component, Inject, Output} from '@angular/core';
import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
import {SmpConstants} from "../../../smp.constants";
......@@ -7,6 +7,7 @@ import {UserService} from "../../../system-settings/user/user.service";
import {CredentialRo} from "../../../security/credential.model";
import {CertificateRo} from "../../../system-settings/user/certificate-ro.model";
import {CertificateService} from "../../../system-settings/user/certificate.service";
import {HttpErrorHandlerService} from "../../error/http-error-handler.service";
@Component({
......@@ -34,6 +35,7 @@ export class CredentialDialogComponent {
constructor(@Inject(MAT_DIALOG_DATA) public data: any,
private userService: UserService,
private httpErrorHandlerService: HttpErrorHandlerService,
private certificateService: CertificateService,
public dialogRef: MatDialogRef<CredentialDialogComponent>,
private formBuilder: FormBuilder
......@@ -138,6 +140,7 @@ export class CredentialDialogComponent {
});
if (res.invalid) {
this.showErrorMessage(res.invalidReason);
} else {
this.clearAlert()
}
......@@ -154,6 +157,10 @@ export class CredentialDialogComponent {
},
err => {
this.clearCertificateData()
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(err)){
this.closeDialog();
return;
}
this.showErrorMessage("Error uploading certificate file [" + file.name + "]." + err.error?.errorDescription)
}
);
......@@ -175,6 +182,10 @@ export class CredentialDialogComponent {
this.userService.notifyAccessTokenUpdated(response.credential);
this.setDisabled(true);
}, (err) => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(err)){
this.closeDialog();
return;
}
this.showErrorMessage(err.error.errorDescription);
});
}
......@@ -208,16 +219,17 @@ export class CredentialDialogComponent {
}
return null;
}
get minSelectableDate(): Date {
return this.credentialType == CredentialDialogComponent.ACCESS_TOKEN_TYPE? new Date():null;
return this.credentialType == CredentialDialogComponent.ACCESS_TOKEN_TYPE ? new Date() : null;
}
showSuccessMessage(value:string) {
showSuccessMessage(value: string) {
this.message = value;
this.messageType = "success";
}
showErrorMessage(value:string) {
showErrorMessage(value: string) {
this.message = value;
this.messageType = "error";
}
......
import {Injectable} from '@angular/core';
import {Router, NavigationStart, NavigationEnd} from '@angular/router';
import {Observable, Subject} from 'rxjs';
import {HttpErrorResponse} from "@angular/common/http";
import {NavigationService} from "../../window/sidenav/navigation-model.service";
import {AlertMessageService} from "../alert-message/alert-message.service";
@Injectable()
export class HttpErrorHandlerService {
constructor (private navigationService: NavigationService,
private alertMessageService: AlertMessageService,) {
}
public logoutOnInvalidSessionError(err: any): boolean {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
this.navigationService.navigateToLogin();
this.alertMessageService.error(err.error?.errorDescription)
return true;
}
}
return false;
}
}
......@@ -8,7 +8,6 @@ export const authenticationGuard = () => {
const navigationService = inject(NavigationService);
const securityService = inject(SecurityService);
const alertService = inject(AlertMessageService);
const router = inject(Router);
// test if logged in
securityService.isAuthenticated(true).subscribe((isAuthenticated: boolean) => {
......@@ -17,9 +16,7 @@ export const authenticationGuard = () => {
} else {
alertService.error('You have been logged out because of inactivity or missing access permissions.', true);
// Redirect to the login page
navigationService.reset();
router.navigate(['/login'], {queryParams: {returnUrl: router.url}});
router.parseUrl('/login');
navigationService.navigateToLogin();
}
});
};
......@@ -2,7 +2,7 @@
import {Observable, ReplaySubject} from 'rxjs';
import {User} from './user.model';
import {SecurityEventService} from './security-event.service';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {HttpClient, HttpErrorResponse, HttpHeaders} from '@angular/common/http';
import {SmpConstants} from "../smp.constants";
import {Authority} from "./authority.model";
import {AlertMessageService} from "../common/alert-message/alert-message.service";
......@@ -169,4 +169,5 @@ export class SecurityService {
private clearLocalStorage() {
localStorage.removeItem(this.LOCAL_STORAGE_KEY_CURRENT_USER);
}
}
......@@ -16,6 +16,7 @@ import {
} from "../../common/dialogs/password-change-dialog/password-change-dialog.component";
import {UserDetailsDialogMode} from "../user/user-details-dialog/user-details-dialog.component";
import {ApplicationRoleEnum} from "../../common/enums/application-role.enum";
import {HttpErrorHandlerService} from "../../common/error/http-error-handler.service";
@Component({
......@@ -39,6 +40,7 @@ export class AdminUserComponent implements AfterViewInit, BeforeLeaveGuard {
@ViewChild(MatPaginator) paginator: MatPaginator;
constructor(private adminUserService: AdminUserService,
private httpErrorHandlerService: HttpErrorHandlerService,
private securityService: SecurityService,
private alertService: AlertMessageService,
private dialog: MatDialog) {
......@@ -127,6 +129,9 @@ export class AdminUserComponent implements AfterViewInit, BeforeLeaveGuard {
this.selected = selectUser;
}
}, (error) => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)) {
return;
}
this.alertService.error(error.error?.errorDescription)
});
}
......@@ -149,6 +154,9 @@ export class AdminUserComponent implements AfterViewInit, BeforeLeaveGuard {
this.alertService.success("User [" + user.username + "] updated!");
}
}, (error) => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)) {
return;
}
this.alertService.error(error.error?.errorDescription)
});
}
......@@ -163,6 +171,9 @@ export class AdminUserComponent implements AfterViewInit, BeforeLeaveGuard {
this.alertService.success("User [" + user.username + "] created!");
}
}, (error) => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)) {
return;
}
this.alertService.error(error.error?.errorDescription)
});
}
......@@ -192,6 +203,9 @@ export class AdminUserComponent implements AfterViewInit, BeforeLeaveGuard {
this.alertService.success("User [" + user.username + "] deleted!");
}
}, (error) => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)) {
return;
}
this.alertService.error(error.error?.errorDescription)
});
......
......@@ -7,6 +7,7 @@ import {SecurityService} from "../../security/security.service";
import {Observable, Subject} from "rxjs";
import {CredentialRo} from "../../security/credential.model";
import {AccessTokenRo} from "../../common/dialogs/access-token-generation-dialog/access-token-ro.model";
import {HttpErrorHandlerService} from "../../common/error/http-error-handler.service";
/**
* Class handle current user settings such-as profile, credentials, DomiSMP settings... ,
......@@ -27,6 +28,7 @@ export class UserService {
constructor(
private http: HttpClient,
private httpErrorHandlerService: HttpErrorHandlerService,
private securityService: SecurityService,
private alertService: AlertMessageService,
) {
......@@ -53,6 +55,9 @@ export class UserService {
.subscribe((response: CredentialRo) => {
this.notifyPwdStatusUpdated(response)
}, error => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)){
return;
}
this.alertService.error(error.error?.errorDescription)
});
}
......@@ -67,6 +72,9 @@ export class UserService {
.subscribe((response: CredentialRo[]) => {
this.notifyAccessTokensUpdated(response)
}, error => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)){
return;
}
this.alertService.error(error.error?.errorDescription)
});
}
......@@ -82,6 +90,9 @@ export class UserService {
.subscribe((response: CredentialRo) => {
this.notifyAccessTokenUpdated(response)
}, error => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)){
return;
}
this.alertService.error(error.error?.errorDescription)
});
}
......@@ -97,6 +108,9 @@ export class UserService {
.subscribe((response: CredentialRo) => {
this.notifyAccessTokenUpdated(response)
}, error => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)){
return;
}
this.alertService.error(error.error?.errorDescription)
});
}
......@@ -112,6 +126,9 @@ export class UserService {
.subscribe((response: CredentialRo) => {
this.notifyCertificateUpdated(response)
}, error => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)){
return;
}
this.alertService.error(error.error?.errorDescription)
});
}
......@@ -127,6 +144,9 @@ export class UserService {
.subscribe((response: CredentialRo) => {
this.notifyCertificateUpdated(response)
}, error => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)){
return;
}
this.alertService.error(error.error?.errorDescription)
});
}
......@@ -153,7 +173,11 @@ export class UserService {
.subscribe((response: CredentialRo) => {
this.notifyCertificateUpdated(response)
}, error => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)){
return;
}
this.alertService.error(error.error?.errorDescription)
});
}
......@@ -170,6 +194,9 @@ export class UserService {
.subscribe((response: CredentialRo[]) => {
this.notifyCertificatesUpdated(response)
}, error => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)){
return;
}
this.alertService.error(error.error?.errorDescription)
});
}
......
......@@ -9,6 +9,7 @@ import {CertificateDialogComponent} from "../../common/dialogs/certificate-dialo
import {CredentialDialogComponent} from "../../common/dialogs/credential-dialog/credential-dialog.component";
import {BeforeLeaveGuard} from "../../window/sidenav/navigation-on-leave-guard";
import {UserCertificatePanelComponent} from "./user-certificate-panel/user-certificate-panel.component";
import {HttpErrorHandlerService} from "../../common/error/http-error-handler.service";
@Component({
......@@ -23,6 +24,7 @@ export class UserCertificatesComponent implements BeforeLeaveGuard {
userCertificateCredentialComponents: QueryList<UserCertificatePanelComponent>;
constructor(private securityService: SecurityService,
private httpErrorHandlerService: HttpErrorHandlerService,
private userService: UserService,
public dialog: MatDialog) {
......@@ -78,21 +80,27 @@ export class UserCertificatesComponent implements BeforeLeaveGuard {
}
public createNew() {
this.dialog.open(CredentialDialogComponent,{
data:{
this.dialog.open(CredentialDialogComponent, {
data: {
credentialType: CredentialDialogComponent.CERTIFICATE_TYPE,
formTitle: "Import certificate dialog"
}
} ).afterClosed();
}).afterClosed();
}
public onShowItemClicked(credential: CredentialRo) {
this.userService.getUserCertificateCredentialObservable(credential).subscribe((response: CredentialRo) => {
this.dialog.open(CertificateDialogComponent, {
data: {row: response.certificate}
this.userService.getUserCertificateCredentialObservable(credential)
.subscribe((response: CredentialRo) => {
this.dialog.open(CertificateDialogComponent, {
data: {row: response.certificate}
});
}, error => {
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(error)) {
return;
}
});
});
}
......@@ -119,7 +127,7 @@ export class UserCertificatesComponent implements BeforeLeaveGuard {
}
isDirty(): boolean {
let dirtyComp = !this.userCertificateCredentialComponents?null: this.userCertificateCredentialComponents.find(cmp => cmp.isDirty())
let dirtyComp = !this.userCertificateCredentialComponents ? null : this.userCertificateCredentialComponents.find(cmp => cmp.isDirty())
return !!dirtyComp;
}
}
......
......@@ -317,4 +317,9 @@ export class NavigationService extends MatTreeNestedDataSource<NavigationNode> {
return false;
}
public navigateToLogin(): void {
this.reset();
this.router.navigate(['/login'], {queryParams: {returnUrl: this.router.url}});
this.router.parseUrl('/login');
}
}
......@@ -30,7 +30,7 @@ public class TruststoreController {
this.payloadValidatorService = payloadValidatorService;
}
@PreAuthorize("@smpAuthorizationService.systemAdministrator || @smpAuthorizationService.isCurrentlyLoggedIn(#userId)")
@PreAuthorize("@smpAuthorizationService.isCurrentlyLoggedIn(#userId)")
@PostMapping(path = "/{user-id}/validate-certificate", consumes = MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
public CertificateRO validateCertificate(@PathVariable("user-id") String userId, @RequestBody byte[] data) {
LOG.info("Got certificate data size: {}", data.length);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment