Skip to content

Commit

Permalink
Implement meta-format representation
Browse files Browse the repository at this point in the history
Signed-off-by: Knut Ahlers <knut@ahlers.me>
  • Loading branch information
Luzifer committed Oct 1, 2023
1 parent 37b84cf commit f26c7ff
Showing 1 changed file with 88 additions and 0 deletions.
88 changes: 88 additions & 0 deletions src/ots-meta.js
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

0 comments on commit f26c7ff

Please sign in to comment.