import { DomainError } from '../errors/domain.error'; export class EncryptedData { private readonly _ciphertext: string; private readonly _iv: string; private readonly _authTag: string; private readonly _keyId: string; private constructor( ciphertext: string, iv: string, authTag: string, keyId: string, ) { this._ciphertext = ciphertext; this._iv = iv; this._authTag = authTag; this._keyId = keyId; } static create(params: { ciphertext: string; iv: string; authTag: string; keyId: string; }): EncryptedData { if (!params.ciphertext || params.ciphertext.length === 0) { throw new DomainError('Ciphertext cannot be empty'); } if (!params.iv || params.iv.length === 0) { throw new DomainError('IV cannot be empty'); } if (!params.authTag || params.authTag.length === 0) { throw new DomainError('Auth tag cannot be empty'); } if (!params.keyId || params.keyId.length === 0) { throw new DomainError('Key ID cannot be empty'); } return new EncryptedData( params.ciphertext, params.iv, params.authTag, params.keyId, ); } static fromSerializedString(serialized: string, keyId: string): EncryptedData { const parts = serialized.split(':'); if (parts.length !== 3) { throw new DomainError('Invalid encrypted data format'); } return new EncryptedData(parts[0], parts[1], parts[2], keyId); } get ciphertext(): string { return this._ciphertext; } get iv(): string { return this._iv; } get authTag(): string { return this._authTag; } get keyId(): string { return this._keyId; } toSerializedString(): string { return `${this._ciphertext}:${this._iv}:${this._authTag}`; } }