I've been working on intercepting outgoing HTTP requests in Angular 2 in order to generate a token from the request body and attach it to the header of each post request. Below is the code snippet that I've implemented.
Initially, I encountered a runtime error stating:
"e.json() is not a function"
To address this error, I attempted to catch the exception and add a 'json' function if missing. However, this led to a new runtime error:
"message: __generator is not defined"
stack: "ReferenceError: __generator is not defined↵ at e.<anonymous>"
In an effort to resolve this issue, I set "noEmitHelpers": false
based on a suggestion from this question: async/await __generator is not defined
Despite this adjustment, the runtime error persists.
Any advice or assistance would be greatly appreciated.
declare var TextEncoder: any
import { Headers, Http, Request, RequestOptions, RequestOptionsArgs, Response, XHRBackend } from "@angular/http"
import { Injectable } from "@angular/core"
import { Observable } from "rxjs/Rx"
// operators
import "rxjs/add/operator/catch"
import "rxjs/add/observable/throw"
import "rxjs/add/operator/map"
import { fromPromise } from "rxjs/observable/fromPromise"
import { switchMap } from "rxjs/operators"
@Injectable()
export class DigestIntegrationInterceptor extends Http {
constructor(
backend: XHRBackend,
options: RequestOptions
) {
super(backend, options)
}
request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
return super.request(url, options);
}
post(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
const timeStamp = new Date().getTime() + "";
const tokenPromise = this.generateDigestHex(this.generateToken(body, timeStamp));
return fromPromise(tokenPromise).pipe(
switchMap((token:string) => super.post(url, body, this.generateHeaders(token, timeStamp, options))),
// add 'json' function to error if it's missing
catchError(e => typeof e.json === 'function' ? Observable.throw(e): Observable.throw({ json: () => e })),
// To check what the observable emits - for debugging purpose only
tap({
next: v => console.log('http interceptor next', v),
error: e => console.log('http interceptor error', e),
})
);
}
generateHeaders(token:string, timeStamp, options: RequestOptionsArgs){
if (options == null) {
options = new RequestOptions();
}
if (options.headers == null) {
options.headers = new Headers({ 'Content-Type': 'application/json' });
}
options.headers.append("X-TOKEN", token);
options.headers.append("X-REQ-TS", timeStamp);
return options;
}
generateToken(requestBody: any, timeStamp: string): string {
return `X-${timeStamp}-${JSON.stringify(requestBody)}`;
}
async generateDigestHex(message) {
const msgUint8 = new TextEncoder().encode(message);
const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray
.map((b) => b.toString(16)['padStart'](2, "0"))
.join("");
return hashHex;
}
}