Added the Sheepstar API to the Archive

This commit is contained in:
2022-09-06 16:37:56 +02:00
parent d6c272cdaf
commit bb78376745
36 changed files with 5346 additions and 0 deletions

View File

@ -0,0 +1,45 @@
const app = require('express').Router();
const crypto = require('crypto');
const checkPermission = require("../middlewares/checkPermission");
const APIKey = require("../models/APIKey");
app.put("/", checkPermission("admin.apikey.create"), async (req, res) => {
// Generate apikey
const token = crypto.randomBytes(64).toString('hex');
try {
// Return response
res.status(200).send(await APIKey.create({token: token, client_id: req.clientId}));
} catch (e) {
res.status(500).json({message: "An internal error occurred."})
}
});
app.get("/:apiKey", checkPermission("admin.apikey.info"), async (req, res) => {
// Validate request
if (!req.params.apiKey) return res.status(400).json({message: "You need to provide an api key"});
// Search for the api key
const apikey = await APIKey.findOne({where: {token: req.params.apiKey}});
if (apikey) {
// Return response
res.status(200).json(apikey);
} else res.status(402).json({message: "Invalid API key"});
});
app.delete("/:apiKey", checkPermission("admin.apikey.delete"), async (req, res) => {
// Validate request
if (!req.params.apiKey) return res.status(400).json({message: "You need to provide an api key"});
// Search for the api key
const apikey = await APIKey.findOne({where: {token: req.params.apiKey}});
if (apikey) {
// Destroy api key
await APIKey.destroy({where: {token: req.params.apiKey}});
// Return response
res.status(200).json({message: "Successfully deleted"});
} else res.status(402).json({message: "Invalid API key"});
});
module.exports = app;

View File

@ -0,0 +1,70 @@
const app = require('express').Router();
const checkPermission = require("../middlewares/checkPermission");
const articleValidation = require("../validation/articleValidation");
const Article = require("../models/Article");
app.put("/", checkPermission("admin.article.create"), async (req, res) => {
// Validate request
const {error} = articleValidation.create.validate(req.body);
if (error) return res.status(400).json({message: error.details[0].message});
// Check if article already exists
const {count: articleCount} = await Article.findAndCountAll({where: req.body});
if (articleCount === 1) return res.status(400).json({message: "Article already exists"});
// Create article
res.status(200).json(await Article.create(req.body));
});
app.delete("/", checkPermission("admin.article.delete"), async (req, res) => {
// Validate request
const {error} = articleValidation.info.validate(req.body);
if (error) return res.status(400).json({message: error.details[0].message});
// Check if already exists
const {count: articleCount} = await Article.findAndCountAll({where: req.body});
if (articleCount === 0) return res.status(400).json({message: "Article does not exist"});
// Delete the article
await Article.destroy({where: req.body});
res.status(200).json({message: "Article deleted successfully"});
});
app.get("/:articleId", checkPermission("admin.article.info"), async (req, res) => {
// Validate request
if (!req.params.articleId) return res.status(400).json({message: "Missing article id"});
// Get the article information
const info = await Article.findByPk(req.params.articleId);
if (info) {
res.status(200).json(info);
} else res.status(404).json({message: "Article not found"});
});
app.get("/:moduleName/list", checkPermission("articles.list"), async (req, res) => {
// Validate request
if (!req.params.moduleName) return res.status(400).json({message: "Module name is required"});
// Get the article
const list = await Article.findAndCountAll({where: {moduleName: req.params.moduleName}});
if (list) {
res.status(200).json(list.rows);
} else res.status(404).json({message: "No articles found"});
});
app.get("/:moduleName/:articleId", checkPermission("admin.article.info"), async (req, res) => {
// Validate request
if (!req.params.moduleName) return res.status(400).json({message: "Missing module name"});
if (!req.params.articleId) return res.status(400).json({message: "Missing article id"});
// Get the article information
const info = await Article.findOne({where: {moduleName: req.params.moduleName, articleId: req.params.articleId}});
if (info) {
res.status(200).json(info);
} else res.status(404).json({message: "Article not found"});
});
module.exports = app;

View File

