-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #708 from christophercr/feature/xsrf
feat(stark-core): implement Stark XSRF module
- Loading branch information
Showing
17 changed files
with
874 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from "./xsrf/interceptors"; | ||
export * from "./xsrf/services"; | ||
export * from "./xsrf/xsrf.module"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./interceptors/http-xsrf.interceptor"; |
34 changes: 34 additions & 0 deletions
34
packages/stark-core/src/modules/xsrf/interceptors/http-xsrf.interceptor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Inject, Injectable } from "@angular/core"; | ||
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http"; | ||
import { Observable } from "rxjs"; | ||
import { tap } from "rxjs/operators"; | ||
import { StarkXSRFService, STARK_XSRF_SERVICE } from "../services/xsrf.service.intf"; | ||
|
||
/** | ||
* Angular Http interceptor that adds the XSRF configuration to every state-changing request (POST,PUT,PATCH and DELETE) | ||
* and stores the XSRF token from every response. | ||
* | ||
* Defined in the HttpClientXsrfModule set in packages/stark-core/src/modules/http/http.module.ts | ||
*/ | ||
@Injectable() | ||
export class StarkXSRFHttpInterceptor implements HttpInterceptor { | ||
public constructor(@Inject(STARK_XSRF_SERVICE) public xsrfService: StarkXSRFService) {} | ||
|
||
/** | ||
* @param request - The intercepted outgoing `HttpRequest` | ||
* @param next - The next request handler where the `HttpRequest` will be forwarded to | ||
* @returns The modified `HttpRequest` with the XSRF configuration enabled. | ||
*/ | ||
public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | ||
const xsrfProtectedRequest: HttpRequest<any> = this.xsrfService.configureHttpRequest(request); | ||
|
||
return next | ||
.handle(xsrfProtectedRequest) // pass request through to the next request handler | ||
.pipe( | ||
// the Http response is intercepted in order to extract and store the XSRF token via the XSRF service | ||
tap((_httpResponse: HttpEvent<any>) => { | ||
this.xsrfService.storeXSRFToken(); | ||
}) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from "./services/xsrf.service"; | ||
export * from "./services/xsrf-config.intf"; | ||
export { STARK_XSRF_SERVICE, StarkXSRFService } from "./services/xsrf.service.intf"; |
35 changes: 35 additions & 0 deletions
35
packages/stark-core/src/modules/xsrf/services/xsrf-config.intf.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { InjectionToken } from "@angular/core"; | ||
import { Observable } from "rxjs"; | ||
|
||
/** | ||
* The InjectionToken version of the config name | ||
*/ | ||
export const STARK_XSRF_CONFIG: InjectionToken<StarkXSRFConfig> = new InjectionToken<StarkXSRFConfig>("StarkXSRFConfig"); | ||
|
||
/** | ||
* Alternative literal object to define the waitBeforePinging function and its DI dependencies | ||
*/ | ||
export interface StarkXSRFWaitBeforePingingLiteral { | ||
/** | ||
* Array of Dependency Injection tokens for the dependencies of the waitBeforePingingFn. | ||
*/ | ||
deps: any[]; | ||
|
||
/** | ||
* Function that will be called by the XSRF service passing the necessary dependencies to get the corresponding Promise/Observable | ||
* that the service should wait for before pinging all the backends. | ||
*/ | ||
waitBeforePingingFn: (...deps: any[]) => Promise<any> | PromiseLike<any> | Observable<any>; | ||
} | ||
|
||
/** | ||
* Definition of the configuration object for the Stark XSRF service | ||
*/ | ||
export interface StarkXSRFConfig { | ||
/** | ||
* Function that will be called by the XSRF service to get the corresponding Promise/Observable | ||
* that the service should wait for before pinging all the backends. | ||
* Alternatively, this can be defined as a {@link StarkXSRFWaitBeforePingingLiteral|literal} | ||
*/ | ||
waitBeforePinging?: (() => Promise<any> | PromiseLike<any> | Observable<any>) | StarkXSRFWaitBeforePingingLiteral; | ||
} |
52 changes: 52 additions & 0 deletions
52
packages/stark-core/src/modules/xsrf/services/xsrf.service.intf.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { InjectionToken } from "@angular/core"; | ||
import { HttpRequest } from "@angular/common/http"; | ||
|
||
/** | ||
* The name of the service in case an injection is needed | ||
*/ | ||
export const starkXSRFServiceName: string = "StarkXSRFService"; | ||
/** | ||
* The InjectionToken version of the service name | ||
*/ | ||
export const STARK_XSRF_SERVICE: InjectionToken<StarkXSRFService> = new InjectionToken<StarkXSRFService>(starkXSRFServiceName); | ||
|
||
/** | ||
* Stark XSRF Service. | ||
* Service to get/store the XSRF token to be used with the different backends. | ||
*/ | ||
export interface StarkXSRFService { | ||
/** | ||
* Add the necessary options to the XHR config in order to enable XSRF protection. | ||
* Since the service will add the XSRF header to the XHR object, this method must be called after calling the XHR open() method because | ||
* headers cannot be set before open(). See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader | ||
* This method should be used for those HTTP state-changing requests (POST, PUT, PATCH or DELETE) which are not performed | ||
* using StarkHttpService or Angular raw $http | ||
* @param xhr - The XHR object to be configured | ||
*/ | ||
configureXHR(xhr: XMLHttpRequest): void; | ||
|
||
/** | ||
* Return a new `HttpRequest` including the necessary options for state-changing requests (POST, PUT, PATCH or DELETE) | ||
* in order to enable XSRF protection. | ||
* Logs a warning whenever there is no XSRF token to be sent in such requests | ||
* @param request - The Angular `HttpRequest` to be modified | ||
* @returns The modified Angular `HttpRequest` | ||
*/ | ||
configureHttpRequest(request: HttpRequest<any>): HttpRequest<any>; | ||
|
||
/** | ||
* Get the current XSRF token (in case there is one already stored) | ||
*/ | ||
getXSRFToken(): string | undefined; | ||
|
||
/** | ||
* Store the token from the current XSRF cookie | ||
*/ | ||
storeXSRFToken(): void; | ||
|
||
/** | ||
* Trigger a GET Http request to all the backends in order to get their XSRF tokens. | ||
* Then the response is intercepted by the XSRF Http Interceptor to store the token from the current XSRF cookie | ||
*/ | ||
pingBackends(): void; | ||
} |
Oops, something went wrong.