import { FlattenedSign } from '../flattened/sign.js'; import { JWSInvalid } from '../../util/errors.js'; class IndividualSignature { constructor(sig, key, options) { this.parent = sig; this.key = key; this.options = options; } setProtectedHeader(protectedHeader) { if (this.protectedHeader) { throw new TypeError('setProtectedHeader can only be called once'); } this.protectedHeader = protectedHeader; return this; } setUnprotectedHeader(unprotectedHeader) { if (this.unprotectedHeader) { throw new TypeError('setUnprotectedHeader can only be called once'); } this.unprotectedHeader = unprotectedHeader; return this; } addSignature(...args) { return this.parent.addSignature(...args); } sign(...args) { return this.parent.sign(...args); } done() { return this.parent; } } export class GeneralSign { constructor(payload) { this._signatures = []; this._payload = payload; } addSignature(key, options) { const signature = new IndividualSignature(this, key, options); this._signatures.push(signature); return signature; } async sign() { if (!this._signatures.length) { throw new JWSInvalid('at least one signature must be added'); } const jws = { signatures: [], payload: '', }; for (let i = 0; i < this._signatures.length; i++) { const signature = this._signatures[i]; const flattened = new FlattenedSign(this._payload); flattened.setProtectedHeader(signature.protectedHeader); flattened.setUnprotectedHeader(signature.unprotectedHeader); const { payload, ...rest } = await flattened.sign(signature.key, signature.options); if (i === 0) { jws.payload = payload; } else if (jws.payload !== payload) { throw new JWSInvalid('inconsistent use of JWS Unencoded Payload Option (RFC7797)'); } jws.signatures.push(rest); } return jws; } }