@ -0,0 +1,57 @@
const app = require('express').Router();
const qs = require("qs");
const axios = require('axios');
const crypto = require("crypto");
const Account = require("../models/Account");
const Session = require("../models/Session");
app.post("/token", async (req, res) => {
// Check if code is valid
if (!req.body.code) return res.status(400).json({message: "You need to provide a code"});
try {
// Get access & refresh token
const tokens = await axios.post(DISCORD_TOKEN_ENDPOINT, qs.stringify({
"code": req.body.code, "grant_type": "authorization_code", "client_secret": process.env.CLIENT_SECRET,
"client_id": process.env.CLIENT_ID, "redirect_uri": process.env.REDIRECT_URI
}));
// Check if all scopes are provided
if (tokens.data.scope !== "identify email guilds") throw "Not all scopes were specified";
// Get user data
const {data} = await axios.get(DISCORD_USER_ENDPOINT, {
headers: {Authorization: "Bearer " + tokens.data.access_token}
});
//Check if account exists
const account = await Account.findAndCountAll({where: {client_id: data.id}});
// Define user data
userData = {client_id: data.id, username: data.username+"#"+data.discriminator,
email: data.email, locale: data.locale, avatar: data.avatar};
// Create/update account
if (account.count === 1)
await Account.update(userData,{where: {client_id: data.id}});
else await Account.create(userData);
// Generate random token
const token = crypto.randomBytes(48).toString('hex');
// Create session
await Session.create({
token: token, client_id: data.id, access_token: tokens.data.access_token, refresh_token: tokens.data.refresh_token,
user_agent: req.get("user-agent")
});
// Return token
res.status(200).json({token: token});
} catch (e) {
res.status(400).json({message: "Something went wrong"});
}
});
module.exports = app;

View File

@ -0,0 +1,135 @@
const app = require('express').Router();
const crypto = require('crypto');
const checkPermission = require("../middlewares/checkPermission");
const giftValidation = require("../validation/giftValidation");
const Article = require("../models/Article");
const Gift = require("../models/Gift");
const ActivatedArticle = require("../models/ActivatedArticle");
app.put("/", checkPermission("admin.gift.create"), async (req, res) => {
// Validate request
const {error} = giftValidation.create.validate(req.body);
if (error) return res.status(400).json({message: error.details[0].message});
// Set optional fields
const giftID = (req.body.giftID || crypto.randomBytes(15).toString("hex")).toUpperCase();
const expiry_date = new Date(req.body.expiry_date || new Date("4000-01-01"));
const item_expiry_date = new Date(req.body.item_expiry_date || new Date("4000-01-01"));
// Check if article exists
const {count: articleCount} = await Article.findAndCountAll({where: {id: req.body.articleID}});
if (articleCount === 0) return res.status(400).json({message: "Article does not exist"});
// Check if code already exists
const {count: codeCount} = await Gift.findAndCountAll({where: {giftID: giftID}});
if (codeCount === 1) return res.status(400).json({message: "Code already exists"});
// Create gift
await Gift.create({
giftID: giftID,
articleID: req.body.articleID,
expiry_date: expiry_date,
item_expiry_date: item_expiry_date
});
// Return gift
res.status(200).json({
giftID: giftID, articleID: req.body.articleID,
expiry_date: expiry_date.toISOString(), item_expiry_date: item_expiry_date.toISOString()
});
});
app.get("/:giftID", checkPermission("admin.gift.info"), async (req, res) => {
// Validate request
if (!req.params.giftID) return res.status(400).json({message: "Gift ID is required"});
// Check if code is in database
const giftInfo = await Gift.findOne({where: {giftID: req.params.giftID}});
// Return info
if (giftInfo)
res.status(200).json(giftInfo);
else res.status(404).json({message: "Gift not found"});
});
app.delete("/:giftID", checkPermission("admin.gift.delete"), async (req, res) => {
// Validate request
if (!req.params.giftID) return res.status(400).json({message: "Gift ID is required"});
// Check if code exists
const {count} = await Gift.findAndCountAll({where: {giftID: req.params.giftID}});
if (count === 0) return res.status(400).json({message: "Gift not found"});
// Delete code
await Gift.destroy({where: {giftID: req.params.giftID}});
// Send response
res.status(200).json({message: "Gift successfully deleted"});
});
app.patch("/", checkPermission("admin.gift.update"), async (req, res) => {
// Validate request
const {error} = giftValidation.update.validate(req.body);
if (error) return res.status(400).json({message: error.details[0].message});
// Check if code exists
const {count} = await Gift.findAndCountAll({where: {giftID: req.body.giftID}});
if (count === 0) return res.status(400).json({message: "Gift not found"});
// Add changes to object
const updatedGift = {};
if (req.body.articleID) {
// Check if article exists
const {count: articleCount} = await Article.findAndCountAll({where: {articleID: req.body.articleID}});
if (articleCount === 0) return res.status(400).json({message: "Article does not exist"});
updatedGift["articleID"] = req.body.articleID;
}
if (req.body.expiry_date) updatedGift["expiry_date"] = req.body.expiry_date;
if (req.body.item_expiry_date) updatedGift["item_expiry_date"] = req.body.item_expiry_date;
// Update
await Gift.update(updatedGift, {where: {giftID: req.body.giftID}});
// Send response
res.status(200).json({message: "Gift updated successfully"});
});
app.post("/redeem", async (req, res) => {
// Validate request
const {error} = giftValidation.redeem.validate(req.body);
if (error) return res.status(400).json({message: error.details[0].message});
// Check if code is in database
const giftInfo = await Gift.findOne({where: {giftID: req.body.giftID}});
// Check if gift exists
if (!giftInfo) return res.status(404).json({message: "Gift not found"});
// Get the article
const article = await Article.findOne({where: {id: giftInfo.articleID}});
// Check if article limit reached
const {count} = await ActivatedArticle.findAndCountAll({
where: {
articleID: giftInfo.articleID,
guildID: req.body.guildID
}
});
if (count >= article.maxOwnCount) return res.status(400).json({message: "Maximum limit of this item reached"});
// Redeem article
await ActivatedArticle.create({
articleID: giftInfo.articleID,
expiry_date: giftInfo.item_expiry_date,
guildID: req.body.guildID
});
await Gift.destroy({where: {giftID: req.body.giftID}});
// Send response
res.json({message: "Article successfully redeemed"});
});
module.exports = app;

