start of caching, csrf interceptor, and device service

This commit is contained in:
Jesse Lucas 2020-03-20 19:44:21 -04:00
parent 03c6fb2f82
commit 05f01a5d94
11 changed files with 85 additions and 33 deletions

View File

@ -9,6 +9,7 @@ import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatCardModule } from '@angular/material/card';
import { FlexLayoutModule } from '@angular/flex-layout';
import { httpInterceptorProviders } from './http-interceptors';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@ -28,6 +29,7 @@ import { InMemoryConfigDataService } from './in-memory-config-data.service';
import { deviceID } from './api-utils';
import { environment } from '../environments/environment';
import { ChartItemComponent } from './charts/chart-item/chart-item.component';
import { CSRFInterceptor } from './http-interceptors/csrf-intercepor';
@NgModule({
declarations: [
@ -61,7 +63,7 @@ import { ChartItemComponent } from './charts/chart-item/chart-item.component';
[] : HttpClientInMemoryWebApiModule.forRoot(InMemoryConfigDataService,
{ dataEncapsulation: false, delay: 200 }),
],
providers: [],
providers: [httpInterceptorProviders],
bootstrap: [AppComponent]
})

View File

@ -21,7 +21,7 @@ export class FolderChartComponent implements OnInit {
ngOnInit(): void {
for (let state in Folder.StateType) {
console.log(state);
// console.log(state);
}
}

View File

@ -1,5 +1,4 @@
import { Injectable } from '@angular/core';
import { deviceID } from './api-utils';
@Injectable({
providedIn: 'root'
@ -8,14 +7,6 @@ export class CookieService {
constructor() { }
getCSRFHeader(): any {
const dID: String = deviceID();
const csrfCookie = 'CSRF-Token-' + dID
const csrfHeader = {};
csrfHeader['X-CSRF-Token-' + dID] = this.getCookie(csrfCookie);
return csrfHeader;
}
getCookie(name: string): string {
let ca: Array<string> = document.cookie.split(';');
let caLen: number = ca.length;

View File

@ -13,25 +13,25 @@ import Folder from './folder'
providedIn: 'root'
})
export class DbStatusService {
private folderStatus: Object = {};
private headers: HttpHeaders;
private dbStatusUrl = environment.production ? apiURL + 'rest/db/status' : 'api/dbStatus';
private statuses: Map<string, Folder.Status>;
constructor(private http: HttpClient, private cookieService: CookieService) {
this.headers = new HttpHeaders(this.cookieService.getCSRFHeader())
this.statuses = new Map();
}
getFolderStatus(id: string): Observable<Folder.Status> {
let httpOptions: { headers: HttpHeaders } |
{ headers: HttpHeaders, params: HttpParams };
// First check to see if we have a cached value
if (this.statuses.has(id)) {
return of(this.statuses.get(id));
}
let httpOptions: { params: HttpParams };
if (id) {
httpOptions = {
headers: this.headers,
params: new HttpParams().set('folder', id)
};
} else {
httpOptions = { headers: this.headers };
}
} else { }
return this.http
.get<Folder.Status>(this.dbStatusUrl, httpOptions)
@ -41,13 +41,13 @@ export class DbStatusService {
// Remove from array in developement
// in-memory-web-api returns arrays
if (!environment.production) {
console.log("status res!", res);
const a: any = res as any;
if (a.length > 0) {
return res[0];
res = res[0];
}
return {};
}
// cache result
this.statuses.set(id, res)
return res;
})
);

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { DeviceService } from './device.service';
describe('DeviceService', () => {
let service: DeviceService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(DeviceService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,9 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class DeviceService {
constructor() { }
}

View File

@ -26,7 +26,7 @@ export class FolderService {
startIndex = startIndex + 1;
this.dbStatusService.getFolderStatus(folder.id).subscribe(
status => {
folder["status"] = status;
folder.status = status;
observer.next(folder);
// recursively get the status of the next folder
@ -41,6 +41,7 @@ export class FolderService {
*/
getAll(): Observable<Folder> {
const folderObservable: Observable<Folder> = new Observable((observer) => {
this.systemConfigService.getFolders().subscribe(
folders => {
this.folders = folders;
@ -53,5 +54,4 @@ export class FolderService {
});
return folderObservable
}
}
}

View File

@ -0,0 +1,29 @@
import { Injectable } from '@angular/core';
import { deviceID } from '../api-utils';
import {
HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders
} from '@angular/common/http';
import { CookieService } from '../cookie.service';
@Injectable()
export class CSRFInterceptor implements HttpInterceptor {
constructor(private cookieService: CookieService) { }
intercept(req: HttpRequest<any>, next: HttpHandler) {
const dID: String = deviceID();
const csrfCookie = 'CSRF-Token-' + dID
// Clone the request and replace the original headers with
// cloned headers, updated with the CSRF information.
const csrfReq = req.clone({
headers: req.headers.set('X-CSRF-Token-' + dID,
this.cookieService.getCookie(csrfCookie))
});
// send cloned request with header to the next handler.
return next.handle(csrfReq);
}
}

View File

@ -0,0 +1,8 @@
/* "Barrel" of Http Interceptors */
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { CSRFInterceptor } from './csrf-intercepor';
/** Http interceptor providers in outside-in order */
export const httpInterceptorProviders = [
{ provide: HTTP_INTERCEPTORS, useClass: CSRFInterceptor, multi: true },
];

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { config } from './mock/mock-config'
import { dbStatus } from './mock/mock-db-status'
import { config } from './mocks/mock-config'
import { dbStatus } from './mocks/mock-db-status'
@Injectable({
providedIn: 'root'

View File

@ -20,17 +20,14 @@ export class SystemConfigService {
private devicesSubject: Subject<Device[]> = new Subject();
private systemConfigUrl = environment.production ? apiURL + 'rest/system/config' : 'api/config';
private httpOptions: any;
private checkInterval: number = 100;
constructor(private http: HttpClient, private cookieService: CookieService) {
this.httpOptions = { headers: new HttpHeaders(this.cookieService.getCSRFHeader()) };
}
constructor(private http: HttpClient) { }
getSystemConfig(): Observable<any> {
return this.http
.get(this.systemConfigUrl, this.httpOptions)
.get(this.systemConfigUrl)
.pipe(
retry(apiRetry),
map(res => {