@decaf-ts/integrations 0.11.0 → 0.12.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.
Files changed (496) hide show
  1. package/README.md +164 -0
  2. package/dist/integrations.cjs +1 -1
  3. package/dist/integrations.cjs.map +1 -1
  4. package/dist/integrations.js +1 -1
  5. package/dist/integrations.js.map +1 -1
  6. package/docker/mailpit-compose.yml +17 -0
  7. package/docker/postgres-compose.yml +26 -0
  8. package/lib/cjs/blob/azure/AzureBlobStoreService.cjs +12 -23
  9. package/lib/cjs/blob/azure/AzureBlobStoreService.cjs.map +1 -1
  10. package/lib/cjs/blob/core/BlobStoreService.cjs +26 -25
  11. package/lib/cjs/blob/core/BlobStoreService.cjs.map +1 -1
  12. package/lib/cjs/blob/gcp/GcsBlobStoreService.cjs +12 -23
  13. package/lib/cjs/blob/gcp/GcsBlobStoreService.cjs.map +1 -1
  14. package/lib/cjs/blob/s3/S3BlobStoreService.cjs +11 -16
  15. package/lib/cjs/blob/s3/S3BlobStoreService.cjs.map +1 -1
  16. package/lib/cjs/blob/s3/S3CompatibleBlobStoreService.cjs +14 -16
  17. package/lib/cjs/blob/s3/S3CompatibleBlobStoreService.cjs.map +1 -1
  18. package/lib/cjs/comms/email/EmailService.cjs +376 -0
  19. package/lib/cjs/comms/email/EmailService.cjs.map +1 -0
  20. package/lib/cjs/comms/email/index.cjs +29 -0
  21. package/lib/cjs/comms/email/index.cjs.map +1 -0
  22. package/lib/cjs/comms/email/mime.cjs +225 -0
  23. package/lib/cjs/comms/email/mime.cjs.map +1 -0
  24. package/lib/cjs/comms/email/smtp.cjs +204 -0
  25. package/lib/cjs/comms/email/smtp.cjs.map +1 -0
  26. package/lib/cjs/comms/environment.cjs +63 -0
  27. package/lib/cjs/comms/environment.cjs.map +1 -0
  28. package/lib/cjs/comms/gmail/GmailService.cjs +235 -0
  29. package/lib/cjs/comms/gmail/GmailService.cjs.map +1 -0
  30. package/lib/cjs/comms/gmail/index.cjs +24 -0
  31. package/lib/cjs/comms/gmail/index.cjs.map +1 -0
  32. package/lib/cjs/comms/index.cjs +31 -0
  33. package/lib/cjs/comms/index.cjs.map +1 -0
  34. package/lib/cjs/comms/slack/SlackService.cjs +264 -0
  35. package/lib/cjs/comms/slack/SlackService.cjs.map +1 -0
  36. package/lib/cjs/comms/slack/index.cjs +24 -0
  37. package/lib/cjs/comms/slack/index.cjs.map +1 -0
  38. package/lib/cjs/comms/teams/TeamsService.cjs +212 -0
  39. package/lib/cjs/comms/teams/TeamsService.cjs.map +1 -0
  40. package/lib/cjs/comms/teams/index.cjs +24 -0
  41. package/lib/cjs/comms/teams/index.cjs.map +1 -0
  42. package/lib/cjs/comms/telegram/TelegramService.cjs +196 -0
  43. package/lib/cjs/comms/telegram/TelegramService.cjs.map +1 -0
  44. package/lib/cjs/comms/telegram/index.cjs +24 -0
  45. package/lib/cjs/comms/telegram/index.cjs.map +1 -0
  46. package/lib/cjs/devops/environment.cjs +43 -0
  47. package/lib/cjs/devops/environment.cjs.map +1 -0
  48. package/lib/cjs/devops/github/GithubService.cjs +302 -0
  49. package/lib/cjs/devops/github/GithubService.cjs.map +1 -0
  50. package/lib/cjs/devops/github/index.cjs +24 -0
  51. package/lib/cjs/devops/github/index.cjs.map +1 -0
  52. package/lib/cjs/devops/gitlab/GitlabService.cjs +282 -0
  53. package/lib/cjs/devops/gitlab/GitlabService.cjs.map +1 -0
  54. package/lib/cjs/devops/gitlab/index.cjs +24 -0
  55. package/lib/cjs/devops/gitlab/index.cjs.map +1 -0
  56. package/lib/cjs/devops/index.cjs +28 -0
  57. package/lib/cjs/devops/index.cjs.map +1 -0
  58. package/lib/cjs/feature-flags/models/FeatureFlag.model.cjs +2 -0
  59. package/lib/cjs/feature-flags/models/FeatureFlag.model.cjs.map +1 -1
  60. package/lib/cjs/feature-flags/models/FeatureFlagAccess.model.cjs +2 -0
  61. package/lib/cjs/feature-flags/models/FeatureFlagAccess.model.cjs.map +1 -1
  62. package/lib/cjs/index.cjs +3 -3
  63. package/lib/cjs/io/airtable/AirtableService.cjs +266 -0
  64. package/lib/cjs/io/airtable/AirtableService.cjs.map +1 -0
  65. package/lib/cjs/io/airtable/index.cjs +24 -0
  66. package/lib/cjs/io/airtable/index.cjs.map +1 -0
  67. package/lib/cjs/io/environment.cjs +46 -0
  68. package/lib/cjs/io/environment.cjs.map +1 -0
  69. package/lib/cjs/io/google-sheets/GoogleSheetsService.cjs +288 -0
  70. package/lib/cjs/io/google-sheets/GoogleSheetsService.cjs.map +1 -0
  71. package/lib/cjs/io/google-sheets/index.cjs +24 -0
  72. package/lib/cjs/io/google-sheets/index.cjs.map +1 -0
  73. package/lib/cjs/io/graphql/GraphqlService.cjs +143 -0
  74. package/lib/cjs/io/graphql/GraphqlService.cjs.map +1 -0
  75. package/lib/cjs/io/graphql/index.cjs +24 -0
  76. package/lib/cjs/io/graphql/index.cjs.map +1 -0
  77. package/lib/cjs/io/index.cjs +30 -0
  78. package/lib/cjs/io/index.cjs.map +1 -0
  79. package/lib/cjs/io/spreadsheet/SpreadsheetService.cjs +205 -0
  80. package/lib/cjs/io/spreadsheet/SpreadsheetService.cjs.map +1 -0
  81. package/lib/cjs/io/spreadsheet/index.cjs +25 -0
  82. package/lib/cjs/io/spreadsheet/index.cjs.map +1 -0
  83. package/lib/cjs/namespaces/index.cjs +1 -0
  84. package/lib/cjs/namespaces/index.cjs.map +1 -1
  85. package/lib/cjs/namespaces/models/credential.model.cjs +115 -0
  86. package/lib/cjs/namespaces/models/credential.model.cjs.map +1 -0
  87. package/lib/cjs/namespaces/models/effective-permission.model.cjs +2 -0
  88. package/lib/cjs/namespaces/models/effective-permission.model.cjs.map +1 -1
  89. package/lib/cjs/namespaces/models/group-membership.model.cjs +2 -0
  90. package/lib/cjs/namespaces/models/group-membership.model.cjs.map +1 -1
  91. package/lib/cjs/namespaces/models/group.model.cjs +2 -0
  92. package/lib/cjs/namespaces/models/group.model.cjs.map +1 -1
  93. package/lib/cjs/namespaces/models/index.cjs +1 -0
  94. package/lib/cjs/namespaces/models/index.cjs.map +1 -1
  95. package/lib/cjs/namespaces/models/inheritance-block.model.cjs +2 -0
  96. package/lib/cjs/namespaces/models/inheritance-block.model.cjs.map +1 -1
  97. package/lib/cjs/namespaces/models/org-unit-closure.model.cjs +2 -0
  98. package/lib/cjs/namespaces/models/org-unit-closure.model.cjs.map +1 -1
  99. package/lib/cjs/namespaces/models/org-unit-membership.model.cjs +2 -0
  100. package/lib/cjs/namespaces/models/org-unit-membership.model.cjs.map +1 -1
  101. package/lib/cjs/namespaces/models/org-unit-profile.model.cjs +2 -0
  102. package/lib/cjs/namespaces/models/org-unit-profile.model.cjs.map +1 -1
  103. package/lib/cjs/namespaces/models/org-unit.model.cjs +2 -0
  104. package/lib/cjs/namespaces/models/org-unit.model.cjs.map +1 -1
  105. package/lib/cjs/namespaces/models/permission.model.cjs +2 -0
  106. package/lib/cjs/namespaces/models/permission.model.cjs.map +1 -1
  107. package/lib/cjs/namespaces/models/principal.model.cjs +2 -0
  108. package/lib/cjs/namespaces/models/principal.model.cjs.map +1 -1
  109. package/lib/cjs/namespaces/models/protected-resource.model.cjs +2 -0
  110. package/lib/cjs/namespaces/models/protected-resource.model.cjs.map +1 -1
  111. package/lib/cjs/namespaces/models/resource-grant.model.cjs +2 -0
  112. package/lib/cjs/namespaces/models/resource-grant.model.cjs.map +1 -1
  113. package/lib/cjs/namespaces/models/role-assignment.model.cjs +2 -0
  114. package/lib/cjs/namespaces/models/role-assignment.model.cjs.map +1 -1
  115. package/lib/cjs/namespaces/models/role-permission.model.cjs +2 -0
  116. package/lib/cjs/namespaces/models/role-permission.model.cjs.map +1 -1
  117. package/lib/cjs/namespaces/models/role.model.cjs +2 -0
  118. package/lib/cjs/namespaces/models/role.model.cjs.map +1 -1
  119. package/lib/cjs/namespaces/models/storage-binding.model.cjs +2 -0
  120. package/lib/cjs/namespaces/models/storage-binding.model.cjs.map +1 -1
  121. package/lib/cjs/namespaces/models/tenant-membership.model.cjs +2 -0
  122. package/lib/cjs/namespaces/models/tenant-membership.model.cjs.map +1 -1
  123. package/lib/cjs/namespaces/models/tenant-profile.model.cjs +2 -0
  124. package/lib/cjs/namespaces/models/tenant-profile.model.cjs.map +1 -1
  125. package/lib/cjs/namespaces/models/tenant.model.cjs +2 -0
  126. package/lib/cjs/namespaces/models/tenant.model.cjs.map +1 -1
  127. package/lib/cjs/namespaces/models/user.model.cjs +2 -0
  128. package/lib/cjs/namespaces/models/user.model.cjs.map +1 -1
  129. package/lib/cjs/namespaces/rls/index.cjs +28 -0
  130. package/lib/cjs/namespaces/rls/index.cjs.map +1 -0
  131. package/lib/cjs/namespaces/rls/principal-resolver.cjs +66 -0
  132. package/lib/cjs/namespaces/rls/principal-resolver.cjs.map +1 -0
  133. package/lib/cjs/namespaces/rls/rls-bootstrap.service.cjs +269 -0
  134. package/lib/cjs/namespaces/rls/rls-bootstrap.service.cjs.map +1 -0
  135. package/lib/cjs/namespaces/rls/rls.constants.cjs +79 -0
  136. package/lib/cjs/namespaces/rls/rls.constants.cjs.map +1 -0
  137. package/lib/cjs/namespaces/rls/rls.template.cjs +719 -0
  138. package/lib/cjs/namespaces/rls/rls.template.cjs.map +1 -0
  139. package/lib/cjs/namespaces/rls/rls.types.cjs +4 -0
  140. package/lib/cjs/namespaces/rls/rls.types.cjs.map +1 -0
  141. package/lib/cjs/namespaces/rls/session-binding.cjs +70 -0
  142. package/lib/cjs/namespaces/rls/session-binding.cjs.map +1 -0
  143. package/lib/cjs/namespaces/services/credential.service.cjs +327 -0
  144. package/lib/cjs/namespaces/services/credential.service.cjs.map +1 -0
  145. package/lib/cjs/namespaces/services/index.cjs +1 -0
  146. package/lib/cjs/namespaces/services/index.cjs.map +1 -1
  147. package/lib/cjs/namespaces/types.cjs +6 -1
  148. package/lib/cjs/namespaces/types.cjs.map +1 -1
  149. package/lib/cjs/redis/adapter.cjs +7 -1
  150. package/lib/cjs/redis/adapter.cjs.map +1 -1
  151. package/lib/cjs/secrets/InfraCredentialBootstrap.cjs +80 -0
  152. package/lib/cjs/secrets/InfraCredentialBootstrap.cjs.map +1 -0
  153. package/lib/cjs/secrets/aws/AwsSecretService.cjs +2 -15
  154. package/lib/cjs/secrets/aws/AwsSecretService.cjs.map +1 -1
  155. package/lib/cjs/secrets/azure/AzureKeyVaultSecretService.cjs +2 -16
  156. package/lib/cjs/secrets/azure/AzureKeyVaultSecretService.cjs.map +1 -1
  157. package/lib/cjs/secrets/core/SecretReference.cjs +1 -0
  158. package/lib/cjs/secrets/core/SecretReference.cjs.map +1 -1
  159. package/lib/cjs/secrets/fs/FsSecretEnvironment.cjs +28 -0
  160. package/lib/cjs/secrets/fs/FsSecretEnvironment.cjs.map +1 -0
  161. package/lib/cjs/secrets/fs/FsSecretService.cjs +420 -0
  162. package/lib/cjs/secrets/fs/FsSecretService.cjs.map +1 -0
  163. package/lib/cjs/secrets/fs/FsSecretServiceConfig.cjs +25 -0
  164. package/lib/cjs/secrets/fs/FsSecretServiceConfig.cjs.map +1 -0
  165. package/lib/cjs/secrets/fs/index.cjs +27 -0
  166. package/lib/cjs/secrets/fs/index.cjs.map +1 -0
  167. package/lib/cjs/secrets/gcp/GcpSecretManagerService.cjs +2 -16
  168. package/lib/cjs/secrets/gcp/GcpSecretManagerService.cjs.map +1 -1
  169. package/lib/cjs/secrets/index.cjs +2 -0
  170. package/lib/cjs/secrets/index.cjs.map +1 -1
  171. package/lib/cjs/secrets/model/ModelSecretService.cjs +335 -43
  172. package/lib/cjs/secrets/model/ModelSecretService.cjs.map +1 -1
  173. package/lib/cjs/secrets/model/Secret.cjs +83 -5
  174. package/lib/cjs/secrets/model/Secret.cjs.map +1 -1
  175. package/lib/cjs/secrets/onepassword/OnePasswordSecretService.cjs +2 -16
  176. package/lib/cjs/secrets/onepassword/OnePasswordSecretService.cjs.map +1 -1
  177. package/lib/cjs/secrets/vault/VaultSecretService.cjs +2 -16
  178. package/lib/cjs/secrets/vault/VaultSecretService.cjs.map +1 -1
  179. package/lib/cjs/shared/environmentValue.cjs +24 -0
  180. package/lib/cjs/shared/environmentValue.cjs.map +1 -1
  181. package/lib/cjs/shared/http/HttpApiService.cjs +190 -0
  182. package/lib/cjs/shared/http/HttpApiService.cjs.map +1 -0
  183. package/lib/cjs/shared/http/hermeticBoot.cjs +150 -0
  184. package/lib/cjs/shared/http/hermeticBoot.cjs.map +1 -0
  185. package/lib/cjs/shared/http/index.cjs +28 -0
  186. package/lib/cjs/shared/http/index.cjs.map +1 -0
  187. package/lib/esm/blob/azure/AzureBlobStoreService.js +13 -21
  188. package/lib/esm/blob/azure/AzureBlobStoreService.js.map +1 -1
  189. package/lib/esm/blob/core/BlobStoreService.js +26 -25
  190. package/lib/esm/blob/core/BlobStoreService.js.map +1 -1
  191. package/lib/esm/blob/gcp/GcsBlobStoreService.js +13 -21
  192. package/lib/esm/blob/gcp/GcsBlobStoreService.js.map +1 -1
  193. package/lib/esm/blob/s3/S3BlobStoreService.js +12 -14
  194. package/lib/esm/blob/s3/S3BlobStoreService.js.map +1 -1
  195. package/lib/esm/blob/s3/S3CompatibleBlobStoreService.js +14 -16
  196. package/lib/esm/blob/s3/S3CompatibleBlobStoreService.js.map +1 -1
  197. package/lib/esm/comms/email/EmailService.js +338 -0
  198. package/lib/esm/comms/email/EmailService.js.map +1 -0
  199. package/lib/esm/comms/email/index.js +12 -0
  200. package/lib/esm/comms/email/index.js.map +1 -0
  201. package/lib/esm/comms/email/mime.js +218 -0
  202. package/lib/esm/comms/email/mime.js.map +1 -0
  203. package/lib/esm/comms/email/smtp.js +166 -0
  204. package/lib/esm/comms/email/smtp.js.map +1 -0
  205. package/lib/esm/comms/environment.js +59 -0
  206. package/lib/esm/comms/environment.js.map +1 -0
  207. package/lib/esm/comms/gmail/GmailService.js +230 -0
  208. package/lib/esm/comms/gmail/GmailService.js.map +1 -0
  209. package/lib/esm/comms/gmail/index.js +7 -0
  210. package/lib/esm/comms/gmail/index.js.map +1 -0
  211. package/lib/esm/comms/index.js +14 -0
  212. package/lib/esm/comms/index.js.map +1 -0
  213. package/lib/esm/comms/slack/SlackService.js +259 -0
  214. package/lib/esm/comms/slack/SlackService.js.map +1 -0
  215. package/lib/esm/comms/slack/index.js +7 -0
  216. package/lib/esm/comms/slack/index.js.map +1 -0
  217. package/lib/esm/comms/teams/TeamsService.js +204 -0
  218. package/lib/esm/comms/teams/TeamsService.js.map +1 -0
  219. package/lib/esm/comms/teams/index.js +7 -0
  220. package/lib/esm/comms/teams/index.js.map +1 -0
  221. package/lib/esm/comms/telegram/TelegramService.js +191 -0
  222. package/lib/esm/comms/telegram/TelegramService.js.map +1 -0
  223. package/lib/esm/comms/telegram/index.js +7 -0
  224. package/lib/esm/comms/telegram/index.js.map +1 -0
  225. package/lib/esm/devops/environment.js +39 -0
  226. package/lib/esm/devops/environment.js.map +1 -0
  227. package/lib/esm/devops/github/GithubService.js +297 -0
  228. package/lib/esm/devops/github/GithubService.js.map +1 -0
  229. package/lib/esm/devops/github/index.js +7 -0
  230. package/lib/esm/devops/github/index.js.map +1 -0
  231. package/lib/esm/devops/gitlab/GitlabService.js +277 -0
  232. package/lib/esm/devops/gitlab/GitlabService.js.map +1 -0
  233. package/lib/esm/devops/gitlab/index.js +7 -0
  234. package/lib/esm/devops/gitlab/index.js.map +1 -0
  235. package/lib/esm/devops/index.js +11 -0
  236. package/lib/esm/devops/index.js.map +1 -0
  237. package/lib/esm/feature-flags/models/FeatureFlag.model.js +2 -0
  238. package/lib/esm/feature-flags/models/FeatureFlag.model.js.map +1 -1
  239. package/lib/esm/feature-flags/models/FeatureFlagAccess.model.js +2 -0
  240. package/lib/esm/feature-flags/models/FeatureFlagAccess.model.js.map +1 -1
  241. package/lib/esm/index.js +3 -3
  242. package/lib/esm/io/airtable/AirtableService.js +261 -0
  243. package/lib/esm/io/airtable/AirtableService.js.map +1 -0
  244. package/lib/esm/io/airtable/index.js +7 -0
  245. package/lib/esm/io/airtable/index.js.map +1 -0
  246. package/lib/esm/io/environment.js +42 -0
  247. package/lib/esm/io/environment.js.map +1 -0
  248. package/lib/esm/io/google-sheets/GoogleSheetsService.js +283 -0
  249. package/lib/esm/io/google-sheets/GoogleSheetsService.js.map +1 -0
  250. package/lib/esm/io/google-sheets/index.js +7 -0
  251. package/lib/esm/io/google-sheets/index.js.map +1 -0
  252. package/lib/esm/io/graphql/GraphqlService.js +138 -0
  253. package/lib/esm/io/graphql/GraphqlService.js.map +1 -0
  254. package/lib/esm/io/graphql/index.js +7 -0
  255. package/lib/esm/io/graphql/index.js.map +1 -0
  256. package/lib/esm/io/index.js +13 -0
  257. package/lib/esm/io/index.js.map +1 -0
  258. package/lib/esm/io/spreadsheet/SpreadsheetService.js +200 -0
  259. package/lib/esm/io/spreadsheet/SpreadsheetService.js.map +1 -0
  260. package/lib/esm/io/spreadsheet/index.js +8 -0
  261. package/lib/esm/io/spreadsheet/index.js.map +1 -0
  262. package/lib/esm/namespaces/index.js +1 -0
  263. package/lib/esm/namespaces/index.js.map +1 -1
  264. package/lib/esm/namespaces/models/credential.model.js +106 -0
  265. package/lib/esm/namespaces/models/credential.model.js.map +1 -0
  266. package/lib/esm/namespaces/models/effective-permission.model.js +2 -0
  267. package/lib/esm/namespaces/models/effective-permission.model.js.map +1 -1
  268. package/lib/esm/namespaces/models/group-membership.model.js +2 -0
  269. package/lib/esm/namespaces/models/group-membership.model.js.map +1 -1
  270. package/lib/esm/namespaces/models/group.model.js +2 -0
  271. package/lib/esm/namespaces/models/group.model.js.map +1 -1
  272. package/lib/esm/namespaces/models/index.js +1 -0
  273. package/lib/esm/namespaces/models/index.js.map +1 -1
  274. package/lib/esm/namespaces/models/inheritance-block.model.js +2 -0
  275. package/lib/esm/namespaces/models/inheritance-block.model.js.map +1 -1
  276. package/lib/esm/namespaces/models/org-unit-closure.model.js +2 -0
  277. package/lib/esm/namespaces/models/org-unit-closure.model.js.map +1 -1
  278. package/lib/esm/namespaces/models/org-unit-membership.model.js +2 -0
  279. package/lib/esm/namespaces/models/org-unit-membership.model.js.map +1 -1
  280. package/lib/esm/namespaces/models/org-unit-profile.model.js +2 -0
  281. package/lib/esm/namespaces/models/org-unit-profile.model.js.map +1 -1
  282. package/lib/esm/namespaces/models/org-unit.model.js +2 -0
  283. package/lib/esm/namespaces/models/org-unit.model.js.map +1 -1
  284. package/lib/esm/namespaces/models/permission.model.js +2 -0
  285. package/lib/esm/namespaces/models/permission.model.js.map +1 -1
  286. package/lib/esm/namespaces/models/principal.model.js +2 -0
  287. package/lib/esm/namespaces/models/principal.model.js.map +1 -1
  288. package/lib/esm/namespaces/models/protected-resource.model.js +2 -0
  289. package/lib/esm/namespaces/models/protected-resource.model.js.map +1 -1
  290. package/lib/esm/namespaces/models/resource-grant.model.js +2 -0
  291. package/lib/esm/namespaces/models/resource-grant.model.js.map +1 -1
  292. package/lib/esm/namespaces/models/role-assignment.model.js +2 -0
  293. package/lib/esm/namespaces/models/role-assignment.model.js.map +1 -1
  294. package/lib/esm/namespaces/models/role-permission.model.js +2 -0
  295. package/lib/esm/namespaces/models/role-permission.model.js.map +1 -1
  296. package/lib/esm/namespaces/models/role.model.js +2 -0
  297. package/lib/esm/namespaces/models/role.model.js.map +1 -1
  298. package/lib/esm/namespaces/models/storage-binding.model.js +2 -0
  299. package/lib/esm/namespaces/models/storage-binding.model.js.map +1 -1
  300. package/lib/esm/namespaces/models/tenant-membership.model.js +2 -0
  301. package/lib/esm/namespaces/models/tenant-membership.model.js.map +1 -1
  302. package/lib/esm/namespaces/models/tenant-profile.model.js +2 -0
  303. package/lib/esm/namespaces/models/tenant-profile.model.js.map +1 -1
  304. package/lib/esm/namespaces/models/tenant.model.js +2 -0
  305. package/lib/esm/namespaces/models/tenant.model.js.map +1 -1
  306. package/lib/esm/namespaces/models/user.model.js +2 -0
  307. package/lib/esm/namespaces/models/user.model.js.map +1 -1
  308. package/lib/esm/namespaces/rls/index.js +11 -0
  309. package/lib/esm/namespaces/rls/index.js.map +1 -0
  310. package/lib/esm/namespaces/rls/principal-resolver.js +61 -0
  311. package/lib/esm/namespaces/rls/principal-resolver.js.map +1 -0
  312. package/lib/esm/namespaces/rls/rls-bootstrap.service.js +261 -0
  313. package/lib/esm/namespaces/rls/rls-bootstrap.service.js.map +1 -0
  314. package/lib/esm/namespaces/rls/rls.constants.js +75 -0
  315. package/lib/esm/namespaces/rls/rls.constants.js.map +1 -0
  316. package/lib/esm/namespaces/rls/rls.template.js +711 -0
  317. package/lib/esm/namespaces/rls/rls.template.js.map +1 -0
  318. package/lib/esm/namespaces/rls/rls.types.js +9 -0
  319. package/lib/esm/namespaces/rls/rls.types.js.map +1 -0
  320. package/lib/esm/namespaces/rls/session-binding.js +65 -0
  321. package/lib/esm/namespaces/rls/session-binding.js.map +1 -0
  322. package/lib/esm/namespaces/services/credential.service.js +322 -0
  323. package/lib/esm/namespaces/services/credential.service.js.map +1 -0
  324. package/lib/esm/namespaces/services/index.js +1 -0
  325. package/lib/esm/namespaces/services/index.js.map +1 -1
  326. package/lib/esm/namespaces/types.js +6 -0
  327. package/lib/esm/namespaces/types.js.map +1 -1
  328. package/lib/esm/redis/adapter.js +7 -1
  329. package/lib/esm/redis/adapter.js.map +1 -1
  330. package/lib/esm/secrets/InfraCredentialBootstrap.js +74 -0
  331. package/lib/esm/secrets/InfraCredentialBootstrap.js.map +1 -0
  332. package/lib/esm/secrets/aws/AwsSecretService.js +3 -13
  333. package/lib/esm/secrets/aws/AwsSecretService.js.map +1 -1
  334. package/lib/esm/secrets/azure/AzureKeyVaultSecretService.js +2 -13
  335. package/lib/esm/secrets/azure/AzureKeyVaultSecretService.js.map +1 -1
  336. package/lib/esm/secrets/core/SecretReference.js +1 -0
  337. package/lib/esm/secrets/core/SecretReference.js.map +1 -1
  338. package/lib/esm/secrets/fs/FsSecretEnvironment.js +24 -0
  339. package/lib/esm/secrets/fs/FsSecretEnvironment.js.map +1 -0
  340. package/lib/esm/secrets/fs/FsSecretService.js +412 -0
  341. package/lib/esm/secrets/fs/FsSecretService.js.map +1 -0
  342. package/lib/esm/secrets/fs/FsSecretServiceConfig.js +21 -0
  343. package/lib/esm/secrets/fs/FsSecretServiceConfig.js.map +1 -0
  344. package/lib/esm/secrets/fs/index.js +10 -0
  345. package/lib/esm/secrets/fs/index.js.map +1 -0
  346. package/lib/esm/secrets/gcp/GcpSecretManagerService.js +2 -13
  347. package/lib/esm/secrets/gcp/GcpSecretManagerService.js.map +1 -1
  348. package/lib/esm/secrets/index.js +2 -0
  349. package/lib/esm/secrets/index.js.map +1 -1
  350. package/lib/esm/secrets/model/ModelSecretService.js +337 -42
  351. package/lib/esm/secrets/model/ModelSecretService.js.map +1 -1
  352. package/lib/esm/secrets/model/Secret.js +86 -7
  353. package/lib/esm/secrets/model/Secret.js.map +1 -1
  354. package/lib/esm/secrets/onepassword/OnePasswordSecretService.js +2 -13
  355. package/lib/esm/secrets/onepassword/OnePasswordSecretService.js.map +1 -1
  356. package/lib/esm/secrets/vault/VaultSecretService.js +2 -13
  357. package/lib/esm/secrets/vault/VaultSecretService.js.map +1 -1
  358. package/lib/esm/shared/environmentValue.js +24 -0
  359. package/lib/esm/shared/environmentValue.js.map +1 -1
  360. package/lib/esm/shared/http/HttpApiService.js +181 -0
  361. package/lib/esm/shared/http/HttpApiService.js.map +1 -0
  362. package/lib/esm/shared/http/hermeticBoot.js +146 -0
  363. package/lib/esm/shared/http/hermeticBoot.js.map +1 -0
  364. package/lib/esm/shared/http/index.js +11 -0
  365. package/lib/esm/shared/http/index.js.map +1 -0
  366. package/lib/types/blob/azure/AzureBlobStoreService.d.cts +7 -7
  367. package/lib/types/blob/azure/AzureBlobStoreService.d.mts +7 -7
  368. package/lib/types/blob/core/BlobStoreService.d.cts +28 -27
  369. package/lib/types/blob/core/BlobStoreService.d.mts +28 -27
  370. package/lib/types/blob/gcp/GcsBlobStoreService.d.cts +7 -7
  371. package/lib/types/blob/gcp/GcsBlobStoreService.d.mts +7 -7
  372. package/lib/types/blob/s3/S3BlobStoreService.d.cts +9 -1
  373. package/lib/types/blob/s3/S3BlobStoreService.d.mts +9 -1
  374. package/lib/types/blob/s3/S3CompatibleBlobStoreService.d.cts +11 -15
  375. package/lib/types/blob/s3/S3CompatibleBlobStoreService.d.mts +11 -15
  376. package/lib/types/comms/email/EmailService.d.cts +184 -0
  377. package/lib/types/comms/email/EmailService.d.mts +184 -0
  378. package/lib/types/comms/email/index.d.cts +11 -0
  379. package/lib/types/comms/email/index.d.mts +11 -0
  380. package/lib/types/comms/email/mime.d.cts +84 -0
  381. package/lib/types/comms/email/mime.d.mts +84 -0
  382. package/lib/types/comms/email/smtp.d.cts +107 -0
  383. package/lib/types/comms/email/smtp.d.mts +107 -0
  384. package/lib/types/comms/environment.d.cts +84 -0
  385. package/lib/types/comms/environment.d.mts +84 -0
  386. package/lib/types/comms/gmail/GmailService.d.cts +190 -0
  387. package/lib/types/comms/gmail/GmailService.d.mts +190 -0
  388. package/lib/types/comms/gmail/index.d.cts +6 -0
  389. package/lib/types/comms/gmail/index.d.mts +6 -0
  390. package/lib/types/comms/index.d.cts +13 -0
  391. package/lib/types/comms/index.d.mts +13 -0
  392. package/lib/types/comms/slack/SlackService.d.cts +259 -0
  393. package/lib/types/comms/slack/SlackService.d.mts +259 -0
  394. package/lib/types/comms/slack/index.d.cts +6 -0
  395. package/lib/types/comms/slack/index.d.mts +6 -0
  396. package/lib/types/comms/teams/TeamsService.d.cts +172 -0
  397. package/lib/types/comms/teams/TeamsService.d.mts +172 -0
  398. package/lib/types/comms/teams/index.d.cts +6 -0
  399. package/lib/types/comms/teams/index.d.mts +6 -0
  400. package/lib/types/comms/telegram/TelegramService.d.cts +202 -0
  401. package/lib/types/comms/telegram/TelegramService.d.mts +202 -0
  402. package/lib/types/comms/telegram/index.d.cts +6 -0
  403. package/lib/types/comms/telegram/index.d.mts +6 -0
  404. package/lib/types/devops/environment.d.cts +62 -0
  405. package/lib/types/devops/environment.d.mts +62 -0
  406. package/lib/types/devops/github/GithubService.d.cts +287 -0
  407. package/lib/types/devops/github/GithubService.d.mts +287 -0
  408. package/lib/types/devops/github/index.d.cts +6 -0
  409. package/lib/types/devops/github/index.d.mts +6 -0
  410. package/lib/types/devops/gitlab/GitlabService.d.cts +277 -0
  411. package/lib/types/devops/gitlab/GitlabService.d.mts +277 -0
  412. package/lib/types/devops/gitlab/index.d.cts +6 -0
  413. package/lib/types/devops/gitlab/index.d.mts +6 -0
  414. package/lib/types/devops/index.d.cts +10 -0
  415. package/lib/types/devops/index.d.mts +10 -0
  416. package/lib/types/index.d.cts +2 -2
  417. package/lib/types/index.d.mts +2 -2
  418. package/lib/types/io/airtable/AirtableService.d.cts +268 -0
  419. package/lib/types/io/airtable/AirtableService.d.mts +268 -0
  420. package/lib/types/io/airtable/index.d.cts +6 -0
  421. package/lib/types/io/airtable/index.d.mts +6 -0
  422. package/lib/types/io/environment.d.cts +67 -0
  423. package/lib/types/io/environment.d.mts +67 -0
  424. package/lib/types/io/google-sheets/GoogleSheetsService.d.cts +204 -0
  425. package/lib/types/io/google-sheets/GoogleSheetsService.d.mts +204 -0
  426. package/lib/types/io/google-sheets/index.d.cts +6 -0
  427. package/lib/types/io/google-sheets/index.d.mts +6 -0
  428. package/lib/types/io/graphql/GraphqlService.d.cts +173 -0
  429. package/lib/types/io/graphql/GraphqlService.d.mts +173 -0
  430. package/lib/types/io/graphql/index.d.cts +6 -0
  431. package/lib/types/io/graphql/index.d.mts +6 -0
  432. package/lib/types/io/index.d.cts +12 -0
  433. package/lib/types/io/index.d.mts +12 -0
  434. package/lib/types/io/spreadsheet/SpreadsheetService.d.cts +144 -0
  435. package/lib/types/io/spreadsheet/SpreadsheetService.d.mts +144 -0
  436. package/lib/types/io/spreadsheet/index.d.cts +7 -0
  437. package/lib/types/io/spreadsheet/index.d.mts +7 -0
  438. package/lib/types/namespaces/index.d.cts +1 -0
  439. package/lib/types/namespaces/index.d.mts +1 -0
  440. package/lib/types/namespaces/models/credential.model.d.cts +23 -0
  441. package/lib/types/namespaces/models/credential.model.d.mts +23 -0
  442. package/lib/types/namespaces/models/index.d.cts +1 -0
  443. package/lib/types/namespaces/models/index.d.mts +1 -0
  444. package/lib/types/namespaces/rls/index.d.cts +10 -0
  445. package/lib/types/namespaces/rls/index.d.mts +10 -0
  446. package/lib/types/namespaces/rls/principal-resolver.d.cts +47 -0
  447. package/lib/types/namespaces/rls/principal-resolver.d.mts +47 -0
  448. package/lib/types/namespaces/rls/rls-bootstrap.service.d.cts +157 -0
  449. package/lib/types/namespaces/rls/rls-bootstrap.service.d.mts +157 -0
  450. package/lib/types/namespaces/rls/rls.constants.d.cts +52 -0
  451. package/lib/types/namespaces/rls/rls.constants.d.mts +52 -0
  452. package/lib/types/namespaces/rls/rls.template.d.cts +42 -0
  453. package/lib/types/namespaces/rls/rls.template.d.mts +42 -0
  454. package/lib/types/namespaces/rls/rls.types.d.cts +77 -0
  455. package/lib/types/namespaces/rls/rls.types.d.mts +77 -0
  456. package/lib/types/namespaces/rls/session-binding.d.cts +87 -0
  457. package/lib/types/namespaces/rls/session-binding.d.mts +87 -0
  458. package/lib/types/namespaces/services/credential.service.d.cts +175 -0
  459. package/lib/types/namespaces/services/credential.service.d.mts +175 -0
  460. package/lib/types/namespaces/services/index.d.cts +1 -0
  461. package/lib/types/namespaces/services/index.d.mts +1 -0
  462. package/lib/types/namespaces/types.d.cts +37 -0
  463. package/lib/types/namespaces/types.d.mts +37 -0
  464. package/lib/types/redis/adapter.d.cts +2 -0
  465. package/lib/types/redis/adapter.d.mts +2 -0
  466. package/lib/types/redis/types.d.cts +27 -2
  467. package/lib/types/redis/types.d.mts +27 -2
  468. package/lib/types/secrets/InfraCredentialBootstrap.d.cts +100 -0
  469. package/lib/types/secrets/InfraCredentialBootstrap.d.mts +100 -0
  470. package/lib/types/secrets/core/SecretTypes.d.cts +15 -1
  471. package/lib/types/secrets/core/SecretTypes.d.mts +15 -1
  472. package/lib/types/secrets/fs/FsSecretEnvironment.d.cts +42 -0
  473. package/lib/types/secrets/fs/FsSecretEnvironment.d.mts +42 -0
  474. package/lib/types/secrets/fs/FsSecretService.d.cts +207 -0
  475. package/lib/types/secrets/fs/FsSecretService.d.mts +207 -0
  476. package/lib/types/secrets/fs/FsSecretServiceConfig.d.cts +37 -0
  477. package/lib/types/secrets/fs/FsSecretServiceConfig.d.mts +37 -0
  478. package/lib/types/secrets/fs/index.d.cts +9 -0
  479. package/lib/types/secrets/fs/index.d.mts +9 -0
  480. package/lib/types/secrets/index.d.cts +2 -0
  481. package/lib/types/secrets/index.d.mts +2 -0
  482. package/lib/types/secrets/model/ModelSecretService.d.cts +190 -1
  483. package/lib/types/secrets/model/ModelSecretService.d.mts +190 -1
  484. package/lib/types/secrets/model/Secret.d.cts +44 -3
  485. package/lib/types/secrets/model/Secret.d.mts +44 -3
  486. package/lib/types/shared/environmentValue.d.cts +24 -0
  487. package/lib/types/shared/environmentValue.d.mts +24 -0
  488. package/lib/types/shared/http/HttpApiService.d.cts +193 -0
  489. package/lib/types/shared/http/HttpApiService.d.mts +193 -0
  490. package/lib/types/shared/http/hermeticBoot.d.cts +84 -0
  491. package/lib/types/shared/http/hermeticBoot.d.mts +84 -0
  492. package/lib/types/shared/http/index.d.cts +10 -0
  493. package/lib/types/shared/http/index.d.mts +10 -0
  494. package/package.json +180 -3
  495. package/sql/002_rls.sql +660 -15
  496. package/sql/004_credentials.sql +46 -0
