diff --git a/src/api/routes/auth/forgot.ts b/src/api/routes/auth/forgot.ts
index e240dff2..7e1ba65a 100644
--- a/src/api/routes/auth/forgot.ts
+++ b/src/api/routes/auth/forgot.ts
@@ -30,7 +30,18 @@ const router = Router();
router.post(
"/",
- route({ body: "ForgotPasswordSchema" }),
+ route({
+ body: "ForgotPasswordSchema",
+ responses: {
+ 204: {},
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 500: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
const { login, captcha_key } = req.body as ForgotPasswordSchema;
diff --git a/src/api/routes/auth/generate-registration-tokens.ts b/src/api/routes/auth/generate-registration-tokens.ts
index 723875f8..48fe6421 100644
--- a/src/api/routes/auth/generate-registration-tokens.ts
+++ b/src/api/routes/auth/generate-registration-tokens.ts
@@ -16,7 +16,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { route, random } from "@spacebar/api";
+import { random, route } from "@spacebar/api";
import { Config, ValidRegistrationToken } from "@spacebar/util";
import { Request, Response, Router } from "express";
@@ -25,7 +25,10 @@ export default router;
router.get(
"/",
- route({ right: "OPERATOR" }),
+ route({
+ right: "OPERATOR",
+ responses: { 200: { body: "GenerateRegistrationTokensResponse" } },
+ }),
async (req: Request, res: Response) => {
const count = req.query.count ? parseInt(req.query.count as string) : 1;
const length = req.query.length
diff --git a/src/api/routes/auth/location-metadata.ts b/src/api/routes/auth/location-metadata.ts
index 52a45c67..28293e59 100644
--- a/src/api/routes/auth/location-metadata.ts
+++ b/src/api/routes/auth/location-metadata.ts
@@ -16,20 +16,29 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Request, Response } from "express";
-import { route } from "@spacebar/api";
-import { getIpAdress, IPAnalysis } from "@spacebar/api";
+import { IPAnalysis, getIpAdress, route } from "@spacebar/api";
+import { Request, Response, Router } from "express";
const router = Router();
-router.get("/", route({}), async (req: Request, res: Response) => {
- //TODO
- //Note: It's most likely related to legal. At the moment Discord hasn't finished this too
- const country_code = (await IPAnalysis(getIpAdress(req))).country_code;
- res.json({
- consent_required: false,
- country_code: country_code,
- promotional_email_opt_in: { required: true, pre_checked: false },
- });
-});
+router.get(
+ "/",
+ route({
+ responses: {
+ 200: {
+ body: "LocationMetadataResponse",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ //TODO
+ //Note: It's most likely related to legal. At the moment Discord hasn't finished this too
+ const country_code = (await IPAnalysis(getIpAdress(req))).country_code;
+ res.json({
+ consent_required: false,
+ country_code: country_code,
+ promotional_email_opt_in: { required: true, pre_checked: false },
+ });
+ },
+);
export default router;
diff --git a/src/api/routes/auth/login.ts b/src/api/routes/auth/login.ts
index fe0b4f99..729bd1cb 100644
--- a/src/api/routes/auth/login.ts
+++ b/src/api/routes/auth/login.ts
@@ -36,7 +36,17 @@ export default router;
router.post(
"/",
- route({ body: "LoginSchema" }),
+ route({
+ body: "LoginSchema",
+ responses: {
+ 200: {
+ body: "TokenResponse",
+ },
+ 400: {
+ body: "APIErrorOrCaptchaResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
const { login, password, captcha_key, undelete } =
req.body as LoginSchema;
diff --git a/src/api/routes/auth/logout.ts b/src/api/routes/auth/logout.ts
index 51909afa..94a3e474 100644
--- a/src/api/routes/auth/logout.ts
+++ b/src/api/routes/auth/logout.ts
@@ -22,14 +22,25 @@ import { Request, Response, Router } from "express";
const router: Router = Router();
export default router;
-router.post("/", route({}), async (req: Request, res: Response) => {
- if (req.body.provider != null || req.body.voip_provider != null) {
- console.log(`[LOGOUT]: provider or voip provider not null!`, req.body);
- } else {
- delete req.body.provider;
- delete req.body.voip_provider;
- if (Object.keys(req.body).length != 0)
- console.log(`[LOGOUT]: Extra fields sent in logout!`, req.body);
- }
- res.status(204).send();
-});
+router.post(
+ "/",
+ route({
+ responses: {
+ 204: {},
+ },
+ }),
+ async (req: Request, res: Response) => {
+ if (req.body.provider != null || req.body.voip_provider != null) {
+ console.log(
+ `[LOGOUT]: provider or voip provider not null!`,
+ req.body,
+ );
+ } else {
+ delete req.body.provider;
+ delete req.body.voip_provider;
+ if (Object.keys(req.body).length != 0)
+ console.log(`[LOGOUT]: Extra fields sent in logout!`, req.body);
+ }
+ res.status(204).send();
+ },
+);
diff --git a/src/api/routes/auth/mfa/totp.ts b/src/api/routes/auth/mfa/totp.ts
index 2396443d..0bfc2c52 100644
--- a/src/api/routes/auth/mfa/totp.ts
+++ b/src/api/routes/auth/mfa/totp.ts
@@ -16,16 +16,26 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
-import { BackupCode, generateToken, User, TotpSchema } from "@spacebar/util";
-import { verifyToken } from "node-2fa";
+import { BackupCode, TotpSchema, User, generateToken } from "@spacebar/util";
+import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
+import { verifyToken } from "node-2fa";
const router = Router();
router.post(
"/",
- route({ body: "TotpSchema" }),
+ route({
+ body: "TotpSchema",
+ responses: {
+ 200: {
+ body: "TokenResponse",
+ },
+ 400: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
// const { code, ticket, gift_code_sku_id, login_source } =
const { code, ticket } = req.body as TotpSchema;
diff --git a/src/api/routes/auth/mfa/webauthn.ts b/src/api/routes/auth/mfa/webauthn.ts
index 1b387411..e7278047 100644
--- a/src/api/routes/auth/mfa/webauthn.ts
+++ b/src/api/routes/auth/mfa/webauthn.ts
@@ -41,7 +41,13 @@ function toArrayBuffer(buf: Buffer) {
router.post(
"/",
- route({ body: "WebAuthnTotpSchema" }),
+ route({
+ body: "WebAuthnTotpSchema",
+ responses: {
+ 200: { body: "TokenResponse" },
+ 400: { body: "APIErrorResponse" },
+ },
+ }),
async (req: Request, res: Response) => {
if (!WebAuthn.fido2) {
// TODO: I did this for typescript and I can't use !
diff --git a/src/api/routes/auth/register.ts b/src/api/routes/auth/register.ts
index 430c9532..70acedcd 100644
--- a/src/api/routes/auth/register.ts
+++ b/src/api/routes/auth/register.ts
@@ -42,7 +42,13 @@ const router: Router = Router();
router.post(
"/",
- route({ body: "RegisterSchema" }),
+ route({
+ body: "RegisterSchema",
+ responses: {
+ 200: { body: "TokenResponse" },
+ 400: { body: "APIErrorOrCaptchaResponse" },
+ },
+ }),
async (req: Request, res: Response) => {
const body = req.body as RegisterSchema;
const { register, security, limits } = Config.get();
diff --git a/src/api/routes/auth/reset.ts b/src/api/routes/auth/reset.ts
index 852a43c7..9c17d2b0 100644
--- a/src/api/routes/auth/reset.ts
+++ b/src/api/routes/auth/reset.ts
@@ -31,9 +31,20 @@ import { Request, Response, Router } from "express";
const router = Router();
+// TODO: the response interface also returns settings, but this route doesn't actually return that.
router.post(
"/",
- route({ body: "PasswordResetSchema" }),
+ route({
+ body: "PasswordResetSchema",
+ responses: {
+ 200: {
+ body: "TokenResponse",
+ },
+ 400: {
+ body: "APIErrorOrCaptchaResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
const { password, token } = req.body as PasswordResetSchema;
diff --git a/src/api/routes/auth/verify/index.ts b/src/api/routes/auth/verify/index.ts
index c1afcde9..da92f256 100644
--- a/src/api/routes/auth/verify/index.ts
+++ b/src/api/routes/auth/verify/index.ts
@@ -37,9 +37,20 @@ async function getToken(user: User) {
return { token };
}
+// TODO: the response interface also returns settings, but this route doesn't actually return that.
router.post(
"/",
- route({ body: "VerifyEmailSchema" }),
+ route({
+ body: "VerifyEmailSchema",
+ responses: {
+ 200: {
+ body: "TokenResponse",
+ },
+ 400: {
+ body: "APIErrorOrCaptchaResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
const { captcha_key, token } = req.body;
diff --git a/src/api/routes/auth/verify/resend.ts b/src/api/routes/auth/verify/resend.ts
index f2727abd..215308ec 100644
--- a/src/api/routes/auth/verify/resend.ts
+++ b/src/api/routes/auth/verify/resend.ts
@@ -24,7 +24,14 @@ const router = Router();
router.post(
"/",
- route({ right: "RESEND_VERIFICATION_EMAIL" }),
+ route({
+ right: "RESEND_VERIFICATION_EMAIL",
+ responses: {
+ 204: {},
+ 400: {},
+ 500: {},
+ },
+ }),
async (req: Request, res: Response) => {
const user = await User.findOneOrFail({
where: { id: req.user_id },
diff --git a/src/api/routes/auth/verify/view-backup-codes-challenge.ts b/src/api/routes/auth/verify/view-backup-codes-challenge.ts
index b12719ff..63158d9d 100644
--- a/src/api/routes/auth/verify/view-backup-codes-challenge.ts
+++ b/src/api/routes/auth/verify/view-backup-codes-challenge.ts
@@ -16,15 +16,21 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
-import { FieldErrors, User, BackupCodesChallengeSchema } from "@spacebar/util";
+import { BackupCodesChallengeSchema, FieldErrors, User } from "@spacebar/util";
import bcrypt from "bcrypt";
+import { Request, Response, Router } from "express";
const router = Router();
router.post(
"/",
- route({ body: "BackupCodesChallengeSchema" }),
+ route({
+ body: "BackupCodesChallengeSchema",
+ responses: {
+ 200: { body: "BackupCodesChallengeResponse" },
+ 400: { body: "APIErrorResponse" },
+ },
+ }),
async (req: Request, res: Response) => {
const { password } = req.body as BackupCodesChallengeSchema;
diff --git a/src/api/util/handlers/route.ts b/src/api/util/handlers/route.ts
index 604df4e9..66bd2890 100644
--- a/src/api/util/handlers/route.ts
+++ b/src/api/util/handlers/route.ts
@@ -17,21 +17,21 @@
*/
import {
- ajv,
DiscordApiErrors,
EVENT,
FieldErrors,
- SpacebarApiErrors,
- getPermission,
- getRights,
- normalizeBody,
PermissionResolvable,
Permissions,
RightResolvable,
Rights,
+ SpacebarApiErrors,
+ ajv,
+ getPermission,
+ getRights,
+ normalizeBody,
} from "@spacebar/util";
-import { NextFunction, Request, Response } from "express";
import { AnyValidateFunction } from "ajv/dist/core";
+import { NextFunction, Request, Response } from "express";
declare global {
// TODO: fix this
@@ -53,6 +53,11 @@ export interface RouteOptions {
permission?: PermissionResolvable;
right?: RightResolvable;
body?: `${string}Schema`; // typescript interface name
+ responses?: {
+ [status: number]: {
+ body?: `${string}Response`;
+ };
+ };
test?: {
response?: RouteResponse;
body?: unknown;
|