const express = require("express") const router = express.Router() const Errors = require("../lib/errors.js") const auth = require("../lib/authorize.js") const { User, Theme, Message } = require("../models") const { Op } = require("sequelize") const dayjs = require("dayjs") const fs = require("fs") const os = require("os") router.all("*", auth, async (req, res, next) => { try { if (!req.user.admin) { throw Errors.unauthorized } else { next() } } catch (err) { next(err) } }) router.all("*", auth, async (req, res, next) => { try { if (!req.user.emailVerified && process.env.EMAIL_VERIFICATION === "true") { throw Errors.emailVerificationRequired } else { next() } } catch (e) { next(e) } }) router.get("/", auth, async (req, res, next) => { try { res.json({ users: await User.count(), themes: await Theme.count(), messages: await Message.count(), usersToday: await User.count({ where: { lastSeenAt: { [Op.gte]: dayjs().startOf("day").toDate() } } }), usersThisWeek: await User.count({ where: { lastSeenAt: { [Op.gte]: dayjs().startOf("week").toDate() } } }) }) } catch (err) { return next(err) } }) router.get("/metrics", auth, async (req, res, next) => { try { const sevenDaysAgo = new Date(new Date().setDate(new Date().getDate() - 7)) const createdAt = { [Op.gte]: sevenDaysAgo } const registrationStats = await User.findAll({ where: { createdAt: createdAt }, attributes: { exclude: ["totp", "password"] } }) const messages = await Message.findAll({ where: { createdAt: createdAt }, attributes: { exclude: ["totp", "password"] } }) const registrationGraphInterim = registrationStats.reduce(function ( result, user ) { let day = dayjs(user.createdAt).format("YYYY-MM-DD") if (!result[day]) { result[day] = 0 } result[day]++ return result }, {}) const messagesGraphInterim = messages.reduce(function (result, message) { let day = dayjs(message.createdAt).format("YYYY-MM-DD") if (!result[day]) { result[day] = 0 } result[day]++ return result }, {}) const usersGraph = { labels: Object.keys(registrationGraphInterim), datasets: [ { data: Object.values(registrationGraphInterim), label: "Users", borderColor: "#3e95cd", pointBackgroundColor: "#FFFFFF", backgroundColor: "transparent" } ] } const messagesGraph = { labels: Object.keys(messagesGraphInterim), datasets: [ { data: Object.values(messagesGraphInterim), label: "Messages", borderColor: "#3e95cd", pointBackgroundColor: "#FFFFFF", backgroundColor: "transparent" } ] } res.json({ users: usersGraph, activeUsers: messagesGraph }) } catch (err) { return next(err) } }) router.get("/users", auth, async (req, res, next) => { try { const users = await User.findAndCountAll({ include: [ { model: Theme, as: "themeObject" } ], attributes: { exclude: ["totp", "password"] } }) res.json(users) } catch (err) { return next(err) } }) router.get("/themes", auth, async (req, res, next) => { try { const themes = await Theme.findAndCountAll({ include: [ { model: User, as: "user", attributes: { exclude: ["totp", "password"] } }, { model: User, as: "users" } ] }) res.json(themes) } catch (err) { return next(err) } }) router.put("/themes/apply", auth, async (req, res, next) => { try { await User.update( { themeId: req.body.themeId }, { where: { id: req.user.id } } ) res.sendStatus(204) } catch (err) { return next(err) } }) router.put("/state", auth, async (req, res, next) => { function setEnvValue(key, value) { // read file from hdd & split if from a linebreak to a array const ENV_VARS = fs.readFileSync(".env", "utf8").split(os.EOL) // find the env we want based on the key const target = ENV_VARS.indexOf( ENV_VARS.find((line) => { // (?