Skip to content

Commit

Permalink
adding dashboard playground
Browse files Browse the repository at this point in the history
  • Loading branch information
Wiran-Larbi committed Jun 3, 2024
1 parent e66d483 commit 1f10afd
Show file tree
Hide file tree
Showing 16 changed files with 247 additions and 20 deletions.
3 changes: 3 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions frontend/src/app/api/fn/authentication/refresh-token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* tslint:disable */
/* eslint-disable */
import { HttpClient, HttpContext, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { StrictHttpResponse } from '../../strict-http-response';
import { RequestBuilder } from '../../request-builder';

import { AuthenticationResponse } from '../../models/authentication-response';
import { RefreshTokenRequest } from '../../models/refresh-token-request';

export interface RefreshToken$Params {
body: RefreshTokenRequest
}

export function refreshToken(http: HttpClient, rootUrl: string, params: RefreshToken$Params, context?: HttpContext): Observable<StrictHttpResponse<AuthenticationResponse>> {
const rb = new RequestBuilder(rootUrl, refreshToken.PATH, 'post');
if (params) {
rb.body(params.body, 'application/json');
}

return http.request(
rb.build({ responseType: 'json', accept: 'application/json', context })
).pipe(
filter((r: any): r is HttpResponse<any> => r instanceof HttpResponse),
map((r: HttpResponse<any>) => {
return r as StrictHttpResponse<AuthenticationResponse>;
})
);
}

refreshToken.PATH = '/auth/refresh-token';
1 change: 1 addition & 0 deletions frontend/src/app/api/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ export { MembersStatsResponse } from './models/members-stats-response';
export { PointCaptureRequest } from './models/point-capture-request';
export { PointCaptureResponse } from './models/point-capture-response';
export { PointsCaptureAllResponse } from './models/points-capture-all-response';
export { RefreshTokenRequest } from './models/refresh-token-request';
export { RegisterRequest } from './models/register-request';
export { ResetPasswordRequest } from './models/reset-password-request';
3 changes: 2 additions & 1 deletion frontend/src/app/api/models/authentication-response.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* tslint:disable */
/* eslint-disable */
export interface AuthenticationResponse {
token?: string;
access_token?: string;
refresh_token?: string;
}
6 changes: 6 additions & 0 deletions frontend/src/app/api/models/refresh-token-request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* tslint:disable */
/* eslint-disable */
export interface RefreshTokenRequest {
accessToken?: string;
refreshToken?: string;
}
27 changes: 27 additions & 0 deletions frontend/src/app/api/services/authentication.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import { logout5 } from '../fn/authentication/logout-5';
import { Logout5$Params } from '../fn/authentication/logout-5';
import { logout6 } from '../fn/authentication/logout-6';
import { Logout6$Params } from '../fn/authentication/logout-6';
import { refreshToken } from '../fn/authentication/refresh-token';
import { RefreshToken$Params } from '../fn/authentication/refresh-token';
import { register } from '../fn/authentication/register';
import { Register$Params } from '../fn/authentication/register';
import { resendActivationEmail } from '../fn/authentication/resend-activation-email';
Expand Down Expand Up @@ -113,6 +115,31 @@ export class AuthenticationService extends BaseService {
);
}

/** Path part for operation `refreshToken()` */
static readonly RefreshTokenPath = '/auth/refresh-token';

/**
* This method provides access to the full `HttpResponse`, allowing access to response headers.
* To access only the response body, use `refreshToken()` instead.
*
* This method sends `application/json` and handles request body of type `application/json`.
*/
refreshToken$Response(params: RefreshToken$Params, context?: HttpContext): Observable<StrictHttpResponse<AuthenticationResponse>> {
return refreshToken(this.http, this.rootUrl, params, context);
}

/**
* This method provides access only to the response body.
* To access the full response (for headers, for example), `refreshToken$Response()` instead.
*
* This method sends `application/json` and handles request body of type `application/json`.
*/
refreshToken(params: RefreshToken$Params, context?: HttpContext): Observable<AuthenticationResponse> {
return this.refreshToken$Response(params, context).pipe(
map((r: StrictHttpResponse<AuthenticationResponse>): AuthenticationResponse => r.body)
);
}

