CP #0 JWT Interceptor + HttpError (WIP?) + New generated model (Swagger) + Navigation small changes

This commit is contained in:
ThomasFransolet 2019-07-14 02:41:31 +02:00
parent 07ae264402
commit fc1c96552d
42 changed files with 304 additions and 54 deletions

View File

@ -1,7 +1,7 @@
{ {
"$schema": "./node_modules/ng-swagger-gen/ng-swagger-gen-schema.json", "$schema": "./node_modules/ng-swagger-gen/ng-swagger-gen-schema.json",
"swagger": "swagger.json", "swagger": "swagger.json",
"output": "src/app/api", "output": "src/app/_api",
"prefix": "Api", "prefix": "Api",
"ignoreUnusedModels": true, "ignoreUnusedModels": true,
"minParamsForContainer": 2, "minParamsForContainer": 2,

View File

@ -11,6 +11,7 @@ import { IOTService } from './services/iot.service';
import { MQTTService } from './services/mqtt.service'; import { MQTTService } from './services/mqtt.service';
import { TokenService } from './services/token.service'; import { TokenService } from './services/token.service';
import { TwitterService } from './services/twitter.service'; import { TwitterService } from './services/twitter.service';
import { UserService } from './services/user.service';
import { ValuesService } from './services/values.service'; import { ValuesService } from './services/values.service';
/** /**
@ -34,6 +35,7 @@ import { ValuesService } from './services/values.service';
MQTTService, MQTTService,
TokenService, TokenService,
TwitterService, TwitterService,
UserService,
ValuesService ValuesService
], ],
}) })

View File

@ -6,3 +6,4 @@ export { SmartPrinterMessage } from './models/smart-printer-message';
export { SmartGardenMessage } from './models/smart-garden-message'; export { SmartGardenMessage } from './models/smart-garden-message';
export { User } from './models/user'; export { User } from './models/user';
export { TwitterAuthModel } from './models/twitter-auth-model'; export { TwitterAuthModel } from './models/twitter-auth-model';
export { UserInfo } from './models/user-info';

View File

@ -0,0 +1,11 @@
/* tslint:disable */
export interface UserInfo {
id?: string;
role?: string;
username?: string;
password?: string;
firstName?: string;
lastName?: string;
token?: string;
birthday?: string;
}

View File

@ -6,4 +6,5 @@ export { IOTService } from './services/iot.service';
export { MQTTService } from './services/mqtt.service'; export { MQTTService } from './services/mqtt.service';
export { TokenService } from './services/token.service'; export { TokenService } from './services/token.service';
export { TwitterService } from './services/twitter.service'; export { TwitterService } from './services/twitter.service';
export { UserService } from './services/user.service';
export { ValuesService } from './services/values.service'; export { ValuesService } from './services/values.service';

View File

@ -0,0 +1,98 @@
/* tslint:disable */
import { Injectable } from '@angular/core';
import { HttpClient, HttpRequest, HttpResponse, HttpHeaders } from '@angular/common/http';
import { BaseService as __BaseService } from '../base-service';
import { ApiConfiguration as __Configuration } from '../api-configuration';
import { StrictHttpResponse as __StrictHttpResponse } from '../strict-http-response';
import { Observable as __Observable } from 'rxjs';
import { map as __map, filter as __filter } from 'rxjs/operators';
import { UserInfo } from '../models/user-info';
@Injectable({
providedIn: 'root',
})
class UserService extends __BaseService {
static readonly GetPath = '/api/user';
static readonly Get_1Path = '/api/user/{id}';
constructor(
config: __Configuration,
http: HttpClient
) {
super(config, http);
}
/**
* @return Success
*/
GetResponse(): __Observable<__StrictHttpResponse<Array<UserInfo>>> {
let __params = this.newParams();
let __headers = new HttpHeaders();
let __body: any = null;
let req = new HttpRequest<any>(
'GET',
this.rootUrl + `/api/user`,
__body,
{
headers: __headers,
params: __params,
responseType: 'json'
});
return this.http.request<any>(req).pipe(
__filter(_r => _r instanceof HttpResponse),
__map((_r) => {
return _r as __StrictHttpResponse<Array<UserInfo>>;
})
);
}
/**
* @return Success
*/
Get(): __Observable<Array<UserInfo>> {
return this.GetResponse().pipe(
__map(_r => _r.body as Array<UserInfo>)
);
}
/**
* @param id id user
* @return Success
*/
Get_1Response(id: string): __Observable<__StrictHttpResponse<UserInfo>> {
let __params = this.newParams();
let __headers = new HttpHeaders();
let __body: any = null;
let req = new HttpRequest<any>(
'GET',
this.rootUrl + `/api/user/${id}`,
__body,
{
headers: __headers,
params: __params,
responseType: 'json'
});
return this.http.request<any>(req).pipe(
__filter(_r => _r instanceof HttpResponse),
__map((_r) => {
return _r as __StrictHttpResponse<UserInfo>;
})
);
}
/**
* @param id id user
* @return Success
*/
Get_1(id: string): __Observable<UserInfo> {
return this.Get_1Response(id).pipe(
__map(_r => _r.body as UserInfo)
);
}
}
module UserService {
}
export { UserService }

View File

@ -1,4 +1,4 @@
import { BorderCardDirective } from '../border-card.directive'; import { BorderCardDirective } from './border-card.directive';
describe('BorderCardDirective', () => { describe('BorderCardDirective', () => {
it('should create an instance', () => { it('should create an instance', () => {

View File

@ -2,14 +2,14 @@ import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router, UrlTree } from '@angular/router'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router, UrlTree } from '@angular/router';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { AuthService } from './auth.service'; import { AuthenticationService } from '../_services/authentication.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class AuthGuard implements CanActivate { export class AuthGuard implements CanActivate {
constructor(private _authService: AuthService, private router: Router){} constructor(private _authService: AuthenticationService, private router: Router){}
canActivate( canActivate(
next: ActivatedRouteSnapshot, next: ActivatedRouteSnapshot,

View File

@ -0,0 +1,24 @@
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { AuthenticationService } from '../_services/authentication.service';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private _authService: AuthenticationService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError(err => {
if (err.status === 401) {
// auto logout if 401 response returned from api
this._authService.Logout();
location.reload(true);
}
const error = err.error.message || err.statusText;
return throwError(error);
}))
}
}

View File

@ -0,0 +1,24 @@
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthenticationService } from '../_services/authentication.service';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
constructor(private _authService: AuthenticationService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
let currentUser = this._authService.currentUserValue;
if (currentUser && currentUser.token) {
request = request.clone({
setHeaders: {
Authorization: 'Bearer ' + currentUser.token
}
});
}
return next.handle(request);
}
}

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { TokenService } from './api/services/token.service'; import { BooksService } from '../_api/services/books.service';
@Injectable({ @Injectable({
@ -11,11 +11,11 @@ import { TokenService } from './api/services/token.service';
export class AppService { export class AppService {
constructor( constructor(
protected http: HttpClient, protected http: HttpClient,
private _tokenService: TokenService private _bookService: BooksService
) { } ) { }
public GetToken(username: string, password: string): Observable<any> { public ConnectionTest(): Observable<any> {
return this._tokenService.Create({username: username, password: password}); return this._bookService.Get();
} }
} }

View File

@ -0,0 +1,56 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, BehaviorSubject } from 'rxjs';
import { TokenService } from '../_api/services/token.service';
import { UserInfo } from '../_api/models/user-info';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
private currentUserSubject: BehaviorSubject<UserInfo>;
public currentUser: Observable<UserInfo>;
public IsLoggedIn = false;
constructor(
protected http: HttpClient,
private _tokenService: TokenService
) {
this.currentUserSubject = new BehaviorSubject<UserInfo>(JSON.parse(localStorage.getItem('currentUser')));
this.currentUser = this.currentUserSubject.asObservable();
}
public GetToken(username: string, password: string): Observable<any> {
return this._tokenService.Create({username: username, password: password});
}
public GetAuthStatus() {
return this.IsLoggedIn;
}
public Login(username: string, password: string) {
return this._tokenService.Create({username: username, password: password})
.pipe(map(user => {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem('currentUser', JSON.stringify(user));
this.currentUserSubject.next(user);
console.log('This is USER = ',user)
return user;
}));
}
public Logout() {
localStorage.removeItem('currentUser');
this.currentUserSubject.next(null);
this.IsLoggedIn = false;
}
public get currentUserValue(): UserInfo {
return this.currentUserSubject.value;
}
}

View File

@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './control-panel/home/home.component'; import { HomeComponent } from './control-panel/home/home.component';
import { ConfigComponent } from './control-panel/profile/config/config.component'; import { ConfigComponent } from './control-panel/profile/config/config.component';
import { AuthGuard } from './utils/auth.guard'; import { AuthGuard } from './_helpers/auth.guard';
import { NotFoundComponent } from './control-panel/not-found/not-found.component'; import { NotFoundComponent } from './control-panel/not-found/not-found.component';
import { ProfileComponent } from './control-panel/profile/profile/profile.component'; import { ProfileComponent } from './control-panel/profile/profile/profile.component';
import { EditProfileComponent } from './control-panel/profile/edit-profile/edit-profile.component'; import { EditProfileComponent } from './control-panel/profile/edit-profile/edit-profile.component';

View File

@ -6,7 +6,7 @@
</div> </div>
<div class="ui-toolbar-group-right"> <div class="ui-toolbar-group-right">
<button pButton type="button" label="ABOUT"></button> <button pButton type="button" label="ABOUT" (click)="Logout()"></button>
<button pButton type="button" label="TEAM" ></button> <button pButton type="button" label="TEAM" ></button>
<button pButton type="button" label="CONTACT" ></button> <button pButton type="button" label="CONTACT" ></button>
<button *ngIf="!Connected" pButton type="button" label="SIGN UP" icon="pi pi-pencil" iconPos="right" (click)="SignUp()"></button> <button *ngIf="!Connected" pButton type="button" label="SIGN UP" icon="pi pi-pencil" iconPos="right" (click)="SignUp()"></button>

View File

@ -1,9 +1,10 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { MenuItem } from 'primeng/api'; import { MenuItem } from 'primeng/api';
import { AppService } from './app.service'; import { AppService } from './_services/app.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { AuthService } from './utils/auth.service'; import { AuthenticationService } from './_services/authentication.service';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { first } from 'rxjs/operators';
@Component({ @Component({
@ -30,7 +31,7 @@ export class AppComponent implements OnInit{
constructor( constructor(
private _appService: AppService, private _appService: AppService,
private _translateService: TranslateService, private _translateService: TranslateService,
private _authService: AuthService, private _authService: AuthenticationService,
private _router: Router private _router: Router
){} ){}
@ -38,15 +39,28 @@ export class AppComponent implements OnInit{
this.items = [ this.items = [
{label: 'Update', icon: 'pi pi-refresh'}, {label: 'Update', icon: 'pi pi-refresh'},
{label: 'Delete', icon: 'pi pi-times'} {label: 'Delete', icon: 'pi pi-times'}
]; ];
// To Include in a fonction of a dropdown language chose // To Include in a fonction of a dropdown language chose
this._translateService.setDefaultLang('fr'); this._translateService.setDefaultLang('fr');
let currentUser = this._authService.currentUserValue;
console.log(currentUser);
if (currentUser && currentUser.token) {
this.Connected = true;
this.DisplayLoginModal = false;
this.Username = null;
this.Password = null;
this._authService.IsLoggedIn = true;
}
} }
public LogIn() public LogIn()
{ {
this._appService.GetToken(this.Username, this.Password) /*this._appService.GetToken(this.Username, this.Password)
.subscribe(res => { .subscribe(res => {
console.log(res.Token); console.log(res.Token);
this.Connected = true; this.Connected = true;
@ -58,10 +72,35 @@ export class AppComponent implements OnInit{
this._router.navigate(['/profile/01']); this._router.navigate(['/profile/01']);
}, () => { }, () => {
console.log('ERROR'); console.log('ERROR');
}); });*/
this._authService.Login(this.Username, this.Password)
.pipe(first())
.subscribe(
data => {
console.log(data);
this.Connected = true;
this.DisplayLoginModal = false;
this.Username = null;
this.Password = null;
this._authService.IsLoggedIn = true;
this._router.navigate(['/profile/01']);
},
error => {
console.log('ERROR');
});
// change route -> /config view // change route -> /config view
} }
public Logout() {
this._authService.Logout();
this.Connected = false;
this.Username = null;
this.Password = null;
this._authService.IsLoggedIn = false;
this._router.navigate(['/home']);
}
public SignUp() public SignUp()
{ {
this.DisplaySignInModal = true; this.DisplaySignInModal = true;

View File

@ -5,30 +5,32 @@ import { NgModule, Provider, APP_INITIALIZER } from '@angular/core';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { HomeComponent } from './control-panel/home/home.component'; import { HomeComponent } from './control-panel/home/home.component';
import { HttpClientModule, HttpClient } from '@angular/common/http'; import { HttpClientModule, HttpClient, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AlertModule } from 'ngx-bootstrap/alert'; import { AlertModule } from 'ngx-bootstrap/alert';
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { CarouselModule } from 'ngx-bootstrap/carousel'; import { CarouselModule } from 'ngx-bootstrap/carousel';
import { BorderCardDirective } from './directives/border-card.directive'; import { BorderCardDirective } from './_helpers/_directives/border-card.directive';
import { ToolbarModule } from 'primeng/toolbar'; import { ToolbarModule } from 'primeng/toolbar';
import { ButtonModule } from 'primeng/button'; import { ButtonModule } from 'primeng/button';
import { SplitButtonModule } from 'primeng/splitbutton'; import { SplitButtonModule } from 'primeng/splitbutton';
import { DialogModule } from 'primeng/dialog'; import { DialogModule } from 'primeng/dialog';
import { InputTextModule } from 'primeng/inputtext'; import { InputTextModule } from 'primeng/inputtext';
import { ApiConfiguration } from './api/api-configuration'; import { ApiConfiguration } from './_api/api-configuration';
import { AppService } from './app.service'; import { AppService } from './_services/app.service';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { CalendarModule } from 'primeng/calendar'; import { CalendarModule } from 'primeng/calendar';
import {TranslateModule, TranslateLoader} from '@ngx-translate/core'; import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader'; import {TranslateHttpLoader} from '@ngx-translate/http-loader';
import { AuthService } from './utils/auth.service'; import { AuthenticationService } from './_services/authentication.service';
import { ConfigComponent } from './control-panel/profile/config/config.component'; import { ConfigComponent } from './control-panel/profile/config/config.component';
import { NotFoundComponent } from './control-panel/not-found/not-found.component'; import { NotFoundComponent } from './control-panel/not-found/not-found.component';
import { ProfileComponent } from './control-panel/profile/profile/profile.component'; import { ProfileComponent } from './control-panel/profile/profile/profile.component';
import { EditProfileComponent } from './control-panel/profile/edit-profile/edit-profile.component'; import { EditProfileComponent } from './control-panel/profile/edit-profile/edit-profile.component';
import { JwtInterceptor } from './_helpers/jwt.interceptor';
import { ErrorInterceptor } from './_helpers/error.interceptor';
@ -89,7 +91,9 @@ export function HttpLoaderFactory(http: HttpClient) {
providers: [ providers: [
INIT_API_CONFIGURATION, INIT_API_CONFIGURATION,
AppService, AppService,
AuthService AuthenticationService,
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
], ],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })

View File

@ -1,4 +1,8 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { AppService } from '../../../_services/app.service';
import { TranslateService } from '@ngx-translate/core';
import { AuthenticationService } from '../../../_services/authentication.service';
import { Router } from '@angular/router';
@Component({ @Component({
selector: 'app-profile', selector: 'app-profile',
@ -7,9 +11,21 @@ import { Component, OnInit } from '@angular/core';
}) })
export class ProfileComponent implements OnInit { export class ProfileComponent implements OnInit {
constructor() { } constructor(
private _appService: AppService,
private _translateService: TranslateService,
private _router: Router
) { }
ngOnInit() { ngOnInit() {
this._appService.ConnectionTest().subscribe(
res => {
console.log(res);
console.log('SUCCESS !!');
}, () => {
console.log('error in test');
}
);
} }
} }

View File

@ -1,27 +0,0 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { TokenService } from '../api/services/token.service';
@Injectable({
providedIn: 'root'
})
export class AuthService {
public IsLoggedIn = false;
constructor(
protected http: HttpClient,
private _tokenService: TokenService
) { }
public GetToken(username: string, password: string): Observable<any> {
return this._tokenService.Create({username: username, password: password});
}
public GetAuthStatus() {
return this.IsLoggedIn;
}
}

View File

@ -1,3 +1,4 @@
export const environment = { export const environment = {
production: true production: false,
apiUrl: 'https://localhost:5001'
}; };

File diff suppressed because one or more lines are too long