Initial application generated by JHipster-5.8.2
This commit is contained in:
@ -0,0 +1,85 @@
|
||||
import { Component, ElementRef, Input, Renderer } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'jhi-password-strength-bar',
|
||||
template: `
|
||||
<div id="strength">
|
||||
<small jhiTranslate="global.messages.validate.newpassword.strength">Password strength:</small>
|
||||
<ul id="strengthBar">
|
||||
<li class="point"></li>
|
||||
<li class="point"></li>
|
||||
<li class="point"></li>
|
||||
<li class="point"></li>
|
||||
<li class="point"></li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
styleUrls: ['password-strength-bar.css']
|
||||
})
|
||||
export class PasswordStrengthBarComponent {
|
||||
colors = ['#F00', '#F90', '#FF0', '#9F0', '#0F0'];
|
||||
|
||||
constructor(private renderer: Renderer, private elementRef: ElementRef) {}
|
||||
|
||||
measureStrength(p: string): number {
|
||||
let force = 0;
|
||||
const regex = /[$-/:-?{-~!"^_`\[\]]/g; // "
|
||||
const lowerLetters = /[a-z]+/.test(p);
|
||||
const upperLetters = /[A-Z]+/.test(p);
|
||||
const numbers = /[0-9]+/.test(p);
|
||||
const symbols = regex.test(p);
|
||||
|
||||
const flags = [lowerLetters, upperLetters, numbers, symbols];
|
||||
const passedMatches = flags.filter((isMatchedFlag: boolean) => {
|
||||
return isMatchedFlag === true;
|
||||
}).length;
|
||||
|
||||
force += 2 * p.length + (p.length >= 10 ? 1 : 0);
|
||||
force += passedMatches * 10;
|
||||
|
||||
// penalty (short password)
|
||||
force = p.length <= 6 ? Math.min(force, 10) : force;
|
||||
|
||||
// penalty (poor variety of characters)
|
||||
force = passedMatches === 1 ? Math.min(force, 10) : force;
|
||||
force = passedMatches === 2 ? Math.min(force, 20) : force;
|
||||
force = passedMatches === 3 ? Math.min(force, 40) : force;
|
||||
|
||||
return force;
|
||||
}
|
||||
|
||||
getColor(s: number): any {
|
||||
let idx = 0;
|
||||
if (s <= 10) {
|
||||
idx = 0;
|
||||
} else if (s <= 20) {
|
||||
idx = 1;
|
||||
} else if (s <= 30) {
|
||||
idx = 2;
|
||||
} else if (s <= 40) {
|
||||
idx = 3;
|
||||
} else {
|
||||
idx = 4;
|
||||
}
|
||||
return { idx: idx + 1, col: this.colors[idx] };
|
||||
}
|
||||
|
||||
@Input()
|
||||
set passwordToCheck(password: string) {
|
||||
if (password) {
|
||||
const c = this.getColor(this.measureStrength(password));
|
||||
const element = this.elementRef.nativeElement;
|
||||
if (element.className) {
|
||||
this.renderer.setElementClass(element, element.className, false);
|
||||
}
|
||||
const lis = element.getElementsByTagName('li');
|
||||
for (let i = 0; i < lis.length; i++) {
|
||||
if (i < c.idx) {
|
||||
this.renderer.setElementStyle(lis[i], 'backgroundColor', c.col);
|
||||
} else {
|
||||
this.renderer.setElementStyle(lis[i], 'backgroundColor', '#DDD');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
/* ==========================================================================
|
||||
start Password strength bar style
|
||||
========================================================================== */
|
||||
ul#strengthBar {
|
||||
display: inline;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
margin-left: 15px;
|
||||
padding: 0;
|
||||
vertical-align: 2px;
|
||||
}
|
||||
|
||||
.point {
|
||||
background: #ddd;
|
||||
border-radius: 2px;
|
||||
display: inline-block;
|
||||
height: 5px;
|
||||
margin-right: 1px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.point:last-child {
|
||||
margin: 0 !important;
|
||||
}
|
77
src/main/webapp/app/account/password/password.component.html
Normal file
77
src/main/webapp/app/account/password/password.component.html
Normal file
@ -0,0 +1,77 @@
|
||||
<div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<h2 jhiTranslate="password.title" [translateValues]="{username: account.login}" *ngIf="account">Password for [<b>{{account.login}}</b>]</h2>
|
||||
|
||||
<div class="alert alert-success" *ngIf="success" jhiTranslate="password.messages.success">
|
||||
<strong>Password changed!</strong>
|
||||
</div>
|
||||
<div class="alert alert-danger" *ngIf="error" jhiTranslate="password.messages.error">
|
||||
<strong>An error has occurred!</strong> The password could not be changed.
|
||||
</div>
|
||||
|
||||
<div class="alert alert-danger" *ngIf="doNotMatch" jhiTranslate="global.messages.error.dontmatch">
|
||||
The password and its confirmation do not match!
|
||||
</div>
|
||||
|
||||
<form name="form" role="form" (ngSubmit)="changePassword()" #passwordForm="ngForm">
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-control-label" for="currentPassword" jhiTranslate="global.form.currentpassword">Current password</label>
|
||||
<input type="password" class="form-control" id="currentPassword" name="currentPassword" #currentPasswordInput="ngModel"
|
||||
placeholder="{{'global.form.currentpassword.placeholder' | translate}}"
|
||||
[(ngModel)]="currentPassword" required>
|
||||
<div *ngIf="currentPasswordInput.dirty && currentPasswordInput.invalid">
|
||||
<small class="form-text text-danger"
|
||||
*ngIf="currentPasswordInput.errors.required" jhiTranslate="global.messages.validate.newpassword.required">
|
||||
Your password is required.
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-control-label" for="newPassword" jhiTranslate="global.form.newpassword">New password</label>
|
||||
<input type="password" class="form-control" id="newPassword" name="newPassword" #newPasswordInput="ngModel"
|
||||
placeholder="{{'global.form.newpassword.placeholder' | translate}}"
|
||||
[(ngModel)]="newPassword" minlength=4 maxlength=50 required>
|
||||
<div *ngIf="newPasswordInput.dirty && newPasswordInput.invalid">
|
||||
<small class="form-text text-danger"
|
||||
*ngIf="newPasswordInput.errors.required" jhiTranslate="global.messages.validate.newpassword.required">
|
||||
Your password is required.
|
||||
</small>
|
||||
<small class="form-text text-danger"
|
||||
*ngIf="newPasswordInput.errors.minlength" jhiTranslate="global.messages.validate.newpassword.minlength">
|
||||
Your password is required to be at least 4 characters.
|
||||
</small>
|
||||
<small class="form-text text-danger"
|
||||
*ngIf="newPasswordInput.errors.maxlength" jhiTranslate="global.messages.validate.newpassword.maxlength">
|
||||
Your password cannot be longer than 50 characters.
|
||||
</small>
|
||||
</div>
|
||||
<jhi-password-strength-bar [passwordToCheck]="newPassword"></jhi-password-strength-bar>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-control-label" for="confirmPassword" jhiTranslate="global.form.confirmpassword">New password confirmation</label>
|
||||
<input type="password" class="form-control" id="confirmPassword" name="confirmPassword" #confirmPasswordInput="ngModel"
|
||||
placeholder="{{'global.form.confirmpassword.placeholder' | translate}}"
|
||||
[(ngModel)]="confirmPassword" minlength=4 maxlength=50 required>
|
||||
<div *ngIf="confirmPasswordInput.dirty && confirmPasswordInput.invalid">
|
||||
<small class="form-text text-danger"
|
||||
*ngIf="confirmPasswordInput.errors.required" jhiTranslate="global.messages.validate.confirmpassword.required">
|
||||
Your confirmation password is required.
|
||||
</small>
|
||||
<small class="form-text text-danger"
|
||||
*ngIf="confirmPasswordInput.errors.minlength" jhiTranslate="global.messages.validate.confirmpassword.minlength">
|
||||
Your confirmation password is required to be at least 4 characters.
|
||||
</small>
|
||||
<small class="form-text text-danger"
|
||||
*ngIf="confirmPasswordInput.errors.maxlength" jhiTranslate="global.messages.validate.confirmpassword.maxlength">
|
||||
Your confirmation password cannot be longer than 50 characters.
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" [disabled]="passwordForm.form.invalid" class="btn btn-primary" jhiTranslate="password.form.button">Save</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
46
src/main/webapp/app/account/password/password.component.ts
Normal file
46
src/main/webapp/app/account/password/password.component.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { AccountService } from 'app/core';
|
||||
import { PasswordService } from './password.service';
|
||||
|
||||
@Component({
|
||||
selector: 'jhi-password',
|
||||
templateUrl: './password.component.html'
|
||||
})
|
||||
export class PasswordComponent implements OnInit {
|
||||
doNotMatch: string;
|
||||
error: string;
|
||||
success: string;
|
||||
account: any;
|
||||
currentPassword: string;
|
||||
newPassword: string;
|
||||
confirmPassword: string;
|
||||
|
||||
constructor(private passwordService: PasswordService, private accountService: AccountService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.accountService.identity().then(account => {
|
||||
this.account = account;
|
||||
});
|
||||
}
|
||||
|
||||
changePassword() {
|
||||
if (this.newPassword !== this.confirmPassword) {
|
||||
this.error = null;
|
||||
this.success = null;
|
||||
this.doNotMatch = 'ERROR';
|
||||
} else {
|
||||
this.doNotMatch = null;
|
||||
this.passwordService.save(this.newPassword, this.currentPassword).subscribe(
|
||||
() => {
|
||||
this.error = null;
|
||||
this.success = 'OK';
|
||||
},
|
||||
() => {
|
||||
this.success = null;
|
||||
this.error = 'ERROR';
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
14
src/main/webapp/app/account/password/password.route.ts
Normal file
14
src/main/webapp/app/account/password/password.route.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Route } from '@angular/router';
|
||||
|
||||
import { UserRouteAccessService } from 'app/core';
|
||||
import { PasswordComponent } from './password.component';
|
||||
|
||||
export const passwordRoute: Route = {
|
||||
path: 'password',
|
||||
component: PasswordComponent,
|
||||
data: {
|
||||
authorities: ['ROLE_USER'],
|
||||
pageTitle: 'global.menu.account.password'
|
||||
},
|
||||
canActivate: [UserRouteAccessService]
|
||||
};
|
14
src/main/webapp/app/account/password/password.service.ts
Normal file
14
src/main/webapp/app/account/password/password.service.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { SERVER_API_URL } from 'app/app.constants';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class PasswordService {
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
save(newPassword: string, currentPassword: string): Observable<any> {
|
||||
return this.http.post(SERVER_API_URL + 'api/account/change-password', { currentPassword, newPassword });
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user