/** Path part for operation `authenticate()` */
static readonly AuthenticatePath = '/auth/authenticate';

Expand Down
8 changes: 8 additions & 0 deletions frontend/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,11 @@ describe('AppComponent', () => {
expect(compiled.querySelector('.content span')?.textContent).toContain('frontend app is running!');
});
});








13 changes: 10 additions & 3 deletions frontend/src/app/core/interceptors/auth.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
HttpInterceptor,
HttpErrorResponse
} from '@angular/common/http';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { Observable } from 'rxjs';
import { catchError, Observable } from 'rxjs';
import { JwtTokenService } from '../services/jwt-token.service';
import { RefreshTokenService } from '../services/refresh-token.service';
import { refreshToken } from 'app/api/fn/authentication/refresh-token';
import { from } from 'rxjs';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

constructor(private jwtTokenService: JwtTokenService) {}
constructor(private jwtTokenService: JwtTokenService, private refreshTokenService: RefreshTokenService) {}

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
request = request.clone({
Expand All @@ -22,8 +26,11 @@ export class AuthInterceptor implements HttpInterceptor {
});
return next.handle(request);
}

}



export const authInterceptorProvider = {
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
Expand Down
68 changes: 68 additions & 0 deletions frontend/src/app/core/interceptors/refresh.interceptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpErrorResponse,
HttpClient
} from '@angular/common/http';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { catchError, Observable, switchMap } from 'rxjs';
import { JwtTokenService } from '../services/jwt-token.service';
import { RefreshTokenService } from '../services/refresh-token.service';
import { refreshToken } from 'app/api/fn/authentication/refresh-token';
import { from } from 'rxjs';
import { environment } from 'app/core/environments/environment';


@Injectable()
export class RefreshInterceptor implements HttpInterceptor {

constructor(private refreshTokenService: RefreshTokenService, private jwtTokenService: JwtTokenService, private http: HttpClient) {}

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
return next.handle(request).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401 || error.status === 403) {
const params = {
body: {
access_token: this.jwtTokenService.token,
refresh_token: this.refreshTokenService.token
}
}

return this.http.post(`${environment.apiBaseUrl}/auth/refresh-token`, params).pipe(
switchMap((response: any) => {
this.jwtTokenService.token = response.access_token!;
this.refreshTokenService.token = response.refresh_token!;
request = request.clone({
setHeaders: {
Authorization: `Bearer ${response.access_token}`
}
});
return next.handle(request);
}),
catchError((error: HttpErrorResponse) => {
this.refreshTokenService.removeToken();
return from(Promise.reject(error));
})
);
}else {
return from(Promise.reject(error));
}
}


));
}

}



