Skip to content

Commit

Permalink
add api services
Browse files Browse the repository at this point in the history
  • Loading branch information
bastyen committed Jul 9, 2024
1 parent 2344baa commit 48e36f2
Show file tree
Hide file tree
Showing 16 changed files with 386 additions and 33 deletions.
12 changes: 11 additions & 1 deletion front-end/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ import {
import { MatListModule } from '@angular/material/list';
import { MatSidenav, MatSidenavModule } from '@angular/material/sidenav';
import { Location } from '@angular/common';
import { AuthService } from './services/auth.service';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
import { Platform } from '@angular/cdk/platform';
import { MatBadgeModule } from '@angular/material/badge';
import { MatDividerModule } from '@angular/material/divider';
import { OfflineService } from './services/offline.service';
import { AuthService } from './services/auth.service';

@Component({
selector: 'app-root',
Expand All @@ -38,6 +39,7 @@ import { OfflineService } from './services/offline.service';
MatListModule,
MatBadgeModule,
MatDividerModule,
MatSnackBarModule,
],
templateUrl: './app.component.html',
styleUrl: './app.component.scss',
Expand All @@ -52,6 +54,7 @@ export class AppComponent {
location = inject(Location);
authService = inject(AuthService);
offlineService = inject(OfflineService);
snackBar = inject(MatSnackBar);

@ViewChild('sidenav') private sidenav!: MatSidenav;

Expand Down Expand Up @@ -112,6 +115,8 @@ export class AppComponent {
click: () => {
this.authService.logout();
this.sidenav.close();
this.snackBar.open('Vous êtes déconnecté', '', { duration: 2000 });
this.router.navigate(['..']);
},
observationsPending: false,
},
Expand Down Expand Up @@ -144,6 +149,11 @@ export class AppComponent {

ngOnInit() {
this.authService.isAuth.subscribe((value) => {
if (value) {
this.authService.getAccount().subscribe((account) => {
console.log(account);
});
}
this.handleAuthentification(value);
});
this.router.events.subscribe((event) => {
Expand Down
13 changes: 11 additions & 2 deletions front-end/src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@ import { provideClientHydration } from '@angular/platform-browser';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { MAT_DATE_LOCALE } from '@angular/material/core';
import { provideMomentDateAdapter } from '@angular/material-moment-adapter';
import { provideHttpClient, withFetch } from '@angular/common/http';
import {
provideHttpClient,
withFetch,
withInterceptorsFromDi,
} from '@angular/common/http';
import { provideServiceWorker } from '@angular/service-worker';
import { httpInterceptorProviders } from './interceptors/http.interceptor';

export function tokenGetter() {
return localStorage.getItem('access_token');
}
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
Expand All @@ -31,7 +39,8 @@ export const appConfig: ApplicationConfig = {
monthYearA11yLabel: 'MMMM YYYY',
},
}),
provideHttpClient(withFetch()),
httpInterceptorProviders,
provideHttpClient(withInterceptorsFromDi(), withFetch()),
provideServiceWorker('ngsw-worker.js', {
enabled: !isDevMode(),
registrationStrategy: 'registerWhenStable:30000',
Expand Down
1 change: 0 additions & 1 deletion front-end/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ export const routes: Routes = [
backButton: true,
accountButton: false,
},
canActivate: [authGuard],
},
{
path: 'mon-compte',
Expand Down
90 changes: 90 additions & 0 deletions front-end/src/app/interceptors/http.interceptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { inject, Injectable } from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HTTP_INTERCEPTORS,
HttpErrorResponse,
} from '@angular/common/http';
import {
BehaviorSubject,
catchError,
filter,
Observable,
switchMap,
take,
throwError,
} from 'rxjs';
import { AuthService } from '../services/auth.service';

const TOKEN_HEADER_KEY = 'Authorization';
@Injectable()
export class HttpRequestInterceptor implements HttpInterceptor {
isRefreshing = false;
refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);

authService = inject(AuthService);

intercept(
req: HttpRequest<any>,
next: HttpHandler,
): Observable<HttpEvent<any>> {
if (req.url.includes('account') && !req.url.includes('sign-up')) {
const token = this.authService.getToken();
if (token) {
req = this.addTokenHeader(req, token);
}
}

return next.handle(req).pipe(
catchError((error) => {
if (error instanceof HttpErrorResponse && error.status === 401) {
return this.handle401Error(req, next);
}
return throwError(() => new Error('Erreur'));
}),
);
}

handle401Error(req: HttpRequest<any>, next: HttpHandler) {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);

const refreshToken = this.authService.getRefreshToken();

if (refreshToken) {
return this.authService.refreshToken(refreshToken).pipe(
switchMap((token: any) => {
this.isRefreshing = false;
this.authService.saveToken(token.accessToken);

return next.handle(this.addTokenHeader(req, token.accessToken));
}),
catchError(() => {
this.isRefreshing = false;
this.authService.logout();
return throwError(() => new Error('Erreur'));
}),
);
}
}

return this.refreshTokenSubject.pipe(
filter((token) => token !== null),
take(1),
switchMap((token) => next.handle(this.addTokenHeader(req, token))),
);
}

addTokenHeader(req: HttpRequest<any>, token: string) {
return req.clone({
headers: req.headers.set(TOKEN_HEADER_KEY, `Bearer ${token}`),
});
}
}

export const httpInterceptorProviders = [
{ provide: HTTP_INTERCEPTORS, useClass: HttpRequestInterceptor, multi: true },
];
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@
<mat-error>Une adresse email est nécessaire</mat-error>
}
</mat-form-field>
<mat-form-field>
<mat-label>Nom</mat-label>
<input type="text" matInput [formControl]="lastNameFormControl" />
@if (lastNameFormControl.hasError("required")) {
<mat-error>Un nom nécessaire</mat-error>
}
</mat-form-field>
<mat-form-field>
<mat-label>Prénom</mat-label>
<input type="text" matInput [formControl]="firstNameFormControl" />
@if (emailFormControl.hasError("required")) {
<mat-error>Un prénom nécessaire</mat-error>
}
</mat-form-field>
<mat-form-field>
<mat-label>Mot de passe</mat-label>
<input type="password" matInput [formControl]="passwordFormControl" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { Router, RouterLink } from '@angular/router';
import { AuthService } from '../../services/auth.service';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';

@Component({
selector: 'app-create-account',
Expand All @@ -22,6 +24,7 @@ import { Router, RouterLink } from '@angular/router';
ReactiveFormsModule,
MatButtonModule,
RouterLink,
MatSnackBarModule,
],
templateUrl: './create-account.component.html',
styleUrl: './create-account.component.scss',
Expand All @@ -31,6 +34,8 @@ export class CreateAccountComponent {
Validators.required,
Validators.email,
]);
firstNameFormControl = new FormControl('', [Validators.required]);
lastNameFormControl = new FormControl('', [Validators.required]);
passwordFormControl = new FormControl('', [
Validators.required,
Validators.minLength(6),
Expand All @@ -43,6 +48,8 @@ export class CreateAccountComponent {
passwordError = false;

router = inject(Router);
authService = inject(AuthService);
snackBar = inject(MatSnackBar);

ngOnInit() {
this.passwordFormControl.valueChanges.subscribe((value) => {
Expand All @@ -67,10 +74,28 @@ export class CreateAccountComponent {
this.passwordError = false;
if (
this.emailFormControl.valid &&
this.firstNameFormControl.valid &&
this.lastNameFormControl.valid &&
this.passwordFormControl.valid &&
this.confirmPasswordFormControl.valid
) {
this.router.navigate(['/se-connecter']);
this.authService
.createAccount({
email: this.emailFormControl.value!,
last_name: this.lastNameFormControl.value!,
first_name: this.firstNameFormControl.value!,
password: this.passwordFormControl.value!,
})
.subscribe({
next: (success) => {
console.log('success', success);
this.snackBar.open('Compte créé', '', { duration: 2000 });
this.router.navigate(['/se-connecter']);
},
error: (error) => {
console.log('error', error);
},
});
}
} else {
this.passwordError = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<mat-error>Une adresse email est nécessaire</mat-error>
}
</mat-form-field>
<button mat-flat-button color="primary" (click)="resetPassword()">
<button disabled mat-flat-button color="primary" (click)="resetPassword()">
Réinitialiser mon mot de passe
</button>
</form>
25 changes: 21 additions & 4 deletions front-end/src/app/pages/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { Router, RouterLink } from '@angular/router';
import { AuthService } from '../../services/auth.service';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';

@Component({
selector: 'app-login',
Expand All @@ -21,6 +22,7 @@ import { AuthService } from '../../services/auth.service';
ReactiveFormsModule,
MatButtonModule,
RouterLink,
MatSnackBarModule,
],
templateUrl: './login.component.html',
styleUrl: './login.component.scss',
Expand All @@ -37,13 +39,28 @@ export class LoginComponent {

router = inject(Router);
authService = inject(AuthService);
snackBar = inject(MatSnackBar);

onLogin() {
if (this.emailFormControl.valid && this.passwordFormControl.valid) {
this.authService.login();
if (this.authService.isAuth.value) {
this.router.navigate(['..']);
}
this.authService
.login({
email: this.emailFormControl.value!,
password: this.passwordFormControl.value!,
})
.subscribe({
next: (success: any) => {
console.log('success', success);
this.snackBar.open('Vous êtes connecté', '', { duration: 2000 });
this.authService.saveToken(success.access);
this.authService.saveRefreshToken(success.refresh);
this.authService.checkAuth();
this.router.navigate(['..']);
},
error: (error) => {
console.log('error', error);
},
});
}
}
}
8 changes: 8 additions & 0 deletions front-end/src/app/pages/my-account/my-account.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
<mat-label>Email</mat-label>
<input disabled type="email" matInput [value]="email" />
</mat-form-field>
<mat-form-field>
<mat-label>Nom</mat-label>
<input disabled type="text" matInput [value]="lastName" />
</mat-form-field>
<mat-form-field>
<mat-label>Prénom</mat-label>
<input disabled type="text" matInput [value]="firstName" />
</mat-form-field>
</form>

<div class="change-password-button-container">
Expand Down
Loading

0 comments on commit 48e36f2

Please sign in to comment.