@bitblit/ratchet-aws 4.0.80-alpha

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 (241) hide show
  1. package/dist/cjs/batch/aws-batch-background-processor.js +44 -0
  2. package/dist/cjs/batch/aws-batch-ratchet.js +55 -0
  3. package/dist/cjs/build/ratchet-aws-info.js +18 -0
  4. package/dist/cjs/cache/dynamo-db-storage-provider.js +111 -0
  5. package/dist/cjs/cache/s3-storage-provider.js +44 -0
  6. package/dist/cjs/cache/simple-cache-object-wrapper.js +2 -0
  7. package/dist/cjs/cache/simple-cache-read-options.js +2 -0
  8. package/dist/cjs/cache/simple-cache-storage-provider.js +2 -0
  9. package/dist/cjs/cache/simple-cache.js +66 -0
  10. package/dist/cjs/cloudwatch/cloud-watch-log-group-ratchet.js +73 -0
  11. package/dist/cjs/cloudwatch/cloud-watch-logs-ratchet.js +173 -0
  12. package/dist/cjs/cloudwatch/cloud-watch-metrics-ratchet.js +57 -0
  13. package/dist/cjs/daemon/daemon-like.js +2 -0
  14. package/dist/cjs/daemon/daemon-process-create-options.js +2 -0
  15. package/dist/cjs/daemon/daemon-process-state-public-token.js +2 -0
  16. package/dist/cjs/daemon/daemon-process-state.js +2 -0
  17. package/dist/cjs/daemon/daemon-util.js +152 -0
  18. package/dist/cjs/daemon/daemon.js +126 -0
  19. package/dist/cjs/dao/prototype-dao-config.js +2 -0
  20. package/dist/cjs/dao/prototype-dao-db.js +2 -0
  21. package/dist/cjs/dao/prototype-dao-provider.js +2 -0
  22. package/dist/cjs/dao/prototype-dao.js +88 -0
  23. package/dist/cjs/dao/s3-prototype-dao-provider.js +28 -0
  24. package/dist/cjs/dao/s3-simple-dao.js +78 -0
  25. package/dist/cjs/dao/simple-dao-item.js +2 -0
  26. package/dist/cjs/dynamodb/dynamo-ratchet-like.js +2 -0
  27. package/dist/cjs/dynamodb/dynamo-ratchet.js +667 -0
  28. package/dist/cjs/dynamodb/dynamo-table-ratchet.js +91 -0
  29. package/dist/cjs/dynamodb/hash-spreader.js +62 -0
  30. package/dist/cjs/ec2/ec2-ratchet.js +107 -0
  31. package/dist/cjs/environment/cascade-environment-service-provider.js +27 -0
  32. package/dist/cjs/environment/env-var-environment-service-provider.js +33 -0
  33. package/dist/cjs/environment/environment-service-config.js +2 -0
  34. package/dist/cjs/environment/environment-service-provider.js +2 -0
  35. package/dist/cjs/environment/environment-service.js +52 -0
  36. package/dist/cjs/environment/fixed-environment-service-provider.js +24 -0
  37. package/dist/cjs/environment/s3-environment-service-provider.js +29 -0
  38. package/dist/cjs/environment/ssm-environment-service-provider.js +61 -0
  39. package/dist/cjs/expiring-code/dynamo-expiring-code-provider.js +26 -0
  40. package/dist/cjs/expiring-code/expiring-code-params.js +2 -0
  41. package/dist/cjs/expiring-code/expiring-code-provider.js +2 -0
  42. package/dist/cjs/expiring-code/expiring-code-ratchet.js +37 -0
  43. package/dist/cjs/expiring-code/expiring-code.js +2 -0
  44. package/dist/cjs/expiring-code/s3-expiring-code-provider.js +49 -0
  45. package/dist/cjs/iam/aws-credentials-ratchet.js +21 -0
  46. package/dist/cjs/index.js +81 -0
  47. package/dist/cjs/lambda/lambda-event-detector.js +42 -0
  48. package/dist/cjs/lambda/lambda-event-type-guards.js +28 -0
  49. package/dist/cjs/model/cloud-watch-metrics-minute-level-dynamo-count-request.js +2 -0
  50. package/dist/cjs/model/cloud-watch-metrics-unit.js +33 -0
  51. package/dist/cjs/model/dynamo/doc-put-item-command-input.js +2 -0
  52. package/dist/cjs/model/dynamo/doc-query-command-input.js +2 -0
  53. package/dist/cjs/model/dynamo/doc-scan-command-input.js +2 -0
  54. package/dist/cjs/model/dynamo/doc-update-item-command-input.js +2 -0
  55. package/dist/cjs/model/dynamo-count-result.js +2 -0
  56. package/dist/cjs/route53/route-53-ratchet.js +57 -0
  57. package/dist/cjs/runtime-parameter/cached-stored-runtime-parameter.js +2 -0
  58. package/dist/cjs/runtime-parameter/dynamo-runtime-parameter-provider.js +38 -0
  59. package/dist/cjs/runtime-parameter/global-variable-override-runtime-parameter-provider.js +54 -0
  60. package/dist/cjs/runtime-parameter/memory-runtime-parameter-provider.js +30 -0
  61. package/dist/cjs/runtime-parameter/runtime-parameter-provider.js +2 -0
  62. package/dist/cjs/runtime-parameter/runtime-parameter-ratchet.js +74 -0
  63. package/dist/cjs/runtime-parameter/stored-runtime-parameter.js +2 -0
  64. package/dist/cjs/s3/s3-cache-ratchet.js +332 -0
  65. package/dist/cjs/s3/s3-cache-to-local-disk-ratchet.js +105 -0
  66. package/dist/cjs/s3/s3-location-sync-ratchet.js +142 -0
  67. package/dist/cjs/s3/s3-ratchet.js +26 -0
  68. package/dist/cjs/ses/email-attachment.js +2 -0
  69. package/dist/cjs/ses/mailer-config.js +2 -0
  70. package/dist/cjs/ses/mailer-like.js +2 -0
  71. package/dist/cjs/ses/mailer.js +208 -0
  72. package/dist/cjs/ses/ratchet-template-renderer.js +2 -0
  73. package/dist/cjs/ses/ready-to-send-email.js +2 -0
  74. package/dist/cjs/ses/remote-handlebars-template-renderer.js +79 -0
  75. package/dist/cjs/ses/resolved-ready-to-send-email.js +2 -0
  76. package/dist/cjs/sns/sns-ratchet.js +47 -0
  77. package/dist/cjs/sync-lock/dynamo-db-sync-lock.js +69 -0
  78. package/dist/cjs/sync-lock/memory-sync-lock.js +40 -0
  79. package/dist/cjs/sync-lock/sync-lock-provider.js +2 -0
  80. package/dist/es/batch/aws-batch-background-processor.js +40 -0
  81. package/dist/es/batch/aws-batch-ratchet.js +51 -0
  82. package/dist/es/build/ratchet-aws-info.js +14 -0
  83. package/dist/es/cache/dynamo-db-storage-provider.js +107 -0
  84. package/dist/es/cache/s3-storage-provider.js +40 -0
  85. package/dist/es/cache/simple-cache-object-wrapper.js +1 -0
  86. package/dist/es/cache/simple-cache-read-options.js +1 -0
  87. package/dist/es/cache/simple-cache-storage-provider.js +1 -0
  88. package/dist/es/cache/simple-cache.js +62 -0
  89. package/dist/es/cloudwatch/cloud-watch-log-group-ratchet.js +69 -0
  90. package/dist/es/cloudwatch/cloud-watch-logs-ratchet.js +169 -0
  91. package/dist/es/cloudwatch/cloud-watch-metrics-ratchet.js +53 -0
  92. package/dist/es/daemon/daemon-like.js +1 -0
  93. package/dist/es/daemon/daemon-process-create-options.js +1 -0
  94. package/dist/es/daemon/daemon-process-state-public-token.js +1 -0
  95. package/dist/es/daemon/daemon-process-state.js +1 -0
  96. package/dist/es/daemon/daemon-util.js +148 -0
  97. package/dist/es/daemon/daemon.js +122 -0
  98. package/dist/es/dao/prototype-dao-config.js +1 -0
  99. package/dist/es/dao/prototype-dao-db.js +1 -0
  100. package/dist/es/dao/prototype-dao-provider.js +1 -0
  101. package/dist/es/dao/prototype-dao.js +84 -0
  102. package/dist/es/dao/s3-prototype-dao-provider.js +24 -0
  103. package/dist/es/dao/s3-simple-dao.js +74 -0
  104. package/dist/es/dao/simple-dao-item.js +1 -0
  105. package/dist/es/dynamodb/dynamo-ratchet-like.js +1 -0
  106. package/dist/es/dynamodb/dynamo-ratchet.js +663 -0
  107. package/dist/es/dynamodb/dynamo-table-ratchet.js +87 -0
  108. package/dist/es/dynamodb/hash-spreader.js +58 -0
  109. package/dist/es/ec2/ec2-ratchet.js +103 -0
  110. package/dist/es/environment/cascade-environment-service-provider.js +23 -0
  111. package/dist/es/environment/env-var-environment-service-provider.js +29 -0
  112. package/dist/es/environment/environment-service-config.js +1 -0
  113. package/dist/es/environment/environment-service-provider.js +1 -0
  114. package/dist/es/environment/environment-service.js +48 -0
  115. package/dist/es/environment/fixed-environment-service-provider.js +20 -0
  116. package/dist/es/environment/s3-environment-service-provider.js +25 -0
  117. package/dist/es/environment/ssm-environment-service-provider.js +56 -0
  118. package/dist/es/expiring-code/dynamo-expiring-code-provider.js +22 -0
  119. package/dist/es/expiring-code/expiring-code-params.js +1 -0
  120. package/dist/es/expiring-code/expiring-code-provider.js +1 -0
  121. package/dist/es/expiring-code/expiring-code-ratchet.js +33 -0
  122. package/dist/es/expiring-code/expiring-code.js +1 -0
  123. package/dist/es/expiring-code/s3-expiring-code-provider.js +45 -0
  124. package/dist/es/iam/aws-credentials-ratchet.js +17 -0
  125. package/dist/es/index.js +78 -0
  126. package/dist/es/lambda/lambda-event-detector.js +38 -0
  127. package/dist/es/lambda/lambda-event-type-guards.js +24 -0
  128. package/dist/es/model/cloud-watch-metrics-minute-level-dynamo-count-request.js +1 -0
  129. package/dist/es/model/cloud-watch-metrics-unit.js +30 -0
  130. package/dist/es/model/dynamo/doc-put-item-command-input.js +1 -0
  131. package/dist/es/model/dynamo/doc-query-command-input.js +1 -0
  132. package/dist/es/model/dynamo/doc-scan-command-input.js +1 -0
  133. package/dist/es/model/dynamo/doc-update-item-command-input.js +1 -0
  134. package/dist/es/model/dynamo-count-result.js +1 -0
  135. package/dist/es/route53/route-53-ratchet.js +53 -0
  136. package/dist/es/runtime-parameter/cached-stored-runtime-parameter.js +1 -0
  137. package/dist/es/runtime-parameter/dynamo-runtime-parameter-provider.js +34 -0
  138. package/dist/es/runtime-parameter/global-variable-override-runtime-parameter-provider.js +49 -0
  139. package/dist/es/runtime-parameter/memory-runtime-parameter-provider.js +26 -0
  140. package/dist/es/runtime-parameter/runtime-parameter-provider.js +1 -0
  141. package/dist/es/runtime-parameter/runtime-parameter-ratchet.js +70 -0
  142. package/dist/es/runtime-parameter/stored-runtime-parameter.js +1 -0
  143. package/dist/es/s3/s3-cache-ratchet.js +328 -0
  144. package/dist/es/s3/s3-cache-to-local-disk-ratchet.js +100 -0
  145. package/dist/es/s3/s3-location-sync-ratchet.js +137 -0
  146. package/dist/es/s3/s3-ratchet.js +22 -0
  147. package/dist/es/ses/email-attachment.js +1 -0
  148. package/dist/es/ses/mailer-config.js +1 -0
  149. package/dist/es/ses/mailer-like.js +1 -0
  150. package/dist/es/ses/mailer.js +204 -0
  151. package/dist/es/ses/ratchet-template-renderer.js +1 -0
  152. package/dist/es/ses/ready-to-send-email.js +1 -0
  153. package/dist/es/ses/remote-handlebars-template-renderer.js +74 -0
  154. package/dist/es/ses/resolved-ready-to-send-email.js +1 -0
  155. package/dist/es/sns/sns-ratchet.js +43 -0
  156. package/dist/es/sync-lock/dynamo-db-sync-lock.js +65 -0
  157. package/dist/es/sync-lock/memory-sync-lock.js +36 -0
  158. package/dist/es/sync-lock/sync-lock-provider.js +1 -0
  159. package/dist/tsconfig.cjs.tsbuildinfo +1 -0
  160. package/dist/tsconfig.es.tsbuildinfo +1 -0
  161. package/dist/tsconfig.types.tsbuildinfo +1 -0
  162. package/dist/types/batch/aws-batch-background-processor.d.ts +12 -0
  163. package/dist/types/batch/aws-batch-ratchet.d.ts +16 -0
  164. package/dist/types/build/ratchet-aws-info.d.ts +5 -0
  165. package/dist/types/cache/dynamo-db-storage-provider.d.ts +25 -0
  166. package/dist/types/cache/s3-storage-provider.d.ts +14 -0
  167. package/dist/types/cache/simple-cache-object-wrapper.d.ts +7 -0
  168. package/dist/types/cache/simple-cache-read-options.d.ts +5 -0
  169. package/dist/types/cache/simple-cache-storage-provider.d.ts +8 -0
  170. package/dist/types/cache/simple-cache.d.ts +14 -0
  171. package/dist/types/cloudwatch/cloud-watch-log-group-ratchet.d.ts +9 -0
  172. package/dist/types/cloudwatch/cloud-watch-logs-ratchet.d.ts +14 -0
  173. package/dist/types/cloudwatch/cloud-watch-metrics-ratchet.d.ts +10 -0
  174. package/dist/types/daemon/daemon-like.d.ts +17 -0
  175. package/dist/types/daemon/daemon-process-create-options.d.ts +7 -0
  176. package/dist/types/daemon/daemon-process-state-public-token.d.ts +4 -0
  177. package/dist/types/daemon/daemon-process-state.d.ts +13 -0
  178. package/dist/types/daemon/daemon-util.d.ts +24 -0
  179. package/dist/types/daemon/daemon.d.ts +33 -0
  180. package/dist/types/dao/prototype-dao-config.d.ts +8 -0
  181. package/dist/types/dao/prototype-dao-db.d.ts +4 -0
  182. package/dist/types/dao/prototype-dao-provider.d.ts +5 -0
  183. package/dist/types/dao/prototype-dao.d.ts +15 -0
  184. package/dist/types/dao/s3-prototype-dao-provider.d.ts +10 -0
  185. package/dist/types/dao/s3-simple-dao.d.ts +15 -0
  186. package/dist/types/dao/simple-dao-item.d.ts +5 -0
  187. package/dist/types/dynamodb/dynamo-ratchet-like.d.ts +27 -0
  188. package/dist/types/dynamodb/dynamo-ratchet.d.ts +36 -0
  189. package/dist/types/dynamodb/dynamo-table-ratchet.d.ts +11 -0
  190. package/dist/types/dynamodb/hash-spreader.d.ts +15 -0
  191. package/dist/types/ec2/ec2-ratchet.d.ts +25 -0
  192. package/dist/types/environment/cascade-environment-service-provider.d.ts +9 -0
  193. package/dist/types/environment/env-var-environment-service-provider.d.ts +10 -0
  194. package/dist/types/environment/environment-service-config.d.ts +7 -0
  195. package/dist/types/environment/environment-service-provider.d.ts +7 -0
  196. package/dist/types/environment/environment-service.d.ts +14 -0
  197. package/dist/types/environment/fixed-environment-service-provider.d.ts +10 -0
  198. package/dist/types/environment/s3-environment-service-provider.d.ts +18 -0
  199. package/dist/types/environment/ssm-environment-service-provider.d.ts +12 -0
  200. package/dist/types/expiring-code/dynamo-expiring-code-provider.d.ts +12 -0
  201. package/dist/types/expiring-code/expiring-code-params.d.ts +7 -0
  202. package/dist/types/expiring-code/expiring-code-provider.d.ts +5 -0
  203. package/dist/types/expiring-code/expiring-code-ratchet.d.ts +13 -0
  204. package/dist/types/expiring-code/expiring-code.d.ts +6 -0
  205. package/dist/types/expiring-code/s3-expiring-code-provider.d.ts +17 -0
  206. package/dist/types/iam/aws-credentials-ratchet.d.ts +9 -0
  207. package/dist/types/index.d.ts +81 -0
  208. package/dist/types/lambda/lambda-event-detector.d.ts +14 -0
  209. package/dist/types/lambda/lambda-event-type-guards.d.ts +10 -0
  210. package/dist/types/model/cloud-watch-metrics-minute-level-dynamo-count-request.d.ts +12 -0
  211. package/dist/types/model/cloud-watch-metrics-unit.d.ts +29 -0
  212. package/dist/types/model/dynamo/doc-put-item-command-input.d.ts +4 -0
  213. package/dist/types/model/dynamo/doc-query-command-input.d.ts +5 -0
  214. package/dist/types/model/dynamo/doc-scan-command-input.d.ts +5 -0
  215. package/dist/types/model/dynamo/doc-update-item-command-input.d.ts +5 -0
  216. package/dist/types/model/dynamo-count-result.d.ts +5 -0
  217. package/dist/types/route53/route-53-ratchet.d.ts +7 -0
  218. package/dist/types/runtime-parameter/cached-stored-runtime-parameter.d.ts +4 -0
  219. package/dist/types/runtime-parameter/dynamo-runtime-parameter-provider.d.ts +11 -0
  220. package/dist/types/runtime-parameter/global-variable-override-runtime-parameter-provider.d.ts +24 -0
  221. package/dist/types/runtime-parameter/memory-runtime-parameter-provider.d.ts +13 -0
  222. package/dist/types/runtime-parameter/runtime-parameter-provider.d.ts +11 -0
  223. package/dist/types/runtime-parameter/runtime-parameter-ratchet.d.ts +15 -0
  224. package/dist/types/runtime-parameter/stored-runtime-parameter.d.ts +6 -0
  225. package/dist/types/s3/s3-cache-ratchet.d.ts +38 -0
  226. package/dist/types/s3/s3-cache-to-local-disk-ratchet.d.ts +21 -0
  227. package/dist/types/s3/s3-location-sync-ratchet.d.ts +21 -0
  228. package/dist/types/s3/s3-ratchet.d.ts +5 -0
  229. package/dist/types/ses/email-attachment.d.ts +23 -0
  230. package/dist/types/ses/mailer-config.d.ts +15 -0
  231. package/dist/types/ses/mailer-like.d.ts +18 -0
  232. package/dist/types/ses/mailer.d.ts +26 -0
  233. package/dist/types/ses/ratchet-template-renderer.d.ts +8 -0
  234. package/dist/types/ses/ready-to-send-email.d.ts +66 -0
  235. package/dist/types/ses/remote-handlebars-template-renderer.d.ts +15 -0
  236. package/dist/types/ses/resolved-ready-to-send-email.d.ts +16 -0
  237. package/dist/types/sns/sns-ratchet.d.ts +8 -0
  238. package/dist/types/sync-lock/dynamo-db-sync-lock.d.ts +10 -0
  239. package/dist/types/sync-lock/memory-sync-lock.d.ts +11 -0
  240. package/dist/types/sync-lock/sync-lock-provider.d.ts +5 -0
  241. package/package.json +112 -0