View File

@ -0,0 +1,51 @@
const app = require('express').Router();
const crypto = require("crypto");
const checkPermission = require("../middlewares/checkPermission");
const ShortenedLink = require("../models/ShortenedLink");
const linkValidation = require("../validation/linkValidation");
app.put("/", checkPermission("url.create"), async (req, res) => {
// Validate request
const {error} = linkValidation.short.validate(req.body);
if (error) return res.status(400).json({message: error.details[0].message});
// Set optional fields
req.body.shorten_url = req.body.custom_url || crypto.randomBytes(3).toString('hex');
// Check if shorten url exists
const {count} = await ShortenedLink.findAndCountAll({where: {shorten_url: req.body.shorten_url}});
if (count === 1) return res.status(400).json({message: "URL already exists"});
// Create the link
await ShortenedLink.create(req.body);
// Return the response
res.status(200).json({message: "Link successfully created", "shorten_url": req.body.shorten_url});
});
app.delete("/:code", checkPermission("url.delete"), async (req, res) => {
if (!req.params.code) return res.status(400).json({message: "You need to provide the shorten url code"});
// Search for the link
const link = await ShortenedLink.findOne({where: {shorten_url: req.params.code}});
if (link) {
// Destroy the link
await ShortenedLink.destroy({where: {shorten_url: req.params.code}});
// Return response
res.status(200).json({message: "Link successfully deleted"});
} else res.status(404).json({message: "Link not found"});
});
app.get("/:code", checkPermission("url.info"), async (req, res) => {
if (!req.params.code) return res.status(400).json({message: "You need to provide the shorten url code"});
// Search the link
const link = await ShortenedLink.findOne({where: {shorten_url: req.params.code}});
if (link) {
// Return response
res.status(200).json(link);
} else res.status(404).json({message: "Link not found"});
})
module.exports = app;

View File

