From b68dd4c800e10c507ecf7424c784bf5d6b8807a3 Mon Sep 17 00:00:00 2001 From: Rampeur Date: Sun, 10 Aug 2025 09:15:18 +0200 Subject: [PATCH] =?UTF-8?q?Mise=20=C3=A0=20jour=20de=20routes=20et=20model?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 2 +- .env.development | 2 +- .env.local | 2 +- .env.production | 2 +- controllers/profiles.js | 102 ++--- controllers/users.js | 112 +++--- models copy/Article.js | 27 -- models copy/Comment.js | 11 - models copy/Tag.js | 16 - models copy/User.js | 58 --- models/Article.js | 74 ++-- models/Comment.js | 54 ++- models/Tag.js | 51 +-- models/User.js | 125 +++--- models/mysql/Article.js | 20 +- models/mysql/Comment.js | 8 +- models/mysql/Tag.js | 5 +- models/mysql/User.js | 43 +-- nodemon.json | 2 +- package-lock.json | 827 +++++++++++++++++++++++++++++++++++++++- package.json | 5 +- routes/articles.js | 30 -- routes/comments.js | 23 -- routes/profiles.js | 16 - routes/tags.js | 10 - routes/users.js | 16 - server.js | 183 +++++---- util/jwt.js | 2 +- 28 files changed, 1211 insertions(+), 617 deletions(-) delete mode 100644 models copy/Article.js delete mode 100644 models copy/Comment.js delete mode 100644 models copy/Tag.js delete mode 100644 models copy/User.js delete mode 100644 routes/articles.js delete mode 100644 routes/comments.js delete mode 100644 routes/profiles.js delete mode 100644 routes/tags.js delete mode 100644 routes/users.js diff --git a/.env b/.env index 948fdc4..13bd70f 100644 --- a/.env +++ b/.env @@ -2,7 +2,7 @@ APP_ENV="development" NODE_ENV="development" DEBUG=false SERVER_PORT="3200" -SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO" +JWT_SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO" SESSION_LIFETIME="3600" SENDGRID_API_KEY="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" SENDGRID_FROM_MAIL="contact@rampeur.fr" diff --git a/.env.development b/.env.development index cebbad5..5f06c34 100644 --- a/.env.development +++ b/.env.development @@ -2,7 +2,7 @@ APP_ENV="development" NODE_ENV="development" DEBUG=false SERVER_PORT="3200" -SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO" +JWT_SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO" SESSION_LIFETIME=3600 SENDGRID_API_KEY="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" SENDGRID_FROM_MAIL="contact@rampeur.fr" diff --git a/.env.local b/.env.local index 791da64..97f7d4c 100644 --- a/.env.local +++ b/.env.local @@ -2,7 +2,7 @@ APP_ENV="local" NODE_ENV="development" DEBUG=false SERVER_PORT="3200" -SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO" +JWT_SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO" SESSION_LIFETIME=3600 SENDGRID_API_KEY="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" SENDGRID_FROM_MAIL="contact@rampeur.fr" diff --git a/.env.production b/.env.production index aaca62e..1816212 100644 --- a/.env.production +++ b/.env.production @@ -2,7 +2,7 @@ APP_ENV="production" NODE_ENV="production" DEBUG=false SERVER_PORT="3200" -SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO" +JWT_SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO" SESSION_LIFETIME=3600 SENDGRID_API_KEY="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" SENDGRID_FROM_MAIL="contact@rampeur.fr" diff --git a/controllers/profiles.js b/controllers/profiles.js index 8c21a04..76dd81c 100644 --- a/controllers/profiles.js +++ b/controllers/profiles.js @@ -3,72 +3,78 @@ const asyncHandler = require("../middlewares/asyncHandler"); const ErrorResponse = require("../util/errorResponse"); module.exports.getProfile = asyncHandler(async (req, res, next) => { - const username = req.params.username; - const { loggedUser } = req; - const user = await User.findOne({ where: { username: username } }); + const username = req.params.username; + const { loggedUser } = req; + const user = await User.findOne({ where: { username: username } }); - if (!user) { - return next(new ErrorResponse(`User not found`, 404)); - } + if (!user) { + return next(new ErrorResponse(`User not found`, 404)); + } - let isFollowing = false; + let isFollowing = false; - if (loggedUser) { - const followers = await user.getFollowers(); - isFollowing = followers.some((user) => user.id === loggedUser.id); - } + if (loggedUser) { + const followers = await user.getFollowers(); + isFollowing = followers.some((user) => user.id === loggedUser.id); + } - const profile = { - username, - bio: user.bio, - image: user.image, - following: isFollowing, - }; - res.status(200).json({ profile }); + const profile = { + username, + firstname: user.firstname, + lastname: user.lastname, + bio: user.bio, + image: user.image, + following: isFollowing, + }; + res.status(200).json({ profile }); }); module.exports.followUser = asyncHandler(async (req, res, next) => { - const username = req.params.username; - const { loggedUser } = req; - const userToFollow = await User.findOne({ where: { username: username } }); + const username = req.params.username; + const { loggedUser } = req; + const userToFollow = await User.findOne({ where: { username: username } }); - if (!userToFollow) { - return next(new ErrorResponse(`User not found`, 404)); - } + if (!userToFollow) { + return next(new ErrorResponse(`User not found`, 404)); + } - const currentUser = await User.findByPk(loggedUser.id); + const currentUser = await User.findByPk(loggedUser.id); - await userToFollow.addFollower(currentUser); + await userToFollow.addFollower(currentUser); - const profile = { - username: username, - bio: userToFollow.dataValues.bio, - image: userToFollow.dataValues.image, - following: true, - }; + const profile = { + username: username, + firstname: userToFollow.dataValues.firstname, + lastname: userToFollow.dataValues.lastname, + bio: userToFollow.dataValues.bio, + image: userToFollow.dataValues.image, + following: true, + }; - res.status(200).json({ profile }); + res.status(200).json({ profile }); }); module.exports.unfollowUser = asyncHandler(async (req, res, next) => { - const username = req.params.username; - const { loggedUser } = req; - const userToUnfollow = await User.findOne({ where: { username: username } }); + const username = req.params.username; + const { loggedUser } = req; + const userToUnfollow = await User.findOne({ where: { username: username } }); - if (!userToUnfollow) { - return next(new ErrorResponse(`User not found`, 404)); - } + if (!userToUnfollow) { + return next(new ErrorResponse(`User not found`, 404)); + } - const currentUser = await User.findByPk(loggedUser.id); + const currentUser = await User.findByPk(loggedUser.id); - await userToUnfollow.removeFollower(currentUser); + await userToUnfollow.removeFollower(currentUser); - const profile = { - username: username, - bio: userToUnfollow.dataValues.bio, - image: userToUnfollow.dataValues.image, - following: false, - }; + const profile = { + username: username, + firstname: userToUnfollow.dataValues.firstname, + lastname: userToUnfollow.dataValues.lastname, + bio: userToUnfollow.dataValues.bio, + image: userToUnfollow.dataValues.image, + following: false, + }; - res.status(200).json({ profile }); + res.status(200).json({ profile }); }); diff --git a/controllers/users.js b/controllers/users.js index 6a788e6..c31e63f 100644 --- a/controllers/users.js +++ b/controllers/users.js @@ -4,90 +4,94 @@ const ErrorResponse = require("../util/errorResponse"); const { sign } = require("../util/jwt"); module.exports.createUser = asyncHandler(async (req, res, next) => { - const { email, password, username } = req.body.user; + const { email, password, username, firstname, lastname } = req.body.user; - fieldValidation(email, next); - fieldValidation(password, next); - fieldValidation(username, next); + fieldValidation(email, next); + fieldValidation(password, next); + fieldValidation(username, next); + fieldValidation(firstname, next); + fieldValidation(lastname, next); - const user = await User.create({ - email: email, - password: password, - username: username, - }); + const user = await User.create({ + email: email, + password: password, + username: username, + firstname: firstname, + lastname: lastname, + }); - if (user.dataValues.password) { - delete user.dataValues.password; - } + if (user.dataValues.password) { + delete user.dataValues.password; + } - user.dataValues.token = await sign(user); + user.dataValues.token = await sign(user); - user.dataValues.bio = null; - user.dataValues.image = null; + user.dataValues.bio = null; + user.dataValues.image = null; - res.status(201).json({ user }); + res.status(201).json({ user }); }); module.exports.loginUser = asyncHandler(async (req, res, next) => { - const { email, password } = req.body.user; + const { email, password } = req.body.user; - fieldValidation(email, next); - fieldValidation(password, next); + fieldValidation(email, next); + fieldValidation(password, next); - const user = await User.findOne({ - where: { - email: email, - }, - }); + const user = await User.findOne({ + where: { + email: email, + }, + }); - if (!user) { - return next(new ErrorResponse(`User not found`, 404)); - } + if (!user) { + return next(new ErrorResponse(`User not found`, 404)); + } - const isMatch = user.matchPassword(password); + const isMatch = user.matchPassword(password); - if (!isMatch) { - return next(new ErrorResponse("Wrong password", 401)); - } + if (!isMatch) { + return next(new ErrorResponse("Wrong password", 401)); + } - delete user.dataValues.password; + delete user.dataValues.password; - user.dataValues.token = await sign(user); + user.dataValues.token = await sign(user); - user.dataValues.bio = null; - user.dataValues.image = null; + user.dataValues.bio = null; + user.dataValues.image = null; - res.status(200).json({ user }); + res.status(200).json({ user }); }); module.exports.getCurrentUser = asyncHandler(async (req, res, next) => { - const { loggedUser } = req; - const user = await User.findByPk(loggedUser.id); + const { loggedUser } = req; + const user = await User.findByPk(loggedUser.id); - if (!user) { - return next(new ErrorResponse(`User not found`, 404)); - } + if (!user) { + return next(new ErrorResponse(`User not found`, 404)); + } - user.dataValues.token = req.headers.authorization.split(" ")[1]; + user.dataValues.token = req.headers.authorization.split(" ")[1]; - res.status(200).json({ user }); + res.status(200).json({ user }); }); module.exports.updateUser = asyncHandler(async (req, res, next) => { - await User.update(req.body.user, { - where: { - id: req.user.id, - }, - }); + await User.update(req.body.user, { + where: { + id: req.user.id, + }, + }); - const user = await User.findByPk(req.user.id); - user.dataValues.token = req.headers.authorization.split(" ")[1]; + const user = await User.findByPk(req.user.id); + user.dataValues.token = req.headers.authorization.split(" ")[1]; - res.status(200).json({ user }); + res.status(200).json({ user }); }); const fieldValidation = (field, next) => { - if (!field) { - return next(new ErrorResponse(`Missing fields`, 400)); - } + if (!field) { + return next(new ErrorResponse(`Missing fields`, 400)); + } }; diff --git a/models copy/Article.js b/models copy/Article.js deleted file mode 100644 index 236f6ba..0000000 --- a/models copy/Article.js +++ /dev/null @@ -1,27 +0,0 @@ -const { DataTypes, Model } = require("sequelize"); -const sequelize = require("../util/database"); -const slugify = require("slugify"); - -const Article = sequelize.define("Article", { - slug: { - type: DataTypes.STRING, - allowNull: false, - }, - title: { - type: DataTypes.STRING, - allowNull: false, - }, - description: { - type: DataTypes.TEXT, - }, - body: { - type: DataTypes.TEXT, - allowNull: false, - }, -}); - -Article.beforeValidate((article) => { - article.slug = slugify(article.title, { lower: true }); -}); - -module.exports = Article; diff --git a/models copy/Comment.js b/models copy/Comment.js deleted file mode 100644 index 42e731a..0000000 --- a/models copy/Comment.js +++ /dev/null @@ -1,11 +0,0 @@ -const { DataTypes, Model } = require("sequelize"); -const sequelize = require("../util/database"); - -const Comment = sequelize.define("Comment", { - body: { - type: DataTypes.TEXT, - allowNull: false, - }, -}); - -module.exports = Comment; diff --git a/models copy/Tag.js b/models copy/Tag.js deleted file mode 100644 index 89f54c4..0000000 --- a/models copy/Tag.js +++ /dev/null @@ -1,16 +0,0 @@ -const { DataTypes, Model } = require("sequelize"); -const sequelize = require("../util/database"); - -const Tag = sequelize.define( - "Tag", - { - name: { - type: DataTypes.STRING, - allowNull: false, - primaryKey: true, - }, - }, - { timestamps: false } -); - -module.exports = Tag; diff --git a/models copy/User.js b/models copy/User.js deleted file mode 100644 index 94bd322..0000000 --- a/models copy/User.js +++ /dev/null @@ -1,58 +0,0 @@ -const { DataTypes, Model } = require("sequelize"); -const sequelize = require("../util/database"); -const bcrypt = require("bcryptjs"); - -/** - * "email": "jake@jake.jake", - "token": "jwt.token.here", - "username": "jake", - "bio": "I work at statefarm", - "image": null - */ - -const User = sequelize.define( - "User", - { - email: { - type: DataTypes.STRING, - allowNull: false, - unique: true, - }, - - username: { - type: DataTypes.STRING, - allowNull: false, - unique: true, - }, - password: { - type: DataTypes.STRING, - allowNull: false, - }, - - bio: { - type: DataTypes.TEXT, - allowNull: true, - }, - image: { - type: DataTypes.TEXT, - allowNull: true, - }, - }, - { timestamps: false } -); - -Model.prototype.matchPassword = async function (enteredPassword) { - return await bcrypt.compare(enteredPassword, this.password); -}; - -const DEFAULT_SALT_ROUNDS = 10; - -User.addHook("beforeCreate", async (user) => { - const encryptedPassword = await bcrypt.hash( - user.password, - DEFAULT_SALT_ROUNDS - ); - user.password = encryptedPassword; -}); - -module.exports = User; diff --git a/models/Article.js b/models/Article.js index cc08952..42d127f 100644 --- a/models/Article.js +++ b/models/Article.js @@ -1,50 +1,36 @@ +const { DataTypes, Model } = require("sequelize"); +const sequelize = require("../util/database"); const slugify = require("slugify"); -//const slug = require("slug"); -const { - Model -} = require('sequelize'); -module.exports = (sequelize, DataTypes) => { - class Article extends Model { - /** - * Helper method for defining associations. - * This method is not a part of Sequelize lifecycle. - * The `models/index` file will call this method automatically. - */ - static associate(models) { - /* define association here */ - } - } - Article.init({ - article_id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false }, - article_slug: { type: DataTypes.STRING, allowNull: false }, - article_title: { type: DataTypes.STRING, allowNull: false }, - article_description: { type: DataTypes.TEXT }, - article_body: { type: DataTypes.TEXT, allowNull: false } - }, { - sequelize, - timestamps: false, - modelName: 'Article', - tableName: 'article', - createdAt: true, - updatedAt: true - }); +const Article = sequelize.define("Article", { + id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false }, + slug: { type: DataTypes.STRING, allowNull: false }, + title: { type: DataTypes.STRING, allowNull: false }, + description: { type: DataTypes.TEXT }, + body: { type: DataTypes.TEXT, allowNull: false }, + createdAt: { type: DataTypes.DATE, allowNull: true }, + updatedAt: { type: DataTypes.DATE, allowNull: true } +}, { + sequelize, + timestamps: false, + modelName: 'Article', + tableName: 'article', + createdAt: true, + updatedAt: true +}); - Article.beforeValidate((article) => { - //article.slug = slug(article.title) + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36); - article.slug = slugify(article.title, { lower: true }); - - }); +Article.beforeValidate((article) => { + article.slug = slugify(article.title, { lower: true }); +}); - Article.prototype.toJSONFor = function () { - return { - id: this.article_id, - slug: this.article_slug, - title: this.article_title, - description: this.article_description, - body: this.article_body - }; +Article.prototype.toJSONFor = function () { + return { + id: this.id, + slug: this.slug, + title: this.title, + description: this.description, + body: this.body }; - - return Article; }; + +module.exports = Article; diff --git a/models/Comment.js b/models/Comment.js index 437faa3..c37fff3 100644 --- a/models/Comment.js +++ b/models/Comment.js @@ -1,35 +1,25 @@ -const { - Model -} = require('sequelize'); -module.exports = (sequelize, DataTypes) => { - class Comment extends Model { - /** - * Helper method for defining associations. - * This method is not a part of Sequelize lifecycle. - * The `models/index` file will call this method automatically. - */ - static associate(models) { - /* define association here */ - } - } - Comment.init({ - comment_id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false }, - comment_body: { type: DataTypes.TEXT, allowNull: false } - }, { - sequelize, - timestamps: false, - modelName: 'Comment', - tableName: 'comment', - createdAt: true, - updatedAt: true - }); +const { DataTypes, Model } = require("sequelize"); +const sequelize = require("../util/database"); - Comment.prototype.toJSONFor = function () { - return { - id: this.comment_id, - body: this.comment_body - }; +const Comment = sequelize.define("Comment", { + id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false }, + body: { type: DataTypes.TEXT, allowNull: false }, + createdAt: { type: DataTypes.DATE, allowNull: true }, + updatedAt: { type: DataTypes.DATE, allowNull: true } +}, { + sequelize, + timestamps: false, + modelName: 'Comment', + tableName: 'comment', + createdAt: true, + updatedAt: true +}); + +Comment.prototype.toJSONFor = function () { + return { + id: this.id, + body: this.body }; +}; - return Comment; -}; \ No newline at end of file +module.exports = Comment; diff --git a/models/Tag.js b/models/Tag.js index 882f01f..f4d14eb 100644 --- a/models/Tag.js +++ b/models/Tag.js @@ -1,34 +1,23 @@ -const { - Model -} = require('sequelize'); -module.exports = (sequelize, DataTypes) => { - class Tag extends Model { - /** - * Helper method for defining associations. - * This method is not a part of Sequelize lifecycle. - * The `models/index` file will call this method automatically. - */ - static associate(models) { - /* define association here */ - } - } - Tag.init({ - tag_name: { type: DataTypes.STRING, allowNull: false, primaryKey: true } - }, { - sequelize, - timestamps: false, - modelName: 'Tag', - tableName: 'tag', - createdAt: true, - updatedAt: true - }); +const { DataTypes, Model } = require("sequelize"); +const sequelize = require("../util/database"); - Tag.prototype.toJSONFor = function () { - return { - id: this.tag_id, - name: this.tag_name - }; +const Tag = sequelize.define("Tag", { + name: { type: DataTypes.STRING, primaryKey: true, allowNull: false }, + createdAt: { type: DataTypes.DATE, allowNull: true }, + updatedAt: { type: DataTypes.DATE, allowNull: true } +}, { + sequelize, + timestamps: false, + modelName: 'Tag', + tableName: 'tag', + createdAt: true, + updatedAt: true +}); + +Tag.prototype.toJSONFor = function () { + return { + name: this.name }; +}; - return Tag; -}; \ No newline at end of file +module.exports = Tag; diff --git a/models/User.js b/models/User.js index 55a2159..8f00f43 100644 --- a/models/User.js +++ b/models/User.js @@ -1,74 +1,61 @@ -'use strict'; - +const { DataTypes, Model } = require("sequelize"); +const sequelize = require("../util/database"); const bcrypt = require("bcryptjs"); -const { - Model -} = require('sequelize'); -module.exports = (sequelize, DataTypes) => { - class User extends Model { - /** - * Helper method for defining associations. - * This method is not a part of Sequelize lifecycle. - * The `models/index` file will call this method automatically. - */ - static associate(models) { - /* define association here */ - } - } - User.init({ - user_id: {type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false}, - user_username: {type: DataTypes.STRING, allowNull: false}, - user_lastname: {type: DataTypes.STRING}, - user_firstname: {type: DataTypes.STRING}, - user_email: {type: DataTypes.STRING}, - user_adresse: {type: DataTypes.STRING}, - user_ville: {type: DataTypes.STRING}, - user_region: {type: DataTypes.STRING}, - user_cp: {type: DataTypes.STRING}, - user_pays: {type: DataTypes.STRING}, - user_tel: {type: DataTypes.STRING}, - user_mobile: {type: DataTypes.STRING}, - user_role: {type: DataTypes.INTEGER} - }, { - sequelize, - timestamps: false, - modelName: 'User', - tableName: 'user', - createdAt: true, - updatedAt: true - }); +/** + * "email": "jake@jake.jake", + "token": "jwt.token.here", + "username": "jake", + "bio": "I work at statefarm", + "image": null + */ - User.prototype.matchPassword = async function (enteredPassword) { - return await bcrypt.compare(enteredPassword, this.password); - }; +const User = sequelize.define("User", { + id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false }, + email: { type: DataTypes.STRING, allowNull: false, unique: true }, + username: { type: DataTypes.STRING, allowNull: false, unique: true }, + firstname: { type: DataTypes.STRING }, + lastname: { type: DataTypes.STRING }, + bio: { type: DataTypes.TEXT, allowNull: true }, + image: { type: DataTypes.TEXT, allowNull: true }, + role: { type: DataTypes.STRING }, + password: { type: DataTypes.STRING, allowNull: false }, + createdAt: { type: DataTypes.DATE, allowNull: true }, + updatedAt: { type: DataTypes.DATE, allowNull: true } +}, { + sequelize, + timestamps: false, + modelName: 'User', + tableName: 'user', + createdAt: true, + updatedAt: true +}); - const DEFAULT_SALT_ROUNDS = 10; - - User.addHook("beforeCreate", async (user) => { - const encryptedPassword = await bcrypt.hash( - user.password, - DEFAULT_SALT_ROUNDS - ); - user.password = encryptedPassword; - }); - - User.prototype.toJSONFor = function () { - return { - id: this.mbr_id, - username: this.mbr_pseudo, - lastname: this.mbr_nom, - firstname: this.mbr_prenom, - email: this.mbr_email, - adresse: this.mbr_adresse, - ville: this.mbr_ville, - region: this.mbr_region, - cp: this.mbr_cp, - pays: this.mbr_pays, - tel: this.mbr_tel, - mobile: this.mbr_mobile, - statut: this.mbr_statut - }; - }; - return User; +Model.prototype.matchPassword = async function (enteredPassword) { + return await bcrypt.compare(enteredPassword, this.password); }; + +const DEFAULT_SALT_ROUNDS = 10; + +User.addHook("beforeCreate", async (user) => { + const encryptedPassword = await bcrypt.hash( + user.password, + DEFAULT_SALT_ROUNDS + ); + user.password = encryptedPassword; +}); + +User.prototype.toJSONFor = function () { + return { + id: this.id, + email: this.email, + username: this.username, + firstname: this.firstname, + lastname: this.lastname, + bio: this.bio, + image: this.image, + role: this.role + }; +}; + +module.exports = User; diff --git a/models/mysql/Article.js b/models/mysql/Article.js index 5294a82..054e72c 100644 --- a/models/mysql/Article.js +++ b/models/mysql/Article.js @@ -16,11 +16,11 @@ module.exports = (sequelize, DataTypes) => { } } Article.init({ - article_id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false }, - article_slug: { type: DataTypes.STRING, allowNull: false }, - article_title: { type: DataTypes.STRING, allowNull: false }, - article_description: { type: DataTypes.TEXT }, - article_body: { type: DataTypes.TEXT, allowNull: false } + articleId: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false }, + slug: { type: DataTypes.STRING, allowNull: false }, + title: { type: DataTypes.STRING, allowNull: false }, + description: { type: DataTypes.TEXT }, + body: { type: DataTypes.TEXT, allowNull: false } }, { sequelize, timestamps: false, @@ -36,11 +36,11 @@ module.exports = (sequelize, DataTypes) => { Article.prototype.toJSONFor = function () { return { - id: this.article_id, - slug: this.article_slug, - title: this.article_title, - description: this.article_description, - body: this.article_body + articleId: this.articleId, + slug: this.slug, + title: this.title, + description: this.description, + body: this.body }; }; diff --git a/models/mysql/Comment.js b/models/mysql/Comment.js index 437faa3..72d0e4e 100644 --- a/models/mysql/Comment.js +++ b/models/mysql/Comment.js @@ -13,8 +13,8 @@ module.exports = (sequelize, DataTypes) => { } } Comment.init({ - comment_id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false }, - comment_body: { type: DataTypes.TEXT, allowNull: false } + commentId: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false }, + body: { type: DataTypes.TEXT, allowNull: false } }, { sequelize, timestamps: false, @@ -26,8 +26,8 @@ module.exports = (sequelize, DataTypes) => { Comment.prototype.toJSONFor = function () { return { - id: this.comment_id, - body: this.comment_body + commentId: this.commentId, + body: this.body }; }; diff --git a/models/mysql/Tag.js b/models/mysql/Tag.js index 882f01f..136d998 100644 --- a/models/mysql/Tag.js +++ b/models/mysql/Tag.js @@ -13,7 +13,7 @@ module.exports = (sequelize, DataTypes) => { } } Tag.init({ - tag_name: { type: DataTypes.STRING, allowNull: false, primaryKey: true } + name: { type: DataTypes.STRING, primaryKey: true, allowNull: false } }, { sequelize, timestamps: false, @@ -25,8 +25,7 @@ module.exports = (sequelize, DataTypes) => { Tag.prototype.toJSONFor = function () { return { - id: this.tag_id, - name: this.tag_name + name: this.name }; }; diff --git a/models/mysql/User.js b/models/mysql/User.js index 55a2159..1b26b4a 100644 --- a/models/mysql/User.js +++ b/models/mysql/User.js @@ -17,19 +17,15 @@ module.exports = (sequelize, DataTypes) => { } } User.init({ - user_id: {type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false}, - user_username: {type: DataTypes.STRING, allowNull: false}, - user_lastname: {type: DataTypes.STRING}, - user_firstname: {type: DataTypes.STRING}, - user_email: {type: DataTypes.STRING}, - user_adresse: {type: DataTypes.STRING}, - user_ville: {type: DataTypes.STRING}, - user_region: {type: DataTypes.STRING}, - user_cp: {type: DataTypes.STRING}, - user_pays: {type: DataTypes.STRING}, - user_tel: {type: DataTypes.STRING}, - user_mobile: {type: DataTypes.STRING}, - user_role: {type: DataTypes.INTEGER} + userId: {type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false}, + email: {type: DataTypes.STRING, allowNull: false, unique: true}, + username: {type: DataTypes.STRING, allowNull: false, unique: true}, + firstname: {type: DataTypes.STRING}, + lastname: {type: DataTypes.STRING}, + bio: {type: DataTypes.TEXT, allowNull: true}, + image: {type: DataTypes.TEXT, allowNull: true}, + role: {type: DataTypes.STRING}, + password: {type: DataTypes.STRING, allowNull: false} }, { sequelize, timestamps: false, @@ -55,19 +51,14 @@ module.exports = (sequelize, DataTypes) => { User.prototype.toJSONFor = function () { return { - id: this.mbr_id, - username: this.mbr_pseudo, - lastname: this.mbr_nom, - firstname: this.mbr_prenom, - email: this.mbr_email, - adresse: this.mbr_adresse, - ville: this.mbr_ville, - region: this.mbr_region, - cp: this.mbr_cp, - pays: this.mbr_pays, - tel: this.mbr_tel, - mobile: this.mbr_mobile, - statut: this.mbr_statut + userId: this.userId, + email: this.email, + username: this.username, + firstname: this.firstname, + lastname: this.lastname, + bio: this.bio, + image: this.image, + role: this.role }; }; return User; diff --git a/nodemon.json b/nodemon.json index 89a1986..34aa736 100644 --- a/nodemon.json +++ b/nodemon.json @@ -4,7 +4,7 @@ "NODE_ENV" : "development", "DEBUG": false, "SERVER_PORT": "3200", - "SECRET": "$2b$10$aEsAUG7Dy8dcTORi1vaQle", + "JWT_SECRET": "$2b$10$aEsAUG7Dy8dcTORi1vaQle", "SESSION_LIFETIME": "3600", "MONGODB_URI": "mongodb://localhost:27017/adastradb", "SENDGRID_API_KEY": "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", diff --git a/package-lock.json b/package-lock.json index 69e894e..5e559df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,8 @@ "devDependencies": { "@eslint/js": "^9.0.0", "eslint": "^9.0.0", - "prettier": "^2.8.0" + "prettier": "^2.8.0", + "sequelize-cli": "^6.6.3" }, "engines": { "node": "^16.20.2 || ^18.19.1 || ^20.11.1" @@ -222,6 +223,39 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@one-ini/wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "dev": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@sendgrid/client": { "version": "8.1.5", "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-8.1.5.tgz", @@ -295,6 +329,15 @@ "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.2.tgz", "integrity": "sha512-y7pa/oEJJ4iGYBxOpfAKn5b9+xuihvzDVnC/OSvlVnGxVg0pOqmjiMafiJ1KVNQEaPZf9HsEp5icEwGg8uIe5Q==" }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -344,6 +387,18 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -387,6 +442,15 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/aws-ssl-profiles": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", @@ -442,6 +506,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/body-parser": { "version": "1.20.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", @@ -597,6 +667,75 @@ "node": ">= 6" } }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -634,11 +773,30 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -777,6 +935,12 @@ "node": ">= 0.4" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -785,11 +949,59 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/editorconfig": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", + "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", + "dev": true, + "dependencies": { + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "9.0.1", + "semver": "^7.5.3" + }, + "bin": { + "editorconfig": "bin/editorconfig" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/editorconfig/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/editorconfig/node_modules/minimatch": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", @@ -839,6 +1051,15 @@ "node": ">= 0.4" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1194,6 +1415,22 @@ } } }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", @@ -1225,6 +1462,21 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1254,6 +1506,15 @@ "is-property": "^1.0.2" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -1289,6 +1550,26 @@ "node": ">= 0.4" } }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -1301,6 +1582,30 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -1324,6 +1629,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1447,6 +1758,12 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -1466,6 +1783,21 @@ "node": ">=8" } }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1474,6 +1806,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -1504,6 +1845,51 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-beautify": { + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz", + "integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==", + "dev": true, + "dependencies": { + "config-chain": "^1.1.13", + "editorconfig": "^1.0.4", + "glob": "^10.4.2", + "js-cookie": "^3.0.5", + "nopt": "^7.2.1" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1534,6 +1920,18 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -1662,6 +2060,12 @@ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==" }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "node_modules/lru.min": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.2.tgz", @@ -1749,6 +2153,15 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -1921,6 +2334,21 @@ "node": ">=4" } }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -2006,6 +2434,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2044,6 +2478,28 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", @@ -2054,6 +2510,12 @@ "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==" }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2089,6 +2551,12 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -2167,6 +2635,35 @@ "node": ">=8.10.0" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -2326,6 +2823,28 @@ } } }, + "node_modules/sequelize-cli": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/sequelize-cli/-/sequelize-cli-6.6.3.tgz", + "integrity": "sha512-1YYPrcSRt/bpMDDSKM5ubY1mnJ2TEwIaGZcqITw4hLtGtE64nIqaBnLtMvH8VKHg6FbWpXTiFNc2mS/BtQCXZw==", + "dev": true, + "dependencies": { + "fs-extra": "^9.1.0", + "js-beautify": "1.15.4", + "lodash": "^4.17.21", + "picocolors": "^1.1.1", + "resolve": "^1.22.1", + "umzug": "^2.3.0", + "yargs": "^16.2.0" + }, + "bin": { + "sequelize": "lib/sequelize", + "sequelize-cli": "lib/sequelize" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/sequelize-pool": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", @@ -2442,6 +2961,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -2477,6 +3008,102 @@ "node": ">= 0.8" } }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2501,6 +3128,18 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2557,6 +3196,18 @@ "node": ">= 0.6" } }, + "node_modules/umzug": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.3.0.tgz", + "integrity": "sha512-Z274K+e8goZK8QJxmbRPhl89HPO1K+ORFtm6rySPhFKfKc5GHhqdzD0SGhSWHkzoXasqJuItdhorSvY7/Cgflw==", + "dev": true, + "dependencies": { + "bluebird": "^3.7.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", @@ -2567,6 +3218,15 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==" }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -2648,6 +3308,171 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 92541fc..2d98fe6 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "devDependencies": { "@eslint/js": "^9.0.0", "eslint": "^9.0.0", - "prettier": "^2.8.0" + "prettier": "^2.8.0", + "sequelize-cli": "^6.6.3" } -} \ No newline at end of file +} diff --git a/routes/articles.js b/routes/articles.js deleted file mode 100644 index e5c04c4..0000000 --- a/routes/articles.js +++ /dev/null @@ -1,30 +0,0 @@ -const express = require("express"); -const router = express.Router(); -const { - getArticle, - getArticles, - createArticle, - articlesFeed, - addFavoriteArticle, - deleteFavoriteArticle, - deleteArticle, - updateArticle, -} = require("../controllers/articles"); -const { protect } = require("../middlewares/auth"); - -router - .route("/articles") - .get(protect, getArticles) - .post(protect, createArticle); -router.route("/articles/feed").get(protect, articlesFeed); -router - .route("/articles/:slug") - .get(protect, getArticle) - .put(protect, updateArticle) - .delete(protect, deleteArticle); -router - .route("/articles/:slug/favorite") - .post(protect, addFavoriteArticle) - .delete(protect, deleteFavoriteArticle); - -module.exports = router; diff --git a/routes/comments.js b/routes/comments.js deleted file mode 100644 index 322bea3..0000000 --- a/routes/comments.js +++ /dev/null @@ -1,23 +0,0 @@ -const express = require("express"); -const router = express.Router(); - -const { - getComment, - getComments, - createComment, - deleteComment, -} = require("../controllers/comments"); - -const { protect } = require("../middlewares/auth"); - -router - .route("/articles/:slug/comments") - .get(protect, getComments) - .post(protect, createComment); - -router - .route("/articles/:slug/comments/:id") - .get(protect, getComment) - .delete(protect, deleteComment); - -module.exports = router; diff --git a/routes/profiles.js b/routes/profiles.js deleted file mode 100644 index d6a558b..0000000 --- a/routes/profiles.js +++ /dev/null @@ -1,16 +0,0 @@ -const express = require("express"); -const router = express.Router(); -const { - getProfile, - followUser, - unfollowUser, -} = require("../controllers/profiles"); -const { protect } = require("../middlewares/auth"); - -router.route("/profiles/:username").get(protect, getProfile); -router - .route("/profiles/:username/follow") - .post(protect, followUser) - .delete(protect, unfollowUser); - -module.exports = router; diff --git a/routes/tags.js b/routes/tags.js deleted file mode 100644 index 5157a6d..0000000 --- a/routes/tags.js +++ /dev/null @@ -1,10 +0,0 @@ -const express = require("express"); -const router = express.Router(); - -const { getTags } = require("../controllers/tags"); - -const { protect } = require("../middlewares/auth"); - -router.route("/tags/").get(getTags); - -module.exports = router; diff --git a/routes/users.js b/routes/users.js deleted file mode 100644 index 9bf832e..0000000 --- a/routes/users.js +++ /dev/null @@ -1,16 +0,0 @@ -const express = require("express"); -const router = express.Router(); -const { - createUser, - loginUser, - getCurrentUser, - updateUser, -} = require("../controllers/users"); -const { protect } = require("../middlewares/auth"); - -router.post("/users", createUser); -router.post("/users/login", loginUser); - -router.route("/user").get(protect, getCurrentUser).put(protect, updateUser); - -module.exports = router; diff --git a/server.js b/server.js index 510be04..89a4d66 100644 --- a/server.js +++ b/server.js @@ -1,25 +1,28 @@ var appEnv = process.env.APP_ENV; - if (appEnv == undefined) { appEnv = 'development'; } -const dotenv = require("dotenv"); -dotenv.config({ path: `.env.${appEnv}` }); +require('dotenv').config({ path: `.env.${appEnv}` }); +const { promisify } = require('util'); const express = require("express"); const sequelize = require("./util/database"); +const chalk = require('chalk'); const morgan = require("morgan"); const colors = require("colors"); +const utils = require('./routes/utils'); const { errorHandler } = require("./middlewares/errorHandler"); -// Import Models +var isProduction = appEnv === 'production'; + /* +var db = require("./models"); +*/ +// Import Models const User = require("./models/User"); const Article = require("./models/Article"); const Tag = require("./models/Tag"); const Comment = require("./models/Comment"); -*/ -var db = require("./models/mysql"); const app = express(); @@ -27,31 +30,47 @@ const app = express(); app.use(express.json()); if (process.env.NODE_ENV === "development") { - app.use(morgan("dev")); + morgan.token('statusColor', (req, res) => { + let status = (typeof res.headersSent !== 'boolean' ? Boolean(res.header) : res.headersSent) + ? res.statusCode + : undefined + + return status >= 500 ? chalk.red(status) + : status >= 429 ? chalk.magenta(status) + : status >= 400 ? chalk.yellow(status) + : status >= 300 ? chalk.cyan(status) + : status >= 200 ? chalk.green(status) + : chalk.underline(status); + }); + app.use(morgan('[:date[iso]] ":method :url HTTP/:http-version" :statusColor :res[content-length] ":referrer" ":user-agent" :remote-addr')); + //app.use(require('method-override')()); + //app.use(express.static(__dirname + '/public')); } else { - app.use(morgan('[:date[iso]] ":method :url HTTP/:http-version" :statusColor :res[content-length] ":referrer" ":user-agent" :remote-addr')); + app.use(morgan("dev")); } + // CORS app.use((req, res, next) => { - res.header("Access-Control-Allow-Origin", "*"); - res.header( - "Access-Control-Allow-Headers", - "Origin, X-Requested-With, Content-Type, Accept, Authorization" - ); - if (req.method === "OPTIONS") { - res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, GET"); - return res.status(200).json({}); - } - next(); + res.header("Access-Control-Allow-Origin", "*"); + res.header( + "Access-Control-Allow-Headers", + "Origin, X-Requested-With, Content-Type, Accept, Authorization" + ); + if (req.method === "OPTIONS") { + res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, GET"); + return res.status(200).json({}); + } + next(); }); + // Route files -const users = require("./routes/users"); -const profiles = require("./routes/profiles"); -const articles = require("./routes/articles"); -const comments = require("./routes/comments"); -const tags = require("./routes/tags"); +const users = require("./routes/api/users"); +const profiles = require("./routes/api/profiles"); +const articles = require("./routes/api/articles"); +const comments = require("./routes/api/comments"); +const tags = require("./routes/api/tags"); // Mount routers app.use(users); @@ -60,83 +79,87 @@ app.use(articles); app.use(comments); app.use(tags); -const PORT = process.env.PORT || process.env.SERVER_PORT; +//app.use(require('./routes')); app.use(errorHandler); -console.log(`User: ${User}`); -// Relations -db.User.belongsToMany(User, { - as: "followers", - through: "Followers", - foreignKey: "userId", - timestamps: false, -}); -db.User.belongsToMany(User, { - as: "following", - through: "Followers", - foreignKey: "followerId", - timestamps: false, -}); +//console.log(`User: ${User}`); -db.User.hasMany(Article, { - foreignKey: "authorId", - onDelete: "CASCADE", +// Relations +User.belongsToMany(User, { + as: "followers", + through: "Followers", + foreignKey: "userId", + timestamps: false, +}); +User.belongsToMany(User, { + as: "following", + through: "Followers", + foreignKey: "followerId", + timestamps: false, +}); +User.hasMany(Article, { + foreignKey: "authorId", + onDelete: "CASCADE", }); Article.belongsTo(User, { as: "author", foreignKey: "authorId" }); - User.hasMany(Comment, { - foreignKey: "authorId", - onDelete: "CASCADE", + foreignKey: "authorId", + onDelete: "CASCADE", }); Comment.belongsTo(User, { as: "author", foreignKey: "authorId" }); - Article.hasMany(Comment, { - foreignKey: "articleId", - onDelete: "CASCADE", + foreignKey: "articleId", + onDelete: "CASCADE", }); Comment.belongsTo(Article, { foreignKey: "articleId" }); - User.belongsToMany(Article, { - as: "favorites", - through: "Favorites", - timestamps: false, + as: "favorites", + through: "Favorites", + timestamps: false, }); Article.belongsToMany(User, { - through: "Favorites", - foreignKey: "articleId", - timestamps: false, + through: "Favorites", + foreignKey: "articleId", + timestamps: false, }); - Article.belongsToMany(Tag, { - through: "TagLists", - as: "tagLists", - foreignKey: "articleId", - timestamps: false, - onDelete: "CASCADE", + through: "TagLists", + as: "tagLists", + foreignKey: "articleId", + timestamps: false, + onDelete: "CASCADE", }); Tag.belongsToMany(Article, { - through: "ArticleTags", - uniqueKey: false, - timestamps: false, + through: "ArticleTags", + uniqueKey: false, + timestamps: false, }); - +/* const sync = async () => await sequelize.sync({ force: true }); sync().then(() => { - User.create({ - email: "test@test.com", - password: "123456", - username: "neo", - }); - User.create({ - email: "test2@test.com", - password: "123456", - username: "celeb_neo", - }); + User.create({ + email: "jgautier.webdev@gmail.com", + username: "adastra", + firstname: "Julien", + lastname: "Gautier", + password: "DKxp24PSnr", + role: "admin" + }); + User.create({ + email: "rampeur@gmail.com", + username: "solide", + firstname: "Rampeur", + lastname: "Solide", + password: "DKxp24PSnr", + role: "user" + }); }); +*/ +const startServer = async () => { + const port = process.env.SERVER_PORT || 3200; + await promisify(app.listen).bind(app)(port); + console.log(`${utils.getDateTimeISOString()}`, chalk.green(`${process.env.APP_ENV} API server listening on port ${port}`)); +} -const server = app.listen( - PORT, - console.log( - `Server running in ${process.env.NODE_ENV} mode on port ${PORT}`.yellow.bold - ) -); +// finally, let's start our server... +startServer(); \ No newline at end of file diff --git a/util/jwt.js b/util/jwt.js index 4bfed3b..556df63 100644 --- a/util/jwt.js +++ b/util/jwt.js @@ -2,7 +2,7 @@ const jwt = require("jsonwebtoken"); module.exports.sign = async (user) => { const token = await jwt.sign( - { id: user.id, username: user.username, email: user.email }, + { userId: user.userId, username: user.username, email: user.email }, process.env.JWT_SECRET ); return token;