@goatlab/node-backend 0.0.16 → 0.1.1

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 (129) hide show
  1. package/README.md +54 -38
  2. package/dist/container/Container.d.ts +441 -0
  3. package/dist/container/Container.js +895 -0
  4. package/dist/container/Container.js.map +1 -0
  5. package/dist/container/DistributedCacheInvalidator.d.ts +84 -0
  6. package/dist/container/DistributedCacheInvalidator.js +213 -0
  7. package/dist/container/DistributedCacheInvalidator.js.map +1 -0
  8. package/dist/container/LruCache.d.ts +14 -0
  9. package/dist/container/LruCache.js +23 -0
  10. package/dist/container/LruCache.js.map +1 -0
  11. package/dist/container/types.d.ts +128 -0
  12. package/dist/container/types.js +6 -0
  13. package/dist/container/types.js.map +1 -0
  14. package/dist/index.d.ts +31 -0
  15. package/dist/index.js +53 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/server/bootstraps/getExpressTrpcApp.d.ts +17 -0
  18. package/dist/server/bootstraps/getExpressTrpcApp.js +98 -0
  19. package/dist/server/bootstraps/getExpressTrpcApp.js.map +1 -0
  20. package/dist/server/consts.d.ts +35 -0
  21. package/dist/server/consts.js +33 -0
  22. package/dist/server/consts.js.map +1 -0
  23. package/dist/server/context/context.model.d.ts +13 -0
  24. package/dist/server/context/context.model.js +3 -0
  25. package/dist/server/context/context.model.js.map +1 -0
  26. package/dist/server/context/request.context.d.ts +40 -0
  27. package/dist/server/context/request.context.js +91 -0
  28. package/dist/server/context/request.context.js.map +1 -0
  29. package/dist/server/context/trpc.context.d.ts +11 -0
  30. package/dist/server/context/trpc.context.js +67 -0
  31. package/dist/server/context/trpc.context.js.map +1 -0
  32. package/dist/server/initOpenApiDocs.d.ts +9 -0
  33. package/dist/server/initOpenApiDocs.js +18 -0
  34. package/dist/server/initOpenApiDocs.js.map +1 -0
  35. package/dist/server/middleware/cloudTaskDecrypt.middleware.d.ts +6 -0
  36. package/dist/server/middleware/cloudTaskDecrypt.middleware.js +44 -0
  37. package/dist/server/middleware/cloudTaskDecrypt.middleware.js.map +1 -0
  38. package/dist/server/middleware/error.middleware.d.ts +17 -0
  39. package/dist/server/middleware/error.middleware.js +66 -0
  40. package/dist/server/middleware/error.middleware.js.map +1 -0
  41. package/dist/server/middleware/handleRequest.middleware.d.ts +7 -0
  42. package/dist/server/middleware/handleRequest.middleware.js +40 -0
  43. package/dist/server/middleware/handleRequest.middleware.js.map +1 -0
  44. package/dist/server/middleware/logger/cloudRun.logger.d.ts +27 -0
  45. package/dist/server/middleware/logger/cloudRun.logger.js +87 -0
  46. package/dist/server/middleware/logger/cloudRun.logger.js.map +1 -0
  47. package/dist/server/middleware/logger/logger.service.d.ts +6 -0
  48. package/dist/server/middleware/logger/logger.service.js +17 -0
  49. package/dist/server/middleware/logger/logger.service.js.map +1 -0
  50. package/dist/server/middleware/logs.middleware.d.ts +7 -0
  51. package/dist/server/middleware/logs.middleware.js +130 -0
  52. package/dist/server/middleware/logs.middleware.js.map +1 -0
  53. package/dist/server/middleware/requireAuthenticated.d.ts +2 -0
  54. package/dist/server/middleware/requireAuthenticated.js +13 -0
  55. package/dist/server/middleware/requireAuthenticated.js.map +1 -0
  56. package/dist/server/middleware/trpcError.middleware.d.ts +4 -0
  57. package/dist/server/middleware/trpcError.middleware.js +38 -0
  58. package/dist/server/middleware/trpcError.middleware.js.map +1 -0
  59. package/dist/server/schemas/user.schema.d.ts +109 -0
  60. package/dist/server/schemas/user.schema.js +28 -0
  61. package/dist/server/schemas/user.schema.js.map +1 -0
  62. package/dist/server/sentry/getSentry.d.ts +6 -0
  63. package/dist/server/sentry/getSentry.js +45 -0
  64. package/dist/server/sentry/getSentry.js.map +1 -0
  65. package/dist/server/sentry/sentry.service.d.ts +34 -0
  66. package/dist/server/sentry/sentry.service.js +110 -0
  67. package/dist/server/sentry/sentry.service.js.map +1 -0
  68. package/dist/server/services/email/email.model.d.ts +84 -0
  69. package/dist/server/services/email/email.model.js +62 -0
  70. package/dist/server/services/email/email.model.js.map +1 -0
  71. package/dist/server/services/email/email.service.d.ts +23 -0
  72. package/dist/server/services/email/email.service.js +139 -0
  73. package/dist/server/services/email/email.service.js.map +1 -0
  74. package/dist/server/services/gcp/getGcpServiceAccountFromBase64.d.ts +15 -0
  75. package/dist/server/services/gcp/getGcpServiceAccountFromBase64.js +9 -0
  76. package/dist/server/services/gcp/getGcpServiceAccountFromBase64.js.map +1 -0
  77. package/dist/server/services/secrets/secret.service.d.ts +32 -0
  78. package/dist/server/services/secrets/secret.service.js +220 -0
  79. package/dist/server/services/secrets/secret.service.js.map +1 -0
  80. package/dist/server/services/sendgrid/sendgrid.model.d.ts +118 -0
  81. package/dist/server/services/sendgrid/sendgrid.model.js +3 -0
  82. package/dist/server/services/sendgrid/sendgrid.model.js.map +1 -0
  83. package/dist/server/services/sendgrid/sendgridApi.service.d.ts +13 -0
  84. package/dist/server/services/sendgrid/sendgridApi.service.js +79 -0
  85. package/dist/server/services/sendgrid/sendgridApi.service.js.map +1 -0
  86. package/dist/server/services/sendgrid/sendgridHooks.model.d.ts +27 -0
  87. package/dist/server/services/sendgrid/sendgridHooks.model.js +19 -0
  88. package/dist/server/services/sendgrid/sendgridHooks.model.js.map +1 -0
  89. package/dist/server/services/translations/template.util.d.ts +7 -0
  90. package/dist/server/services/translations/template.util.js +11 -0
  91. package/dist/server/services/translations/template.util.js.map +1 -0
  92. package/dist/server/services/translations/translation.model.d.ts +4 -0
  93. package/dist/server/services/translations/translation.model.js +6 -0
  94. package/dist/server/services/translations/translation.model.js.map +1 -0
  95. package/dist/server/services/translations/translation.service.d.ts +25 -0
  96. package/dist/server/services/translations/translation.service.js +97 -0
  97. package/dist/server/services/translations/translation.service.js.map +1 -0
  98. package/dist/server/services/util/benchmarker.d.ts +13 -0
  99. package/dist/server/services/util/benchmarker.js +34 -0
  100. package/dist/server/services/util/benchmarker.js.map +1 -0
  101. package/dist/server/services/util/pagination.d.ts +50 -0
  102. package/dist/server/services/util/pagination.js +57 -0
  103. package/dist/server/services/util/pagination.js.map +1 -0
  104. package/dist/server/services/util/url.service.d.ts +75 -0
  105. package/dist/server/services/util/url.service.js +139 -0
  106. package/dist/server/services/util/url.service.js.map +1 -0
  107. package/dist/server/test/express.mock.d.ts +6 -0
  108. package/dist/server/test/express.mock.js +49 -0
  109. package/dist/server/test/express.mock.js.map +1 -0
  110. package/dist/server/test/firebase.mock.d.ts +4 -0
  111. package/dist/server/test/firebase.mock.js +30 -0
  112. package/dist/server/test/firebase.mock.js.map +1 -0
  113. package/dist/server/test/mock.model.d.ts +5 -0
  114. package/dist/server/test/mock.model.js +3 -0
  115. package/dist/server/test/mock.model.js.map +1 -0
  116. package/dist/server/test/trpc.mock.d.ts +6 -0
  117. package/dist/server/test/trpc.mock.js +14 -0
  118. package/dist/server/test/trpc.mock.js.map +1 -0
  119. package/dist/server/trpc.d.ts +364 -0
  120. package/dist/server/trpc.js +87 -0
  121. package/dist/server/trpc.js.map +1 -0
  122. package/dist/server/types/Envinronment.d.ts +1 -0
  123. package/dist/server/types/Envinronment.js +3 -0
  124. package/dist/server/types/Envinronment.js.map +1 -0
  125. package/dist/test/const.d.ts +4 -0
  126. package/dist/test/const.js +11 -1
  127. package/dist/test/const.js.map +1 -1
  128. package/dist/tsconfig.tsbuildinfo +1 -1
  129. package/package.json +34 -3
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SentryService = void 0;
4
+ const js_utils_1 = require("@goatlab/js-utils");
5
+ const sentrySeverityMap = {
6
+ debug: 'log',
7
+ info: 'log',
8
+ log: 'log',
9
+ warning: 'warn',
10
+ error: 'error',
11
+ fatal: 'error',
12
+ };
13
+ class SentryService {
14
+ config;
15
+ constructor(config) {
16
+ this.config = config;
17
+ }
18
+ //@Memo.syncMethod()
19
+ sentry() {
20
+ // Lazy-loading `@sentry/node`
21
+ const sentry = require('@sentry/node');
22
+ if (!this.config.dsn) {
23
+ return sentry;
24
+ }
25
+ console.log('SentryService init...');
26
+ sentry.init({
27
+ maxValueLength: 2000, // Default is 250 characters
28
+ ...this.config,
29
+ });
30
+ return sentry;
31
+ }
32
+ init() {
33
+ this.sentry();
34
+ }
35
+ /**
36
+ * For GDPR reasons we never send more information than just User ID.
37
+ */
38
+ setUserId(id) {
39
+ this.sentry().getCurrentScope().setUser({
40
+ id,
41
+ });
42
+ }
43
+ /**
44
+ * Does console.error(err)
45
+ * Returns "eventId" or undefined (if error was not reported).
46
+ */
47
+ captureException(error, logError = true) {
48
+ // Console.error(err)
49
+ // Using request-aware logger here
50
+ if (logError) {
51
+ this.config.logger?.error('captureException:', error);
52
+ }
53
+ if (error?.data?.report === false) {
54
+ // Skip reporting the error
55
+ return;
56
+ }
57
+ // This is to avoid Sentry cutting err.message to 253 characters
58
+ // It will log additional "breadcrumb object" before the error
59
+ // It's a Breadcrumb, not a console.log, because console.log are NOT automatically attached as Breadcrumbs in cron-job environments (outside of Express)
60
+ this.sentry().addBreadcrumb({
61
+ message: js_utils_1.Inspect.any(error, {
62
+ includeErrorData: true,
63
+ colors: false,
64
+ }),
65
+ // Data: (err as AppError).data, // included in message
66
+ });
67
+ return this.sentry().captureException(js_utils_1.Errors.anyToError(error, Error, {
68
+ stringifyFn: js_utils_1.Inspect.anyStringifyFn,
69
+ }));
70
+ }
71
+ /**
72
+ * Returns "eventId"
73
+ */
74
+ captureMessage(message, level) {
75
+ this.config.logger?.[sentrySeverityMap[level || 'error'] || 'log']('captureMessage:', message);
76
+ return this.sentry().captureMessage(message, level);
77
+ }
78
+ addBreadcrumb(breadcrumb) {
79
+ this.sentry().addBreadcrumb(breadcrumb);
80
+ }
81
+ /**
82
+ * Currently it will only use `logger.error` ("error" level) and ignore `log` and `warn`.
83
+ *
84
+ * For each `logger.error` - it'll do a captureException.
85
+ *
86
+ * @experimental
87
+ */
88
+ getCommonLogger() {
89
+ return {
90
+ log() { }, // Noop
91
+ warn() { }, // Noop
92
+ error: (...args) => {
93
+ const message = args
94
+ .map((arg) => js_utils_1.Inspect.any(arg, {
95
+ includeErrorData: true,
96
+ colors: false,
97
+ }))
98
+ .join(' ');
99
+ this.sentry().addBreadcrumb({
100
+ message,
101
+ });
102
+ this.sentry().captureException(js_utils_1.Errors.anyToError(args.length === 1 ? args[0] : args, Error, {
103
+ stringifyFn: js_utils_1.Inspect.anyStringifyFn,
104
+ }));
105
+ },
106
+ };
107
+ }
108
+ }
109
+ exports.SentryService = SentryService;
110
+ //# sourceMappingURL=sentry.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentry.service.js","sourceRoot":"","sources":["../../../src/server/sentry/sentry.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { z } from 'zod';
2
+ export declare enum EmailCategory {
3
+ SIMPLE = "SIMPLE",
4
+ TEST_EMAIL = "TEST_EMAIL",
5
+ EMAIL_VERIFICATION = "EMAIL_VERIFICATION",
6
+ SEND_ONCE = "SEND_ONCE",
7
+ OTP = "OTP",
8
+ MEETING = "MEETING",
9
+ ORGANIZATION_INVITATION = "ORGANIZATION_INVITATION",
10
+ PDF_EXAM = "PDF_EXAM"
11
+ }
12
+ export interface EmailAddress {
13
+ email: string;
14
+ name?: string;
15
+ }
16
+ export interface EmailTest {
17
+ to: string;
18
+ subject: string;
19
+ mjml: string;
20
+ }
21
+ export declare const testEmailTemplate: z.ZodObject<{
22
+ to: z.ZodString;
23
+ subject: z.ZodString;
24
+ mjml: z.ZodString;
25
+ }, "strip", z.ZodTypeAny, {
26
+ to?: string;
27
+ subject?: string;
28
+ mjml?: string;
29
+ }, {
30
+ to?: string;
31
+ subject?: string;
32
+ mjml?: string;
33
+ }>;
34
+ export interface EmailAttachment {
35
+ Content: string;
36
+ Type: string;
37
+ FileName: string;
38
+ }
39
+ export declare enum Layout {
40
+ default = "layouts/default.ejs"
41
+ }
42
+ export declare enum Content {
43
+ simple = "simple/simple.ejs",
44
+ doubleAction = "doubleAction/doubleAction.ejs"
45
+ }
46
+ export type Theme = {
47
+ logo: string;
48
+ logoLink: string;
49
+ primaryColor: string;
50
+ buttonTextColor: string;
51
+ privacyPolicyLink: string;
52
+ unsubscribeLink: string;
53
+ facebook: string;
54
+ instagram: string;
55
+ twitter: string;
56
+ appName: string;
57
+ };
58
+ export interface EmailVerificationResp {
59
+ res?: boolean;
60
+ suggestion?: string;
61
+ }
62
+ interface SimpleTemplate {
63
+ layout: Layout.default;
64
+ content: Content.simple;
65
+ categories: [EmailCategory.SIMPLE | EmailCategory.OTP | EmailCategory.MEETING];
66
+ theme?: Theme;
67
+ placeholders: {
68
+ title?: string;
69
+ imgSrc?: string;
70
+ imgAlt?: string;
71
+ greeting: string;
72
+ body: string;
73
+ footer: string;
74
+ };
75
+ }
76
+ export type EmailTemplates = SimpleTemplate;
77
+ export interface SendEmailFromTemplateParams {
78
+ template: EmailTemplates;
79
+ to: string;
80
+ subject: string;
81
+ attachments?: EmailAttachment[];
82
+ archive?: boolean;
83
+ }
84
+ export {};
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Content = exports.Layout = exports.testEmailTemplate = exports.EmailCategory = void 0;
4
+ const zod_1 = require("zod");
5
+ // export const themeVariables = {
6
+ // [Theme.Gealium]: {
7
+ // logo: `https://www.${env.BASE_DOMAIN}/assets/images/logo-wide-black.png`,
8
+ // logoLink: `https://www.${env.BASE_DOMAIN}/`,
9
+ // primaryColor: '#4db7a3',
10
+ // buttonTextColor: '#ffffff',
11
+ // privacyPolicyLink: 'https://www.gealium.com/about/privacy',
12
+ // unsubscribeLink: 'https://www.gealium.com',
13
+ // facebook: 'Gealium',
14
+ // instagram: 'gealium_com',
15
+ // twitter: 'https://www.gealium.com',
16
+ // appName: 'Gealium',
17
+ // },
18
+ // [Theme.Agrosocial]: {
19
+ // logo: `https://storage.googleapis.com/public-agrosocial-prod/assets/AGSemailcode.png`,
20
+ // logoLink: `https://www.${env.BASE_DOMAIN}/`,
21
+ // primaryColor: '#4db7a3',
22
+ // buttonTextColor: '#ffffff',
23
+ // privacyPolicyLink: 'https://www.agrosocial.com/termsandprivacy',
24
+ // unsubscribeLink: 'https://www.agrosocial.com',
25
+ // facebook: 'agrosocial',
26
+ // instagram: 'agrosocial',
27
+ // twitter: 'https://www.agrosocial.com',
28
+ // appName: 'AgroSocial',
29
+ // },
30
+ // }
31
+ // export const getThemeFromEnv = (): Theme => {
32
+ // if (env.APP_NAME.toLowerCase() === 'agrosocial') {
33
+ // return Theme.Agrosocial
34
+ // }
35
+ // return Theme.Gealium
36
+ // }
37
+ var EmailCategory;
38
+ (function (EmailCategory) {
39
+ EmailCategory["SIMPLE"] = "SIMPLE";
40
+ EmailCategory["TEST_EMAIL"] = "TEST_EMAIL";
41
+ EmailCategory["EMAIL_VERIFICATION"] = "EMAIL_VERIFICATION";
42
+ EmailCategory["SEND_ONCE"] = "SEND_ONCE";
43
+ EmailCategory["OTP"] = "OTP";
44
+ EmailCategory["MEETING"] = "MEETING";
45
+ EmailCategory["ORGANIZATION_INVITATION"] = "ORGANIZATION_INVITATION";
46
+ EmailCategory["PDF_EXAM"] = "PDF_EXAM";
47
+ })(EmailCategory || (exports.EmailCategory = EmailCategory = {}));
48
+ exports.testEmailTemplate = zod_1.z.object({
49
+ to: zod_1.z.string(),
50
+ subject: zod_1.z.string(),
51
+ mjml: zod_1.z.string(),
52
+ });
53
+ var Layout;
54
+ (function (Layout) {
55
+ Layout["default"] = "layouts/default.ejs";
56
+ })(Layout || (exports.Layout = Layout = {}));
57
+ var Content;
58
+ (function (Content) {
59
+ Content["simple"] = "simple/simple.ejs";
60
+ Content["doubleAction"] = "doubleAction/doubleAction.ejs";
61
+ })(Content || (exports.Content = Content = {}));
62
+ //# sourceMappingURL=email.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.model.js","sourceRoot":"","sources":["../../../../src/server/services/email/email.model.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AAEvB,kCAAkC;AAClC,uBAAuB;AACvB,gFAAgF;AAChF,mDAAmD;AACnD,+BAA+B;AAC/B,kCAAkC;AAClC,kEAAkE;AAClE,kDAAkD;AAClD,2BAA2B;AAC3B,gCAAgC;AAChC,0CAA0C;AAC1C,0BAA0B;AAC1B,OAAO;AACP,0BAA0B;AAC1B,6FAA6F;AAC7F,mDAAmD;AACnD,+BAA+B;AAC/B,kCAAkC;AAClC,uEAAuE;AACvE,qDAAqD;AACrD,8BAA8B;AAC9B,+BAA+B;AAC/B,6CAA6C;AAC7C,6BAA6B;AAC7B,OAAO;AACP,IAAI;AAEJ,gDAAgD;AAChD,uDAAuD;AACvD,8BAA8B;AAC9B,MAAM;AAEN,yBAAyB;AACzB,IAAI;AAEJ,IAAY,aASX;AATD,WAAY,aAAa;IACvB,kCAAiB,CAAA;IACjB,0CAAyB,CAAA;IACzB,0DAAyC,CAAA;IACzC,wCAAuB,CAAA;IACvB,4BAAW,CAAA;IACX,oCAAmB,CAAA;IACnB,oEAAmD,CAAA;IACnD,sCAAqB,CAAA;AACvB,CAAC,EATW,aAAa,6BAAb,aAAa,QASxB;AAaY,QAAA,iBAAiB,GAAG,OAAC,CAAC,MAAM,CAAC;IACxC,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;IACd,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;IACnB,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CAAA;AAWF,IAAY,MAEX;AAFD,WAAY,MAAM;IAChB,yCAA+B,CAAA;AACjC,CAAC,EAFW,MAAM,sBAAN,MAAM,QAEjB;AAED,IAAY,OAGX;AAHD,WAAY,OAAO;IACjB,uCAA4B,CAAA;IAC5B,yDAA8C,CAAA;AAChD,CAAC,EAHW,OAAO,uBAAP,OAAO,QAGlB"}
@@ -0,0 +1,23 @@
1
+ import type { SendGridEmailResponse } from '../sendgrid/sendgrid.model';
2
+ import type { EmailTest, SendEmailFromTemplateParams, Theme } from './email.model';
3
+ import { SendgridService } from '../sendgrid/sendgridApi.service';
4
+ export declare class EmailService {
5
+ private shouldSendEmail;
6
+ private baseDomain;
7
+ private fromName;
8
+ private emailTransport;
9
+ private emailArchive;
10
+ private theme;
11
+ constructor({ fromName, shouldSendEmail, baseDomain, emailTransport, emailArchive, theme, }: {
12
+ fromName: string;
13
+ shouldSendEmail: boolean;
14
+ baseDomain?: string;
15
+ emailTransport: SendgridService;
16
+ emailArchive?: string;
17
+ theme: Theme;
18
+ });
19
+ private compileTemplate;
20
+ private compileMjml;
21
+ sendEmailFromTemplate({ template, to, subject, attachments, archive, }: SendEmailFromTemplateParams): Promise<SendGridEmailResponse>;
22
+ sendEmailTemplateTest(email: EmailTest): Promise<SendGridEmailResponse>;
23
+ }
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmailService = void 0;
4
+ const js_utils_1 = require("@goatlab/js-utils");
5
+ const ejs_1 = require("ejs");
6
+ const mjml_1 = require("mjml");
7
+ const consts_1 = require("../../consts");
8
+ const email_model_1 = require("./email.model");
9
+ class EmailService {
10
+ shouldSendEmail = true;
11
+ baseDomain = '@goatlab.com';
12
+ fromName = '';
13
+ emailTransport;
14
+ emailArchive;
15
+ theme;
16
+ constructor({ fromName, shouldSendEmail, baseDomain, emailTransport, emailArchive, theme, }) {
17
+ this.shouldSendEmail = shouldSendEmail;
18
+ this.fromName = fromName;
19
+ if (baseDomain) {
20
+ this.baseDomain = baseDomain;
21
+ }
22
+ this.emailTransport = emailTransport;
23
+ if (emailArchive?.length) {
24
+ this.emailArchive = emailArchive;
25
+ }
26
+ if (theme) {
27
+ this.theme = theme;
28
+ }
29
+ }
30
+ async compileTemplate(template) {
31
+ const innerContent = await (0, ejs_1.renderFile)(`${consts_1.config.templateDir}/${template.content}`, {
32
+ ...template.placeholders,
33
+ theme: this.theme,
34
+ });
35
+ const html = await (0, ejs_1.renderFile)(`${consts_1.config.templateDir}/${template.layout}`, {
36
+ ...template.placeholders,
37
+ theme: this.theme,
38
+ content: innerContent,
39
+ });
40
+ return html;
41
+ }
42
+ compileMjml(mjml) {
43
+ const compiledMjMl = (0, mjml_1.default)(mjml, {
44
+ keepComments: false,
45
+ });
46
+ if (compiledMjMl.errors.length) {
47
+ console.log(compiledMjMl.errors);
48
+ throw new Error('Template could not compile');
49
+ }
50
+ return compiledMjMl.html;
51
+ }
52
+ async sendEmailFromTemplate({ template, to, subject, attachments, archive, }) {
53
+ if (!this.shouldSendEmail) {
54
+ return {
55
+ isSuccess: true,
56
+ statusCode: 1,
57
+ body: 'Email not sent. No emails are sent in test mode',
58
+ headers: {},
59
+ };
60
+ }
61
+ const mjml = await this.compileTemplate(template);
62
+ const html = this.compileMjml(mjml);
63
+ const bcc = [];
64
+ if (archive && this.emailArchive?.length) {
65
+ bcc.push({
66
+ email: this.emailArchive,
67
+ });
68
+ }
69
+ // This will not work if we are running in other environments (AWS/AZURE) check before using any other env
70
+ const isRunningInGCP =
71
+ // Linux container
72
+ !!(process.platform === 'linux' &&
73
+ // Cloud run
74
+ (process.env.K_SERVICE ??
75
+ // Cloud run job
76
+ process.env.CLOUD_RUN_JOB));
77
+ // Avoid sending emails to real users in dev, test and local prod
78
+ // Prod emails will only go out from linux and (GCP or CIRCLECI)
79
+ const shouldSendEmailToRealUser = to.endsWith(`@${this.baseDomain}`) ||
80
+ (this.shouldSendEmail && isRunningInGCP);
81
+ // Exit if we are testing emails and TEST_EMAIL_ADDRESS is not set
82
+ if (!process.env.TEST_EMAIL_ADDRESS && !shouldSendEmailToRealUser) {
83
+ console.log('Email not sent. TEST_EMAIL_ADDRESS env variable is missing');
84
+ return {
85
+ isSuccess: false,
86
+ statusCode: 1,
87
+ body: 'Email not sent. TEST_EMAIL_ADDRESS env variable is missing',
88
+ headers: {},
89
+ };
90
+ }
91
+ const recipient = shouldSendEmailToRealUser
92
+ ? {
93
+ email: to,
94
+ }
95
+ : {
96
+ email: process.env.TEST_EMAIL_ADDRESS || '',
97
+ };
98
+ if (!this.emailTransport) {
99
+ throw new Error('No email transport (Sendgrid) defined');
100
+ }
101
+ return await this.emailTransport?.sendFinalizedEmail({
102
+ html,
103
+ fromEmail: `info@${this.baseDomain}`,
104
+ fromName: js_utils_1.Strings.capitalize(this.fromName),
105
+ subject,
106
+ replyTo: `no_reply@${this.baseDomain}`,
107
+ recipients: [recipient],
108
+ attachments,
109
+ categories: template.categories,
110
+ bcc,
111
+ });
112
+ }
113
+ async sendEmailTemplateTest(email) {
114
+ const html = this.compileMjml(email.mjml);
115
+ const [username, domain] = email.to.split('@');
116
+ // Emails will only go out to domain accounts
117
+ if (domain && domain !== this.baseDomain) {
118
+ throw new Error(`Cannot send emails to ${domain} accounts`);
119
+ }
120
+ if (!this.emailTransport) {
121
+ throw new Error('No email transport (Sendgrid) defined');
122
+ }
123
+ return await this.emailTransport?.sendFinalizedEmail({
124
+ html,
125
+ fromEmail: `info@${this.baseDomain}`,
126
+ fromName: js_utils_1.Strings.capitalize(this.fromName),
127
+ subject: email.subject,
128
+ replyTo: `no_reply@${this.baseDomain}`,
129
+ recipients: [
130
+ {
131
+ email: `${username}@${this.baseDomain}`,
132
+ },
133
+ ],
134
+ categories: [email_model_1.EmailCategory.TEST_EMAIL],
135
+ });
136
+ }
137
+ }
138
+ exports.EmailService = EmailService;
139
+ //# sourceMappingURL=email.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.service.js","sourceRoot":"","sources":["../../../../src/server/services/email/email.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export interface GCPServiceAccount {
2
+ [k: string]: any;
3
+ keyFilename: string;
4
+ project_id: string;
5
+ client_id: string;
6
+ client_email: string;
7
+ private_key: string;
8
+ private_key_id: string;
9
+ auth_uri: string;
10
+ type: string;
11
+ token_uri: string;
12
+ auth_provider_x509_cert_url: string;
13
+ client_x509_cert_url: string;
14
+ }
15
+ export declare function getGcpServiceAccountFromBase64(base64: string): undefined | GCPServiceAccount;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getGcpServiceAccountFromBase64 = getGcpServiceAccountFromBase64;
4
+ function getGcpServiceAccountFromBase64(base64) {
5
+ // Create Google credentials from Secret
6
+ const serviceAccount = JSON.parse(Buffer.from(base64, 'base64').toString('utf8'));
7
+ return serviceAccount;
8
+ }
9
+ //# sourceMappingURL=getGcpServiceAccountFromBase64.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getGcpServiceAccountFromBase64.js","sourceRoot":"","sources":["../../../../src/server/services/gcp/getGcpServiceAccountFromBase64.ts"],"names":[],"mappings":";;AAeA,wEASC;AATD,SAAgB,8BAA8B,CAC5C,MAAc;IAEd,wCAAwC;IACxC,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAC/B,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAC/C,CAAA;IAED,OAAO,cAAmC,CAAA;AAC5C,CAAC"}
@@ -0,0 +1,32 @@
1
+ export type SecretProvider = 'GCP' | 'FILE' | 'VAULT' | 'ENV';
2
+ export interface VaultConfig {
3
+ endpoint: string;
4
+ token?: string;
5
+ mount?: string;
6
+ namespace?: string;
7
+ }
8
+ export declare class SecretService<SecretType> {
9
+ provider: SecretProvider;
10
+ location: string;
11
+ encryptionKey: string;
12
+ vaultConfig?: VaultConfig;
13
+ constructor({ provider, location, encryptionKey, vaultConfig }: {
14
+ provider: SecretProvider;
15
+ location: string;
16
+ encryptionKey: string;
17
+ vaultConfig?: VaultConfig;
18
+ });
19
+ loadSecretsFromFile(): SecretType;
20
+ loadSecretsFromGCP(): SecretType;
21
+ loadEncryptionKeyFromGCP(): string;
22
+ loadSecretsFromEnv(): SecretType;
23
+ loadSecretsFromVault(): Promise<SecretType>;
24
+ storeSecretsToVault(secrets: Partial<SecretType>): Promise<void>;
25
+ loadSecrets(): SecretType | Promise<SecretType>;
26
+ loadEncryptionKey(): string;
27
+ getSecret(secretName: keyof SecretType): Promise<string>;
28
+ getSecretJson<T = any>(secretName: keyof SecretType): Promise<T>;
29
+ getSecretSync(secretName: keyof SecretType): string;
30
+ getSecretJsonSync<T = any>(secretName: keyof SecretType): T;
31
+ static clearCache(): void;
32
+ }