From f26c7ff412a9447b312fbdac58a3f8f68c02be6a Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Sun, 1 Oct 2023 13:36:26 +0200 Subject: [PATCH] Implement meta-format representation Signed-off-by: Knut Ahlers --- src/ots-meta.js | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/ots-meta.js diff --git a/src/ots-meta.js b/src/ots-meta.js new file mode 100644 index 0000000..2ed0870 --- /dev/null +++ b/src/ots-meta.js @@ -0,0 +1,88 @@ +import appCrypto from './crypto' + +/** + * OTSMeta defines the structure of (de-)serializing stored payload for secrets + */ +class OTSMeta { + /** @type File[] */ + #files = [] + + /** @type String */ + #secret = '' + + /** @type Number */ + #version = 1.0 + + /** + * @param {String | null} jsonString JSON string representation of OTSMeta created by serialize + */ + constructor(jsonString = null) { + if (jsonString === null) { + return + } + + if (!jsonString.startsWith('OTSMeta')) { + // Looks like we got a plain string, we assume that to be a secret only + this.#secret = jsonString + return + } + + const data = JSON.parse(jsonString) + + this.#secret = data.secret + this.#version = data.v + + for (const f of data.attachments || []) { + const content = appCrypto.b64ToAb(f.data) + this.#files.push(new File([content], f.name)) + } + } + + get files() { + return this.#files + } + + get secret() { + return this.#secret + } + + set secret(secret) { + this.#secret = secret + } + + /** + * @returns {Promise} + */ + serialize() { + const output = { + secret: this.#secret, + v: this.#version, + } + + if (this.#files.length === 0) { + /* + * We got no attachments, therefore we do a simple fallback to + * the old "just the secret"-format + */ + return new Promise(resolve => { + resolve(this.#secret) + }) + } + + const encodes = [] + output.attachments = [] + + for (const f of this.#files) { + encodes.push(f.arrayBuffer() + .then(ab => { + const data = appCrypto.abToB64(ab) + output.attachments.push({ data, name: f.name }) + })) + } + + return Promise.all(encodes) + .then(() => `OTSMeta${JSON.stringify(output)}`) + } +} + +export default OTSMeta