@hedhog/mail 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. package/dist/enums/mail-configuration-type.enum.d.ts +5 -0
  2. package/dist/enums/mail-configuration-type.enum.d.ts.map +1 -0
  3. package/dist/enums/mail-configuration-type.enum.js +9 -0
  4. package/dist/enums/mail-configuration-type.enum.js.map +1 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +19 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/interfaces/mail-module-options.interface.d.ts +13 -0
  10. package/dist/interfaces/mail-module-options.interface.d.ts.map +1 -0
  11. package/dist/interfaces/mail-module-options.interface.js +3 -0
  12. package/dist/interfaces/mail-module-options.interface.js.map +1 -0
  13. package/dist/interfaces/mail-type.d.ts +13 -0
  14. package/dist/interfaces/mail-type.d.ts.map +1 -0
  15. package/dist/interfaces/mail-type.js +3 -0
  16. package/dist/interfaces/mail-type.js.map +1 -0
  17. package/dist/mail.consts.d.ts +17 -0
  18. package/dist/mail.consts.d.ts.map +1 -0
  19. package/dist/mail.consts.js +5 -0
  20. package/dist/mail.consts.js.map +1 -0
  21. package/dist/mail.module.d.ts +6 -0
  22. package/dist/mail.module.d.ts.map +1 -0
  23. package/dist/mail.module.js +37 -0
  24. package/dist/mail.module.js.map +1 -0
  25. package/dist/mail.service.d.ts +14 -0
  26. package/dist/mail.service.d.ts.map +1 -0
  27. package/dist/mail.service.js +247 -0
  28. package/dist/mail.service.js.map +1 -0
  29. package/dist/mail.service.spec.d.ts +2 -0
  30. package/dist/mail.service.spec.d.ts.map +1 -0
  31. package/dist/mail.service.spec.js +17 -0
  32. package/dist/mail.service.spec.js.map +1 -0
  33. package/package.json +13 -0
  34. package/src/enums/mail-configuration-type.enum.ts +4 -0
  35. package/src/index.ts +2 -0
  36. package/src/interfaces/mail-module-options.interface.ts +13 -0
  37. package/src/interfaces/mail-type.ts +12 -0
  38. package/src/mail.consts.ts +20 -0
  39. package/src/mail.module.ts +26 -0
  40. package/src/mail.service.spec.ts +18 -0
  41. package/src/mail.service.ts +256 -0
  42. package/tsconfig.lib.json +9 -0
  43. package/tsconfig.production.json +20 -0
