made the error experience better. authentication failures now take the shape of a snackbar. pre-authentication failures (i.e. improperly formatted email) now show up on the bottom of the input field

pull/1/head
Chris Veilleux 2019-02-04 15:09:28 -06:00
parent c5a8729a58
commit 154910e853
3 changed files with 49 additions and 50 deletions

View File

@ -1,33 +1,37 @@
<form
fxLayout="column"
#loginForm="ngForm"
(ngSubmit)="authorizeUser()"
>
<mat-form-field>
<fa-icon [icon]="usernameIcon" matPrefix></fa-icon>
<mat-label>Email Address</mat-label>
<input
id="username"
matInput
name="username"
placeholder="Email Address"
required
type="text"
[(ngModel)]="username"
[(ngModel)]="emailAddress"
[formControl]="emailFormControl"
>
<mat-hint>Mycroft Account Email</mat-hint>
<mat-error *ngIf="emailFormControl.hasError('email') && !emailFormControl.hasError('required')">
Must be a valid email address
</mat-error>
<mat-error *ngIf="emailFormControl.hasError('required')">
Email is required
</mat-error>
</mat-form-field>
<mat-form-field>
<fa-icon [icon]="passwordIcon" matPrefix></fa-icon>
<mat-label>Password</mat-label>
<input
id="password"
matInput
name="password"
placeholder="Password"
required
type="password"
[(ngModel)]="password"
[formControl]="passwordFormControl"
>
<mat-hint>Forgot password?</mat-hint>
<mat-hint>Mycroft Account Password</mat-hint>
<mat-error *ngIf="passwordFormControl.hasError('required')">
Password is required
</mat-error>
</mat-form-field>
<button mat-button type="submit">LOG IN</button>
<a class="mat-body-2" href="http://market.mycroft-test.net">Forgot password?</a>
</form>
<div class="mat-body-2" *ngIf="authFailed">Invalid username/password combination; try again</div>

View File

@ -6,27 +6,24 @@ form {
border-radius: 10px;
padding: 16px;
fa-icon {
color: mat-color($mycroft-accent, A700);
margin-right: 16px;
mat-form-field {
margin-bottom: 8px;
}
mat-checkbox {
color: mat-color($mycroft-accent, A700);
}
#forgot-password {
margin-left: 32px;
}
button {
@include action-button-primary;
margin-top: 32px;
margin-bottom: 8px;
margin-top: 8px;
text-align: center;
}
}
a {
margin-left: auto;
margin-right: auto;
}
.mat-body-2 {
color: red;
padding: 16px;
}

View File

@ -1,43 +1,41 @@
import { Component, OnInit } from '@angular/core';
import { faLock, faUser } from '@fortawesome/free-solid-svg-icons';
import { FormControl, Validators } from '@angular/forms';
import { MatSnackBar } from '@angular/material';
import { AuthResponse, AppService } from '../../app.service';
const noDelay = 0;
const tenSeconds = 10000;
@Component({
selector: 'sso-internal-login',
templateUrl: './internal-login.component.html',
styleUrls: ['./internal-login.component.scss']
})
export class InternalLoginComponent implements OnInit {
public authFailed: boolean;
public password: string;
public passwordIcon = faLock;
public username: string;
public usernameIcon = faUser;
public emailAddress: string;
public emailFormControl = new FormControl(null, [Validators.email, Validators.required]);
public passwordFormControl = new FormControl(null, [Validators.required]);
constructor(private authService: AppService) { }
constructor(private authService: AppService, private errorSnackbar: MatSnackBar) { }
ngOnInit() { }
ngOnInit() { }
authorizeUser(): void {
this.authService.authorizeInternal(this.username, this.password).subscribe(
(response) => { this.onAuthSuccess(response); },
(response) => { this.onAuthFailure(response); }
);
}
onAuthSuccess(authResponse: AuthResponse): void {
this.authFailed = false;
this.authService.generateTokenCookies(authResponse);
this.authService.navigateToRedirectURI(noDelay);
}
onAuthFailure(authorizeUserResponse): void {
if (authorizeUserResponse.status === 401) {
this.authFailed = true;
}
}
authorizeUser(): void {
this.authService.authorizeInternal(this.emailAddress, this.password).subscribe(
(response) => { this.authService.navigateToRedirectURI(noDelay); },
(response) => { this.onAuthFailure(response); }
);
}
onAuthFailure(authorizeUserResponse): void {
if (authorizeUserResponse.status === 401) {
this.errorSnackbar.open(
'Authentication error, please try again',
null,
{panelClass: 'mycroft-no-action-snackbar', duration: tenSeconds}
);
}
}
}