@@ -0,0 +1,376 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.EmailService = void 0;
37
+ /**
38
+ * @module integrations/comms/email/service
39
+ * @summary Email integration service for sending mail and reading inboxes across SMTP, Microsoft Graph, and IMAP.
40
+ * @description Exposes an undecorated client-based service that
41
+ * multiplexes three delivery surfaces behind one config: SMTP delivery through
42
+ * the built-in {@link SmtpClient} (raw MIME built by {@link buildEmail}), and
43
+ * Microsoft Graph (`sendMail`, message listing) through {@link HttpApiService}
44
+ * with a bearer token. `listInbox` reads via Graph while `listImapMessages`
45
+ * dynamically imports the optional `imapflow` package for direct IMAP reads.
46
+ * Configuration comes from an explicit {@link EmailServiceConfig} or the
47
+ * `comms.email` environment slice; failures are mapped to decaf errors via
48
+ * {@link httpError} (Graph) or wrapped `InternalError`s (SMTP).
49
+ */
50
+ const db_decorators_1 = require("@decaf-ts/db-decorators");
51
+ const environment_js_1 = require("./../environment.cjs");
52
+ const environmentValue_js_1 = require("./../../shared/environmentValue.cjs");
53
+ const index_js_1 = require("./../../shared/http/index.cjs");
54
+ const smtp_js_1 = require("./smtp.cjs");
55
+ const mime_js_1 = require("./mime.cjs");
56
+ /**
57
+ * ISO 8601 date shapes accepted by the Graph `receivedDateTime` filter.
58
+ * Date-only values and full timestamps (with optional fractional seconds and
59
+ * `Z`/offset) are allowed; anything else is rejected before it can reach
60
+ * `$filter`.
61
+ */
62
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:\d{2})?)?$/;
63
+ /**
64
+ * Validates and returns an ISO 8601 date for a Graph `$filter` literal.
65
+ *
66
+ * @param value - Caller-supplied `since` value.
67
+ * @returns The validated ISO date string.
68
+ * @throws {BadRequestError} when the value is not a parseable ISO 8601 date.
69
+ */
70
+ function assertIsoDate(value) {
71
+ if (!ISO_DATE.test(value) || Number.isNaN(Date.parse(value))) {
72
+ throw new db_decorators_1.BadRequestError("Email inbox 'since' filter must be an ISO 8601 date");
73
+ }
74
+ return value;
75
+ }
76
+ /**
77
+ * Escapes a value for use inside an OData single-quoted string literal.
78
+ *
79
+ * @param value - Raw filter value.
80
+ * @returns The value with embedded single quotes doubled per OData rules.
81
+ */
82
+ function escapeODataString(value) {
83
+ return value.replace(/'/g, "''");
84
+ }
85
+ /**
86
+ * @description Multi-provider email send/inbox service
87
+ * @summary Resolves the delivery provider from config (`provider`, or inferred
88
+ * from the presence of `host` vs `token`), builds RFC 5322 MIME with
89
+ * UTF-8-encoded headers via {@link buildEmail}, then delivers through SMTP or
90
+ * posts to Graph. Inbox reads go through Graph `messages` (with `$top`,
91
+ * `$filter`, `$orderby`) or the optional `imapflow` package.
92
+ * @category Comms
93
+ * @memberOf module:integrations/comms/email/service
94
+ */
95
+ class EmailService extends index_js_1.HttpApiService {
96
+ constructor() {
97
+ super(...arguments);
98
+ this.serviceName = "Email";
99
+ }
100
+ /**
101
+ * @description Default Microsoft Graph base URL used when no override is configured
102
+ * @returns The Graph v1.0 endpoint URL
103
+ */
104
+ defaultBaseUrl() {
105
+ return "https://graph.microsoft.com/v1.0";
106
+ }
107
+ /**
108
+ * @description Authorization headers for Graph requests
109
+ * @param config - Resolved service config
110
+ * @returns A bearer-token `Authorization` header map, empty when no `token` is configured
111
+ */
112
+ authHeaders(config) {
113
+ return config.token ? { Authorization: `Bearer ${config.token}` } : {};
114
+ }
115
+ /**
116
+ * @description Pins the SMTP plaintext-AUTH default on top of the base initialization
117
+ * @summary Runs the {@link HttpApiService} initialization (explicit config
118
+ * merged over the `comms.email` environment slice) and then defaults an
119
+ * unresolved `allowPlaintextAuth` to `false`, so credentials are only sent
120
+ * over a TLS-protected session unless the config explicitly opts in. This
121
+ * closes the F1 residual where an environment-only `allowPlaintextAuth`
122
+ * opt-in would otherwise reach a boot whose explicit config omits the key
123
+ * (defense in depth on top of {@link bootWithoutEnvironment}, which disables
124
+ * the environment slice entirely on the node path).
125
+ * @param {...any[]} args - An optional `Partial<EmailServiceConfig>`, optionally followed by a decaf `Context`.
126
+ * @returns {Promise<{config: EmailServiceConfig, client: AxiosInstance}>} The merged configuration, with `allowPlaintextAuth` defaulted to `false` when unset, and the configured Axios instance.
127
+ */
128
+ async initialize(...args) {
129
+ const initialized = await super.initialize(...args);
130
+ initialized.config.allowPlaintextAuth =
131
+ initialized.config.allowPlaintextAuth ?? false;
132
+ return initialized;
133
+ }
134
+ /**
135
+ * @description Builds service config from the `comms.email` environment slice
136
+ * @returns A partial config when either an SMTP `host` or a Graph `token` is present, otherwise `undefined`
137
+ */
138
+ configFromEnvironment() {
139
+ const env = environment_js_1.CommsEnvironment.comms.email;
140
+ const host = (0, environmentValue_js_1.envString)(env?.host);
141
+ const token = (0, environmentValue_js_1.envString)(env?.token);
142
+ if (!host && !token)
143
+ return undefined;
144
+ const provider = (0, environmentValue_js_1.envString)(env.provider);
145
+ return {
146
+ provider: provider ?? (host ? "smtp" : "graph"),
147
+ host,
148
+ port: (0, environmentValue_js_1.envNumber)(env.port),
149
+ secure: (0, environmentValue_js_1.envBoolean)(env.secure),
150
+ username: (0, environmentValue_js_1.envString)(env.username),
151
+ password: (0, environmentValue_js_1.envString)(env.password),
152
+ allowPlaintextAuth: (0, environmentValue_js_1.envBoolean)(env.allowPlaintextAuth),
153
+ from: (0, environmentValue_js_1.envString)(env.from),
154
+ token,
155
+ graphBaseUrl: (0, environmentValue_js_1.envString)(env.graphBaseUrl),
156
+ timeout: (0, environmentValue_js_1.envNumber)(env.timeout),
157
+ };
158
+ }
159
+ /**
160
+ * @description Selects the delivery provider
161
+ * @summary Prefers an explicit `provider`, then infers `smtp` from a
162
+ * configured `host` and `graph` from a configured `token`.
163
+ * @param config - Resolved service config
164
+ * @returns The resolved provider
165
+ * @throws {InternalError} when neither an SMTP host nor a Graph token is configured
166
+ */
167
+ resolveProvider(config) {
168
+ if (config.provider)
169
+ return config.provider;
170
+ if (config.host)
171
+ return "smtp";
172
+ if (config.token)
173
+ return "graph";
174
+ throw new db_decorators_1.InternalError("Email requires either an SMTP host or a Microsoft Graph token");
175
+ }
176
+ /**
177
+ * @description Resolves the fallback sender address
178
+ * @summary Uses `from`, then `username`, then the `From` header override.
179
+ * @param config - Resolved service config
180
+ * @returns The resolved sender address
181
+ * @throws {InternalError} when no sender address can be resolved
182
+ */
183
+ resolveFrom(config) {
184
+ const from = config.from ?? config.username ?? config.headers?.["From"] ?? undefined;
185
+ if (!from)
186
+ throw new db_decorators_1.InternalError("Email requires a sender address");
187
+ return from;
188
+ }
189
+ /**
190
+ * @description Sends an email through the resolved provider
191
+ * @summary Builds the raw MIME message (honouring `input.from`, else the
192
+ * resolved config sender), then delivers via SMTP or Graph. SMTP config
193
+ * passes `allowPlaintextAuth` through unchanged, so the plaintext-AUTH
194
+ * opt-out is inherited from the service config.
195
+ * @param input - Message input (recipients, subject, text/html body, attachments)
196
+ * @returns The send result with the generated `Message-ID` and provider
197
+ * @throws {BadRequestError} when an address, attachment filename, or content type fails validation (via {@link buildEmail})
198
+ * @throws {InternalError} when the provider cannot be resolved, the SMTP host is missing, plaintext AUTH is refused, or SMTP delivery fails
199
+ */
200
+ async send(input) {
201
+ const config = this.config;
202
+ const provider = this.resolveProvider(config);
203
+ const from = input.from || this.resolveFrom(config);
204
+ const built = (0, mime_js_1.buildEmail)({ ...input, from });
205
+ if (provider === "graph") {
206
+ await this.sendViaGraph(built.raw, from);
207
+ return {
208
+ messageId: built.messageId,
209
+ from,
210
+ recipients: built.recipients,
211
+ provider,
212
+ };
213
+ }
214
+ if (!config.host) {
215
+ throw new db_decorators_1.InternalError("Email SMTP provider requires a host");
216
+ }
217
+ const client = new smtp_js_1.SmtpClient({
218
+ host: config.host,
219
+ port: config.port,
220
+ secure: config.secure,
221
+ username: config.username,
222
+ password: config.password,
223
+ timeout: config.timeout,
224
+ allowPlaintextAuth: config.allowPlaintextAuth,
225
+ });
226
+ try {
227
+ await client.connect();
228
+ await client.send(built.from, built.recipients, built.raw);
229
+ return {
230
+ messageId: built.messageId,
231
+ from,
232
+ recipients: built.recipients,
233
+ provider,
234
+ };
235
+ }
236
+ catch (error) {
237
+ if (error instanceof db_decorators_1.InternalError)
238
+ throw error;
239
+ throw new db_decorators_1.InternalError(`Email SMTP delivery failed: ${error instanceof Error ? error.message : String(error)}`);
240
+ }
241
+ finally {
242
+ await client.close().catch(() => undefined);
243
+ }
244
+ }
245
+ /**
246
+ * @description Posts a raw MIME message to the Microsoft Graph `sendMail` endpoint
247
+ * @summary Sends the base64-encoded raw message to
248
+ * `/users/<from>/sendMail` (or `/me/sendMail` when no sender is resolved)
249
+ * with the configured `graphBaseUrl`/`baseUrl`.
250
+ * @param raw - Raw RFC 5322 message text
251
+ * @param from - Sender mailbox (UPN) for the Graph path
252
+ * @throws {Error} Graph error mapped through {@link httpError}
253
+ */
254
+ async sendViaGraph(raw, from) {
255
+ const config = this.config;
256
+ this.requireToken(config);
257
+ const baseUrl = config.graphBaseUrl ??
258
+ config.baseUrl ??
259
+ "https://graph.microsoft.com/v1.0";
260
+ const path = from
261
+ ? `/users/${encodeURIComponent(from)}/sendMail`
262
+ : "/me/sendMail";
263
+ try {
264
+ await this.client.post(`${baseUrl}${path}`, Buffer.from(raw, "utf8").toString("base64"), {
265
+ headers: { "Content-Type": "text/plain" },
266
+ });
267
+ }
268
+ catch (error) {
269
+ throw (0, index_js_1.httpError)("Microsoft Graph", "sendMail", error);
270
+ }
271
+ }
272
+ /**
273
+ * @description Lists messages from a Graph mailbox
274
+ * @summary Queries `<mailbox>/messages` with `$top`, an optional
275
+ * subject/since `$filter`, and `receivedDateTime desc` ordering. The mailbox
276
+ * is URL-encoded as a single path segment, quotes in the subject are escaped
277
+ * for the OData string literal, and `since` must be an ISO 8601 date.
278
+ * @param query - Inbox filter (mailbox, limit, since, subject)
279
+ * @returns The raw Graph message records
280
+ * @throws {BadRequestError} when `since` is not an ISO 8601 date
281
+ * @throws {InternalError} when no `token` is configured; Graph errors mapped through {@link httpError}
282
+ */
283
+ async listInbox(query = {}) {
284
+ const config = this.config;
285
+ this.requireToken(config);
286
+ const baseUrl = config.graphBaseUrl ??
287
+ config.baseUrl ??
288
+ "https://graph.microsoft.com/v1.0";
289
+ const mailbox = encodeURIComponent(query.mailbox ?? "me");
290
+ const filters = [
291
+ query.subject
292
+ ? `contains(subject,'${escapeODataString(query.subject)}')`
293
+ : undefined,
294
+ query.since
295
+ ? `receivedDateTime ge ${assertIsoDate(query.since)}`
296
+ : undefined,
297
+ ].filter(Boolean);
298
+ try {
299
+ const response = await this.client.get(`${baseUrl}/${mailbox}/messages`, {
300
+ params: {
301
+ $top: query.limit ?? 25,
302
+ $filter: filters.length ? filters.join(" and ") : undefined,
303
+ $orderby: "receivedDateTime desc",
304
+ },
305
+ });
306
+ return response.data.value ?? [];
307
+ }
308
+ catch (error) {
309
+ throw (0, index_js_1.httpError)("Microsoft Graph", "list messages", error);
310
+ }
311
+ }
312
+ /**
313
+ * @description Lists messages directly over IMAP
314
+ * @summary Dynamically imports the optional `imapflow` package, connects to
315
+ * `host` (default port 993, implicit TLS), and fetches the newest messages
316
+ * from `INBOX`.
317
+ *
318
+ * R2 direct-library-wrap justification: IMAP is a stateful protocol
319
+ * (mailbox locks, sequence/UID state, IDLE) whose correct implementation is
320
+ * large and security-sensitive. `imapflow` is the maintained n8n-vetted
321
+ * client for exactly this surface, so wrapping it is deliberate; a local
322
+ * reimplementation would add risk without changing the node contract. The
323
+ * package stays optional so SMTP/Graph-only consumers do not install it.
324
+ * @param query - Inbox filter (limit only is honoured by IMAP)
325
+ * @returns The fetched IMAP message records
326
+ * @throws {InternalError} when `imapflow` is not installed, no `host` is configured, or the IMAP session fails
327
+ */
328
+ async listImapMessages(query = {}) {
329
+ let ImapFlow;
330
+ try {
331
+ const moduleName = "imapflow";
332
+ const imported = (await Promise.resolve(`${moduleName}`).then(s => __importStar(require(s))));
333
+ ImapFlow = imported.ImapFlow;
334
+ if (!ImapFlow)
335
+ throw new Error("imapflow did not export ImapFlow");
336
+ }
337
+ catch {
338
+ throw new db_decorators_1.InternalError("IMAP reads require the optional 'imapflow' package; install it to use this surface");
339
+ }
340
+ const config = this.config;
341
+ if (!config.host)
342
+ throw new db_decorators_1.InternalError("IMAP requires a host");
343
+ const client = new ImapFlow({
344
+ host: config.host,
345
+ port: config.port ?? 993,
346
+ secure: config.secure ?? true,
347
+ auth: {
348
+ user: config.username,
349
+ pass: config.password,
350
+ },
351
+ });
352
+ const messages = [];
353
+ await client.connect();
354
+ try {
355
+ const lock = await client.getMailboxLock("INBOX");
356
+ try {
357
+ const limit = query.limit ?? 25;
358
+ for await (const message of client.fetch(`${Math.max(1, limit)}:*`, { envelope: true, source: false }, { uid: false })) {
359
+ messages.push(message);
360
+ if (messages.length >= limit)
361
+ break;
362
+ }
363
+ }
364
+ finally {
365
+ lock.release();
366
+ }
367
+ }
368
+ finally {
369
+ await client.logout().catch(() => undefined);
370
+ }
371
+ return messages;
372
+ }
373
+ }
374
+ exports.EmailService = EmailService;
375
+ //# sourceMappingURL=EmailService.js.map
376
+ //# sourceMappingURL=EmailService.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comms/email/EmailService.cjs","sourceRoot":"","sources":["comms/email/EmailService.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ /**
18
+ * @module integrations/comms/email
19
+ * @summary Email service (SMTP + Microsoft Graph send, Graph/IMAP inbox reads).
20
+ * @description Re-exports the {@link EmailService} and its config/result
21
+ * types, the raw MIME builder, and the nodemailer-backed {@link SmtpClient}
22
+ * with its {@link SmtpConfig}
23
+ * (also available directly from the `./smtp` subpath).
24
+ */
25
+ __exportStar(require("./EmailService.cjs"), exports);
26
+ __exportStar(require("./mime.cjs"), exports);
27
+ __exportStar(require("./smtp.cjs"), exports);
28
+ //# sourceMappingURL=index.js.map
29
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comms/email/index.cjs","sourceRoot":"","sources":["comms/email/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;;;GAOG;AACH,oDAAkC;AAClC,4CAA0B;AAC1B,4CAA0B;AAC1B,iCAAiC"}
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertEmailAddress = assertEmailAddress;
4
+ exports.encodeHeader = encodeHeader;
5
+ exports.parseAddressList = parseAddressList;
6
+ exports.buildEmail = buildEmail;
7
+ /**
8
+ * @module integrations/comms/email/mime
9
+ * @summary RFC 5322/MIME message building and address handling for the Email service.
10
+ * @description Builds a complete raw MIME message from an
11
+ * {@link EmailMessageInput}: UTF-8 headers are RFC 2047 base64-word encoded
12
+ * ({@link encodeHeader}), recipient lists are comma-split and trimmed
13
+ * ({@link parseAddressList}), and the body becomes a
14
+ * `text/plain`/`text/html` `multipart/alternative` (when both are present),
15
+ * a single part otherwise — wrapped in `multipart/mixed` with base64
16
+ * attachments when any are supplied. Boundary markers and the `Message-ID`
17
+ * carry a random UUID per message.
18
+ *
19
+ * Every address, attachment filename, and content type is validated against
20
+ * conservative allowlists ({@link assertEmailAddress} and friends) before it is
21
+ * written into a header, so workflow input can never inject MIME headers or
22
+ * SMTP commands. All validation and structural failures (missing recipient,
23
+ * forbidden control characters, non-mailbox addresses, unsafe filenames or
24
+ * content types) throw decaf `BadRequestError`s.
25
+ */
26
+ const node_crypto_1 = require("node:crypto");
27
+ const db_decorators_1 = require("@decaf-ts/db-decorators");
28
+ const ASCII_HEADER = /^[\x20-\x7E]*$/;
29
+ /**
30
+ * Characters that must never appear in an address, attachment filename, or
31
+ * content type: CR/LF (header and SMTP-command injection), NUL, and any other
32
+ * C0/C1 control character.
33
+ */
34
+ // eslint-disable-next-line no-control-regex -- matching control characters is the purpose of this allowlist
35
+ const FORBIDDEN_CONTROL = /[\x00-\x1F\x7F-\x9F]/;
36
+ /**
37
+ * Conservative mailbox allowlist: a dot-atom local part followed by a
38
+ * dot-separated domain. Display names are deliberately not accepted because
39
+ * the envelope (`MAIL FROM`/`RCPT TO`) and the MIME headers share the same
40
+ * validated value.
41
+ */
42
+ const EMAIL_ADDRESS = /^[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]+@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$/;
43
+ /**
44
+ * Allowlisted MIME content type: `type/subtype` plus optional
45
+ * `; parameter=value` pairs whose values are tokens or quoted strings without
46
+ * control characters, quotes, or backslashes.
47
+ */
48
+ const CONTENT_TYPE = /^[A-Za-z0-9!#$&^_.+-]+\/[A-Za-z0-9!#$&^_.+-]+(?:\s*;\s*[A-Za-z0-9-]+=(?:"[^"\\\r\n]*"|[A-Za-z0-9!#$&^_.+-]+))*$/;
49
+ /**
50
+ * Rejects any value carrying CR/LF, NUL, or another control character.
51
+ *
52
+ * @param value - Value about to be written into a header, SMTP command, or MIME part.
53
+ * @param field - Human-readable field name used in the error message.
54
+ * @throws {BadRequestError} when the value contains a forbidden control character.
55
+ */
56
+ function rejectControlCharacters(value, field) {
57
+ if (FORBIDDEN_CONTROL.test(value)) {
58
+ throw new db_decorators_1.BadRequestError(`Email ${field} contains a forbidden control character`);
59
+ }
60
+ }
61
+ /**
62
+ * Validates a mailbox address against the allowlist and returns it trimmed.
63
+ *
64
+ * @param value - Candidate address.
65
+ * @param field - Human-readable field name used in the error message.
66
+ * @returns The trimmed, validated mailbox address.
67
+ * @throws {BadRequestError} when the address contains control characters or is not a bare mailbox.
68
+ */
69
+ function assertEmailAddress(value, field = "address") {
70
+ rejectControlCharacters(value, field);
71
+ const address = value.trim();
72
+ if (!EMAIL_ADDRESS.test(address)) {
73
+ throw new db_decorators_1.BadRequestError(`Email ${field} is not a valid mailbox address`);
74
+ }
75
+ return address;
76
+ }
77
+ /**
78
+ * Validates an attachment filename for safe inclusion in a quoted MIME header.
79
+ *
80
+ * @param value - Candidate filename.
81
+ * @throws {BadRequestError} when the filename carries control characters, a quote, or a backslash.
82
+ */
83
+ function assertAttachmentFilename(value) {
84
+ rejectControlCharacters(value, "attachment filename");
85
+ if (/["\\]/.test(value)) {
86
+ throw new db_decorators_1.BadRequestError("Email attachment filename contains a forbidden character");
87
+ }
88
+ }
89
+ /**
90
+ * Validates an attachment content type against the MIME allowlist.
91
+ *
92
+ * @param value - Declared content type.
93
+ * @throws {BadRequestError} when the value is not an allowlisted `type/subtype` with safe parameters.
94
+ */
95
+ function assertContentType(value) {
96
+ rejectControlCharacters(value, "attachment content type");
97
+ if (!CONTENT_TYPE.test(value.trim())) {
98
+ throw new db_decorators_1.BadRequestError("Email attachment content type is not an allowed MIME type");
99
+ }
100
+ }
101
+ /**
102
+ * @description Encodes a MIME header value safely
103
+ * @summary Pure-ASCII values pass through; anything else becomes an RFC 2047
104
+ * `=?UTF-8?B?...?=` encoded word.
105
+ * @param value - Raw header value
106
+ * @returns The header value safe for raw message transport
107
+ */
108
+ function encodeHeader(value) {
109
+ if (ASCII_HEADER.test(value))
110
+ return value;
111
+ return `=?UTF-8?B?${Buffer.from(value, "utf8").toString("base64")}?=`;
112
+ }
113
+ /**
114
+ * @description Normalizes a recipient input into an allowlisted address list
115
+ * @summary Splits comma-separated strings, trims entries, drops empties, and
116
+ * validates every remaining entry as a bare mailbox address. Values carrying
117
+ * CR/LF, NUL, or other control characters are rejected outright so workflow
118
+ * input can never inject MIME headers or SMTP envelope commands.
119
+ * @param value - Single address, comma-separated string, array, or `undefined`
120
+ * @returns The trimmed, validated list of addresses
121
+ * @throws {BadRequestError} when an entry is not a valid mailbox address
122
+ */
123
+ function parseAddressList(value) {
124
+ if (!value)
125
+ return [];
126
+ const values = Array.isArray(value) ? value : [value];
127
+ return values
128
+ .flatMap((entry) => entry.split(","))
129
+ .map((entry) => entry.trim())
130
+ .filter((entry) => entry.length > 0)
131
+ .map((entry) => assertEmailAddress(entry, "recipient"));
132
+ }
133
+ function base64Lines(value) {
134
+ return Buffer.from(value, "utf8")
135
+ .toString("base64")
136
+ .replace(/(.{76})/g, "$1\r\n");
137
+ }
138
+ function textPart(contentType, value) {
139
+ return `Content-Type: ${contentType}; charset=utf-8\r\nContent-Transfer-Encoding: base64\r\n\r\n${base64Lines(value)}`;
140
+ }
141
+ function bodyEntity(input) {
142
+ if (input.text !== undefined && input.html !== undefined) {
143
+ const boundary = `alt-${(0, node_crypto_1.randomUUID)()}`;
144
+ return [
145
+ `Content-Type: multipart/alternative; boundary="${boundary}"`,
146
+ "",
147
+ `--${boundary}`,
148
+ textPart("text/plain", input.text),
149
+ `--${boundary}`,
150
+ textPart("text/html", input.html),
151
+ `--${boundary}--`,
152
+ ].join("\r\n");
153
+ }
154
+ if (input.html !== undefined) {
155
+ return textPart("text/html", input.html);
156
+ }
157
+ return textPart("text/plain", input.text ?? "");
158
+ }
159
+ function attachmentPart(attachment) {
160
+ const content = attachment.encoding === "utf8"
161
+ ? base64Lines(attachment.content)
162
+ : attachment.content.replace(/\r?\n/g, "");
163
+ const contentType = attachment.contentType ?? "application/octet-stream";
164
+ assertAttachmentFilename(attachment.filename);
165
+ assertContentType(contentType);
166
+ return [
167
+ `Content-Type: ${contentType}; name="${encodeHeader(attachment.filename)}"`,
168
+ "Content-Transfer-Encoding: base64",
169
+ `Content-Disposition: attachment; filename="${encodeHeader(attachment.filename)}"`,
170
+ "",
171
+ content,
172
+ ].join("\r\n");
173
+ }
174
+ function entity(input) {
175
+ const attachments = input.attachments ?? [];
176
+ if (attachments.length === 0)
177
+ return bodyEntity(input);
178
+ const boundary = `mix-${(0, node_crypto_1.randomUUID)()}`;
179
+ const parts = [bodyEntity(input), ...attachments.map(attachmentPart)];
180
+ return `Content-Type: multipart/mixed; boundary="${boundary}"\r\n\r\n${parts
181
+ .map((part) => `--${boundary}\r\n${part}`)
182
+ .join("\r\n")}\r\n--${boundary}--`;
183
+ }
184
+ /**
185
+ * @description Builds the complete raw MIME message
186
+ * @summary Generates the `Message-ID`, resolves recipients (throwing when
187
+ * none remain), emits the standard headers, and assembles the body entity
188
+ * (alternative text/HTML parts, plus attachments when present).
189
+ * @param input - Message input
190
+ * @returns The built message with raw text, sender, recipients, and `Message-ID`
191
+ * @throws {BadRequestError} when the message has no recipient or any address,
192
+ * attachment filename, or content type fails validation
193
+ */
194
+ function buildEmail(input) {
195
+ const messageId = `<${(0, node_crypto_1.randomUUID)()}@as-graph>`;
196
+ const from = assertEmailAddress(input.from, "sender");
197
+ const to = parseAddressList(input.to);
198
+ const cc = parseAddressList(input.cc);
199
+ const bcc = parseAddressList(input.bcc);
200
+ const recipients = [...to, ...cc, ...bcc];
201
+ if (recipients.length === 0) {
202
+ throw new db_decorators_1.BadRequestError("Email message requires at least one recipient");
203
+ }
204
+ const replyTo = input.replyTo
205
+ ? assertEmailAddress(input.replyTo, "reply-to")
206
+ : undefined;
207
+ const headers = [
208
+ `From: ${from}`,
209
+ `To: ${to.join(", ")}`,
210
+ ...(cc.length ? [`Cc: ${cc.join(", ")}`] : []),
211
+ `Subject: ${encodeHeader(input.subject)}`,
212
+ ...(replyTo ? [`Reply-To: ${replyTo}`] : []),
213
+ `Date: ${new Date().toUTCString()}`,
214
+ `Message-ID: ${messageId}`,
215
+ "MIME-Version: 1.0",
216
+ ].join("\r\n");
217
+ return {
218
+ raw: `${headers}\r\n${entity(input)}`,
219
+ from,
220
+ recipients,
221
+ messageId,
222
+ };
223
+ }
224
+ //# sourceMappingURL=mime.js.map
225
+ //# sourceMappingURL=mime.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comms/email/mime.cjs","sourceRoot":"","sources":["comms/email/mime.js"],"names":[],"mappings":"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"}