diff --git a/backend/package.json b/backend/package.json index c4fa1a695..451a5a86d 100644 --- a/backend/package.json +++ b/backend/package.json @@ -39,6 +39,7 @@ "@types/express": "^4.17.12", "@types/jsonwebtoken": "^8.5.2", "@types/libsodium-wrappers": "^0.7.9", + "@types/nodemailer": "^6.4.4", "@typescript-eslint/eslint-plugin": "^4.28.0", "@typescript-eslint/parser": "^4.28.0", "eslint": "^7.29.0", diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index feff3b6c1..b2ba39553 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -36,7 +36,7 @@ const email = { EMAIL_SENDER: process.env.EMAIL_SENDER || 'info@gradido.net', EMAIL_PASSWORD: process.env.EMAIL_PASSWORD || 'xxx', EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL || 'gmail.com', - EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || 587, + EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || '587', } // This is needed by graphql-directive-auth diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index 6a32974b5..d0cd86ed0 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -3,6 +3,7 @@ import { Resolver, Query, Args, Authorized, Ctx, Mutation } from 'type-graphql' import { getCustomRepository, getConnection, getRepository } from 'typeorm' +import { createTransport } from 'nodemailer' import CONFIG from '../../config' @@ -354,6 +355,8 @@ async function sendCoins( signature: { ed25519: sign }, }) const sigMap = SignatureMap.create({ sigPair: [sigPair] }) + const userRepository = getCustomRepository(UserRepository) + const recipiantUser = await userRepository.findByPubkeyHex(recipiantPublicKey) // created transaction, now save it to db await getConnection().transaction(async (transactionalEntityManager) => { @@ -365,10 +368,8 @@ async function sendCoins( transactionRepository.save(transaction).catch(() => { throw new Error('error saving transaction') }) - console.log('transaction after saving: %o', transaction) - - const userRepository = getCustomRepository(UserRepository) - const recipiantUser = await userRepository.findByPubkeyHex(recipiantPublicKey) + console.log('transaction after saving: %o', transaction) + if (!recipiantUser) { throw new Error('Cannot find recipiant user by local send coins transaction') } @@ -438,6 +439,35 @@ async function sendCoins( }) }) // send notification email + if(CONFIG.EMAIL) { + let transporter = createTransport({ + host: CONFIG.EMAIL_SMTP_URL, + port: Number(CONFIG.EMAIL_SMTP_PORT), + secure: false, // true for 465, false for other ports + requireTLS: true, + auth: { + user: CONFIG.EMAIL_USERNAME, + pass: CONFIG.EMAIL_PASSWORD, + }, + }); + + // send mail with defined transport object + // TODO: translate + let info = await transporter.sendMail({ + from: 'Gradido (nicht antworten) <' + CONFIG.EMAIL_SENDER + '>', // sender address + to: recipiantUser.firstName + ' ' + recipiantUser.lastName + ' <' + recipiantUser.email + '>', // list of receivers + subject: 'Gradido Überweisung', // Subject line + text: 'Hallo ' + recipiantUser.firstName + ' ' + recipiantUser.lastName + ',\n\n' + + 'Du hast soeben ' + amount + ' GDD von ' + senderUser.firstName + ' ' + senderUser.lastName + ' erhalten.\n' + + senderUser.firstName + ' ' + senderUser.lastName + ' schreibt: \n\n' + + memo + '\n\n' + + 'Bitte antworte nicht auf diese E-Mail!\n\n' + + 'Mit freundlichen Grüßen\ņ Gradido Community Server', // plain text body + }); + if(!info.messageId) { + throw new Error('error sending notification email, but transaction succeed') + } + } } return true } diff --git a/backend/yarn.lock b/backend/yarn.lock index 315d077bd..3ad3e65d1 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -923,6 +923,13 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.4.tgz#218712242446fc868d0e007af29a4408c7765bc0" integrity sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A== +"@types/nodemailer@^6.4.4": + version "6.4.4" + resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.4.tgz#c265f7e7a51df587597b3a49a023acaf0c741f4b" + integrity sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw== + dependencies: + "@types/node" "*" + "@types/prettier@^2.1.5": version "2.4.1" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.1.tgz#e1303048d5389563e130f5bdd89d37a99acb75eb" @@ -4204,6 +4211,11 @@ node-releases@^1.1.76: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.76.tgz#df245b062b0cafbd5282ab6792f7dccc2d97f36e" integrity sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA== +nodemailer@^6.6.5: + version "6.6.5" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.6.5.tgz#f9f6953cee5cfe82cbea152eeddacf7a0442049a" + integrity sha512-C/v856DBijUzHcHIgGpQoTrfsH3suKIRAGliIzCstatM2cAa+MYX3LuyCrABiO/cdJTxgBBHXxV1ztiqUwst5A== + nodemon@^2.0.7: version "2.0.7" resolved "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz"