contrition/src/controllers/Info.ts

67 lines
2.0 KiB
TypeScript

import { Request, Response } from "express";
import { DiscordCache } from "../entity/DiscordCache";
import { DiscordToken } from "../entity/DiscordToken";
import { Guild } from "../entity/Guild";
import { fail, respond } from "./Util";
/**
* info handles requests for users to get their information. In in this
* situation, this handler authenticates the user credentials, and then returns
* the following information:
*
* - Discord ID
* - Discord Username#Discriminator
* - Discord Profile picture
* - Registered platforms that can be appealed to at the moment
*
* @route /api/info
*
*/
export const info = async (req: Request, res: Response) => {
const { token } = req.body;
// enforce valid request body
if (!(typeof token === "string")) {
return fail(res, 400, "Invalid request body");
}
// if the token is bad, the user is not correctly authenticating
const discordToken = await DiscordToken.findOne({ where: { id: token } });
if (!discordToken) {
return fail(res, 400, "Invalid token provided");
}
// DiscordCache checks to see if the information for the user is in our
// database. If it's not, then it queries it, automatically caches it, and
// then returns it.
let cache: DiscordCache;
try {
cache = await discordToken.queryData();
} catch ({ status, reason }) {
fail(res, status, reason);
return;
}
// Get the registered guilds that can be appealed to. This data is combined
// with the cached information to be returned to the user.
let platforms: Guild[];
try {
platforms = await Guild.all();
} catch (err) {
console.error("Could not fetch guilds", err);
return fail(res, 500, "An internal error occurred.");
}
// Create the JSON response data, and return it to the caller.
respond(res, {
id: cache.userID,
username: cache.username,
discriminator: cache.discriminator,
avatar: cache.avatar,
platforms: platforms.map((g) => ({
name: g.name,
id: g.id,
})),
});
};