✨ API: ShortLinks - GET/POST/PUT/DELETE
This commit is contained in:
parent
fbfd8899e9
commit
eba7858caf
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
191
api/controllers/links_shortener.js
Normal file
191
api/controllers/links_shortener.js
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
23
api/routes/links_shortener.js
Normal file
23
api/routes/links_shortener.js
Normal 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
|
Reference in New Issue
Block a user