This commit is contained in:
		| @@ -15,12 +15,17 @@ interface Key { | ||||
|   valid_until: number; | ||||
| } | ||||
|  | ||||
| interface LabelledKey extends Key { | ||||
|   index: string; | ||||
| } | ||||
|  | ||||
| interface KeyPair { | ||||
|   private_key?: Key; | ||||
|   public_key: Key; | ||||
| } | ||||
|  | ||||
| type KeyStoreData = Record<string, KeyPair>; | ||||
| type KeyStoreExport = LabelledKey[]; | ||||
|  | ||||
| async function create_key (valid_for: number) { | ||||
|   const time = (new Date) | ||||
| @@ -59,19 +64,19 @@ class KeyStore { | ||||
|       .toFixed (0); | ||||
|   } | ||||
|  | ||||
|   private garbage_collect (set: KeyStoreData = this._keys): void { | ||||
|   private garbage_collect (): void { | ||||
|     const time = (new Date) | ||||
|       .getTime (); | ||||
|     const keys = Object.keys (set); | ||||
|     const keys = Object.keys (this._keys); | ||||
|     for (const index of keys) { | ||||
|       const entry = set[index]; | ||||
|       const entry = this._keys[index]; | ||||
|       if (typeof entry.private_key !== 'undefined' | ||||
|         && entry.private_key.valid_until < time | ||||
|       ) | ||||
|         delete entry.private_key; | ||||
|  | ||||
|       if (entry.public_key.valid_until < time) | ||||
|         delete set[index]; | ||||
|         delete this._keys[index]; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -117,22 +122,25 @@ class KeyStore { | ||||
|     return key.public_key.key; | ||||
|   } | ||||
|  | ||||
|   public export_verification_data (): KeyStoreData { | ||||
|   public export_verification_data (): KeyStoreExport { | ||||
|     this.garbage_collect (); | ||||
|     const out: KeyStoreData = {}; | ||||
|     const out: KeyStoreExport = []; | ||||
|     for (const index of Object.keys (this._keys)) | ||||
|       out[index] = { public_key: this._keys[index].public_key }; | ||||
|       out.push ({ ...this._keys[index].public_key, index }); | ||||
|  | ||||
|     return out; | ||||
|   } | ||||
|  | ||||
|   public import_verification_data (data: KeyStoreData): void { | ||||
|     const import_set = { ...data }; | ||||
|     this.garbage_collect (import_set); | ||||
|     for (const key of Object.keys (import_set)) { | ||||
|       if (typeof this._keys[key] !== 'undefined') | ||||
|   public import_verification_data (data: KeyStoreExport): void { | ||||
|     for (const key of data) { | ||||
|       if (typeof this._keys[key.index] !== 'undefined') | ||||
|         throw new Error ('cannot import to the same instance'); | ||||
|       this._keys[key] = import_set[key]; | ||||
|       this._keys[key.index] = { | ||||
|         public_key: { | ||||
|           key:         key.key, | ||||
|           valid_until: key.valid_until | ||||
|         } | ||||
|       }; | ||||
|     } | ||||
|     this.garbage_collect (); | ||||
|   } | ||||
| @@ -140,4 +148,4 @@ class KeyStore { | ||||
|  | ||||
| const ks: KeyStore = (new KeyStore); | ||||
| export default ks; | ||||
| export { KeyStore, KeyStoreData, Key, KeyPair }; | ||||
| export { KeyStore, Key, LabelledKey, KeyStoreExport }; | ||||
|   | ||||
| @@ -28,7 +28,10 @@ import create_gateway, { | ||||
|   Gateway, | ||||
|   AnyFunc | ||||
| } from './Gateway'; | ||||
| import keystore, { KeyStore, KeyStoreData } from './KeyStore'; | ||||
| import keystore, { | ||||
|   KeyStore, KeyStoreExport, | ||||
|   LabelledKey, Key | ||||
| } from './KeyStore'; | ||||
|  | ||||
| export { | ||||
|   create_gateway, | ||||
| @@ -54,5 +57,7 @@ export { | ||||
|   Gateway, | ||||
|   AnyFunc, | ||||
|   KeyStore, | ||||
|   KeyStoreData | ||||
|   KeyStoreExport, | ||||
|   LabelledKey, | ||||
|   Key | ||||
| }; | ||||
|   | ||||
| @@ -155,17 +155,14 @@ describe ('key store', () => { | ||||
|     const exp = ks.export_verification_data (); | ||||
|     // eslint-disable-next-line dot-notation | ||||
|     expect (Object.keys (ks['_keys'])) | ||||
|       .toEqual (Object.keys (exp)); | ||||
|     expect (Object.keys (exp) | ||||
|       .filter ((v) => typeof exp[v].private_key !== 'undefined').length) | ||||
|       .toEqual (0); | ||||
|       .toEqual (exp.map ((v) => v.index)); | ||||
|  | ||||
|     const ks2 = (new KeyStore); | ||||
|     expect (ks2.instance_id).not.toEqual (ks.instance_id); | ||||
|     ks2.import_verification_data (exp); | ||||
|     // eslint-disable-next-line dot-notation | ||||
|     expect (ks2['_keys']) | ||||
|       .toEqual (exp); | ||||
|     expect (Object.keys (ks2['_keys'])) | ||||
|       .toEqual (exp.map ((v) => v.index)); | ||||
|  | ||||
|     const sign2 = await ks2.get_sign_key (iat, frame); | ||||
|     const ver2 = ks2.get_key (iat); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user