mirror of
https://gitlab.com/Alamantus/Readlebee.git
synced 2025-05-31 14:40:06 +02:00
Start adding support for email confirmation with nodemailer
This commit is contained in:
parent
7ed4148b37
commit
fd84706104
7 changed files with 63 additions and 16 deletions
|
@ -37,6 +37,7 @@
|
||||||
"fastify-cookie": "^3.1.0",
|
"fastify-cookie": "^3.1.0",
|
||||||
"fastify-helmet": "^3.0.1",
|
"fastify-helmet": "^3.0.1",
|
||||||
"fastify-jwt": "^1.0.0",
|
"fastify-jwt": "^1.0.0",
|
||||||
|
"fastify-nodemailer": "^4.1.1",
|
||||||
"fastify-sequelize": "^1.0.4",
|
"fastify-sequelize": "^1.0.4",
|
||||||
"fastify-static": "^2.5.0",
|
"fastify-static": "^2.5.0",
|
||||||
"make-promises-safe": "^5.0.0",
|
"make-promises-safe": "^5.0.0",
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
"db_database": "readlebee",
|
"db_database": "readlebee",
|
||||||
"db_username": "postgres",
|
"db_username": "postgres",
|
||||||
"db_password": "password",
|
"db_password": "password",
|
||||||
|
"email_host": null,
|
||||||
|
"email_port": 465,
|
||||||
|
"email_username": null,
|
||||||
|
"email_password": "password",
|
||||||
"jwtSecretKey": "SomethingAtLeast32CharactersLong!",
|
"jwtSecretKey": "SomethingAtLeast32CharactersLong!",
|
||||||
"tokenExpireDays": 7,
|
"tokenExpireDays": 7,
|
||||||
"inventaireDomain": "https://inventaire.io"
|
"inventaireDomain": "https://inventaire.io"
|
||||||
|
|
|
@ -97,7 +97,7 @@ class Account {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async createUser (email, username, displayName, password) {
|
async createUser (email, username, displayName, password, needsConfirmation) {
|
||||||
const hashData = Account.hashPassword(password);
|
const hashData = Account.hashPassword(password);
|
||||||
// The data should already have gone through Account.cleanCreateAccountFormData()
|
// The data should already have gone through Account.cleanCreateAccountFormData()
|
||||||
return await this.model.create({
|
return await this.model.create({
|
||||||
|
@ -106,6 +106,7 @@ class Account {
|
||||||
displayName,
|
displayName,
|
||||||
passwordHash: hashData.hash,
|
passwordHash: hashData.hash,
|
||||||
passwordSalt: hashData.salt,
|
passwordSalt: hashData.salt,
|
||||||
|
accountConfirm: needsConfirmation ? crypto.randomBytes(32).toString('hex') : null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,10 @@ function getSequelizeModels (sequelize) {
|
||||||
type: Sequelize.STRING,
|
type: Sequelize.STRING,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
},
|
},
|
||||||
|
accountConfirm: {
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
|
||||||
// Timestamps
|
// Timestamps
|
||||||
createdAt: {
|
createdAt: {
|
||||||
|
|
|
@ -47,6 +47,21 @@ switch (fastify.siteConfig.db_engine) {
|
||||||
}
|
}
|
||||||
fastify.register(require('fastify-sequelize'), sequelizeConfig);
|
fastify.register(require('fastify-sequelize'), sequelizeConfig);
|
||||||
|
|
||||||
|
if (!fastify.siteConfig.email_host || !fastify.siteConfig.email_username) {
|
||||||
|
console.warn('###\nNo email server set up. You will not be able to send emails without entering your email configuration.\n###');
|
||||||
|
} else {
|
||||||
|
fastify.register(require('fastify-nodemailer'), {
|
||||||
|
pool: true,
|
||||||
|
host: fastify.siteConfig.email_host,
|
||||||
|
port: fastify.siteConfig.email_port,
|
||||||
|
secure: true, // use TLS
|
||||||
|
auth: {
|
||||||
|
user: fastify.siteConfig.email_username,
|
||||||
|
pass: fastify.siteConfig.email_password,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Every request, check to see if a valid token exists
|
// Every request, check to see if a valid token exists
|
||||||
fastify.addHook('onRequest', async (request, reply) => {
|
fastify.addHook('onRequest', async (request, reply) => {
|
||||||
request.isLoggedInUser = false;
|
request.isLoggedInUser = false;
|
||||||
|
@ -83,5 +98,6 @@ fastify.listen(fastify.siteConfig.port, function (err, address) {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fastify.decorate('canEmail', typeof fastify.nodemailer !== 'undefined');
|
||||||
fastify.decorate('models', require('./getSequelizeModels')(fastify.sequelize));
|
fastify.decorate('models', require('./getSequelizeModels')(fastify.sequelize));
|
||||||
});
|
});
|
|
@ -27,27 +27,35 @@ async function routes(fastify, options) {
|
||||||
return reply.code(400).send(canCreateUser);
|
return reply.code(400).send(canCreateUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await account.createUser(formData.email, formData.username, formData.displayName, formData.password);
|
const result = await account.createUser(formData.email, formData.username, formData.displayName, formData.password, fastify.canEmail);
|
||||||
|
|
||||||
if (typeof result.error !== 'undefined') {
|
if (typeof result.error !== 'undefined') {
|
||||||
return reply.code(400).send(result);
|
return reply.code(400).send(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = fastify.jwt.sign({ id: result.id });
|
if (fastify.canEmail) {
|
||||||
const expireTime = fastify.siteConfig.tokenExpireDays * (24 * 60 * 60e3); // The section in parentheses is milliseconds in a day
|
// fastify.nodemailer.sendMail();
|
||||||
|
return reply.send({
|
||||||
|
error: false,
|
||||||
|
message: 'api.account_create_success',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const token = fastify.jwt.sign({ id: result.id });
|
||||||
|
const expireTime = fastify.siteConfig.tokenExpireDays * (24 * 60 * 60e3); // The section in parentheses is milliseconds in a day
|
||||||
|
|
||||||
return reply
|
return reply
|
||||||
.setCookie('token', token, {
|
.setCookie('token', token, {
|
||||||
path: '/',
|
path: '/',
|
||||||
expires: new Date(Date.now() + expireTime),
|
expires: new Date(Date.now() + expireTime),
|
||||||
maxAge: new Date(Date.now() + expireTime), // Both are set as a "just in case"
|
maxAge: new Date(Date.now() + expireTime), // Both are set as a "just in case"
|
||||||
httpOnly: true, // Prevents JavaScript on the front end from grabbing it
|
httpOnly: true, // Prevents JavaScript on the front end from grabbing it
|
||||||
sameSite: true, // Prevents the cookie from being used outside of this site
|
sameSite: true, // Prevents the cookie from being used outside of this site
|
||||||
})
|
})
|
||||||
.send({
|
.send({
|
||||||
error: false,
|
error: false,
|
||||||
message: 'api.account_create_success',
|
message: 'api.account_create_success',
|
||||||
});
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
fastify.get('/api/login', async (request, reply) => {
|
fastify.get('/api/login', async (request, reply) => {
|
||||||
|
|
13
yarn.lock
13
yarn.lock
|
@ -2786,6 +2786,14 @@ fastify-jwt@^1.0.0:
|
||||||
jsonwebtoken "^8.3.0"
|
jsonwebtoken "^8.3.0"
|
||||||
steed "^1.1.3"
|
steed "^1.1.3"
|
||||||
|
|
||||||
|
fastify-nodemailer@^4.1.1:
|
||||||
|
version "4.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/fastify-nodemailer/-/fastify-nodemailer-4.1.1.tgz#8bb1bffc17546044a12f2531ca63eabf15b6ef6b"
|
||||||
|
integrity sha512-VTsV5mERoXgjCbEMYnYTd0j9FDFpZ6cpHzjJ7+L9UiruC3obudkguZysaZhhlLOcmBCiIdJqQu1xh6hbPfV2mA==
|
||||||
|
dependencies:
|
||||||
|
fastify-plugin "^1.6.0"
|
||||||
|
nodemailer "^6.0.0"
|
||||||
|
|
||||||
fastify-plugin@^0.1.1:
|
fastify-plugin@^0.1.1:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/fastify-plugin/-/fastify-plugin-0.1.1.tgz#13a94f495a90fd5a7ae4bcd827c54ea5986c794f"
|
resolved "https://registry.yarnpkg.com/fastify-plugin/-/fastify-plugin-0.1.1.tgz#13a94f495a90fd5a7ae4bcd827c54ea5986c794f"
|
||||||
|
@ -4662,6 +4670,11 @@ node-releases@^1.1.29:
|
||||||
dependencies:
|
dependencies:
|
||||||
semver "^5.3.0"
|
semver "^5.3.0"
|
||||||
|
|
||||||
|
nodemailer@^6.0.0:
|
||||||
|
version "6.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.3.0.tgz#a89b0c62d3937bdcdeecbf55687bd7911b627e12"
|
||||||
|
integrity sha512-TEHBNBPHv7Ie/0o3HXnb7xrPSSQmH1dXwQKRaMKDBGt/ZN54lvDVujP6hKkO/vjkIYL9rK8kHSG11+G42Nhxuw==
|
||||||
|
|
||||||
noop-logger@^0.1.1:
|
noop-logger@^0.1.1:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2"
|
resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2"
|
||||||
|
|
Loading…
Add table
Reference in a new issue