Add util for assigning req-ktchi-data

This commit is contained in:
zkldi
2021-05-26 17:24:42 +01:00
parent 3e0920e089
commit 6671323ff3
6 changed files with 132 additions and 8 deletions
+1 -2
View File
@@ -26,8 +26,7 @@ export function CreateAPIKey(): string {
}
/**
* Despite these functions doing ultimately the same thing, they're separate incase they ever need to,
* you know, not do that.
* Despite these functions doing ultimately the same thing, they're separate incase they ever need to return something different.
* @returns A string
*/
export function CreateInviteCode(): string {
@@ -0,0 +1,41 @@
import { GenericAuthDocument } from "kamaitachi-common";
import { RequestHandler } from "express";
import db from "../../../../external/mongo/db";
import { SYMBOL_KtchiData } from "../../../../lib/constants/ktchi";
import { SplitAuthorizationHeader } from "../../../../utils/misc";
import { AssignToReqKtchiData } from "../../../../utils/req-ktchi-data";
const ValidateAuthToken: RequestHandler = async (req, res, next) => {
const header = req.header("Authorization");
if (!header) {
return res.status(400).json({
success: false,
description: `No Authorization provided.`,
});
}
const { type, token } = SplitAuthorizationHeader(header);
if (type !== "Bearer") {
return res.status(400).json({
success: false,
description: `Invalid Authorization Type.`,
});
}
const beatorajaAuthDoc = (await db["beatoraja-auth-tokens"].find({
token,
})) as GenericAuthDocument | null;
if (!beatorajaAuthDoc) {
return res.status(401).json({
success: false,
description: "Unauthorised.",
});
}
AssignToReqKtchiData(req, { beatorajaAuthDoc });
return next();
};
@@ -1,11 +1,31 @@
import { PBScoreDocument } from "kamaitachi-common";
import { Router } from "express";
import { ChartDocument, PBScoreDocument } from "kamaitachi-common";
import { Router, RequestHandler } from "express";
import db from "../../../../../external/mongo/db";
import { SYMBOL_KtchiData } from "../../../../../lib/constants/ktchi";
import { KtchiPBScoreToBeatorajaFormat } from "./convert-scores";
import { AssignToReqKtchiData } from "../../../../../utils/req-ktchi-data";
const router: Router = Router({ mergeParams: true });
const GetChartDocument: RequestHandler = async (req, res, next) => {
const chart = (await db.charts.bms.findOne({
"data.chartSHA256": req.params.chartSHA256,
})) as ChartDocument<"bms:7K" | "bms:14K"> | null;
if (!chart) {
return res.status(404).json({
success: false,
description: `Chart does not exist on IR yet.`,
});
}
AssignToReqKtchiData(req, { beatorajaChartDoc: chart });
return next();
};
router.use(GetChartDocument);
/**
* Retrieves scores for the given chart.
* @name GET /ir/beatoraja/chart/:chartSHA256/scores
@@ -1,20 +1,63 @@
import { Router } from "express";
import db from "../../../../external/mongo/db";
import { Random20Hex } from "../../../../utils/misc";
import { PRIVATEINFO_GetUserCaseInsensitive } from "../../../../utils/user";
import prValidate from "../../../middleware/prudence-validate";
import { PasswordCompare } from "../../api/v1/auth/auth";
import chartsRouter from "./charts/router";
import coursesRouter from "./courses/router";
const router: Router = Router({ mergeParams: true });
/**
* Takes a username and password and returns a unique auth token for the user
* to make ir requests with.
* @name POST /ir/beatoraja/login
*/
router.post(
"/auth/login",
"/login",
prValidate({
username: "string",
password: "string",
}),
async (req, res) => {}
async (req, res) => {
const userDoc = await PRIVATEINFO_GetUserCaseInsensitive(req.body.username);
if (!userDoc) {
return res.status(404).json({
success: false,
description: `The user ${req.body.username} does not exist.`,
});
}
const validPassword = PasswordCompare(req.body.password, userDoc.password);
if (!validPassword) {
return res.status(401).json({
success: false,
description: `Invalid password.`,
});
}
// User is who they claim to be.
const token = Random20Hex();
await db["beatoraja-auth-tokens"].insert({
userID: userDoc.id,
token,
});
return res.status(200).json({
success: true,
description: `Successfully created auth token.`,
body: {
token,
},
});
}
);
router.use("/charts/:chartSHA256", chartsRouter);
router.use("/courses/:courseSHA256", coursesRouter);
export default router;
+9
View File
@@ -37,3 +37,12 @@ export function MStoS(ms: number) {
export function RFA(arr: unknown[]) {
return arr[Math.floor(Math.random() * arr.length)];
}
/**
* Splits an Authorization header into the token and the type.
*/
export function SplitAuthorizationHeader(authHeader: string) {
const parts = authHeader.split(" ");
return { type: parts[0], token: parts.slice(1).join(" ") };
}
+12
View File
@@ -0,0 +1,12 @@
import { SYMBOL_KtchiData } from "../lib/constants/ktchi";
import { Request } from "express";
import { KtchiRequestData } from "./types";
import deepmerge from "deepmerge";
export function AssignToReqKtchiData(req: Request, data: Partial<KtchiRequestData>) {
if (!req[SYMBOL_KtchiData]) {
req[SYMBOL_KtchiData] = data;
} else {
req[SYMBOL_KtchiData] = deepmerge(req[SYMBOL_KtchiData]!, data);
}
}