issue/1 (#31)
Co-authored-by: dbroqua <contact@darkou.fr> Reviewed-on: https://git.darkou.fr/dbroqua/MusicTopus/pulls/31
This commit is contained in:
parent
ac72c1c13c
commit
aeb5df067c
28 changed files with 630 additions and 66 deletions
|
@ -13,9 +13,11 @@ import { isXhr } from "./helpers";
|
|||
|
||||
import indexRouter from "./routes";
|
||||
import maCollectionRouter from "./routes/ma-collection";
|
||||
import collectionRouter from "./routes/collection";
|
||||
|
||||
import importAlbumRouterApiV1 from "./routes/api/v1/albums";
|
||||
import importSearchRouterApiV1 from "./routes/api/v1/search";
|
||||
import importMeRouterApiV1 from "./routes/api/v1/me";
|
||||
|
||||
// Mongoose schema init
|
||||
require("./models/users");
|
||||
|
@ -82,8 +84,10 @@ app.use(
|
|||
|
||||
app.use("/", indexRouter);
|
||||
app.use("/ma-collection", maCollectionRouter);
|
||||
app.use("/collection", collectionRouter);
|
||||
app.use("/api/v1/albums", importAlbumRouterApiV1);
|
||||
app.use("/api/v1/search", importSearchRouterApiV1);
|
||||
app.use("/api/v1/me", importMeRouterApiV1);
|
||||
|
||||
// Handle 404
|
||||
app.use((req, res) => {
|
||||
|
@ -113,7 +117,10 @@ app.use((error, req, res, next) => {
|
|||
} else {
|
||||
res.status(error.errorCode || 500);
|
||||
res.render("index", {
|
||||
page: { title: "500: Oups… le serveur a crashé !", error },
|
||||
page: {
|
||||
title: error.title || "500: Oups… le serveur a crashé !",
|
||||
error,
|
||||
},
|
||||
errorCode: error.errorCode || 500,
|
||||
viewname: "error",
|
||||
user: req.user || null,
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
class ErrorEvent extends Error {
|
||||
/**
|
||||
* @param {Number} errorCode
|
||||
* @param {String} title
|
||||
* @param {Mixed} ...params
|
||||
*/
|
||||
constructor(errorCode, ...params) {
|
||||
constructor(errorCode, title, ...params) {
|
||||
super(...params);
|
||||
|
||||
if (Error.captureStackTrace) {
|
||||
|
@ -14,6 +15,7 @@ class ErrorEvent extends Error {
|
|||
}
|
||||
|
||||
this.errorCode = parseInt(errorCode, 10);
|
||||
this.title = title;
|
||||
this.date = new Date();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,19 @@ import xl from "excel4node";
|
|||
import Pages from "./Pages";
|
||||
|
||||
import AlbumsModel from "../models/albums";
|
||||
import UsersModel from "../models/users";
|
||||
import ErrorEvent from "../libs/error";
|
||||
|
||||
/**
|
||||
* Classe permettant la gestion des albums d'un utilisateur
|
||||
*/
|
||||
class Albums extends Pages {
|
||||
/**
|
||||
* Méthode permettant de remplacer certains cartactères par leur équivalents html
|
||||
* @param {String} str
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
static replaceSpecialChars(str) {
|
||||
if (!str) {
|
||||
return "";
|
||||
|
@ -487,7 +494,7 @@ class Albums extends Pages {
|
|||
static async getAllDistincts(field, user) {
|
||||
const distincts = await AlbumsModel.find(
|
||||
{
|
||||
user,
|
||||
User: user,
|
||||
},
|
||||
[],
|
||||
{
|
||||
|
@ -513,8 +520,11 @@ class Albums extends Pages {
|
|||
order = "asc",
|
||||
artists_sort,
|
||||
format,
|
||||
userId: collectionUserId,
|
||||
} = this.req.query;
|
||||
|
||||
let userId = this.req.user?._id;
|
||||
|
||||
const where = {};
|
||||
|
||||
if (artists_sort) {
|
||||
|
@ -524,8 +534,35 @@ class Albums extends Pages {
|
|||
where["formats.name"] = format;
|
||||
}
|
||||
|
||||
if (!this.req.user && !collectionUserId) {
|
||||
throw new ErrorEvent(
|
||||
401,
|
||||
"Cette collection n'est pas publique",
|
||||
"Cette collection n'est pas publique"
|
||||
);
|
||||
}
|
||||
|
||||
if (collectionUserId) {
|
||||
const userIsSharingCollection = await UsersModel.findById(
|
||||
collectionUserId
|
||||
);
|
||||
|
||||
if (
|
||||
!userIsSharingCollection ||
|
||||
!userIsSharingCollection.isPublicCollection
|
||||
) {
|
||||
throw new ErrorEvent(
|
||||
401,
|
||||
"Cette collection n'est pas publique",
|
||||
"Cette collection n'est pas publique"
|
||||
);
|
||||
}
|
||||
|
||||
userId = userIsSharingCollection._id;
|
||||
}
|
||||
|
||||
const count = await AlbumsModel.count({
|
||||
user: this.req.user._id,
|
||||
User: userId,
|
||||
...where,
|
||||
});
|
||||
|
||||
|
@ -547,7 +584,7 @@ class Albums extends Pages {
|
|||
|
||||
const rows = await AlbumsModel.find(
|
||||
{
|
||||
user: this.req.user._id,
|
||||
User: userId,
|
||||
...where,
|
||||
},
|
||||
[],
|
||||
|
@ -619,6 +656,29 @@ class Albums extends Pages {
|
|||
|
||||
this.setPageContent("item", item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode permettant de créer la page "collection/:userId"
|
||||
*/
|
||||
async loadPublicCollection() {
|
||||
const { userId } = this.req.params;
|
||||
|
||||
const user = await UsersModel.findById(userId);
|
||||
|
||||
if (!user || !user.isPublicCollection) {
|
||||
throw new ErrorEvent(
|
||||
401,
|
||||
"Cet utilisateur ne souhaite pas partager sa collection"
|
||||
);
|
||||
}
|
||||
|
||||
const artists = await Albums.getAllDistincts("artists_sort", userId);
|
||||
const formats = await Albums.getAllDistincts("formats.name", userId);
|
||||
|
||||
this.setPageContent("username", user.username);
|
||||
this.setPageContent("artists", artists);
|
||||
this.setPageContent("formats", formats);
|
||||
}
|
||||
}
|
||||
|
||||
export default Albums;
|
||||
|
|
45
src/middleware/Me.js
Normal file
45
src/middleware/Me.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
import Joi from "joi";
|
||||
|
||||
import UsersModel from "../models/users";
|
||||
|
||||
/**
|
||||
* Classe permettant la gestion de l'utilisateur connecté
|
||||
*/
|
||||
class Me {
|
||||
constructor(req) {
|
||||
this.req = req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode permettant de modifier le profil d'un utilisateur
|
||||
* @return {Object}
|
||||
*/
|
||||
async patchMe() {
|
||||
const { body, user } = this.req;
|
||||
|
||||
const schema = Joi.object({
|
||||
isPublicCollection: Joi.boolean(),
|
||||
});
|
||||
|
||||
const value = await schema.validateAsync(body);
|
||||
const update = await UsersModel.findByIdAndUpdate(
|
||||
user._id,
|
||||
{ $set: value },
|
||||
{ new: true }
|
||||
);
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
this.req.login(update, (err) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
return resolve(null);
|
||||
});
|
||||
});
|
||||
|
||||
return update;
|
||||
}
|
||||
}
|
||||
|
||||
export default Me;
|
|
@ -1,5 +1,7 @@
|
|||
/* eslint-disable func-names */
|
||||
/* eslint-disable no-invalid-this */
|
||||
/* eslint-disable no-param-reassign */
|
||||
|
||||
import mongoose from "mongoose";
|
||||
import uniqueValidator from "mongoose-unique-validator";
|
||||
import crypto from "crypto";
|
||||
|
@ -23,8 +25,20 @@ const UserSchema = new mongoose.Schema(
|
|||
},
|
||||
hash: String,
|
||||
salt: String,
|
||||
isPublicCollection: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
{ timestamps: true }
|
||||
{
|
||||
timestamps: true,
|
||||
toJSON: {
|
||||
transform(doc, ret) {
|
||||
delete ret.hash;
|
||||
delete ret.salt;
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
UserSchema.plugin(uniqueValidator, { message: "est déjà utilisé" });
|
||||
|
|
|
@ -9,7 +9,7 @@ const router = express.Router();
|
|||
|
||||
router
|
||||
.route("/")
|
||||
.get(ensureLoggedIn("/connexion"), async (req, res, next) => {
|
||||
.get(async (req, res, next) => {
|
||||
try {
|
||||
const albums = new Albums(req);
|
||||
const data = await albums.getAll();
|
||||
|
|
24
src/routes/api/v1/me.js
Normal file
24
src/routes/api/v1/me.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import express from "express";
|
||||
import { ensureLoggedIn } from "connect-ensure-login";
|
||||
|
||||
import { sendResponse } from "../../../libs/format";
|
||||
|
||||
import Me from "../../../middleware/Me";
|
||||
|
||||
// eslint-disable-next-line new-cap
|
||||
const router = express.Router();
|
||||
|
||||
router
|
||||
.route("/")
|
||||
.patch(ensureLoggedIn("/connexion"), async (req, res, next) => {
|
||||
try {
|
||||
const me = new Me(req);
|
||||
const data = await me.patchMe();
|
||||
|
||||
return sendResponse(req, res, data);
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
22
src/routes/collection.js
Normal file
22
src/routes/collection.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
import express from "express";
|
||||
|
||||
import Albums from "../middleware/Albums";
|
||||
|
||||
import render from "../libs/format";
|
||||
|
||||
// eslint-disable-next-line new-cap
|
||||
const router = express.Router();
|
||||
|
||||
router.route("/:userId").get(async (req, res, next) => {
|
||||
try {
|
||||
const page = new Albums(req, "collection");
|
||||
|
||||
await page.loadPublicCollection();
|
||||
|
||||
render(res, page);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
|
@ -10,7 +10,7 @@ const router = express.Router();
|
|||
|
||||
router.route("/").get(ensureLoggedIn("/connexion"), async (req, res, next) => {
|
||||
try {
|
||||
const page = new Albums(req, "mon-compte/ma-collection");
|
||||
const page = new Albums(req, "mon-compte/ma-collection/index");
|
||||
|
||||
await page.loadMyCollection();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue