-
-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement meta-format representation
Signed-off-by: Knut Ahlers <knut@ahlers.me>
- Loading branch information
Showing
1 changed file
with
88 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<string>} | ||
*/ | ||
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 |