This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -2,3 +2,4 @@ | ||||
| /dist/ | ||||
| /.nyc_output/ | ||||
| /coverage/ | ||||
| /.stryker-tmp/ | ||||
|   | ||||
| @@ -11,8 +11,9 @@ type TokenType = 'access_token'|'refresh_token'|'part_token'|'none' | ||||
|  | ||||
| interface VerificationResult { | ||||
|   authorized: boolean; | ||||
|   valid: boolean; | ||||
|   type: TokenType; | ||||
|   next_module: string; | ||||
|   next_module?: string; | ||||
| } | ||||
|  | ||||
| interface SignatureResult { | ||||
| @@ -24,8 +25,8 @@ class Authority { | ||||
|   public verify (key: string): VerificationResult { | ||||
|     const result: VerificationResult = { | ||||
|       authorized: false, | ||||
|       type:        'none', | ||||
|       next_module: '' | ||||
|       valid:      false, | ||||
|       type:       'none' | ||||
|     }; | ||||
|     const data = verify_signature_get_info ( | ||||
|       key, | ||||
| @@ -41,6 +42,7 @@ class Authority { | ||||
|     if (!blacklist.is_valid (data.id)) | ||||
|       return result; | ||||
|  | ||||
|     result.valid = true; | ||||
|     result.authorized = result.type === 'access_token'; | ||||
|     result.next_module = data.obj; | ||||
|  | ||||
|   | ||||
| @@ -9,20 +9,22 @@ | ||||
|   "description": "authentication middleware for express", | ||||
|   "license": "MIT", | ||||
|   "devDependencies": { | ||||
|     "@ert78gb/jasmine-ts": "^0.3.1", | ||||
|     "@sapphirecode/eslint-config-ts": "^1.1.27", | ||||
|     "@stryker-mutator/core": "^4.3.1", | ||||
|     "@stryker-mutator/jasmine-runner": "^4.3.1", | ||||
|     "@types/jasmine": "^3.6.2", | ||||
|     "@types/node": "^10.0.0", | ||||
|     "eslint": "^7.14.0", | ||||
|     "jasmine": "^3.6.3", | ||||
|     "jasmine-ts": "^0.3.0", | ||||
|     "nyc": "^15.1.0", | ||||
|     "ts-node": "^8.0.0", | ||||
|     "ts-node": "^9.1.1", | ||||
|     "typescript": "^4.1.2" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue,.mjs", | ||||
|     "test": "nyc jasmine-ts --config=\"jasmine.json\"", | ||||
|     "mutate": "stryker run", | ||||
|     "mutate": "stryker run --fileLogLevel trace --logLevel debug", | ||||
|     "compile": "tsc" | ||||
|   }, | ||||
|   "files": [ | ||||
|   | ||||
							
								
								
									
										23
									
								
								stryker.conf.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								stryker.conf.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| /* | ||||
|  * Copyright (C) Sapphirecode - All Rights Reserved | ||||
|  * This file is part of crypto-helper which is released under MIT. | ||||
|  * See file 'LICENSE' for full license details. | ||||
|  * Created by Timo Hocker <timo@scode.ovh>, May 2020 | ||||
|  */ | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
| /** | ||||
|  * @type {import('@stryker-mutator/api/core').StrykerOptions} | ||||
|  */ | ||||
| module.exports = { | ||||
|   packageManager:   'yarn', | ||||
|   reporters:        [ | ||||
|     'clear-text', | ||||
|     'progress' | ||||
|   ], | ||||
|   testRunner:        'jasmine', | ||||
|   jasmineConfigFile: 'jasmine.json', | ||||
|   coverageAnalysis:  'perTest', | ||||
|   mutate:            [ 'lib/*.ts' ] | ||||
| }; | ||||
| @@ -1,5 +1,15 @@ | ||||
| import { hash_sha512 } from '@sapphirecode/crypto-helper'; | ||||
| import auth from '../../lib/Authority'; | ||||
| import bl from '../../lib/Blacklist'; | ||||
|  | ||||
| function modify_signature (signature: string): string { | ||||
|   const dec = decodeURIComponent (signature) | ||||
|     .split ('.'); | ||||
|   dec[1] = hash_sha512 ('', ''); | ||||
|   return encodeURIComponent (dec.join ('.')); | ||||
| } | ||||
|  | ||||
| // eslint-disable-next-line max-lines-per-function | ||||
| describe ('authority', () => { | ||||
|   beforeEach (() => { | ||||
|     jasmine.clock () | ||||
| @@ -9,6 +19,8 @@ describe ('authority', () => { | ||||
|   }); | ||||
|  | ||||
|   afterEach (() => { | ||||
|     jasmine.clock () | ||||
|       .tick (24 * 60 * 60 * 1000); | ||||
|     jasmine.clock () | ||||
|       .uninstall (); | ||||
|   }); | ||||
| @@ -20,6 +32,8 @@ describe ('authority', () => { | ||||
|     const res = auth.verify (token.signature); | ||||
|     expect (res.authorized) | ||||
|       .toBeTrue (); | ||||
|     expect (res.valid) | ||||
|       .toBeTrue (); | ||||
|     expect (res.type) | ||||
|       .toEqual ('access_token'); | ||||
|     expect (res.next_module) | ||||
| @@ -33,6 +47,8 @@ describe ('authority', () => { | ||||
|     const res = auth.verify (token.signature); | ||||
|     expect (res.authorized) | ||||
|       .toBeFalse (); | ||||
|     expect (res.valid) | ||||
|       .toBeTrue (); | ||||
|     expect (res.type) | ||||
|       .toEqual ('refresh_token'); | ||||
|     expect (res.next_module) | ||||
| @@ -46,9 +62,75 @@ describe ('authority', () => { | ||||
|     const res = auth.verify (token.signature); | ||||
|     expect (res.authorized) | ||||
|       .toBeFalse (); | ||||
|     expect (res.valid) | ||||
|       .toBeTrue (); | ||||
|     expect (res.type) | ||||
|       .toEqual ('part_token'); | ||||
|     expect (res.next_module) | ||||
|       .toEqual ('2fa'); | ||||
|   }); | ||||
|  | ||||
|   it ('should reject an invalid access token', () => { | ||||
|     const token = auth.sign ('access_token', 60); | ||||
|     token.signature = modify_signature (token.signature); | ||||
|     jasmine.clock () | ||||
|       .tick (30000); | ||||
|     const res = auth.verify (token.signature); | ||||
|     expect (res.authorized) | ||||
|       .toBeFalse (); | ||||
|     expect (res.valid) | ||||
|       .toBeFalse (); | ||||
|     expect (res.type) | ||||
|       .toEqual ('none'); | ||||
|     expect (res.next_module) | ||||
|       .toBeUndefined (); | ||||
|   }); | ||||
|  | ||||
|   it ('should reject blacklisted access token', () => { | ||||
|     const token = auth.sign ('access_token', 60); | ||||
|     jasmine.clock () | ||||
|       .tick (30000); | ||||
|     bl.add_signature (token.id); | ||||
|     const res = auth.verify (token.signature); | ||||
|     expect (res.authorized) | ||||
|       .toBeFalse (); | ||||
|     expect (res.valid) | ||||
|       .toBeFalse (); | ||||
|     expect (res.type) | ||||
|       .toEqual ('access_token'); | ||||
|     expect (res.next_module) | ||||
|       .toBeUndefined (); | ||||
|   }); | ||||
|  | ||||
|   it ('should reject an invalid refresh token', () => { | ||||
|     const token = auth.sign ('refresh_token', 600); | ||||
|     token.signature = modify_signature (token.signature); | ||||
|     jasmine.clock () | ||||
|       .tick (30000); | ||||
|     const res = auth.verify (token.signature); | ||||
|     expect (res.authorized) | ||||
|       .toBeFalse (); | ||||
|     expect (res.valid) | ||||
|       .toBeFalse (); | ||||
|     expect (res.type) | ||||
|       .toEqual ('none'); | ||||
|     expect (res.next_module) | ||||
|       .toBeUndefined (); | ||||
|   }); | ||||
|  | ||||
|   it ('should reject a blacklisted refresh token', () => { | ||||
|     const token = auth.sign ('refresh_token', 600); | ||||
|     jasmine.clock () | ||||
|       .tick (30000); | ||||
|     bl.add_signature (token.id); | ||||
|     const res = auth.verify (token.signature); | ||||
|     expect (res.authorized) | ||||
|       .toBeFalse (); | ||||
|     expect (res.valid) | ||||
|       .toBeFalse (); | ||||
|     expect (res.type) | ||||
|       .toEqual ('refresh_token'); | ||||
|     expect (res.next_module) | ||||
|       .toBeUndefined (); | ||||
|   }); | ||||
| }); | ||||
|   | ||||
| @@ -95,6 +95,8 @@ describe ('key store', () => { | ||||
|   }); | ||||
|  | ||||
|   afterAll (() => { | ||||
|     jasmine.clock () | ||||
|       .tick (24 * 60 * 60 * 1000); | ||||
|     jasmine.clock () | ||||
|       .uninstall (); | ||||
|   }); | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
|     "strict": true,  | ||||
|     "esModuleInterop": true, | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "declaration": true   | ||||
|     "declaration": true, | ||||
|     "sourceMap": true | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user