This commit is contained in:
parent
669bc19943
commit
b27ab8c6fc
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
|||||||
/dist/
|
/dist/
|
||||||
/.nyc_output/
|
/.nyc_output/
|
||||||
/coverage/
|
/coverage/
|
||||||
|
/.stryker-tmp/
|
||||||
|
@ -11,8 +11,9 @@ type TokenType = 'access_token'|'refresh_token'|'part_token'|'none'
|
|||||||
|
|
||||||
interface VerificationResult {
|
interface VerificationResult {
|
||||||
authorized: boolean;
|
authorized: boolean;
|
||||||
|
valid: boolean;
|
||||||
type: TokenType;
|
type: TokenType;
|
||||||
next_module: string;
|
next_module?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SignatureResult {
|
interface SignatureResult {
|
||||||
@ -23,9 +24,9 @@ interface SignatureResult {
|
|||||||
class Authority {
|
class Authority {
|
||||||
public verify (key: string): VerificationResult {
|
public verify (key: string): VerificationResult {
|
||||||
const result: VerificationResult = {
|
const result: VerificationResult = {
|
||||||
authorized: false,
|
authorized: false,
|
||||||
type: 'none',
|
valid: false,
|
||||||
next_module: ''
|
type: 'none'
|
||||||
};
|
};
|
||||||
const data = verify_signature_get_info (
|
const data = verify_signature_get_info (
|
||||||
key,
|
key,
|
||||||
@ -41,6 +42,7 @@ class Authority {
|
|||||||
if (!blacklist.is_valid (data.id))
|
if (!blacklist.is_valid (data.id))
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
result.valid = true;
|
||||||
result.authorized = result.type === 'access_token';
|
result.authorized = result.type === 'access_token';
|
||||||
result.next_module = data.obj;
|
result.next_module = data.obj;
|
||||||
|
|
||||||
|
10
package.json
10
package.json
@ -9,20 +9,22 @@
|
|||||||
"description": "authentication middleware for express",
|
"description": "authentication middleware for express",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@ert78gb/jasmine-ts": "^0.3.1",
|
||||||
"@sapphirecode/eslint-config-ts": "^1.1.27",
|
"@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/jasmine": "^3.6.2",
|
||||||
"@types/node": "^10.0.0",
|
"@types/node": "^10.0.0",
|
||||||
"eslint": "^7.14.0",
|
"eslint": "^7.14.0",
|
||||||
"jasmine": "^3.6.3",
|
"jasmine": "^3.6.3",
|
||||||
"jasmine-ts": "^0.3.0",
|
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"ts-node": "^8.0.0",
|
"ts-node": "^9.1.1",
|
||||||
"typescript": "^4.1.2"
|
"typescript": "^4.1.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue,.mjs",
|
"lint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue,.mjs",
|
||||||
"test": "nyc jasmine-ts --config=\"jasmine.json\"",
|
"test": "nyc jasmine-ts --config=\"jasmine.json\"",
|
||||||
"mutate": "stryker run",
|
"mutate": "stryker run --fileLogLevel trace --logLevel debug",
|
||||||
"compile": "tsc"
|
"compile": "tsc"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
@ -43,4 +45,4 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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 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', () => {
|
describe ('authority', () => {
|
||||||
beforeEach (() => {
|
beforeEach (() => {
|
||||||
jasmine.clock ()
|
jasmine.clock ()
|
||||||
@ -9,6 +19,8 @@ describe ('authority', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach (() => {
|
afterEach (() => {
|
||||||
|
jasmine.clock ()
|
||||||
|
.tick (24 * 60 * 60 * 1000);
|
||||||
jasmine.clock ()
|
jasmine.clock ()
|
||||||
.uninstall ();
|
.uninstall ();
|
||||||
});
|
});
|
||||||
@ -20,6 +32,8 @@ describe ('authority', () => {
|
|||||||
const res = auth.verify (token.signature);
|
const res = auth.verify (token.signature);
|
||||||
expect (res.authorized)
|
expect (res.authorized)
|
||||||
.toBeTrue ();
|
.toBeTrue ();
|
||||||
|
expect (res.valid)
|
||||||
|
.toBeTrue ();
|
||||||
expect (res.type)
|
expect (res.type)
|
||||||
.toEqual ('access_token');
|
.toEqual ('access_token');
|
||||||
expect (res.next_module)
|
expect (res.next_module)
|
||||||
@ -33,6 +47,8 @@ describe ('authority', () => {
|
|||||||
const res = auth.verify (token.signature);
|
const res = auth.verify (token.signature);
|
||||||
expect (res.authorized)
|
expect (res.authorized)
|
||||||
.toBeFalse ();
|
.toBeFalse ();
|
||||||
|
expect (res.valid)
|
||||||
|
.toBeTrue ();
|
||||||
expect (res.type)
|
expect (res.type)
|
||||||
.toEqual ('refresh_token');
|
.toEqual ('refresh_token');
|
||||||
expect (res.next_module)
|
expect (res.next_module)
|
||||||
@ -46,9 +62,75 @@ describe ('authority', () => {
|
|||||||
const res = auth.verify (token.signature);
|
const res = auth.verify (token.signature);
|
||||||
expect (res.authorized)
|
expect (res.authorized)
|
||||||
.toBeFalse ();
|
.toBeFalse ();
|
||||||
|
expect (res.valid)
|
||||||
|
.toBeTrue ();
|
||||||
expect (res.type)
|
expect (res.type)
|
||||||
.toEqual ('part_token');
|
.toEqual ('part_token');
|
||||||
expect (res.next_module)
|
expect (res.next_module)
|
||||||
.toEqual ('2fa');
|
.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 (() => {
|
afterAll (() => {
|
||||||
|
jasmine.clock ()
|
||||||
|
.tick (24 * 60 * 60 * 1000);
|
||||||
jasmine.clock ()
|
jasmine.clock ()
|
||||||
.uninstall ();
|
.uninstall ();
|
||||||
});
|
});
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
"strict": true,
|
"strict": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"declaration": true
|
"declaration": true,
|
||||||
|
"sourceMap": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user