Skip to content

Commit 9d7be8c

Browse files
committed
Merge branch 'feature/authentication' into develop
2 parents ee46ad0 + b264bd5 commit 9d7be8c

40 files changed

+838
-119
lines changed

src/app/app.module.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { APP_INITIALIZER, ErrorHandler, NgModule } from '@angular/core';
2-
import { HttpClientModule } from '@angular/common/http';
2+
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
33
import { BrowserModule } from '@angular/platform-browser';
44
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
55
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@@ -13,8 +13,8 @@ import { environment } from '../environments/environment';
1313
import { AppRoutingModule } from './core/routes/app-routing.module';
1414
import { AppComponent } from './core/components/app/app.component';
1515
import { ROOT_REDUCERS } from './core/store/app.store';
16-
import { ROOT_EFFECTS } from './core/store/app.effects';
1716
import { Router } from '@angular/router';
17+
import { AuthInterceptor } from './modules/authentication/interceptors/auth.interceptor';
1818

1919
@NgModule({
2020
declarations: [
@@ -24,7 +24,7 @@ import { Router } from '@angular/router';
2424
AppRoutingModule,
2525
BrowserAnimationsModule,
2626
BrowserModule,
27-
EffectsModule.forRoot(ROOT_EFFECTS),
27+
EffectsModule.forRoot(),
2828
FormsModule,
2929
HttpClientModule,
3030
ReactiveFormsModule,
@@ -49,6 +49,11 @@ import { Router } from '@angular/router';
4949
deps: [Sentry.TraceService],
5050
multi: true,
5151
},
52+
{
53+
provide: HTTP_INTERCEPTORS,
54+
useClass: AuthInterceptor,
55+
multi: true,
56+
}
5257
],
5358
bootstrap: [AppComponent],
5459
})

src/app/core/guards/admin.guard.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,36 @@
11
import { Injectable } from '@angular/core';
22
import { CanActivate } from '@angular/router';
3+
import { Store } from '@ngrx/store';
4+
import { first, map, Observable } from 'rxjs';
5+
6+
import { getCurrentUserAction } from '@app/modules/authentication/store/auth.actions';
7+
import { selectCurrentUser } from '@app/modules/authentication/store/auth.selectors';
8+
import { User } from '@app/modules/user/interfaces/user.interface';
39

