diff --git a/client/src/app/shared/password-input/password-input.component.html b/client/src/app/shared/password-input/password-input.component.html new file mode 100644 index 0000000000000000000000000000000000000000..c348074d362ae4b2d722f7731712c776617197fb --- /dev/null +++ b/client/src/app/shared/password-input/password-input.component.html @@ -0,0 +1,13 @@ +<label> + {{label}} + + <input + [type]="isVisible ? 'text' : 'password'" + [placeholder]="placeholder" + [(ngModel)]="inputModel" + (ngModelChange)="inputModelChange.emit(inputModel)" + (change)="change.emit($event)" + (focus)="focus.emit($event)" + (blur)="blur.emit($event)"> + <app-button (click)="togglePasswordVisible()" [text]="toggleText"></app-button> +</label> \ No newline at end of file diff --git a/client/src/app/shared/password-input/password-input.component.scss b/client/src/app/shared/password-input/password-input.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..00cdc2a928d04283ff39dc2652060db7868d0e76 --- /dev/null +++ b/client/src/app/shared/password-input/password-input.component.scss @@ -0,0 +1,3 @@ +input{ + padding: 5px; +} \ No newline at end of file diff --git a/client/src/app/shared/password-input/password-input.component.spec.ts b/client/src/app/shared/password-input/password-input.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..e1a583ebf97f377951e4c45c6a18ffa72574a073 --- /dev/null +++ b/client/src/app/shared/password-input/password-input.component.spec.ts @@ -0,0 +1,27 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule } from '@angular/forms'; + +import { PasswordInputComponent } from './password-input.component'; + +describe('PasswordInputComponent', () => { + let component: PasswordInputComponent; + let fixture: ComponentFixture<PasswordInputComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ PasswordInputComponent ], + imports: [ FormsModule ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PasswordInputComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/client/src/app/shared/password-input/password-input.component.ts b/client/src/app/shared/password-input/password-input.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..1de87ce717ae8c560437c9ab698a7f7f88a0f0d0 --- /dev/null +++ b/client/src/app/shared/password-input/password-input.component.ts @@ -0,0 +1,41 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; + +@Component({ + selector: 'app-password-input', + templateUrl: './password-input.component.html', + styleUrls: ['./password-input.component.scss'] +}) +export class PasswordInputComponent { + + isVisible: boolean = false; + toggleText: string = "show"; + + @Input() + label: string = ""; + + @Input() + inputModel: string; + + @Input() + placeholder: string = ""; + + @Output() + inputModelChange = new EventEmitter<string>(); + + @Output() + change = new EventEmitter(); + + @Output() + focus = new EventEmitter(); + + @Output() + blur = new EventEmitter(); + + constructor() { } + + togglePasswordVisible() { + this.isVisible = !this.isVisible; + this.toggleText = this.isVisible ? "hide" : "show"; + } + +} diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index 8459044413a154cba6617960c61140ff610119a9..765f8a9a5cd60df1b854ba9c8335554bdf29aa2f 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts @@ -1,7 +1,8 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { TextInputComponent } from './text-input/text-input.component'; import { FormsModule } from '@angular/forms'; +import { TextInputComponent } from './text-input/text-input.component'; +import { PasswordInputComponent } from './password-input/password-input.component'; import { NumberInputComponent } from './number-input/number-input.component'; import { ButtonComponent } from './button/button.component'; import { SelectComponent } from './select/select.component'; @@ -12,11 +13,13 @@ import { SelectComponent } from './select/select.component'; TextInputComponent, NumberInputComponent, ButtonComponent, - SelectComponent + SelectComponent, + PasswordInputComponent ], exports: [ TextInputComponent, NumberInputComponent, + PasswordInputComponent, ButtonComponent, SelectComponent ], diff --git a/client/src/app/users/user-login-form/user-login-form.component.html b/client/src/app/users/user-login-form/user-login-form.component.html index eef16a753d7e6b413b223860361a29d1eb1a647a..b1ce307b2e409dcd4d35e166b2210cc9e99d81a0 100644 --- a/client/src/app/users/user-login-form/user-login-form.component.html +++ b/client/src/app/users/user-login-form/user-login-form.component.html @@ -3,7 +3,7 @@ <app-text-input [(inputModel)]="username" label="Brukernavn" (blur)="checkForm()"></app-text-input> - <app-text-input [(inputModel)]="password" label="Passord" (blur)="checkForm()"></app-text-input> + <app-password-input [(inputModel)]="password" label="Passord" (blur)="checkForm()"></app-password-input> <p>{{statusMessage}}</p> diff --git a/client/src/app/users/user-registration-form/user-registration-form.component.html b/client/src/app/users/user-registration-form/user-registration-form.component.html index 5542f8e32b34e3079cd8ed997c179fb35b205faf..2078e7de7f23d82ba33c84a0c5c8a67c545343af 100644 --- a/client/src/app/users/user-registration-form/user-registration-form.component.html +++ b/client/src/app/users/user-registration-form/user-registration-form.component.html @@ -5,7 +5,9 @@ <app-text-input [(inputModel)]="email" label="Epost" (blur)="checkForm()"></app-text-input> - <app-text-input [(inputModel)]="password" label="Passord" (blur)="checkForm()"></app-text-input> + <app-password-input [(inputModel)]="password" label="Passord" (blur)="checkForm()"></app-password-input> + + <app-password-input [(inputModel)]="confirm_password" label="Bekreft passord" (blur)="checkForm()"></app-password-input> <p>{{statusMessage}}</p> diff --git a/client/src/app/users/user-registration-form/user-registration-form.component.ts b/client/src/app/users/user-registration-form/user-registration-form.component.ts index 25cf7f669a89962b54b71983b54f4f03ea547e12..9bccc2204127c5793421142e8d11a91dda2a4a4e 100644 --- a/client/src/app/users/user-registration-form/user-registration-form.component.ts +++ b/client/src/app/users/user-registration-form/user-registration-form.component.ts @@ -13,6 +13,7 @@ export class UserRegistrationFormComponent implements OnInit { username: string = ""; email: string = ""; password: string = ""; + confirm_password: string = ""; statusMessage: string = ""; @@ -37,6 +38,14 @@ export class UserRegistrationFormComponent implements OnInit { this.setStatusMessage("Passordet kan ikke være tom"); return false; } + else if (this.confirm_password == "") { + this.setStatusMessage("Passordet kan ikke være tom"); + return false; + } + else if (this.confirm_password !== this.password) { + this.setStatusMessage("Passordene gitt samsvarer ikke"); + return false; + } this.setStatusMessage(""); return true; @@ -56,7 +65,7 @@ export class UserRegistrationFormComponent implements OnInit { // Adds user to database and changes page afterwards this.authService.registerUser(newUser).then(status => { console.log("User was added: " + JSON.stringify(status)); - this.router.navigateByUrl("/"); + this.router.navigateByUrl("/login"); }).catch(error => { console.log("Error adding user: " + error); }); diff --git a/client/src/app/users/user.service.spec.ts b/client/src/app/users/user.service.spec.ts index 4896330522c5ff8656e82647f1c17287f5e08920..e0577bfad4be1dd5e26776350e9b918bd3e3b27b 100644 --- a/client/src/app/users/user.service.spec.ts +++ b/client/src/app/users/user.service.spec.ts @@ -76,55 +76,5 @@ describe('UserService', () => { }); }); - describe('addUser', () => { - it('should add an user', () => { - const user = new User({ - userId: 1, - username: "zorg", - email: "blob@planet.us", - password: "Hyttepine", - create_time: 1613552549000, - }); - - // Adds user - service.addUser(user) - .then(post => {}) - .catch(error => { - fail(); - }); - - // Mocks and checks HTTP request - const req = httpMock.expectOne("api/user/"); - expect(req.request.method).toBe("POST"); - expect(req.request.body).toEqual(user.serialize()); - req.flush({ - data: [{ - status: "success" - }] - }); - }); - - it('should reject on http error', () => { - const user = new User({ - userId: 1, - username: "zorg", - email: "blob@planet.us", - password: "Hyttepine", - create_time: 1613552549000, - }); - - // Adds user, gets HTTP error, should catch - service.addUser(user).then(user => { - fail(); - }).catch(error => {}); - - // Mocks and checks HTTP request - const req = httpMock.expectOne("api/user/"); - expect(req.request.method).toBe("POST"); - expect(req.request.body).toEqual(user.serialize()); - req.error(new ErrorEvent("400")); - }); - }); - });