From 93c506a3dbbf50cbf5bc5164ab6fb3b10f55704e Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 6 Mar 2020 00:58:43 +0100 Subject: [PATCH] Adding a password validator --- package-lock.json | 29 ++++++++++++++--- package.json | 1 + src/app/app.module.ts | 4 ++- src/app/login/login.component.html | 10 ++++-- src/app/login/login.component.ts | 13 ++++++-- src/app/misc/password-validator.ts | 26 +++++++++++++++ src/app/services/auth.service.ts | 51 ++++++++++++++++++++++++++++++ 7 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 src/app/misc/password-validator.ts create mode 100644 src/app/services/auth.service.ts diff --git a/package-lock.json b/package-lock.json index b818d5a9..ee1a231a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2895,8 +2895,7 @@ "base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" }, "batch": { "version": "0.6.1", @@ -3844,6 +3843,11 @@ "randomfill": "^1.0.3" } }, + "crypto-js": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", + "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" + }, "css-parse": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", @@ -6993,6 +6997,24 @@ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, + "oidc-client": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/oidc-client/-/oidc-client-1.10.1.tgz", + "integrity": "sha512-/QB5Nl7c9GmT9ir1E+OVY3+yZZnuk7Qa9ZEAJqSvDq0bAyAU9KAgeKipTEfKjGdGLTeOLy9FRWuNpULMkfZydQ==", + "requires": { + "base64-js": "^1.3.0", + "core-js": "^2.6.4", + "crypto-js": "^3.1.9-1", + "uuid": "^3.3.2" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + } + } + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -9777,8 +9799,7 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, "validate-npm-package-license": { "version": "3.0.4", diff --git a/package.json b/package.json index 39c798ce..a0e72f12 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "hammerjs": "^2.0.8", "hls.js": "^0.12.4", "jquery": "^3.4.1", + "oidc-client": "^1.10.1", "popper.js": "^1.16.1", "zone.js": "~0.9.1" }, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 56bd9327..162cc64b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -28,6 +28,7 @@ import {FormsModule, ReactiveFormsModule} from "@angular/forms"; import { MatInputModule } from "@angular/material/input"; import { MatFormFieldModule } from "@angular/material/form-field"; import {MatTabsModule} from "@angular/material/tabs"; +import {PasswordValidator} from "./misc/password-validator"; @NgModule({ declarations: [ @@ -41,7 +42,8 @@ import {MatTabsModule} from "@angular/material/tabs"; SearchComponent, PeopleListComponent, ShowsListComponent, - LoginComponent + LoginComponent, + PasswordValidator ], imports: [ BrowserModule, diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index 47f52fe2..e08a8b68 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -19,13 +19,16 @@
Password - + A password is required + + Error: {{signinPassword.getError("passwordError")["error"]}} + @@ -60,13 +63,16 @@
Password - + A password is required + + Error: {{signinPassword.getError("passwordError")["error"]}} +
diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index f5182f29..feb6d9e2 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import {FormControl, FormGroup, Validators} from "@angular/forms"; +import {AuthService} from "../services/auth.service"; @Component({ selector: 'app-login', @@ -12,7 +12,7 @@ export class LoginComponent signinInformation: {email: string, username: string, password: string} = {email: "", username: "", password: ""}; hidePassword: boolean = true; - constructor() { } + constructor(private authService: AuthService) { } async login() { @@ -21,6 +21,13 @@ export class LoginComponent async signin() { - console.log("Signing in") + this.authService.register(this.signinInformation) + .subscribe(result => + { + console.log("Sucess: " + result); + }, error => { + console.log("Register error: " + error); + }); + console.log("Register returned"); } } diff --git a/src/app/misc/password-validator.ts b/src/app/misc/password-validator.ts new file mode 100644 index 00000000..2f0c3d96 --- /dev/null +++ b/src/app/misc/password-validator.ts @@ -0,0 +1,26 @@ +import {AbstractControl, NG_VALIDATORS, Validator} from "@angular/forms"; +import {Directive} from "@angular/core"; + +@Directive({ + selector: "[passwordValidator]", + providers: [{provide: NG_VALIDATORS, useExisting: PasswordValidator, multi: true}] +}) +export class PasswordValidator implements Validator +{ + validate(control: AbstractControl): {[key: string]: any} | null + { + if (!control.value) + return null; + if (!/[a-z]/.test(control.value)) + return {"passwordError": {error: "The password must contains a lowercase letter."}}; + if (!/[A-Z]/.test(control.value)) + return {"passwordError": {error: "The password must contains an uppercase letter."}}; + if (!/[0-9]/.test(control.value)) + return {"passwordError": {error: "The password must contains a digit."}}; + if (!/\W/.test(control.value)) + return {"passwordError": {error: "The password must contains a non-alphanumeric character."}}; + if (control.value.toString().length < 6) + return {"passwordError": {error: "Password must be at least 6 character long."}}; + return null; + } +} \ No newline at end of file diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts new file mode 100644 index 00000000..87b89846 --- /dev/null +++ b/src/app/services/auth.service.ts @@ -0,0 +1,51 @@ +import { Injectable } from '@angular/core'; +import { UserManager, UserManagerSettings, User } from 'oidc-client'; +import {HttpClient} from "@angular/common/http"; +import { catchError } from 'rxjs/operators'; +import {EMPTY} from "rxjs"; +import {MatSnackBar} from "@angular/material/snack-bar"; + +@Injectable({ + providedIn: 'root' +}) +export class AuthService +{ + user: User | null; + private _userManager = new UserManager(this.getClientSettings()); + + constructor(private http: HttpClient, private snackBar: MatSnackBar) + { + this._userManager.getUser().then(user => + { + this.user = user; + if (user) + console.log("Logged in as: " + user.profile.name); + }); + } + + login() + { + return this._userManager.signinRedirect(); + } + + register(userRegistration: any) + { + return this.http.post("/api/account/register", userRegistration).pipe(catchError((error => + { + console.log(error.status + " - " + error.message); + this.snackBar.open(`An unknown error occured: ${error.message}.`, null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 }); + return EMPTY; + }))); + } + + getClientSettings(): UserManagerSettings + { + return { + authority: "", + client_id: "kyoo.webapp", + redirect_uri: "/logged", + response_type:"id_token token", + scope:"openid profile kyoo.read" + }; + } +}