@rapidmx/restapi 0.1.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/LICENSE +382 -0
- package/README.md +50 -0
- package/dist/lib/blob/BlobStore.js +6 -0
- package/dist/lib/blob/BlobStore.js.map +1 -0
- package/dist/lib/blob/LocalFsBlobStore.js +101 -0
- package/dist/lib/blob/LocalFsBlobStore.js.map +1 -0
- package/dist/lib/blob/index.js +7 -0
- package/dist/lib/blob/index.js.map +1 -0
- package/dist/lib/index.js +12 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/jobs/AttachmentExtractionJob.js +124 -0
- package/dist/lib/jobs/AttachmentExtractionJob.js.map +1 -0
- package/dist/lib/jobs/CalendarReminderJob.js +132 -0
- package/dist/lib/jobs/CalendarReminderJob.js.map +1 -0
- package/dist/lib/jobs/EasDeviceStateCleanupJob.js +101 -0
- package/dist/lib/jobs/EasDeviceStateCleanupJob.js.map +1 -0
- package/dist/lib/jobs/ExternalShareExpirationJob.js +117 -0
- package/dist/lib/jobs/ExternalShareExpirationJob.js.map +1 -0
- package/dist/lib/jobs/MailboxQuotaRecalcJob.js +163 -0
- package/dist/lib/jobs/MailboxQuotaRecalcJob.js.map +1 -0
- package/dist/lib/jobs/MeetingSchedulingJob.js +106 -0
- package/dist/lib/jobs/MeetingSchedulingJob.js.map +1 -0
- package/dist/lib/jobs/QuarantineRetentionJob.js +97 -0
- package/dist/lib/jobs/QuarantineRetentionJob.js.map +1 -0
- package/dist/lib/jobs/ScanQueueJob.js +223 -0
- package/dist/lib/jobs/ScanQueueJob.js.map +1 -0
- package/dist/lib/jobs/SearchIndexJob.js +146 -0
- package/dist/lib/jobs/SearchIndexJob.js.map +1 -0
- package/dist/lib/jobs/index.js +10 -0
- package/dist/lib/jobs/index.js.map +1 -0
- package/dist/lib/jobs/mongo/AttachmentExtractionJobMongo.js +14 -0
- package/dist/lib/jobs/mongo/AttachmentExtractionJobMongo.js.map +1 -0
- package/dist/lib/jobs/mongo/CalendarReminderJobMongo.js +13 -0
- package/dist/lib/jobs/mongo/CalendarReminderJobMongo.js.map +1 -0
- package/dist/lib/jobs/mongo/EasDeviceStateCleanupJobMongo.js +13 -0
- package/dist/lib/jobs/mongo/EasDeviceStateCleanupJobMongo.js.map +1 -0
- package/dist/lib/jobs/mongo/ExternalShareExpirationJobMongo.js +13 -0
- package/dist/lib/jobs/mongo/ExternalShareExpirationJobMongo.js.map +1 -0
- package/dist/lib/jobs/mongo/MailboxQuotaRecalcJobMongo.js +15 -0
- package/dist/lib/jobs/mongo/MailboxQuotaRecalcJobMongo.js.map +1 -0
- package/dist/lib/jobs/mongo/MeetingSchedulingJobMongo.js +13 -0
- package/dist/lib/jobs/mongo/MeetingSchedulingJobMongo.js.map +1 -0
- package/dist/lib/jobs/mongo/QuarantineRetentionJobMongo.js +13 -0
- package/dist/lib/jobs/mongo/QuarantineRetentionJobMongo.js.map +1 -0
- package/dist/lib/jobs/mongo/ScanQueueJobMongo.js +18 -0
- package/dist/lib/jobs/mongo/ScanQueueJobMongo.js.map +1 -0
- package/dist/lib/jobs/mongo/SearchIndexJobMongo.js +14 -0
- package/dist/lib/jobs/mongo/SearchIndexJobMongo.js.map +1 -0
- package/dist/lib/jobs/mongo/index.js +10 -0
- package/dist/lib/jobs/mongo/index.js.map +1 -0
- package/dist/lib/jobs/mongo.js +2 -0
- package/dist/lib/jobs/mongo.js.map +1 -0
- package/dist/lib/jobs/sql/AttachmentExtractionJobSQL.js +14 -0
- package/dist/lib/jobs/sql/AttachmentExtractionJobSQL.js.map +1 -0
- package/dist/lib/jobs/sql/CalendarReminderJobSQL.js +13 -0
- package/dist/lib/jobs/sql/CalendarReminderJobSQL.js.map +1 -0
- package/dist/lib/jobs/sql/EasDeviceStateCleanupJobSQL.js +13 -0
- package/dist/lib/jobs/sql/EasDeviceStateCleanupJobSQL.js.map +1 -0
- package/dist/lib/jobs/sql/ExternalShareExpirationJobSQL.js +13 -0
- package/dist/lib/jobs/sql/ExternalShareExpirationJobSQL.js.map +1 -0
- package/dist/lib/jobs/sql/MailboxQuotaRecalcJobSQL.js +15 -0
- package/dist/lib/jobs/sql/MailboxQuotaRecalcJobSQL.js.map +1 -0
- package/dist/lib/jobs/sql/MeetingSchedulingJobSQL.js +13 -0
- package/dist/lib/jobs/sql/MeetingSchedulingJobSQL.js.map +1 -0
- package/dist/lib/jobs/sql/QuarantineRetentionJobSQL.js +13 -0
- package/dist/lib/jobs/sql/QuarantineRetentionJobSQL.js.map +1 -0
- package/dist/lib/jobs/sql/ScanQueueJobSQL.js +18 -0
- package/dist/lib/jobs/sql/ScanQueueJobSQL.js.map +1 -0
- package/dist/lib/jobs/sql/SearchIndexJobSQL.js +14 -0
- package/dist/lib/jobs/sql/SearchIndexJobSQL.js.map +1 -0
- package/dist/lib/jobs/sql/index.js +10 -0
- package/dist/lib/jobs/sql/index.js.map +1 -0
- package/dist/lib/jobs/sql.js +2 -0
- package/dist/lib/jobs/sql.js.map +1 -0
- package/dist/lib/models/index.js +2 -0
- package/dist/lib/models/index.js.map +1 -0
- package/dist/lib/models/mongo/AttachmentMongo.js +129 -0
- package/dist/lib/models/mongo/AttachmentMongo.js.map +1 -0
- package/dist/lib/models/mongo/CalendarEventMongo.js +172 -0
- package/dist/lib/models/mongo/CalendarEventMongo.js.map +1 -0
- package/dist/lib/models/mongo/CalendarShareLinkMongo.js +85 -0
- package/dist/lib/models/mongo/CalendarShareLinkMongo.js.map +1 -0
- package/dist/lib/models/mongo/ContactListMongo.js +60 -0
- package/dist/lib/models/mongo/ContactListMongo.js.map +1 -0
- package/dist/lib/models/mongo/ContactMongo.js +148 -0
- package/dist/lib/models/mongo/ContactMongo.js.map +1 -0
- package/dist/lib/models/mongo/DeviceSyncStateMongo.js +97 -0
- package/dist/lib/models/mongo/DeviceSyncStateMongo.js.map +1 -0
- package/dist/lib/models/mongo/FolderMongo.js +102 -0
- package/dist/lib/models/mongo/FolderMongo.js.map +1 -0
- package/dist/lib/models/mongo/IngestQueueEntryMongo.js +93 -0
- package/dist/lib/models/mongo/IngestQueueEntryMongo.js.map +1 -0
- package/dist/lib/models/mongo/MailboxMongo.js +105 -0
- package/dist/lib/models/mongo/MailboxMongo.js.map +1 -0
- package/dist/lib/models/mongo/MessageMongo.js +180 -0
- package/dist/lib/models/mongo/MessageMongo.js.map +1 -0
- package/dist/lib/models/mongo/NoteMongo.js +83 -0
- package/dist/lib/models/mongo/NoteMongo.js.map +1 -0
- package/dist/lib/models/mongo/QuarantineEntryMongo.js +99 -0
- package/dist/lib/models/mongo/QuarantineEntryMongo.js.map +1 -0
- package/dist/lib/models/mongo/ScanResultMongo.js +112 -0
- package/dist/lib/models/mongo/ScanResultMongo.js.map +1 -0
- package/dist/lib/models/mongo/SearchIndexStateMongo.js +83 -0
- package/dist/lib/models/mongo/SearchIndexStateMongo.js.map +1 -0
- package/dist/lib/models/mongo/TaskMongo.js +105 -0
- package/dist/lib/models/mongo/TaskMongo.js.map +1 -0
- package/dist/lib/models/mongo/index.js +16 -0
- package/dist/lib/models/mongo/index.js.map +1 -0
- package/dist/lib/models/mongo.js +2 -0
- package/dist/lib/models/mongo.js.map +1 -0
- package/dist/lib/models/sql/AttachmentSQL.js +129 -0
- package/dist/lib/models/sql/AttachmentSQL.js.map +1 -0
- package/dist/lib/models/sql/CalendarEventSQL.js +176 -0
- package/dist/lib/models/sql/CalendarEventSQL.js.map +1 -0
- package/dist/lib/models/sql/CalendarShareLinkSQL.js +85 -0
- package/dist/lib/models/sql/CalendarShareLinkSQL.js.map +1 -0
- package/dist/lib/models/sql/ContactListSQL.js +60 -0
- package/dist/lib/models/sql/ContactListSQL.js.map +1 -0
- package/dist/lib/models/sql/ContactSQL.js +148 -0
- package/dist/lib/models/sql/ContactSQL.js.map +1 -0
- package/dist/lib/models/sql/DeviceSyncStateSQL.js +97 -0
- package/dist/lib/models/sql/DeviceSyncStateSQL.js.map +1 -0
- package/dist/lib/models/sql/FolderSQL.js +106 -0
- package/dist/lib/models/sql/FolderSQL.js.map +1 -0
- package/dist/lib/models/sql/IngestQueueEntrySQL.js +97 -0
- package/dist/lib/models/sql/IngestQueueEntrySQL.js.map +1 -0
- package/dist/lib/models/sql/MailboxSQL.js +105 -0
- package/dist/lib/models/sql/MailboxSQL.js.map +1 -0
- package/dist/lib/models/sql/MessageSQL.js +184 -0
- package/dist/lib/models/sql/MessageSQL.js.map +1 -0
- package/dist/lib/models/sql/NoteSQL.js +83 -0
- package/dist/lib/models/sql/NoteSQL.js.map +1 -0
- package/dist/lib/models/sql/QuarantineEntrySQL.js +103 -0
- package/dist/lib/models/sql/QuarantineEntrySQL.js.map +1 -0
- package/dist/lib/models/sql/ScanResultSQL.js +116 -0
- package/dist/lib/models/sql/ScanResultSQL.js.map +1 -0
- package/dist/lib/models/sql/SearchIndexStateSQL.js +83 -0
- package/dist/lib/models/sql/SearchIndexStateSQL.js.map +1 -0
- package/dist/lib/models/sql/TaskSQL.js +109 -0
- package/dist/lib/models/sql/TaskSQL.js.map +1 -0
- package/dist/lib/models/sql/index.js +16 -0
- package/dist/lib/models/sql/index.js.map +1 -0
- package/dist/lib/models/sql.js +2 -0
- package/dist/lib/models/sql.js.map +1 -0
- package/dist/lib/models/types.js +108 -0
- package/dist/lib/models/types.js.map +1 -0
- package/dist/lib/mongo.js +8 -0
- package/dist/lib/mongo.js.map +1 -0
- package/dist/lib/push/MailPushRoute.js +42 -0
- package/dist/lib/push/MailPushRoute.js.map +1 -0
- package/dist/lib/push/index.js +6 -0
- package/dist/lib/push/index.js.map +1 -0
- package/dist/lib/routes/BaseAttachmentRoute.js +142 -0
- package/dist/lib/routes/BaseAttachmentRoute.js.map +1 -0
- package/dist/lib/routes/BaseCalendarShareLinkRoute.js +123 -0
- package/dist/lib/routes/BaseCalendarShareLinkRoute.js.map +1 -0
- package/dist/lib/routes/BaseFolderRoute.js +192 -0
- package/dist/lib/routes/BaseFolderRoute.js.map +1 -0
- package/dist/lib/routes/BaseMailIngestRoute.js +179 -0
- package/dist/lib/routes/BaseMailIngestRoute.js.map +1 -0
- package/dist/lib/routes/BaseMailboxRoute.js +187 -0
- package/dist/lib/routes/BaseMailboxRoute.js.map +1 -0
- package/dist/lib/routes/BaseMessageRoute.js +142 -0
- package/dist/lib/routes/BaseMessageRoute.js.map +1 -0
- package/dist/lib/routes/BaseScopedChildRoute.js +348 -0
- package/dist/lib/routes/BaseScopedChildRoute.js.map +1 -0
- package/dist/lib/routes/BaseSearchRoute.js +91 -0
- package/dist/lib/routes/BaseSearchRoute.js.map +1 -0
- package/dist/lib/routes/index.js +13 -0
- package/dist/lib/routes/index.js.map +1 -0
- package/dist/lib/routes/mongo/AttachmentRouteMongo.js +26 -0
- package/dist/lib/routes/mongo/AttachmentRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/CalendarEventRouteMongo.js +27 -0
- package/dist/lib/routes/mongo/CalendarEventRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/CalendarShareLinkRouteMongo.js +26 -0
- package/dist/lib/routes/mongo/CalendarShareLinkRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/ContactListRouteMongo.js +26 -0
- package/dist/lib/routes/mongo/ContactListRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/ContactRouteMongo.js +27 -0
- package/dist/lib/routes/mongo/ContactRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/FolderRouteMongo.js +26 -0
- package/dist/lib/routes/mongo/FolderRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/IngestQueueRouteMongo.js +33 -0
- package/dist/lib/routes/mongo/IngestQueueRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/MailIngestRouteMongo.js +14 -0
- package/dist/lib/routes/mongo/MailIngestRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/MailboxRouteMongo.js +39 -0
- package/dist/lib/routes/mongo/MailboxRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/MessageRouteMongo.js +27 -0
- package/dist/lib/routes/mongo/MessageRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/NoteRouteMongo.js +26 -0
- package/dist/lib/routes/mongo/NoteRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/QuarantineRouteMongo.js +35 -0
- package/dist/lib/routes/mongo/QuarantineRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/SearchRouteMongo.js +13 -0
- package/dist/lib/routes/mongo/SearchRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/TaskRouteMongo.js +27 -0
- package/dist/lib/routes/mongo/TaskRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/index.js +15 -0
- package/dist/lib/routes/mongo/index.js.map +1 -0
- package/dist/lib/routes/mongo.js +2 -0
- package/dist/lib/routes/mongo.js.map +1 -0
- package/dist/lib/routes/sql/AttachmentRouteSQL.js +26 -0
- package/dist/lib/routes/sql/AttachmentRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/CalendarEventRouteSQL.js +27 -0
- package/dist/lib/routes/sql/CalendarEventRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/CalendarShareLinkRouteSQL.js +26 -0
- package/dist/lib/routes/sql/CalendarShareLinkRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/ContactListRouteSQL.js +26 -0
- package/dist/lib/routes/sql/ContactListRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/ContactRouteSQL.js +27 -0
- package/dist/lib/routes/sql/ContactRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/FolderRouteSQL.js +26 -0
- package/dist/lib/routes/sql/FolderRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/IngestQueueRouteSQL.js +29 -0
- package/dist/lib/routes/sql/IngestQueueRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/MailIngestRouteSQL.js +35 -0
- package/dist/lib/routes/sql/MailIngestRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/MailboxRouteSQL.js +64 -0
- package/dist/lib/routes/sql/MailboxRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/MessageRouteSQL.js +27 -0
- package/dist/lib/routes/sql/MessageRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/NoteRouteSQL.js +26 -0
- package/dist/lib/routes/sql/NoteRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/QuarantineRouteSQL.js +29 -0
- package/dist/lib/routes/sql/QuarantineRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/SearchRouteSQL.js +13 -0
- package/dist/lib/routes/sql/SearchRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/TaskRouteSQL.js +27 -0
- package/dist/lib/routes/sql/TaskRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/index.js +15 -0
- package/dist/lib/routes/sql/index.js.map +1 -0
- package/dist/lib/routes/sql.js +2 -0
- package/dist/lib/routes/sql.js.map +1 -0
- package/dist/lib/scan/AvScanProvider.js +2 -0
- package/dist/lib/scan/AvScanProvider.js.map +1 -0
- package/dist/lib/scan/ClamAvScanProvider.js +112 -0
- package/dist/lib/scan/ClamAvScanProvider.js.map +1 -0
- package/dist/lib/scan/RspamdSpamScanProvider.js +100 -0
- package/dist/lib/scan/RspamdSpamScanProvider.js.map +1 -0
- package/dist/lib/scan/ScanPipeline.js +118 -0
- package/dist/lib/scan/ScanPipeline.js.map +1 -0
- package/dist/lib/scan/SpamScanProvider.js +2 -0
- package/dist/lib/scan/SpamScanProvider.js.map +1 -0
- package/dist/lib/scan/index.js +10 -0
- package/dist/lib/scan/index.js.map +1 -0
- package/dist/lib/search/MongoTextSearchProvider.js +116 -0
- package/dist/lib/search/MongoTextSearchProvider.js.map +1 -0
- package/dist/lib/search/OpenSearchProvider.js +156 -0
- package/dist/lib/search/OpenSearchProvider.js.map +1 -0
- package/dist/lib/search/PostgresFullTextSearchProvider.js +139 -0
- package/dist/lib/search/PostgresFullTextSearchProvider.js.map +1 -0
- package/dist/lib/search/SearchProvider.js +6 -0
- package/dist/lib/search/SearchProvider.js.map +1 -0
- package/dist/lib/search/extraction/DocxTextExtractor.js +27 -0
- package/dist/lib/search/extraction/DocxTextExtractor.js.map +1 -0
- package/dist/lib/search/extraction/ExtractorRegistry.js +82 -0
- package/dist/lib/search/extraction/ExtractorRegistry.js.map +1 -0
- package/dist/lib/search/extraction/HtmlTextExtractor.js +20 -0
- package/dist/lib/search/extraction/HtmlTextExtractor.js.map +1 -0
- package/dist/lib/search/extraction/PdfTextExtractor.js +22 -0
- package/dist/lib/search/extraction/PdfTextExtractor.js.map +1 -0
- package/dist/lib/search/extraction/PlainTextExtractor.js +14 -0
- package/dist/lib/search/extraction/PlainTextExtractor.js.map +1 -0
- package/dist/lib/search/extraction/TextExtractor.js +6 -0
- package/dist/lib/search/extraction/TextExtractor.js.map +1 -0
- package/dist/lib/search/index.js +15 -0
- package/dist/lib/search/index.js.map +1 -0
- package/dist/lib/sql.js +8 -0
- package/dist/lib/sql.js.map +1 -0
- package/dist/lib/transport/MTAIngestAdapter.js +30 -0
- package/dist/lib/transport/MTAIngestAdapter.js.map +1 -0
- package/dist/lib/transport/MailTransport.js +6 -0
- package/dist/lib/transport/MailTransport.js.map +1 -0
- package/dist/lib/transport/PostfixSendmailTransport.js +61 -0
- package/dist/lib/transport/PostfixSendmailTransport.js.map +1 -0
- package/dist/lib/transport/index.js +8 -0
- package/dist/lib/transport/index.js.map +1 -0
- package/dist/lib/util/FolderUtils.js +50 -0
- package/dist/lib/util/FolderUtils.js.map +1 -0
- package/dist/lib/util/MailSendUtils.js +36 -0
- package/dist/lib/util/MailSendUtils.js.map +1 -0
- package/dist/lib/util/MailboxScopeUtils.js +23 -0
- package/dist/lib/util/MailboxScopeUtils.js.map +1 -0
- package/dist/lib/util/OptionalDeps.js +23 -0
- package/dist/lib/util/OptionalDeps.js.map +1 -0
- package/dist/lib/util/RecoverableRepoUtils.js +42 -0
- package/dist/lib/util/RecoverableRepoUtils.js.map +1 -0
- package/dist/lib/util/index.js +17 -0
- package/dist/lib/util/index.js.map +1 -0
- package/dist/types/blob/BlobStore.d.ts +54 -0
- package/dist/types/blob/LocalFsBlobStore.d.ts +23 -0
- package/dist/types/blob/index.d.ts +2 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/jobs/AttachmentExtractionJob.d.ts +34 -0
- package/dist/types/jobs/CalendarReminderJob.d.ts +37 -0
- package/dist/types/jobs/EasDeviceStateCleanupJob.d.ts +26 -0
- package/dist/types/jobs/ExternalShareExpirationJob.d.ts +34 -0
- package/dist/types/jobs/MailboxQuotaRecalcJob.d.ts +44 -0
- package/dist/types/jobs/MeetingSchedulingJob.d.ts +32 -0
- package/dist/types/jobs/QuarantineRetentionJob.d.ts +27 -0
- package/dist/types/jobs/ScanQueueJob.d.ts +41 -0
- package/dist/types/jobs/SearchIndexJob.d.ts +37 -0
- package/dist/types/jobs/index.d.ts +9 -0
- package/dist/types/jobs/mongo/AttachmentExtractionJobMongo.d.ts +6 -0
- package/dist/types/jobs/mongo/CalendarReminderJobMongo.d.ts +5 -0
- package/dist/types/jobs/mongo/EasDeviceStateCleanupJobMongo.d.ts +5 -0
- package/dist/types/jobs/mongo/ExternalShareExpirationJobMongo.d.ts +5 -0
- package/dist/types/jobs/mongo/MailboxQuotaRecalcJobMongo.d.ts +7 -0
- package/dist/types/jobs/mongo/MeetingSchedulingJobMongo.d.ts +5 -0
- package/dist/types/jobs/mongo/QuarantineRetentionJobMongo.d.ts +5 -0
- package/dist/types/jobs/mongo/ScanQueueJobMongo.d.ts +10 -0
- package/dist/types/jobs/mongo/SearchIndexJobMongo.d.ts +6 -0
- package/dist/types/jobs/mongo/index.d.ts +9 -0
- package/dist/types/jobs/mongo.d.ts +1 -0
- package/dist/types/jobs/sql/AttachmentExtractionJobSQL.d.ts +6 -0
- package/dist/types/jobs/sql/CalendarReminderJobSQL.d.ts +5 -0
- package/dist/types/jobs/sql/EasDeviceStateCleanupJobSQL.d.ts +5 -0
- package/dist/types/jobs/sql/ExternalShareExpirationJobSQL.d.ts +5 -0
- package/dist/types/jobs/sql/MailboxQuotaRecalcJobSQL.d.ts +7 -0
- package/dist/types/jobs/sql/MeetingSchedulingJobSQL.d.ts +5 -0
- package/dist/types/jobs/sql/QuarantineRetentionJobSQL.d.ts +5 -0
- package/dist/types/jobs/sql/ScanQueueJobSQL.d.ts +10 -0
- package/dist/types/jobs/sql/SearchIndexJobSQL.d.ts +6 -0
- package/dist/types/jobs/sql/index.d.ts +9 -0
- package/dist/types/jobs/sql.d.ts +1 -0
- package/dist/types/models/index.d.ts +1 -0
- package/dist/types/models/mongo/AttachmentMongo.d.ts +22 -0
- package/dist/types/models/mongo/CalendarEventMongo.d.ts +28 -0
- package/dist/types/models/mongo/CalendarShareLinkMongo.d.ts +16 -0
- package/dist/types/models/mongo/ContactListMongo.d.ts +13 -0
- package/dist/types/models/mongo/ContactMongo.d.ts +25 -0
- package/dist/types/models/mongo/DeviceSyncStateMongo.d.ts +18 -0
- package/dist/types/models/mongo/FolderMongo.d.ts +18 -0
- package/dist/types/models/mongo/IngestQueueEntryMongo.d.ts +17 -0
- package/dist/types/models/mongo/MailboxMongo.d.ts +18 -0
- package/dist/types/models/mongo/MessageMongo.d.ts +29 -0
- package/dist/types/models/mongo/NoteMongo.d.ts +16 -0
- package/dist/types/models/mongo/QuarantineEntryMongo.d.ts +18 -0
- package/dist/types/models/mongo/ScanResultMongo.d.ts +23 -0
- package/dist/types/models/mongo/SearchIndexStateMongo.d.ts +16 -0
- package/dist/types/models/mongo/TaskMongo.d.ts +19 -0
- package/dist/types/models/mongo/index.d.ts +15 -0
- package/dist/types/models/mongo.d.ts +1 -0
- package/dist/types/models/sql/AttachmentSQL.d.ts +22 -0
- package/dist/types/models/sql/CalendarEventSQL.d.ts +28 -0
- package/dist/types/models/sql/CalendarShareLinkSQL.d.ts +16 -0
- package/dist/types/models/sql/ContactListSQL.d.ts +13 -0
- package/dist/types/models/sql/ContactSQL.d.ts +25 -0
- package/dist/types/models/sql/DeviceSyncStateSQL.d.ts +18 -0
- package/dist/types/models/sql/FolderSQL.d.ts +18 -0
- package/dist/types/models/sql/IngestQueueEntrySQL.d.ts +17 -0
- package/dist/types/models/sql/MailboxSQL.d.ts +18 -0
- package/dist/types/models/sql/MessageSQL.d.ts +29 -0
- package/dist/types/models/sql/NoteSQL.d.ts +16 -0
- package/dist/types/models/sql/QuarantineEntrySQL.d.ts +18 -0
- package/dist/types/models/sql/ScanResultSQL.d.ts +23 -0
- package/dist/types/models/sql/SearchIndexStateSQL.d.ts +16 -0
- package/dist/types/models/sql/TaskSQL.d.ts +19 -0
- package/dist/types/models/sql/index.d.ts +15 -0
- package/dist/types/models/sql.d.ts +1 -0
- package/dist/types/models/types.d.ts +541 -0
- package/dist/types/mongo.d.ts +3 -0
- package/dist/types/push/MailPushRoute.d.ts +37 -0
- package/dist/types/push/index.d.ts +1 -0
- package/dist/types/routes/BaseAttachmentRoute.d.ts +24 -0
- package/dist/types/routes/BaseCalendarShareLinkRoute.d.ts +35 -0
- package/dist/types/routes/BaseFolderRoute.d.ts +58 -0
- package/dist/types/routes/BaseMailIngestRoute.d.ts +47 -0
- package/dist/types/routes/BaseMailboxRoute.d.ts +60 -0
- package/dist/types/routes/BaseMessageRoute.d.ts +27 -0
- package/dist/types/routes/BaseScopedChildRoute.d.ts +61 -0
- package/dist/types/routes/BaseSearchRoute.d.ts +23 -0
- package/dist/types/routes/index.d.ts +8 -0
- package/dist/types/routes/mongo/AttachmentRouteMongo.d.ts +6 -0
- package/dist/types/routes/mongo/CalendarEventRouteMongo.d.ts +6 -0
- package/dist/types/routes/mongo/CalendarShareLinkRouteMongo.d.ts +6 -0
- package/dist/types/routes/mongo/ContactListRouteMongo.d.ts +6 -0
- package/dist/types/routes/mongo/ContactRouteMongo.d.ts +6 -0
- package/dist/types/routes/mongo/FolderRouteMongo.d.ts +5 -0
- package/dist/types/routes/mongo/IngestQueueRouteMongo.d.ts +13 -0
- package/dist/types/routes/mongo/MailIngestRouteMongo.d.ts +6 -0
- package/dist/types/routes/mongo/MailboxRouteMongo.d.ts +8 -0
- package/dist/types/routes/mongo/MessageRouteMongo.d.ts +6 -0
- package/dist/types/routes/mongo/NoteRouteMongo.d.ts +6 -0
- package/dist/types/routes/mongo/QuarantineRouteMongo.d.ts +15 -0
- package/dist/types/routes/mongo/SearchRouteMongo.d.ts +5 -0
- package/dist/types/routes/mongo/TaskRouteMongo.d.ts +6 -0
- package/dist/types/routes/mongo/index.d.ts +14 -0
- package/dist/types/routes/mongo.d.ts +1 -0
- package/dist/types/routes/sql/AttachmentRouteSQL.d.ts +6 -0
- package/dist/types/routes/sql/CalendarEventRouteSQL.d.ts +6 -0
- package/dist/types/routes/sql/CalendarShareLinkRouteSQL.d.ts +6 -0
- package/dist/types/routes/sql/ContactListRouteSQL.d.ts +6 -0
- package/dist/types/routes/sql/ContactRouteSQL.d.ts +6 -0
- package/dist/types/routes/sql/FolderRouteSQL.d.ts +5 -0
- package/dist/types/routes/sql/IngestQueueRouteSQL.d.ts +9 -0
- package/dist/types/routes/sql/MailIngestRouteSQL.d.ts +23 -0
- package/dist/types/routes/sql/MailboxRouteSQL.d.ts +22 -0
- package/dist/types/routes/sql/MessageRouteSQL.d.ts +6 -0
- package/dist/types/routes/sql/NoteRouteSQL.d.ts +6 -0
- package/dist/types/routes/sql/QuarantineRouteSQL.d.ts +9 -0
- package/dist/types/routes/sql/SearchRouteSQL.d.ts +5 -0
- package/dist/types/routes/sql/TaskRouteSQL.d.ts +6 -0
- package/dist/types/routes/sql/index.d.ts +14 -0
- package/dist/types/routes/sql.d.ts +1 -0
- package/dist/types/scan/AvScanProvider.d.ts +22 -0
- package/dist/types/scan/ClamAvScanProvider.d.ts +17 -0
- package/dist/types/scan/RspamdSpamScanProvider.d.ts +16 -0
- package/dist/types/scan/ScanPipeline.d.ts +53 -0
- package/dist/types/scan/SpamScanProvider.d.ts +29 -0
- package/dist/types/scan/index.d.ts +5 -0
- package/dist/types/search/MongoTextSearchProvider.d.ts +22 -0
- package/dist/types/search/OpenSearchProvider.d.ts +24 -0
- package/dist/types/search/PostgresFullTextSearchProvider.d.ts +21 -0
- package/dist/types/search/SearchProvider.d.ts +62 -0
- package/dist/types/search/extraction/DocxTextExtractor.d.ts +14 -0
- package/dist/types/search/extraction/ExtractorRegistry.d.ts +19 -0
- package/dist/types/search/extraction/HtmlTextExtractor.d.ts +11 -0
- package/dist/types/search/extraction/PdfTextExtractor.d.ts +10 -0
- package/dist/types/search/extraction/PlainTextExtractor.d.ts +10 -0
- package/dist/types/search/extraction/TextExtractor.d.ts +17 -0
- package/dist/types/search/index.d.ts +10 -0
- package/dist/types/sql.d.ts +3 -0
- package/dist/types/transport/MTAIngestAdapter.d.ts +25 -0
- package/dist/types/transport/MailTransport.d.ts +29 -0
- package/dist/types/transport/PostfixSendmailTransport.d.ts +15 -0
- package/dist/types/transport/index.d.ts +3 -0
- package/dist/types/util/FolderUtils.d.ts +15 -0
- package/dist/types/util/MailSendUtils.d.ts +19 -0
- package/dist/types/util/MailboxScopeUtils.d.ts +19 -0
- package/dist/types/util/OptionalDeps.d.ts +9 -0
- package/dist/types/util/RecoverableRepoUtils.d.ts +24 -0
- package/dist/types/util/index.d.ts +12 -0
- package/package.json +122 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
14
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
15
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
16
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
17
|
+
import { ApiError, ObjectDecorators } from "@rapidrest/core";
|
|
18
|
+
import { ACLAction, ApiErrorMessages, ApiErrors, DocDecorators, RouteDecorators, } from "@rapidrest/service-core";
|
|
19
|
+
import { ScanPipeline } from "../scan/ScanPipeline.js";
|
|
20
|
+
import { findOrCreateWellKnownFolder } from "../util/FolderUtils.js";
|
|
21
|
+
import { scanAndRelay } from "../util/MailSendUtils.js";
|
|
22
|
+
import { RecoverableRepoUtils } from "../util/RecoverableRepoUtils.js";
|
|
23
|
+
import { BaseScopedChildRoute } from "./BaseScopedChildRoute.js";
|
|
24
|
+
import { FolderType } from "../models/types.js";
|
|
25
|
+
const { Inject } = ObjectDecorators;
|
|
26
|
+
const { Description, Returns, Summary } = DocDecorators;
|
|
27
|
+
const { Get, Param, Post, Request, Response, User: AuthUser } = RouteDecorators;
|
|
28
|
+
/**
|
|
29
|
+
* Extends `BaseScopedChildRoute` (scoped by `folderUid` — see the architecture note on `Message.mailboxUid`)
|
|
30
|
+
* with a `send` endpoint that composes, (re-)scans, and relays a drafted message via `MailTransport`, then
|
|
31
|
+
* moves it into the mailbox's Sent Items folder. Ordinary `create`/`update`/`delete`/`find`/`findById`
|
|
32
|
+
* (save-draft, edit-draft, discard-draft, list, fetch) are handled entirely by the base class — this is the
|
|
33
|
+
* only mail-specific behavior a `Message` needs beyond scoped CRUD.
|
|
34
|
+
*
|
|
35
|
+
* `folderClass` is supplied by the Mongo/SQL concrete subclasses so this class can look up (and, if needed,
|
|
36
|
+
* create) the mailbox's Sent Items folder without depending on either backend directly.
|
|
37
|
+
*
|
|
38
|
+
* @author Jean-Philippe Steinmetz
|
|
39
|
+
*/
|
|
40
|
+
export class BaseMessageRoute extends BaseScopedChildRoute {
|
|
41
|
+
constructor() {
|
|
42
|
+
super(...arguments);
|
|
43
|
+
this.scopeProperty = "folderUid";
|
|
44
|
+
}
|
|
45
|
+
async getFolderRepo() {
|
|
46
|
+
if (!this.folderRepo) {
|
|
47
|
+
this.folderRepo = await this._objectFactory.newInstance(RecoverableRepoUtils, {
|
|
48
|
+
name: this.folderClass.name,
|
|
49
|
+
args: [this.folderClass],
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return this.folderRepo;
|
|
53
|
+
}
|
|
54
|
+
async send(id, req, user) {
|
|
55
|
+
if (!this.repoUtils || !this.blobStore || !this.mailTransport || !this.scanPipeline) {
|
|
56
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
57
|
+
}
|
|
58
|
+
const message = await this.repoUtils.findOne(id, { ignoreACL: true });
|
|
59
|
+
if (!message) {
|
|
60
|
+
throw new ApiError(ApiErrors.NOT_FOUND, 404, ApiErrorMessages.NOT_FOUND);
|
|
61
|
+
}
|
|
62
|
+
if (!(await this.aclUtils.hasPermission(user, message.folderUid, ACLAction.UPDATE))) {
|
|
63
|
+
throw new ApiError(ApiErrors.AUTH_PERMISSION_FAILURE, 403, ApiErrorMessages.AUTH_PERMISSION_FAILURE);
|
|
64
|
+
}
|
|
65
|
+
// The message's `bodyBlobKey` already holds the fully composed RFC 5322 source (assembled by the
|
|
66
|
+
// webmail compose UI, or an EAS/MAPI "send" handler, before this endpoint is called) — this route's
|
|
67
|
+
// job is scanning and relay, not MIME composition.
|
|
68
|
+
const raw = await this.blobStore.get(message.bodyBlobKey);
|
|
69
|
+
const envelopeTo = message.recipients.map((r) => r.address);
|
|
70
|
+
const { sanitizedHtmlBlobKey: scannedHtmlBlobKey } = await scanAndRelay(raw, message.from.address, envelopeTo, this.scanPipeline, this.mailTransport, this.blobStore);
|
|
71
|
+
const folderRepo = await this.getFolderRepo();
|
|
72
|
+
const sentFolder = await findOrCreateWellKnownFolder(folderRepo, this.folderClass, message.mailboxUid, FolderType.SENT_ITEMS, user);
|
|
73
|
+
const flags = { ...message.flags, read: true };
|
|
74
|
+
// `scanAndRelay()` only stores a new blob when this send pass actually produced sanitized HTML - a
|
|
75
|
+
// message with no HTML body at all keeps whatever `sanitizedHtmlBlobKey` it already had (absent, for a
|
|
76
|
+
// freshly composed draft).
|
|
77
|
+
const sanitizedHtmlBlobKey = scannedHtmlBlobKey ?? message.sanitizedHtmlBlobKey;
|
|
78
|
+
return await this.repoUtils.update({
|
|
79
|
+
uid: message.uid,
|
|
80
|
+
version: message.version,
|
|
81
|
+
folderUid: sentFolder.uid,
|
|
82
|
+
flags,
|
|
83
|
+
sanitizedHtmlBlobKey,
|
|
84
|
+
}, message, { user, ignoreACL: true });
|
|
85
|
+
}
|
|
86
|
+
async content(id, res, user) {
|
|
87
|
+
if (!this.repoUtils || !this.blobStore) {
|
|
88
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
89
|
+
}
|
|
90
|
+
const message = await this.repoUtils.findOne(id, { ignoreACL: true });
|
|
91
|
+
if (!message || !(await this.aclUtils.hasPermission(user, message.folderUid, ACLAction.READ))) {
|
|
92
|
+
throw new ApiError(ApiErrors.NOT_FOUND, 404, ApiErrorMessages.NOT_FOUND);
|
|
93
|
+
}
|
|
94
|
+
if (message.sanitizedHtmlBlobKey) {
|
|
95
|
+
const html = await this.blobStore.get(message.sanitizedHtmlBlobKey);
|
|
96
|
+
res.setHeader("content-type", "text/html; charset=utf-8");
|
|
97
|
+
res.send(html);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
res.setHeader("content-type", "text/plain; charset=utf-8");
|
|
101
|
+
res.send(Buffer.from(message.bodyPreview ?? "", "utf-8"));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
__decorate([
|
|
105
|
+
Inject("BlobStore"),
|
|
106
|
+
__metadata("design:type", Object)
|
|
107
|
+
], BaseMessageRoute.prototype, "blobStore", void 0);
|
|
108
|
+
__decorate([
|
|
109
|
+
Inject("MailTransport"),
|
|
110
|
+
__metadata("design:type", Object)
|
|
111
|
+
], BaseMessageRoute.prototype, "mailTransport", void 0);
|
|
112
|
+
__decorate([
|
|
113
|
+
Inject(ScanPipeline),
|
|
114
|
+
__metadata("design:type", ScanPipeline)
|
|
115
|
+
], BaseMessageRoute.prototype, "scanPipeline", void 0);
|
|
116
|
+
__decorate([
|
|
117
|
+
Summary("Send message"),
|
|
118
|
+
Description("Scans and relays a drafted message via the configured MailTransport, then moves it into the " +
|
|
119
|
+
"mailbox's Sent Items folder."),
|
|
120
|
+
Returns([Object]),
|
|
121
|
+
Post("/:id/send"),
|
|
122
|
+
__param(0, Param("id")),
|
|
123
|
+
__param(1, Request),
|
|
124
|
+
__param(2, AuthUser),
|
|
125
|
+
__metadata("design:type", Function),
|
|
126
|
+
__metadata("design:paramtypes", [String, Object, Object]),
|
|
127
|
+
__metadata("design:returntype", Promise)
|
|
128
|
+
], BaseMessageRoute.prototype, "send", null);
|
|
129
|
+
__decorate([
|
|
130
|
+
Summary("Get message content"),
|
|
131
|
+
Description("Streams the message's sanitized HTML body (post-`ScanPipeline`, safe to render directly) if one " +
|
|
132
|
+
"exists, otherwise falls back to its plain-text preview. Never serves `bodyBlobKey`'s raw MIME " +
|
|
133
|
+
"source directly — that content is never sanitized."),
|
|
134
|
+
Get("/:id/content"),
|
|
135
|
+
__param(0, Param("id")),
|
|
136
|
+
__param(1, Response),
|
|
137
|
+
__param(2, AuthUser),
|
|
138
|
+
__metadata("design:type", Function),
|
|
139
|
+
__metadata("design:paramtypes", [String, Object, Object]),
|
|
140
|
+
__metadata("design:returntype", Promise)
|
|
141
|
+
], BaseMessageRoute.prototype, "content", null);
|
|
142
|
+
//# sourceMappingURL=BaseMessageRoute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseMessageRoute.js","sourceRoot":"","sources":["../../../src/routes/BaseMessageRoute.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
14
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
15
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
16
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
17
|
+
import { ApiError } from "@rapidrest/core";
|
|
18
|
+
import { ACLAction, ApiErrorMessages, ApiErrors, CRUDRoute, RouteDecorators, } from "@rapidrest/service-core";
|
|
19
|
+
const { Delete, Get, Head, Param, Post, Put, Query, Request, Response, User: AuthUser } = RouteDecorators;
|
|
20
|
+
/**
|
|
21
|
+
* Resolves an unauthenticated caller's `?shareToken=` query parameter into a synthetic, ACL-checkable identity
|
|
22
|
+
* (`uid` = the token itself) when no real authenticated `user` is present — see `BaseScopedChildRoute`'s own
|
|
23
|
+
* doc comment for the full explanation of the mechanism this is one half of. Kept as a small private function
|
|
24
|
+
* duplicated in `BaseScopedChildRoute.ts`/`BaseFolderRoute.ts` (identical in both), rather than a shared
|
|
25
|
+
* `util/` module, deliberately: `ClassLoader` (see `@rapidrest/core`) scans and dynamically `import()`s an
|
|
26
|
+
* entire test-fixture directory's files concurrently via `Promise.all`, and a brand-new leaf module reached
|
|
27
|
+
* for the very first time by *several* of those concurrent imports at once triggered a real, repeatable
|
|
28
|
+
* `"Class extends value undefined"` failure under Vitest's module transform — the same class of "concurrent
|
|
29
|
+
* first dynamic import of the same module can resolve inconsistently" issue already documented on
|
|
30
|
+
* `ConnectionManager.connect()`'s sequential-redis-connection comment. Duplicating these few lines avoids ever
|
|
31
|
+
* introducing that new shared module into the concurrently-scanned graph.
|
|
32
|
+
*/
|
|
33
|
+
function resolveEffectiveUser(user, query) {
|
|
34
|
+
if (user) {
|
|
35
|
+
return user;
|
|
36
|
+
}
|
|
37
|
+
const shareToken = query?.shareToken;
|
|
38
|
+
return typeof shareToken === "string" && shareToken.length > 0
|
|
39
|
+
? ({ uid: shareToken, roles: [], scopes: [] })
|
|
40
|
+
: undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Base CRUD route for any entity that has no `AccessControlList` of its own and is instead permission-checked
|
|
44
|
+
* against a named "scope" field it carries — `folderUid` for most entities (`Message`, `CalendarEvent`,
|
|
45
|
+
* `Task`, `Note`, `Contact`, `Attachment`, `CalendarShareLink`), or `mailboxUid` for the one entity with no
|
|
46
|
+
* folder to belong to (`ContactList`). See the architecture note on `Message.mailboxUid` in `models/types.ts`
|
|
47
|
+
* for the full rationale, and `BaseFolderRoute` for `Folder`'s own (different) pattern.
|
|
48
|
+
*
|
|
49
|
+
* Concrete subclasses set `scopeProperty` to the field name to scope by; everything else is generic. A
|
|
50
|
+
* `mailboxUid`-scoped concrete class still works identically here since `ACLUtils.hasPermission` resolves any
|
|
51
|
+
* uid to its `AccessControlList` regardless of which kind of entity that uid actually names.
|
|
52
|
+
*
|
|
53
|
+
* IMPORTANT implementation note: this class deliberately does NOT delegate to `ModelRoute`'s `doFind`/
|
|
54
|
+
* `doCount`/`doFindById`/`doDelete`/`doTruncate`/`doUpdate` helpers, even though `CRUDRoute` (which this
|
|
55
|
+
* extends) normally does. Those helpers' own internal `RepoUtils.find`/`findOne`/`count`/`truncate` calls do
|
|
56
|
+
* NOT forward an `ignoreACL: true` passed into the helper's `options` down to that internal call — verified by
|
|
57
|
+
* reading their source — so calling them after establishing permission below would still hit this library's
|
|
58
|
+
* deny-by-default class-level ACL and fail. `doCreateObject`/`doBulkCreate` are the exception (verified safe:
|
|
59
|
+
* they forward `options`, `ignoreACL` included, straight through to `RepoUtils.create()`), so `create()` still
|
|
60
|
+
* uses them. Every other operation calls `this.repoUtils` directly instead.
|
|
61
|
+
*
|
|
62
|
+
* Read-shaped denials (`find`/`count`/`exists`/`findById`) fail quietly (an empty result / zero count / `404`)
|
|
63
|
+
* rather than `403`, so a caller with no access can't distinguish "records exist but you can't see them" from
|
|
64
|
+
* "nothing matches". Write-shaped denials (`create`/`update`/`delete`/`truncate`/`updateProperty`) return
|
|
65
|
+
* `403`, since the caller already knows the target scope/record they were trying to act on.
|
|
66
|
+
*
|
|
67
|
+
* Read-shaped methods also resolve an unauthenticated caller's `?shareToken=` query param via the local
|
|
68
|
+
* `resolveEffectiveUser()` helper below before checking permission — this, together with
|
|
69
|
+
* `BaseCalendarShareLinkRoute` keeping a real `ACLRecord` for each link's token in sync on the shared folder's
|
|
70
|
+
* `AccessControlList`, is the entire mechanism behind anonymous `CalendarShareLink` consumption. There is no
|
|
71
|
+
* separate route or lookup for it: a share link's token is checked by `ACLUtils.hasPermission()` exactly the
|
|
72
|
+
* same way any other uid is, through these same `find`/`count`/`exists`/`findById` methods every other caller
|
|
73
|
+
* already uses.
|
|
74
|
+
*
|
|
75
|
+
* @author Jean-Philippe Steinmetz
|
|
76
|
+
*/
|
|
77
|
+
export class BaseScopedChildRoute extends CRUDRoute {
|
|
78
|
+
scopeUidOf(obj) {
|
|
79
|
+
return obj?.[this.scopeProperty];
|
|
80
|
+
}
|
|
81
|
+
async requirePermission(scopeUid, user, action) {
|
|
82
|
+
if (!scopeUid || !(await this.aclUtils.hasPermission(user, scopeUid, action))) {
|
|
83
|
+
throw new ApiError(ApiErrors.AUTH_PERMISSION_FAILURE, 403, ApiErrorMessages.AUTH_PERMISSION_FAILURE);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Publishes live-update notifications (see `push/MailPushRoute.ts`) for create/update/delete on this entity
|
|
88
|
+
* type. Channels are bare `folderUid`/`mailboxUid` values, matching every other permission check in this
|
|
89
|
+
* class — a webmail client subscribed to a folder it can read sees every mutation of a record scoped to it.
|
|
90
|
+
* `this.notificationUtils` is inherited from `ModelRoute` (`@Inject(NotificationUtils)` there already) —
|
|
91
|
+
* publishing is fire-and-forget (see `NotificationUtils.sendMessage()`) and never blocks or fails a request.
|
|
92
|
+
*/
|
|
93
|
+
notify(scopeUid, action, data) {
|
|
94
|
+
/* v8 ignore else -- unreachable via real usage: every call site derives `scopeUid` from a record that
|
|
95
|
+
already passed `requirePermission()` (which throws on a falsy scope) earlier in the same method, so
|
|
96
|
+
it is always truthy by the time `notify()` runs. The `string | undefined` parameter type (matching
|
|
97
|
+
`scopeUidOf()`'s own return type) is what requires this guard to typecheck, not a real code path. */
|
|
98
|
+
if (scopeUid) {
|
|
99
|
+
this.notificationUtils?.sendMessage(scopeUid, this.modelClass.name, action, data);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async count(params, query, res, user) {
|
|
103
|
+
if (!this.repoUtils) {
|
|
104
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
105
|
+
}
|
|
106
|
+
const scopeUid = this.scopeUidOf(query);
|
|
107
|
+
if (!scopeUid) {
|
|
108
|
+
throw new ApiError(ApiErrors.INVALID_REQUEST, 400, ApiErrorMessages.INVALID_REQUEST);
|
|
109
|
+
}
|
|
110
|
+
if (!(await this.aclUtils.hasPermission(resolveEffectiveUser(user, query), scopeUid, ACLAction.COUNT))) {
|
|
111
|
+
return res.status(200).setHeader("content-length", 0);
|
|
112
|
+
}
|
|
113
|
+
// `shareToken` is consumed above by `resolveEffectiveUser()` for permission resolution only - it names
|
|
114
|
+
// no field on `T`, so it must not be forwarded into the data filter below (SQL: an unknown-column
|
|
115
|
+
// error; Mongo: a `$match` no real document ever satisfies, silently returning zero results either way).
|
|
116
|
+
const { shareToken: _shareToken, ...filterQuery } = query ?? {};
|
|
117
|
+
const result = await this.repoUtils.count({ ...filterQuery, ...params }, { limit: query?.limit, page: query?.page, version: query?.version, user, ignoreACL: true });
|
|
118
|
+
return res.status(200).setHeader("content-length", result);
|
|
119
|
+
}
|
|
120
|
+
async create(obj, req, user) {
|
|
121
|
+
const objs = Array.isArray(obj) ? obj : [obj];
|
|
122
|
+
for (const single of objs) {
|
|
123
|
+
await this.requirePermission(this.scopeUidOf(single), user, ACLAction.CREATE);
|
|
124
|
+
}
|
|
125
|
+
if (Array.isArray(obj)) {
|
|
126
|
+
const created = await this.doBulkCreate(obj, { req, user, ignoreACL: true });
|
|
127
|
+
for (const single of created) {
|
|
128
|
+
this.notify(this.scopeUidOf(single), "create", single);
|
|
129
|
+
}
|
|
130
|
+
return created;
|
|
131
|
+
}
|
|
132
|
+
const created = await this.doCreateObject(obj, { req, user, ignoreACL: true });
|
|
133
|
+
this.notify(this.scopeUidOf(created), "create", created);
|
|
134
|
+
return created;
|
|
135
|
+
}
|
|
136
|
+
async delete(id, version, purge, req, user) {
|
|
137
|
+
if (!this.repoUtils) {
|
|
138
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
139
|
+
}
|
|
140
|
+
const existing = await this.repoUtils.findOne(id, { version, ignoreACL: true });
|
|
141
|
+
if (!existing) {
|
|
142
|
+
throw new ApiError(ApiErrors.NOT_FOUND, 404, ApiErrorMessages.NOT_FOUND);
|
|
143
|
+
}
|
|
144
|
+
await this.requirePermission(this.scopeUidOf(existing), user, ACLAction.DELETE);
|
|
145
|
+
await this.repoUtils.delete(existing.uid, { user, version, purge: purge === "true", ignoreACL: true });
|
|
146
|
+
this.notify(this.scopeUidOf(existing), "delete", { uid: existing.uid });
|
|
147
|
+
}
|
|
148
|
+
async exists(id, query, res, user) {
|
|
149
|
+
if (!this.repoUtils) {
|
|
150
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
151
|
+
}
|
|
152
|
+
const existing = await this.repoUtils.findOne(id, {
|
|
153
|
+
version: query?.version,
|
|
154
|
+
includeDeleted: query?.deleted === true || query?.deleted === "true",
|
|
155
|
+
ignoreACL: true,
|
|
156
|
+
});
|
|
157
|
+
const scopeUid = existing ? this.scopeUidOf(existing) : undefined;
|
|
158
|
+
const permitted = scopeUid
|
|
159
|
+
? await this.aclUtils.hasPermission(resolveEffectiveUser(user, query), scopeUid, ACLAction.EXISTS)
|
|
160
|
+
: false;
|
|
161
|
+
return permitted
|
|
162
|
+
? res.status(200).setHeader("content-length", 1)
|
|
163
|
+
: res.status(404).setHeader("content-length", 0);
|
|
164
|
+
}
|
|
165
|
+
async find(params, query, user) {
|
|
166
|
+
if (!this.repoUtils) {
|
|
167
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
168
|
+
}
|
|
169
|
+
const scopeUid = this.scopeUidOf(query);
|
|
170
|
+
if (!scopeUid) {
|
|
171
|
+
throw new ApiError(ApiErrors.INVALID_REQUEST, 400, ApiErrorMessages.INVALID_REQUEST);
|
|
172
|
+
}
|
|
173
|
+
if (!(await this.aclUtils.hasPermission(resolveEffectiveUser(user, query), scopeUid, ACLAction.LIST))) {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
// See the identical `shareToken` exclusion (and its rationale) in `count()` above.
|
|
177
|
+
const { shareToken: _shareToken, ...filterQuery } = query ?? {};
|
|
178
|
+
return await this.repoUtils.find({ ...filterQuery, ...params }, { limit: query?.limit, page: query?.page, version: query?.version, user, ignoreACL: true });
|
|
179
|
+
}
|
|
180
|
+
async findById(id, query, user) {
|
|
181
|
+
if (!this.repoUtils) {
|
|
182
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
183
|
+
}
|
|
184
|
+
const existing = await this.repoUtils.findOne(id, {
|
|
185
|
+
version: query?.version,
|
|
186
|
+
includeDeleted: query?.deleted === true || query?.deleted === "true",
|
|
187
|
+
ignoreACL: true,
|
|
188
|
+
});
|
|
189
|
+
const scopeUid = existing ? this.scopeUidOf(existing) : undefined;
|
|
190
|
+
if (!scopeUid || !(await this.aclUtils.hasPermission(resolveEffectiveUser(user, query), scopeUid, ACLAction.READ))) {
|
|
191
|
+
throw new ApiError(ApiErrors.NOT_FOUND, 404, ApiErrorMessages.NOT_FOUND);
|
|
192
|
+
}
|
|
193
|
+
return existing;
|
|
194
|
+
}
|
|
195
|
+
async truncate(params, query, user) {
|
|
196
|
+
if (!this.repoUtils) {
|
|
197
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
198
|
+
}
|
|
199
|
+
await this.requirePermission(this.scopeUidOf(query), user, ACLAction.TRUNCATE);
|
|
200
|
+
await this.repoUtils.truncate({ ...query, ...params }, { limit: query?.limit, page: query?.page, version: query?.version, user, ignoreACL: true });
|
|
201
|
+
}
|
|
202
|
+
async update(id, obj, req, user) {
|
|
203
|
+
if (!this.repoUtils) {
|
|
204
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
205
|
+
}
|
|
206
|
+
const existing = await this.repoUtils.findOne(id, { skipCache: true, ignoreACL: true });
|
|
207
|
+
if (!existing) {
|
|
208
|
+
throw new ApiError(ApiErrors.NOT_FOUND, 404, ApiErrorMessages.NOT_FOUND);
|
|
209
|
+
}
|
|
210
|
+
await this.requirePermission(this.scopeUidOf(existing), user, ACLAction.UPDATE);
|
|
211
|
+
// `obj` is client-supplied and `scopeProperty` (`folderUid`/`mailboxUid`) is an ordinary, writable field
|
|
212
|
+
// on every entity this class serves - none of them mark it `@ReadOnly`, since a folder/mailbox transfer
|
|
213
|
+
// (e.g. moving a Message between folders) is legitimate functionality, not something to block outright.
|
|
214
|
+
// But the check above only establishes permission on the record's CURRENT scope; without also checking
|
|
215
|
+
// the NEW one, a caller with UPDATE access to their own folder could silently re-parent any record they
|
|
216
|
+
// can already reach into a folder/mailbox they have no access to at all (or vice versa: pull a record
|
|
217
|
+
// OUT of a folder they don't own but happen to know the uid of, into their own), completely bypassing
|
|
218
|
+
// the scope-based permission model this route family exists to enforce - equivalent to planting
|
|
219
|
+
// attacker-controlled content directly into a victim's mailbox, bypassing ingestion/scanning entirely
|
|
220
|
+
// for entities like `Message`/`Attachment`.
|
|
221
|
+
const newScopeUid = this.scopeUidOf(obj);
|
|
222
|
+
if (newScopeUid !== undefined && newScopeUid !== this.scopeUidOf(existing)) {
|
|
223
|
+
await this.requirePermission(newScopeUid, user, ACLAction.CREATE);
|
|
224
|
+
}
|
|
225
|
+
await this.validate(obj, { user });
|
|
226
|
+
const updated = await this.repoUtils.update(obj, existing, { user, ignoreACL: true });
|
|
227
|
+
// Notify the record's new scope always, and its OLD scope too if this update re-parented it - a
|
|
228
|
+
// client subscribed to the folder the record just left needs to know it's gone from their view, not
|
|
229
|
+
// just that it appeared somewhere else.
|
|
230
|
+
const oldScopeUid = this.scopeUidOf(existing);
|
|
231
|
+
const updatedScopeUid = this.scopeUidOf(updated);
|
|
232
|
+
this.notify(updatedScopeUid, "update", updated);
|
|
233
|
+
if (newScopeUid !== undefined && oldScopeUid !== updatedScopeUid) {
|
|
234
|
+
this.notify(oldScopeUid, "delete", { uid: updated.uid });
|
|
235
|
+
}
|
|
236
|
+
return updated;
|
|
237
|
+
}
|
|
238
|
+
async updateBulk(obj, req, user) {
|
|
239
|
+
const results = [];
|
|
240
|
+
for (const single of obj) {
|
|
241
|
+
results.push(await this.update(single.uid, single, req, user));
|
|
242
|
+
}
|
|
243
|
+
return results;
|
|
244
|
+
}
|
|
245
|
+
async updateProperty(id, propertyName, obj, user) {
|
|
246
|
+
if (!this.repoUtils) {
|
|
247
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
248
|
+
}
|
|
249
|
+
const existing = await this.repoUtils.findOne(id, { ignoreACL: true });
|
|
250
|
+
if (!existing) {
|
|
251
|
+
throw new ApiError(ApiErrors.NOT_FOUND, 404, ApiErrorMessages.NOT_FOUND);
|
|
252
|
+
}
|
|
253
|
+
return await this.update(id, { uid: existing.uid, version: existing.version, [propertyName]: obj }, undefined, user);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
__decorate([
|
|
257
|
+
Head(),
|
|
258
|
+
__param(0, Param()),
|
|
259
|
+
__param(1, Query()),
|
|
260
|
+
__param(2, Response),
|
|
261
|
+
__param(3, AuthUser),
|
|
262
|
+
__metadata("design:type", Function),
|
|
263
|
+
__metadata("design:paramtypes", [Object, Object, Object, Object]),
|
|
264
|
+
__metadata("design:returntype", Promise)
|
|
265
|
+
], BaseScopedChildRoute.prototype, "count", null);
|
|
266
|
+
__decorate([
|
|
267
|
+
Post(),
|
|
268
|
+
__param(1, Request),
|
|
269
|
+
__param(2, AuthUser),
|
|
270
|
+
__metadata("design:type", Function),
|
|
271
|
+
__metadata("design:paramtypes", [Object, Object, Object]),
|
|
272
|
+
__metadata("design:returntype", Promise)
|
|
273
|
+
], BaseScopedChildRoute.prototype, "create", null);
|
|
274
|
+
__decorate([
|
|
275
|
+
Delete("/:id"),
|
|
276
|
+
__param(0, Param("id")),
|
|
277
|
+
__param(1, Query("version")),
|
|
278
|
+
__param(2, Query("purge")),
|
|
279
|
+
__param(3, Request),
|
|
280
|
+
__param(4, AuthUser),
|
|
281
|
+
__metadata("design:type", Function),
|
|
282
|
+
__metadata("design:paramtypes", [String, Object, Object, Object, Object]),
|
|
283
|
+
__metadata("design:returntype", Promise)
|
|
284
|
+
], BaseScopedChildRoute.prototype, "delete", null);
|
|
285
|
+
__decorate([
|
|
286
|
+
Head("/:id"),
|
|
287
|
+
__param(0, Param("id")),
|
|
288
|
+
__param(1, Query()),
|
|
289
|
+
__param(2, Response),
|
|
290
|
+
__param(3, AuthUser),
|
|
291
|
+
__metadata("design:type", Function),
|
|
292
|
+
__metadata("design:paramtypes", [String, Object, Object, Object]),
|
|
293
|
+
__metadata("design:returntype", Promise)
|
|
294
|
+
], BaseScopedChildRoute.prototype, "exists", null);
|
|
295
|
+
__decorate([
|
|
296
|
+
Get(),
|
|
297
|
+
__param(0, Param()),
|
|
298
|
+
__param(1, Query()),
|
|
299
|
+
__param(2, AuthUser),
|
|
300
|
+
__metadata("design:type", Function),
|
|
301
|
+
__metadata("design:paramtypes", [Object, Object, Object]),
|
|
302
|
+
__metadata("design:returntype", Promise)
|
|
303
|
+
], BaseScopedChildRoute.prototype, "find", null);
|
|
304
|
+
__decorate([
|
|
305
|
+
Get("/:id"),
|
|
306
|
+
__param(0, Param("id")),
|
|
307
|
+
__param(1, Query()),
|
|
308
|
+
__param(2, AuthUser),
|
|
309
|
+
__metadata("design:type", Function),
|
|
310
|
+
__metadata("design:paramtypes", [String, Object, Object]),
|
|
311
|
+
__metadata("design:returntype", Promise)
|
|
312
|
+
], BaseScopedChildRoute.prototype, "findById", null);
|
|
313
|
+
__decorate([
|
|
314
|
+
Delete(),
|
|
315
|
+
__param(0, Param()),
|
|
316
|
+
__param(1, Query()),
|
|
317
|
+
__param(2, AuthUser),
|
|
318
|
+
__metadata("design:type", Function),
|
|
319
|
+
__metadata("design:paramtypes", [Object, Object, Object]),
|
|
320
|
+
__metadata("design:returntype", Promise)
|
|
321
|
+
], BaseScopedChildRoute.prototype, "truncate", null);
|
|
322
|
+
__decorate([
|
|
323
|
+
Put("/:id"),
|
|
324
|
+
__param(0, Param("id")),
|
|
325
|
+
__param(2, Request),
|
|
326
|
+
__param(3, AuthUser),
|
|
327
|
+
__metadata("design:type", Function),
|
|
328
|
+
__metadata("design:paramtypes", [String, Object, Object, Object]),
|
|
329
|
+
__metadata("design:returntype", Promise)
|
|
330
|
+
], BaseScopedChildRoute.prototype, "update", null);
|
|
331
|
+
__decorate([
|
|
332
|
+
Put(),
|
|
333
|
+
__param(1, Request),
|
|
334
|
+
__param(2, AuthUser),
|
|
335
|
+
__metadata("design:type", Function),
|
|
336
|
+
__metadata("design:paramtypes", [Array, Object, Object]),
|
|
337
|
+
__metadata("design:returntype", Promise)
|
|
338
|
+
], BaseScopedChildRoute.prototype, "updateBulk", null);
|
|
339
|
+
__decorate([
|
|
340
|
+
Put("/:id/:property"),
|
|
341
|
+
__param(0, Param("id")),
|
|
342
|
+
__param(1, Param("property")),
|
|
343
|
+
__param(3, AuthUser),
|
|
344
|
+
__metadata("design:type", Function),
|
|
345
|
+
__metadata("design:paramtypes", [String, String, Object, Object]),
|
|
346
|
+
__metadata("design:returntype", Promise)
|
|
347
|
+
], BaseScopedChildRoute.prototype, "updateProperty", null);
|
|
348
|
+
//# sourceMappingURL=BaseScopedChildRoute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseScopedChildRoute.js","sourceRoot":"","sources":["../../../src/routes/BaseScopedChildRoute.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAE,QAAQ,EAAgB,MAAM,iBAAiB,CAAC;AACzD,OAAO,EACH,SAAS,EACT,gBAAgB,EAChB,SAAS,EAET,SAAS,EAGT,eAAe,GAElB,MAAM,yBAAyB,CAAC;AACjC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC;AAE1G;;;;;;;;;;;;GAYG;AACH,SAAS,oBAAoB,CAAC,IAAyB,EAAE,KAAU;IAC/D,IAAI,IAAI,EAAE,CAAC;QACP,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,UAAU,GAAY,KAAK,EAAE,UAAU,CAAC;IAC9C,OAAO,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QAC1D,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAC9C,CAAC,CAAC,SAAS,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,OAAgB,oBAA2C,SAAQ,SAAY;IAIzE,UAAU,CAAC,GAAQ;QACvB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,QAA4B,EAAE,IAAyB,EAAE,MAAc;QACnG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,QAAS,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;YAC7E,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,uBAAuB,EAAE,GAAG,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;QACzG,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACK,MAAM,CAAC,QAA4B,EAAE,MAAsC,EAAE,IAAS;QAC1F;;;+GAGuG;QACvG,IAAI,QAAQ,EAAE,CAAC;YACX,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACtF,CAAC;IACL,CAAC;IAGY,AAAN,KAAK,CAAC,KAAK,CACL,MAAW,EACX,KAAU,EACT,GAAiB,EACjB,IAAc;QAExB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,QAAQ,GAAuB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,eAAe,EAAE,GAAG,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,QAAS,CAAC,aAAa,CAAC,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACtG,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;QAC1D,CAAC;QACD,uGAAuG;QACvG,kGAAkG;QAClG,yGAAyG;QACzG,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC;QAChE,MAAM,MAAM,GAAW,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAC7C,EAAE,GAAG,WAAW,EAAE,GAAG,MAAM,EAAE,EAC7B,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAC7F,CAAC;QACF,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IAGY,AAAN,KAAK,CAAC,MAAM,CAAC,GAAY,EAAW,GAAgB,EAAY,IAAc;QACjF,MAAM,IAAI,GAAQ,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACnD,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAClF,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,OAAO,GAAQ,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAClF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC3D,CAAC;YACD,OAAO,OAAO,CAAC;QACnB,CAAC;QACD,MAAM,OAAO,GAAM,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzD,OAAO,OAAO,CAAC;IACnB,CAAC;IAGY,AAAN,KAAK,CAAC,MAAM,CACF,EAAU,EACL,OAA2B,EAC7B,KAAyB,EAChC,GAAgB,EACf,IAAc;QAExB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,QAAQ,GAAkB,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/F,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAChF,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5E,CAAC;IAGY,AAAN,KAAK,CAAC,MAAM,CACF,EAAU,EACd,KAAU,EACT,GAAiB,EACjB,IAAc;QAExB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,QAAQ,GAAkB,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE;YAC7D,OAAO,EAAE,KAAK,EAAE,OAAO;YACvB,cAAc,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,IAAI,KAAK,EAAE,OAAO,KAAK,MAAM;YACpE,SAAS,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,MAAM,QAAQ,GAAuB,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtF,MAAM,SAAS,GAAY,QAAQ;YAC/B,CAAC,CAAC,MAAM,IAAI,CAAC,QAAS,CAAC,aAAa,CAAC,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC;YACnG,CAAC,CAAC,KAAK,CAAC;QACZ,OAAO,SAAS;YACZ,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC,CAAC;YAChD,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;IACzD,CAAC;IAGY,AAAN,KAAK,CAAC,IAAI,CAAU,MAAW,EAAW,KAAU,EAAY,IAAc;QACjF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,QAAQ,GAAuB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,eAAe,EAAE,GAAG,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,QAAS,CAAC,aAAa,CAAC,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACrG,OAAO,EAAE,CAAC;QACd,CAAC;QACD,mFAAmF;QACnF,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC;QAChE,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC5B,EAAE,GAAG,WAAW,EAAE,GAAG,MAAM,EAAE,EAC7B,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAC7F,CAAC;IACN,CAAC;IAGY,AAAN,KAAK,CAAC,QAAQ,CAAc,EAAU,EAAW,KAAU,EAAY,IAAc;QACxF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,QAAQ,GAAkB,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE;YAC7D,OAAO,EAAE,KAAK,EAAE,OAAO;YACvB,cAAc,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,IAAI,KAAK,EAAE,OAAO,KAAK,MAAM;YACpE,SAAS,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,MAAM,QAAQ,GAAuB,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtF,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,QAAS,CAAC,aAAa,CAAC,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAClH,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,QAAS,CAAC;IACrB,CAAC;IAGY,AAAN,KAAK,CAAC,QAAQ,CAAU,MAAW,EAAW,KAAU,EAAY,IAAc;QACrF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC/E,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CACzB,EAAE,GAAG,KAAK,EAAE,GAAG,MAAM,EAAE,EACvB,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAC7F,CAAC;IACN,CAAC;IAGY,AAAN,KAAK,CAAC,MAAM,CACF,EAAU,EACvB,GAAoB,EACX,GAAiB,EAChB,IAAc;QAExB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,QAAQ,GAAkB,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAEhF,yGAAyG;QACzG,wGAAwG;QACxG,wGAAwG;QACxG,uGAAuG;QACvG,wGAAwG;QACxG,sGAAsG;QACtG,sGAAsG;QACtG,gGAAgG;QAChG,sGAAsG;QACtG,4CAA4C;QAC5C,MAAM,WAAW,GAAuB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC7D,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzE,MAAM,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACnC,MAAM,OAAO,GAAM,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEzF,gGAAgG;QAChG,oGAAoG;QACpG,wCAAwC;QACxC,MAAM,WAAW,GAAuB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAClE,MAAM,eAAe,GAAuB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACrE,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,eAAe,EAAE,CAAC;YAC/D,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;IAGY,AAAN,KAAK,CAAC,UAAU,CAAC,GAAsB,EAAW,GAAgB,EAAY,IAAc;QAC/F,MAAM,OAAO,GAAQ,EAAE,CAAC;QACxB,KAAK,MAAM,MAAM,IAAI,GAAG,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAGY,AAAN,KAAK,CAAC,cAAc,CACV,EAAU,EACJ,YAAoB,EACvC,GAAQ,EACE,IAAc;QAExB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,QAAQ,GAAkB,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,MAAM,IAAI,CAAC,MAAM,CACpB,EAAE,EACF,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAG,QAAgB,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC,EAAE,GAAG,EAAS,EACrF,SAAS,EACT,IAAI,CACP,CAAC;IACN,CAAC;CACJ;AAvNgB;IADZ,IAAI,EAAE;IAEF,WAAA,KAAK,EAAE,CAAA;IACP,WAAA,KAAK,EAAE,CAAA;IACP,WAAA,QAAQ,CAAA;IACR,WAAA,QAAQ,CAAA;;;;iDAqBZ;AAGY;IADZ,IAAI,EAAE;IAC4B,WAAA,OAAO,CAAA;IAAoB,WAAA,QAAQ,CAAA;;;;kDAerE;AAGY;IADZ,MAAM,CAAC,MAAM,CAAC;IAEV,WAAA,KAAK,CAAC,IAAI,CAAC,CAAA;IACX,WAAA,KAAK,CAAC,SAAS,CAAC,CAAA;IAChB,WAAA,KAAK,CAAC,OAAO,CAAC,CAAA;IACd,WAAA,OAAO,CAAA;IACP,WAAA,QAAQ,CAAA;;;;kDAYZ;AAGY;IADZ,IAAI,CAAC,MAAM,CAAC;IAER,WAAA,KAAK,CAAC,IAAI,CAAC,CAAA;IACX,WAAA,KAAK,EAAE,CAAA;IACP,WAAA,QAAQ,CAAA;IACR,WAAA,QAAQ,CAAA;;;;kDAiBZ;AAGY;IADZ,GAAG,EAAE;IACa,WAAA,KAAK,EAAE,CAAA;IAAe,WAAA,KAAK,EAAE,CAAA;IAAc,WAAA,QAAQ,CAAA;;;;gDAiBrE;AAGY;IADZ,GAAG,CAAC,MAAM,CAAC;IACW,WAAA,KAAK,CAAC,IAAI,CAAC,CAAA;IAAc,WAAA,KAAK,EAAE,CAAA;IAAc,WAAA,QAAQ,CAAA;;;;oDAc5E;AAGY;IADZ,MAAM,EAAE;IACc,WAAA,KAAK,EAAE,CAAA;IAAe,WAAA,KAAK,EAAE,CAAA;IAAc,WAAA,QAAQ,CAAA;;;;oDASzE;AAGY;IADZ,GAAG,CAAC,MAAM,CAAC;IAEP,WAAA,KAAK,CAAC,IAAI,CAAC,CAAA;IAEX,WAAA,OAAO,CAAA;IACP,WAAA,QAAQ,CAAA;;;;kDAwCZ;AAGY;IADZ,GAAG,EAAE;IAC2C,WAAA,OAAO,CAAA;IAAoB,WAAA,QAAQ,CAAA;;;;sDAMnF;AAGY;IADZ,GAAG,CAAC,gBAAgB,CAAC;IAEjB,WAAA,KAAK,CAAC,IAAI,CAAC,CAAA;IACX,WAAA,KAAK,CAAC,UAAU,CAAC,CAAA;IAEjB,WAAA,QAAQ,CAAA;;;;0DAeZ"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
14
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
15
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
16
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
17
|
+
import { ApiError, ObjectDecorators } from "@rapidrest/core";
|
|
18
|
+
import { ApiErrorMessages, ApiErrors, DocDecorators, RepoUtils, RouteDecorators } from "@rapidrest/service-core";
|
|
19
|
+
import { resolveCallerMailboxUid } from "../util/MailboxScopeUtils.js";
|
|
20
|
+
const { Inject, Logger } = ObjectDecorators;
|
|
21
|
+
const { Description, Returns, Summary } = DocDecorators;
|
|
22
|
+
const { Auth, Get, Query, User: AuthUser } = RouteDecorators;
|
|
23
|
+
/**
|
|
24
|
+
* Exposes full-text search across a mailbox's messages/contacts/calendar events/notes/tasks. Unlike every
|
|
25
|
+
* other route in this library, this is NOT a `ModelRoute`/`CRUDRoute` subclass — `RepoUtils.find()` has no
|
|
26
|
+
* full-text query capability, so this route calls the injected `SearchProvider` directly instead.
|
|
27
|
+
*
|
|
28
|
+
* `mailboxClass` is supplied by the Mongo/SQL concrete subclasses. Search is always scoped to a mailbox the
|
|
29
|
+
* requesting user owns (`ownerUserUid === user.uid`) — a client-supplied `mailboxUid` is deliberately not
|
|
30
|
+
* accepted, so this endpoint can never be used to search another user's mailbox.
|
|
31
|
+
*
|
|
32
|
+
* @author Jean-Philippe Steinmetz
|
|
33
|
+
*/
|
|
34
|
+
export class BaseSearchRoute {
|
|
35
|
+
async getMailboxRepo() {
|
|
36
|
+
if (!this.mailboxRepo) {
|
|
37
|
+
this.mailboxRepo = await this._objectFactory.newInstance(RepoUtils, {
|
|
38
|
+
name: this.mailboxClass.name,
|
|
39
|
+
args: [this.mailboxClass],
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return this.mailboxRepo;
|
|
43
|
+
}
|
|
44
|
+
async search(text, typesParam, cursor, limitParam, user) {
|
|
45
|
+
if (!this.searchProvider) {
|
|
46
|
+
throw new ApiError(ApiErrors.INTERNAL_ERROR, 500, ApiErrorMessages.INTERNAL_ERROR);
|
|
47
|
+
}
|
|
48
|
+
if (!text || !user) {
|
|
49
|
+
throw new ApiError(ApiErrors.INVALID_REQUEST, 400, ApiErrorMessages.INVALID_REQUEST);
|
|
50
|
+
}
|
|
51
|
+
const mailboxRepo = await this.getMailboxRepo();
|
|
52
|
+
const mailboxUid = await resolveCallerMailboxUid(mailboxRepo, user);
|
|
53
|
+
if (!mailboxUid) {
|
|
54
|
+
throw new ApiError(ApiErrors.NOT_FOUND, 404, ApiErrorMessages.NOT_FOUND);
|
|
55
|
+
}
|
|
56
|
+
const entityTypes = typesParam
|
|
57
|
+
? typesParam.split(",")
|
|
58
|
+
: undefined;
|
|
59
|
+
return await this.searchProvider.search({
|
|
60
|
+
mailboxUid,
|
|
61
|
+
text,
|
|
62
|
+
entityTypes,
|
|
63
|
+
cursor,
|
|
64
|
+
limit: limitParam ? parseInt(limitParam, 10) : undefined,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
__decorate([
|
|
69
|
+
Inject("SearchProvider"),
|
|
70
|
+
__metadata("design:type", Object)
|
|
71
|
+
], BaseSearchRoute.prototype, "searchProvider", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
Logger,
|
|
74
|
+
__metadata("design:type", Object)
|
|
75
|
+
], BaseSearchRoute.prototype, "logger", void 0);
|
|
76
|
+
__decorate([
|
|
77
|
+
Summary("Search mailbox"),
|
|
78
|
+
Description("Performs a full-text search across the requesting user's mail, contacts, calendar, notes, and tasks."),
|
|
79
|
+
Returns([Object]),
|
|
80
|
+
Auth(["jwt"]),
|
|
81
|
+
Get(),
|
|
82
|
+
__param(0, Query("q")),
|
|
83
|
+
__param(1, Query("types")),
|
|
84
|
+
__param(2, Query("cursor")),
|
|
85
|
+
__param(3, Query("limit")),
|
|
86
|
+
__param(4, AuthUser),
|
|
87
|
+
__metadata("design:type", Function),
|
|
88
|
+
__metadata("design:paramtypes", [String, Object, Object, Object, Object]),
|
|
89
|
+
__metadata("design:returntype", Promise)
|
|
90
|
+
], BaseSearchRoute.prototype, "search", null);
|
|
91
|
+
//# sourceMappingURL=BaseSearchRoute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseSearchRoute.js","sourceRoot":"","sources":["../../../src/routes/BaseSearchRoute.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
export * from "./BaseAttachmentRoute.js";
|
|
6
|
+
export * from "./BaseCalendarShareLinkRoute.js";
|
|
7
|
+
export * from "./BaseFolderRoute.js";
|
|
8
|
+
export * from "./BaseMailboxRoute.js";
|
|
9
|
+
export * from "./BaseMailIngestRoute.js";
|
|
10
|
+
export * from "./BaseMessageRoute.js";
|
|
11
|
+
export * from "./BaseScopedChildRoute.js";
|
|
12
|
+
export * from "./BaseSearchRoute.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/routes/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC"}
|