From 3335f16ad1a6ec114058a8b7e6e71c2cae33c33d Mon Sep 17 00:00:00 2001 From: Puyodead1 Date: Thu, 23 Mar 2023 11:01:38 -0400 Subject: applications --- src/api/routes/applications/#id/bot/index.ts | 124 +++++++++++++-------- src/api/routes/applications/#id/entitlements.ts | 22 +++- src/api/routes/applications/#id/index.ts | 91 ++++++++++----- src/api/routes/applications/#id/skus.ts | 18 ++- src/api/routes/applications/detectable.ts | 20 +++- src/api/routes/applications/index.ts | 37 ++++-- src/api/util/handlers/route.ts | 3 +- .../responses/ApplicationDetectableResponse.ts | 1 + .../responses/ApplicationEntitlementsResponse.ts | 1 + .../schemas/responses/ApplicationSkusResponse.ts | 1 + src/util/schemas/responses/ApplicationsResponse.ts | 3 + src/util/schemas/responses/index.ts | 4 + 12 files changed, 227 insertions(+), 98 deletions(-) create mode 100644 src/util/schemas/responses/ApplicationDetectableResponse.ts create mode 100644 src/util/schemas/responses/ApplicationEntitlementsResponse.ts create mode 100644 src/util/schemas/responses/ApplicationSkusResponse.ts create mode 100644 src/util/schemas/responses/ApplicationsResponse.ts (limited to 'src') diff --git a/src/api/routes/applications/#id/bot/index.ts b/src/api/routes/applications/#id/bot/index.ts index e3f1832c..1df7fba0 100644 --- a/src/api/routes/applications/#id/bot/index.ts +++ b/src/api/routes/applications/#id/bot/index.ts @@ -16,78 +16,114 @@ along with this program. If not, see . */ -import { Request, Response, Router } from "express"; import { route } from "@spacebar/api"; import { Application, - generateToken, - User, BotModifySchema, - handleFile, DiscordApiErrors, + User, + generateToken, + handleFile, } from "@spacebar/util"; +import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; import { verifyToken } from "node-2fa"; const router: Router = Router(); -router.post("/", route({}), async (req: Request, res: Response) => { - const app = await Application.findOneOrFail({ - where: { id: req.params.id }, - relations: ["owner"], - }); +router.post( + "/", + route({ + responses: { + 200: { + body: "TokenResponse", + }, + 400: { + body: "APIErrorResponse", + }, + }, + }), + async (req: Request, res: Response) => { + const app = await Application.findOneOrFail({ + where: { id: req.params.id }, + relations: ["owner"], + }); - if (app.owner.id != req.user_id) - throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; + if (app.owner.id != req.user_id) + throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; - const user = await User.register({ - username: app.name, - password: undefined, - id: app.id, - req, - }); + const user = await User.register({ + username: app.name, + password: undefined, + id: app.id, + req, + }); - user.id = app.id; - user.premium_since = new Date(); - user.bot = true; + user.id = app.id; + user.premium_since = new Date(); + user.bot = true; - await user.save(); + await user.save(); - // flags is NaN here? - app.assign({ bot: user, flags: app.flags || 0 }); + // flags is NaN here? + app.assign({ bot: user, flags: app.flags || 0 }); - await app.save(); + await app.save(); - res.send({ - token: await generateToken(user.id), - }).status(204); -}); + res.send({ + token: await generateToken(user.id), + }).status(204); + }, +); -router.post("/reset", route({}), async (req: Request, res: Response) => { - const bot = await User.findOneOrFail({ where: { id: req.params.id } }); - const owner = await User.findOneOrFail({ where: { id: req.user_id } }); +router.post( + "/reset", + route({ + responses: { + 200: { + body: "TokenResponse", + }, + 400: { + body: "APIErrorResponse", + }, + }, + }), + async (req: Request, res: Response) => { + const bot = await User.findOneOrFail({ where: { id: req.params.id } }); + const owner = await User.findOneOrFail({ where: { id: req.user_id } }); - if (owner.id != req.user_id) - throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; + if (owner.id != req.user_id) + throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; - if ( - owner.totp_secret && - (!req.body.code || verifyToken(owner.totp_secret, req.body.code)) - ) - throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); + if ( + owner.totp_secret && + (!req.body.code || verifyToken(owner.totp_secret, req.body.code)) + ) + throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); - bot.data = { hash: undefined, valid_tokens_since: new Date() }; + bot.data = { hash: undefined, valid_tokens_since: new Date() }; - await bot.save(); + await bot.save(); - const token = await generateToken(bot.id); + const token = await generateToken(bot.id); - res.json({ token }).status(200); -}); + res.json({ token }).status(200); + }, +); router.patch( "/", - route({ body: "BotModifySchema" }), + route({ + body: "BotModifySchema", + responses: { + 200: { + body: "Application", + }, + 400: { + body: "APIErrorResponse", + }, + }, + }), async (req: Request, res: Response) => { const body = req.body as BotModifySchema; if (!body.avatar?.trim()) delete body.avatar; diff --git a/src/api/routes/applications/#id/entitlements.ts b/src/api/routes/applications/#id/entitlements.ts index e88fb7f7..6388e6b3 100644 --- a/src/api/routes/applications/#id/entitlements.ts +++ b/src/api/routes/applications/#id/entitlements.ts @@ -16,15 +16,25 @@ along with this program. If not, see . */ -import { Router, Response, Request } from "express"; import { route } from "@spacebar/api"; +import { Request, Response, Router } from "express"; const router = Router(); -router.get("/", route({}), (req: Request, res: Response) => { - // TODO: - //const { exclude_consumed } = req.query; - res.status(200).send([]); -}); +router.get( + "/", + route({ + responses: { + 200: { + body: "ApplicationEntitlementsResponse", + }, + }, + }), + (req: Request, res: Response) => { + // TODO: + //const { exclude_consumed } = req.query; + res.status(200).send([]); + }, +); export default router; diff --git a/src/api/routes/applications/#id/index.ts b/src/api/routes/applications/#id/index.ts index 067f5dad..dec2a9b1 100644 --- a/src/api/routes/applications/#id/index.ts +++ b/src/api/routes/applications/#id/index.ts @@ -16,32 +16,55 @@ along with this program. If not, see . */ -import { Request, Response, Router } from "express"; import { route } from "@spacebar/api"; import { Application, - DiscordApiErrors, ApplicationModifySchema, + DiscordApiErrors, } from "@spacebar/util"; -import { verifyToken } from "node-2fa"; +import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; +import { verifyToken } from "node-2fa"; const router: Router = Router(); -router.get("/", route({}), async (req: Request, res: Response) => { - const app = await Application.findOneOrFail({ - where: { id: req.params.id }, - relations: ["owner", "bot"], - }); - if (app.owner.id != req.user_id) - throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; +router.get( + "/", + route({ + responses: { + 200: { + body: "Application", + }, + 400: { + body: "APIErrorResponse", + }, + }, + }), + async (req: Request, res: Response) => { + const app = await Application.findOneOrFail({ + where: { id: req.params.id }, + relations: ["owner", "bot"], + }); + if (app.owner.id != req.user_id) + throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; - return res.json(app); -}); + return res.json(app); + }, +); router.patch( "/", - route({ body: "ApplicationModifySchema" }), + route({ + body: "ApplicationModifySchema", + responses: { + 200: { + body: "Application", + }, + 400: { + body: "APIErrorResponse", + }, + }, + }), async (req: Request, res: Response) => { const body = req.body as ApplicationModifySchema; @@ -73,23 +96,35 @@ router.patch( }, ); -router.post("/delete", route({}), async (req: Request, res: Response) => { - const app = await Application.findOneOrFail({ - where: { id: req.params.id }, - relations: ["bot", "owner"], - }); - if (app.owner.id != req.user_id) - throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; +router.post( + "/delete", + route({ + responses: { + 200: {}, + 400: { + body: "APIErrorResponse", + }, + }, + }), + async (req: Request, res: Response) => { + const app = await Application.findOneOrFail({ + where: { id: req.params.id }, + relations: ["bot", "owner"], + }); + if (app.owner.id != req.user_id) + throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; - if ( - app.owner.totp_secret && - (!req.body.code || verifyToken(app.owner.totp_secret, req.body.code)) - ) - throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); + if ( + app.owner.totp_secret && + (!req.body.code || + verifyToken(app.owner.totp_secret, req.body.code)) + ) + throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); - await Application.delete({ id: app.id }); + await Application.delete({ id: app.id }); - res.send().status(200); -}); + res.send().status(200); + }, +); export default router; diff --git a/src/api/routes/applications/#id/skus.ts b/src/api/routes/applications/#id/skus.ts index fcb75423..dc4fad23 100644 --- a/src/api/routes/applications/#id/skus.ts +++ b/src/api/routes/applications/#id/skus.ts @@ -16,13 +16,23 @@ along with this program. If not, see . */ -import { Request, Response, Router } from "express"; import { route } from "@spacebar/api"; +import { Request, Response, Router } from "express"; const router: Router = Router(); -router.get("/", route({}), async (req: Request, res: Response) => { - res.json([]).status(200); -}); +router.get( + "/", + route({ + responses: { + 200: { + body: "ApplicationSkusResponse", + }, + }, + }), + async (req: Request, res: Response) => { + res.json([]).status(200); + }, +); export default router; diff --git a/src/api/routes/applications/detectable.ts b/src/api/routes/applications/detectable.ts index a8e30894..5cf9d171 100644 --- a/src/api/routes/applications/detectable.ts +++ b/src/api/routes/applications/detectable.ts @@ -16,14 +16,24 @@ along with this program. If not, see . */ -import { Request, Response, Router } from "express"; import { route } from "@spacebar/api"; +import { Request, Response, Router } from "express"; const router: Router = Router(); -router.get("/", route({}), async (req: Request, res: Response) => { - //TODO - res.send([]).status(200); -}); +router.get( + "/", + route({ + responses: { + 200: { + body: "ApplicationDetectableResponse", + }, + }, + }), + async (req: Request, res: Response) => { + //TODO + res.send([]).status(200); + }, +); export default router; diff --git a/src/api/routes/applications/index.ts b/src/api/routes/applications/index.ts index 80a19aa8..2290414c 100644 --- a/src/api/routes/applications/index.ts +++ b/src/api/routes/applications/index.ts @@ -16,28 +16,45 @@ along with this program. If not, see . */ -import { Request, Response, Router } from "express"; import { route } from "@spacebar/api"; import { Application, ApplicationCreateSchema, - trimSpecial, User, + trimSpecial, } from "@spacebar/util"; +import { Request, Response, Router } from "express"; const router: Router = Router(); -router.get("/", route({}), async (req: Request, res: Response) => { - const results = await Application.find({ - where: { owner: { id: req.user_id } }, - relations: ["owner", "bot"], - }); - res.json(results).status(200); -}); +router.get( + "/", + route({ + responses: { + 200: { + body: "ApplicationsResponse", + }, + }, + }), + async (req: Request, res: Response) => { + const results = await Application.find({ + where: { owner: { id: req.user_id } }, + relations: ["owner", "bot"], + }); + res.json(results).status(200); + }, +); router.post( "/", - route({ body: "ApplicationCreateSchema" }), + route({ + body: "ApplicationCreateSchema", + responses: { + 200: { + body: "Application", + }, + }, + }), async (req: Request, res: Response) => { const body = req.body as ApplicationCreateSchema; const user = await User.findOneOrFail({ where: { id: req.user_id } }); diff --git a/src/api/util/handlers/route.ts b/src/api/util/handlers/route.ts index 66bd2890..04910ed4 100644 --- a/src/api/util/handlers/route.ts +++ b/src/api/util/handlers/route.ts @@ -55,7 +55,8 @@ export interface RouteOptions { body?: `${string}Schema`; // typescript interface name responses?: { [status: number]: { - body?: `${string}Response`; + // body?: `${string}Response`; + body?: string; }; }; test?: { diff --git a/src/util/schemas/responses/ApplicationDetectableResponse.ts b/src/util/schemas/responses/ApplicationDetectableResponse.ts new file mode 100644 index 00000000..958b8d43 --- /dev/null +++ b/src/util/schemas/responses/ApplicationDetectableResponse.ts @@ -0,0 +1 @@ +export type ApplicationDetectableResponse = unknown[]; diff --git a/src/util/schemas/responses/ApplicationEntitlementsResponse.ts b/src/util/schemas/responses/ApplicationEntitlementsResponse.ts new file mode 100644 index 00000000..1d2b349e --- /dev/null +++ b/src/util/schemas/responses/ApplicationEntitlementsResponse.ts @@ -0,0 +1 @@ +export type ApplicationEntitlementsResponse = unknown[]; diff --git a/src/util/schemas/responses/ApplicationSkusResponse.ts b/src/util/schemas/responses/ApplicationSkusResponse.ts new file mode 100644 index 00000000..8d577c92 --- /dev/null +++ b/src/util/schemas/responses/ApplicationSkusResponse.ts @@ -0,0 +1 @@ +export type ApplicationSkusResponse = unknown[]; diff --git a/src/util/schemas/responses/ApplicationsResponse.ts b/src/util/schemas/responses/ApplicationsResponse.ts new file mode 100644 index 00000000..fef3fbde --- /dev/null +++ b/src/util/schemas/responses/ApplicationsResponse.ts @@ -0,0 +1,3 @@ +import { Application } from "../../entities"; + +export type ApplicationsResponse = Application[]; diff --git a/src/util/schemas/responses/index.ts b/src/util/schemas/responses/index.ts index ed91b866..6dde4d24 100644 --- a/src/util/schemas/responses/index.ts +++ b/src/util/schemas/responses/index.ts @@ -1,5 +1,9 @@ export * from "./APIErrorOrCaptchaResponse"; export * from "./APIErrorResponse"; +export * from "./ApplicationDetectableResponse"; +export * from "./ApplicationEntitlementsResponse"; +export * from "./ApplicationSkusResponse"; +export * from "./ApplicationsResponse"; export * from "./BackupCodesChallengeResponse"; export * from "./CaptchaRequiredResponse"; export * from "./GenerateRegistrationTokensResponse"; -- cgit 1.4.1