diff --git a/api/app.js b/api/app.js
index 6ab858f..5b78647 100644
--- a/api/app.js
+++ b/api/app.js
@@ -37,12 +37,12 @@ app.use((error, _req, res, _next) => {
});
/* Database Relations */
-const Functions = require('./models/functions');
-const Categories = require('./models/categories');
-const Users = require('./models/users');
-const Favorites = require('./models/favorites');
-const Comments = require('./models/comments');
-const Quotes = require('./models/quotes');
+const Functions = require('./models/functions');
+const Categories = require('./models/categories');
+const Users = require('./models/users');
+const Favorites = require('./models/favorites');
+const Comments = require('./models/comments');
+const Quotes = require('./models/quotes');
// A function has a category
Categories.hasOne(Functions, { constraints: true, onDelete: 'CASCADE'});
diff --git a/api/assets/functions/functionObject.js b/api/assets/functions/functionObject.js
index ba8ebe6..db4416c 100644
--- a/api/assets/functions/functionObject.js
+++ b/api/assets/functions/functionObject.js
@@ -9,6 +9,7 @@ const calculateAgeOutput = require('./main/calculateAge');
const heapAlgorithmOutput = require('./main/heapAlgorithm');
const convertEncodingOutput = require('./main/convertEncoding');
const randomQuote = require('./main/randomQuote');
+const linkShortener = require('./main/linkShortener');
const functionObject = {
randomNumber : randomNumberOutput,
@@ -22,6 +23,7 @@ const functionObject = {
heapAlgorithm : heapAlgorithmOutput,
convertEncoding : convertEncodingOutput,
randomQuote : randomQuote,
+ linkShortener : linkShortener,
};
// Choisi la fonction à exécuter
diff --git a/api/assets/functions/main/linkShortener.js b/api/assets/functions/main/linkShortener.js
new file mode 100644
index 0000000..8bdc058
--- /dev/null
+++ b/api/assets/functions/main/linkShortener.js
@@ -0,0 +1,52 @@
+const validator = require('validator');
+const errorHandling = require('../../utils/errorHandling');
+const { requiredFields, serverError } = require('../../config/errors');
+const Short_links = require('../../../models/short_links');
+
+module.exports = linkShortener = 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 Short_links.findOne({ where: { url } });
+ if (urlInDatabase) {
+ const urlShort = `https://short-links.divlo.fr/?q=${urlInDatabase.shortcut}`;
+ return errorHandling(next, { message: `L'url a déjà été raccourcie...
${urlShort}`, statusCode: 400 });
+ }
+
+ // Si le nom du raccourci existe déjà
+ const shortcutInDatabase = await Short_links.findOne({ where: { shortcut: shortcutName } });
+ if (shortcutInDatabase) {
+ const urlShort = `https://short-links.divlo.fr/?q=${shortcutInDatabase.shortcut}`;
+ return errorHandling(next, { message: `Le nom du raccourci a déjà été utilisé...
${urlShort}`, statusCode: 400 });
+ }
+
+ // Ajout du lien raccourci
+ const result = await Short_links.create({ url, shortcut: shortcutName });
+ const shortcutLinkResult = `https://short-links.divlo.fr/?q=${result.shortcut}`;
+ return res.status(200).json({ resultHTML: `URL Raccourcie :
${shortcutLinkResult}`, result: shortcutLinkResult });
+ } catch {
+ console.log(error);
+ return errorHandling(next, serverError);
+ }
+}
\ No newline at end of file
diff --git a/api/models/short_links.js b/api/models/short_links.js
new file mode 100644
index 0000000..1ce431c
--- /dev/null
+++ b/api/models/short_links.js
@@ -0,0 +1,19 @@
+const Sequelize = require('sequelize');
+const sequelize = require('../assets/utils/database');
+
+module.exports = sequelize.define('short_link', {
+ id: {
+ type: Sequelize.INTEGER,
+ allowNull: false,
+ autoIncrement: true,
+ primaryKey: true
+ },
+ url: {
+ type: Sequelize.TEXT,
+ allowNull: false,
+ },
+ shortcut: {
+ type: Sequelize.TEXT,
+ allowNull: false,
+ }
+});
\ No newline at end of file
diff --git a/api/package-lock.json b/api/package-lock.json
index 9e1a4a7..e6dbf9f 100644
--- a/api/package-lock.json
+++ b/api/package-lock.json
@@ -1545,6 +1545,11 @@
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
+ },
+ "validator": {
+ "version": "10.11.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz",
+ "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw=="
}
}
},
@@ -1798,9 +1803,9 @@
"integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw=="
},
"validator": {
- "version": "10.11.0",
- "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz",
- "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw=="
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.0.0.tgz",
+ "integrity": "sha512-anYx5fURbgF04lQV18nEQWZ/3wHGnxiKdG4aL8J+jEDsm98n/sU/bey+tYk6tnGJzm7ioh5FoqrAiQ6m03IgaA=="
},
"vary": {
"version": "1.1.2",
diff --git a/api/package.json b/api/package.json
index 52cedb5..3e81f8e 100644
--- a/api/package.json
+++ b/api/package.json
@@ -25,7 +25,8 @@
"nodemailer": "^6.4.6",
"sequelize": "^5.21.5",
"smart-request-balancer": "^2.1.1",
- "uuid": "^7.0.2"
+ "uuid": "^7.0.2",
+ "validator": "^13.0.0"
},
"devDependencies": {
"dotenv": "^8.2.0",