export const refreshInterceptorProvider = {
provide: HTTP_INTERCEPTORS,
useClass: RefreshInterceptor,
multi: true
}
2 changes: 1 addition & 1 deletion frontend/src/app/core/routeguards/auth.routeguards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class AuthActivateRouteGuard implements CanActivate {
canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot)
: boolean | Promise<boolean> {
// @ts-ignore
this.token = localStorage.getItem("token");
this.token = localStorage.getItem("access_token");
if(!this.token){
console.log("User not authenticated");
this.router.navigate(['/auth/authenticate']);
Expand Down
7 changes: 3 additions & 4 deletions frontend/src/app/core/services/jwt-token.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ export class JwtTokenService {
constructor() { }

set token(token: string) {
localStorage.setItem('token', token);
localStorage.setItem('access_token', token);
}

get token() {
return localStorage.getItem('token') as string;
return localStorage.getItem('access_token') as string;
}

removeToken(): void {
localStorage.removeItem('token');
localStorage.removeItem('access_token');
}

isTokenExist(): boolean {
Expand All @@ -32,7 +32,6 @@ export class JwtTokenService {
getActiveUser(): User {
const data = Object.entries(this.getPayload()).map(([key, value]) => value);
let [fullName, email, iat, exp, authorities]: Array<string|Array<string>|undefined> = [...data] as Array<string|undefined>;
// let activeRole = authorities.find((role: string) => role.startsWith('ROLE_')).split('_')[1];
if (authorities?.length! >= 1) {
authorities = (authorities as any).filter((role: string) => role.startsWith('ROLE_'));
}
Expand Down
28 changes: 28 additions & 0 deletions frontend/src/app/core/services/refresh-token.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Injectable } from '@angular/core';


@Injectable({
providedIn: 'root'
})
export class RefreshTokenService {

constructor() { }

set token(token: string) {
localStorage.setItem('refresh_token', token);
}

get token() {
return localStorage.getItem('refresh_token') as string;
}

removeToken(): void {
localStorage.removeItem('refresh_token');
}

isTokenExist(): boolean {
return !!this.token;
}


}
4 changes: 3 additions & 1 deletion frontend/src/app/modules/auth/auth-user.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common';
import {AuthUserRouting} from "./auth-user-routing.module";
import { HttpClientModule } from '@angular/common/http';
import { AuthInterceptor } from '../../core/interceptors/auth.interceptor';
import { RefreshInterceptor } from 'app/core/interceptors/refresh.interceptor';


// @ts-ignore
Expand All @@ -13,7 +14,8 @@ import { AuthInterceptor } from '../../core/interceptors/auth.interceptor';
AuthUserRouting
],
providers: [
AuthInterceptor
AuthInterceptor,
RefreshInterceptor
]
})
export class AuthUserModule { }
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<app-modal [showModal]="showModal" [title]="alertTitle" [message]="alertMessage" [color]="alertColor" ></app-modal>
<app-card-center title="Two-Factor Authentication" description="Enter activation code sent to {{email_register}}, to pursuite to login.">
<code-input [isCodeHidden]="false" [codeLength]="6" [code]="token" (codeCompleted)="onCodeCompleted($event)" >

</code-input>
<div class="mt-4 mb-16 text-sm text-center">
<p>Didn't get the code?
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/app/modules/auth/pages/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import {AuthenticationRequest} from "../../api/services/authentication-request";
import {AuthenticationResponse} from "../../../../api/models/authentication-response";
import {JwtTokenService} from "../../../../core/services/jwt-token.service";
import { SharedModule } from '../../../../shared/shared.module';
import { RefreshTokenService } from 'app/core/services/refresh-token.service';

@Component({
selector: 'app-login',
templateUrl: './login.component.html',
standalone: true,
imports: [CommonModule,FormsModule, ReactiveFormsModule, HttpClientModule, RouterLink, SharedModule],
providers: [AuthenticationService, RouterLink, JwtTokenService]
providers: [AuthenticationService, RouterLink, JwtTokenService, RefreshTokenService]
})
export class LoginComponent implements OnInit {
email = new FormControl('', [Validators.required, Validators.email]);
Expand All @@ -39,7 +40,7 @@ export class LoginComponent implements OnInit {



constructor(private authenticationService: AuthenticationService ,private tokenService: JwtTokenService ,private router: Router) {}
constructor(private authenticationService: AuthenticationService ,private tokenService: JwtTokenService, private refreshTokenService: RefreshTokenService ,private router: Router) {}

ngOnInit(): void {}

Expand Down Expand Up @@ -77,7 +78,8 @@ export class LoginComponent implements OnInit {
}).subscribe({
next: (responseData: AuthenticationResponse) => {
// Set Local Storage to Authorization Jwt Token
this.tokenService.token = responseData.token as string;
this.tokenService.token = responseData.access_token as string;
this.refreshTokenService.token = responseData.refresh_token as string;
this.router.navigate(['dashboard']);
},
error: (error) => {
Expand Down
Loading

0 comments on commit 1f10afd

Please sign in to comment.