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

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

Pull request #148: [EDELIVERY-13784] submit login on enter event

Merge in EDELIVERY/smp from EDELIVERY-13784-as-a-user-i-would-like-to-press-enter-and-login-after-entering-username-and-password to development

* commit '7beca50f':
  [EDELIVERY-13784] submit login on enter event
parents 65a3b0f7 7beca50f
No related branches found
No related tags found
No related merge requests found
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
<ng-template #loginFormContainer> <ng-template #loginFormContainer>
<div [formGroup]="loginForm" class="form-control"> <div [formGroup]="loginForm" class="form-control" (ngSubmit)="login()" (keydown.enter)="onLoginFormEnterKeyDown($event)">
<mat-form-field style="width: 100%"> <mat-form-field style="width: 100%">
<mat-label>{{ "login.label.login.username" | translate }}</mat-label> <mat-label>{{ "login.label.login.username" | translate }}</mat-label>
<input matInput id="username_id" <input matInput id="username_id"
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
<mat-form-field style="width: 100%"> <mat-form-field style="width: 100%">
<mat-label>{{ "login.label.password" | translate }}</mat-label> <mat-label>{{ "login.label.password" | translate }}</mat-label>
<input matInput id="password_id" type="password" <input matInput id="password_id" type="password"
formControlName="password" required> formControlName="password" required>
</mat-form-field> </mat-form-field>
<button mat-raised-button color="primary" id="loginbutton_id" [disabled]="!loginForm.valid" <button mat-raised-button color="primary" id="loginbutton_id" [disabled]="!loginForm.valid"
......
import {Component, OnDestroy, OnInit} from '@angular/core'; import {Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router'; import {ActivatedRoute, Router} from '@angular/router';
import {SecurityService} from '../security/security.service'; import {SecurityService} from '../security/security.service';
import {AlertMessageService} from '../common/alert-message/alert-message.service'; import {
AlertMessageService
} from '../common/alert-message/alert-message.service';
import {SecurityEventService} from '../security/security-event.service'; import {SecurityEventService} from '../security/security-event.service';
import {User} from '../security/user.model'; import {User} from '../security/user.model';
import {MatDialog} from '@angular/material/dialog'; import {MatDialog} from '@angular/material/dialog';
import {DefaultPasswordDialogComponent} from 'app/security/default-password-dialog/default-password-dialog.component';
import {lastValueFrom, Subscription} from 'rxjs'; import {lastValueFrom, Subscription} from 'rxjs';
import { import {
ExpiredPasswordDialogComponent ExpiredPasswordDialogComponent
} from '../common/dialogs/expired-password-dialog/expired-password-dialog.component'; } from '../common/dialogs/expired-password-dialog/expired-password-dialog.component';
import {GlobalLookups} from "../common/global-lookups"; import {GlobalLookups} from "../common/global-lookups";
import {PasswordChangeDialogComponent} from "../common/dialogs/password-change-dialog/password-change-dialog.component"; import {
import {InformationDialogComponent} from "../common/dialogs/information-dialog/information-dialog.component"; PasswordChangeDialogComponent
} from "../common/dialogs/password-change-dialog/password-change-dialog.component";
import {
InformationDialogComponent
} from "../common/dialogs/information-dialog/information-dialog.component";
import {formatDate} from "@angular/common"; import {formatDate} from "@angular/common";
import {EntityStatus} from "../common/enums/entity-status.enum"; import {
import {FormControl, FormGroup, Validators} from "@angular/forms"; FormGroup,
UntypedFormBuilder,
UntypedFormControl,
UntypedFormGroup,
Validators
} from "@angular/forms";
import {TranslateService} from "@ngx-translate/core"; import {TranslateService} from "@ngx-translate/core";
import {WindowSpinnerService} from "../common/services/window-spinner.service";
@Component({ @Component({
templateUrl: './login.component.html', templateUrl: './login.component.html',
...@@ -24,8 +35,8 @@ import {TranslateService} from "@ngx-translate/core"; ...@@ -24,8 +35,8 @@ import {TranslateService} from "@ngx-translate/core";
}) })
export class LoginComponent implements OnInit, OnDestroy { export class LoginComponent implements OnInit, OnDestroy {
loginForm: FormGroup; loginForm: UntypedFormGroup;
resetForm: FormGroup; resetForm: UntypedFormGroup;
loading = false; loading = false;
returnUrl: string; returnUrl: string;
sub: Subscription; sub: Subscription;
...@@ -39,17 +50,28 @@ export class LoginComponent implements OnInit, OnDestroy { ...@@ -39,17 +50,28 @@ export class LoginComponent implements OnInit, OnDestroy {
private alertService: AlertMessageService, private alertService: AlertMessageService,
private securityEventService: SecurityEventService, private securityEventService: SecurityEventService,
private dialog: MatDialog, private dialog: MatDialog,
private translateService: TranslateService) { private translateService: TranslateService,
private fb: UntypedFormBuilder,
private windowSpinnerService: WindowSpinnerService) {
this.loginForm = fb.group({
'username': new UntypedFormControl({value: ''}, [Validators.required]),
'password': new UntypedFormControl({value: ''}, [Validators.required]),
});
this.resetForm = new FormGroup({
'resetUsername': new UntypedFormControl({value: ''}, [Validators.required]),
});
this.loginForm.controls['username'].setValue('');
this.loginForm.controls['password'].setValue('');
this.resetForm.controls['resetUsername'].setValue('');
} }
ngOnInit() { ngOnInit() {
this.initForm();
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
// make reference to this to be available in async functions where ''this'' is something else
this.sub = this.securityEventService.onLoginSuccessEvent().subscribe( this.sub = this.securityEventService.onLoginSuccessEvent().subscribe(
user => { user => {
if (user && user.passwordExpired) { if (user?.passwordExpired) {
if (user.forceChangeExpiredPassword) { if (user.forceChangeExpiredPassword) {
this.dialog.open(PasswordChangeDialogComponent, { this.dialog.open(PasswordChangeDialogComponent, {
data: { data: {
...@@ -82,10 +104,10 @@ export class LoginComponent implements OnInit, OnDestroy { ...@@ -82,10 +104,10 @@ export class LoginComponent implements OnInit, OnDestroy {
switch (error.status) { switch (error.status) {
case HTTP_UNAUTHORIZED: case HTTP_UNAUTHORIZED:
message = error.error.errorDescription; message = error.error.errorDescription;
this.loginForm['password'].setValue(''); this.loginForm.controls['password'].setValue('');
break; break;
case HTTP_FORBIDDEN: case HTTP_FORBIDDEN:
const forbiddenCode = error.message; const forbiddenCode = error?.message;
switch (forbiddenCode) { switch (forbiddenCode) {
case USER_INACTIVE: case USER_INACTIVE:
message = await lastValueFrom(this.translateService.get("login.error.inactive.user")); message = await lastValueFrom(this.translateService.get("login.error.inactive.user"));
...@@ -93,7 +115,7 @@ export class LoginComponent implements OnInit, OnDestroy { ...@@ -93,7 +115,7 @@ export class LoginComponent implements OnInit, OnDestroy {
default: default:
message = await lastValueFrom(this.translateService.get("login.error.invalid.credentials", {errorStatus: error.status})); message = await lastValueFrom(this.translateService.get("login.error.invalid.credentials", {errorStatus: error.status}));
// clear the password // clear the password
this.loginForm['password'].setValue(''); this.loginForm.controls['password'].setValue('');
break; break;
} }
break; break;
...@@ -109,24 +131,21 @@ export class LoginComponent implements OnInit, OnDestroy { ...@@ -109,24 +131,21 @@ export class LoginComponent implements OnInit, OnDestroy {
}); });
} }
private initForm() { onLoginFormEnterKeyDown(event: KeyboardEvent) {
this.loginForm = new FormGroup({ if (this.loginForm.valid
username: new FormControl('', Validators.required), && !this.windowSpinnerService.showSpinner) {
password: new FormControl('', Validators.required), event.preventDefault();
}); this.login();
}
this.resetForm = new FormGroup({
resetUsername: new FormControl('', Validators.required),
});
} }
async login() { async login() {
this.alertService.clearAlert(); this.alertService.clearAlert();
if (this.loginForm.valid) { if (this.loginForm.valid) {
this.securityService.login( this.securityService.login(
this.loginForm.get('username').value, this.loginForm.controls['username'].value,
this.loginForm.get('password').value this.loginForm.controls['password'].value
); );
} else { } else {
this.alertService.error(await lastValueFrom(this.translateService.get("login.error.invalid.username.or.password"))); this.alertService.error(await lastValueFrom(this.translateService.get("login.error.invalid.username.or.password")));
...@@ -137,7 +156,7 @@ export class LoginComponent implements OnInit, OnDestroy { ...@@ -137,7 +156,7 @@ export class LoginComponent implements OnInit, OnDestroy {
this.alertService.clearAlert(); this.alertService.clearAlert();
if (this.resetForm.valid) { if (this.resetForm.valid) {
this.securityService.requestCredentialReset( this.securityService.requestCredentialReset(
this.resetForm.get('resetUsername').value this.resetForm.controls['resetUsername'].value
); );
} else { } else {
this.alertService.error(await lastValueFrom(this.translateService.get("login.error.invalid.username"))); this.alertService.error(await lastValueFrom(this.translateService.get("login.error.invalid.username")));
......
...@@ -39,6 +39,7 @@ export class SecurityService { ...@@ -39,6 +39,7 @@ export class SecurityService {
} }
login(username: string, password: string) { login(username: string, password: string) {
this.windowSpinnerService.showSpinner = true;
let headers: HttpHeaders = new HttpHeaders({'Content-Type': 'application/json'}); let headers: HttpHeaders = new HttpHeaders({'Content-Type': 'application/json'});
return this.http.post<User>(SmpConstants.REST_PUBLIC_SECURITY_AUTHENTICATION, return this.http.post<User>(SmpConstants.REST_PUBLIC_SECURITY_AUTHENTICATION,
JSON.stringify({ JSON.stringify({
...@@ -52,9 +53,14 @@ export class SecurityService { ...@@ -52,9 +53,14 @@ export class SecurityService {
this.securityEventService.notifyLoginSuccessEvent(response); this.securityEventService.notifyLoginSuccessEvent(response);
}, },
error: (error: any) => { error: (error: any) => {
this.windowSpinnerService.showSpinner = false
this.alertService.error(error.error?.errorDescription) this.alertService.error(error.error?.errorDescription)
this.securityEventService.notifyLoginErrorEvent(error); this.securityEventService.notifyLoginErrorEvent(error);
}, complete: () => {
this.windowSpinnerService.showSpinner = false
} }
}); });
} }
......
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