Files
adastra_api/src/routes/api/skydive/applications.routes.js
T
julien b3a31e4725 feat(auth): migrate Application model from MongoDB to MySQL
- 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
2026-04-26 18:26:58 +02:00

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;