| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 | "use strict";const async = require("async");const hooks = require("./hooks");const moduleManager = require("../../index");const db = require("../db");const cache = require("../cache");const utils = require("../utils");// const logger = require("../logger");const songs = require("../songs");const reportableIssues = [    {        name: "Video",        reasons: [            "Doesn't exist",            "It's private",            "It's not available in my country",        ],    },    {        name: "Title",        reasons: ["Incorrect", "Inappropriate"],    },    {        name: "Duration",        reasons: [            "Skips too soon",            "Skips too late",            "Starts too soon",            "Skips too late",        ],    },    {        name: "Artists",        reasons: ["Incorrect", "Inappropriate"],    },    {        name: "Thumbnail",        reasons: ["Incorrect", "Inappropriate", "Doesn't exist"],    },];cache.runJob("SUB", {    channel: "report.resolve",    cb: (reportId) => {        utils.runJob("EMIT_TO_ROOM", {            room: "admin.reports",            args: ["event:admin.report.resolved", reportId],        });    },});cache.runJob("SUB", {    channel: "report.create",    cb: (report) => {        utils.runJob("EMIT_TO_ROOM", {            room: "admin.reports",            args: ["event:admin.report.created", report],        });    },});module.exports = {    /**     * Gets all reports     *     * @param {Object} session - the session object automatically added by socket.io     * @param {Function} cb - gets called with the result     */    index: hooks.adminRequired(async (session, cb) => {        const reportModel = await db.runJob("GET_MODEL", {            modelName: "report",        });        async.waterfall(            [                (next) => {                    reportModel                        .find({ resolved: false })                        .sort({ released: "desc" })                        .exec(next);                },            ],            async (err, reports) => {                if (err) {                    err = await utils.runJob("GET_ERROR", { error: err });                    console.log(                        "ERROR",                        "REPORTS_INDEX",                        `Indexing reports failed. "${err}"`                    );                    return cb({ status: "failure", message: err });                }                console.log(                    "SUCCESS",                    "REPORTS_INDEX",                    "Indexing reports successful."                );                cb({ status: "success", data: reports });            }        );    }),    /**     * Gets a specific report     *     * @param {Object} session - the session object automatically added by socket.io     * @param {String} reportId - the id of the report to return     * @param {Function} cb - gets called with the result     */    findOne: hooks.adminRequired(async (session, reportId, cb) => {        const reportModel = await db.runJob("GET_MODEL", {            modelName: "report",        });        async.waterfall(            [                (next) => {                    reportModel.findOne({ _id: reportId }).exec(next);                },            ],            async (err, report) => {                if (err) {                    err = await utils.runJob("GET_ERROR", { error: err });                    console.log(                        "ERROR",                        "REPORTS_FIND_ONE",                        `Finding report "${reportId}" failed. "${err}"`                    );                    return cb({ status: "failure", message: err });                }                console.log(                    "SUCCESS",                    "REPORTS_FIND_ONE",                    `Finding report "${reportId}" successful.`                );                cb({ status: "success", data: report });            }        );    }),    /**     * Gets all reports for a songId (_id)     *     * @param {Object} session - the session object automatically added by socket.io     * @param {String} songId - the id of the song to index reports for     * @param {Function} cb - gets called with the result     */    getReportsForSong: hooks.adminRequired(async (session, songId, cb) => {        const reportModel = await db.runJob("GET_MODEL", {            modelName: "report",        });        async.waterfall(            [                (next) => {                    reportModel                        .find({ song: { _id: songId }, resolved: false })                        .sort({ released: "desc" })                        .exec(next);                },                (reports, next) => {                    let data = [];                    for (let i = 0; i < reports.length; i++) {                        data.push(reports[i]._id);                    }                    next(null, data);                },            ],            async (err, data) => {                if (err) {                    err = await utils.runJob("GET_ERROR", { error: err });                    console.log(                        "ERROR",                        "GET_REPORTS_FOR_SONG",                        `Indexing reports for song "${songId}" failed. "${err}"`                    );                    return cb({ status: "failure", message: err });                } else {                    console.log(                        "SUCCESS",                        "GET_REPORTS_FOR_SONG",                        `Indexing reports for song "${songId}" successful.`                    );                    return cb({ status: "success", data });                }            }        );    }),    /**     * Resolves a report     *     * @param {Object} session - the session object automatically added by socket.io     * @param {String} reportId - the id of the report that is getting resolved     * @param {Function} cb - gets called with the result     */    resolve: hooks.adminRequired(async (session, reportId, cb) => {        const reportModel = await db.runJob("GET_MODEL", {            modelName: "report",        });        async.waterfall(            [                (next) => {                    reportModel.findOne({ _id: reportId }).exec(next);                },                (report, next) => {                    if (!report) return next("Report not found.");                    report.resolved = true;                    report.save((err) => {                        if (err) next(err.message);                        else next();                    });                },            ],            async (err) => {                if (err) {                    err = await utils.runJob("GET_ERROR", { error: err });                    console.log(                        "ERROR",                        "REPORTS_RESOLVE",                        `Resolving report "${reportId}" failed by user "${session.userId}". "${err}"`                    );                    return cb({ status: "failure", message: err });                } else {                    cache.runJob("PUB", {                        channel: "report.resolve",                        value: reportId,                    });                    console.log(                        "SUCCESS",                        "REPORTS_RESOLVE",                        `User "${session.userId}" resolved report "${reportId}".`                    );                    cb({                        status: "success",                        message: "Successfully resolved Report",                    });                }            }        );    }),    /**     * Creates a new report     *     * @param {Object} session - the session object automatically added by socket.io     * @param {Object} data - the object of the report data     * @param {Function} cb - gets called with the result     */    create: hooks.loginRequired(async (session, data, cb) => {        const reportModel = await db.runJob("GET_MODEL", {            modelName: "report",        });        const songModel = await db.runJob("GET_MODEL", { modelName: "song" });        async.waterfall(            [                (next) => {                    songModel.findOne({ songId: data.songId }).exec(next);                },                (song, next) => {                    if (!song) return next("Song not found.");                    songs                        .runJob("GET_SONG", { id: song._id })                        .then((response) => {                            next(null, response.song);                        })                        .catch(next);                },                (song, next) => {                    if (!song) return next("Song not found.");                    delete data.songId;                    data.song = {                        _id: song._id,                        songId: song.songId,                    };                    for (let z = 0; z < data.issues.length; z++) {                        if (                            reportableIssues.filter((issue) => {                                return issue.name == data.issues[z].name;                            }).length > 0                        ) {                            for (let r = 0; r < reportableIssues.length; r++) {                                if (                                    reportableIssues[r].reasons.every(                                        (reason) =>                                            data.issues[z].reasons.indexOf(                                                reason                                            ) < -1                                    )                                ) {                                    return cb({                                        status: "failure",                                        message: "Invalid data",                                    });                                }                            }                        } else                            return cb({                                status: "failure",                                message: "Invalid data",                            });                    }                    next();                },                (next) => {                    let issues = [];                    for (let r = 0; r < data.issues.length; r++) {                        if (!data.issues[r].reasons.length <= 0)                            issues.push(data.issues[r]);                    }                    data.issues = issues;                    next();                },                (next) => {                    data.createdBy = session.userId;                    data.createdAt = Date.now();                    reportModel.create(data, next);                },            ],            async (err, report) => {                if (err) {                    err = await utils.runJob("GET_ERROR", { error: err });                    console.log(                        "ERROR",                        "REPORTS_CREATE",                        `Creating report for "${data.song._id}" failed by user "${session.userId}". "${err}"`                    );                    return cb({ status: "failure", message: err });                } else {                    cache.runJob("PUB", {                        channel: "report.create",                        value: report,                    });                    console.log(                        "SUCCESS",                        "REPORTS_CREATE",                        `User "${session.userId}" created report for "${data.songId}".`                    );                    return cb({                        status: "success",                        message: "Successfully created report",                    });                }            }        );    }),};
 |