| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-15 11:35:08 -08:00
										 |  |  | import {HttpHeaders} from '@angular/common/http/src/headers'; | 
					
						
							|  |  |  | import {HttpRequest} from '@angular/common/http/src/request'; | 
					
						
							|  |  |  | import {HttpXsrfCookieExtractor, HttpXsrfInterceptor, HttpXsrfTokenExtractor} from '@angular/common/http/src/xsrf'; | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-15 11:35:08 -08:00
										 |  |  | import {HttpClientTestingBackend} from '@angular/common/http/testing/src/backend'; | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-24 21:22:22 -04:00
										 |  |  | class SampleTokenExtractor extends HttpXsrfTokenExtractor { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   constructor(private token: string|null) { | 
					
						
							|  |  |  |     super(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   getToken(): string|null { | 
					
						
							|  |  |  |     return this.token; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-16 14:42:55 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  |   describe('HttpXsrfInterceptor', () => { | 
					
						
							|  |  |  |     let backend: HttpClientTestingBackend; | 
					
						
							|  |  |  |     const interceptor = new HttpXsrfInterceptor(new SampleTokenExtractor('test'), 'X-XSRF-TOKEN'); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       backend = new HttpClientTestingBackend(); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  |     it('applies XSRF protection to outgoing requests', () => { | 
					
						
							|  |  |  |       interceptor.intercept(new HttpRequest('POST', '/test', {}), backend).subscribe(); | 
					
						
							|  |  |  |       const req = backend.expectOne('/test'); | 
					
						
							|  |  |  |       expect(req.request.headers.get('X-XSRF-TOKEN')).toEqual('test'); | 
					
						
							|  |  |  |       req.flush({}); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     it('does not apply XSRF protection when request is a GET', () => { | 
					
						
							|  |  |  |       interceptor.intercept(new HttpRequest('GET', '/test'), backend).subscribe(); | 
					
						
							|  |  |  |       const req = backend.expectOne('/test'); | 
					
						
							|  |  |  |       expect(req.request.headers.has('X-XSRF-TOKEN')).toEqual(false); | 
					
						
							|  |  |  |       req.flush({}); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     it('does not apply XSRF protection when request is a HEAD', () => { | 
					
						
							|  |  |  |       interceptor.intercept(new HttpRequest('HEAD', '/test'), backend).subscribe(); | 
					
						
							|  |  |  |       const req = backend.expectOne('/test'); | 
					
						
							|  |  |  |       expect(req.request.headers.has('X-XSRF-TOKEN')).toEqual(false); | 
					
						
							|  |  |  |       req.flush({}); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     it('does not overwrite existing header', () => { | 
					
						
							|  |  |  |       interceptor | 
					
						
							|  |  |  |           .intercept( | 
					
						
							|  |  |  |               new HttpRequest( | 
					
						
							|  |  |  |                   'POST', '/test', {}, {headers: new HttpHeaders().set('X-XSRF-TOKEN', 'blah')}), | 
					
						
							|  |  |  |               backend) | 
					
						
							|  |  |  |           .subscribe(); | 
					
						
							|  |  |  |       const req = backend.expectOne('/test'); | 
					
						
							|  |  |  |       expect(req.request.headers.get('X-XSRF-TOKEN')).toEqual('blah'); | 
					
						
							|  |  |  |       req.flush({}); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     it('does not set the header for a null token', () => { | 
					
						
							|  |  |  |       const interceptor = new HttpXsrfInterceptor(new SampleTokenExtractor(null), 'X-XSRF-TOKEN'); | 
					
						
							|  |  |  |       interceptor.intercept(new HttpRequest('POST', '/test', {}), backend).subscribe(); | 
					
						
							|  |  |  |       const req = backend.expectOne('/test'); | 
					
						
							|  |  |  |       expect(req.request.headers.has('X-XSRF-TOKEN')).toEqual(false); | 
					
						
							|  |  |  |       req.flush({}); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     afterEach(() => { | 
					
						
							|  |  |  |       backend.verify(); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  |   describe('HttpXsrfCookieExtractor', () => { | 
					
						
							|  |  |  |     let document: {[key: string]: string}; | 
					
						
							| 
									
										
										
										
											2017-07-27 16:13:16 -07:00
										 |  |  |     let extractor: HttpXsrfCookieExtractor; | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       document = { | 
					
						
							|  |  |  |         cookie: 'XSRF-TOKEN=test', | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       extractor = new HttpXsrfCookieExtractor(document, 'browser', 'XSRF-TOKEN'); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     it('parses the cookie from document.cookie', () => { | 
					
						
							|  |  |  |       expect(extractor.getToken()).toEqual('test'); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  |     it('does not re-parse if document.cookie has not changed', () => { | 
					
						
							|  |  |  |       expect(extractor.getToken()).toEqual('test'); | 
					
						
							|  |  |  |       expect(extractor.getToken()).toEqual('test'); | 
					
						
							| 
									
										
										
										
											2018-06-29 11:55:55 -07:00
										 |  |  |       expect(getParseCount(extractor)).toEqual(1); | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |     it('re-parses if document.cookie changes', () => { | 
					
						
							|  |  |  |       expect(extractor.getToken()).toEqual('test'); | 
					
						
							|  |  |  |       document['cookie'] = 'XSRF-TOKEN=blah'; | 
					
						
							|  |  |  |       expect(extractor.getToken()).toEqual('blah'); | 
					
						
							| 
									
										
										
										
											2018-06-29 11:55:55 -07:00
										 |  |  |       expect(getParseCount(extractor)).toEqual(2); | 
					
						
							| 
									
										
										
										
											2017-07-13 17:22:02 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-06-29 11:55:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | function getParseCount(extractor: HttpXsrfCookieExtractor): number { | 
					
						
							|  |  |  |   return (extractor as any).parseCount; | 
					
						
							| 
									
										
										
										
											2018-11-15 11:35:08 -08:00
										 |  |  | } |