/* * Copyright (C) Sapphirecode - All Rights Reserved * This file is part of Auth-Server-Helper which is released under MIT. * See file 'LICENSE' for full license details. * Created by Timo Hocker , December 2020 */ import { generate_keypair } from '@sapphirecode/crypto-helper'; interface Keypair { private_key: string; public_key: string; } interface Key { key: Keypair; valid_until: number; timeout: NodeJS.Timeout; } function get_index (iat: number): string { return Math.floor (iat / 60) .toFixed (0); } class KeyStore { private _keys: Record = {}; private set_timeout (index: string, valid_for: number): NodeJS.Timeout { return setTimeout (() => { delete this._keys[index]; }, (valid_for + 5) * 1000); } public async get_sign_key (iat: number, valid_for: number): Promise { const index = get_index (iat); if (valid_for <= 0) throw new Error ('cannot create infinitely valid key'); if ((iat + 1) * 1000 < (new Date) .getTime ()) throw new Error ('cannot access already expired keys'); const valid_until = (new Date) .getTime () + (valid_for * 1000); if (typeof this._keys[index] !== 'undefined') { const key = this._keys[index]; if (key.valid_until < valid_until) { clearTimeout (key.timeout); key.timeout = this.set_timeout (index, valid_for); key.valid_until = valid_until; } return key.key.private_key; } this._keys[index] = { key: await generate_keypair (), timeout: this.set_timeout (index, valid_for), valid_until }; return this._keys[index].key.private_key; } public get_key (iat: number): string { const index = get_index (iat); if (typeof this._keys[index] === 'undefined') throw new Error ('key could not be found'); const key = this._keys[index]; return key.key.public_key; } } const ks: KeyStore = (new KeyStore); export default ks; export { KeyStore };