Skip to content
Snippets Groups Projects
Commit a1606311 authored by Hugo SUBTIL's avatar Hugo SUBTIL
Browse files

fix(auth): add better signin signup logic

feat(auth): add logout
parent ec52547c
No related branches found
No related tags found
3 merge requests!68Recette,!67Dev,!38Feat/auth
......@@ -14,14 +14,15 @@
<a routerLink="/projects" [routerLinkActive]="'active'" i18n>Projets</a> -->
<a routerLink="/about" [routerLinkActive]="'active'" i18n>Qui sommes-nous ?</a>
<!-- <a routerLink="/login" [routerLinkActive]="'active'" i18n><span class="clickable ico-mglass purple"></span></a> -->
<button (click)="isSignUpOpen = !isSignUpOpen">
<button *ngIf="!isLoggedIn" (click)="isPopUpOpen = !isPopUpOpen">
<span class="ico-profile" fxLayout="column" fxLayoutAlign="center center">
<span class="head"></span>
<span class="body"></span>
</span>
</button>
<button *ngIf="isLoggedIn" (click)="logout()">Logout</button>
</div>
</div>
<app-menu-phone *ngIf="showMenu" (closeEvent)="closeMenu($event)"></app-menu-phone>
<!-- <app-signup-modal [openned]="isSignUpOpen" (closed)="closeSignUpModal()"></app-signup-modal> -->
<app-signin-modal [openned]="isSignUpOpen" (closed)="closeSignUpModal()"></app-signin-modal>
<app-signup-modal *ngIf="displaySignUp" [openned]="isPopUpOpen" (closed)="closeSignUpModal($event)"></app-signup-modal>
<app-signin-modal *ngIf="!displaySignUp" [openned]="isPopUpOpen" (closed)="closeSignInModal()"></app-signin-modal>
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../services/auth.service';
@Component({
selector: 'app-header',
......@@ -7,9 +8,10 @@ import { Component, OnInit } from '@angular/core';
})
export class HeaderComponent implements OnInit {
public showMenu = false;
public isSignUpOpen = false;
public isPopUpOpen = false;
public displaySignUp = true;
constructor() {}
constructor(private authService: AuthService) {}
ngOnInit(): void {}
public openMenu(): void {
......@@ -18,7 +20,25 @@ export class HeaderComponent implements OnInit {
public closeMenu(): void {
this.showMenu = false;
}
public closeSignUpModal(): void {
this.isSignUpOpen = false;
public get isLoggedIn(): boolean {
return this.authService.isLoggedIn();
}
public logout(): void {
return this.authService.logout();
}
public closeSignInModal(): void {
this.isPopUpOpen = false;
this.displaySignUp = true;
}
public closeSignUpModal(value: boolean): void {
if (!value) {
this.displaySignUp = false;
} else {
this.isPopUpOpen = false;
}
}
}
export class UserAuth {
username: string;
access_token: string;
expires_at: string;
}
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { DateTime } from 'luxon';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { UserAuth } from '../models/user-auth.model';
import { User } from '../models/user.model';
@Injectable({
providedIn: 'root',
})
export class AuthService {
private userSubject: BehaviorSubject<User>;
public user: Observable<User>;
private userSubject: BehaviorSubject<UserAuth>;
public user: Observable<UserAuth>;
constructor(private http: HttpClient) {
this.userSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('user')));
this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user')));
this.user = this.userSubject.asObservable();
}
public get userValue(): UserAuth {
return this.userSubject.value;
}
public get token(): string {
return this.userSubject.value.access_token;
}
public logout(): void {
localStorage.removeItem('user');
this.userSubject.next(null);
}
public isLoggedIn(): boolean {
if (this.userValue) {
return new DateTime.local().setZone('Europe/Paris') < this.getExpiration();
}
return false;
}
public getExpiration(): void {
return DateTime.fromISO(this.userValue.expires_at, { zone: 'Europe/Paris' });
}
public register(user: User): Observable<any> {
return this.http.post('api/users', user);
}
public login(email: string, password: string): Observable<any> {
return this.http
.post<User>('api/auth/login', { email, password })
.post<UserAuth>('api/auth/login', { email, password })
.pipe(
map((user) => {
// store user details and jwt token in local storage to keep user logged in between page refreshes
......@@ -29,10 +58,6 @@ export class AuthService {
);
}
public register(user: User): Observable<any> {
return this.http.post('api/users', user);
}
public verifyUser(userId: string, token: string): Observable<any> {
return this.http.post(`api/users/verify/${userId}`, null, {
params: { token },
......
......@@ -10,6 +10,7 @@
<label for="email">Email</label>
<input
type="email"
autocomplete="on"
formControlName="email"
class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.email.errors }"
......@@ -22,6 +23,7 @@
<label for="password">Mot de passe</label>
<input
type="password"
autocomplete="on"
formControlName="password"
class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.password.errors }"
......@@ -38,6 +40,7 @@
<label for="confirmPassword">Confirmation du mot de passe</label>
<input
type="password"
autocomplete="on"
formControlName="confirmPassword"
class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.confirmPassword.errors }"
......
......@@ -7,35 +7,38 @@
<div class="card-body">
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="username">Username</label>
<label for="username">Identifiant</label>
<input
type="text"
formControlName="username"
autocomplete="on"
class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.username.errors }"
/>
<div *ngIf="submitted && f.username.errors" class="invalid-feedback">
<div *ngIf="f.username.errors.required">Username is required</div>
<div *ngIf="f.username.errors.required">Identifiant requis</div>
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<label for="password">Mot de passe</label>
<input
type="password"
formControlName="password"
autocomplete="on"
class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.password.errors }"
/>
<div *ngIf="submitted && f.password.errors">
<div *ngIf="f.password.errors.required">Password is required</div>
<div *ngIf="f.password.errors.required">Mot de passe requis</div>
</div>
</div>
<div *ngIf="authFailed">Identifiant ou mot de passe invalide</div>
<div>
<button [disabled]="loading">
<span *ngIf="loading"></span>
Login
</button>
<a routerLink="../register" class="btn btn-link">Register</a>
<button (click)="sendSwitchToSignIn()">Inscription</button>
</div>
</form>
</div>
......
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormGroup, FormBuilder, Validators, AbstractControl } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { first } from 'rxjs/operators';
import { AuthService } from '../../../services/auth.service';
......@@ -12,17 +13,26 @@ export class SignUpModalComponent implements OnInit {
public loginForm: FormGroup;
public loading = false;
public submitted = false;
public authFailed = false;
public returnUrl: string;
constructor(private formBuilder: FormBuilder, private authService: AuthService) {}
constructor(
private formBuilder: FormBuilder,
private route: ActivatedRoute,
private router: Router,
private authService: AuthService
) {}
@Input() public openned: boolean;
@Output() closed = new EventEmitter();
@Output() closed = new EventEmitter<boolean>();
ngOnInit(): void {
this.loginForm = this.formBuilder.group({
username: ['', Validators.required],
password: ['', Validators.required],
});
// get return url from route parameters or default to '/'
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
}
// getter for form fields
......@@ -31,7 +41,11 @@ export class SignUpModalComponent implements OnInit {
}
public closeModal(): void {
this.closed.emit();
this.closed.emit(true);
}
public sendSwitchToSignIn(): void {
this.closed.emit(false);
}
public onSubmit(): void {
......@@ -47,11 +61,13 @@ export class SignUpModalComponent implements OnInit {
.login(this.f.username.value, this.f.password.value)
.pipe(first())
.subscribe(
(data) => {
//TODO: redirect to ?
() => {
this.router.navigate([this.returnUrl]);
this.closeModal();
},
(error) => {
() => {
this.loading = false;
this.authFailed = true;
}
);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment