From ca82df1b7ea89d988e76c4dad16856d90326e613 Mon Sep 17 00:00:00 2001 From: jleroy Date: Tue, 11 Mar 2025 12:05:07 +0100 Subject: [PATCH] auth back --- backend/controllers/authController.js | 4 +- .../_component/sidbar/sidbar.component.html | 4 +- src/app/_component/sidbar/sidbar.component.ts | 51 +++++++-- src/app/_services/auth.service.ts | 23 +++- src/app/public/pages/home/home.component.ts | 12 ++- .../public/pages/login/login.component.html | 57 ++++++++-- src/app/public/pages/login/login.component.ts | 69 +++++++++++- .../pages/not-found/not-found.component.ts | 12 ++- .../pages/register/register.component.html | 101 ++++++++++++++++-- .../pages/register/register.component.ts | 92 +++++++++++++++- .../public/pages/search/search.component.css | 0 .../public/pages/search/search.component.html | 0 .../public/pages/search/search.component.ts | 19 ---- src/app/public/public-routing.module.ts | 5 +- 14 files changed, 388 insertions(+), 61 deletions(-) delete mode 100644 src/app/public/pages/search/search.component.css delete mode 100644 src/app/public/pages/search/search.component.html delete mode 100644 src/app/public/pages/search/search.component.ts diff --git a/backend/controllers/authController.js b/backend/controllers/authController.js index 0be461e..b1dbb87 100644 --- a/backend/controllers/authController.js +++ b/backend/controllers/authController.js @@ -27,7 +27,7 @@ export const register = async (req, res) => { // Hash du mot de passe const hashedPassword = await bcrypt.hash(password_hash, 10); const result = await conn.query( - 'INSERT INTO users (email, firstname, lastname, password_hash) VALUES (?, ?, ?, ?, ?)', + 'INSERT INTO users (email, firstname, lastname, password_hash) VALUES (?, ?, ?, ?)', [email, firstname, lastname, hashedPassword] ); res.status(201).json({ @@ -83,7 +83,7 @@ export const login = async (req, res) => { 'UPDATE users SET updated_at = CURRENT_TIMESTAMP WHERE id = ?', [user.id] ); - await setLogs(email + " s'est connecté !") + res.cookie('jwt', token, { httpOnly: true, secure: true, diff --git a/src/app/_component/sidbar/sidbar.component.html b/src/app/_component/sidbar/sidbar.component.html index 6661e5c..c432250 100644 --- a/src/app/_component/sidbar/sidbar.component.html +++ b/src/app/_component/sidbar/sidbar.component.html @@ -85,8 +85,8 @@ Profile -
+

Entrez vos identifiants pour vous connecter

-
+ +
+ Inscription réussie ! Vous pouvez maintenant vous connecter. +
+ + +
+ {{ loginError }} +
+ + +
- + +
+
L'email est requis.
+
Veuillez entrer une adresse email valide.
+
+
- + +
+
Le mot de passe est requis.
+
-

- Pas encore de compte? S'inscrire + Pas encore de compte ? S'inscrire

diff --git a/src/app/public/pages/login/login.component.ts b/src/app/public/pages/login/login.component.ts index a82396a..9834619 100644 --- a/src/app/public/pages/login/login.component.ts +++ b/src/app/public/pages/login/login.component.ts @@ -1,14 +1,75 @@ -import { Component } from '@angular/core'; -import {RouterLink} from '@angular/router'; +import {Component, OnInit} from '@angular/core'; +import {ActivatedRoute, Router, RouterLink} from '@angular/router'; +import {Title} from '@angular/platform-browser'; +import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms'; +import {AuthService} from '../../../_services/auth.service'; +import {NgClass, NgIf} from '@angular/common'; @Component({ selector: 'app-login', imports: [ - RouterLink + RouterLink, + NgIf, + ReactiveFormsModule, + NgClass ], templateUrl: './login.component.html', styleUrl: './login.component.css' }) -export class LoginComponent { +export class LoginComponent implements OnInit { + loginForm: FormGroup; + isSubmitting = false; + loginError = ''; + registrationSuccess = false; + constructor( + private title: Title, + private fb: FormBuilder, + private authService: AuthService, + private router: Router, + private route: ActivatedRoute + ) { + this.loginForm = this.fb.group({ + email: ['', [Validators.required, Validators.email]], + password: ['', [Validators.required]] + }); + } + + ngOnInit(): void { + this.title.setTitle('Connexion - YouVideo'); + this.route.queryParams.subscribe(params => { + if (params['registered'] === 'success') { + this.registrationSuccess = true; + } + }); + } + + onSubmit(): void { + if (this.loginForm.invalid) { + Object.keys(this.loginForm.controls).forEach(key => { + const control = this.loginForm.get(key); + control?.markAsTouched(); + }); + return; + } + + this.isSubmitting = true; + this.loginError = ''; + + const loginData = { + email: this.loginForm.value.email, + password: this.loginForm.value.password + }; + + this.authService.login(loginData).subscribe({ + next: (response) => { + this.isSubmitting = false; + this.router.navigate(['/']); + }, + error: (error) => { + this.isSubmitting = false; + this.loginError = error.error?.message || 'Identifiants incorrects. Veuillez réessayer.'; + } + }); + } } diff --git a/src/app/public/pages/not-found/not-found.component.ts b/src/app/public/pages/not-found/not-found.component.ts index 8e7b578..dd624c7 100644 --- a/src/app/public/pages/not-found/not-found.component.ts +++ b/src/app/public/pages/not-found/not-found.component.ts @@ -1,4 +1,5 @@ -import { Component } from '@angular/core'; +import {Component, OnInit} from '@angular/core'; +import {Title} from '@angular/platform-browser'; @Component({ selector: 'app-not-found', @@ -6,6 +7,13 @@ import { Component } from '@angular/core'; templateUrl: './not-found.component.html', styleUrl: './not-found.component.css' }) -export class NotFoundComponent { +export class NotFoundComponent implements OnInit { + + constructor(private title: Title) { + } + + ngOnInit(): void { + this.title.setTitle('404 - YouVideo'); + } } diff --git a/src/app/public/pages/register/register.component.html b/src/app/public/pages/register/register.component.html index 9258500..b798bf4 100644 --- a/src/app/public/pages/register/register.component.html +++ b/src/app/public/pages/register/register.component.html @@ -5,39 +5,124 @@

Entrez vos informations pour vous inscrire

-
+ +
- + +
+
L'email est requis.
+
Veuillez entrer une adresse email valide.
+
+
- + +
+
Le prénom est requis.
+
Le prénom doit contenir au moins 2 caractères.
+
+
- + +
+
Le nom est requis.
+
Le nom doit contenir au moins 2 caractères.
+
+
- + +
+
Le mot de passe est requis.
+
Le mot de passe doit contenir au moins 8 caractères.
+
+
- + +
+
La confirmation du mot de passe est requise.
+
Les mots de passe ne correspondent pas.
+
- + + +
+

+ Déjà inscrit ? + Connectez-vous +

+
diff --git a/src/app/public/pages/register/register.component.ts b/src/app/public/pages/register/register.component.ts index 27c2c6f..123eb67 100644 --- a/src/app/public/pages/register/register.component.ts +++ b/src/app/public/pages/register/register.component.ts @@ -1,14 +1,98 @@ -import { Component } from '@angular/core'; -import {RouterLink} from '@angular/router'; +import {Component, OnInit} from '@angular/core'; +import {Router, RouterLink} from '@angular/router'; +import {Title} from '@angular/platform-browser'; +import {AuthService} from '../../../_services/auth.service'; +import { + AbstractControl, + FormBuilder, + FormGroup, + ReactiveFormsModule, + ValidationErrors, + Validators +} from '@angular/forms'; +import {Users} from '../../../_models/users'; +import {NgClass, NgIf} from '@angular/common'; @Component({ selector: 'app-register', imports: [ - RouterLink + RouterLink, + ReactiveFormsModule, + NgClass, + NgIf ], templateUrl: './register.component.html', styleUrl: './register.component.css' }) -export class RegisterComponent { +export class RegisterComponent implements OnInit { + registerForm: FormGroup; + isSubmitting = false; + submissionError = ''; + + constructor( + private title: Title, + private authService: AuthService, + private fb: FormBuilder, + private router: Router + ) { + // Initialiser le formulaire avec FormBuilder + this.registerForm = this.fb.group({ + email: ['', [Validators.required, Validators.email]], + firstname: ['', [Validators.required, Validators.minLength(2)]], + lastname: ['', [Validators.required, Validators.minLength(2)]], + password: ['', [Validators.required, Validators.minLength(8)]], + confirmPassword: ['', [Validators.required]] + }, { + validators: this.passwordMatchValidator + }); + } + + ngOnInit(): void { + this.title.setTitle('S\'inscrire - YouVideo'); + } + + passwordMatchValidator(control: AbstractControl): ValidationErrors | null { + const password = control.get('password'); + const confirmPassword = control.get('confirmPassword'); + if (password && confirmPassword && password.value !== confirmPassword.value) { + confirmPassword.setErrors({ passwordMismatch: true }); + return { passwordMismatch: true }; + } + return null; + } + + onSubmit(): void { + if (this.registerForm.invalid) { + Object.keys(this.registerForm.controls).forEach(key => { + const control = this.registerForm.get(key); + control?.markAsTouched(); + }); + return; + } + + this.isSubmitting = true; + this.submissionError = ''; + + const user: Users = { + id: 0, + email: this.registerForm.value.email, + firstname: this.registerForm.value.firstname, + lastname: this.registerForm.value.lastname, + password_hash: this.registerForm.value.password, + updated_at: new Date(), + created_at: new Date() + }; + + this.authService.register(user).subscribe({ + next: (response) => { + this.isSubmitting = false; + this.router.navigate(['/login'], { queryParams: { registered: 'success' } }); + }, + error: (error) => { + this.isSubmitting = false; + this.submissionError = error.error?.message || 'Une erreur est survenue lors de l\'inscription.'; + } + }); + } } diff --git a/src/app/public/pages/search/search.component.css b/src/app/public/pages/search/search.component.css deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/public/pages/search/search.component.html b/src/app/public/pages/search/search.component.html deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/public/pages/search/search.component.ts b/src/app/public/pages/search/search.component.ts deleted file mode 100644 index 0932cbb..0000000 --- a/src/app/public/pages/search/search.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component } from '@angular/core'; -import {ReactiveFormsModule} from '@angular/forms'; -import {NgForOf, NgIf} from '@angular/common'; - -@Component({ - selector: 'app-search', - imports: [ - NgIf, - NgForOf, - ReactiveFormsModule - ], - templateUrl: './search.component.html', - styleUrl: './search.component.css' -}) -export class SearchComponent { - - - -} diff --git a/src/app/public/public-routing.module.ts b/src/app/public/public-routing.module.ts index aa7795c..e796cba 100644 --- a/src/app/public/public-routing.module.ts +++ b/src/app/public/public-routing.module.ts @@ -5,12 +5,13 @@ import {PublicLayoutComponent} from './public-layout/public-layout.component'; import {HomeComponent} from './pages/home/home.component'; import {LoginComponent} from './pages/login/login.component'; import {RegisterComponent} from './pages/register/register.component'; +import {noAuthGuard} from '../_guards/no-auth.guard'; const routes: Routes = [ { path: '', component: PublicLayoutComponent, children: [ { path: '', component: HomeComponent }, - { path: 'login', component: LoginComponent }, - { path: 'register', component: RegisterComponent }, + { path: 'login', component: LoginComponent, canActivate: [noAuthGuard] }, + { path: 'register', component: RegisterComponent, canActivate: [noAuthGuard] }, ] }, { path: '**', component: NotFoundComponent },