fix
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Timo Hocker 2021-01-06 11:15:56 +01:00
parent 05f2e53a8f
commit df8de9e0c8
2 changed files with 72 additions and 18 deletions

View File

@ -7,26 +7,50 @@
import { create_salt } from '@sapphirecode/crypto-helper'; import { create_salt } from '@sapphirecode/crypto-helper';
interface Key {
key: string;
valid_until: number;
timeout: NodeJS.Timeout;
}
class KeyStore { class KeyStore {
private _keys: Record<string, string> = {}; private _keys: Record<string, Key> = {};
private set_timeout (index: string, valid_for: number): NodeJS.Timeout {
return setTimeout (() => {
delete this._keys[index];
}, (valid_for + 5) * 1000);
}
public get_key (iat: number, valid_for = 0): string { public get_key (iat: number, valid_for = 0): string {
const key = Math.floor (iat / 60) const index = Math.floor (iat / 60)
.toFixed (0); .toFixed (0);
if (typeof this._keys[key] === 'string') const valid_until = (new Date)
return this._keys[key]; .getTime () + (valid_for * 1000);
if (typeof this._keys[index] !== 'undefined') {
const key = this._keys[index];
if (valid_for !== 0 && key.valid_until < valid_until) {
clearTimeout (key.timeout);
key.timeout = this.set_timeout (index, valid_for);
key.valid_until = valid_until;
}
return key.key;
}
if (valid_for !== 0) { if (valid_for !== 0) {
if ((iat + valid_for) * 1000 < (new Date) if ((iat + 1) * 1000 < (new Date)
.getTime ()) .getTime ())
throw new Error ('cannot create already expired keys'); throw new Error ('cannot create already expired keys');
this._keys[key] = create_salt (); this._keys[index] = {
setTimeout (() => { key: create_salt (),
delete this._keys[key]; timeout: this.set_timeout (index, valid_for),
}, (valid_for + 5) * 1000); valid_until
return this._keys[key]; };
return this._keys[index].key;
} }
throw new Error ('key could not be found'); throw new Error ('key could not be found');

View File

@ -7,6 +7,8 @@
import ks from '../../lib/KeyStore'; import ks from '../../lib/KeyStore';
const frame = 60;
/* eslint-disable-next-line max-lines-per-function */ /* eslint-disable-next-line max-lines-per-function */
describe ('key store', () => { describe ('key store', () => {
beforeAll (() => { beforeAll (() => {
@ -23,7 +25,7 @@ describe ('key store', () => {
it ('should generate a new key', () => { it ('should generate a new key', () => {
const iat = (new Date) const iat = (new Date)
.getTime () / 1000; .getTime () / 1000;
const duration = 600; const duration = 10 * frame;
const key = ks.get_key (iat, duration); const key = ks.get_key (iat, duration);
expect (typeof key) expect (typeof key)
.toEqual ('string'); .toEqual ('string');
@ -39,17 +41,17 @@ describe ('key store', () => {
}); });
it ('should return the same key on a different time', () => { it ('should return the same key on a different time', () => {
const key = ks.get_key (keys[0].iat + 30); const key = ks.get_key (keys[0].iat + (frame / 2));
expect (key) expect (key)
.toEqual (keys[0].key); .toEqual (keys[0].key);
}); });
it ('should generate a new key after 60 seconds', () => { it ('should generate a new key after time frame is over', () => {
jasmine.clock () jasmine.clock ()
.tick (60000); .tick (frame * 1000);
const iat = (new Date) const iat = (new Date)
.getTime () / 1000; .getTime () / 1000;
const duration = 600; const duration = 10 * frame;
const key = ks.get_key (iat, duration); const key = ks.get_key (iat, duration);
expect (typeof key) expect (typeof key)
.toEqual ('string'); .toEqual ('string');
@ -69,13 +71,13 @@ describe ('key store', () => {
}); });
it ('should throw on non existing key', () => { it ('should throw on non existing key', () => {
expect (() => ks.get_key (keys[1].iat + 60)) expect (() => ks.get_key (keys[1].iat + frame))
.toThrowError ('key could not be found'); .toThrowError ('key could not be found');
}); });
it ('should delete a key after it expires', () => { it ('should delete a key after it expires', () => {
jasmine.clock () jasmine.clock ()
.tick (600000); .tick (10000 * frame);
expect (() => ks.get_key (keys[0].iat)) expect (() => ks.get_key (keys[0].iat))
.toThrowError ('key could not be found'); .toThrowError ('key could not be found');
}); });
@ -88,12 +90,40 @@ describe ('key store', () => {
it ('should reject key generation of expired keys', () => { it ('should reject key generation of expired keys', () => {
const iat = ((new Date) const iat = ((new Date)
.getTime () / 1000) - 10; .getTime () / 1000) - 2;
const duration = 5; const duration = 5;
expect (() => ks.get_key (iat, duration)) expect (() => ks.get_key (iat, duration))
.toThrowError ('cannot create already expired keys'); .toThrowError ('cannot create already expired keys');
}); });
it ('key should live as long as the longest created token', () => {
const base = new Date;
base.setSeconds (2, 0);
jasmine.clock ()
.mockDate (base);
jasmine.clock ()
.tick (24 * 60 * 60 * 1000);
const iat = (new Date)
.getTime () / 1000;
const duration1 = frame;
const duration2 = frame * 10;
const key1 = ks.get_key (iat, duration1);
const step = 0.9 * frame;
jasmine.clock ()
.tick (step * 1000);
const key2 = ks.get_key (iat + step, duration2);
expect (key1)
.toEqual (key2);
jasmine.clock ()
.tick (5000 * frame);
const keyv = ks.get_key (iat + step);
expect (keyv)
.toEqual (key1);
});
// required use case: insert keys for verification of old tokens
afterAll (() => { afterAll (() => {
jasmine.clock () jasmine.clock ()
.tick (24 * 60 * 60 * 1000); .tick (24 * 60 * 60 * 1000);