@@ -0,0 +1,204 @@
1
+ import { Logger } from '@bitblit/ratchet-common';
2
+ import { SendRawEmailCommand } from '@aws-sdk/client-ses';
3
+ import { StringRatchet } from '@bitblit/ratchet-common';
4
+ import { ErrorRatchet } from '@bitblit/ratchet-common';
5
+ import { DateTime } from 'luxon';
6
+ import { Base64Ratchet } from '@bitblit/ratchet-common';
7
+ import { RequireRatchet } from '@bitblit/ratchet-common';
8
+ export class Mailer {
9
+ constructor(ses, config = {}) {
10
+ this.ses = ses;
11
+ this.config = config;
12
+ RequireRatchet.notNullOrUndefined(this.ses);
13
+ if (!!config.archive && !config.archive.getDefaultBucket()) {
14
+ throw new Error('If archive specified, must set a default bucket');
15
+ }
16
+ }
17
+ async fillEmailBody(rts, context, htmlTemplateName, txtTemplateName = null, layoutName = null, partialNames = null) {
18
+ RequireRatchet.notNullOrUndefined(htmlTemplateName);
19
+ if (!this.config.templateRenderer) {
20
+ ErrorRatchet.throwFormattedErr('Cannot use fill body if template renderer not set');
21
+ }
22
+ rts.htmlMessage = await this.config.templateRenderer.renderTemplate(htmlTemplateName, context, layoutName, partialNames);
23
+ rts.txtMessage = !!txtTemplateName ? await this.config.templateRenderer.renderTemplate(txtTemplateName, context) : null;
24
+ return rts;
25
+ }
26
+ async fillEmailBodyAndSend(rts, context, htmlTemplateName, txtTemplateName = null, layoutName = null, partialNames = null) {
27
+ const newVal = await this.fillEmailBody(rts, context, htmlTemplateName, txtTemplateName, layoutName, partialNames);
28
+ const rval = await this.sendEmail(newVal);
29
+ return rval;
30
+ }
31
+ filterEmailsToValid(emails) {
32
+ const rval = (emails || []).filter((e) => {
33
+ if (!this.config.allowedDestinationEmails || this.config.allowedDestinationEmails.length == 0) {
34
+ return true;
35
+ }
36
+ else {
37
+ const match = this.config.allowedDestinationEmails.find((s) => s.test(e));
38
+ return !!match;
39
+ }
40
+ });
41
+ return rval;
42
+ }
43
+ async archiveEmailIfConfigured(rts) {
44
+ let rval = false;
45
+ if (!!rts && !!this.config.archive && !rts.doNotArchive) {
46
+ Logger.debug('Archiving outbound email to : %j', rts.destinationAddresses);
47
+ let targetPath = StringRatchet.trimToEmpty(this.config.archivePrefix);
48
+ if (!targetPath.endsWith('/')) {
49
+ targetPath += '/';
50
+ }
51
+ const now = DateTime.utc();
52
+ targetPath +=
53
+ 'year=' +
54
+ now.toFormat('yyyy') +
55
+ '/month=' +
56
+ now.toFormat('MM') +
57
+ '/day=' +
58
+ now.toFormat('dd') +
59
+ '/hour=' +
60
+ now.toFormat('HH') +
61
+ '/' +
62
+ now.toFormat('mm_ss__SSS');
63
+ targetPath += '.json';
64
+ try {
65
+ await this.config.archive.writeObjectToCacheFile(targetPath, rts);
66
+ rval = true;
67
+ }
68
+ catch (err) {
69
+ Logger.warn('Failed to archive email %s %j : %s', targetPath, rts, err);
70
+ }
71
+ }
72
+ return rval;
73
+ }
74
+ applyLimitsToBodySizesIfAnyInPlace(rts) {
75
+ if (this.config.maxMessageBodySizeInBytes) {
76
+ const txtSize = StringRatchet.trimToEmpty(rts.txtMessage).length;
77
+ const htmlSize = StringRatchet.trimToEmpty(rts.htmlMessage).length;
78
+ const totalSize = txtSize + htmlSize;
79
+ if (totalSize > this.config.maxMessageBodySizeInBytes) {
80
+ Logger.warn('Max message size is %d but size is %d - converting', this.config.maxMessageBodySizeInBytes, totalSize);
81
+ rts.attachments = rts.attachments || [];
82
+ if (StringRatchet.trimToNull(rts.txtMessage)) {
83
+ const txtAttach = {
84
+ filename: 'original-txt-body.txt',
85
+ contentType: 'text/plain',
86
+ base64Data: Base64Ratchet.generateBase64VersionOfString(rts.txtMessage),
87
+ };
88
+ rts.attachments.push(txtAttach);
89
+ }
90
+ if (StringRatchet.trimToNull(rts.htmlMessage)) {
91
+ const htmlAttach = {
92
+ filename: 'original-html-body.html',
93
+ contentType: 'text/html',
94
+ base64Data: Base64Ratchet.generateBase64VersionOfString(rts.htmlMessage),
95
+ };
96
+ rts.attachments.push(htmlAttach);
97
+ }
98
+ rts.htmlMessage = null;
99
+ rts.txtMessage = 'The message was too large and was converted to attachment(s). Please see attached files for content';
100
+ }
101
+ }
102
+ }
103
+ applyLimitsToAttachmentSizesIfAnyInPlace(rts) {
104
+ if (this.config.maxAttachmentSizeInBase64Bytes) {
105
+ const filtered = [];
106
+ if (rts.attachments) {
107
+ rts.attachments.forEach((a) => {
108
+ if (a.base64Data && a.base64Data.length < this.config.maxAttachmentSizeInBase64Bytes) {
109
+ filtered.push(a);
110
+ }
111
+ else {
112
+ Logger.warn('Removing too-large attachment : %s : %s : %d', a.filename, a.contentType, a.base64Data.length);
113
+ filtered.push({
114
+ filename: 'attachment-removed-notice-' + StringRatchet.createRandomHexString(4) + '.txt',
115
+ contentType: 'text/plain',
116
+ base64Data: Base64Ratchet.generateBase64VersionOfString('Attachment ' +
117
+ a.filename +
118
+ ' of type ' +
119
+ a.contentType +
120
+ ' was removed since it was ' +
121
+ a.base64Data.length +
122
+ ' bytes but max allowed is ' +
123
+ this.config.maxAttachmentSizeInBase64Bytes),
124
+ });
125
+ }
126
+ });
127
+ }
128
+ rts.attachments = filtered;
129
+ }
130
+ }
131
+ async sendEmail(inRts) {
132
+ RequireRatchet.notNullOrUndefined(inRts, 'RTS must be defined');
133
+ RequireRatchet.notNullOrUndefined(inRts.destinationAddresses, 'Destination addresses must be defined');
134
+ let rval = null;
135
+ let toAddresses = this.filterEmailsToValid(inRts.destinationAddresses);
136
+ const autoBcc = inRts.doNotAutoBcc ? [] : this.config.autoBccAddresses || [];
137
+ const bccAddresses = (inRts.bccAddresses || []).concat(autoBcc);
138
+ if (toAddresses.length === 0 && bccAddresses.length > 0) {
139
+ Logger.debug('Destination emails filtered to none but BCC defined, copying BCC');
140
+ toAddresses = bccAddresses;
141
+ }
142
+ const rts = Object.assign({}, inRts);
143
+ rts.srcDestinationAddresses = inRts.destinationAddresses;
144
+ rts.srcBccAddresses = inRts.bccAddresses;
145
+ rts.destinationAddresses = toAddresses;
146
+ rts.bccAddresses = bccAddresses;
147
+ this.applyLimitsToBodySizesIfAnyInPlace(rts);
148
+ this.applyLimitsToAttachmentSizesIfAnyInPlace(rts);
149
+ await this.archiveEmailIfConfigured(rts);
150
+ if (rts.destinationAddresses.length === 0) {
151
+ Logger.info('After cleaning email lists, no destination addresses left - not sending email');
152
+ }
153
+ else {
154
+ const toLine = 'To: ' + rts.destinationAddresses.join(', ') + '\n';
155
+ const bccLine = !!rts.bccAddresses && rts.bccAddresses.length > 0 ? 'Bcc: ' + rts.bccAddresses.join(', ') + '\n' : '';
156
+ try {
157
+ const from = rts.fromAddress || this.config.defaultSendingAddress;
158
+ const boundary = 'NextPart';
159
+ const altBoundary = 'AltPart';
160
+ let rawMail = 'From: ' + from + '\n';
161
+ rawMail += toLine;
162
+ rawMail += bccLine;
163
+ rawMail += 'Subject: ' + rts.subject + '\n';
164
+ rawMail += 'MIME-Version: 1.0\n';
165
+ rawMail += 'Content-Type: multipart/mixed; boundary="' + boundary + '"\n';
166
+ rawMail += '\n\n--' + boundary + '\n';
167
+ rawMail += 'Content-Type: multipart/alternative; boundary="' + altBoundary + '"\n';
168
+ if (!!StringRatchet.trimToNull(rts.htmlMessage)) {
169
+ rawMail += '\n\n--' + altBoundary + '\n';
170
+ rawMail += 'Content-Type: text/html; charset="UTF-8"\n\n';
171
+ rawMail += rts.htmlMessage;
172
+ }
173
+ if (!!StringRatchet.trimToNull(rts.txtMessage)) {
174
+ rawMail += '\n\n--' + altBoundary + '\n';
175
+ rawMail += 'Content-Type: text/plain\n\n';
176
+ rawMail += rts.txtMessage;
177
+ }
178
+ rawMail += '\n\n--' + altBoundary + '--\n';
179
+ if (rts.attachments) {
180
+ rts.attachments.forEach((a) => {
181
+ rawMail += '\n\n--' + boundary + '\n';
182
+ rawMail += 'Content-Type: ' + a.contentType + '; name="' + a.filename + '"\n';
183
+ rawMail += 'Content-Transfer-Encoding: base64\n';
184
+ rawMail += 'Content-Disposition: attachment\n\n';
185
+ rawMail += a.base64Data.replace(/([^\0]{76})/g, '$1\n') + '\n\n';
186
+ });
187
+ }
188
+ rawMail += '\n\n--' + boundary + '--\n';
189
+ const params = {
190
+ RawMessage: { Data: new TextEncoder().encode(rawMail) },
191
+ };
192
+ rval = await this.ses.send(new SendRawEmailCommand(params));
193
+ }
194
+ catch (err) {
195
+ Logger.error('Error while processing email: %s', err, err);
196
+ }
197
+ }
198
+ return rval;
199
+ }
200
+ static validEmail(email) {
201
+ return email !== null && Mailer.EMAIL.test(email);
202
+ }
203
+ }
204
+ Mailer.EMAIL = new RegExp('.+@.+\\.[a-z]+');
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ import handlebars from 'handlebars';
2
+ import fetch from 'cross-fetch';
3
+ import { StringRatchet } from '@bitblit/ratchet-common';
4
+ import { Logger } from '@bitblit/ratchet-common';
5
+ import layouts from 'handlebars-layouts';
6
+ export class RemoteHandlebarsTemplateRenderer {
7
+ constructor(prefix = '', suffix = '', maxCacheTemplates = 10) {
8
+ this.prefix = prefix;
9
+ this.suffix = suffix;
10
+ this.maxCacheTemplates = maxCacheTemplates;
11
+ if (this.maxCacheTemplates > 0) {
12
+ this.cache = new Map();
13
+ }
14
+ }
15
+ async renderTemplate(templateName, context, layoutName = null) {
16
+ return this.renderRemoteTemplate(templateName, context, layoutName);
17
+ }
18
+ async renderRemoteTemplate(templateName, inContext, layoutName = null) {
19
+ const template = await this.fetchTemplate(templateName);
20
+ const layoutText = !!layoutName ? await this.fetchTemplateText(layoutName) : null;
21
+ if (!!layoutText) {
22
+ await layouts.register(handlebars);
23
+ handlebars.registerPartial(layoutName, layoutText);
24
+ }
25
+ const context = inContext || {};
26
+ const result = !!template ? template(context) : null;
27
+ return result;
28
+ }
29
+ async renderTemplateDirect(templateText, context, layoutName = null) {
30
+ const template = handlebars.compile(templateText);
31
+ const result = template(context);
32
+ return result;
33
+ }
34
+ async fetchTemplate(templateName) {
35
+ let rval = null;
36
+ try {
37
+ if (!!this.cache && this.cache.has(templateName)) {
38
+ Logger.silly('Cache hit for template : %s', templateName);
39
+ rval = this.cache.get(templateName);
40
+ }
41
+ else {
42
+ Logger.debug('Cache miss for template : %s', templateName);
43
+ const templateText = await this.fetchTemplateText(templateName);
44
+ if (!!templateText) {
45
+ rval = handlebars.compile(templateText);
46
+ if (!!this.cache && !!rval) {
47
+ this.cache.set(templateName, rval);
48
+ if (this.cache.size > this.maxCacheTemplates) {
49
+ this.cache.delete(Array.from(this.cache.keys())[0]);
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+ catch (err) {
56
+ Logger.warn('Could not fetch and compile template : %s : %s', templateName, err, err);
57
+ rval = null;
58
+ }
59
+ return rval;
60
+ }
61
+ async fetchTemplateText(templateName) {
62
+ let rval = null;
63
+ const url = StringRatchet.trimToEmpty(this.prefix) + templateName + StringRatchet.trimToEmpty(this.suffix);
64
+ try {
65
+ const resp = await fetch(url);
66
+ rval = await resp.text();
67
+ }
68
+ catch (err) {
69
+ Logger.warn('Could not fetch url : %s : %s', url, err, err);
70
+ rval = null;
71
+ }
72
+ return rval;
73
+ }
74
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,43 @@
1
+ import { Logger } from '@bitblit/ratchet-common';
2
+ import { PublishCommand, SNSClient } from '@aws-sdk/client-sns';
3
+ import { RequireRatchet } from '@bitblit/ratchet-common';
4
+ export class SnsRatchet {
5
+ constructor(sns = new SNSClient({ region: 'us-east-1' }), topicArn) {
6
+ this.sns = sns;
7
+ this.topicArn = topicArn;
8
+ RequireRatchet.notNullOrUndefined(this.sns, 'sns');
9
+ RequireRatchet.notNullOrUndefined(this.topicArn, 'topicArn');
10
+ }
11
+ async sendMessage(inMsg, suppressErrors = false) {
12
+ let result = null;
13
+ try {
14
+ const safeInMsg = inMsg ? inMsg : 'NO-MESSAGE-PROVIDED';
15
+ const msg = typeof safeInMsg === 'string' ? safeInMsg : JSON.stringify(safeInMsg);
16
+ const params = {
17
+ TopicArn: this.topicArn,
18
+ Message: msg,
19
+ };
20
+ Logger.debug('Sending via SNS : %j', params);
21
+ result = await this.sns.send(new PublishCommand(params));
22
+ }
23
+ catch (err) {
24
+ if (suppressErrors) {
25
+ Logger.error('Failed to fire SNS notification : %j : %s', inMsg, err);
26
+ }
27
+ else {
28
+ throw err;
29
+ }
30
+ }
31
+ return result;
32
+ }
33
+ async conditionallySendMessage(inMsg, condition, suppressErrors = false) {
34
+ let rval = null;
35
+ if (condition) {
36
+ rval = await this.sendMessage(inMsg, suppressErrors);
37
+ }
38
+ else {
39
+ Logger.info('Not sending message, condition was false : %j', inMsg);
40
+ }
41
+ return rval;
42
+ }
43
+ }
@@ -0,0 +1,65 @@
1
+ import { Logger, RequireRatchet, StringRatchet } from '@bitblit/ratchet-common';
2
+ import { PutItemCommand } from '@aws-sdk/client-dynamodb';
3
+ export class DynamoDbSyncLock {
4
+ constructor(ratchet, tableName) {
5
+ this.ratchet = ratchet;
6
+ this.tableName = tableName;
7
+ RequireRatchet.notNullOrUndefined(ratchet, 'ratchet');
8
+ RequireRatchet.notNullOrUndefined(StringRatchet.trimToNull(this.tableName), 'tableName');
9
+ }
10
+ async acquireLock(lockKey, expirationSeconds = 30) {
11
+ let rval = false;
12
+ if (!!lockKey && !!expirationSeconds) {
13
+ const nowSeconds = Math.floor(new Date().getTime() / 1000);
14
+ const row = {
15
+ lockingKey: lockKey,
16
+ timestamp: nowSeconds,
17
+ expires: nowSeconds + expirationSeconds,
18
+ };
19
+ const params = {
20
+ Item: row,
21
+ ReturnConsumedCapacity: 'TOTAL',
22
+ TableName: this.tableName,
23
+ ConditionExpression: 'attribute_not_exists(lockingKey)',
24
+ };
25
+ try {
26
+ const pio = await this.ratchet.getDDB().send(new PutItemCommand(params));
27
+ rval = true;
28
+ }
29
+ catch (err) {
30
+ if (String(err).indexOf('ConditionalCheckFailedException') > -1) {
31
+ Logger.silly('Unable to acquire lock on %s', lockKey);
32
+ }
33
+ }
34
+ }
35
+ return rval;
36
+ }
37
+ async releaseLock(lockKey) {
38
+ if (StringRatchet.trimToNull(lockKey)) {
39
+ try {
40
+ const dio = await this.ratchet.simpleDelete(this.tableName, { lockingKey: lockKey });
41
+ Logger.silly('Released lock %s : %s', lockKey, dio);
42
+ }
43
+ catch (err) {
44
+ Logger.warn('Failed to release lock key : %s : %s', lockKey, err, err);
45
+ }
46
+ }
47
+ }
48
+ async clearExpiredSyncLocks() {
49
+ const nowSeconds = Math.floor(new Date().getTime() / 1000);
50
+ const scan = {
51
+ TableName: this.tableName,
52
+ FilterExpression: 'expires < :now',
53
+ ExpressionAttributeValues: {
54
+ ':now': nowSeconds,
55
+ },
56
+ };
57
+ const vals = await this.ratchet.fullyExecuteScan(scan);
58
+ const keysOnly = vals.map((v) => {
59
+ const next = { lockingKey: v['lockingKey'] };
60
+ return next;
61
+ });
62
+ const removed = await this.ratchet.deleteAllInBatches(this.tableName, keysOnly, 25);
63
+ return removed;
64
+ }
65
+ }
@@ -0,0 +1,36 @@
1
+ import { StringRatchet } from '@bitblit/ratchet-common';
2
+ export class MemorySyncLock {
3
+ constructor() {
4
+ this._locks = new Map();
5
+ }
6
+ async acquireLock(lockKey, expirationSeconds = 30) {
7
+ let rval = false;
8
+ if (StringRatchet.trimToNull(lockKey)) {
9
+ const now = Date.now();
10
+ const val = this._locks.get(lockKey);
11
+ if (!val || val < now) {
12
+ this._locks.set(lockKey, now + expirationSeconds * 1000);
13
+ rval = true;
14
+ }
15
+ }
16
+ return rval;
17
+ }
18
+ async releaseLock(lockKey) {
19
+ if (StringRatchet.trimToNull(lockKey)) {
20
+ this._locks.delete(lockKey);
21
+ }
22
+ }
23
+ async clearExpiredSyncLocks() {
24
+ const toRemove = [];
25
+ const now = Date.now();
26
+ this._locks.forEach((v, k) => {
27
+ if (v < now) {
28
+ toRemove.push(k);
29
+ }
30
+ });
31
+ toRemove.forEach((k) => {
32
+ this._locks.delete(k);
33
+ });
34
+ return toRemove.length;
35
+ }
36
+ }
@@ -0,0 +1 @@
1
+ export {};