@ -0,0 +1,72 @@
const app = require('express').Router();
const fs = require('fs');
const checkPermission = require("../middlewares/checkPermission");
const mediaValidation = require("../validation/mediaValidation");
const crypto = require('crypto');
const Media = require("../models/Media");
app.put("/", checkPermission("admin.media.upload"), async (req, res) => {
// Validate request
const {error} = mediaValidation.upload.validate(req.body);
if (error) return res.status(400).json({message: error.details[0].message});
// Check if file was provided
if (req.files && req.files.asset) {
const asset = req.files.asset;
const assetID = crypto.randomBytes(8).toString('hex');
const splittedAsset = asset.name.split(".");
const assetEnding = splittedAsset[splittedAsset.length - 1];
// Check if the asset exists
const {count: assetCount} = await Media.findAndCountAll({where: {assetID: assetID}});
if (assetCount === 1) return res.status(400).json({message: "This asset already exists"});
// Create the asset
await Media.create({
assetID: assetID, assetCreator: req.token, assetEnding: assetEnding,
assetName: asset.name, assetDescription: req.body.assetDescription
});
// Move the asset to the upload directory
await req.files.asset.mv(process.env.CDN_MEDIA_PATH + "/" + assetID);
// Send response
res.status(200).json({
message: "Asset successfully uploaded", id: assetID,
url: "https://cdn.sheepstar.xyz/" + assetID + "." + assetEnding
});
} else res.status(400).json({message: "You must provide an asset"});
});
app.delete("/:assetID", checkPermission("admin.media.delete"), async (req, res) => {
// Validate request
if (!req.params.assetID) return res.status(400).json({message: "You must provide an asset ID"});
// Check if asset exists
const {count} = await Media.findAndCountAll({where: {assetID: req.params.assetID}});
if (count === 0) res.status(404).json({message: "The provided asset does not exist."});
// Delete asset
try {
fs.unlinkSync(process.env.CDN_MEDIA_PATH + "/" + req.params.assetID);
await Media.destroy({where: {assetID: req.params.assetID}});
} catch (e) {
return res.status(500).json({message: "The provided asset could not be deleted"});
}
res.status(200).json({message: "Asset successfully deleted"});
});
app.get("/:assetID", checkPermission("admin.media.info"), async (req, res) => {
// Validate request
if (!req.params.assetID) return res.status(400).json({message: "You must provide an asset ID"});
// Check if asset exists
const {count, rows} = await Media.findAndCountAll({where: {assetID: req.params.assetID}});
if (count === 0) res.status(404).json({message: "The provided asset does not exist."});
// Return response
res.status(200).json(rows);
});
module.exports = app;

View File

@ -0,0 +1,81 @@
const app = require('express').Router();
const checkPermission = require("../middlewares/checkPermission");
const shopValidation = require("../validation/shopValidation");
const Article = require("../models/Article");
const ActivatedArticle = require("../models/ActivatedArticle");
const {owns} = require("../validation/shopValidation");
app.get("/", checkPermission("shop.info"), async (req, res) => {
// Validate request
const {error} = shopValidation.info.validate(req.query);
if (error) return res.status(400).json({message: error.details[0].message});
// Get article info
const info = await ActivatedArticle.findAndCountAll({where: req.query});
// Return info
if (info) {
res.status(200).json(info.rows);
} else res.json(404).json({message: "Article not found"});
});
app.get("/owns", checkPermission("shop.info"), async (req, res) => {
// Validate request
const {error} = shopValidation.owns.validate(req.query);
if (error) return res.status(400).json({message: error.details[0].message});
if (await Article.findByPk(req.query.articleID) === null) return res.status(404).json({message: "Article not found"});
// Get the article information
const info = await ActivatedArticle.findOne({
where: {
articleID: req.query.articleID,
guildID: req.query.guildID
}
});
const premiumInfo = await ActivatedArticle.findOne({
where: {
articleID: 1,
guildID: req.query.guildID
}
});
res.status(200).json(info !== null || premiumInfo !== null);
});
app.delete("/", checkPermission("shop.delete"), async (req, res) => {
// Validate request
const {error} = shopValidation.owns.validate(req.body);
if (error) return res.status(400).json({message: error.details[0].message});
// Check if already exists
const {count: articleCount} = await ActivatedArticle.findAndCountAll({where: req.body});
if (articleCount === 0) return res.status(400).json({message: "Article does not exist"});
// Delete the article
await ActivatedArticle.destroy({where: req.body});
res.status(200).json({message: "Article deleted successfully"});
});
app.put("/", checkPermission("shop.buy"), async (req, res) => {
// Validate request
const {error} = shopValidation.buy.validate(req.body);
if (error) return res.status(400).json({message: error.details[0].message});
// Check if article exists
const article = await Article.findByPk(req.body.articleID);
if (!article) return res.status(404).json({message: "Article does not exist"});
if (!req.body.expiry_date) req.body.expiry_date = new Date("4000-01-01");
// Check if article limit reached
const {count} = await ActivatedArticle.findAndCountAll({where: req.body});
if (count >= article.maxOwnCount) return res.status(400).json({message: "Maximum limit of this item reached"});
res.status(200).json(await ActivatedArticle.create(req.body));
});
module.exports = app;

View File

@ -0,0 +1,17 @@
const app = require('express').Router();
const axios = require('axios');
const {refreshToken} = require("../lib/discord");
app.get("/guilds", async (req, res) => {
const accessToken = await refreshToken(req.token);
try {
const {data} = await axios.get(DISCORD_USER_GUILDS_ENDPOINT, {
headers: {Authorization: "Bearer " + accessToken}
});
res.status(200).json(data);
} catch (e) {
res.status(500).json({message: "Something went wrong"});
}
});
module.exports = app;