b3a31e4725
- Add Sequelize migration creating the 'application' table
- Add Application Sequelize model with slugify, toJSONFor, toAuthJSON
- Rewrite passport-headerapikey strategy to use DB.Application
- Rewrite applications.routes.js to use Sequelize (findAll, count,
build/save, destroy) instead of Mongoose
- Fix pre-existing bug: passport was querying { encryptedKey } but the
stored field is named 'apikey'
- Add Application to MySQL models index and relationships
- Remove Application from Mongoose models index and delete the schema
141 lines
5.1 KiB
JavaScript
141 lines
5.1 KiB
JavaScript
var router = require('express').Router();
|
|
const { Op } = require('sequelize');
|
|
const DB = require('../../../database/mysql');
|
|
const auth = require('../../../middlewares/auth');
|
|
const mailer = require('@sendgrid/mail');
|
|
const { UserService } = require('../../../services');
|
|
|
|
mailer.setApiKey(process.env.SENDGRID_API_KEY);
|
|
|
|
// Preload application objects on routes with ':application'
|
|
router.param('application', function (req, res, next, slug) {
|
|
DB.Application.findOne({ where: { slug } })
|
|
.then(function (application) {
|
|
if (!application) {
|
|
return res.sendStatus(404);
|
|
}
|
|
req.application = application;
|
|
return next();
|
|
}).catch(next);
|
|
});
|
|
|
|
/**
|
|
* return all applications
|
|
*/
|
|
router.get('/', auth.required, function (req, res, next) {
|
|
const limit = parseInt(req.query.limit) || 25;
|
|
const offset = parseInt(req.query.offset) || 0;
|
|
const where = {};
|
|
|
|
if (req.query.apikey) where.apikey = req.query.apikey;
|
|
if (req.query.maskedkey) where.maskedkey = req.query.maskedkey;
|
|
|
|
Promise.all([
|
|
req.query.author ? UserService.getUserByUsername(req.query.author) : null,
|
|
req.payload ? UserService.getUserById(req.payload.id) : null
|
|
]).then(function ([author, user]) {
|
|
if (author) where.authorId = author.id;
|
|
|
|
return Promise.all([
|
|
DB.Application.findAll({ where, limit, offset, order: [['createdAt', 'DESC']] }),
|
|
DB.Application.count({ where })
|
|
]).then(function ([applications, applicationsCount]) {
|
|
return res.json({
|
|
applications: applications.map((a) => a.toJSONFor(user)),
|
|
applicationsCount
|
|
});
|
|
});
|
|
}).catch(next);
|
|
});
|
|
|
|
/**
|
|
* save an application
|
|
*/
|
|
router.post('/', auth.required, function (req, res, next) {
|
|
Promise.all([
|
|
UserService.getUserById(req.payload.id),
|
|
auth.generateAPIKey()
|
|
]).then(function ([user, keys]) {
|
|
if (!user) {
|
|
return res.status(401).json({ message: 'Unauthorized - You are not allowed to access this resource.' });
|
|
}
|
|
|
|
const application = DB.Application.build(req.body.application);
|
|
application.authorId = user.id;
|
|
application.apikey = keys.encrypted;
|
|
application.maskedkey = keys.masked;
|
|
|
|
return application.save().then(function () {
|
|
const msg = {
|
|
to: user.email,
|
|
from: process.env.SENDGRID_FROM_MAIL,
|
|
subject: `Api-Key ${application.title}`,
|
|
text: `Votre Api-Key: ${keys.key}\nAttention, cette Api-Key doit être conservée et ne sera plus affichée.\n\n${application.title}\n${application.description}`,
|
|
html: `<h2>${application.title}</h2>
|
|
<p>
|
|
Votre Api-Key: ${keys.key}<br />
|
|
<strong>Attention, cette Api-Key doit être conservée et ne sera plus affichée.</strong>
|
|
</p>
|
|
<hr />
|
|
<p>${application.description}</p>`
|
|
};
|
|
return mailer.send(msg).then(() => {
|
|
return res.json({ application: application.toJSONFor(user) });
|
|
}).catch(err => {
|
|
return res.status(500).json({ message: 'A SendGrid error occured while sending an email', err });
|
|
});
|
|
});
|
|
}).catch(next);
|
|
});
|
|
|
|
/**
|
|
* return an application
|
|
*/
|
|
router.get('/:application', auth.required, function (req, res, next) {
|
|
Promise.resolve(req.payload ? UserService.getUserById(req.payload.id) : null)
|
|
.then(function (user) {
|
|
return res.json({ application: req.application.toJSONFor(user) });
|
|
}).catch(next);
|
|
});
|
|
|
|
/**
|
|
* update an application
|
|
*/
|
|
router.put('/:application', auth.required, function (req, res, next) {
|
|
UserService.getUserById(req.payload.id).then(function (user) {
|
|
if (req.application.authorId !== req.payload.id) {
|
|
return res.status(403).json({ errors: { Forbidden: 'Vous ne disposez pas des autorisations suffisantes' } });
|
|
}
|
|
|
|
const fields = ['title', 'description', 'apikey', 'maskedkey'];
|
|
fields.forEach((f) => {
|
|
if (typeof req.body.application[f] !== 'undefined') {
|
|
req.application[f] = req.body.application[f];
|
|
}
|
|
});
|
|
|
|
return req.application.save().then(function (application) {
|
|
return res.json({ application: application.toJSONFor(user) });
|
|
}).catch(next);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* delete an application
|
|
*/
|
|
router.delete('/:application', auth.required, function (req, res, next) {
|
|
UserService.getUserById(req.payload.id).then(function (user) {
|
|
if (!user) {
|
|
return res.status(401).json({ errors: { Unauthorized: 'authentification requise' } });
|
|
}
|
|
if (user.role !== 'Admin' && req.application.authorId !== req.payload.id) {
|
|
return res.status(403).json({ errors: { Forbidden: 'Vous ne disposez pas des autorisations suffisantes' } });
|
|
}
|
|
return req.application.destroy().then(function () {
|
|
return res.json({ deleted: true });
|
|
});
|
|
}).catch(next);
|
|
});
|
|
|
|
module.exports = router;
|