Added password change page

This commit is contained in:
Lukas Metzger 2018-04-08 16:48:56 +02:00
parent 9c001d9d88
commit 7d063fde98
11 changed files with 113 additions and 6 deletions

View file

@ -1,3 +1,4 @@
import { PasswordComponent } from './pages/password/password.component';
import { AuthGuard } from './services/auth-guard.service';
import { DomainsComponent } from './pages/domains/domains.component';
import { NgModule } from '@angular/core';
@ -24,6 +25,10 @@ const routes: Routes = [
path: 'domains',
component: DomainsComponent
},
{
path: 'password',
component: PasswordComponent
},
{
path: '**',
redirectTo: '/'

View file

@ -1,5 +1,6 @@
<app-navbar *ngIf="gs.isLoggedIn" brand="PDNS Manager">
<app-navbar-entry icon="navicon" target="/domains">Domains</app-navbar-entry>
<app-navbar-entry icon="key" target="/password">Password</app-navbar-entry>
<app-navbar-entry icon="sign-out" right (click)="onLogout()" neverActive>Logout</app-navbar-entry>
</app-navbar>

View file

@ -1,3 +1,4 @@
import { PasswordOperation } from './operations/password.operations';
import { AuthGuard } from './services/auth-guard.service';
import { FocusDirective } from './utils/Focus.directive';
import { BrowserModule } from '@angular/platform-browser';
@ -19,6 +20,7 @@ import { StateService } from './services/state.service';
import { HttpService } from './services/http.service';
import { SessionOperation } from './operations/session.operation';
import { DomainsComponent } from './pages/domains/domains.component';
import { PasswordComponent } from './pages/password/password.component';
@NgModule({
declarations: [
@ -32,7 +34,8 @@ import { DomainsComponent } from './pages/domains/domains.component';
ModalContainerComponent,
LoginComponent,
DomainsComponent,
FocusDirective
FocusDirective,
PasswordComponent
],
imports: [
BrowserModule,
@ -44,6 +47,7 @@ import { DomainsComponent } from './pages/domains/domains.component';
StateService,
HttpService,
SessionOperation,
PasswordOperation,
AuthGuard
],
bootstrap: [AppComponent]

View file

@ -0,0 +1,24 @@
import { UserApitype } from './../apitypes/User.apitype';
import { Injectable } from '@angular/core';
import { HttpService } from '../services/http.service';
import { StateService } from '../services/state.service';
import { SessionApitype } from '../apitypes/Session.apitype';
@Injectable()
export class PasswordOperation {
constructor(private http: HttpService, private gs: StateService) { }
public async changePassword(password: string): Promise<boolean> {
try {
await this.http.put('/users/me', {
password: password
});
return true;
} catch (e) {
console.error(e);
return false;
}
}
}

View file

@ -2,7 +2,6 @@ import { UserApitype } from './../apitypes/User.apitype';
import { Injectable } from '@angular/core';
import { HttpService } from '../services/http.service';
import { StateService } from '../services/state.service';
import { AxiosResponse, AxiosError } from 'axios';
import { SessionApitype } from '../apitypes/Session.apitype';
@Injectable()

View file

@ -11,12 +11,12 @@ import { SessionOperation } from '../../operations/session.operation';
styleUrls: ['./login.component.scss']
})
export class LoginComponent {
loginForm: FormGroup;
public loginForm: FormGroup;
loginError = false;
public loginError = false;
constructor(private router: Router, private fb: FormBuilder, public gs: StateService,
public sessions: SessionOperation, private route: ActivatedRoute) {
private sessions: SessionOperation, private route: ActivatedRoute) {
this.createForm();
}

View file

@ -0,0 +1,29 @@
<div class="row">
<div class="col-12 col-md-6 col-lg-3">
<p class="font-weight-bold">Change your password:</p>
<form autocomplete="off" [formGroup]="passwordForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control auto-validstate" formControlName="password" appFocus />
<div class="invalid-feedback">
Password is required.
</div>
</div>
<div class="form-group">
<label>Repeat password</label>
<input type="password" class="form-control auto-validstate" formControlName="password2" />
<div class="invalid-feedback">
Passwords do not match.
</div>
</div>
<app-alert type="success" *ngIf="changeSuccessfull">
<app-alert-message>Password change sucessfull.</app-alert-message>
</app-alert>
<button type="submit" class="btn btn-success float-right" [disabled]="!passwordForm.valid">Change</button>
</form>
</div>
</div>

View file

@ -0,0 +1,32 @@
import { PasswordOperation } from './../../operations/password.operations';
import { PasswordValidationUtil } from './../../utils/PasswordValidation.util';
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-password',
templateUrl: './password.component.html',
styleUrls: ['./password.component.scss']
})
export class PasswordComponent {
public passwordForm: FormGroup;
public changeSuccessfull = false;
constructor(private fb: FormBuilder, private password: PasswordOperation) {
this.createForm();
}
private createForm() {
this.passwordForm = this.fb.group({
password: ['', Validators.required],
password2: ['', Validators.required]
}, { validator: PasswordValidationUtil.matchPassword });
}
public async onSubmit() {
this.changeSuccessfull = await this.password.changePassword(this.passwordForm.value.password);
setTimeout(() => this.changeSuccessfull = false, 3000);
}
}

View file

@ -16,7 +16,6 @@ export class HttpService {
}
public async get(url: string, params: Object = {}): Promise<any> {
console.log('Get request');
const parts = [];
for (const [k, v] of Object.entries(params)) {
let value;

View file

@ -0,0 +1,14 @@
import { AbstractControl } from '@angular/forms';
export class PasswordValidationUtil {
static matchPassword(ac: AbstractControl) {
const password = ac.get('password').value;
const password2 = ac.get('password2').value;
if (password !== password2) {
ac.get('password2').setErrors({ matchPassword: true });
} else {
return null;
}
}
}