From 21bfda32e452c05b8906bf318df7415d6cd5acd0 Mon Sep 17 00:00:00 2001 From: Puyodead1 Date: Thu, 22 Dec 2022 10:05:51 -0500 Subject: add connections --- src/api/middlewares/Authentication.ts | 2 + .../#connection_name/#connection_id/refresh.ts | 11 +++++ .../connections/#connection_name/authorize.ts | 35 +++++++++++++++ .../connections/#connection_name/callback.ts | 52 ++++++++++++++++++++++ src/api/routes/users/@me/connections.ts | 24 ++++++++-- 5 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 src/api/routes/connections/#connection_name/#connection_id/refresh.ts create mode 100644 src/api/routes/connections/#connection_name/authorize.ts create mode 100644 src/api/routes/connections/#connection_name/callback.ts (limited to 'src/api') diff --git a/src/api/middlewares/Authentication.ts b/src/api/middlewares/Authentication.ts index 771f0de8..55527984 100644 --- a/src/api/middlewares/Authentication.ts +++ b/src/api/middlewares/Authentication.ts @@ -52,6 +52,8 @@ export const NO_AUTHORIZATION_ROUTES = [ "/oauth2/callback", // Asset delivery /\/guilds\/\d+\/widget\.(json|png)/, + // Connections + /\/connections\/\w+\/callback/ ]; export const API_PREFIX = /^\/api(\/v\d+)?/; diff --git a/src/api/routes/connections/#connection_name/#connection_id/refresh.ts b/src/api/routes/connections/#connection_name/#connection_id/refresh.ts new file mode 100644 index 00000000..cce50436 --- /dev/null +++ b/src/api/routes/connections/#connection_name/#connection_id/refresh.ts @@ -0,0 +1,11 @@ +import { route } from "@fosscord/api"; +import { Request, Response, Router } from "express"; +const router = Router(); + +router.post("/", route({}), async (req: Request, res: Response) => { + // TODO: + const { connection_name, connection_id } = req.params; + res.sendStatus(204); +}); + +export default router; diff --git a/src/api/routes/connections/#connection_name/authorize.ts b/src/api/routes/connections/#connection_name/authorize.ts new file mode 100644 index 00000000..8e640a69 --- /dev/null +++ b/src/api/routes/connections/#connection_name/authorize.ts @@ -0,0 +1,35 @@ +import { Request, Response, Router } from "express"; +import { FieldErrors } from "../../../../util"; +import { ConnectionStore } from "../../../../util/connections"; +import { route } from "../../../util"; + +const router = Router(); + +router.get("/", route({}), async (req: Request, res: Response) => { + const { connection_id: connection_name } = req.params; + const connection = ConnectionStore.connections.get(connection_name); + if (!connection) + throw FieldErrors({ + provider_id: { + code: "BASE_TYPE_CHOICES", + message: req.t("common:field.BASE_TYPE_CHOICES", { + types: Array.from(ConnectionStore.connections.keys()).join( + ", ", + ), + }), + }, + }); + + if (!connection.settings.enabled) + throw FieldErrors({ + provider_id: { + message: "This connection has been disabled server-side.", + }, + }); + + res.json({ + url: await connection.getAuthorizationUrl(req.user_id), + }); +}); + +export default router; diff --git a/src/api/routes/connections/#connection_name/callback.ts b/src/api/routes/connections/#connection_name/callback.ts new file mode 100644 index 00000000..f158a037 --- /dev/null +++ b/src/api/routes/connections/#connection_name/callback.ts @@ -0,0 +1,52 @@ +import { Request, Response, Router } from "express"; +import { + ConnectionCallbackSchema, + emitEvent, + FieldErrors, +} from "../../../../util"; +import { ConnectionStore } from "../../../../util/connections"; +import { route } from "../../../util"; + +const router = Router(); + +router.post( + "/", + route({ body: "ConnectionCallbackSchema" }), + async (req: Request, res: Response) => { + const { connection_id: connection_name } = req.params; + const connection = ConnectionStore.connections.get(connection_name); + if (!connection) + throw FieldErrors({ + provider_id: { + code: "BASE_TYPE_CHOICES", + message: req.t("common:field.BASE_TYPE_CHOICES", { + types: Array.from( + ConnectionStore.connections.keys(), + ).join(", "), + }), + }, + }); + + if (!connection.settings.enabled) + throw FieldErrors({ + provider_id: { + message: "This connection has been disabled server-side.", + }, + }); + + const body = req.body as ConnectionCallbackSchema; + const userId = connection.getUserId(body.state); + const emit = await connection.handleCallback(body); + + // whether we should emit a connections update event, only used when a connection doesnt already exist + if (emit) + emitEvent({ + event: "USER_CONNECTIONS_UPDATE", + data: {}, + user_id: userId, + }); + res.sendStatus(204); + }, +); + +export default router; diff --git a/src/api/routes/users/@me/connections.ts b/src/api/routes/users/@me/connections.ts index 74315bfe..a5041be1 100644 --- a/src/api/routes/users/@me/connections.ts +++ b/src/api/routes/users/@me/connections.ts @@ -16,14 +16,32 @@ along with this program. If not, see . */ -import { Request, Response, Router } from "express"; import { route } from "@fosscord/api"; +import { ConnectedAccount, ConnectedAccountDTO } from "@fosscord/util"; +import { Request, Response, Router } from "express"; const router: Router = Router(); router.get("/", route({}), async (req: Request, res: Response) => { - //TODO - res.json([]).status(200); + const connections = await ConnectedAccount.find({ + where: { + user_id: req.user_id, + }, + select: [ + "external_id", + "type", + "name", + "verified", + "visibility", + "show_activity", + "revoked", + "access_token", + "friend_sync", + "integrations", + ], + }); + + res.json(connections.map((x) => new ConnectedAccountDTO(x, true))); }); export default router; -- cgit 1.5.1