diff options
author | Puyodead1 <puyodead@proton.me> | 2022-12-23 18:34:36 -0500 |
---|---|---|
committer | Puyodead1 <puyodead@proton.me> | 2023-03-18 19:27:39 -0400 |
commit | 0db1fa5f0b2b9b357c1f96178c0e5df7858a99ab (patch) | |
tree | b045eee5f984a40ae47413bad2458cf65eff3c8e /src/api | |
parent | Don't try to upload entire config for each connection loaded (diff) | |
download | server-0db1fa5f0b2b9b357c1f96178c0e5df7858a99ab.tar.xz |
Refreshable connections, refactoring, access-token endpoint
- Aded /users/@me/connections/:connection_name/:connection_id/access-token - Replaced `access_token` property on ConnectedAccount with `token_data` object for refreshing tokens - Made a common interface for connection things like ComonOAuthTokenResponse - Added `RefreshableConnection` class - Added token refresh to Spotify connection (disabled)
Diffstat (limited to 'src/api')
-rw-r--r-- | src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts | 84 | ||||
-rw-r--r-- | src/api/routes/users/@me/connections/index.ts | 2 |
2 files changed, 85 insertions, 1 deletions
diff --git a/src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts b/src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts new file mode 100644 index 00000000..8d51a770 --- /dev/null +++ b/src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts @@ -0,0 +1,84 @@ +import { route } from "@fosscord/api"; +import { + ApiError, + ConnectedAccount, + ConnectionStore, + DiscordApiErrors, + FieldErrors, +} from "@fosscord/util"; +import { Request, Response, Router } from "express"; +import RefreshableConnection from "../../../../../../../util/connections/RefreshableConnection"; +const router = Router(); + +// TODO: this route is only used for spotify, twitch, and youtube. (battlenet seems to be able to PUT, maybe others also) + +// spotify is disabled here because it cant be used +const ALLOWED_CONNECTIONS = ["twitch", "youtube"]; + +router.get("/", route({}), async (req: Request, res: Response) => { + // TODO: get the current access token or refresh it if it's expired + const { connection_name, connection_id } = req.params; + + const connection = ConnectionStore.connections.get(connection_id); + + if (!ALLOWED_CONNECTIONS.includes(connection_name) || !connection) + throw FieldErrors({ + provider_id: { + code: "BASE_TYPE_CHOICES", + message: req.t("common:field.BASE_TYPE_CHOICES", { + types: ALLOWED_CONNECTIONS.join(", "), + }), + }, + }); + + if (!connection.settings.enabled) + throw FieldErrors({ + provider_id: { + message: "This connection has been disabled server-side.", + }, + }); + + const connectedAccount = await ConnectedAccount.findOne({ + where: { + type: connection_name, + id: connection_id, + user_id: req.user_id, + }, + select: [ + "external_id", + "type", + "name", + "verified", + "visibility", + "show_activity", + "revoked", + "token_data", + "friend_sync", + "integrations", + ], + }); + if (!connectedAccount) throw DiscordApiErrors.UNKNOWN_CONNECTION; + if (connectedAccount.revoked) + throw new ApiError("Connection revoked", 0, 400); + if (!connectedAccount.token_data) + throw new ApiError("No token data", 0, 400); + + let access_token = connectedAccount.token_data.access_token; + const { expires_at, expires_in } = connectedAccount.token_data; + + if (expires_at && expires_at < Date.now()) { + if (!(connection instanceof RefreshableConnection)) + throw new ApiError("Access token expired", 0, 400); + const tokenData = await connection.refresh(connectedAccount); + access_token = tokenData.access_token; + } else if (expires_in && expires_in < Date.now()) { + if (!(connection instanceof RefreshableConnection)) + throw new ApiError("Access token expired", 0, 400); + const tokenData = await connection.refresh(connectedAccount); + access_token = tokenData.access_token; + } + + res.json({ access_token }); +}); + +export default router; diff --git a/src/api/routes/users/@me/connections/index.ts b/src/api/routes/users/@me/connections/index.ts index a5041be1..8e762f19 100644 --- a/src/api/routes/users/@me/connections/index.ts +++ b/src/api/routes/users/@me/connections/index.ts @@ -35,7 +35,7 @@ router.get("/", route({}), async (req: Request, res: Response) => { "visibility", "show_activity", "revoked", - "access_token", + "token_data", "friend_sync", "integrations", ], |