Files
toho-miku/api/jsonApi.js

156 lines
3.7 KiB
JavaScript

require("dotenv").config();
const Sequelize = require('sequelize');
const express = require('express');
const bodyParser = require('body-parser');
const { Card, User, DropHistory, Character, Group } = require("../models");
const { Op } = require('sequelize');
const ACCESS_TOKEN = process.env.API_ACCESS_TOKEN;
const app = express();
const router = express.Router();
const PREFIX = '/api/v1';
app.use(bodyParser.json());
function isAuthorized(req, res=null) {
const providedToken = req.headers['apikey'];
if (providedToken !== ACCESS_TOKEN) {
if(res) {
res.status(401).json({ error: 'Unauthorized' });
}
return false;
}
return true;
}
router.get('/', (req, res) => {
const routes = router.stack
.filter(layer => layer.route) // Filter out non-routes
.map(layer => {
return {
route: PREFIX + layer.route.path,
methods: layer.route.methods
};
});
res.json({ routes: routes });
});
router.get('/ping', (req, res) => {
res.json({ status: 'Pong' });
});
router.get('/stats', async (req, res) => {
if(!isAuthorized(req, res)){return;}
res.json({
users: await User.count(),
cards: await Card.count({where: { burned: { [Op.eq]: false }}}),
burned: await Card.count({where: { burned: { [Op.eq]: true }}}),
drops: await DropHistory.count(),
groups: await Group.count({where: { enabled: { [Op.eq]: true }}}),
characters: await Character.count({where: { enabled: { [Op.eq]: true }}}),
uptime: app.client.uptime
});
});
router.get('/most-recent-drop', async (req, res) => {
if(!isAuthorized(req, res)){return;}
try {
const mostRecentDrop = await DropHistory.findOne({
order: [['createdAt', 'DESC']],
where: {
type: 0
}
});
if (!mostRecentDrop) {
return res.status(404).send('No drops found');
}
const dropData = JSON.parse(mostRecentDrop.dropData);
const cards = await Promise.all(Object.keys(dropData).map(async key => {
const cardData = dropData[key]?.cardData;
if(!cardData) {return};
const card = JSON.parse(cardData);
return { identifier: card.identifier, quality: card.quality, character: await Character.findByPk(card.characterId) };
}));
let response = { dropper: await User.findByPk(dropData.dropper), cards: cards.filter(Boolean)};
res.json(response);
} catch (error) {
console.error(error);
res.status(500).send('Error fetching most recent drop');
}
});
/**
* Groups
*/
router.get('/groups', async (req, res) => {
let condition = {
where: {
[Sequelize.Op.or]: [
{enabled: 1}
]
}
}
if(isAuthorized && req.query.include_disabled) {
condition['where'][Sequelize.Op.or].push({enabled: 0});
}
let groups = await Group.findAll(condition);
res.json(groups);
});
router.get('/groups/:group_id', async (req, res) => {
let group = await Group.findByPk(req.params.group_id);
if (!group.enabled && !isAuthorized(req)) {
res.status(404).json({ error: 'Group not found' });
return;
}
res.json(group);
});
/**
* Characters
*/
router.get('/characters', async (req, res) => {
let condition = {
where: {
[Sequelize.Op.or]: [
{enabled: 1}
]
}
}
if(isAuthorized && req.query.include_disabled) {
condition['where'][Sequelize.Op.or].push({enabled: 0});
}
let characters = await Character.findAll(condition);
res.json(characters);
});
router.get('/characters/:character_id', async (req, res) => {
let character = await Character.findByPk(req.params.character_id);
if (!character.enabled && !isAuthorized(req)) {
res.status(404).json({ error: 'Character not found' });
return;
}
res.json(character);
});
app.use(PREFIX, router);
module.exports = app;