410
@Injectable({
511
providedIn: 'root'
612
})
713
export class AdminGuard implements CanActivate {
814

15+
constructor(private store: Store) {}
16+
917
emails: string[] = [
1018
'manfouothierno@isdg-sarl.com',
1119
'patouossaibrahim@yahoo.com',
1220
'monneylobe@gmail.com',
1321
];
1422

15-
canActivate(): boolean {
16-
return true;
23+
canActivate(): Observable<boolean> {
24+
return this.store.select(selectCurrentUser).pipe(
25+
first(),
26+
map((user: User | null) => {
27+
if (!user) {
28+
this.store.dispatch(getCurrentUserAction());
29+
return false;
30+
}
31+
return this.emails.includes(user.email);
32+
})
33+
);
1734
}
1835

1936
}

src/app/core/guards/auth.guard.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
11
import { Injectable } from '@angular/core';
2-
import { ActivatedRouteSnapshot, CanActivateChild, RouterStateSnapshot } from '@angular/router';
2+
import { CanActivateChild, Router } from '@angular/router';
3+
import { AccessTokenService } from '@app/modules/authentication/services/access-token.service';
4+
import { selectIsLoggedIn } from '@app/modules/authentication/store/auth.selectors';
5+
import { Store } from '@ngrx/store';
6+
import { filter, first, map, Observable } from 'rxjs';
37

48
@Injectable({
59
providedIn: 'root'
610
})
711
export class AuthGuard implements CanActivateChild {
12+
constructor(
13+
private store: Store,
14+
private router: Router,
15+
private accessTokenService: AccessTokenService
16+
) {}
817

9-
canActivateChild(
10-
childRoute: ActivatedRouteSnapshot,
11-
state: RouterStateSnapshot
12-
): boolean {
13-
return true;
18+
canActivateChild(): Observable<boolean> {
19+
return this.store.select(selectIsLoggedIn).pipe(
20+
first((value) => value !== null),
21+
map(() => {
22+
if ( ! this.accessTokenService.getAccessToken()) {
23+
this.router.navigateByUrl('/auth/login')
24+
return false;
25+
}
26+
27+
return true;
28+
})
29+
);
1430
}
1531

1632
}

src/app/core/guards/guest.guard.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
11
import { Injectable } from '@angular/core';
2-
import { ActivatedRouteSnapshot, CanActivateChild, RouterStateSnapshot } from '@angular/router';
2+
import { CanActivateChild, Router } from '@angular/router';
3+
import { AccessTokenService } from '@app/modules/authentication/services/access-token.service';
4+
import { selectIsLoggedIn } from '@app/modules/authentication/store/auth.selectors';
5+
import { Store } from '@ngrx/store';
6+
import { first, map, Observable } from 'rxjs';
37

48
@Injectable({
59
providedIn: 'root'
610
})
711
export class GuestGuard implements CanActivateChild {
12+
constructor(
13+
private store: Store,
14+
private router: Router,
15+
private accessTokenService: AccessTokenService
16+
) {}
817

9-
canActivateChild(
10-
route: ActivatedRouteSnapshot,
11-
state: RouterStateSnapshot
12-
): boolean {
13-
return true;
18+
canActivateChild(): Observable<boolean> {
19+
return this.store.select(selectIsLoggedIn).pipe(
20+
first((value) => value !== null),
21+
map(() => {
22+
if (! this.accessTokenService.tokenExpired()) {
23+
this.router.navigateByUrl('/dashboard')
24+
return false
25+
}
26+
27+
return true;
28+
})
29+
);
1430
}
1531

1632
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Injectable } from '@angular/core';
2+
import { Store } from '@ngrx/store';
3+
import { first, map, Observable } from 'rxjs';
4+
import { CanActivateChild } from '@angular/router';
5+
6+
import { selectCurrentUser } from '@app/modules/authentication/store/auth.selectors';
7+
import { getCurrentUserAction } from '@app/modules/authentication/store/auth.actions';
8+
import { User } from '@app/modules/user/interfaces/user.interface';
9+
10+
@Injectable({
11+
providedIn: 'root'
12+
})
13+
export class UserDataGuard implements CanActivateChild {
14+
constructor(private store: Store) {}
15+
16+
canActivateChild(): Observable<boolean> {
17+
return this.store.select(selectCurrentUser).pipe(
18+
first(),
19+
map((user: User | null) => {
20+
if (! user) {
21+
this.store.dispatch(getCurrentUserAction());
22+
}
23+
console.log(user);
24+
return true;
25+
})
26+
);
27+
}
28+
29+
}

src/app/core/store/app.effects.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/app/core/store/app.store.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import { routerReducer, RouterState } from '@ngrx/router-store';
22
import { Action, ActionReducerMap } from '@ngrx/store';
33

4+
import { AuthState } from '@app/modules/authentication/interfaces/state.interface';
5+
import { authFeatureKey, authReducer } from '@app/modules/authentication/store/auth.reducer';
6+
47
export interface AppState {
58
router: RouterState;
9+
[authFeatureKey]: AuthState;
610
}
711

812
export const ROOT_REDUCERS: ActionReducerMap<AppState, Action> = {
913
router: routerReducer,
14+
[authFeatureKey]: authReducer,
1015
};
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import { getSelectors } from '@ngrx/router-store';
22

3-
export const { selectRouteParams } = getSelectors();
3+
export const { selectRouteParams, selectQueryParams } = getSelectors();

src/app/modules/authentication/authentication.module.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import { NgModule } from '@angular/core';
22
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
33
import { RouterModule } from '@angular/router';
4+
import { StoreModule } from '@ngrx/store';
5+
import { EffectsModule } from '@ngrx/effects';
46

57
import { SharedModule } from '@shared/shared.module';
68
import { authRoutes } from './routes/authenticate.routes';
79

810
import { ForgotPasswordComponent } from './pages/forgot-password/forgot-password.component';
911
import { LoginComponent } from './pages/login/login.component';
1012
import { ResetPasswordComponent } from './pages/reset-password/reset-password.component';
13+
import { authReducer, authFeatureKey } from './store/auth.reducer';
14+
import { AuthEffects } from './store/auth.effects';
1115

1216
@NgModule({
1317
declarations: [
@@ -16,10 +20,12 @@ import { ResetPasswordComponent } from './pages/reset-password/reset-password.co
1620
ResetPasswordComponent
1721
],
1822
imports: [
23+
EffectsModule.forFeature([AuthEffects]),
1924
FormsModule,
2025
ReactiveFormsModule,
21-
SharedModule,
2226
RouterModule.forChild(authRoutes),
27+
SharedModule,
28+
StoreModule.forFeature(authFeatureKey, authReducer)
2329
],
2430
exports: [],
2531
providers: [],
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Injectable } from '@angular/core';
2+
import {
3+
HttpEvent,
4+
HttpInterceptor,
5+
HttpHandler,
6+
HttpRequest
7+
} from '@angular/common/http';
8+
import { Observable } from 'rxjs';
9+
10+
import { AccessTokenService } from '../services/access-token.service';
11+
import { environment } from 'environments/environment';
12+
13+
@Injectable()
14+
export class AuthInterceptor implements HttpInterceptor {
15+
16+
constructor(private accessTokenService: AccessTokenService) { }
17+
18+
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
19+
const isApiUrl = request.url.startsWith(environment.apiUrl);
20+
const accessToken = this.accessTokenService.getAccessToken();
21+
22+
if (accessToken && isApiUrl) {
23+
request = request.clone({
24+
setHeaders: { Authorization: `Bearer ${accessToken}` }
25+
});
26+
}
27+
28+
return next.handle(request);
29+
}
30+
}

0 commit comments

Comments
 (0)