@@ -0,0 +1,5 @@
1
+ export declare enum MailConfigurationTypeEnum {
2
+ AWS = "AWS",
3
+ GMAIL = "GMAIL"
4
+ }
5
+ //# sourceMappingURL=mail-configuration-type.enum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-configuration-type.enum.d.ts","sourceRoot":"","sources":["../../src/enums/mail-configuration-type.enum.ts"],"names":[],"mappings":"AAAA,oBAAY,yBAAyB;IACjC,GAAG,QAAQ;IACX,KAAK,UAAU;CAClB"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MailConfigurationTypeEnum = void 0;
4
+ var MailConfigurationTypeEnum;
5
+ (function (MailConfigurationTypeEnum) {
6
+ MailConfigurationTypeEnum["AWS"] = "AWS";
7
+ MailConfigurationTypeEnum["GMAIL"] = "GMAIL";
8
+ })(MailConfigurationTypeEnum || (exports.MailConfigurationTypeEnum = MailConfigurationTypeEnum = {}));
9
+ //# sourceMappingURL=mail-configuration-type.enum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-configuration-type.enum.js","sourceRoot":"","sources":["../../src/enums/mail-configuration-type.enum.ts"],"names":[],"mappings":";;;AAAA,IAAY,yBAGX;AAHD,WAAY,yBAAyB;IACjC,wCAAW,CAAA;IACX,4CAAe,CAAA;AACnB,CAAC,EAHW,yBAAyB,yCAAzB,yBAAyB,QAGpC"}
@@ -0,0 +1,3 @@
1
+ export * from './mail.module';
2
+ export * from './mail.service';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
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
+ __exportStar(require("./mail.module"), exports);
18
+ __exportStar(require("./mail.service"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,iDAA+B"}
@@ -0,0 +1,13 @@
1
+ import { MailConfigurationTypeEnum } from "../enums/mail-configuration-type.enum";
2
+ export interface MailModuleOptions {
3
+ global?: boolean;
4
+ mailConfigurationType: MailConfigurationTypeEnum;
5
+ host?: string;
6
+ from?: string;
7
+ accessKeyId?: string;
8
+ secretAccessKey?: string;
9
+ clientId?: string;
10
+ clientSecret?: string;
11
+ refreshToken?: string;
12
+ }
13
+ //# sourceMappingURL=mail-module-options.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-module-options.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/mail-module-options.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAElF,MAAM,WAAW,iBAAiB;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qBAAqB,EAAE,yBAAyB,CAAC;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=mail-module-options.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-module-options.interface.js","sourceRoot":"","sources":["../../src/interfaces/mail-module-options.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ export interface MailType {
2
+ from?: string;
3
+ to: string | string[];
4
+ cc?: string | string[];
5
+ bcc?: string | string[];
6
+ subject?: string;
7
+ body?: string;
8
+ replyTo?: string | string[];
9
+ priority?: string;
10
+ createdAt?: string;
11
+ updatedAt?: string;
12
+ }
13
+ //# sourceMappingURL=mail-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-type.d.ts","sourceRoot":"","sources":["../../src/interfaces/mail-type.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=mail-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-type.js","sourceRoot":"","sources":["../../src/interfaces/mail-type.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import { MailType } from './interfaces/mail-type';
2
+ export type MailAttachment = {
3
+ filename?: string;
4
+ content?: Buffer;
5
+ contentType?: string;
6
+ };
7
+ export type Mail = {
8
+ attachments?: MailAttachment[];
9
+ } & MailType;
10
+ export type MailConfig = {
11
+ host?: string;
12
+ from?: string;
13
+ accessKeyId?: string;
14
+ secretAccessKey?: string;
15
+ };
16
+ export declare const MAIL_MODULE_OPTIONS = "MAIL_MODULE_OPTIONS";
17
+ //# sourceMappingURL=mail.consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.consts.d.ts","sourceRoot":"","sources":["../src/mail.consts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAChC,GAAG,QAAQ,CAAC;AAEb,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,mBAAmB,wBAAwB,CAAC"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAIL_MODULE_OPTIONS = void 0;
4
+ exports.MAIL_MODULE_OPTIONS = 'MAIL_MODULE_OPTIONS';
5
+ //# sourceMappingURL=mail.consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.consts.js","sourceRoot":"","sources":["../src/mail.consts.ts"],"names":[],"mappings":";;;AAmBa,QAAA,mBAAmB,GAAG,qBAAqB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { MailModuleOptions } from './interfaces/mail-module-options.interface';
3
+ export declare class MailModule {
4
+ static init(options: MailModuleOptions): DynamicModule;
5
+ }
6
+ //# sourceMappingURL=mail.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.module.d.ts","sourceRoot":"","sources":["../src/mail.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAK/E,qBAKa,UAAU;IACrB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,GAAG,aAAa;CAYvD"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var MailModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.MailModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const mail_service_1 = require("./mail.service");
13
+ const mail_consts_1 = require("./mail.consts");
14
+ const axios_1 = require("@nestjs/axios");
15
+ let MailModule = MailModule_1 = class MailModule {
16
+ static init(options) {
17
+ return {
18
+ module: MailModule_1,
19
+ global: options.global,
20
+ providers: [
21
+ {
22
+ provide: mail_consts_1.MAIL_MODULE_OPTIONS,
23
+ useValue: options || {},
24
+ },
25
+ ],
26
+ };
27
+ }
28
+ };
29
+ exports.MailModule = MailModule;
30
+ exports.MailModule = MailModule = MailModule_1 = __decorate([
31
+ (0, common_1.Module)({
32
+ imports: [axios_1.HttpModule],
33
+ providers: [mail_service_1.MailService],
34
+ exports: [mail_service_1.MailService],
35
+ })
36
+ ], MailModule);
37
+ //# sourceMappingURL=mail.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.module.js","sourceRoot":"","sources":["../src/mail.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,iDAA6C;AAG7C,+CAAoD;AACpD,yCAAwD;AAOjD,IAAM,UAAU,kBAAhB,MAAM,UAAU;IACrB,MAAM,CAAC,IAAI,CAAC,OAA0B;QACpC,OAAO;YACL,MAAM,EAAE,YAAU;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,iCAAmB;oBAC5B,QAAQ,EAAE,OAAO,IAAI,EAAE;iBACxB;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAbY,gCAAU;qBAAV,UAAU;IALtB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,kBAAU,CAAC;QACrB,SAAS,EAAE,CAAC,0BAAW,CAAC;QACxB,OAAO,EAAE,CAAC,0BAAW,CAAC;KACvB,CAAC;GACW,UAAU,CAatB"}
@@ -0,0 +1,14 @@
1
+ import { Mail } from './mail.consts';
2
+ import { SES } from 'aws-sdk';
3
+ import { MailModuleOptions } from './interfaces/mail-module-options.interface';
4
+ import { HttpService } from '@nestjs/axios';
5
+ export declare class MailService {
6
+ private readonly mailConfig;
7
+ private readonly httpService;
8
+ constructor(mailConfig: MailModuleOptions, httpService: HttpService);
9
+ send(mail: Mail): Promise<void>;
10
+ createRawEmail(mail: Mail): Promise<string>;
11
+ sendWithGmail(mail: Mail): Promise<import("axios").AxiosResponse<any, any>>;
12
+ sendWithSES(mail: Mail): Promise<import("aws-sdk/lib/request").PromiseResult<SES.SendRawEmailResponse, import("aws-sdk").AWSError>>;
13
+ }
14
+ //# sourceMappingURL=mail.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.service.d.ts","sourceRoot":"","sources":["../src/mail.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAuB,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAG9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,qBACa,WAAW;IAES,OAAO,CAAC,QAAQ,CAAC,UAAU;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW;gBADkB,UAAU,EAAE,iBAAiB,EAC1D,WAAW,EAAE,WAAW;IAGrC,IAAI,CAAC,IAAI,EAAE,IAAI;IAYf,cAAc,CAAC,IAAI,EAAE,IAAI;IAyEzB,aAAa,CAAC,IAAI,EAAE,IAAI;IAqCxB,WAAW,CAAC,IAAI,EAAE,IAAI;CAoH7B"}
@@ -0,0 +1,247 @@
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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || function (mod) {
25
+ if (mod && mod.__esModule) return mod;
26
+ var result = {};
27
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
+ __setModuleDefault(result, mod);
29
+ return result;
30
+ };
31
+ var __metadata = (this && this.__metadata) || function (k, v) {
32
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
33
+ };
34
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
35
+ return function (target, key) { decorator(target, key, paramIndex); }
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.MailService = void 0;
39
+ const common_1 = require("@nestjs/common");
40
+ const mail_consts_1 = require("./mail.consts");
41
+ const aws_sdk_1 = require("aws-sdk");
42
+ const mimemessage = __importStar(require("mimemessage"));
43
+ const mail_configuration_type_enum_1 = require("./enums/mail-configuration-type.enum");
44
+ const googleapis_1 = require("googleapis");
45
+ const axios_1 = require("@nestjs/axios");
46
+ const rxjs_1 = require("rxjs");
47
+ let MailService = class MailService {
48
+ constructor(mailConfig, httpService) {
49
+ this.mailConfig = mailConfig;
50
+ this.httpService = httpService;
51
+ }
52
+ async send(mail) {
53
+ switch (this.mailConfig.mailConfigurationType) {
54
+ case mail_configuration_type_enum_1.MailConfigurationTypeEnum.AWS:
55
+ await this.sendWithSES(mail);
56
+ break;
57
+ case mail_configuration_type_enum_1.MailConfigurationTypeEnum.GMAIL:
58
+ await this.sendWithGmail(mail);
59
+ break;
60
+ }
61
+ }
62
+ async createRawEmail(mail) {
63
+ var _a;
64
+ if (mail.attachments instanceof Array && ((_a = mail.attachments) === null || _a === void 0 ? void 0 : _a.length)) {
65
+ const mailContent = mimemessage.factory({
66
+ contentType: 'multipart/mixed',
67
+ body: [],
68
+ });
69
+ mailContent.header('From', mail.from);
70
+ mailContent.header('To', mail.to);
71
+ mailContent.header('Subject', mail.subject);
72
+ const alternateEntity = mimemessage.factory({
73
+ contentType: 'multipart/alternate',
74
+ body: [],
75
+ });
76
+ const htmlEntity = mimemessage.factory({
77
+ contentType: 'text/html;charset=utf-8',
78
+ body: mail.body,
79
+ });
80
+ alternateEntity.body.push(htmlEntity);
81
+ mailContent.body.push(alternateEntity);
82
+ await Promise.all(mail.attachments.map(async (attachment) => {
83
+ const attachmentEntity = mimemessage.factory({
84
+ contentType: attachment.contentType,
85
+ contentTransferEncoding: 'base64',
86
+ body: attachment.content
87
+ .toString('base64')
88
+ .replace(/([^\0]{76})/g, '$1\n'),
89
+ });
90
+ attachmentEntity.header('Content-Disposition', `attachment; filename="${attachment.filename}"`);
91
+ mailContent.body.push(attachmentEntity);
92
+ }));
93
+ const messageString = mailContent.toString();
94
+ const encodedMessage = Buffer.from(messageString)
95
+ .toString('base64')
96
+ .replace(/\+/g, '-')
97
+ .replace(/\//g, '_')
98
+ .replace(/=+$/, '');
99
+ return encodedMessage;
100
+ }
101
+ else {
102
+ const messageParts = [
103
+ `From: ${mail.from}`,
104
+ `To: ${mail.to instanceof Array ? mail.to.join(',') : mail.to}`,
105
+ `Subject: ${mail.subject}`,
106
+ 'Content-Type: text/plain; charset="UTF-8"',
107
+ '',
108
+ mail.body,
109
+ ];
110
+ const message = messageParts.join('\n');
111
+ const encodedMessage = Buffer.from(message)
112
+ .toString('base64')
113
+ .replace(/\+/g, '-')
114
+ .replace(/\//g, '_')
115
+ .replace(/=+$/, '');
116
+ return encodedMessage;
117
+ }
118
+ }
119
+ async sendWithGmail(mail) {
120
+ const { clientId, clientSecret, from, refreshToken } = this.mailConfig;
121
+ const redirectURI = 'https://developers.google.com/oauthplayground';
122
+ const oauth2Client = new googleapis_1.google.auth.OAuth2(clientId, clientSecret, redirectURI);
123
+ oauth2Client.setCredentials({
124
+ refresh_token: refreshToken,
125
+ });
126
+ const { token } = await oauth2Client.getAccessToken();
127
+ const raw = await this.createRawEmail(Object.assign(Object.assign({}, mail), { from }));
128
+ const url = 'https://www.googleapis.com/gmail/v1/users/me/messages/send';
129
+ const requestBody = {
130
+ raw,
131
+ };
132
+ const headers = {
133
+ Authorization: `Bearer ${token}`,
134
+ 'Content-Type': 'application/json',
135
+ };
136
+ const response = this.httpService.post(url, requestBody, { headers });
137
+ return (0, rxjs_1.firstValueFrom)(response);
138
+ }
139
+ async sendWithSES(mail) {
140
+ const { host, from, accessKeyId, secretAccessKey } = this.mailConfig;
141
+ const ses = new aws_sdk_1.SES({
142
+ apiVersion: '2010-12-01',
143
+ region: host.split('.')[1],
144
+ credentials: {
145
+ accessKeyId,
146
+ secretAccessKey,
147
+ },
148
+ });
149
+ ses.config.update({
150
+ credentials: {
151
+ accessKeyId,
152
+ secretAccessKey,
153
+ },
154
+ });
155
+ if (typeof mail.to === 'string') {
156
+ mail.to = mail.to.split(';');
157
+ }
158
+ if (typeof mail.bcc === 'string') {
159
+ mail.bcc = mail.bcc.split(';');
160
+ }
161
+ else if (!mail.bcc) {
162
+ mail.bcc = [];
163
+ }
164
+ if (typeof mail.cc === 'string') {
165
+ mail.cc = mail.cc.split(';');
166
+ }
167
+ else if (!mail.cc) {
168
+ mail.cc = [];
169
+ }
170
+ if (typeof mail.replyTo === 'string') {
171
+ mail.replyTo = mail.replyTo.split(';');
172
+ }
173
+ else if (!mail.replyTo) {
174
+ mail.replyTo = [];
175
+ }
176
+ if (mail.attachments instanceof Array && mail.attachments.length > 0) {
177
+ const mailContent = mimemessage.factory({
178
+ contentType: 'multipart/mixed',
179
+ body: [],
180
+ });
181
+ mailContent.header('From', from);
182
+ mailContent.header('To', mail.to);
183
+ mailContent.header('Subject', mail.subject);
184
+ const alternateEntity = mimemessage.factory({
185
+ contentType: 'multipart/alternate',
186
+ body: [],
187
+ });
188
+ const htmlEntity = mimemessage.factory({
189
+ contentType: 'text/html;charset=utf-8',
190
+ body: mail.body,
191
+ });
192
+ alternateEntity.body.push(htmlEntity);
193
+ mailContent.body.push(alternateEntity);
194
+ await Promise.all(mail.attachments.map((item) => {
195
+ const attachmentEntity = mimemessage.factory({
196
+ contentType: item.contentType,
197
+ contentTransferEncoding: 'base64',
198
+ body: item.content
199
+ .toString('base64')
200
+ .replace(/([^\0]{76})/g, '$1\n'),
201
+ });
202
+ attachmentEntity.header('Content-Disposition', `attachment ;filename="${item.filename}"`);
203
+ mailContent.body.push(attachmentEntity);
204
+ }));
205
+ return ses
206
+ .sendRawEmail({
207
+ RawMessage: { Data: mailContent.toString() },
208
+ })
209
+ .promise();
210
+ }
211
+ else {
212
+ const params = {
213
+ Destination: {
214
+ ToAddresses: mail.to,
215
+ BccAddresses: mail.bcc,
216
+ CcAddresses: mail.cc,
217
+ },
218
+ Message: {
219
+ Body: {
220
+ Html: {
221
+ Data: mail.body,
222
+ Charset: 'utf-8',
223
+ },
224
+ Text: {
225
+ Data: mail.body,
226
+ Charset: 'utf-8',
227
+ },
228
+ },
229
+ Subject: {
230
+ Data: mail.subject,
231
+ Charset: 'utf-8',
232
+ },
233
+ },
234
+ ReplyToAddresses: mail.replyTo,
235
+ Source: from,
236
+ };
237
+ return ses.sendEmail(params).promise();
238
+ }
239
+ }
240
+ };
241
+ exports.MailService = MailService;
242
+ exports.MailService = MailService = __decorate([
243
+ (0, common_1.Injectable)(),
244
+ __param(0, (0, common_1.Inject)(mail_consts_1.MAIL_MODULE_OPTIONS)),
245
+ __metadata("design:paramtypes", [Object, axios_1.HttpService])
246
+ ], MailService);
247
+ //# sourceMappingURL=mail.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.service.js","sourceRoot":"","sources":["../src/mail.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mail.service.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.service.spec.d.ts","sourceRoot":"","sources":["../src/mail.service.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const testing_1 = require("@nestjs/testing");
4
+ const mail_service_1 = require("./mail.service");
5
+ describe('MailService', () => {
6
+ let service;
7
+ beforeEach(async () => {
8
+ const module = await testing_1.Test.createTestingModule({
9
+ providers: [mail_service_1.MailService],
10
+ }).compile();
11
+ service = module.get(mail_service_1.MailService);
12
+ });
13
+ it('should be defined', () => {
14
+ expect(service).toBeDefined();
15
+ });
16
+ });
17
+ //# sourceMappingURL=mail.service.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.service.spec.js","sourceRoot":"","sources":["../src/mail.service.spec.ts"],"names":[],"mappings":";;AAAA,6CAAsD;AACtD,iDAA6C;AAE7C,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,OAAoB,CAAC;IAEzB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,MAAM,GAAkB,MAAM,cAAI,CAAC,mBAAmB,CAAC;YAC3D,SAAS,EAAE,CAAC,0BAAW,CAAC;SACzB,CAAC,CAAC,OAAO,EAAE,CAAC;QAEb,OAAO,GAAG,MAAM,CAAC,GAAG,CAAc,0BAAW,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC3B,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "@hedhog/mail",
3
+ "version": "0.0.3",
4
+ "main": "dist/index.js",
5
+ "scripts": {
6
+ "build": "tsc --project tsconfig.production.json && npm version patch",
7
+ "prod": "npm run build && npm publish --access public"
8
+ },
9
+ "keywords": [],
10
+ "author": "HedHog",
11
+ "license": "MIT",
12
+ "description": ""
13
+ }
@@ -0,0 +1,4 @@
1
+ export enum MailConfigurationTypeEnum {
2
+ AWS = 'AWS',
3
+ GMAIL = 'GMAIL',
4
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './mail.module';
2
+ export * from './mail.service';
@@ -0,0 +1,13 @@
1
+ import { MailConfigurationTypeEnum } from "../enums/mail-configuration-type.enum";
2
+
3
+ export interface MailModuleOptions {
4
+ global?: boolean;
5
+ mailConfigurationType: MailConfigurationTypeEnum;
6
+ host?: string;
7
+ from?: string;
8
+ accessKeyId?: string;
9
+ secretAccessKey?: string;
10
+ clientId?: string;
11
+ clientSecret?: string;
12
+ refreshToken?: string;
13
+ }
@@ -0,0 +1,12 @@
1
+ export interface MailType {
2
+ from?: string;
3
+ to: string | string[];
4
+ cc?: string | string[];
5
+ bcc?: string | string[];
6
+ subject?: string;
7
+ body?: string;
8
+ replyTo?: string | string[];
9
+ priority?: string;
10
+ createdAt?: string;
11
+ updatedAt?: string;
12
+ }
@@ -0,0 +1,20 @@
1
+ import { MailType } from './interfaces/mail-type';
2
+
3
+ export type MailAttachment = {
4
+ filename?: string;
5
+ content?: Buffer;
6
+ contentType?: string;
7
+ };
8
+
9
+ export type Mail = {
10
+ attachments?: MailAttachment[];
11
+ } & MailType;
12
+
13
+ export type MailConfig = {
14
+ host?: string;
15
+ from?: string;
16
+ accessKeyId?: string;
17
+ secretAccessKey?: string;
18
+ };
19
+
20
+ export const MAIL_MODULE_OPTIONS = 'MAIL_MODULE_OPTIONS';
@@ -0,0 +1,26 @@
1
+ import { DynamicModule, Module } from '@nestjs/common';
2
+ import { MailService } from './mail.service';
3
+ import { MailModuleOptions } from './interfaces/mail-module-options.interface';
4
+ import { MailConfigurationTypeEnum } from './enums/mail-configuration-type.enum';
5
+ import { MAIL_MODULE_OPTIONS } from './mail.consts';
6
+ import { HttpModule, HttpService } from '@nestjs/axios';
7
+
8
+ @Module({
9
+ imports: [HttpModule],
10
+ providers: [MailService],
11
+ exports: [MailService],
12
+ })
13
+ export class MailModule {
14
+ static init(options: MailModuleOptions): DynamicModule {
15
+ return {
16
+ module: MailModule,
17
+ global: options.global,
18
+ providers: [
19
+ {
20
+ provide: MAIL_MODULE_OPTIONS,
21
+ useValue: options || {},
22
+ },
23
+ ],
24
+ };
25
+ }
26
+ }
@@ -0,0 +1,18 @@
1
+ import { Test, TestingModule } from '@nestjs/testing';
2
+ import { MailService } from './mail.service';
3
+
4
+ describe('MailService', () => {
5
+ let service: MailService;
6
+
7
+ beforeEach(async () => {
8
+ const module: TestingModule = await Test.createTestingModule({
9
+ providers: [MailService],
10
+ }).compile();
11
+
12
+ service = module.get<MailService>(MailService);
13
+ });
14
+
15
+ it('should be defined', () => {
16
+ expect(service).toBeDefined();
17
+ });
18
+ });
@@ -0,0 +1,256 @@
1
+ import { Inject, Injectable } from '@nestjs/common';
2
+ import { Mail, MAIL_MODULE_OPTIONS } from './mail.consts';
3
+ import { SES } from 'aws-sdk';
4
+ import * as mimemessage from 'mimemessage';
5
+ import { MailConfigurationTypeEnum } from './enums/mail-configuration-type.enum';
6
+ import { MailModuleOptions } from './interfaces/mail-module-options.interface';
7
+ import { google } from 'googleapis';
8
+ import { HttpService } from '@nestjs/axios';
9
+ import { firstValueFrom } from 'rxjs';
10
+
11
+ @Injectable()
12
+ export class MailService {
13
+ constructor(
14
+ @Inject(MAIL_MODULE_OPTIONS) private readonly mailConfig: MailModuleOptions,
15
+ private readonly httpService: HttpService,
16
+ ) {}
17
+
18
+ async send(mail: Mail) {
19
+ switch (this.mailConfig.mailConfigurationType) {
20
+ case MailConfigurationTypeEnum.AWS:
21
+ await this.sendWithSES(mail);
22
+ break;
23
+
24
+ case MailConfigurationTypeEnum.GMAIL:
25
+ await this.sendWithGmail(mail);
26
+ break;
27
+ }
28
+ }
29
+
30
+ async createRawEmail(mail: Mail) {
31
+ if (mail.attachments instanceof Array && mail.attachments?.length) {
32
+ const mailContent = mimemessage.factory({
33
+ contentType: 'multipart/mixed',
34
+ body: [],
35
+ });
36
+
37
+ mailContent.header('From', mail.from);
38
+ mailContent.header('To', mail.to);
39
+ mailContent.header('Subject', mail.subject);
40
+
41
+ const alternateEntity = mimemessage.factory({
42
+ contentType: 'multipart/alternate',
43
+ body: [],
44
+ });
45
+
46
+ const htmlEntity = mimemessage.factory({
47
+ contentType: 'text/html;charset=utf-8',
48
+ body: mail.body,
49
+ });
50
+
51
+ alternateEntity.body.push(htmlEntity);
52
+
53
+ mailContent.body.push(alternateEntity);
54
+
55
+ await Promise.all(
56
+ mail.attachments.map(async (attachment) => {
57
+ const attachmentEntity = mimemessage.factory({
58
+ contentType: attachment.contentType,
59
+ contentTransferEncoding: 'base64',
60
+ body: attachment.content
61
+ .toString('base64')
62
+ .replace(/([^\0]{76})/g, '$1\n'),
63
+ });
64
+
65
+ attachmentEntity.header(
66
+ 'Content-Disposition',
67
+ `attachment; filename="${attachment.filename}"`,
68
+ );
69
+
70
+ mailContent.body.push(attachmentEntity);
71
+ }),
72
+ );
73
+
74
+ const messageString = mailContent.toString();
75
+ const encodedMessage = Buffer.from(messageString)
76
+ .toString('base64')
77
+ .replace(/\+/g, '-')
78
+ .replace(/\//g, '_')
79
+ .replace(/=+$/, '');
80
+
81
+ return encodedMessage;
82
+ } else {
83
+ const messageParts = [
84
+ `From: ${mail.from}`,
85
+ `To: ${mail.to instanceof Array ? mail.to.join(',') : mail.to}`,
86
+ `Subject: ${mail.subject}`,
87
+ 'Content-Type: text/plain; charset="UTF-8"',
88
+ '',
89
+ mail.body,
90
+ ];
91
+
92
+ const message = messageParts.join('\n');
93
+ const encodedMessage = Buffer.from(message)
94
+ .toString('base64')
95
+ .replace(/\+/g, '-')
96
+ .replace(/\//g, '_')
97
+ .replace(/=+$/, '');
98
+
99
+ return encodedMessage;
100
+ }
101
+ }
102
+
103
+ async sendWithGmail(mail: Mail) {
104
+ const { clientId, clientSecret, from, refreshToken } = this.mailConfig;
105
+ const redirectURI = 'https://developers.google.com/oauthplayground';
106
+
107
+ const oauth2Client = new google.auth.OAuth2(
108
+ clientId,
109
+ clientSecret,
110
+ redirectURI,
111
+ );
112
+
113
+ oauth2Client.setCredentials({
114
+ refresh_token: refreshToken,
115
+ });
116
+
117
+ const { token } = await oauth2Client.getAccessToken();
118
+
119
+ const raw = await this.createRawEmail({
120
+ ...mail,
121
+ from,
122
+ });
123
+
124
+ const url = 'https://www.googleapis.com/gmail/v1/users/me/messages/send';
125
+
126
+ const requestBody = {
127
+ raw,
128
+ };
129
+
130
+ const headers = {
131
+ Authorization: `Bearer ${token}`,
132
+ 'Content-Type': 'application/json',
133
+ };
134
+
135
+ const response = this.httpService.post(url, requestBody, { headers });
136
+
137
+ return firstValueFrom(response);
138
+ }
139
+
140
+ async sendWithSES(mail: Mail) {
141
+ const { host, from, accessKeyId, secretAccessKey } = this.mailConfig;
142
+
143
+ const ses = new SES({
144
+ apiVersion: '2010-12-01',
145
+ region: host.split('.')[1],
146
+ credentials: {
147
+ accessKeyId,
148
+ secretAccessKey,
149
+ },
150
+ });
151
+
152
+ ses.config.update({
153
+ credentials: {
154
+ accessKeyId,
155
+ secretAccessKey,
156
+ },
157
+ });
158
+
159
+ if (typeof mail.to === 'string') {
160
+ mail.to = mail.to.split(';');
161
+ }
162
+ if (typeof mail.bcc === 'string') {
163
+ mail.bcc = mail.bcc.split(';');
164
+ } else if (!mail.bcc) {
165
+ mail.bcc = [];
166
+ }
167
+ if (typeof mail.cc === 'string') {
168
+ mail.cc = mail.cc.split(';');
169
+ } else if (!mail.cc) {
170
+ mail.cc = [];
171
+ }
172
+ if (typeof mail.replyTo === 'string') {
173
+ mail.replyTo = mail.replyTo.split(';');
174
+ } else if (!mail.replyTo) {
175
+ mail.replyTo = [];
176
+ }
177
+
178
+ if (mail.attachments instanceof Array && mail.attachments.length > 0) {
179
+ const mailContent = mimemessage.factory({
180
+ contentType: 'multipart/mixed',
181
+ body: [],
182
+ });
183
+
184
+ mailContent.header('From', from);
185
+ mailContent.header('To', mail.to);
186
+ mailContent.header('Subject', mail.subject);
187
+
188
+ const alternateEntity = mimemessage.factory({
189
+ contentType: 'multipart/alternate',
190
+ body: [],
191
+ });
192
+
193
+ const htmlEntity = mimemessage.factory({
194
+ contentType: 'text/html;charset=utf-8',
195
+ body: mail.body,
196
+ });
197
+
198
+ alternateEntity.body.push(htmlEntity);
199
+
200
+ mailContent.body.push(alternateEntity);
201
+
202
+ await Promise.all(
203
+ mail.attachments.map((item) => {
204
+ const attachmentEntity = mimemessage.factory({
205
+ contentType: item.contentType,
206
+ contentTransferEncoding: 'base64',
207
+ body: item.content
208
+ .toString('base64')
209
+ .replace(/([^\0]{76})/g, '$1\n'),
210
+ });
211
+
212
+ attachmentEntity.header(
213
+ 'Content-Disposition',
214
+ `attachment ;filename="${item.filename}"`,
215
+ );
216
+
217
+ mailContent.body.push(attachmentEntity);
218
+ }),
219
+ );
220
+
221
+ return ses
222
+ .sendRawEmail({
223
+ RawMessage: { Data: mailContent.toString() },
224
+ })
225
+ .promise();
226
+ } else {
227
+ const params = {
228
+ Destination: {
229
+ ToAddresses: mail.to,
230
+ BccAddresses: mail.bcc,
231
+ CcAddresses: mail.cc,
232
+ },
233
+ Message: {
234
+ Body: {
235
+ Html: {
236
+ Data: mail.body,
237
+ Charset: 'utf-8',
238
+ },
239
+ Text: {
240
+ Data: mail.body,
241
+ Charset: 'utf-8',
242
+ },
243
+ },
244
+ Subject: {
245
+ Data: mail.subject,
246
+ Charset: 'utf-8',
247
+ },
248
+ },
249
+ ReplyToAddresses: mail.replyTo,
250
+ Source: from,
251
+ };
252
+
253
+ return ses.sendEmail(params).promise();
254
+ }
255
+ }
256
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "declaration": true,
5
+ "outDir": "../../dist/libs/mail"
6
+ },
7
+ "include": ["src/**/*"],
8
+ "exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
9
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "experimentalDecorators": true,
4
+ "target": "es2017",
5
+ "module": "commonjs",
6
+ "lib": ["es2017", "es7", "es6"],
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "sourceMap": true,
10
+ "outDir": "./dist",
11
+ "rootDir": "./src",
12
+ "strict": true,
13
+ "noImplicitAny": false,
14
+ "strictNullChecks": false,
15
+ "allowSyntheticDefaultImports": true,
16
+ "esModuleInterop": true,
17
+ "emitDecoratorMetadata": true
18
+ },
19
+ "exclude": ["node_modules", "dist"]
20
+ }