API: ShortLinks - GET/POST/PUT/DELETE

This commit is contained in:
divlo 2020-08-03 18:39:35 +02:00
parent fbfd8899e9
commit eba7858caf
5 changed files with 220 additions and 74 deletions

View File

@ -32,6 +32,7 @@ app.use('/favorites', require('./routes/favorites'))
app.use('/comments', require('./routes/comments')) app.use('/comments', require('./routes/comments'))
app.use('/quotes', require('./routes/quotes')) app.use('/quotes', require('./routes/quotes'))
app.use('/tasks', require('./routes/tasks')) app.use('/tasks', require('./routes/tasks'))
app.use('/links', require('./routes/links_shortener'))
/* Errors Handling */ /* Errors Handling */
app.use((_req, _res, next) => app.use((_req, _res, next) =>
@ -51,6 +52,7 @@ const Favorites = require('./models/favorites')
const Comments = require('./models/comments') const Comments = require('./models/comments')
const Quotes = require('./models/quotes') const Quotes = require('./models/quotes')
const Tasks = require('./models/tasks') const Tasks = require('./models/tasks')
const ShortLinks = require('./models/short_links')
// A function has a category // A function has a category
Categories.hasOne(Functions, { constraints: true, onDelete: 'CASCADE' }) Categories.hasOne(Functions, { constraints: true, onDelete: 'CASCADE' })
@ -76,6 +78,10 @@ Quotes.belongsTo(Users, { constraints: false })
Users.hasMany(Tasks) Users.hasMany(Tasks)
Tasks.belongsTo(Users, { constraints: false }) Tasks.belongsTo(Users, { constraints: false })
// Users can have links
Users.hasMany(ShortLinks)
ShortLinks.belongsTo(Users, { constraints: false })
/* Server */ /* Server */
// sequelize.sync({ force: true }) // sequelize.sync({ force: true })
sequelize sequelize

View File

@ -9,7 +9,6 @@ const calculateAgeOutput = require('./main/calculateAge')
const heapAlgorithmOutput = require('./main/heapAlgorithm') const heapAlgorithmOutput = require('./main/heapAlgorithm')
const convertEncodingOutput = require('./main/convertEncoding') const convertEncodingOutput = require('./main/convertEncoding')
const randomQuote = require('./main/randomQuote') const randomQuote = require('./main/randomQuote')
const linkShortener = require('./main/linkShortener')
const rightPriceOutput = require('./main/rightPrice') const rightPriceOutput = require('./main/rightPrice')
const isPalindromeOutput = require('./main/isPalindrome') const isPalindromeOutput = require('./main/isPalindrome')
const findLongestWordOutput = require('./main/findLongestWord') const findLongestWordOutput = require('./main/findLongestWord')
@ -28,7 +27,6 @@ const functionObject = {
heapAlgorithm: heapAlgorithmOutput, heapAlgorithm: heapAlgorithmOutput,
convertEncoding: convertEncodingOutput, convertEncoding: convertEncodingOutput,
randomQuote: randomQuote, randomQuote: randomQuote,
linkShortener: linkShortener,
rightPrice: rightPriceOutput, rightPrice: rightPriceOutput,
isPalindrome: isPalindromeOutput, isPalindrome: isPalindromeOutput,
findLongestWord: findLongestWordOutput, findLongestWord: findLongestWordOutput,

View File

@ -1,72 +0,0 @@
const validator = require('validator')
const errorHandling = require('../../utils/errorHandling')
const { requiredFields, serverError } = require('../../config/errors')
const shortLinks = require('../../../models/short_links')
const shortLinkBaseURL = 'https://s.divlo.fr'
module.exports = async ({ res, next }, argsObject) => {
let { url, shortcutName } = argsObject
// S'il n'y a pas les champs obligatoire
if (!(url && shortcutName)) {
return errorHandling(next, requiredFields)
}
// Si ce n'est pas une url
if (!validator.isURL(url)) {
return errorHandling(next, {
message: 'Veuillez entré une URL valide.',
statusCode: 400
})
}
// Si ce n'est pas de type slug
if (!validator.isSlug(shortcutName)) {
return errorHandling(next, {
message:
"Le nom de votre raccourci doit être de type slug (ne pas contenir d'espaces, ni de caractères spéciaux).",
statusCode: 400
})
}
// Sanitize shortcutName
shortcutName = validator.escape(shortcutName)
shortcutName = validator.trim(shortcutName)
shortcutName = validator.blacklist(shortcutName, ' ')
try {
// Si l'url a déjà été raccourcie
const urlInDatabase = await shortLinks.findOne({ where: { url } })
if (urlInDatabase) {
const urlShort = `${shortLinkBaseURL}/${urlInDatabase.shortcut}`
return errorHandling(next, {
message: `L'url a déjà été raccourcie... <br/> <br/> <a target="_blank" rel="noopener noreferrer" href="${urlShort}">${urlShort}</a>`,
statusCode: 400
})
}
// Si le nom du raccourci existe déjà
const shortcutInDatabase = await shortLinks.findOne({
where: { shortcut: shortcutName }
})
if (shortcutInDatabase) {
const urlShort = `${shortLinkBaseURL}/${shortcutInDatabase.shortcut}`
return errorHandling(next, {
message: `Le nom du raccourci a déjà été utilisé... <br/> <br/> <a target="_blank" rel="noopener noreferrer" href="${urlShort}">${urlShort}</a>`,
statusCode: 400
})
}
// Ajout du lien raccourci
const result = await shortLinks.create({ url, shortcut: shortcutName })
const shortcutLinkResult = `${shortLinkBaseURL}/${result.shortcut}`
return res.status(200).json({
resultHTML: `URL Raccourcie : <br/> <br/> <a target="_blank" rel="noopener noreferrer" href="${shortcutLinkResult}">${shortcutLinkResult}</a>`,
result: shortcutLinkResult
})
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
}
}

View File

@ -0,0 +1,191 @@
const validator = require('validator')
const errorHandling = require('../assets/utils/errorHandling')
const { requiredFields, serverError } = require('../assets/config/errors')
const ShortLinks = require('../models/short_links')
const getPagesHelper = require('../assets/utils/getPagesHelper')
const Sequelize = require('sequelize')
const shortLinkBaseURL = 'https://s.divlo.fr'
exports.getLinks = async (req, res, next) => {
const { userId } = req
const options = {
where: { userId },
order: [['createdAt', 'DESC']]
}
return await getPagesHelper({ req, res, next }, ShortLinks, options)
}
exports.postLink = async (req, res, next) => {
const { userId } = req
let { url, shortcutName } = req.body
// S'il n'y a pas les champs obligatoire
if (!(url && shortcutName)) {
return errorHandling(next, requiredFields)
}
// Si ce n'est pas une url
if (!validator.isURL(url)) {
return errorHandling(next, {
message: 'Veuillez entré une URL valide.',
statusCode: 400
})
}
// Si ce n'est pas de type slug
if (!validator.isSlug(shortcutName)) {
return errorHandling(next, {
message:
"Le nom de votre raccourci doit être de type slug (ne pas contenir d'espaces, ni de caractères spéciaux).",
statusCode: 400
})
}
// Sanitize shortcutName
shortcutName = validator.escape(shortcutName)
shortcutName = validator.trim(shortcutName)
shortcutName = validator.blacklist(shortcutName, ' ')
try {
// Si l'url a déjà été raccourcie
const urlInDatabase = await ShortLinks.findOne({ where: { url } })
if (urlInDatabase) {
const urlShort = `${shortLinkBaseURL}/${urlInDatabase.shortcut}`
return errorHandling(next, {
message: `L'url a déjà été raccourcie... <br/> <br/> <a target="_blank" rel="noopener noreferrer" href="${urlShort}">${urlShort}</a>`,
statusCode: 400
})
}
// Si le nom du raccourci existe déjà
const shortcutInDatabase = await ShortLinks.findOne({
where: { shortcut: shortcutName }
})
if (shortcutInDatabase) {
const urlShort = `${shortLinkBaseURL}/${shortcutInDatabase.shortcut}`
return errorHandling(next, {
message: `Le nom du raccourci a déjà été utilisé... <br/> <br/> <a target="_blank" rel="noopener noreferrer" href="${urlShort}">${urlShort}</a>`,
statusCode: 400
})
}
// Ajout du lien raccourci
const result = await ShortLinks.create({
url,
shortcut: shortcutName,
userId
})
const shortcutLinkResult = `${shortLinkBaseURL}/${result.shortcut}`
return res.status(200).json({
resultHTML: `URL Raccourcie : <br/> <br/> <a target="_blank" rel="noopener noreferrer" href="${shortcutLinkResult}">${shortcutLinkResult}</a>`,
result: shortcutLinkResult
})
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
}
}
exports.putLink = async (req, res, next) => {
const { id } = req.params
const { userId } = req
let { url, shortcutName } = req.body
// S'il n'y a pas les champs obligatoire
if (!(url && shortcutName)) {
return errorHandling(next, requiredFields)
}
// Si ce n'est pas une url
if (!validator.isURL(url)) {
return errorHandling(next, {
message: 'Veuillez entré une URL valide.',
statusCode: 400
})
}
// Si ce n'est pas de type slug
if (!validator.isSlug(shortcutName)) {
return errorHandling(next, {
message:
"Le nom de votre raccourci doit être de type slug (ne pas contenir d'espaces, ni de caractères spéciaux).",
statusCode: 400
})
}
// Sanitize shortcutName
shortcutName = validator.escape(shortcutName)
shortcutName = validator.trim(shortcutName)
shortcutName = validator.blacklist(shortcutName, ' ')
try {
// Si l'url a déjà été raccourcie par quelqu'un d'autre
const urlInDatabase = await ShortLinks.findOne({
where: { url, [Sequelize.Op.not]: { userId } }
})
if (urlInDatabase) {
const urlShort = `${shortLinkBaseURL}/${urlInDatabase.shortcut}`
return errorHandling(next, {
message: `L'url a déjà été raccourcie... <br/> <br/> <a target="_blank" rel="noopener noreferrer" href="${urlShort}">${urlShort}</a>`,
statusCode: 400
})
}
// Si le nom du raccourci existe déjà par quelqu'un d'autre
const shortcutInDatabase = await ShortLinks.findOne({
where: { shortcut: shortcutName, [Sequelize.Op.not]: { userId } }
})
if (shortcutInDatabase) {
const urlShort = `${shortLinkBaseURL}/${shortcutInDatabase.shortcut}`
return errorHandling(next, {
message: `Le nom du raccourci a déjà été utilisé... <br/> <br/> <a target="_blank" rel="noopener noreferrer" href="${urlShort}">${urlShort}</a>`,
statusCode: 400
})
}
// Modification du lien raccourci
const result = await ShortLinks.findOne({
where: { id, userId }
})
console.log(result)
if (!result) {
return errorHandling(next, {
statusCode: 404,
message: "Le raccourci n'existe pas..."
})
}
result.url = url
result.shortcut = shortcutName
const { shortcut } = await result.save()
const shortcutLinkResult = `${shortLinkBaseURL}/${shortcut}`
return res.status(200).json({
resultHTML: `URL Raccourcie : <br/> <br/> <a target="_blank" rel="noopener noreferrer" href="${shortcutLinkResult}">${shortcutLinkResult}</a>`,
result: shortcutLinkResult
})
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
}
}
exports.deleteLink = async (req, res, next) => {
const { id } = req.params
const { userId } = req
try {
const linkResult = await ShortLinks.findOne({
where: { id, userId }
})
if (!linkResult) {
return errorHandling(next, {
message: "Le lien raccourci n'existe pas.",
statusCode: 404
})
}
await linkResult.destroy()
return res.status(200).json({ message: 'La lien a bien été supprimé!' })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
}
}

View File

@ -0,0 +1,23 @@
const { Router } = require('express')
const linksShortenerController = require('../controllers/links_shortener')
const isAuth = require('../middlewares/isAuth')
const LinksShortenerRouter = Router()
LinksShortenerRouter.route('/')
// Récupère les liens d'un utilisateur
.get(isAuth, linksShortenerController.getLinks)
// Ajouter un lien à raccourcir d'un utilisateur
.post(isAuth, linksShortenerController.postLink)
LinksShortenerRouter.route('/:id')
// Permet de modifier le lien raccourci d'un utilisateur
.put(isAuth, linksShortenerController.putLink)
// Supprimer un lien d'un utilisateur
.delete(isAuth, linksShortenerController.deleteLink)
module.exports = LinksShortenerRouter