Source: recipient.js

import Header from './header.js'
import Key from './key.js'
import algs from './algs/index.js'

/**
 * Recipient class
 * 
 * A Univrse Recipient is a structure wrapping a set of headers and an optional
 * content encryption key.
 */
class Recipient {
  /**
   * Instantiates a new Recipient instance with the given params.
   * 
   * Accepted params
   * 
   * * `headers` - headers object
   * * `key` - content encryption key
   * 
   * @param {Object} params
   * @constructor
   */
  constructor({ headers, key }) {
    this.header = Header.wrap(headers)
    this.key = key
  }

  /**
   * Instantiates a new Recipient instance with the given array of parts.
   * 
   * Used internally when decoding CBOR encoded recipients.
   * 
   * @param {Array} parts
   * @constructor
   */
  static fromArray(parts) {
    if (parts.length === 2 && typeof parts[0] === 'object' && typeof parts[0].alg === 'string') {
      return new this({ headers: parts[0], key: parts[1] })
    } else {
      return parts.map(p => this.fromArray(p))
    }
  }

  /**
   * Wraps the given key and headers in a new Recipient instance.
   * 
   * @param {Key|Buffer} key Key instance or encrypted key
   * @param {Object} headers
   * @constructor
   */
  static wrap(key, headers = {}) {
    return new this({ headers, key })
  }

  /**
   * Decrypts the key using the given encryption key.
   * 
   * An second argument of options can be given for the relevant encryption
   * algorithm.
   * 
   * @param {Key} key
   * @param {Object} opts
   * @returns {Recipient}
   */
  async decrypt(key, opts = {}) {
    const { alg } = this.header.headers

    const encOpts = {
      ...opts,
      ...['epk', 'iv', 'tag'].reduce((o, k) => { o[k] = this.header.headers[k]; return o }, {})
    }

    const encodedKey = await algs.decrypt(alg, this.key, key, encOpts)
    this.key = Key.decode(encodedKey)
    return this
  }

  /**
   * Returns the Recipient as an array of component parts.
   * 
   * Used internally prior to encoding the recipient.
   * 
   * @returns {Array}
   */
  toArray() {
    return [this.header.unwrap(), this.key]
  }
}

export default Recipient