change from sendmail to nodemailer
fix eslint errors corresponding to mail sending
This commit is contained in:
parent
a8987604f3
commit
cb5f4b6ef4
21
README.md
21
README.md
|
@ -41,10 +41,11 @@ npm run build
|
||||||
|
|
||||||
All needed files to run it got created in `./build`
|
All needed files to run it got created in `./build`
|
||||||
|
|
||||||
#### Note:
|
Notes:
|
||||||
If you run into problems, make sure that you have rights to g++ (if not, run as root and then chown username:username -R . after build)
|
|
||||||
|
|
||||||
If `npm install` fails with "unable to connect to github.com" set:
|
- If you run into problems, make sure that you have rights to g++ (if not, run as root and then chown username:username -R . after build)
|
||||||
|
|
||||||
|
- If `npm install` fails with "unable to connect to github.com" set:
|
||||||
|
|
||||||
```
|
```
|
||||||
git config --global url.https://github.com/.insteadOf git://github.com/
|
git config --global url.https://github.com/.insteadOf git://github.com/
|
||||||
|
@ -54,7 +55,7 @@ git config --global url.https://github.com/.insteadOf git://github.com/
|
||||||
### Requirements
|
### Requirements
|
||||||
- nodejs environment with [npm](https://www.npmjs.com/get-npm)
|
- nodejs environment with [npm](https://www.npmjs.com/get-npm)
|
||||||
- [pm2](https://github.com/Unitech/pm2) (`npm install -g pm2`) as process manager and for logging
|
- [pm2](https://github.com/Unitech/pm2) (`npm install -g pm2`) as process manager and for logging
|
||||||
- [redis](https://redis.io/) as database for storgìng the canvas
|
- [redis](https://redis.io/) as database for storìng the canvas
|
||||||
- mysql or mariadb ([setup own user](https://www.digitalocean.com/community/tutorials/how-to-create-a-new-user-and-grant-permissions-in-mysql) and [create database](https://www.w3schools.com/SQl/sql_create_db.asp) for pixelplanet) for storing additional data like IP blacklist
|
- mysql or mariadb ([setup own user](https://www.digitalocean.com/community/tutorials/how-to-create-a-new-user-and-grant-permissions-in-mysql) and [create database](https://www.w3schools.com/SQl/sql_create_db.asp) for pixelplanet) for storing additional data like IP blacklist
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
@ -108,7 +109,7 @@ Notes:
|
||||||
| REDDIT_CLIENT_ID | Media |
|
| REDDIT_CLIENT_ID | Media |
|
||||||
| REDDIT_CLIENT_SECRET | Accounts |
|
| REDDIT_CLIENT_SECRET | Accounts |
|
||||||
|
|
||||||
Note:
|
Notes:
|
||||||
|
|
||||||
- The HTML for SocialMedia logins is in src/componets/UserAreaModal.js , delete stuff from there if you don't need it
|
- The HTML for SocialMedia logins is in src/componets/UserAreaModal.js , delete stuff from there if you don't need it
|
||||||
- The HTML for the Help Screen is in src/components/HelpModal.js
|
- The HTML for the Help Screen is in src/components/HelpModal.js
|
||||||
|
@ -124,20 +125,28 @@ The default configuration values can be seen in `src/core/config.js` and for the
|
||||||
|
|
||||||
1. Make sure that mysql and redis are running
|
1. Make sure that mysql and redis are running
|
||||||
3. Start with
|
3. Start with
|
||||||
|
|
||||||
```
|
```
|
||||||
pm2 start ecosystem.yml
|
pm2 start ecosystem.yml
|
||||||
```
|
```
|
||||||
Note: It might be neccessary to change the charset and collate of the sql colum names of table Users to support special character names, which can be done with the SQL command:
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- pixelplanet uses the unix command sendmail for sending verification and password reset mails. If you are on windows, this might not work.
|
||||||
|
- It might be neccessary to change the charset and collate of the sql colum names of table Users to support special character names, which can be done with the SQL command:
|
||||||
```
|
```
|
||||||
ALTER TABLE Users CONVERT TO CHARACTER SET utf8mb4 COLLATE 'utf8mb4_unicode_ci';
|
ALTER TABLE Users CONVERT TO CHARACTER SET utf8mb4 COLLATE 'utf8mb4_unicode_ci';
|
||||||
```
|
```
|
||||||
|
|
||||||
### Logging
|
### Logging
|
||||||
logs are in ~/pm2/log/, you can view them with
|
logs are in ~/pm2/log/, you can view them with
|
||||||
|
|
||||||
```
|
```
|
||||||
pm2 log web
|
pm2 log web
|
||||||
```
|
```
|
||||||
|
|
||||||
you can flush the logs with
|
you can flush the logs with
|
||||||
|
|
||||||
```
|
```
|
||||||
pm2 log flush
|
pm2 log flush
|
||||||
```
|
```
|
||||||
|
|
121
package-lock.json
generated
121
package-lock.json
generated
|
@ -1543,11 +1543,6 @@
|
||||||
"integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
|
"integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"addressparser": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz",
|
|
||||||
"integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y="
|
|
||||||
},
|
|
||||||
"agent-base": {
|
"agent-base": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz",
|
||||||
|
@ -2586,36 +2581,6 @@
|
||||||
"node-gyp-build": "~3.7.0"
|
"node-gyp-build": "~3.7.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"buildmail": {
|
|
||||||
"version": "3.10.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/buildmail/-/buildmail-3.10.0.tgz",
|
|
||||||
"integrity": "sha1-xoJtcW55RbtvaxQ0tTmF4CmgMVk=",
|
|
||||||
"requires": {
|
|
||||||
"addressparser": "1.0.1",
|
|
||||||
"libbase64": "0.1.0",
|
|
||||||
"libmime": "2.1.0",
|
|
||||||
"libqp": "1.1.0",
|
|
||||||
"nodemailer-fetch": "1.6.0",
|
|
||||||
"nodemailer-shared": "1.1.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"iconv-lite": {
|
|
||||||
"version": "0.4.13",
|
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
|
|
||||||
"integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI="
|
|
||||||
},
|
|
||||||
"libmime": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/libmime/-/libmime-2.1.0.tgz",
|
|
||||||
"integrity": "sha1-Ubx23iKDFh65BRxLyArtcT5P0c0=",
|
|
||||||
"requires": {
|
|
||||||
"iconv-lite": "0.4.13",
|
|
||||||
"libbase64": "0.1.0",
|
|
||||||
"libqp": "1.1.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"builtin-modules": {
|
"builtin-modules": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
|
||||||
|
@ -3996,14 +3961,6 @@
|
||||||
"randombytes": "^2.0.0"
|
"randombytes": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dkim-signer": {
|
|
||||||
"version": "0.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/dkim-signer/-/dkim-signer-0.2.2.tgz",
|
|
||||||
"integrity": "sha1-qoHsBx7u02IngbqpIgRNeADl8wg=",
|
|
||||||
"requires": {
|
|
||||||
"libmime": "^2.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"doctrine": {
|
"doctrine": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
||||||
|
@ -7251,33 +7208,6 @@
|
||||||
"type-check": "~0.3.2"
|
"type-check": "~0.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"libbase64": {
|
|
||||||
"version": "0.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz",
|
|
||||||
"integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY="
|
|
||||||
},
|
|
||||||
"libmime": {
|
|
||||||
"version": "2.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/libmime/-/libmime-2.1.3.tgz",
|
|
||||||
"integrity": "sha1-JQF8pataHpiq2+JyUBfPHUikKgw=",
|
|
||||||
"requires": {
|
|
||||||
"iconv-lite": "0.4.15",
|
|
||||||
"libbase64": "0.1.0",
|
|
||||||
"libqp": "1.1.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"iconv-lite": {
|
|
||||||
"version": "0.4.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
|
|
||||||
"integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"libqp": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz",
|
|
||||||
"integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g="
|
|
||||||
},
|
|
||||||
"lie": {
|
"lie": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||||
|
@ -7482,32 +7412,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mailcomposer": {
|
|
||||||
"version": "3.12.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-3.12.0.tgz",
|
|
||||||
"integrity": "sha1-nF4RiKqOHGLsi4a9Q0aBArY56Pk=",
|
|
||||||
"requires": {
|
|
||||||
"buildmail": "3.10.0",
|
|
||||||
"libmime": "2.1.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"iconv-lite": {
|
|
||||||
"version": "0.4.13",
|
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
|
|
||||||
"integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI="
|
|
||||||
},
|
|
||||||
"libmime": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/libmime/-/libmime-2.1.0.tgz",
|
|
||||||
"integrity": "sha1-Ubx23iKDFh65BRxLyArtcT5P0c0=",
|
|
||||||
"requires": {
|
|
||||||
"iconv-lite": "0.4.13",
|
|
||||||
"libbase64": "0.1.0",
|
|
||||||
"libqp": "1.1.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"make-dir": {
|
"make-dir": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
|
||||||
|
@ -8201,18 +8105,10 @@
|
||||||
"true-case-path": "^1.0.2"
|
"true-case-path": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nodemailer-fetch": {
|
"nodemailer": {
|
||||||
"version": "1.6.0",
|
"version": "6.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.4.2.tgz",
|
||||||
"integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q="
|
"integrity": "sha512-g0n4nH1ONGvqYo1v72uSWvF/MRNnnq1LzmSzXb/6EPF3LFb51akOhgG3K2+aETAsJx90/Q5eFNTntu4vBCwyQQ=="
|
||||||
},
|
|
||||||
"nodemailer-shared": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz",
|
|
||||||
"integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=",
|
|
||||||
"requires": {
|
|
||||||
"nodemailer-fetch": "1.6.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"noop-logger": {
|
"noop-logger": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
|
@ -10158,15 +10054,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sendmail": {
|
|
||||||
"version": "1.6.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/sendmail/-/sendmail-1.6.1.tgz",
|
|
||||||
"integrity": "sha512-lIhvnjSi5e5jL8wA1GPP6j2QVlx6JOEfmdn0QIfmuJdmXYGmJ375kcOU0NSm/34J+nypm4sa1AXrYE5w3uNIIA==",
|
|
||||||
"requires": {
|
|
||||||
"dkim-signer": "0.2.2",
|
|
||||||
"mailcomposer": "3.12.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"seq-queue": {
|
"seq-queue": {
|
||||||
"version": "0.0.5",
|
"version": "0.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
"multer": "^1.4.1",
|
"multer": "^1.4.1",
|
||||||
"mysql2": "^2.1.0",
|
"mysql2": "^2.1.0",
|
||||||
"node-sass": "^4.11.0",
|
"node-sass": "^4.11.0",
|
||||||
|
"nodemailer": "^6.4.2",
|
||||||
"passport": "^0.4.0",
|
"passport": "^0.4.0",
|
||||||
"passport-discord": "^0.1.2",
|
"passport-discord": "^0.1.2",
|
||||||
"passport-facebook": "^3.0.0",
|
"passport-facebook": "^3.0.0",
|
||||||
|
@ -72,7 +73,6 @@
|
||||||
"redux-logger": "^3.0.6",
|
"redux-logger": "^3.0.6",
|
||||||
"redux-persist": "^6.0.0",
|
"redux-persist": "^6.0.0",
|
||||||
"redux-thunk": "^2.2.0",
|
"redux-thunk": "^2.2.0",
|
||||||
"sendmail": "^1.6.1",
|
|
||||||
"sequelize": "^5.19.2",
|
"sequelize": "^5.19.2",
|
||||||
"sharp": "^0.23.4",
|
"sharp": "^0.23.4",
|
||||||
"startaudiocontext": "^1.2.1",
|
"startaudiocontext": "^1.2.1",
|
||||||
|
|
137
src/core/mail.js
137
src/core/mail.js
|
@ -3,50 +3,66 @@
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// must use require for arguments
|
|
||||||
import Sequelize from 'sequelize';
|
import Sequelize from 'sequelize';
|
||||||
import logger from './logger';
|
import nodemailer from 'nodemailer';
|
||||||
|
|
||||||
|
import logger from './logger';
|
||||||
import { HOUR, MINUTE } from './constants';
|
import { HOUR, MINUTE } from './constants';
|
||||||
import { HOSTURL } from './config';
|
import { HOSTURL } from './config';
|
||||||
import { DailyCron, HourlyCron } from '../utils/cron';
|
import { DailyCron, HourlyCron } from '../utils/cron';
|
||||||
|
|
||||||
import RegUser from '../data/models/RegUser';
|
import RegUser from '../data/models/RegUser';
|
||||||
|
|
||||||
const sendmail = require('sendmail')({ silent: true });
|
|
||||||
|
/*
|
||||||
|
* define mail transport
|
||||||
|
* using unix command sendmail
|
||||||
|
*/
|
||||||
|
const transporter = nodemailer.createTransport({
|
||||||
|
sendmail: true,
|
||||||
|
newline: 'unix',
|
||||||
|
path: '/usr/sbin/sendmail',
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// TODO make code expire
|
// TODO make code expire
|
||||||
class MailProvider {
|
class MailProvider {
|
||||||
verify_codes: Object;
|
verifyCodes: Object;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.clear_codes = this.clear_codes.bind(this);
|
this.clearCodes = this.clearCodes.bind(this);
|
||||||
|
|
||||||
this.verify_codes = {};
|
this.verifyCodes = {};
|
||||||
HourlyCron.hook(this.clear_codes);
|
HourlyCron.hook(this.clearCodes);
|
||||||
DailyCron.hook(MailProvider.clean_users);
|
DailyCron.hook(MailProvider.cleanUsers);
|
||||||
}
|
}
|
||||||
|
|
||||||
send_verify_mail(to, name) {
|
sendVerifyMail(to, name) {
|
||||||
const past_mail = this.verify_codes[to];
|
const pastMail = this.verifyCodes[to];
|
||||||
if (past_mail) {
|
if (pastMail) {
|
||||||
const min_left = Math.floor(past_mail.timestamp / MINUTE + 15 - Date.now() / MINUTE);
|
const minLeft = Math.floor(
|
||||||
if (min_left > 0) {
|
pastMail.timestamp / MINUTE + 15 - Date.now() / MINUTE,
|
||||||
logger.info(`Verify mail for ${to} - already sent, ${min_left} minutes left`);
|
);
|
||||||
return `We already sent you a verification mail, you can request another one in ${min_left} minutes.`;
|
if (minLeft > 0) {
|
||||||
|
logger.info(
|
||||||
|
`Verify mail for ${to} - already sent, ${minLeft} minutes left`,
|
||||||
|
);
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
return `We already sent you a verification mail, you can request another one in ${minLeft} minutes.`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.info(`Sending verification mail to ${to} / ${name}`);
|
logger.info(`Sending verification mail to ${to} / ${name}`);
|
||||||
const code = this.set_code(to);
|
const code = this.setCode(to);
|
||||||
const verify_url = `${HOSTURL}/api/auth/verify?token=${code}`;
|
const verifyUrl = `${HOSTURL}/api/auth/verify?token=${code}`;
|
||||||
sendmail({
|
transporter.sendMail({
|
||||||
from: 'donotreply@pixelplanet.fun',
|
from: 'donotreply@pixelplanet.fun',
|
||||||
to,
|
to,
|
||||||
replyTo: 'donotreply@pixelplanet.fun',
|
replyTo: 'donotreply@pixelplanet.fun',
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
subject: `Welcome ${name} to PixelPlanet, plese verify your mail`,
|
subject: `Welcome ${name} to PixelPlanet, plese verify your mail`,
|
||||||
text: `Hello,\nwelcome to our little community of pixelplacers, to use your account, you have to verify your mail. You can do that here:\n ${verify_url} \nHave fun and don't hesitate to contact us if you encouter any problems :)\nThanks`,
|
// eslint-disable-next-line max-len
|
||||||
}, (err, reply) => {
|
text: `Hello,\nwelcome to our little community of pixelplacers, to use your account, you have to verify your mail. You can do that here:\n ${verifyUrl} \nHave fun and don't hesitate to contact us if you encouter any problems :)\nThanks`,
|
||||||
|
}, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error(err & err.stack);
|
logger.error(err & err.stack);
|
||||||
}
|
}
|
||||||
|
@ -54,17 +70,22 @@ class MailProvider {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async send_passd_reset_mail(to, ip) {
|
async sendPasswdResetMail(to, ip) {
|
||||||
const past_mail = this.verify_codes[to];
|
const pastMail = this.verifyCodes[to];
|
||||||
if (past_mail) {
|
if (pastMail) {
|
||||||
if (Date.now() < past_mail.timestamp + 15 * MINUTE) {
|
if (Date.now() < pastMail.timestamp + 15 * MINUTE) {
|
||||||
logger.info(`Password reset mail for ${to} requested by ${ip} - already sent`);
|
logger.info(
|
||||||
|
`Password reset mail for ${to} requested by ${ip} - already sent`,
|
||||||
|
);
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
return 'We already sent you a mail with instructions. Please wait before requesting another mail.';
|
return 'We already sent you a mail with instructions. Please wait before requesting another mail.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const reguser = await RegUser.findOne({ where: { email: to } });
|
const reguser = await RegUser.findOne({ where: { email: to } });
|
||||||
if (past_mail || !reguser) {
|
if (pastMail || !reguser) {
|
||||||
logger.info(`Password reset mail for ${to} requested by ${ip} - mail not found`);
|
logger.info(
|
||||||
|
`Password reset mail for ${to} requested by ${ip} - mail not found`,
|
||||||
|
);
|
||||||
return "Couldn't find this mail in our database";
|
return "Couldn't find this mail in our database";
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -78,15 +99,17 @@ class MailProvider {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
logger.info(`Sending Password reset mail to ${to}`);
|
logger.info(`Sending Password reset mail to ${to}`);
|
||||||
const code = this.set_code(to);
|
const code = this.setCode(to);
|
||||||
const restore_url = `${HOSTURL}/reset_password?token=${code}`;
|
const restoreUrl = `${HOSTURL}/reset_password?token=${code}`;
|
||||||
sendmail({
|
transporter.sendMail({
|
||||||
from: 'donotreply@pixelplanet.fun',
|
from: 'donotreply@pixelplanet.fun',
|
||||||
to,
|
to,
|
||||||
replyTo: 'donotreply@pixelplanet.fun',
|
replyTo: 'donotreply@pixelplanet.fun',
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
subject: 'You forgot your password for PixelPlanet? Get a new one here',
|
subject: 'You forgot your password for PixelPlanet? Get a new one here',
|
||||||
text: `Hello,\nYou requested to get a new password. You can change your password within the next 30min here:\n ${restore_url} \nHave fun and don't hesitate to contact us if you encouter any problems :)\nIf you did not request this mail, please just ignore it (the ip that requested this mail was ${ip}).\nThanks`,
|
// eslint-disable-next-line max-len
|
||||||
}, (err, reply) => {
|
text: `Hello,\nYou requested to get a new password. You can change your password within the next 30min here:\n ${restoreUrl} \nHave fun and don't hesitate to contact us if you encouter any problems :)\nIf you did not request this mail, please just ignore it (the ip that requested this mail was ${ip}).\nThanks`,
|
||||||
|
}, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error(err & err.stack);
|
logger.error(err & err.stack);
|
||||||
}
|
}
|
||||||
|
@ -94,34 +117,39 @@ class MailProvider {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_code(email) {
|
setCode(email) {
|
||||||
const code = MailProvider.create_code();
|
const code = MailProvider.createCode();
|
||||||
this.verify_codes[email] = {
|
this.verifyCodes[email] = {
|
||||||
code,
|
code,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
};
|
};
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
async clear_codes() {
|
async clearCodes() {
|
||||||
const cur_time = Date.now();
|
const curTime = Date.now();
|
||||||
const to_delete = [];
|
const toDelete = [];
|
||||||
for (const iteremail in this.verify_codes) {
|
|
||||||
if (cur_time > this.verify_codes[iteremail].timestamp + HOUR) {
|
const mails = Object.keys(this.verifyCodes);
|
||||||
to_delete.push(iteremail);
|
for (let i = 0; i < mails.length; i += 1) {
|
||||||
|
const iteremail = mails[i];
|
||||||
|
if (curTime > this.verifyCodes[iteremail].timestamp + HOUR) {
|
||||||
|
toDelete.push(iteremail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
to_delete.forEach((email) => {
|
toDelete.forEach((email) => {
|
||||||
logger.info(`Mail Code for ${email} expired`);
|
logger.info(`Mail Code for ${email} expired`);
|
||||||
delete this.verify_codes[email];
|
delete this.verifyCodes[email];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: code gets deleted on check
|
// Note: code gets deleted on check
|
||||||
check_code(code) {
|
checkCode(code) {
|
||||||
let email = null;
|
let email = null;
|
||||||
for (const iteremail in this.verify_codes) {
|
const mails = Object.keys(this.verifyCodes);
|
||||||
if (this.verify_codes[iteremail].code == code) {
|
for (let i = 0; i < mails.length; i += 1) {
|
||||||
|
const iteremail = mails[i];
|
||||||
|
if (this.verifyCodes[iteremail].code === code) {
|
||||||
email = iteremail;
|
email = iteremail;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -131,12 +159,12 @@ class MailProvider {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
logger.info(`Got Mail Code from ${email}.`);
|
logger.info(`Got Mail Code from ${email}.`);
|
||||||
delete this.verify_codes[email];
|
delete this.verifyCodes[email];
|
||||||
return email;
|
return email;
|
||||||
}
|
}
|
||||||
|
|
||||||
async verify(code) {
|
async verify(code) {
|
||||||
const email = this.check_code(code);
|
const email = this.checkCode(code);
|
||||||
if (!email) return false;
|
if (!email) return false;
|
||||||
|
|
||||||
const reguser = await RegUser.findOne({ where: { email } });
|
const reguser = await RegUser.findOne({ where: { email } });
|
||||||
|
@ -151,18 +179,21 @@ class MailProvider {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static create_code() {
|
static createCode() {
|
||||||
const part1 = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
const part1 = Math.random().toString(36).substring(2, 15)
|
||||||
const part2 = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
+ Math.random().toString(36).substring(2, 15);
|
||||||
|
const part2 = Math.random().toString(36).substring(2, 15)
|
||||||
|
+ Math.random().toString(36).substring(2, 15);
|
||||||
return `${part1}-${part2}`;
|
return `${part1}-${part2}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static clean_users() {
|
static cleanUsers() {
|
||||||
// delete users that requier verification for more than 4 days
|
// delete users that requier verification for more than 4 days
|
||||||
RegUser.destroy({
|
RegUser.destroy({
|
||||||
where: {
|
where: {
|
||||||
verificationReqAt: {
|
verificationReqAt: {
|
||||||
[Sequelize.Op.lt]: Sequelize.literal('CURRENT_TIMESTAMP - INTERVAL 4 DAY'),
|
[Sequelize.Op.lt]:
|
||||||
|
Sequelize.literal('CURRENT_TIMESTAMP - INTERVAL 4 DAY'),
|
||||||
},
|
},
|
||||||
// NOTE: this means that minecraft verified accounts do not get deleted
|
// NOTE: this means that minecraft verified accounts do not get deleted
|
||||||
verified: 0,
|
verified: 0,
|
||||||
|
|
|
@ -55,7 +55,7 @@ export default async (req: Request, res: Response) => {
|
||||||
mailVerified: false,
|
mailVerified: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
mailProvider.send_verify_mail(email, user.regUser.name);
|
mailProvider.sendVerifyMail(email, user.regUser.name);
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
|
|
|
@ -70,7 +70,7 @@ export default async (req: Request, res: Response) => {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mailProvider.send_verify_mail(email, name);
|
mailProvider.sendVerifyMail(email, name);
|
||||||
res.status(200);
|
res.status(200);
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default async (req: Request, res: Response) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const error = mailProvider.send_verify_mail(email, name);
|
const error = mailProvider.sendVerifyMail(email, name);
|
||||||
if (error) {
|
if (error) {
|
||||||
res.status(400);
|
res.status(400);
|
||||||
res.json({
|
res.json({
|
||||||
|
|
|
@ -28,7 +28,7 @@ export default async (req: Request, res: Response) => {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const error = await mailProvider.send_passd_reset_mail(email, ip);
|
const error = await mailProvider.sendPasswdResetMail(email, ip);
|
||||||
if (error) {
|
if (error) {
|
||||||
res.status(400);
|
res.status(400);
|
||||||
res.json({
|
res.json({
|
||||||
|
|
|
@ -54,7 +54,7 @@ router.post('/', async (req: Request, res: Response, next) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const email = mailProvider.check_code(code);
|
const email = mailProvider.checkCode(code);
|
||||||
if (!email) {
|
if (!email) {
|
||||||
const html = getPasswordResetHtml(null, null, "This password-reset link isn't valid anymore :(");
|
const html = getPasswordResetHtml(null, null, "This password-reset link isn't valid anymore :(");
|
||||||
res.status(401).send(html);
|
res.status(401).send(html);
|
||||||
|
@ -94,14 +94,14 @@ router.get('/', async (req: Request, res: Response, next) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const email = mailProvider.check_code(token);
|
const email = mailProvider.checkCode(token);
|
||||||
if (!email) {
|
if (!email) {
|
||||||
const html = getPasswordResetHtml(null, null, 'This passwort reset link is wrong or already expired, please request a new one (Note: you can use those links just once)');
|
const html = getPasswordResetHtml(null, null, 'This passwort reset link is wrong or already expired, please request a new one (Note: you can use those links just once)');
|
||||||
res.status(401).send(html);
|
res.status(401).send(html);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const code = mailProvider.set_code(email);
|
const code = mailProvider.setCode(email);
|
||||||
const html = getPasswordResetHtml(email, code);
|
const html = getPasswordResetHtml(email, code);
|
||||||
res.status(200).send(html);
|
res.status(200).send(html);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user