@brightchain/brightchain-lib 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/brightchain-lib/BROWSER_COMPAT.md +54 -0
- package/package.json +15 -4
- package/src/browser.d.ts +1 -1
- package/src/browser.d.ts.map +1 -1
- package/src/browser.js +3 -3
- package/src/browser.js.map +1 -1
- package/src/lib/blocks/cblBase.d.ts +16 -1
- package/src/lib/blocks/cblBase.d.ts.map +1 -1
- package/src/lib/blocks/cblBase.js +33 -4
- package/src/lib/blocks/cblBase.js.map +1 -1
- package/src/lib/blocks/encryptedBlockFactory.d.ts +6 -1
- package/src/lib/blocks/encryptedBlockFactory.d.ts.map +1 -1
- package/src/lib/blocks/encryptedBlockFactory.js +14 -5
- package/src/lib/blocks/encryptedBlockFactory.js.map +1 -1
- package/src/lib/blocks/extendedCbl.d.ts.map +1 -1
- package/src/lib/blocks/extendedCbl.js +2 -1
- package/src/lib/blocks/extendedCbl.js.map +1 -1
- package/src/lib/blocks/handle.d.ts +5 -0
- package/src/lib/blocks/handle.d.ts.map +1 -1
- package/src/lib/blocks/handle.js.map +1 -1
- package/src/lib/blocks/handleTuple.d.ts +9 -1
- package/src/lib/blocks/handleTuple.d.ts.map +1 -1
- package/src/lib/blocks/handleTuple.js +23 -1
- package/src/lib/blocks/handleTuple.js.map +1 -1
- package/src/lib/blocks/index.d.ts +1 -0
- package/src/lib/blocks/index.d.ts.map +1 -1
- package/src/lib/blocks/index.js +1 -0
- package/src/lib/blocks/index.js.map +1 -1
- package/src/lib/blocks/memoryTuple.d.ts +9 -2
- package/src/lib/blocks/memoryTuple.d.ts.map +1 -1
- package/src/lib/blocks/memoryTuple.js +12 -3
- package/src/lib/blocks/memoryTuple.js.map +1 -1
- package/src/lib/blocks/vcbl.d.ts +27 -0
- package/src/lib/blocks/vcbl.d.ts.map +1 -0
- package/src/lib/blocks/vcbl.js +107 -0
- package/src/lib/blocks/vcbl.js.map +1 -0
- package/src/lib/constants.d.ts +5 -1
- package/src/lib/constants.d.ts.map +1 -1
- package/src/lib/constants.js +4 -0
- package/src/lib/constants.js.map +1 -1
- package/src/lib/crypto/index.d.ts +12 -0
- package/src/lib/crypto/index.d.ts.map +1 -0
- package/src/lib/crypto/index.js +23 -0
- package/src/lib/crypto/index.js.map +1 -0
- package/src/lib/crypto/platformCrypto.d.ts +132 -0
- package/src/lib/crypto/platformCrypto.d.ts.map +1 -0
- package/src/lib/crypto/platformCrypto.js +181 -0
- package/src/lib/crypto/platformCrypto.js.map +1 -0
- package/src/lib/enumeration-translations/blockType.d.ts.map +1 -1
- package/src/lib/enumeration-translations/blockType.js +16 -0
- package/src/lib/enumeration-translations/blockType.js.map +1 -1
- package/src/lib/enumerations/blockType.d.ts +12 -0
- package/src/lib/enumerations/blockType.d.ts.map +1 -1
- package/src/lib/enumerations/blockType.js +14 -0
- package/src/lib/enumerations/blockType.js.map +1 -1
- package/src/lib/enumerations/brightChainStrings.d.ts +5 -1
- package/src/lib/enumerations/brightChainStrings.d.ts.map +1 -1
- package/src/lib/enumerations/brightChainStrings.js +5 -1
- package/src/lib/enumerations/brightChainStrings.js.map +1 -1
- package/src/lib/enumerations/cblErrorType.d.ts +2 -1
- package/src/lib/enumerations/cblErrorType.d.ts.map +1 -1
- package/src/lib/enumerations/cblErrorType.js +1 -0
- package/src/lib/enumerations/cblErrorType.js.map +1 -1
- package/src/lib/enumerations/communication.d.ts +57 -0
- package/src/lib/enumerations/communication.d.ts.map +1 -0
- package/src/lib/enumerations/communication.js +89 -0
- package/src/lib/enumerations/communication.js.map +1 -0
- package/src/lib/enumerations/deviceType.d.ts +15 -0
- package/src/lib/enumerations/deviceType.d.ts.map +1 -0
- package/src/lib/enumerations/deviceType.js +19 -0
- package/src/lib/enumerations/deviceType.js.map +1 -0
- package/src/lib/enumerations/handleTupleErrorType.d.ts +2 -1
- package/src/lib/enumerations/handleTupleErrorType.d.ts.map +1 -1
- package/src/lib/enumerations/handleTupleErrorType.js +1 -0
- package/src/lib/enumerations/handleTupleErrorType.js.map +1 -1
- package/src/lib/enumerations/index.d.ts +6 -0
- package/src/lib/enumerations/index.d.ts.map +1 -1
- package/src/lib/enumerations/index.js +11 -0
- package/src/lib/enumerations/index.js.map +1 -1
- package/src/lib/enumerations/messaging/deliveryStatus.d.ts +50 -0
- package/src/lib/enumerations/messaging/deliveryStatus.d.ts.map +1 -0
- package/src/lib/enumerations/messaging/deliveryStatus.js +68 -0
- package/src/lib/enumerations/messaging/deliveryStatus.js.map +1 -0
- package/src/lib/enumerations/messaging/emailErrorType.d.ts +36 -0
- package/src/lib/enumerations/messaging/emailErrorType.d.ts.map +1 -0
- package/src/lib/enumerations/messaging/emailErrorType.js +46 -0
- package/src/lib/enumerations/messaging/emailErrorType.js.map +1 -0
- package/src/lib/enumerations/messaging/index.d.ts +2 -1
- package/src/lib/enumerations/messaging/index.d.ts.map +1 -1
- package/src/lib/enumerations/messaging/index.js +2 -1
- package/src/lib/enumerations/messaging/index.js.map +1 -1
- package/src/lib/enumerations/messaging/messageEncryptionScheme.d.ts +4 -2
- package/src/lib/enumerations/messaging/messageEncryptionScheme.d.ts.map +1 -1
- package/src/lib/enumerations/messaging/messageEncryptionScheme.js +3 -1
- package/src/lib/enumerations/messaging/messageEncryptionScheme.js.map +1 -1
- package/src/lib/enumerations/paperKeyPurpose.d.ts +15 -0
- package/src/lib/enumerations/paperKeyPurpose.d.ts.map +1 -0
- package/src/lib/enumerations/paperKeyPurpose.js +19 -0
- package/src/lib/enumerations/paperKeyPurpose.js.map +1 -0
- package/src/lib/enumerations/proofPlatform.d.ts +24 -0
- package/src/lib/enumerations/proofPlatform.d.ts.map +1 -0
- package/src/lib/enumerations/proofPlatform.js +28 -0
- package/src/lib/enumerations/proofPlatform.js.map +1 -0
- package/src/lib/enumerations/readConcern.d.ts +22 -0
- package/src/lib/enumerations/readConcern.d.ts.map +1 -0
- package/src/lib/enumerations/readConcern.js +26 -0
- package/src/lib/enumerations/readConcern.js.map +1 -0
- package/src/lib/enumerations/tupleErrorType.d.ts +2 -1
- package/src/lib/enumerations/tupleErrorType.d.ts.map +1 -1
- package/src/lib/enumerations/tupleErrorType.js +1 -0
- package/src/lib/enumerations/tupleErrorType.js.map +1 -1
- package/src/lib/enumerations/verificationStatus.d.ts +17 -0
- package/src/lib/enumerations/verificationStatus.d.ts.map +1 -0
- package/src/lib/enumerations/verificationStatus.js +21 -0
- package/src/lib/enumerations/verificationStatus.js.map +1 -0
- package/src/lib/errors/blockFetchError.d.ts +51 -0
- package/src/lib/errors/blockFetchError.d.ts.map +1 -0
- package/src/lib/errors/blockFetchError.js +63 -0
- package/src/lib/errors/blockFetchError.js.map +1 -0
- package/src/lib/errors/cblError.d.ts.map +1 -1
- package/src/lib/errors/cblError.js +1 -0
- package/src/lib/errors/cblError.js.map +1 -1
- package/src/lib/errors/handleTupleError.d.ts +10 -1
- package/src/lib/errors/handleTupleError.d.ts.map +1 -1
- package/src/lib/errors/handleTupleError.js +10 -1
- package/src/lib/errors/handleTupleError.js.map +1 -1
- package/src/lib/errors/index.d.ts +16 -0
- package/src/lib/errors/index.d.ts.map +1 -1
- package/src/lib/errors/index.js +22 -0
- package/src/lib/errors/index.js.map +1 -1
- package/src/lib/errors/messaging/emailError.d.ts +55 -0
- package/src/lib/errors/messaging/emailError.d.ts.map +1 -0
- package/src/lib/errors/messaging/emailError.js +64 -0
- package/src/lib/errors/messaging/emailError.js.map +1 -0
- package/src/lib/errors/messaging/index.d.ts +1 -0
- package/src/lib/errors/messaging/index.d.ts.map +1 -1
- package/src/lib/errors/messaging/index.js +1 -0
- package/src/lib/errors/messaging/index.js.map +1 -1
- package/src/lib/errors/poolDeletionError.d.ts +10 -0
- package/src/lib/errors/poolDeletionError.d.ts.map +1 -0
- package/src/lib/errors/poolDeletionError.js +16 -0
- package/src/lib/errors/poolDeletionError.js.map +1 -0
- package/src/lib/errors/poolDeletionTombstoneError.d.ts +12 -0
- package/src/lib/errors/poolDeletionTombstoneError.d.ts.map +1 -0
- package/src/lib/errors/poolDeletionTombstoneError.js +18 -0
- package/src/lib/errors/poolDeletionTombstoneError.js.map +1 -0
- package/src/lib/errors/tupleError.d.ts.map +1 -1
- package/src/lib/errors/tupleError.js +1 -0
- package/src/lib/errors/tupleError.js.map +1 -1
- package/src/lib/i18n/i18n-setup.d.ts +7 -2
- package/src/lib/i18n/i18n-setup.d.ts.map +1 -1
- package/src/lib/i18n/i18n-setup.js +84 -24
- package/src/lib/i18n/i18n-setup.js.map +1 -1
- package/src/lib/i18n/strings/englishUs.d.ts.map +1 -1
- package/src/lib/i18n/strings/englishUs.js +4 -0
- package/src/lib/i18n/strings/englishUs.js.map +1 -1
- package/src/lib/i18n/strings/french.d.ts.map +1 -1
- package/src/lib/i18n/strings/french.js +4 -0
- package/src/lib/i18n/strings/french.js.map +1 -1
- package/src/lib/i18n/strings/german.d.ts.map +1 -1
- package/src/lib/i18n/strings/german.js +4 -0
- package/src/lib/i18n/strings/german.js.map +1 -1
- package/src/lib/i18n/strings/japanese.d.ts.map +1 -1
- package/src/lib/i18n/strings/japanese.js +4 -0
- package/src/lib/i18n/strings/japanese.js.map +1 -1
- package/src/lib/i18n/strings/mandarin.d.ts.map +1 -1
- package/src/lib/i18n/strings/mandarin.js +4 -0
- package/src/lib/i18n/strings/mandarin.js.map +1 -1
- package/src/lib/i18n/strings/spanish.d.ts.map +1 -1
- package/src/lib/i18n/strings/spanish.js +4 -0
- package/src/lib/i18n/strings/spanish.js.map +1 -1
- package/src/lib/i18n/strings/ukrainian.d.ts.map +1 -1
- package/src/lib/i18n/strings/ukrainian.js +4 -0
- package/src/lib/i18n/strings/ukrainian.js.map +1 -1
- package/src/lib/index.d.ts +4 -0
- package/src/lib/index.d.ts.map +1 -1
- package/src/lib/index.js +4 -0
- package/src/lib/index.js.map +1 -1
- package/src/lib/interfaces/auth/index.d.ts +4 -0
- package/src/lib/interfaces/auth/index.d.ts.map +1 -0
- package/src/lib/interfaces/auth/index.js +8 -0
- package/src/lib/interfaces/auth/index.js.map +1 -0
- package/src/lib/interfaces/auth/nodeAuthenticator.d.ts +19 -0
- package/src/lib/interfaces/auth/nodeAuthenticator.d.ts.map +1 -0
- package/src/lib/interfaces/auth/nodeAuthenticator.js +3 -0
- package/src/lib/interfaces/auth/nodeAuthenticator.js.map +1 -0
- package/src/lib/interfaces/auth/poolAcl.d.ts +65 -0
- package/src/lib/interfaces/auth/poolAcl.d.ts.map +1 -0
- package/src/lib/interfaces/auth/poolAcl.js +52 -0
- package/src/lib/interfaces/auth/poolAcl.js.map +1 -0
- package/src/lib/interfaces/availability/availabilityService.d.ts +5 -3
- package/src/lib/interfaces/availability/availabilityService.d.ts.map +1 -1
- package/src/lib/interfaces/availability/availabilityService.js.map +1 -1
- package/src/lib/interfaces/availability/blockRegistry.d.ts +52 -3
- package/src/lib/interfaces/availability/blockRegistry.d.ts.map +1 -1
- package/src/lib/interfaces/availability/blockRegistry.js +1 -1
- package/src/lib/interfaces/availability/discoveryProtocol.d.ts +81 -3
- package/src/lib/interfaces/availability/discoveryProtocol.d.ts.map +1 -1
- package/src/lib/interfaces/availability/discoveryProtocol.js.map +1 -1
- package/src/lib/interfaces/availability/gossipService.d.ts +279 -8
- package/src/lib/interfaces/availability/gossipService.d.ts.map +1 -1
- package/src/lib/interfaces/availability/gossipService.js +232 -0
- package/src/lib/interfaces/availability/gossipService.js.map +1 -1
- package/src/lib/interfaces/availability/index.d.ts +1 -0
- package/src/lib/interfaces/availability/index.d.ts.map +1 -1
- package/src/lib/interfaces/availability/index.js +1 -0
- package/src/lib/interfaces/availability/index.js.map +1 -1
- package/src/lib/interfaces/availability/locationRecord.d.ts +6 -0
- package/src/lib/interfaces/availability/locationRecord.d.ts.map +1 -1
- package/src/lib/interfaces/availability/locationRecord.js +12 -0
- package/src/lib/interfaces/availability/locationRecord.js.map +1 -1
- package/src/lib/interfaces/availability/poolDeletionTombstone.d.ts +40 -0
- package/src/lib/interfaces/availability/poolDeletionTombstone.d.ts.map +1 -0
- package/src/lib/interfaces/availability/poolDeletionTombstone.js +19 -0
- package/src/lib/interfaces/availability/poolDeletionTombstone.js.map +1 -0
- package/src/lib/interfaces/availability/reconciliationService.d.ts +52 -0
- package/src/lib/interfaces/availability/reconciliationService.d.ts.map +1 -1
- package/src/lib/interfaces/availability/reconciliationService.js.map +1 -1
- package/src/lib/interfaces/blockCapacity.d.ts +9 -0
- package/src/lib/interfaces/blockCapacity.d.ts.map +1 -1
- package/src/lib/interfaces/blockEncryption.d.ts +4 -2
- package/src/lib/interfaces/blockEncryption.d.ts.map +1 -1
- package/src/lib/interfaces/blockFetch/blockFetchTransport.d.ts +26 -0
- package/src/lib/interfaces/blockFetch/blockFetchTransport.d.ts.map +1 -0
- package/src/lib/interfaces/blockFetch/blockFetchTransport.js +12 -0
- package/src/lib/interfaces/blockFetch/blockFetchTransport.js.map +1 -0
- package/src/lib/interfaces/blockFetch/blockFetcher.d.ts +71 -0
- package/src/lib/interfaces/blockFetch/blockFetcher.d.ts.map +1 -0
- package/src/lib/interfaces/blockFetch/blockFetcher.js +22 -0
- package/src/lib/interfaces/blockFetch/blockFetcher.js.map +1 -0
- package/src/lib/interfaces/blockFetch/enrichedQueryResult.d.ts +43 -0
- package/src/lib/interfaces/blockFetch/enrichedQueryResult.d.ts.map +1 -0
- package/src/lib/interfaces/blockFetch/enrichedQueryResult.js +13 -0
- package/src/lib/interfaces/blockFetch/enrichedQueryResult.js.map +1 -0
- package/src/lib/interfaces/blockFetch/fetchQueue.d.ts +70 -0
- package/src/lib/interfaces/blockFetch/fetchQueue.d.ts.map +1 -0
- package/src/lib/interfaces/blockFetch/fetchQueue.js +18 -0
- package/src/lib/interfaces/blockFetch/fetchQueue.js.map +1 -0
- package/src/lib/interfaces/blockFetch/index.d.ts +10 -0
- package/src/lib/interfaces/blockFetch/index.d.ts.map +1 -0
- package/src/lib/interfaces/blockFetch/index.js +13 -0
- package/src/lib/interfaces/blockFetch/index.js.map +1 -0
- package/src/lib/interfaces/blocks/index.d.ts +1 -0
- package/src/lib/interfaces/blocks/index.d.ts.map +1 -1
- package/src/lib/interfaces/blocks/vcbl.d.ts +16 -0
- package/src/lib/interfaces/blocks/vcbl.d.ts.map +1 -0
- package/src/lib/interfaces/{messaging/messageRouter.js → blocks/vcbl.js} +1 -1
- package/src/lib/interfaces/blocks/vcbl.js.map +1 -0
- package/src/lib/interfaces/brightpass/auditLog.d.ts +25 -0
- package/src/lib/interfaces/brightpass/auditLog.d.ts.map +1 -0
- package/src/lib/interfaces/brightpass/auditLog.js +21 -0
- package/src/lib/interfaces/brightpass/auditLog.js.map +1 -0
- package/src/lib/interfaces/brightpass/emergencyAccess.d.ts +11 -0
- package/src/lib/interfaces/brightpass/emergencyAccess.d.ts.map +1 -0
- package/src/lib/interfaces/{network/networkTransport.js → brightpass/emergencyAccess.js} +1 -1
- package/src/lib/interfaces/brightpass/emergencyAccess.js.map +1 -0
- package/src/lib/interfaces/brightpass/entryPropertyRecord.d.ts +11 -0
- package/src/lib/interfaces/brightpass/entryPropertyRecord.d.ts.map +1 -0
- package/src/lib/interfaces/brightpass/entryPropertyRecord.js +3 -0
- package/src/lib/interfaces/brightpass/entryPropertyRecord.js.map +1 -0
- package/src/lib/interfaces/brightpass/importTypes.d.ts +10 -0
- package/src/lib/interfaces/brightpass/importTypes.d.ts.map +1 -0
- package/src/lib/interfaces/brightpass/importTypes.js +3 -0
- package/src/lib/interfaces/brightpass/importTypes.js.map +1 -0
- package/src/lib/interfaces/brightpass/index.d.ts +7 -0
- package/src/lib/interfaces/brightpass/index.d.ts.map +1 -0
- package/src/lib/interfaces/brightpass/index.js +10 -0
- package/src/lib/interfaces/brightpass/index.js.map +1 -0
- package/src/lib/interfaces/brightpass/vaultEntry.d.ts +48 -0
- package/src/lib/interfaces/brightpass/vaultEntry.d.ts.map +1 -0
- package/src/lib/interfaces/brightpass/vaultEntry.js +3 -0
- package/src/lib/interfaces/brightpass/vaultEntry.js.map +1 -0
- package/src/lib/interfaces/brightpass/vaultMetadata.d.ts +34 -0
- package/src/lib/interfaces/brightpass/vaultMetadata.d.ts.map +1 -0
- package/src/lib/interfaces/brightpass/vaultMetadata.js +3 -0
- package/src/lib/interfaces/brightpass/vaultMetadata.js.map +1 -0
- package/src/lib/interfaces/clusterKeys.d.ts +4 -2
- package/src/lib/interfaces/clusterKeys.d.ts.map +1 -1
- package/src/lib/interfaces/communication.d.ts +173 -0
- package/src/lib/interfaces/communication.d.ts.map +1 -0
- package/src/lib/interfaces/communication.js +17 -0
- package/src/lib/interfaces/communication.js.map +1 -0
- package/src/lib/interfaces/communicationEvents.d.ts +168 -0
- package/src/lib/interfaces/communicationEvents.d.ts.map +1 -0
- package/src/lib/interfaces/communicationEvents.js +12 -0
- package/src/lib/interfaces/communicationEvents.js.map +1 -0
- package/src/lib/interfaces/crypto/ethereumWallet.d.ts +72 -0
- package/src/lib/interfaces/crypto/ethereumWallet.d.ts.map +1 -0
- package/src/lib/interfaces/crypto/ethereumWallet.js +12 -0
- package/src/lib/interfaces/crypto/ethereumWallet.js.map +1 -0
- package/src/lib/interfaces/crypto/gitSignature.d.ts +95 -0
- package/src/lib/interfaces/crypto/gitSignature.d.ts.map +1 -0
- package/src/lib/interfaces/crypto/gitSignature.js +12 -0
- package/src/lib/interfaces/crypto/gitSignature.js.map +1 -0
- package/src/lib/interfaces/crypto/index.d.ts +3 -0
- package/src/lib/interfaces/crypto/index.d.ts.map +1 -0
- package/src/lib/interfaces/crypto/index.js +3 -0
- package/src/lib/interfaces/crypto/index.js.map +1 -0
- package/src/lib/interfaces/dataKeyComponents.d.ts +7 -2
- package/src/lib/interfaces/dataKeyComponents.d.ts.map +1 -1
- package/src/lib/interfaces/encryptedBlockCreator.d.ts +4 -2
- package/src/lib/interfaces/encryptedBlockCreator.d.ts.map +1 -1
- package/src/lib/interfaces/events/communicationEventEmitter.d.ts +65 -0
- package/src/lib/interfaces/events/communicationEventEmitter.d.ts.map +1 -0
- package/src/lib/interfaces/events/communicationEventEmitter.js +60 -0
- package/src/lib/interfaces/events/communicationEventEmitter.js.map +1 -0
- package/src/lib/interfaces/events/index.d.ts +2 -0
- package/src/lib/interfaces/events/index.d.ts.map +1 -0
- package/src/lib/interfaces/events/index.js +5 -0
- package/src/lib/interfaces/events/index.js.map +1 -0
- package/src/lib/interfaces/failableResult.d.ts +15 -0
- package/src/lib/interfaces/failableResult.d.ts.map +1 -0
- package/src/lib/interfaces/failableResult.js +3 -0
- package/src/lib/interfaces/failableResult.js.map +1 -0
- package/src/lib/interfaces/identity/device.d.ts +59 -0
- package/src/lib/interfaces/identity/device.d.ts.map +1 -0
- package/src/lib/interfaces/identity/device.js +17 -0
- package/src/lib/interfaces/identity/device.js.map +1 -0
- package/src/lib/interfaces/identity/deviceKeyStorage.d.ts +71 -0
- package/src/lib/interfaces/identity/deviceKeyStorage.d.ts.map +1 -0
- package/src/lib/interfaces/identity/deviceKeyStorage.js +16 -0
- package/src/lib/interfaces/identity/deviceKeyStorage.js.map +1 -0
- package/src/lib/interfaces/identity/identityProof.d.ts +90 -0
- package/src/lib/interfaces/identity/identityProof.d.ts.map +1 -0
- package/src/lib/interfaces/identity/identityProof.js +18 -0
- package/src/lib/interfaces/identity/identityProof.js.map +1 -0
- package/src/lib/interfaces/identity/index.d.ts +7 -0
- package/src/lib/interfaces/identity/index.d.ts.map +1 -0
- package/src/lib/interfaces/identity/index.js +3 -0
- package/src/lib/interfaces/identity/index.js.map +1 -0
- package/src/lib/interfaces/identity/paperKey.d.ts +97 -0
- package/src/lib/interfaces/identity/paperKey.d.ts.map +1 -0
- package/src/lib/interfaces/identity/paperKey.js +17 -0
- package/src/lib/interfaces/identity/paperKey.js.map +1 -0
- package/src/lib/interfaces/identity/publicProfile.d.ts +74 -0
- package/src/lib/interfaces/identity/publicProfile.d.ts.map +1 -0
- package/src/lib/interfaces/identity/publicProfile.js +18 -0
- package/src/lib/interfaces/identity/publicProfile.js.map +1 -0
- package/src/lib/interfaces/identity/splitPaperKey.d.ts +73 -0
- package/src/lib/interfaces/identity/splitPaperKey.d.ts.map +1 -0
- package/src/lib/interfaces/identity/splitPaperKey.js +20 -0
- package/src/lib/interfaces/identity/splitPaperKey.js.map +1 -0
- package/src/lib/interfaces/index.d.ts +11 -2
- package/src/lib/interfaces/index.d.ts.map +1 -1
- package/src/lib/interfaces/index.js +12 -0
- package/src/lib/interfaces/index.js.map +1 -1
- package/src/lib/interfaces/messaging/attachmentMetadata.d.ts +47 -0
- package/src/lib/interfaces/messaging/attachmentMetadata.d.ts.map +1 -0
- package/src/lib/interfaces/messaging/attachmentMetadata.js +3 -0
- package/src/lib/interfaces/messaging/attachmentMetadata.js.map +1 -0
- package/src/lib/interfaces/messaging/emailAddress.d.ts +210 -0
- package/src/lib/interfaces/messaging/emailAddress.d.ts.map +1 -0
- package/src/lib/interfaces/messaging/emailAddress.js +213 -0
- package/src/lib/interfaces/messaging/emailAddress.js.map +1 -0
- package/src/lib/interfaces/messaging/emailDelivery.d.ts +80 -0
- package/src/lib/interfaces/messaging/emailDelivery.d.ts.map +1 -0
- package/src/lib/interfaces/messaging/emailDelivery.js +50 -0
- package/src/lib/interfaces/messaging/emailDelivery.js.map +1 -0
- package/src/lib/interfaces/messaging/emailMetadata.d.ts +269 -0
- package/src/lib/interfaces/messaging/emailMetadata.d.ts.map +1 -0
- package/src/lib/interfaces/messaging/emailMetadata.js +16 -0
- package/src/lib/interfaces/messaging/emailMetadata.js.map +1 -0
- package/src/lib/interfaces/messaging/index.d.ts +5 -1
- package/src/lib/interfaces/messaging/index.d.ts.map +1 -1
- package/src/lib/interfaces/messaging/index.js +5 -1
- package/src/lib/interfaces/messaging/index.js.map +1 -1
- package/src/lib/interfaces/messaging/messageMetadata.d.ts +2 -2
- package/src/lib/interfaces/messaging/messageMetadata.d.ts.map +1 -1
- package/src/lib/interfaces/messaging/messageMetadataStore.d.ts +2 -2
- package/src/lib/interfaces/messaging/messageMetadataStore.d.ts.map +1 -1
- package/src/lib/interfaces/messaging/mimePart.d.ts +214 -0
- package/src/lib/interfaces/messaging/mimePart.d.ts.map +1 -0
- package/src/lib/interfaces/messaging/mimePart.js +71 -0
- package/src/lib/interfaces/messaging/mimePart.js.map +1 -0
- package/src/lib/interfaces/network/index.d.ts +0 -1
- package/src/lib/interfaces/network/index.d.ts.map +1 -1
- package/src/lib/interfaces/network/node.d.ts +4 -2
- package/src/lib/interfaces/network/node.d.ts.map +1 -1
- package/src/lib/interfaces/network/nodeAdvertisement.d.ts +4 -2
- package/src/lib/interfaces/network/nodeAdvertisement.d.ts.map +1 -1
- package/src/lib/interfaces/privateVotingDerivation.d.ts +7 -2
- package/src/lib/interfaces/privateVotingDerivation.d.ts.map +1 -1
- package/src/lib/interfaces/requests/communicationRequests.d.ts +154 -0
- package/src/lib/interfaces/requests/communicationRequests.d.ts.map +1 -0
- package/src/lib/interfaces/requests/communicationRequests.js +10 -0
- package/src/lib/interfaces/requests/communicationRequests.js.map +1 -0
- package/src/lib/interfaces/requests/index.d.ts +2 -0
- package/src/lib/interfaces/requests/index.d.ts.map +1 -0
- package/src/lib/interfaces/requests/index.js +3 -0
- package/src/lib/interfaces/requests/index.js.map +1 -0
- package/src/lib/interfaces/responses/blockDataResponse.d.ts +11 -0
- package/src/lib/interfaces/responses/blockDataResponse.d.ts.map +1 -0
- package/src/lib/interfaces/responses/blockDataResponse.js +3 -0
- package/src/lib/interfaces/responses/blockDataResponse.js.map +1 -0
- package/src/lib/interfaces/responses/communicationResponses.d.ts +82 -0
- package/src/lib/interfaces/responses/communicationResponses.d.ts.map +1 -0
- package/src/lib/interfaces/responses/communicationResponses.js +17 -0
- package/src/lib/interfaces/responses/communicationResponses.js.map +1 -0
- package/src/lib/interfaces/responses/cryptoResponses.d.ts +30 -0
- package/src/lib/interfaces/responses/cryptoResponses.d.ts.map +1 -0
- package/src/lib/interfaces/responses/cryptoResponses.js +12 -0
- package/src/lib/interfaces/responses/cryptoResponses.js.map +1 -0
- package/src/lib/interfaces/responses/deviceResponses.d.ts +26 -0
- package/src/lib/interfaces/responses/deviceResponses.d.ts.map +1 -0
- package/src/lib/interfaces/responses/deviceResponses.js +15 -0
- package/src/lib/interfaces/responses/deviceResponses.js.map +1 -0
- package/src/lib/interfaces/responses/directoryResponses.d.ts +26 -0
- package/src/lib/interfaces/responses/directoryResponses.d.ts.map +1 -0
- package/src/lib/interfaces/responses/directoryResponses.js +12 -0
- package/src/lib/interfaces/responses/directoryResponses.js.map +1 -0
- package/src/lib/interfaces/responses/emailResponses.d.ts +40 -0
- package/src/lib/interfaces/responses/emailResponses.d.ts.map +1 -0
- package/src/lib/interfaces/responses/emailResponses.js +18 -0
- package/src/lib/interfaces/responses/emailResponses.js.map +1 -0
- package/src/lib/interfaces/responses/explodingMessageResponses.d.ts +42 -0
- package/src/lib/interfaces/responses/explodingMessageResponses.d.ts.map +1 -0
- package/src/lib/interfaces/responses/explodingMessageResponses.js +11 -0
- package/src/lib/interfaces/responses/explodingMessageResponses.js.map +1 -0
- package/src/lib/interfaces/responses/identityProofResponses.d.ts +33 -0
- package/src/lib/interfaces/responses/identityProofResponses.d.ts.map +1 -0
- package/src/lib/interfaces/responses/identityProofResponses.js +12 -0
- package/src/lib/interfaces/responses/identityProofResponses.js.map +1 -0
- package/src/lib/interfaces/responses/index.d.ts +3 -1
- package/src/lib/interfaces/responses/index.d.ts.map +1 -1
- package/src/lib/interfaces/sealResults.d.ts +7 -2
- package/src/lib/interfaces/sealResults.d.ts.map +1 -1
- package/src/lib/interfaces/services/fecService.d.ts +7 -5
- package/src/lib/interfaces/services/fecService.d.ts.map +1 -1
- package/src/lib/interfaces/services/fecService.js +2 -0
- package/src/lib/interfaces/services/fecService.js.map +1 -1
- package/src/lib/interfaces/singleEncryptedBlockDetails.d.ts +7 -2
- package/src/lib/interfaces/singleEncryptedBlockDetails.d.ts.map +1 -1
- package/src/lib/interfaces/storage/blockMetadata.d.ts +8 -1
- package/src/lib/interfaces/storage/blockMetadata.d.ts.map +1 -1
- package/src/lib/interfaces/storage/blockMetadata.js +3 -1
- package/src/lib/interfaces/storage/blockMetadata.js.map +1 -1
- package/src/lib/interfaces/storage/cblIndex.d.ts +141 -0
- package/src/lib/interfaces/storage/cblIndex.d.ts.map +1 -0
- package/src/lib/interfaces/storage/cblIndex.js +28 -0
- package/src/lib/interfaces/storage/cblIndex.js.map +1 -0
- package/src/lib/interfaces/storage/clientSession.d.ts +22 -0
- package/src/lib/interfaces/storage/clientSession.d.ts.map +1 -0
- package/src/lib/interfaces/storage/clientSession.js +3 -0
- package/src/lib/interfaces/storage/clientSession.js.map +1 -0
- package/src/lib/interfaces/storage/collection.d.ts +80 -0
- package/src/lib/interfaces/storage/collection.d.ts.map +1 -0
- package/src/lib/interfaces/storage/collection.js +3 -0
- package/src/lib/interfaces/storage/collection.js.map +1 -0
- package/src/lib/interfaces/storage/database.d.ts +30 -0
- package/src/lib/interfaces/storage/database.d.ts.map +1 -0
- package/src/lib/interfaces/storage/database.js +3 -0
- package/src/lib/interfaces/storage/database.js.map +1 -0
- package/src/lib/interfaces/storage/databaseLifecycleHooks.d.ts +43 -0
- package/src/lib/interfaces/storage/databaseLifecycleHooks.d.ts.map +1 -0
- package/src/lib/interfaces/storage/databaseLifecycleHooks.js +3 -0
- package/src/lib/interfaces/storage/databaseLifecycleHooks.js.map +1 -0
- package/src/lib/interfaces/storage/documentTypes.d.ts +413 -0
- package/src/lib/interfaces/storage/documentTypes.d.ts.map +1 -0
- package/src/lib/interfaces/storage/documentTypes.js +8 -0
- package/src/lib/interfaces/storage/documentTypes.js.map +1 -0
- package/src/lib/interfaces/storage/encryptedPool.d.ts +64 -0
- package/src/lib/interfaces/storage/encryptedPool.d.ts.map +1 -0
- package/src/lib/interfaces/storage/encryptedPool.js +26 -0
- package/src/lib/interfaces/storage/encryptedPool.js.map +1 -0
- package/src/lib/interfaces/storage/headRegistry.d.ts +128 -0
- package/src/lib/interfaces/storage/headRegistry.d.ts.map +1 -0
- package/src/lib/interfaces/storage/headRegistry.js +3 -0
- package/src/lib/interfaces/storage/headRegistry.js.map +1 -0
- package/src/lib/interfaces/storage/index.d.ts +14 -0
- package/src/lib/interfaces/storage/index.d.ts.map +1 -1
- package/src/lib/interfaces/storage/index.js +14 -1
- package/src/lib/interfaces/storage/index.js.map +1 -1
- package/src/lib/interfaces/storage/pooledBlockStore.d.ts +163 -0
- package/src/lib/interfaces/storage/pooledBlockStore.d.ts.map +1 -0
- package/src/lib/interfaces/storage/pooledBlockStore.js +77 -0
- package/src/lib/interfaces/storage/pooledBlockStore.js.map +1 -0
- package/src/lib/interfaces/storage/readConcernBlockStore.d.ts +47 -0
- package/src/lib/interfaces/storage/readConcernBlockStore.d.ts.map +1 -0
- package/src/lib/interfaces/storage/readConcernBlockStore.js +29 -0
- package/src/lib/interfaces/storage/readConcernBlockStore.js.map +1 -0
- package/src/lib/interfaces/symmetricEncryptionResults.d.ts +7 -5
- package/src/lib/interfaces/symmetricEncryptionResults.d.ts.map +1 -1
- package/src/lib/schemas/messaging/messageMetadataSchema.d.ts.map +1 -1
- package/src/lib/schemas/messaging/messageMetadataSchema.js.map +1 -1
- package/src/lib/services/blockCapacity.service.d.ts.map +1 -1
- package/src/lib/services/blockCapacity.service.js +15 -0
- package/src/lib/services/blockCapacity.service.js.map +1 -1
- package/src/lib/services/brightpass/auditLogger.d.ts +41 -0
- package/src/lib/services/brightpass/auditLogger.d.ts.map +1 -0
- package/src/lib/services/brightpass/auditLogger.js +47 -0
- package/src/lib/services/brightpass/auditLogger.js.map +1 -0
- package/src/lib/services/brightpass/breachDetector.d.ts +68 -0
- package/src/lib/services/brightpass/breachDetector.d.ts.map +1 -0
- package/src/lib/services/brightpass/breachDetector.js +102 -0
- package/src/lib/services/brightpass/breachDetector.js.map +1 -0
- package/src/lib/services/brightpass/importParser.d.ts +105 -0
- package/src/lib/services/brightpass/importParser.d.ts.map +1 -0
- package/src/lib/services/brightpass/importParser.js +380 -0
- package/src/lib/services/brightpass/importParser.js.map +1 -0
- package/src/lib/services/brightpass/index.d.ts +16 -0
- package/src/lib/services/brightpass/index.d.ts.map +1 -0
- package/src/lib/services/brightpass/index.js +19 -0
- package/src/lib/services/brightpass/index.js.map +1 -0
- package/src/lib/services/brightpass/passwordGenerator.d.ts +111 -0
- package/src/lib/services/brightpass/passwordGenerator.d.ts.map +1 -0
- package/src/lib/services/brightpass/passwordGenerator.js +162 -0
- package/src/lib/services/brightpass/passwordGenerator.js.map +1 -0
- package/src/lib/services/brightpass/totpEngine.d.ts +191 -0
- package/src/lib/services/brightpass/totpEngine.d.ts.map +1 -0
- package/src/lib/services/brightpass/totpEngine.js +198 -0
- package/src/lib/services/brightpass/totpEngine.js.map +1 -0
- package/src/lib/services/brightpass/vaultKeyDerivation.d.ts +26 -0
- package/src/lib/services/brightpass/vaultKeyDerivation.d.ts.map +1 -0
- package/src/lib/services/brightpass/vaultKeyDerivation.js +42 -0
- package/src/lib/services/brightpass/vaultKeyDerivation.js.map +1 -0
- package/src/lib/services/brightpass/vaultSerializer.d.ts +14 -0
- package/src/lib/services/brightpass/vaultSerializer.d.ts.map +1 -0
- package/src/lib/services/brightpass/vaultSerializer.js +77 -0
- package/src/lib/services/brightpass/vaultSerializer.js.map +1 -0
- package/src/lib/services/cblService.d.ts +4 -2
- package/src/lib/services/cblService.d.ts.map +1 -1
- package/src/lib/services/cblService.js +8 -4
- package/src/lib/services/cblService.js.map +1 -1
- package/src/lib/services/communication/channelService.d.ts +208 -0
- package/src/lib/services/communication/channelService.d.ts.map +1 -0
- package/src/lib/services/communication/channelService.js +575 -0
- package/src/lib/services/communication/channelService.js.map +1 -0
- package/src/lib/services/communication/conversationService.d.ts +130 -0
- package/src/lib/services/communication/conversationService.d.ts.map +1 -0
- package/src/lib/services/communication/conversationService.js +279 -0
- package/src/lib/services/communication/conversationService.js.map +1 -0
- package/src/lib/services/communication/explodingMessageService.d.ts +168 -0
- package/src/lib/services/communication/explodingMessageService.d.ts.map +1 -0
- package/src/lib/services/communication/explodingMessageService.js +287 -0
- package/src/lib/services/communication/explodingMessageService.js.map +1 -0
- package/src/lib/services/communication/groupService.d.ts +165 -0
- package/src/lib/services/communication/groupService.d.ts.map +1 -0
- package/src/lib/services/communication/groupService.js +437 -0
- package/src/lib/services/communication/groupService.js.map +1 -0
- package/src/lib/services/communication/index.d.ts +16 -0
- package/src/lib/services/communication/index.d.ts.map +1 -0
- package/src/lib/services/communication/index.js +63 -0
- package/src/lib/services/communication/index.js.map +1 -0
- package/src/lib/services/communication/messageOperationsService.d.ts +81 -0
- package/src/lib/services/communication/messageOperationsService.d.ts.map +1 -0
- package/src/lib/services/communication/messageOperationsService.js +162 -0
- package/src/lib/services/communication/messageOperationsService.js.map +1 -0
- package/src/lib/services/communication/permissionService.d.ts +47 -0
- package/src/lib/services/communication/permissionService.d.ts.map +1 -0
- package/src/lib/services/communication/permissionService.js +82 -0
- package/src/lib/services/communication/permissionService.js.map +1 -0
- package/src/lib/services/communication/searchService.d.ts +30 -0
- package/src/lib/services/communication/searchService.d.ts.map +1 -0
- package/src/lib/services/communication/searchService.js +83 -0
- package/src/lib/services/communication/searchService.js.map +1 -0
- package/src/lib/services/crypto/ethereumWalletService.d.ts +159 -0
- package/src/lib/services/crypto/ethereumWalletService.d.ts.map +1 -0
- package/src/lib/services/crypto/ethereumWalletService.js +345 -0
- package/src/lib/services/crypto/ethereumWalletService.js.map +1 -0
- package/src/lib/services/crypto/gitSigningService.d.ts +145 -0
- package/src/lib/services/crypto/gitSigningService.d.ts.map +1 -0
- package/src/lib/services/crypto/gitSigningService.js +291 -0
- package/src/lib/services/crypto/gitSigningService.js.map +1 -0
- package/src/lib/services/crypto/index.d.ts +3 -0
- package/src/lib/services/crypto/index.d.ts.map +1 -0
- package/src/lib/services/crypto/index.js +6 -0
- package/src/lib/services/crypto/index.js.map +1 -0
- package/src/lib/services/identity/deviceProvisioningService.d.ts +146 -0
- package/src/lib/services/identity/deviceProvisioningService.d.ts.map +1 -0
- package/src/lib/services/identity/deviceProvisioningService.js +219 -0
- package/src/lib/services/identity/deviceProvisioningService.js.map +1 -0
- package/src/lib/services/identity/identityProofService.d.ts +139 -0
- package/src/lib/services/identity/identityProofService.d.ts.map +1 -0
- package/src/lib/services/identity/identityProofService.js +245 -0
- package/src/lib/services/identity/identityProofService.js.map +1 -0
- package/src/lib/services/identity/index.d.ts +14 -0
- package/src/lib/services/identity/index.d.ts.map +1 -0
- package/src/lib/services/identity/index.js +17 -0
- package/src/lib/services/identity/index.js.map +1 -0
- package/src/lib/services/identity/memberIdentityProofService.d.ts +179 -0
- package/src/lib/services/identity/memberIdentityProofService.d.ts.map +1 -0
- package/src/lib/services/identity/memberIdentityProofService.js +232 -0
- package/src/lib/services/identity/memberIdentityProofService.js.map +1 -0
- package/src/lib/services/identity/memberPaperKeyService.d.ts +223 -0
- package/src/lib/services/identity/memberPaperKeyService.d.ts.map +1 -0
- package/src/lib/services/identity/memberPaperKeyService.js +279 -0
- package/src/lib/services/identity/memberPaperKeyService.js.map +1 -0
- package/src/lib/services/identity/paperKeyService.d.ts +106 -0
- package/src/lib/services/identity/paperKeyService.d.ts.map +1 -0
- package/src/lib/services/identity/paperKeyService.js +161 -0
- package/src/lib/services/identity/paperKeyService.js.map +1 -0
- package/src/lib/services/identity/publicKeyDirectoryService.d.ts +210 -0
- package/src/lib/services/identity/publicKeyDirectoryService.d.ts.map +1 -0
- package/src/lib/services/identity/publicKeyDirectoryService.js +328 -0
- package/src/lib/services/identity/publicKeyDirectoryService.js.map +1 -0
- package/src/lib/services/identity/splitPaperKeyService.d.ts +92 -0
- package/src/lib/services/identity/splitPaperKeyService.d.ts.map +1 -0
- package/src/lib/services/identity/splitPaperKeyService.js +305 -0
- package/src/lib/services/identity/splitPaperKeyService.js.map +1 -0
- package/src/lib/services/index.d.ts +4 -0
- package/src/lib/services/index.d.ts.map +1 -1
- package/src/lib/services/index.js +7 -0
- package/src/lib/services/index.js.map +1 -1
- package/src/lib/services/messaging/deliveryTimeoutService.js +2 -2
- package/src/lib/services/messaging/deliveryTimeoutService.js.map +1 -1
- package/src/lib/services/messaging/emailEncryptionService.d.ts +250 -0
- package/src/lib/services/messaging/emailEncryptionService.d.ts.map +1 -0
- package/src/lib/services/messaging/emailEncryptionService.js +420 -0
- package/src/lib/services/messaging/emailEncryptionService.js.map +1 -0
- package/src/lib/services/messaging/emailMessageService.d.ts +669 -0
- package/src/lib/services/messaging/emailMessageService.d.ts.map +1 -0
- package/src/lib/services/messaging/emailMessageService.js +1030 -0
- package/src/lib/services/messaging/emailMessageService.js.map +1 -0
- package/src/lib/services/messaging/emailParser.d.ts +476 -0
- package/src/lib/services/messaging/emailParser.d.ts.map +1 -0
- package/src/lib/services/messaging/emailParser.js +1316 -0
- package/src/lib/services/messaging/emailParser.js.map +1 -0
- package/src/lib/services/messaging/emailSerializer.d.ts +403 -0
- package/src/lib/services/messaging/emailSerializer.d.ts.map +1 -0
- package/src/lib/services/messaging/emailSerializer.js +852 -0
- package/src/lib/services/messaging/emailSerializer.js.map +1 -0
- package/src/lib/services/messaging/emailValidator.d.ts +448 -0
- package/src/lib/services/messaging/emailValidator.d.ts.map +1 -0
- package/src/lib/services/messaging/emailValidator.js +810 -0
- package/src/lib/services/messaging/emailValidator.js.map +1 -0
- package/src/lib/services/messaging/gossipRetryService.d.ts +204 -0
- package/src/lib/services/messaging/gossipRetryService.d.ts.map +1 -0
- package/src/lib/services/messaging/gossipRetryService.js +319 -0
- package/src/lib/services/messaging/gossipRetryService.js.map +1 -0
- package/src/lib/services/messaging/inMemoryEmailMetadataStore.d.ts +60 -0
- package/src/lib/services/messaging/inMemoryEmailMetadataStore.d.ts.map +1 -0
- package/src/lib/services/messaging/inMemoryEmailMetadataStore.js +281 -0
- package/src/lib/services/messaging/inMemoryEmailMetadataStore.js.map +1 -0
- package/src/lib/services/messaging/index.d.ts +11 -5
- package/src/lib/services/messaging/index.d.ts.map +1 -1
- package/src/lib/services/messaging/index.js +19 -5
- package/src/lib/services/messaging/index.js.map +1 -1
- package/src/lib/services/messaging/messageCBLService.js +2 -2
- package/src/lib/services/messaging/messageCBLService.js.map +1 -1
- package/src/lib/services/tuple.service.d.ts +27 -2
- package/src/lib/services/tuple.service.d.ts.map +1 -1
- package/src/lib/services/tuple.service.js +62 -20
- package/src/lib/services/tuple.service.js.map +1 -1
- package/src/lib/services/vcblService.d.ts +36 -0
- package/src/lib/services/vcblService.d.ts.map +1 -0
- package/src/lib/services/vcblService.js +326 -0
- package/src/lib/services/vcblService.js.map +1 -0
- package/src/lib/stores/index.d.ts +1 -0
- package/src/lib/stores/index.d.ts.map +1 -1
- package/src/lib/stores/index.js +1 -0
- package/src/lib/stores/index.js.map +1 -1
- package/src/lib/stores/messaging/memoryMessageMetadataStore.d.ts +2 -2
- package/src/lib/stores/messaging/memoryMessageMetadataStore.d.ts.map +1 -1
- package/src/lib/stores/messaging/memoryMessageMetadataStore.js +2 -2
- package/src/lib/stores/messaging/memoryMessageMetadataStore.js.map +1 -1
- package/src/lib/stores/pooledMemoryBlockStore.d.ts +134 -0
- package/src/lib/stores/pooledMemoryBlockStore.d.ts.map +1 -0
- package/src/lib/stores/pooledMemoryBlockStore.js +583 -0
- package/src/lib/stores/pooledMemoryBlockStore.js.map +1 -0
- package/src/lib/types/checksum.d.ts +11 -0
- package/src/lib/types/checksum.d.ts.map +1 -1
- package/src/lib/types/checksum.js +11 -0
- package/src/lib/types/checksum.js.map +1 -1
- package/src/lib/utils/index.d.ts +9 -0
- package/src/lib/utils/index.d.ts.map +1 -1
- package/src/lib/utils/index.js +12 -0
- package/src/lib/utils/index.js.map +1 -1
- package/src/lib/utils/pagination.d.ts +27 -0
- package/src/lib/utils/pagination.d.ts.map +1 -0
- package/src/lib/utils/pagination.js +38 -0
- package/src/lib/utils/pagination.js.map +1 -0
- package/src/lib/enumerations/messaging/messageDeliveryStatus.d.ts +0 -18
- package/src/lib/enumerations/messaging/messageDeliveryStatus.d.ts.map +0 -1
- package/src/lib/enumerations/messaging/messageDeliveryStatus.js +0 -22
- package/src/lib/enumerations/messaging/messageDeliveryStatus.js.map +0 -1
- package/src/lib/enumerations/messaging/routingStrategy.d.ts +0 -12
- package/src/lib/enumerations/messaging/routingStrategy.d.ts.map +0 -1
- package/src/lib/enumerations/messaging/routingStrategy.js +0 -16
- package/src/lib/enumerations/messaging/routingStrategy.js.map +0 -1
- package/src/lib/interfaces/messaging/messageRouter.d.ts +0 -48
- package/src/lib/interfaces/messaging/messageRouter.d.ts.map +0 -1
- package/src/lib/interfaces/messaging/messageRouter.js.map +0 -1
- package/src/lib/interfaces/network/networkTransport.d.ts +0 -19
- package/src/lib/interfaces/network/networkTransport.d.ts.map +0 -1
- package/src/lib/interfaces/network/networkTransport.js.map +0 -1
- package/src/lib/services/messaging/broadcastMessageRouter.d.ts +0 -18
- package/src/lib/services/messaging/broadcastMessageRouter.d.ts.map +0 -1
- package/src/lib/services/messaging/broadcastMessageRouter.js +0 -32
- package/src/lib/services/messaging/broadcastMessageRouter.js.map +0 -1
- package/src/lib/services/messaging/directMessageRouter.d.ts +0 -25
- package/src/lib/services/messaging/directMessageRouter.d.ts.map +0 -1
- package/src/lib/services/messaging/directMessageRouter.js +0 -58
- package/src/lib/services/messaging/directMessageRouter.js.map +0 -1
- package/src/lib/services/messaging/messageForwardingService.d.ts +0 -40
- package/src/lib/services/messaging/messageForwardingService.d.ts.map +0 -1
- package/src/lib/services/messaging/messageForwardingService.js +0 -74
- package/src/lib/services/messaging/messageForwardingService.js.map +0 -1
- package/src/lib/services/messaging/messageRouter.d.ts +0 -24
- package/src/lib/services/messaging/messageRouter.d.ts.map +0 -1
- package/src/lib/services/messaging/messageRouter.js +0 -111
- package/src/lib/services/messaging/messageRouter.js.map +0 -1
- package/src/lib/services/messaging/webSocketTransport.d.ts +0 -34
- package/src/lib/services/messaging/webSocketTransport.d.ts.map +0 -1
- package/src/lib/services/messaging/webSocketTransport.js +0 -115
- package/src/lib/services/messaging/webSocketTransport.js.map +0 -1
|
@@ -0,0 +1,1316 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RFC 5322/MIME Compliant Email Parser
|
|
4
|
+
*
|
|
5
|
+
* Parses raw email strings and provides methods for parsing individual
|
|
6
|
+
* email components (headers, addresses, Message-IDs, dates, content types).
|
|
7
|
+
*
|
|
8
|
+
* Wraps the `postal-mime` library for full email parsing and the
|
|
9
|
+
* `email-addresses` library for RFC 5322 address grammar parsing.
|
|
10
|
+
*
|
|
11
|
+
* **Platform-specific code (Node.js `Buffer`):**
|
|
12
|
+
* This file uses `Buffer.from()` in `decodeEncodedWord()`, `decodeQuotedPrintable()`,
|
|
13
|
+
* and `decodeBase64()` for base64 decoding, quoted-printable decoding, and charset
|
|
14
|
+
* conversion (e.g. ISO-8859-1 → UTF-8). These usages cannot easily be replaced with
|
|
15
|
+
* pure `Uint8Array` operations because:
|
|
16
|
+
* - `Buffer.from(str, 'base64')` and `Buffer.from(str, 'latin1')` provide charset-aware
|
|
17
|
+
* decoding that has no single-call equivalent in the Web Crypto API or `TextDecoder`
|
|
18
|
+
* for all supported charsets.
|
|
19
|
+
* - The `postal-mime` library (used in `parse()`) already handles browser-compatible
|
|
20
|
+
* parsing, so the Buffer-dependent methods are primarily used for the manual
|
|
21
|
+
* header/body decoding path.
|
|
22
|
+
*
|
|
23
|
+
* If browser compatibility is needed for this parser, consider replacing the Buffer
|
|
24
|
+
* calls with `TextDecoder` (for charset conversion) and `atob()` (for base64), or
|
|
25
|
+
* moving this file to `brightchain-api-lib`.
|
|
26
|
+
*
|
|
27
|
+
* @platform Node.js — uses `Buffer` for base64/quoted-printable decoding and charset handling
|
|
28
|
+
* @see RFC 5322 - Internet Message Format
|
|
29
|
+
* @see RFC 2045 - MIME Part One: Format of Internet Message Bodies
|
|
30
|
+
* @see RFC 2046 - MIME Part Two: Media Types
|
|
31
|
+
* @see Requirement 18.4 — platform-specific code documented
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* Requirements: 2.1, 2.2, 2.3, 2.4, 3.4, 3.5, 3.6, 14.4
|
|
35
|
+
*/
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.EmailParser = void 0;
|
|
38
|
+
const emailAddresses = require("email-addresses");
|
|
39
|
+
const postal_mime_1 = require("postal-mime");
|
|
40
|
+
const durabilityLevel_1 = require("../../enumerations/durabilityLevel");
|
|
41
|
+
const emailErrorType_1 = require("../../enumerations/messaging/emailErrorType");
|
|
42
|
+
const messageEncryptionScheme_1 = require("../../enumerations/messaging/messageEncryptionScheme");
|
|
43
|
+
const messagePriority_1 = require("../../enumerations/messaging/messagePriority");
|
|
44
|
+
const replicationStatus_1 = require("../../enumerations/replicationStatus");
|
|
45
|
+
const emailError_1 = require("../../errors/messaging/emailError");
|
|
46
|
+
const emailAddress_1 = require("../../interfaces/messaging/emailAddress");
|
|
47
|
+
const mimePart_1 = require("../../interfaces/messaging/mimePart");
|
|
48
|
+
/**
|
|
49
|
+
* RFC 5322/MIME compliant email parser.
|
|
50
|
+
*
|
|
51
|
+
* Provides methods for parsing email headers, addresses, Message-IDs,
|
|
52
|
+
* dates, and content types. The main `parse()` method (Task 4.6) will
|
|
53
|
+
* use `postal-mime` for full email parsing.
|
|
54
|
+
*
|
|
55
|
+
* @see Design Document: EmailParser Class
|
|
56
|
+
*/
|
|
57
|
+
class EmailParser {
|
|
58
|
+
/**
|
|
59
|
+
* Unfolds multi-line headers by removing CRLF followed by whitespace.
|
|
60
|
+
*
|
|
61
|
+
* Per RFC 5322 Section 2.2.3, long header fields can be split across
|
|
62
|
+
* multiple lines by inserting a CRLF before any whitespace. Unfolding
|
|
63
|
+
* reverses this by removing the CRLF (or LF) that precedes whitespace.
|
|
64
|
+
*
|
|
65
|
+
* Also handles LF followed by whitespace for robustness (Requirement 14.5).
|
|
66
|
+
*
|
|
67
|
+
* @param rawHeaders - The raw header string potentially containing folded lines
|
|
68
|
+
* @returns The unfolded header string
|
|
69
|
+
*
|
|
70
|
+
* @see RFC 5322 Section 2.2.3 - Long Header Fields
|
|
71
|
+
* @see Requirement 14.4 - Unfold multi-line headers
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const parser = new EmailParser();
|
|
76
|
+
* parser.unfoldHeaders('Subject: This is\r\n a long subject');
|
|
77
|
+
* // => 'Subject: This is a long subject'
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
unfoldHeaders(rawHeaders) {
|
|
81
|
+
// Per RFC 5322 Section 2.2.3: remove CRLF followed by at least one WSP (space or tab)
|
|
82
|
+
// Also handle bare LF followed by WSP for robustness
|
|
83
|
+
return rawHeaders.replace(/\r\n([ \t])/g, '$1').replace(/\n([ \t])/g, '$1');
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Parses a raw header section string into a Map of header names to values.
|
|
87
|
+
*
|
|
88
|
+
* Handles:
|
|
89
|
+
* - Header unfolding (multi-line headers)
|
|
90
|
+
* - Multiple values for the same header name
|
|
91
|
+
* - Case-insensitive header name storage (lowercased keys)
|
|
92
|
+
*
|
|
93
|
+
* @param headerSection - The raw header section string (headers separated by line breaks)
|
|
94
|
+
* @returns Map of lowercase header names to arrays of values
|
|
95
|
+
*
|
|
96
|
+
* @see RFC 5322 Section 2.2 - Header Fields
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* const parser = new EmailParser();
|
|
101
|
+
* const headers = parser.parseHeaders('From: alice@example.com\r\nTo: bob@example.com');
|
|
102
|
+
* headers.get('from'); // ['alice@example.com']
|
|
103
|
+
* headers.get('to'); // ['bob@example.com']
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
parseHeaders(headerSection) {
|
|
107
|
+
const result = new Map();
|
|
108
|
+
if (!headerSection || headerSection.trim().length === 0) {
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
// First, unfold multi-line headers
|
|
112
|
+
const unfolded = this.unfoldHeaders(headerSection);
|
|
113
|
+
// Split into individual header lines
|
|
114
|
+
// Handle both CRLF and LF line endings
|
|
115
|
+
const lines = unfolded.split(/\r?\n/);
|
|
116
|
+
for (const line of lines) {
|
|
117
|
+
// Skip empty lines
|
|
118
|
+
if (line.trim().length === 0) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
// Parse "name: value" format
|
|
122
|
+
const colonIndex = line.indexOf(':');
|
|
123
|
+
if (colonIndex <= 0) {
|
|
124
|
+
// No colon found or colon at start - skip invalid line
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const name = line.substring(0, colonIndex).trim().toLowerCase();
|
|
128
|
+
const value = line.substring(colonIndex + 1).trim();
|
|
129
|
+
const existing = result.get(name);
|
|
130
|
+
if (existing) {
|
|
131
|
+
existing.push(value);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
result.set(name, [value]);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Parses a single mailbox address string into an IMailbox object.
|
|
141
|
+
*
|
|
142
|
+
* Uses the `email-addresses` library for RFC 5322 compliant parsing.
|
|
143
|
+
* Supports both name-addr format (`"Display Name" <local@domain>`)
|
|
144
|
+
* and addr-spec format (`local@domain`).
|
|
145
|
+
*
|
|
146
|
+
* @param mailboxString - The mailbox string to parse
|
|
147
|
+
* @returns The parsed IMailbox object
|
|
148
|
+
* @throws {EmailError} With INVALID_MAILBOX if parsing fails
|
|
149
|
+
*
|
|
150
|
+
* @see RFC 5322 Section 3.4 - Address Specification
|
|
151
|
+
* @see Requirement 2.1 - Parse mailbox addresses
|
|
152
|
+
* @see Requirement 2.2 - Parse addr-spec as local-part@domain
|
|
153
|
+
* @see Requirement 2.3 - Support quoted-string local-parts
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const parser = new EmailParser();
|
|
158
|
+
* const mailbox = parser.parseMailbox('John Doe <john@example.com>');
|
|
159
|
+
* // { displayName: 'John Doe', localPart: 'john', domain: 'example.com' }
|
|
160
|
+
*
|
|
161
|
+
* const simple = parser.parseMailbox('user@example.com');
|
|
162
|
+
* // { localPart: 'user', domain: 'example.com' }
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
parseMailbox(mailboxString) {
|
|
166
|
+
if (!mailboxString || mailboxString.trim().length === 0) {
|
|
167
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_MAILBOX, 'Mailbox string is empty', { input: mailboxString });
|
|
168
|
+
}
|
|
169
|
+
const parsed = emailAddresses.parseOneAddress(mailboxString);
|
|
170
|
+
if (!parsed) {
|
|
171
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_MAILBOX, `Failed to parse mailbox address: ${mailboxString}`, { input: mailboxString });
|
|
172
|
+
}
|
|
173
|
+
if (parsed.type === 'group') {
|
|
174
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_MAILBOX, 'Expected a mailbox address but got a group address', { input: mailboxString });
|
|
175
|
+
}
|
|
176
|
+
// parsed is a ParsedMailbox
|
|
177
|
+
return (0, emailAddress_1.createMailbox)(parsed.local, parsed.domain, parsed.name || undefined);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Parses an address list string into an array of IAddress objects.
|
|
181
|
+
*
|
|
182
|
+
* Uses the `email-addresses` library for RFC 5322 compliant parsing.
|
|
183
|
+
* Supports both individual mailboxes and group addresses.
|
|
184
|
+
*
|
|
185
|
+
* @param addressListString - The comma-separated address list string
|
|
186
|
+
* @returns Array of parsed IAddress objects (IMailbox or IAddressGroup)
|
|
187
|
+
* @throws {EmailError} With INVALID_MAILBOX if parsing fails
|
|
188
|
+
*
|
|
189
|
+
* @see RFC 5322 Section 3.4 - Address Specification
|
|
190
|
+
* @see Requirement 2.1 - Parse mailbox addresses
|
|
191
|
+
* @see Requirement 2.4 - Support group addresses
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```typescript
|
|
195
|
+
* const parser = new EmailParser();
|
|
196
|
+
* const addresses = parser.parseAddressList('alice@example.com, Bob <bob@example.com>');
|
|
197
|
+
* // [IMailbox, IMailbox]
|
|
198
|
+
*
|
|
199
|
+
* const withGroup = parser.parseAddressList('Team: alice@example.com, bob@example.com;');
|
|
200
|
+
* // [IAddressGroup]
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
parseAddressList(addressListString) {
|
|
204
|
+
if (!addressListString || addressListString.trim().length === 0) {
|
|
205
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_MAILBOX, 'Address list string is empty', { input: addressListString });
|
|
206
|
+
}
|
|
207
|
+
const parsed = emailAddresses.parseAddressList(addressListString);
|
|
208
|
+
if (!parsed) {
|
|
209
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_MAILBOX, `Failed to parse address list: ${addressListString}`, { input: addressListString });
|
|
210
|
+
}
|
|
211
|
+
return parsed.map((entry) => {
|
|
212
|
+
if (entry.type === 'group') {
|
|
213
|
+
const mailboxes = entry.addresses.map((mb) => (0, emailAddress_1.createMailbox)(mb.local, mb.domain, mb.name || undefined));
|
|
214
|
+
return (0, emailAddress_1.createAddressGroup)(entry.name, mailboxes);
|
|
215
|
+
}
|
|
216
|
+
// entry is a ParsedMailbox
|
|
217
|
+
return (0, emailAddress_1.createMailbox)(entry.local, entry.domain, entry.name || undefined);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Parses a Message-ID string, validating its format.
|
|
222
|
+
*
|
|
223
|
+
* Message-IDs must be enclosed in angle brackets and contain exactly
|
|
224
|
+
* one "@" character per RFC 5322 Section 3.6.4.
|
|
225
|
+
*
|
|
226
|
+
* Also supports extracting multiple Message-IDs from In-Reply-To
|
|
227
|
+
* or References headers when called via parseMessageIdList().
|
|
228
|
+
*
|
|
229
|
+
* @param messageIdString - The Message-ID string to parse (e.g., "<id@domain>")
|
|
230
|
+
* @returns The validated Message-ID string (with angle brackets)
|
|
231
|
+
* @throws {EmailError} With INVALID_MESSAGE_ID if format is invalid
|
|
232
|
+
*
|
|
233
|
+
* @see RFC 5322 Section 3.6.4 - Identification Fields
|
|
234
|
+
* @see Requirement 3.4 - Validate Message-IDs are enclosed in angle brackets
|
|
235
|
+
* @see Requirement 3.5 - Validate Message-IDs contain exactly one "@"
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* const parser = new EmailParser();
|
|
240
|
+
* parser.parseMessageId('<unique-id@example.com>');
|
|
241
|
+
* // => '<unique-id@example.com>'
|
|
242
|
+
*
|
|
243
|
+
* parser.parseMessageId('no-brackets@example.com');
|
|
244
|
+
* // throws EmailError (INVALID_MESSAGE_ID)
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
parseMessageId(messageIdString) {
|
|
248
|
+
if (!messageIdString || messageIdString.trim().length === 0) {
|
|
249
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_MESSAGE_ID, 'Message-ID string is empty', { input: messageIdString });
|
|
250
|
+
}
|
|
251
|
+
const trimmed = messageIdString.trim();
|
|
252
|
+
// Validate angle brackets (Requirement 3.4)
|
|
253
|
+
if (!trimmed.startsWith('<') || !trimmed.endsWith('>')) {
|
|
254
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_MESSAGE_ID, 'Message-ID must be enclosed in angle brackets', { input: messageIdString });
|
|
255
|
+
}
|
|
256
|
+
// Extract the content between angle brackets
|
|
257
|
+
const content = trimmed.substring(1, trimmed.length - 1);
|
|
258
|
+
// Validate exactly one "@" character (Requirement 3.5)
|
|
259
|
+
const atCount = (content.match(/@/g) || []).length;
|
|
260
|
+
if (atCount !== 1) {
|
|
261
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_MESSAGE_ID, `Message-ID must contain exactly one "@" character, found ${atCount}`, { input: messageIdString, atCount });
|
|
262
|
+
}
|
|
263
|
+
return trimmed;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Extracts multiple Message-IDs from In-Reply-To or References header values.
|
|
267
|
+
*
|
|
268
|
+
* These headers can contain multiple Message-IDs separated by whitespace.
|
|
269
|
+
*
|
|
270
|
+
* @param headerValue - The header value containing one or more Message-IDs
|
|
271
|
+
* @returns Array of validated Message-ID strings
|
|
272
|
+
*
|
|
273
|
+
* @see RFC 5322 Section 3.6.4 - Identification Fields
|
|
274
|
+
* @see Requirement 3.6 - Extract multiple Message-IDs separated by whitespace
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* ```typescript
|
|
278
|
+
* const parser = new EmailParser();
|
|
279
|
+
* parser.parseMessageIdList('<id1@example.com> <id2@example.com>');
|
|
280
|
+
* // => ['<id1@example.com>', '<id2@example.com>']
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
parseMessageIdList(headerValue) {
|
|
284
|
+
if (!headerValue || headerValue.trim().length === 0) {
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
287
|
+
// Extract all angle-bracketed Message-IDs from the string
|
|
288
|
+
const messageIdPattern = /<[^>]+>/g;
|
|
289
|
+
const matches = headerValue.match(messageIdPattern);
|
|
290
|
+
if (!matches || matches.length === 0) {
|
|
291
|
+
return [];
|
|
292
|
+
}
|
|
293
|
+
// Validate each extracted Message-ID
|
|
294
|
+
return matches.map((id) => this.parseMessageId(id));
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Parses an RFC 5322 date string into a Date object.
|
|
298
|
+
*
|
|
299
|
+
* Handles common RFC 5322 date formats including:
|
|
300
|
+
* - Full format: "Thu, 13 Feb 2025 15:30:00 +0000"
|
|
301
|
+
* - Without day-of-week: "13 Feb 2025 15:30:00 +0000"
|
|
302
|
+
* - Various timezone formats
|
|
303
|
+
*
|
|
304
|
+
* @param dateString - The RFC 5322 date string to parse
|
|
305
|
+
* @returns The parsed Date object
|
|
306
|
+
* @throws {EmailError} With INVALID_DATE if parsing fails
|
|
307
|
+
*
|
|
308
|
+
* @see RFC 5322 Section 3.3 - Date and Time Specification
|
|
309
|
+
*
|
|
310
|
+
* @example
|
|
311
|
+
* ```typescript
|
|
312
|
+
* const parser = new EmailParser();
|
|
313
|
+
* parser.parseDate('Thu, 13 Feb 2025 15:30:00 +0000');
|
|
314
|
+
* // => Date object for 2025-02-13T15:30:00Z
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
parseDate(dateString) {
|
|
318
|
+
if (!dateString || dateString.trim().length === 0) {
|
|
319
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_DATE, 'Date string is empty', { input: dateString });
|
|
320
|
+
}
|
|
321
|
+
const trimmed = dateString.trim();
|
|
322
|
+
// Try parsing with the built-in Date constructor
|
|
323
|
+
// JavaScript's Date.parse handles many RFC 5322 date formats
|
|
324
|
+
const date = new Date(trimmed);
|
|
325
|
+
if (isNaN(date.getTime())) {
|
|
326
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_DATE, `Failed to parse date: ${dateString}`, { input: dateString });
|
|
327
|
+
}
|
|
328
|
+
return date;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Parses a Content-Type header string into an IContentType object.
|
|
332
|
+
*
|
|
333
|
+
* Extracts the type, subtype, and parameters from a Content-Type header value.
|
|
334
|
+
* Handles quoted parameter values containing special characters.
|
|
335
|
+
*
|
|
336
|
+
* @param contentTypeString - The Content-Type header value to parse
|
|
337
|
+
* @returns The parsed IContentType object
|
|
338
|
+
* @throws {EmailError} With INVALID_CONTENT_TYPE if parsing fails
|
|
339
|
+
*
|
|
340
|
+
* @see RFC 2045 Section 5 - Content-Type Header Field
|
|
341
|
+
* @see Requirement 5.1 - Content-Type with type/subtype and optional parameters
|
|
342
|
+
* @see Requirement 5.2 - Parse Content-Type parameters
|
|
343
|
+
* @see Requirement 5.3 - Handle quoted parameter values
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```typescript
|
|
347
|
+
* const parser = new EmailParser();
|
|
348
|
+
* const ct = parser.parseContentType('text/plain; charset=utf-8');
|
|
349
|
+
* // { type: 'text', subtype: 'plain', parameters: Map { 'charset' => 'utf-8' } }
|
|
350
|
+
*
|
|
351
|
+
* const mp = parser.parseContentType('multipart/mixed; boundary="----=_Part_123"');
|
|
352
|
+
* // { type: 'multipart', subtype: 'mixed', parameters: Map { 'boundary' => '----=_Part_123' } }
|
|
353
|
+
* ```
|
|
354
|
+
*/
|
|
355
|
+
parseContentType(contentTypeString) {
|
|
356
|
+
if (!contentTypeString || contentTypeString.trim().length === 0) {
|
|
357
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_CONTENT_TYPE, 'Content-Type string is empty', { input: contentTypeString });
|
|
358
|
+
}
|
|
359
|
+
const trimmed = contentTypeString.trim();
|
|
360
|
+
// Split on first semicolon to separate media type from parameters
|
|
361
|
+
const semicolonIndex = trimmed.indexOf(';');
|
|
362
|
+
const mediaTypePart = semicolonIndex >= 0
|
|
363
|
+
? trimmed.substring(0, semicolonIndex).trim()
|
|
364
|
+
: trimmed;
|
|
365
|
+
const paramsPart = semicolonIndex >= 0 ? trimmed.substring(semicolonIndex + 1).trim() : '';
|
|
366
|
+
// Parse type/subtype
|
|
367
|
+
const slashIndex = mediaTypePart.indexOf('/');
|
|
368
|
+
if (slashIndex <= 0) {
|
|
369
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_CONTENT_TYPE, `Invalid Content-Type format, expected type/subtype: ${contentTypeString}`, { input: contentTypeString });
|
|
370
|
+
}
|
|
371
|
+
const type = mediaTypePart.substring(0, slashIndex).trim().toLowerCase();
|
|
372
|
+
const subtype = mediaTypePart
|
|
373
|
+
.substring(slashIndex + 1)
|
|
374
|
+
.trim()
|
|
375
|
+
.toLowerCase();
|
|
376
|
+
if (!type || !subtype) {
|
|
377
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.INVALID_CONTENT_TYPE, `Invalid Content-Type: missing type or subtype: ${contentTypeString}`, { input: contentTypeString });
|
|
378
|
+
}
|
|
379
|
+
// Parse parameters
|
|
380
|
+
const parameters = new Map();
|
|
381
|
+
if (paramsPart) {
|
|
382
|
+
this.parseContentTypeParameters(paramsPart, parameters);
|
|
383
|
+
}
|
|
384
|
+
return (0, mimePart_1.createContentType)(type, subtype, parameters);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Parses Content-Type parameters from a parameter string.
|
|
388
|
+
*
|
|
389
|
+
* Handles both quoted and unquoted parameter values.
|
|
390
|
+
*
|
|
391
|
+
* @param paramString - The parameter portion of the Content-Type header
|
|
392
|
+
* @param parameters - Map to populate with parsed parameters
|
|
393
|
+
*/
|
|
394
|
+
parseContentTypeParameters(paramString, parameters) {
|
|
395
|
+
// Use a state machine approach to handle quoted values with semicolons
|
|
396
|
+
let remaining = paramString.trim();
|
|
397
|
+
while (remaining.length > 0) {
|
|
398
|
+
// Find the parameter name
|
|
399
|
+
const equalsIndex = remaining.indexOf('=');
|
|
400
|
+
if (equalsIndex <= 0) {
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
const name = remaining.substring(0, equalsIndex).trim().toLowerCase();
|
|
404
|
+
remaining = remaining.substring(equalsIndex + 1).trim();
|
|
405
|
+
let value;
|
|
406
|
+
if (remaining.startsWith('"')) {
|
|
407
|
+
// Quoted value - find the closing quote (handling escaped quotes)
|
|
408
|
+
let endQuote = 1;
|
|
409
|
+
while (endQuote < remaining.length) {
|
|
410
|
+
if (remaining[endQuote] === '\\' && endQuote + 1 < remaining.length) {
|
|
411
|
+
endQuote += 2; // Skip escaped character
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
if (remaining[endQuote] === '"') {
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
endQuote++;
|
|
418
|
+
}
|
|
419
|
+
// Extract value without quotes, unescape backslash-escaped characters
|
|
420
|
+
value = remaining.substring(1, endQuote).replace(/\\(.)/g, '$1');
|
|
421
|
+
remaining = remaining.substring(endQuote + 1).trim();
|
|
422
|
+
// Skip the semicolon separator if present
|
|
423
|
+
if (remaining.startsWith(';')) {
|
|
424
|
+
remaining = remaining.substring(1).trim();
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
// Unquoted value - find the next semicolon
|
|
429
|
+
const nextSemicolon = remaining.indexOf(';');
|
|
430
|
+
if (nextSemicolon >= 0) {
|
|
431
|
+
value = remaining.substring(0, nextSemicolon).trim();
|
|
432
|
+
remaining = remaining.substring(nextSemicolon + 1).trim();
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
value = remaining.trim();
|
|
436
|
+
remaining = '';
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
if (name) {
|
|
440
|
+
parameters.set(name, value);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Decodes an RFC 2047 encoded-word back to a UTF-8 string.
|
|
446
|
+
*
|
|
447
|
+
* Encoded-words have the format: =?charset?encoding?encoded-text?=
|
|
448
|
+
* where encoding is either "B" (base64) or "Q" (quoted-printable).
|
|
449
|
+
*
|
|
450
|
+
* If the input is not an encoded-word, it is returned as-is.
|
|
451
|
+
*
|
|
452
|
+
* @param encodedWord - The string potentially containing an encoded-word
|
|
453
|
+
* @returns The decoded UTF-8 string
|
|
454
|
+
*
|
|
455
|
+
* @see RFC 2047 - MIME Part Three: Message Header Extensions for Non-ASCII Text
|
|
456
|
+
* @see Requirement 4.5 - Decode RFC 2047 encoded-words in subject lines back to UTF-8
|
|
457
|
+
*
|
|
458
|
+
* @example
|
|
459
|
+
* ```typescript
|
|
460
|
+
* const parser = new EmailParser();
|
|
461
|
+
* parser.decodeEncodedWord('=?UTF-8?B?SGVsbG8gV29ybGQ=?=');
|
|
462
|
+
* // => 'Hello World'
|
|
463
|
+
*
|
|
464
|
+
* parser.decodeEncodedWord('=?UTF-8?Q?Hello_World?=');
|
|
465
|
+
* // => 'Hello World'
|
|
466
|
+
*
|
|
467
|
+
* parser.decodeEncodedWord('plain text');
|
|
468
|
+
* // => 'plain text'
|
|
469
|
+
* ```
|
|
470
|
+
*/
|
|
471
|
+
decodeEncodedWord(encodedWord) {
|
|
472
|
+
if (!encodedWord) {
|
|
473
|
+
return encodedWord;
|
|
474
|
+
}
|
|
475
|
+
// RFC 2047 encoded-word pattern: =?charset?encoding?encoded-text?=
|
|
476
|
+
const encodedWordPattern = /=\?([^?]+)\?([BbQq])\?([^?]*)\?=/g;
|
|
477
|
+
return encodedWord.replace(encodedWordPattern, (_match, charset, encoding, encodedText) => {
|
|
478
|
+
const enc = encoding.toUpperCase();
|
|
479
|
+
let decodedBytes;
|
|
480
|
+
if (enc === 'B') {
|
|
481
|
+
// Base64 decoding
|
|
482
|
+
decodedBytes = Buffer.from(encodedText, 'base64');
|
|
483
|
+
}
|
|
484
|
+
else if (enc === 'Q') {
|
|
485
|
+
// Quoted-printable decoding for encoded-words
|
|
486
|
+
// In Q encoding, underscores represent spaces (RFC 2047 Section 4.2)
|
|
487
|
+
const qpText = encodedText.replace(/_/g, ' ');
|
|
488
|
+
// Decode =XX hex sequences
|
|
489
|
+
const decoded = qpText.replace(/=([0-9A-Fa-f]{2})/g, (_m, hex) => String.fromCharCode(parseInt(hex, 16)));
|
|
490
|
+
decodedBytes = Buffer.from(decoded, 'binary');
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
// Unknown encoding, return as-is
|
|
494
|
+
return _match;
|
|
495
|
+
}
|
|
496
|
+
// Convert bytes to string using the specified charset
|
|
497
|
+
// Node.js Buffer supports common charsets
|
|
498
|
+
const normalizedCharset = charset.toLowerCase();
|
|
499
|
+
try {
|
|
500
|
+
if (normalizedCharset === 'utf-8' || normalizedCharset === 'utf8') {
|
|
501
|
+
return decodedBytes.toString('utf-8');
|
|
502
|
+
}
|
|
503
|
+
else if (normalizedCharset === 'iso-8859-1' ||
|
|
504
|
+
normalizedCharset === 'latin1') {
|
|
505
|
+
return decodedBytes.toString('latin1');
|
|
506
|
+
}
|
|
507
|
+
else if (normalizedCharset === 'us-ascii' ||
|
|
508
|
+
normalizedCharset === 'ascii') {
|
|
509
|
+
return decodedBytes.toString('ascii');
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
// For other charsets, attempt UTF-8 decoding as a best effort
|
|
513
|
+
return decodedBytes.toString('utf-8');
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
catch {
|
|
517
|
+
// If charset conversion fails, return the raw decoded bytes as UTF-8
|
|
518
|
+
return decodedBytes.toString('utf-8');
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Decodes quoted-printable encoded data per RFC 2045 Section 6.7.
|
|
524
|
+
*
|
|
525
|
+
* Replaces =XX sequences with the corresponding byte value and
|
|
526
|
+
* handles soft line breaks (=\r\n or =\n).
|
|
527
|
+
*
|
|
528
|
+
* @param data - The quoted-printable encoded data as Uint8Array
|
|
529
|
+
* @returns The decoded bytes as Uint8Array
|
|
530
|
+
*
|
|
531
|
+
* @see RFC 2045 Section 6.7 - Quoted-Printable Content-Transfer-Encoding
|
|
532
|
+
* @see Requirement 7.8 - Decode content based on Content-Transfer-Encoding
|
|
533
|
+
* @see Requirement 14.9 - Decode body according to Content-Transfer-Encoding header
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* ```typescript
|
|
537
|
+
* const parser = new EmailParser();
|
|
538
|
+
* const encoded = new TextEncoder().encode('Hello=20World');
|
|
539
|
+
* const decoded = parser.decodeQuotedPrintable(encoded);
|
|
540
|
+
* // decoded contains bytes for 'Hello World'
|
|
541
|
+
* ```
|
|
542
|
+
*/
|
|
543
|
+
decodeQuotedPrintable(data) {
|
|
544
|
+
const input = Buffer.from(data);
|
|
545
|
+
const result = [];
|
|
546
|
+
let i = 0;
|
|
547
|
+
while (i < input.length) {
|
|
548
|
+
if (input[i] === 0x3d) {
|
|
549
|
+
// '=' character
|
|
550
|
+
// Check for soft line break: =\r\n or =\n
|
|
551
|
+
if (i + 1 < input.length &&
|
|
552
|
+
input[i + 1] === 0x0d &&
|
|
553
|
+
i + 2 < input.length &&
|
|
554
|
+
input[i + 2] === 0x0a) {
|
|
555
|
+
// =\r\n soft line break - skip all three bytes
|
|
556
|
+
i += 3;
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
if (i + 1 < input.length && input[i + 1] === 0x0a) {
|
|
560
|
+
// =\n soft line break - skip both bytes
|
|
561
|
+
i += 2;
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
// Check for =XX hex encoding
|
|
565
|
+
if (i + 2 < input.length) {
|
|
566
|
+
const hex1 = input[i + 1];
|
|
567
|
+
const hex2 = input[i + 2];
|
|
568
|
+
const hexStr = String.fromCharCode(hex1) + String.fromCharCode(hex2);
|
|
569
|
+
if (/^[0-9A-Fa-f]{2}$/.test(hexStr)) {
|
|
570
|
+
result.push(parseInt(hexStr, 16));
|
|
571
|
+
i += 3;
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
// Not a valid QP sequence, pass through the '=' as-is
|
|
576
|
+
result.push(input[i]);
|
|
577
|
+
i++;
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
result.push(input[i]);
|
|
581
|
+
i++;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
return new Uint8Array(result);
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Decodes base64 encoded data per RFC 2045 Section 6.8.
|
|
588
|
+
*
|
|
589
|
+
* Uses Node.js Buffer for decoding. Ignores whitespace in the input,
|
|
590
|
+
* as line breaks in base64 encoded data are common per RFC 2045.
|
|
591
|
+
*
|
|
592
|
+
* @param data - The base64 encoded data as Uint8Array
|
|
593
|
+
* @returns The decoded bytes as Uint8Array
|
|
594
|
+
*
|
|
595
|
+
* @see RFC 2045 Section 6.8 - Base64 Content-Transfer-Encoding
|
|
596
|
+
* @see Requirement 7.8 - Decode content based on Content-Transfer-Encoding
|
|
597
|
+
* @see Requirement 14.9 - Decode body according to Content-Transfer-Encoding header
|
|
598
|
+
*
|
|
599
|
+
* @example
|
|
600
|
+
* ```typescript
|
|
601
|
+
* const parser = new EmailParser();
|
|
602
|
+
* const encoded = new TextEncoder().encode('SGVsbG8gV29ybGQ=');
|
|
603
|
+
* const decoded = parser.decodeBase64(encoded);
|
|
604
|
+
* // decoded contains bytes for 'Hello World'
|
|
605
|
+
* ```
|
|
606
|
+
*/
|
|
607
|
+
decodeBase64(data) {
|
|
608
|
+
// Convert Uint8Array to string, stripping whitespace (CR, LF, space, tab)
|
|
609
|
+
const base64String = Buffer.from(data)
|
|
610
|
+
.toString('ascii')
|
|
611
|
+
.replace(/[\r\n\s\t]/g, '');
|
|
612
|
+
// Decode using Node.js Buffer
|
|
613
|
+
const decoded = Buffer.from(base64String, 'base64');
|
|
614
|
+
return new Uint8Array(decoded);
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Parses (decodes) the body of a MIME part based on its Content-Transfer-Encoding.
|
|
618
|
+
*
|
|
619
|
+
* Dispatches to the appropriate decoder:
|
|
620
|
+
* - '7bit', '8bit', 'binary': returns body as-is (no decoding needed)
|
|
621
|
+
* - 'quoted-printable': calls decodeQuotedPrintable()
|
|
622
|
+
* - 'base64': calls decodeBase64()
|
|
623
|
+
*
|
|
624
|
+
* @param body - The raw body data as Uint8Array
|
|
625
|
+
* @param contentType - The Content-Type of the body (for future use)
|
|
626
|
+
* @param encoding - The Content-Transfer-Encoding to apply
|
|
627
|
+
* @returns The decoded body as Uint8Array
|
|
628
|
+
*
|
|
629
|
+
* @see RFC 2045 Section 6 - Content-Transfer-Encoding Header Field
|
|
630
|
+
* @see Requirement 7.8 - Decode content based on Content-Transfer-Encoding
|
|
631
|
+
* @see Requirement 14.9 - Decode body according to Content-Transfer-Encoding header
|
|
632
|
+
*
|
|
633
|
+
* @example
|
|
634
|
+
* ```typescript
|
|
635
|
+
* const parser = new EmailParser();
|
|
636
|
+
* const ct = createContentType('text', 'plain');
|
|
637
|
+
* const body = new TextEncoder().encode('SGVsbG8=');
|
|
638
|
+
* const decoded = parser.parseBody(body, ct, ContentTransferEncoding.Base64);
|
|
639
|
+
* // decoded contains bytes for 'Hello'
|
|
640
|
+
* ```
|
|
641
|
+
*/
|
|
642
|
+
parseBody(body, contentType, encoding) {
|
|
643
|
+
switch (encoding) {
|
|
644
|
+
case mimePart_1.ContentTransferEncoding.SevenBit:
|
|
645
|
+
case mimePart_1.ContentTransferEncoding.EightBit:
|
|
646
|
+
case mimePart_1.ContentTransferEncoding.Binary:
|
|
647
|
+
// No decoding needed for these encodings
|
|
648
|
+
return body;
|
|
649
|
+
case mimePart_1.ContentTransferEncoding.QuotedPrintable:
|
|
650
|
+
return this.decodeQuotedPrintable(body);
|
|
651
|
+
case mimePart_1.ContentTransferEncoding.Base64:
|
|
652
|
+
return this.decodeBase64(body);
|
|
653
|
+
default:
|
|
654
|
+
// Unknown encoding, return as-is
|
|
655
|
+
return body;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Parses a multipart MIME body into an array of IMimePart objects.
|
|
660
|
+
*
|
|
661
|
+
* Splits the body by the given boundary delimiter, parses each part's
|
|
662
|
+
* headers and body, and recursively handles nested multipart structures.
|
|
663
|
+
* Preamble text (before the first boundary) and epilogue text (after the
|
|
664
|
+
* final boundary) are handled gracefully and ignored per RFC 2046.
|
|
665
|
+
*
|
|
666
|
+
* @param body - The raw multipart body as Uint8Array
|
|
667
|
+
* @param boundary - The boundary string from the Content-Type header
|
|
668
|
+
* @returns Array of parsed IMimePart objects
|
|
669
|
+
* @throws {EmailError} With MALFORMED_MIME if the boundary is missing or body is malformed
|
|
670
|
+
*
|
|
671
|
+
* @see RFC 2046 Section 5.1 - Multipart Media Type
|
|
672
|
+
* @see Requirement 6.7 - Parse nested multipart structures
|
|
673
|
+
* @see Requirement 6.8 - Handle preamble and epilogue text
|
|
674
|
+
*
|
|
675
|
+
* @example
|
|
676
|
+
* ```typescript
|
|
677
|
+
* const parser = new EmailParser();
|
|
678
|
+
* const body = new TextEncoder().encode(
|
|
679
|
+
* '--boundary\r\nContent-Type: text/plain\r\n\r\nHello\r\n--boundary--'
|
|
680
|
+
* );
|
|
681
|
+
* const parts = parser.parseMultipart(body, 'boundary');
|
|
682
|
+
* // [{ contentType: { type: 'text', subtype: 'plain', ... }, body: ..., size: 5 }]
|
|
683
|
+
* ```
|
|
684
|
+
*/
|
|
685
|
+
parseMultipart(body, boundary) {
|
|
686
|
+
if (!boundary) {
|
|
687
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.MALFORMED_MIME, 'Boundary string is required for multipart parsing', { boundary });
|
|
688
|
+
}
|
|
689
|
+
const bodyStr = new TextDecoder().decode(body);
|
|
690
|
+
// Boundary delimiters per RFC 2046 Section 5.1.1
|
|
691
|
+
const dashBoundary = `--${boundary}`;
|
|
692
|
+
const closingBoundary = `--${boundary}--`;
|
|
693
|
+
// Find the first boundary - everything before it is preamble (ignored per RFC 2046)
|
|
694
|
+
const firstBoundaryIndex = bodyStr.indexOf(dashBoundary);
|
|
695
|
+
if (firstBoundaryIndex === -1) {
|
|
696
|
+
// No boundary found - return empty parts array
|
|
697
|
+
return [];
|
|
698
|
+
}
|
|
699
|
+
// Find the closing boundary - everything after it is epilogue (ignored per RFC 2046)
|
|
700
|
+
const closingBoundaryIndex = bodyStr.indexOf(closingBoundary);
|
|
701
|
+
// Extract the content between first boundary and closing boundary
|
|
702
|
+
const contentArea = closingBoundaryIndex !== -1
|
|
703
|
+
? bodyStr.substring(firstBoundaryIndex, closingBoundaryIndex)
|
|
704
|
+
: bodyStr.substring(firstBoundaryIndex);
|
|
705
|
+
// Split by boundary delimiter to get individual parts
|
|
706
|
+
// Each boundary line starts with --boundary and is followed by CRLF or LF
|
|
707
|
+
const parts = [];
|
|
708
|
+
const boundaryRegex = new RegExp(this.escapeRegExp(dashBoundary) + '[ \\t]*(?:\\r?\\n)', 'g');
|
|
709
|
+
// Find all boundary positions
|
|
710
|
+
const boundaryPositions = [];
|
|
711
|
+
let match;
|
|
712
|
+
while ((match = boundaryRegex.exec(contentArea)) !== null) {
|
|
713
|
+
boundaryPositions.push(match.index + match[0].length);
|
|
714
|
+
}
|
|
715
|
+
if (boundaryPositions.length === 0) {
|
|
716
|
+
return [];
|
|
717
|
+
}
|
|
718
|
+
// Extract each part between consecutive boundaries
|
|
719
|
+
for (let i = 0; i < boundaryPositions.length; i++) {
|
|
720
|
+
const partStart = boundaryPositions[i];
|
|
721
|
+
let partEnd;
|
|
722
|
+
if (i + 1 < boundaryPositions.length) {
|
|
723
|
+
// Find the start of the next boundary line (go back to find the --boundary)
|
|
724
|
+
const nextBoundaryLineStart = contentArea.lastIndexOf(dashBoundary, boundaryPositions[i + 1]);
|
|
725
|
+
// Remove trailing CRLF before the boundary
|
|
726
|
+
partEnd = nextBoundaryLineStart;
|
|
727
|
+
// Strip trailing \r\n or \n before the boundary delimiter
|
|
728
|
+
if (partEnd > 0 && contentArea[partEnd - 1] === '\n') {
|
|
729
|
+
partEnd--;
|
|
730
|
+
}
|
|
731
|
+
if (partEnd > 0 && contentArea[partEnd - 1] === '\r') {
|
|
732
|
+
partEnd--;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
else {
|
|
736
|
+
// Last part - goes to end of content area
|
|
737
|
+
partEnd = contentArea.length;
|
|
738
|
+
// Strip trailing \r\n or \n
|
|
739
|
+
if (partEnd > 0 && contentArea[partEnd - 1] === '\n') {
|
|
740
|
+
partEnd--;
|
|
741
|
+
}
|
|
742
|
+
if (partEnd > 0 && contentArea[partEnd - 1] === '\r') {
|
|
743
|
+
partEnd--;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
if (partStart > partEnd) {
|
|
747
|
+
continue;
|
|
748
|
+
}
|
|
749
|
+
const partContent = contentArea.substring(partStart, partEnd);
|
|
750
|
+
const mimePart = this.parseSinglePart(partContent);
|
|
751
|
+
parts.push(mimePart);
|
|
752
|
+
}
|
|
753
|
+
return parts;
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Parses a single MIME part (headers + body) into an IMimePart object.
|
|
757
|
+
*
|
|
758
|
+
* @param partContent - The raw content of a single MIME part (headers + blank line + body)
|
|
759
|
+
* @returns The parsed IMimePart object
|
|
760
|
+
*/
|
|
761
|
+
parseSinglePart(partContent) {
|
|
762
|
+
// Split headers from body at the first blank line (CRLF CRLF or LF LF)
|
|
763
|
+
const headerBodySeparator = partContent.match(/\r?\n\r?\n/);
|
|
764
|
+
let headerSection;
|
|
765
|
+
let bodyContent;
|
|
766
|
+
if (headerBodySeparator && headerBodySeparator.index !== undefined) {
|
|
767
|
+
headerSection = partContent.substring(0, headerBodySeparator.index);
|
|
768
|
+
bodyContent = partContent.substring(headerBodySeparator.index + headerBodySeparator[0].length);
|
|
769
|
+
}
|
|
770
|
+
else {
|
|
771
|
+
// No blank line found - treat entire content as body with default headers
|
|
772
|
+
headerSection = '';
|
|
773
|
+
bodyContent = partContent;
|
|
774
|
+
}
|
|
775
|
+
// Parse headers
|
|
776
|
+
const headers = this.parseHeaders(headerSection);
|
|
777
|
+
// Parse Content-Type (default to text/plain; charset=us-ascii per RFC 2046)
|
|
778
|
+
let contentType;
|
|
779
|
+
const contentTypeValues = headers.get('content-type');
|
|
780
|
+
if (contentTypeValues && contentTypeValues.length > 0) {
|
|
781
|
+
try {
|
|
782
|
+
contentType = this.parseContentType(contentTypeValues[0]);
|
|
783
|
+
}
|
|
784
|
+
catch {
|
|
785
|
+
contentType = (0, mimePart_1.createContentType)('text', 'plain', new Map([['charset', 'us-ascii']]));
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
else {
|
|
789
|
+
contentType = (0, mimePart_1.createContentType)('text', 'plain', new Map([['charset', 'us-ascii']]));
|
|
790
|
+
}
|
|
791
|
+
// Parse Content-Transfer-Encoding
|
|
792
|
+
let contentTransferEncoding;
|
|
793
|
+
const cteValues = headers.get('content-transfer-encoding');
|
|
794
|
+
if (cteValues && cteValues.length > 0) {
|
|
795
|
+
const cteStr = cteValues[0].trim().toLowerCase();
|
|
796
|
+
const validEncodings = {
|
|
797
|
+
'7bit': mimePart_1.ContentTransferEncoding.SevenBit,
|
|
798
|
+
'8bit': mimePart_1.ContentTransferEncoding.EightBit,
|
|
799
|
+
binary: mimePart_1.ContentTransferEncoding.Binary,
|
|
800
|
+
'quoted-printable': mimePart_1.ContentTransferEncoding.QuotedPrintable,
|
|
801
|
+
base64: mimePart_1.ContentTransferEncoding.Base64,
|
|
802
|
+
};
|
|
803
|
+
contentTransferEncoding = validEncodings[cteStr];
|
|
804
|
+
}
|
|
805
|
+
// Parse Content-Disposition
|
|
806
|
+
let contentDisposition;
|
|
807
|
+
const cdValues = headers.get('content-disposition');
|
|
808
|
+
if (cdValues && cdValues.length > 0) {
|
|
809
|
+
contentDisposition = this.parseContentDisposition(cdValues[0]);
|
|
810
|
+
}
|
|
811
|
+
// Parse Content-ID
|
|
812
|
+
let contentId;
|
|
813
|
+
const cidValues = headers.get('content-id');
|
|
814
|
+
if (cidValues && cidValues.length > 0) {
|
|
815
|
+
contentId = cidValues[0].trim();
|
|
816
|
+
}
|
|
817
|
+
// Parse Content-Description
|
|
818
|
+
let contentDescription;
|
|
819
|
+
const cdescValues = headers.get('content-description');
|
|
820
|
+
if (cdescValues && cdescValues.length > 0) {
|
|
821
|
+
contentDescription = cdescValues[0].trim();
|
|
822
|
+
}
|
|
823
|
+
// Check if this is a nested multipart
|
|
824
|
+
if (contentType.type === 'multipart') {
|
|
825
|
+
const nestedBoundary = contentType.parameters.get('boundary');
|
|
826
|
+
if (nestedBoundary) {
|
|
827
|
+
const bodyBytes = new TextEncoder().encode(bodyContent);
|
|
828
|
+
const nestedParts = this.parseMultipart(bodyBytes, nestedBoundary);
|
|
829
|
+
return {
|
|
830
|
+
contentType,
|
|
831
|
+
contentTransferEncoding,
|
|
832
|
+
contentDisposition,
|
|
833
|
+
contentId,
|
|
834
|
+
contentDescription,
|
|
835
|
+
parts: nestedParts,
|
|
836
|
+
size: bodyBytes.length,
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
// Decode body based on Content-Transfer-Encoding
|
|
841
|
+
const rawBodyBytes = new TextEncoder().encode(bodyContent);
|
|
842
|
+
const decodedBody = contentTransferEncoding
|
|
843
|
+
? this.parseBody(rawBodyBytes, contentType, contentTransferEncoding)
|
|
844
|
+
: rawBodyBytes;
|
|
845
|
+
return {
|
|
846
|
+
contentType,
|
|
847
|
+
contentTransferEncoding,
|
|
848
|
+
contentDisposition,
|
|
849
|
+
contentId,
|
|
850
|
+
contentDescription,
|
|
851
|
+
body: decodedBody,
|
|
852
|
+
size: decodedBody.length,
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* Parses a Content-Disposition header value into an IContentDisposition object.
|
|
857
|
+
*
|
|
858
|
+
* @param dispositionString - The Content-Disposition header value
|
|
859
|
+
* @returns The parsed IContentDisposition object
|
|
860
|
+
*/
|
|
861
|
+
parseContentDisposition(dispositionString) {
|
|
862
|
+
const trimmed = dispositionString.trim();
|
|
863
|
+
// Split on first semicolon to separate disposition type from parameters
|
|
864
|
+
const semicolonIndex = trimmed.indexOf(';');
|
|
865
|
+
const typePart = semicolonIndex >= 0
|
|
866
|
+
? trimmed.substring(0, semicolonIndex).trim().toLowerCase()
|
|
867
|
+
: trimmed.toLowerCase();
|
|
868
|
+
const paramsPart = semicolonIndex >= 0 ? trimmed.substring(semicolonIndex + 1).trim() : '';
|
|
869
|
+
const dispositionType = typePart === 'inline' ? 'inline' : 'attachment';
|
|
870
|
+
const parameters = new Map();
|
|
871
|
+
if (paramsPart) {
|
|
872
|
+
this.parseContentTypeParameters(paramsPart, parameters);
|
|
873
|
+
}
|
|
874
|
+
const result = {
|
|
875
|
+
type: dispositionType,
|
|
876
|
+
};
|
|
877
|
+
const filename = parameters.get('filename');
|
|
878
|
+
if (filename) {
|
|
879
|
+
result.filename = filename;
|
|
880
|
+
}
|
|
881
|
+
const creationDate = parameters.get('creation-date');
|
|
882
|
+
if (creationDate) {
|
|
883
|
+
const d = new Date(creationDate);
|
|
884
|
+
if (!isNaN(d.getTime())) {
|
|
885
|
+
result.creationDate = d;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
const modificationDate = parameters.get('modification-date');
|
|
889
|
+
if (modificationDate) {
|
|
890
|
+
const d = new Date(modificationDate);
|
|
891
|
+
if (!isNaN(d.getTime())) {
|
|
892
|
+
result.modificationDate = d;
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
const readDate = parameters.get('read-date');
|
|
896
|
+
if (readDate) {
|
|
897
|
+
const d = new Date(readDate);
|
|
898
|
+
if (!isNaN(d.getTime())) {
|
|
899
|
+
result.readDate = d;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
const size = parameters.get('size');
|
|
903
|
+
if (size) {
|
|
904
|
+
const s = parseInt(size, 10);
|
|
905
|
+
if (!isNaN(s)) {
|
|
906
|
+
result.size = s;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
return result;
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Escapes special regex characters in a string for use in a RegExp.
|
|
913
|
+
*
|
|
914
|
+
* @param str - The string to escape
|
|
915
|
+
* @returns The escaped string safe for use in RegExp
|
|
916
|
+
*/
|
|
917
|
+
escapeRegExp(str) {
|
|
918
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Parses a raw email (string or Uint8Array) into an IEmailMetadata object.
|
|
922
|
+
*
|
|
923
|
+
* Uses `PostalMime.parse()` as the core parsing engine, then converts
|
|
924
|
+
* postal-mime's Email type to the IEmailMetadata interface. Handles both
|
|
925
|
+
* CRLF and LF line endings (postal-mime handles this internally).
|
|
926
|
+
*
|
|
927
|
+
* @param rawEmail - The raw email as a string or Uint8Array
|
|
928
|
+
* @returns The parsed IEmailMetadata object
|
|
929
|
+
* @throws {EmailError} With PARSE_ERROR if parsing fails
|
|
930
|
+
*
|
|
931
|
+
* @see RFC 5322 - Internet Message Format
|
|
932
|
+
* @see Requirement 14.5 - Handle both CRLF and LF line endings
|
|
933
|
+
*
|
|
934
|
+
* @example
|
|
935
|
+
* ```typescript
|
|
936
|
+
* const parser = new EmailParser();
|
|
937
|
+
* const metadata = await parser.parse(rawEmailString);
|
|
938
|
+
* console.log(metadata.from.address); // "sender@example.com"
|
|
939
|
+
* console.log(metadata.subject); // "Hello World"
|
|
940
|
+
* ```
|
|
941
|
+
*/
|
|
942
|
+
async parse(rawEmail) {
|
|
943
|
+
if (!rawEmail ||
|
|
944
|
+
(typeof rawEmail === 'string' && rawEmail.trim().length === 0) ||
|
|
945
|
+
(rawEmail instanceof Uint8Array && rawEmail.length === 0)) {
|
|
946
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.PARSE_ERROR, 'Raw email input is empty', { input: typeof rawEmail });
|
|
947
|
+
}
|
|
948
|
+
let parsed;
|
|
949
|
+
try {
|
|
950
|
+
parsed = await postal_mime_1.default.parse(rawEmail);
|
|
951
|
+
}
|
|
952
|
+
catch (error) {
|
|
953
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.PARSE_ERROR, `Failed to parse email: ${error instanceof Error ? error.message : String(error)}`, { error: String(error) });
|
|
954
|
+
}
|
|
955
|
+
try {
|
|
956
|
+
return this.convertPostalEmailToMetadata(parsed);
|
|
957
|
+
}
|
|
958
|
+
catch (error) {
|
|
959
|
+
if (error instanceof emailError_1.EmailError) {
|
|
960
|
+
throw error;
|
|
961
|
+
}
|
|
962
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.PARSE_ERROR, `Failed to convert parsed email to metadata: ${error instanceof Error ? error.message : String(error)}`, { error: String(error) });
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Converts a postal-mime Email object to IEmailMetadata.
|
|
967
|
+
*
|
|
968
|
+
* @param email - The postal-mime parsed Email object
|
|
969
|
+
* @returns The converted IEmailMetadata object
|
|
970
|
+
*/
|
|
971
|
+
convertPostalEmailToMetadata(email) {
|
|
972
|
+
// Parse From address (required)
|
|
973
|
+
const from = this.convertPostalAddressToMailbox(email.from);
|
|
974
|
+
if (!from) {
|
|
975
|
+
throw new emailError_1.EmailError(emailErrorType_1.EmailErrorType.MISSING_REQUIRED_HEADER, 'From header is missing or invalid', {});
|
|
976
|
+
}
|
|
977
|
+
// Parse Sender (optional)
|
|
978
|
+
const sender = email.sender
|
|
979
|
+
? this.convertPostalAddressToMailbox(email.sender)
|
|
980
|
+
: undefined;
|
|
981
|
+
// Parse Reply-To (optional)
|
|
982
|
+
const replyTo = email.replyTo
|
|
983
|
+
? email.replyTo
|
|
984
|
+
.map((addr) => this.convertPostalAddressToMailbox(addr))
|
|
985
|
+
.filter((mb) => mb !== undefined)
|
|
986
|
+
: undefined;
|
|
987
|
+
// Parse To (default to empty array)
|
|
988
|
+
const to = email.to
|
|
989
|
+
? email.to.flatMap((addr) => this.convertPostalAddressToMailboxes(addr))
|
|
990
|
+
: [];
|
|
991
|
+
// Parse Cc (optional)
|
|
992
|
+
const cc = email.cc
|
|
993
|
+
? email.cc.flatMap((addr) => this.convertPostalAddressToMailboxes(addr))
|
|
994
|
+
: undefined;
|
|
995
|
+
// Parse Bcc (optional)
|
|
996
|
+
const bcc = email.bcc
|
|
997
|
+
? email.bcc.flatMap((addr) => this.convertPostalAddressToMailboxes(addr))
|
|
998
|
+
: undefined;
|
|
999
|
+
// Parse Message-ID
|
|
1000
|
+
const messageId = email.messageId ||
|
|
1001
|
+
`<${Date.now()}.${Math.random().toString(36).substring(2)}@parsed>`;
|
|
1002
|
+
// Parse In-Reply-To (optional)
|
|
1003
|
+
const inReplyTo = email.inReplyTo || undefined;
|
|
1004
|
+
// Parse References (optional) - postal-mime returns as a single string
|
|
1005
|
+
const references = email.references
|
|
1006
|
+
? this.parseMessageIdList(email.references).map((id) => id)
|
|
1007
|
+
: undefined;
|
|
1008
|
+
// Subject
|
|
1009
|
+
const subject = email.subject || undefined;
|
|
1010
|
+
// Parse Date
|
|
1011
|
+
const date = email.date ? new Date(email.date) : new Date();
|
|
1012
|
+
if (isNaN(date.getTime())) {
|
|
1013
|
+
// Fallback to current date if parsing fails
|
|
1014
|
+
date.setTime(Date.now());
|
|
1015
|
+
}
|
|
1016
|
+
// Parse Content-Type from headers
|
|
1017
|
+
const contentTypeHeader = this.findHeader(email.headers, 'content-type');
|
|
1018
|
+
let contentType;
|
|
1019
|
+
if (contentTypeHeader) {
|
|
1020
|
+
try {
|
|
1021
|
+
contentType = this.parseContentType(contentTypeHeader);
|
|
1022
|
+
}
|
|
1023
|
+
catch {
|
|
1024
|
+
contentType = (0, mimePart_1.createContentType)('text', 'plain', new Map([['charset', 'us-ascii']]));
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
else {
|
|
1028
|
+
contentType = (0, mimePart_1.createContentType)('text', 'plain', new Map([['charset', 'us-ascii']]));
|
|
1029
|
+
}
|
|
1030
|
+
// Parse Content-Transfer-Encoding from headers
|
|
1031
|
+
const cteHeader = this.findHeader(email.headers, 'content-transfer-encoding');
|
|
1032
|
+
let contentTransferEncoding;
|
|
1033
|
+
if (cteHeader) {
|
|
1034
|
+
const cteMap = {
|
|
1035
|
+
'7bit': mimePart_1.ContentTransferEncoding.SevenBit,
|
|
1036
|
+
'8bit': mimePart_1.ContentTransferEncoding.EightBit,
|
|
1037
|
+
binary: mimePart_1.ContentTransferEncoding.Binary,
|
|
1038
|
+
'quoted-printable': mimePart_1.ContentTransferEncoding.QuotedPrintable,
|
|
1039
|
+
base64: mimePart_1.ContentTransferEncoding.Base64,
|
|
1040
|
+
};
|
|
1041
|
+
contentTransferEncoding = cteMap[cteHeader.trim().toLowerCase()];
|
|
1042
|
+
}
|
|
1043
|
+
// Parse MIME-Version from headers (default to "1.0")
|
|
1044
|
+
const mimeVersion = this.findHeader(email.headers, 'mime-version') || '1.0';
|
|
1045
|
+
// Build custom headers map (non-standard headers)
|
|
1046
|
+
const customHeaders = this.extractCustomHeaders(email.headers);
|
|
1047
|
+
// Parse Comments from headers (optional, can appear multiple times)
|
|
1048
|
+
const commentsHeaders = this.findAllHeaders(email.headers, 'comments');
|
|
1049
|
+
const comments = commentsHeaders.length > 0 ? commentsHeaders : undefined;
|
|
1050
|
+
// Parse Keywords from headers (optional)
|
|
1051
|
+
const keywordsHeaders = this.findAllHeaders(email.headers, 'keywords');
|
|
1052
|
+
const keywords = keywordsHeaders.length > 0
|
|
1053
|
+
? keywordsHeaders.flatMap((kw) => kw
|
|
1054
|
+
.split(',')
|
|
1055
|
+
.map((k) => k.trim())
|
|
1056
|
+
.filter((k) => k.length > 0))
|
|
1057
|
+
: undefined;
|
|
1058
|
+
// Build MIME parts from text/html content and attachments
|
|
1059
|
+
const parts = this.buildMimeParts(email);
|
|
1060
|
+
// Convert attachments to IAttachmentMetadata[]
|
|
1061
|
+
const attachments = this.convertAttachments(email.attachments);
|
|
1062
|
+
// Build the IEmailMetadata object
|
|
1063
|
+
const now = new Date();
|
|
1064
|
+
const metadata = {
|
|
1065
|
+
// IBlockMetadata fields (defaults for parsed emails)
|
|
1066
|
+
blockId: messageId,
|
|
1067
|
+
createdAt: now,
|
|
1068
|
+
expiresAt: null,
|
|
1069
|
+
durabilityLevel: durabilityLevel_1.DurabilityLevel.Standard,
|
|
1070
|
+
parityBlockIds: [],
|
|
1071
|
+
accessCount: 0,
|
|
1072
|
+
lastAccessedAt: now,
|
|
1073
|
+
replicationStatus: replicationStatus_1.ReplicationStatus.Pending,
|
|
1074
|
+
targetReplicationFactor: 0,
|
|
1075
|
+
replicaNodeIds: [],
|
|
1076
|
+
size: 0,
|
|
1077
|
+
checksum: '',
|
|
1078
|
+
// IMessageMetadata fields (defaults for parsed emails)
|
|
1079
|
+
messageType: 'email',
|
|
1080
|
+
senderId: from.address,
|
|
1081
|
+
recipients: to.map((r) => r.address),
|
|
1082
|
+
priority: messagePriority_1.MessagePriority.NORMAL,
|
|
1083
|
+
deliveryStatus: new Map(),
|
|
1084
|
+
acknowledgments: new Map(),
|
|
1085
|
+
encryptionScheme: messageEncryptionScheme_1.MessageEncryptionScheme.NONE,
|
|
1086
|
+
isCBL: false,
|
|
1087
|
+
// IEmailMetadata fields
|
|
1088
|
+
from,
|
|
1089
|
+
sender,
|
|
1090
|
+
replyTo: replyTo && replyTo.length > 0 ? replyTo : undefined,
|
|
1091
|
+
to,
|
|
1092
|
+
cc: cc && cc.length > 0 ? cc : undefined,
|
|
1093
|
+
bcc: bcc && bcc.length > 0 ? bcc : undefined,
|
|
1094
|
+
messageId,
|
|
1095
|
+
inReplyTo,
|
|
1096
|
+
references: references && references.length > 0 ? references : undefined,
|
|
1097
|
+
subject,
|
|
1098
|
+
comments,
|
|
1099
|
+
keywords,
|
|
1100
|
+
date,
|
|
1101
|
+
mimeVersion,
|
|
1102
|
+
contentType,
|
|
1103
|
+
contentTransferEncoding,
|
|
1104
|
+
customHeaders,
|
|
1105
|
+
parts: parts.length > 0 ? parts : undefined,
|
|
1106
|
+
attachments: attachments.length > 0 ? attachments : undefined,
|
|
1107
|
+
deliveryReceipts: new Map(),
|
|
1108
|
+
readReceipts: new Map(),
|
|
1109
|
+
};
|
|
1110
|
+
return metadata;
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Converts a postal-mime Address to an IMailbox (single mailbox).
|
|
1114
|
+
* Returns undefined if the address cannot be converted.
|
|
1115
|
+
*/
|
|
1116
|
+
convertPostalAddressToMailbox(address) {
|
|
1117
|
+
if (!address) {
|
|
1118
|
+
return undefined;
|
|
1119
|
+
}
|
|
1120
|
+
// If it's a group address, return the first mailbox or undefined
|
|
1121
|
+
if (address.group) {
|
|
1122
|
+
if (address.group.length > 0) {
|
|
1123
|
+
return this.convertPostalMailboxToIMailbox(address.group[0]);
|
|
1124
|
+
}
|
|
1125
|
+
return undefined;
|
|
1126
|
+
}
|
|
1127
|
+
// It's a regular mailbox
|
|
1128
|
+
return this.convertPostalMailboxToIMailbox(address);
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Converts a postal-mime Address to an array of IMailbox objects.
|
|
1132
|
+
* Handles both individual mailboxes and group addresses.
|
|
1133
|
+
*/
|
|
1134
|
+
convertPostalAddressToMailboxes(address) {
|
|
1135
|
+
if (address.group) {
|
|
1136
|
+
return address.group
|
|
1137
|
+
.map((mb) => this.convertPostalMailboxToIMailbox(mb))
|
|
1138
|
+
.filter((mb) => mb !== undefined);
|
|
1139
|
+
}
|
|
1140
|
+
const mailbox = this.convertPostalMailboxToIMailbox(address);
|
|
1141
|
+
return mailbox ? [mailbox] : [];
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* Converts a postal-mime Mailbox to an IMailbox.
|
|
1145
|
+
*/
|
|
1146
|
+
convertPostalMailboxToIMailbox(mailbox) {
|
|
1147
|
+
if (!mailbox.address) {
|
|
1148
|
+
return undefined;
|
|
1149
|
+
}
|
|
1150
|
+
const atIndex = mailbox.address.lastIndexOf('@');
|
|
1151
|
+
if (atIndex <= 0) {
|
|
1152
|
+
return undefined;
|
|
1153
|
+
}
|
|
1154
|
+
const localPart = mailbox.address.substring(0, atIndex);
|
|
1155
|
+
const domain = mailbox.address.substring(atIndex + 1);
|
|
1156
|
+
return (0, emailAddress_1.createMailbox)(localPart, domain, mailbox.name || undefined);
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Finds the first header value matching the given key (case-insensitive).
|
|
1160
|
+
*/
|
|
1161
|
+
findHeader(headers, key) {
|
|
1162
|
+
const lowerKey = key.toLowerCase();
|
|
1163
|
+
const header = headers.find((h) => h.key.toLowerCase() === lowerKey);
|
|
1164
|
+
return header?.value;
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Finds all header values matching the given key (case-insensitive).
|
|
1168
|
+
*/
|
|
1169
|
+
findAllHeaders(headers, key) {
|
|
1170
|
+
const lowerKey = key.toLowerCase();
|
|
1171
|
+
return headers
|
|
1172
|
+
.filter((h) => h.key.toLowerCase() === lowerKey)
|
|
1173
|
+
.map((h) => h.value);
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Extracts custom/extension headers (X-* and other non-standard headers).
|
|
1177
|
+
* Standard RFC 5322 headers are excluded.
|
|
1178
|
+
*/
|
|
1179
|
+
extractCustomHeaders(headers) {
|
|
1180
|
+
const standardHeaders = new Set([
|
|
1181
|
+
'from',
|
|
1182
|
+
'sender',
|
|
1183
|
+
'reply-to',
|
|
1184
|
+
'to',
|
|
1185
|
+
'cc',
|
|
1186
|
+
'bcc',
|
|
1187
|
+
'message-id',
|
|
1188
|
+
'in-reply-to',
|
|
1189
|
+
'references',
|
|
1190
|
+
'subject',
|
|
1191
|
+
'comments',
|
|
1192
|
+
'keywords',
|
|
1193
|
+
'date',
|
|
1194
|
+
'mime-version',
|
|
1195
|
+
'content-type',
|
|
1196
|
+
'content-transfer-encoding',
|
|
1197
|
+
'content-disposition',
|
|
1198
|
+
'content-id',
|
|
1199
|
+
'content-description',
|
|
1200
|
+
'received',
|
|
1201
|
+
'return-path',
|
|
1202
|
+
'delivered-to',
|
|
1203
|
+
]);
|
|
1204
|
+
const customHeaders = new Map();
|
|
1205
|
+
for (const header of headers) {
|
|
1206
|
+
const lowerKey = header.key.toLowerCase();
|
|
1207
|
+
if (!standardHeaders.has(lowerKey)) {
|
|
1208
|
+
const existing = customHeaders.get(lowerKey);
|
|
1209
|
+
if (existing) {
|
|
1210
|
+
existing.push(header.value);
|
|
1211
|
+
}
|
|
1212
|
+
else {
|
|
1213
|
+
customHeaders.set(lowerKey, [header.value]);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
return customHeaders;
|
|
1218
|
+
}
|
|
1219
|
+
/**
|
|
1220
|
+
* Builds IMimePart[] from postal-mime's parsed email content.
|
|
1221
|
+
* Creates parts from text, html, and attachment content.
|
|
1222
|
+
*/
|
|
1223
|
+
buildMimeParts(email) {
|
|
1224
|
+
const parts = [];
|
|
1225
|
+
// Add text part if present
|
|
1226
|
+
if (email.text !== undefined && email.text !== null) {
|
|
1227
|
+
const textBytes = new TextEncoder().encode(email.text);
|
|
1228
|
+
parts.push({
|
|
1229
|
+
contentType: (0, mimePart_1.createContentType)('text', 'plain', new Map([['charset', 'utf-8']])),
|
|
1230
|
+
body: textBytes,
|
|
1231
|
+
size: textBytes.length,
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
// Add HTML part if present
|
|
1235
|
+
if (email.html !== undefined && email.html !== null) {
|
|
1236
|
+
const htmlBytes = new TextEncoder().encode(email.html);
|
|
1237
|
+
parts.push({
|
|
1238
|
+
contentType: (0, mimePart_1.createContentType)('text', 'html', new Map([['charset', 'utf-8']])),
|
|
1239
|
+
body: htmlBytes,
|
|
1240
|
+
size: htmlBytes.length,
|
|
1241
|
+
});
|
|
1242
|
+
}
|
|
1243
|
+
// Add inline attachments as parts
|
|
1244
|
+
for (const attachment of email.attachments) {
|
|
1245
|
+
if (attachment.disposition === 'inline' || attachment.related) {
|
|
1246
|
+
const contentBytes = this.convertAttachmentContent(attachment);
|
|
1247
|
+
const ct = this.parseAttachmentContentType(attachment.mimeType);
|
|
1248
|
+
const part = {
|
|
1249
|
+
contentType: ct,
|
|
1250
|
+
body: contentBytes,
|
|
1251
|
+
size: contentBytes.length,
|
|
1252
|
+
contentId: attachment.contentId || undefined,
|
|
1253
|
+
contentDescription: attachment.description || undefined,
|
|
1254
|
+
contentDisposition: {
|
|
1255
|
+
type: 'inline',
|
|
1256
|
+
filename: attachment.filename || undefined,
|
|
1257
|
+
},
|
|
1258
|
+
};
|
|
1259
|
+
parts.push(part);
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
return parts;
|
|
1263
|
+
}
|
|
1264
|
+
/**
|
|
1265
|
+
* Converts postal-mime attachments to IAttachmentMetadata[].
|
|
1266
|
+
*/
|
|
1267
|
+
convertAttachments(attachments) {
|
|
1268
|
+
return attachments
|
|
1269
|
+
.filter((att) => att.disposition !== 'inline' && !att.related)
|
|
1270
|
+
.map((att) => this.convertSingleAttachment(att));
|
|
1271
|
+
}
|
|
1272
|
+
/**
|
|
1273
|
+
* Converts a single postal-mime Attachment to IAttachmentMetadata.
|
|
1274
|
+
*/
|
|
1275
|
+
convertSingleAttachment(attachment) {
|
|
1276
|
+
const contentBytes = this.convertAttachmentContent(attachment);
|
|
1277
|
+
return {
|
|
1278
|
+
filename: attachment.filename || 'unnamed',
|
|
1279
|
+
mimeType: attachment.mimeType,
|
|
1280
|
+
size: contentBytes.length,
|
|
1281
|
+
contentId: attachment.contentId || undefined,
|
|
1282
|
+
cblMagnetUrl: '', // Will be populated when stored in CBL
|
|
1283
|
+
blockIds: [], // Will be populated when stored in CBL
|
|
1284
|
+
checksum: '', // Will be calculated when stored
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Converts postal-mime attachment content to Uint8Array.
|
|
1289
|
+
*/
|
|
1290
|
+
convertAttachmentContent(attachment) {
|
|
1291
|
+
if (attachment.content instanceof ArrayBuffer) {
|
|
1292
|
+
return new Uint8Array(attachment.content);
|
|
1293
|
+
}
|
|
1294
|
+
if (typeof attachment.content === 'string') {
|
|
1295
|
+
// Content is a string (possibly base64 encoded)
|
|
1296
|
+
if (attachment.encoding === 'base64') {
|
|
1297
|
+
return new Uint8Array(Buffer.from(attachment.content, 'base64'));
|
|
1298
|
+
}
|
|
1299
|
+
return new TextEncoder().encode(attachment.content);
|
|
1300
|
+
}
|
|
1301
|
+
return new Uint8Array(0);
|
|
1302
|
+
}
|
|
1303
|
+
/**
|
|
1304
|
+
* Parses an attachment's MIME type string into an IContentType.
|
|
1305
|
+
*/
|
|
1306
|
+
parseAttachmentContentType(mimeType) {
|
|
1307
|
+
try {
|
|
1308
|
+
return this.parseContentType(mimeType);
|
|
1309
|
+
}
|
|
1310
|
+
catch {
|
|
1311
|
+
return (0, mimePart_1.createContentType)('application', 'octet-stream');
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
exports.EmailParser = EmailParser;
|
|
1316
|
+
//# sourceMappingURL=emailParser.js.map
|