diff --git a/package-lock.json b/package-lock.json index 978c559..357ea80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,10 @@ "@tsed/schema": "^6.63.2", "@tsed/socketio": "^6.63.2", "@tsed/swagger": "^6.63.2", + "@types/bluebird": "^3.5.36", + "@types/nodemailer": "^6.4.4", + "@types/nodemailer-direct-transport": "^1.0.32", + "@types/nodemailer-smtp-transport": "^2.7.5", "ajv": "^8.6.2", "body-parser": "^1.19.0", "compression": "^1.7.4", @@ -32,6 +36,7 @@ "method-override": "^3.0.0", "moment": "^2.29.1", "mongoose": "^5.13.8", + "nodemailer": "^6.6.5", "socket.io": "^4.1.3" }, "devDependencies": { @@ -44,7 +49,7 @@ "@types/express-session": "^1.17.4", "@types/method-override": "^0.0.32", "@types/multer": "^1.4.7", - "@types/node": "^16.7.1", + "@types/node": "^16.9.6", "ts-node": "^10.2.1", "ts-node-dev": "^1.1.8", "tsconfig-paths": "^3.10.1", @@ -426,6 +431,11 @@ "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", "dev": true }, + "node_modules/@types/bluebird": { + "version": "3.5.36", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.36.tgz", + "integrity": "sha512-HBNx4lhkxN7bx6P0++W8E289foSu8kO8GCk2unhuVggO+cE7rh9DhZUyPhUxNRG9m+5B5BTKxZQ5ZP92x/mx9Q==" + }, "node_modules/@types/body-parser": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", @@ -556,9 +566,79 @@ } }, "node_modules/@types/node": { - "version": "16.7.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.1.tgz", - "integrity": "sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A==" + "version": "16.9.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.6.tgz", + "integrity": "sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==" + }, + "node_modules/@types/nodemailer": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.4.tgz", + "integrity": "sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/nodemailer-direct-transport": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/@types/nodemailer-direct-transport/-/nodemailer-direct-transport-1.0.32.tgz", + "integrity": "sha512-1S0E405ghuApKUSH3x1dJpu/4Y8cQP4kQZ6BSLsfrM5uJB+IKKJuxCUVCDJoe3OTydPtzAoKFGggseXY97jlDw==", + "dependencies": { + "@types/nodemailer": "^3" + } + }, + "node_modules/@types/nodemailer-direct-transport/node_modules/@types/nodemailer": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-3.1.7.tgz", + "integrity": "sha512-z1NHUwMZDnrTQAWvf8AGANfU+KRbBbz+PBHhrxvv+aLCQQRdZw01uidjdRHlbUmHm3EAqlYjqgMyuMaj8Muh8g==", + "dependencies": { + "@types/node": "*", + "@types/nodemailer-direct-transport": "*", + "@types/nodemailer-ses-transport": "*", + "@types/nodemailer-smtp-transport": "*", + "aws-sdk": "^2.37.0" + } + }, + "node_modules/@types/nodemailer-ses-transport": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@types/nodemailer-ses-transport/-/nodemailer-ses-transport-1.5.1.tgz", + "integrity": "sha512-K49ZNWiu+a9Dp9Jv3QeaGXbfxkQNj/i68zmFmQKQ5PnJIoxpT5auuCsGlKva2rnrs+qZLGClbYukwGstwKSKCA==", + "dependencies": { + "@types/nodemailer": "^3", + "aws-sdk": "^2.37.0" + } + }, + "node_modules/@types/nodemailer-ses-transport/node_modules/@types/nodemailer": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-3.1.7.tgz", + "integrity": "sha512-z1NHUwMZDnrTQAWvf8AGANfU+KRbBbz+PBHhrxvv+aLCQQRdZw01uidjdRHlbUmHm3EAqlYjqgMyuMaj8Muh8g==", + "dependencies": { + "@types/node": "*", + "@types/nodemailer-direct-transport": "*", + "@types/nodemailer-ses-transport": "*", + "@types/nodemailer-smtp-transport": "*", + "aws-sdk": "^2.37.0" + } + }, + "node_modules/@types/nodemailer-smtp-transport": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/@types/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.7.5.tgz", + "integrity": "sha512-TziFYmQgyO9QuKvD3j7GcC6rnbp/Js9CEROm5h3u50AAeD8d8LcwoOlhosaEeMyPmy7fVXN63ZC1/MtjvzQViQ==", + "dependencies": { + "@types/node": "*", + "@types/nodemailer": "^3" + } + }, + "node_modules/@types/nodemailer-smtp-transport/node_modules/@types/nodemailer": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-3.1.7.tgz", + "integrity": "sha512-z1NHUwMZDnrTQAWvf8AGANfU+KRbBbz+PBHhrxvv+aLCQQRdZw01uidjdRHlbUmHm3EAqlYjqgMyuMaj8Muh8g==", + "dependencies": { + "@types/node": "*", + "@types/nodemailer-direct-transport": "*", + "@types/nodemailer-ses-transport": "*", + "@types/nodemailer-smtp-transport": "*", + "aws-sdk": "^2.37.0" + } }, "node_modules/@types/qs": { "version": "6.9.7", @@ -792,6 +872,50 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" }, + "node_modules/aws-sdk": { + "version": "2.993.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.993.0.tgz", + "integrity": "sha512-uAxPVkGM0+hWt+OmFUtNgQmmo3tQUW1MJD8wBWFpfw97QpG2WPMv6fEFBJmuaVt0LkElgTs+9oKJsu9WkPIC9Q==", + "hasInstallScript": true, + "dependencies": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/aws-sdk/node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/aws-sdk/node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "node_modules/aws-sdk/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/axios": { "version": "0.21.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", @@ -818,7 +942,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -1614,6 +1737,14 @@ "node": ">= 0.6" } }, + "node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -2390,6 +2521,14 @@ "node": ">=4" } }, + "node_modules/jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/json-schema": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.5.tgz", @@ -2931,6 +3070,14 @@ "tslib": "^2.0.3" } }, + "node_modules/nodemailer": { + "version": "6.6.5", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.5.tgz", + "integrity": "sha512-C/v856DBijUzHcHIgGpQoTrfsH3suKIRAGliIzCstatM2cAa+MYX3LuyCrABiO/cdJTxgBBHXxV1ztiqUwst5A==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -3201,6 +3348,15 @@ "node": ">=0.6" } }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3375,6 +3531,11 @@ "node": ">=6" } }, + "node_modules/sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + }, "node_modules/semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -4064,6 +4225,20 @@ "punycode": "^2.1.0" } }, + "node_modules/url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -4133,6 +4308,23 @@ } } }, + "node_modules/xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "node_modules/xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "engines": { + "node": ">=4.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -4484,6 +4676,11 @@ } } }, + "@types/bluebird": { + "version": "3.5.36", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.36.tgz", + "integrity": "sha512-HBNx4lhkxN7bx6P0++W8E289foSu8kO8GCk2unhuVggO+cE7rh9DhZUyPhUxNRG9m+5B5BTKxZQ5ZP92x/mx9Q==" + }, "@types/body-parser": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", @@ -4614,9 +4811,85 @@ } }, "@types/node": { - "version": "16.7.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.1.tgz", - "integrity": "sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A==" + "version": "16.9.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.6.tgz", + "integrity": "sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==" + }, + "@types/nodemailer": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.4.tgz", + "integrity": "sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw==", + "requires": { + "@types/node": "*" + } + }, + "@types/nodemailer-direct-transport": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/@types/nodemailer-direct-transport/-/nodemailer-direct-transport-1.0.32.tgz", + "integrity": "sha512-1S0E405ghuApKUSH3x1dJpu/4Y8cQP4kQZ6BSLsfrM5uJB+IKKJuxCUVCDJoe3OTydPtzAoKFGggseXY97jlDw==", + "requires": { + "@types/nodemailer": "^3" + }, + "dependencies": { + "@types/nodemailer": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-3.1.7.tgz", + "integrity": "sha512-z1NHUwMZDnrTQAWvf8AGANfU+KRbBbz+PBHhrxvv+aLCQQRdZw01uidjdRHlbUmHm3EAqlYjqgMyuMaj8Muh8g==", + "requires": { + "@types/node": "*", + "@types/nodemailer-direct-transport": "*", + "@types/nodemailer-ses-transport": "*", + "@types/nodemailer-smtp-transport": "*", + "aws-sdk": "^2.37.0" + } + } + } + }, + "@types/nodemailer-ses-transport": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@types/nodemailer-ses-transport/-/nodemailer-ses-transport-1.5.1.tgz", + "integrity": "sha512-K49ZNWiu+a9Dp9Jv3QeaGXbfxkQNj/i68zmFmQKQ5PnJIoxpT5auuCsGlKva2rnrs+qZLGClbYukwGstwKSKCA==", + "requires": { + "@types/nodemailer": "^3", + "aws-sdk": "^2.37.0" + }, + "dependencies": { + "@types/nodemailer": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-3.1.7.tgz", + "integrity": "sha512-z1NHUwMZDnrTQAWvf8AGANfU+KRbBbz+PBHhrxvv+aLCQQRdZw01uidjdRHlbUmHm3EAqlYjqgMyuMaj8Muh8g==", + "requires": { + "@types/node": "*", + "@types/nodemailer-direct-transport": "*", + "@types/nodemailer-ses-transport": "*", + "@types/nodemailer-smtp-transport": "*", + "aws-sdk": "^2.37.0" + } + } + } + }, + "@types/nodemailer-smtp-transport": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/@types/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.7.5.tgz", + "integrity": "sha512-TziFYmQgyO9QuKvD3j7GcC6rnbp/Js9CEROm5h3u50AAeD8d8LcwoOlhosaEeMyPmy7fVXN63ZC1/MtjvzQViQ==", + "requires": { + "@types/node": "*", + "@types/nodemailer": "^3" + }, + "dependencies": { + "@types/nodemailer": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-3.1.7.tgz", + "integrity": "sha512-z1NHUwMZDnrTQAWvf8AGANfU+KRbBbz+PBHhrxvv+aLCQQRdZw01uidjdRHlbUmHm3EAqlYjqgMyuMaj8Muh8g==", + "requires": { + "@types/node": "*", + "@types/nodemailer-direct-transport": "*", + "@types/nodemailer-ses-transport": "*", + "@types/nodemailer-smtp-transport": "*", + "aws-sdk": "^2.37.0" + } + } + } }, "@types/qs": { "version": "6.9.7", @@ -4808,6 +5081,44 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" }, + "aws-sdk": { + "version": "2.993.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.993.0.tgz", + "integrity": "sha512-uAxPVkGM0+hWt+OmFUtNgQmmo3tQUW1MJD8wBWFpfw97QpG2WPMv6fEFBJmuaVt0LkElgTs+9oKJsu9WkPIC9Q==", + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, "axios": { "version": "0.21.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", @@ -4830,8 +5141,7 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "base64id": { "version": "2.0.0", @@ -5451,6 +5761,11 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -6026,6 +6341,11 @@ } } }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" + }, "json-schema": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.5.tgz", @@ -6429,6 +6749,11 @@ "tslib": "^2.0.3" } }, + "nodemailer": { + "version": "6.6.5", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.5.tgz", + "integrity": "sha512-C/v856DBijUzHcHIgGpQoTrfsH3suKIRAGliIzCstatM2cAa+MYX3LuyCrABiO/cdJTxgBBHXxV1ztiqUwst5A==" + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -6630,6 +6955,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -6745,6 +7075,11 @@ "sparse-bitfield": "^3.0.3" } }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -7275,6 +7610,22 @@ "punycode": "^2.1.0" } }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + } + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -7315,6 +7666,20 @@ "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "requires": {} }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 54c59d2..e2bd5fc 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,10 @@ "@tsed/schema": "^6.63.2", "@tsed/socketio": "^6.63.2", "@tsed/swagger": "^6.63.2", + "@types/bluebird": "^3.5.36", + "@types/nodemailer": "^6.4.4", + "@types/nodemailer-direct-transport": "^1.0.32", + "@types/nodemailer-smtp-transport": "^2.7.5", "ajv": "^8.6.2", "body-parser": "^1.19.0", "compression": "^1.7.4", @@ -34,6 +38,7 @@ "method-override": "^3.0.0", "moment": "^2.29.1", "mongoose": "^5.13.8", + "nodemailer": "^6.6.5", "socket.io": "^4.1.3" }, "devDependencies": { @@ -46,7 +51,7 @@ "@types/express-session": "^1.17.4", "@types/method-override": "^0.0.32", "@types/multer": "^1.4.7", - "@types/node": "^16.7.1", + "@types/node": "^16.9.6", "ts-node": "^10.2.1", "ts-node-dev": "^1.1.8", "tsconfig-paths": "^3.10.1", @@ -56,4 +61,4 @@ "packageManager": "npm", "convention": "default" } -} \ No newline at end of file +} diff --git a/src/Server.ts b/src/Server.ts index bdd604f..f8165a0 100644 --- a/src/Server.ts +++ b/src/Server.ts @@ -78,8 +78,9 @@ import compression from "compression"; resource: process.env.KEYCLOAK_CLIENT_ID || "backend", confidentialPort: process.env.KEYCLOAK_CONF_PORT || 0 }, - nodeMailer: { - smtp: "ahoj" + nodemailer: { + transport: process.env.NODEMAILER_TRANSPORT, + defaults: process.env.NODEMAILER_DEFAULTS, } }) export class Server { diff --git a/src/controllers/rest.controller.ts b/src/controllers/rest.controller.ts index 43cd36b..7e28ae2 100644 --- a/src/controllers/rest.controller.ts +++ b/src/controllers/rest.controller.ts @@ -3,16 +3,12 @@ import { ContentType, Description, Summary } from "@tsed/schema"; import { SwaggerSettings } from "@tsed/swagger"; import moment from "moment"; import { KeycloakAuth } from "src/decorators/KeycloakAuthOptions.decorator"; -import { NodeMailerService } from "src/services/NodeMailer.service"; @Controller("/") export class RestController { @Constant("swagger") swagger: SwaggerSettings[]; - @Inject() - nodeMailerService: NodeMailerService; - @ContentType('application/json') @Get("/") @Summary("Root route of the API") @@ -30,9 +26,4 @@ export class RestController { protected() { return { "test": "ahoj" }; } - - @Get("/smtp") - smtp(){ - return this.nodeMailerService.getSmtp(); - } } diff --git a/src/services/NodeMailer.config.ts b/src/services/NodeMailer.config.ts deleted file mode 100644 index 22d65fc..0000000 --- a/src/services/NodeMailer.config.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface NodeMailerConfig{ - smtp: string; -}; \ No newline at end of file diff --git a/src/services/NodeMailer.service.ts b/src/services/NodeMailer.service.ts deleted file mode 100644 index e65479a..0000000 --- a/src/services/NodeMailer.service.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {Constant, Injectable} from "@tsed/di"; -import { NodeMailerConfig } from "./NodeMailer.config"; - -@Injectable() -export class NodeMailerService { - @Constant("nodeMailer") - nodeMailer: NodeMailerConfig; - - public getSmtp(): string{ - return this.nodeMailer.smtp; - } -} diff --git a/src/services/Nodemailer.config.ts b/src/services/Nodemailer.config.ts new file mode 100644 index 0000000..c03d2cf --- /dev/null +++ b/src/services/Nodemailer.config.ts @@ -0,0 +1,8 @@ +import { Address } from 'nodemailer/lib/mailer'; +import SMTPTransport from 'nodemailer/lib/smtp-transport'; + +export interface NodemailerConfig { + transport?: SMTPTransport | SMTPTransport.Options | string, + defaults?: SMTPTransport.Options, + sender?: string | Address, +}; diff --git a/src/services/Nodemailer.service.ts b/src/services/Nodemailer.service.ts new file mode 100644 index 0000000..e50e119 --- /dev/null +++ b/src/services/Nodemailer.service.ts @@ -0,0 +1,96 @@ +import { Constant, Injectable } from "@tsed/di"; +import { NodemailerConfig } from "./Nodemailer.config"; +import * as nodemailer from 'nodemailer'; +import SMTPTransport from "nodemailer/lib/smtp-transport"; +import Mail from "nodemailer/lib/mailer"; +import moment from "moment"; + +@Injectable() +export class NodemailerService { + @Constant("nodemailer") + config: NodemailerConfig; + + private _transporter: nodemailer.Transporter; + + private _testAccount: nodemailer.TestAccount; + + + constructor() { + if (!this.config?.transport) { + // Generate test SMTP service account from ethereal.email + // Only needed if you don't have a real mail account for testing + nodemailer.createTestAccount((err, testAccount) => { + if (err) { + return console.error(err); + } + this._testAccount = testAccount; + console.log(testAccount); + // create reusable transporter object using the default SMTP transport + this._transporter = nodemailer.createTransport({ + host: testAccount.smtp.host, + port: testAccount.smtp.port, + secure: testAccount.smtp.secure, + auth: { + user: testAccount.user, // generated ethereal user + pass: testAccount.pass, // generated ethereal password + }, + }); + this.transporterVerify(); + this.sendTestMail(); + }); + } else { + this._transporter = nodemailer.createTransport( + this.config.transport, + this.config.defaults + ); + this.transporterVerify(); + } + } + + private transporterVerify() { + this._transporter.verify((error) => { + if (error) { + return console.error(error); + } + console.log(`${moment().format('YYYY-MM-DD HH:mm:ss')} Nodemailer: Server is ready to take our messages`); + }) + } + + public async sendTestMail() { + // send mail with defined transport object + let info = await this._transporter.sendMail({ + from: `"Fred Foo 👻" <${this._testAccount.user}>`, // sender address + to: "matuska.lukas@lukasmatuska.cz", // list of receivers + subject: "Hello ✔", // Subject line + text: "Hello world?", // plain text body + html: "Hello world?", // html body + }); + + console.log("Message sent: %s", info.messageId); + // Message sent: + + // Preview only available when sending through an Ethereal account + console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info)); + } + + public async send(id: string, callback: Function) { + // send mail with defined transport object + let info = await this._transporter.sendMail({ + from: this.config.sender, // sender address + to: "matuska.lukas@lukasmatuska.cz", // list of receivers + subject: "Hello ✔", // Subject line + text: "Hello world?", // plain text body + html: "Hello world?", // html body + }); + + console.log("Message sent: %s", info.messageId); + + // Preview only available when sending through an Ethereal account + console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info)); + } + + /*public send(mailOptions: Mail.Options) { + this._transporter.sendMail(mailOptions); + }*/ + +}