This commit is contained in:
2020-03-02 18:47:04 +01:00
committed by smuddy
parent 5b746e0db5
commit ccd91aa81c
93 changed files with 444 additions and 89 deletions

View File

@@ -0,0 +1,7 @@
<app-card *ngIf="user$|async as user">
<h2>Hallo {{user.name}}</h2>
<p>{{user.role|role}}</p>
<app-button-row>
<button mat-button routerLink="../logout">Abmelden</button>
</app-button-row>
</app-card>

View File

@@ -0,0 +1,25 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {InfoComponent} from './info.component';
describe('InfoComponent', () => {
let component: InfoComponent;
let fixture: ComponentFixture<InfoComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [InfoComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(InfoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,21 @@
import {Component, OnInit} from '@angular/core';
import {UserService} from '../../../services/user.service';
import {Observable} from 'rxjs';
import {User} from '../../../services/user';
@Component({
selector: 'app-info',
templateUrl: './info.component.html',
styleUrls: ['./info.component.less']
})
export class InfoComponent implements OnInit {
public user$: Observable<User>;
constructor(private userService: UserService) {
}
ngOnInit() {
this.user$ = this.userService.user$;
}
}

View File

@@ -0,0 +1,8 @@
import {RolePipe} from './role.pipe';
describe('RolePipe', () => {
it('create an instance', () => {
const pipe = new RolePipe();
expect(pipe).toBeTruthy();
});
});

View File

@@ -0,0 +1,15 @@
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'role'
})
export class RolePipe implements PipeTransform {
transform(role: 'admin'): string {
switch (role) {
case 'admin':
return 'Administrator';
}
}
}

View File

@@ -0,0 +1,8 @@
import {AuthMessagePipe} from './auth-message.pipe';
describe('AuthMessagePipe', () => {
it('create an instance', () => {
const pipe = new AuthMessagePipe();
expect(pipe).toBeTruthy();
});
});

View File

@@ -0,0 +1,19 @@
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'authMessage'
})
export class AuthMessagePipe implements PipeTransform {
transform(code: string): string {
switch (code) {
case 'auth/user-not-found':
return 'Benutzer wurde nicht gefunden';
case 'auth/wrong-password':
return 'Passwort ist falsch';
default :
return code;
}
}
}

View File

@@ -0,0 +1,19 @@
<app-card>
<div [formGroup]="form" class="form">
<mat-form-field appearance="outline">
<mat-label>E-Mail Addresse</mat-label>
<input (keyup.enter)="onLogin()" formControlName="user" matInput>
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>Passwort</mat-label>
<input (keyup.enter)="onLogin()" formControlName="pass" matInput type="password">
</mat-form-field>
<app-button-row>
<button (click)="onLogin()" mat-button>Anmelden</button>
<p *ngIf="errorMessage" class="error">{{errorMessage|authMessage}}</p>
</app-button-row>
</div>
</app-card>

View File

@@ -0,0 +1,8 @@
.form {
display: grid;
}
p.error {
margin: 8px 10px;
color: darkred;
}

View File

@@ -0,0 +1,25 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {LoginComponent} from './login.component';
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [LoginComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,36 @@
import {Component, OnInit} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import {AngularFireAuth} from '@angular/fire/auth';
import {Router} from '@angular/router';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.less']
})
export class LoginComponent implements OnInit {
public form: FormGroup;
public errorMessage: string;
constructor(public afAuth: AngularFireAuth, private router: Router) {
}
ngOnInit() {
this.form = new FormGroup({
user: new FormControl(null, [Validators.required, Validators.email]),
pass: new FormControl(null, [Validators.required]),
});
}
public async onLogin() {
this.form.updateValueAndValidity();
if (this.form.valid) {
try {
await this.afAuth.auth.signInWithEmailAndPassword(this.form.value.user, this.form.value.pass);
await this.router.navigateByUrl('/');
} catch (ex) {
this.errorMessage = ex.code;
}
}
}
}

View File

@@ -0,0 +1 @@
<p>logout works!</p>

View File

@@ -0,0 +1,25 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {LogoutComponent} from './logout.component';
describe('LogoutComponent', () => {
let component: LogoutComponent;
let fixture: ComponentFixture<LogoutComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [LogoutComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LogoutComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,18 @@
import {AfterViewInit, Component} from '@angular/core';
import {AngularFireAuth} from '@angular/fire/auth';
import {Router} from '@angular/router';
@Component({
selector: 'app-logout',
templateUrl: './logout.component.html',
styleUrls: ['./logout.component.less']
})
export class LogoutComponent implements AfterViewInit {
constructor(public afAuth: AngularFireAuth, private router: Router) {
}
public async ngAfterViewInit() {
await this.afAuth.auth.signOut();
await this.router.navigateByUrl('/');
}
}

View File

@@ -0,0 +1,36 @@
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {LoginComponent} from './login/login.component';
import {InfoComponent} from './info/info.component';
import {LogoutComponent} from './logout/logout.component';
import {AngularFireAuthGuard, redirectUnauthorizedTo} from '@angular/fire/auth-guard';
const routes: Routes = [
{
path: '',
redirectTo: 'info',
pathMatch: 'full'
},
{
path: 'login',
component: LoginComponent
},
{
path: 'logout',
component: LogoutComponent
},
{
path: 'info',
component: InfoComponent,
canActivate: [AngularFireAuthGuard],
data: {authGuardPipe: () => redirectUnauthorizedTo(['user', 'login'])}
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class UserRoutingModule {
}

View File

@@ -0,0 +1,33 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {LoginComponent} from './login/login.component';
import {UserRoutingModule} from './user-routing.module';
import {CardModule} from '../../widget-modules/components/card/card.module';
import {MatFormFieldModule} from '@angular/material/form-field';
import {ReactiveFormsModule} from '@angular/forms';
import {MatInputModule} from '@angular/material/input';
import {ButtonRowModule} from '../../widget-modules/components/button-row/button-row.module';
import {MatButtonModule} from '@angular/material/button';
import {AuthMessagePipe} from './login/auth-message.pipe';
import {InfoComponent} from './info/info.component';
import {LogoutComponent} from './logout/logout.component';
import {RolePipe} from './info/role.pipe';
@NgModule({
declarations: [LoginComponent, AuthMessagePipe, InfoComponent, LogoutComponent, RolePipe],
imports: [
CommonModule,
UserRoutingModule,
CardModule,
MatFormFieldModule,
ReactiveFormsModule,
MatInputModule,
ButtonRowModule,
MatButtonModule,
]
})
export class UserModule {
}