summary refs log tree commit diff
path: root/src/connections
diff options
context:
space:
mode:
Diffstat (limited to 'src/connections')
-rw-r--r--src/connections/BattleNet/index.ts17
-rw-r--r--src/connections/Discord/index.ts16
-rw-r--r--src/connections/EpicGames/index.ts33
-rw-r--r--src/connections/Facebook/index.ts25
-rw-r--r--src/connections/GitHub/index.ts19
-rw-r--r--src/connections/Reddit/index.ts22
-rw-r--r--src/connections/Spotify/index.ts33
-rw-r--r--src/connections/Twitch/index.ts31
-rw-r--r--src/connections/Twitter/index.ts33
-rw-r--r--src/connections/Xbox/index.ts38
-rw-r--r--src/connections/Youtube/index.ts26
11 files changed, 79 insertions, 214 deletions
diff --git a/src/connections/BattleNet/index.ts b/src/connections/BattleNet/index.ts
index 4fdfccb1..446e0deb 100644
--- a/src/connections/BattleNet/index.ts
+++ b/src/connections/BattleNet/index.ts
@@ -47,11 +47,7 @@ export default class BattleNetConnection extends Connection {
 	settings: BattleNetSettings = new BattleNetSettings();
 
 	init(): void {
-		const settings =
-			ConnectionLoader.getConnectionConfig<BattleNetSettings>(
-				this.id,
-				this.settings,
-			);
+		const settings = ConnectionLoader.getConnectionConfig<BattleNetSettings>(this.id, this.settings);
 
 		if (settings.enabled && (!settings.clientId || !settings.clientSecret))
 			throw new Error(`Invalid settings for connection ${this.id}`);
@@ -73,10 +69,7 @@ export default class BattleNetConnection extends Connection {
 		return this.tokenUrl;
 	}
 
-	async exchangeCode(
-		state: string,
-		code: string,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+	async exchangeCode(state: string, code: string): Promise<ConnectedAccountCommonOAuthTokenResponse> {
 		this.validateState(state);
 
 		const url = this.getTokenUrl();
@@ -92,7 +85,7 @@ export default class BattleNetConnection extends Connection {
 					client_id: this.settings.clientId as string,
 					client_secret: this.settings.clientSecret as string,
 					redirect_uri: this.getRedirectUri(),
-				}),
+				})
 			)
 			.post()
 			.json<ConnectedAccountCommonOAuthTokenResponse>()
@@ -116,9 +109,7 @@ export default class BattleNetConnection extends Connection {
 			});
 	}
 
-	async handleCallback(
-		params: ConnectionCallbackSchema,
-	): Promise<ConnectedAccount | null> {
+	async handleCallback(params: ConnectionCallbackSchema): Promise<ConnectedAccount | null> {
 		const { state, code } = params;
 		if (!code) throw new Error("No code provided");
 
diff --git a/src/connections/Discord/index.ts b/src/connections/Discord/index.ts
index 731086f1..2c5ada04 100644
--- a/src/connections/Discord/index.ts
+++ b/src/connections/Discord/index.ts
@@ -43,10 +43,7 @@ export default class DiscordConnection extends Connection {
 	settings: DiscordSettings = new DiscordSettings();
 
 	init(): void {
-		const settings = ConnectionLoader.getConnectionConfig<DiscordSettings>(
-			this.id,
-			this.settings,
-		);
+		const settings = ConnectionLoader.getConnectionConfig<DiscordSettings>(this.id, this.settings);
 
 		if (settings.enabled && (!settings.clientId || !settings.clientSecret))
 			throw new Error(`Invalid settings for connection ${this.id}`);
@@ -71,10 +68,7 @@ export default class DiscordConnection extends Connection {
 		return this.tokenUrl;
 	}
 
-	async exchangeCode(
-		state: string,
-		code: string,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+	async exchangeCode(state: string, code: string): Promise<ConnectedAccountCommonOAuthTokenResponse> {
 		this.validateState(state);
 		const url = this.getTokenUrl();
 
@@ -90,7 +84,7 @@ export default class DiscordConnection extends Connection {
 					grant_type: "authorization_code",
 					code: code,
 					redirect_uri: this.getRedirectUri(),
-				}),
+				})
 			)
 			.post()
 			.json<ConnectedAccountCommonOAuthTokenResponse>()
@@ -114,9 +108,7 @@ export default class DiscordConnection extends Connection {
 			});
 	}
 
-	async handleCallback(
-		params: ConnectionCallbackSchema,
-	): Promise<ConnectedAccount | null> {
+	async handleCallback(params: ConnectionCallbackSchema): Promise<ConnectedAccount | null> {
 		const { state, code } = params;
 		if (!code) throw new Error("No code provided");
 
diff --git a/src/connections/EpicGames/index.ts b/src/connections/EpicGames/index.ts
index e5b2d336..6c36b3e1 100644
--- a/src/connections/EpicGames/index.ts
+++ b/src/connections/EpicGames/index.ts
@@ -33,8 +33,7 @@ export interface UserResponse {
 	preferredLanguage: string;
 }
 
-export interface EpicTokenResponse
-	extends ConnectedAccountCommonOAuthTokenResponse {
+export interface EpicTokenResponse extends ConnectedAccountCommonOAuthTokenResponse {
 	expires_at: string;
 	refresh_expires_in: number;
 	refresh_expires_at: string;
@@ -47,17 +46,12 @@ export default class EpicGamesConnection extends Connection {
 	public readonly id = "epicgames";
 	public readonly authorizeUrl = "https://www.epicgames.com/id/authorize";
 	public readonly tokenUrl = "https://api.epicgames.dev/epic/oauth/v1/token";
-	public readonly userInfoUrl =
-		"https://api.epicgames.dev/epic/id/v1/accounts";
+	public readonly userInfoUrl = "https://api.epicgames.dev/epic/id/v1/accounts";
 	public readonly scopes = ["basic profile"];
 	settings: EpicGamesSettings = new EpicGamesSettings();
 
 	init(): void {
-		const settings =
-			ConnectionLoader.getConnectionConfig<EpicGamesSettings>(
-				this.id,
-				this.settings,
-			);
+		const settings = ConnectionLoader.getConnectionConfig<EpicGamesSettings>(this.id, this.settings);
 
 		if (settings.enabled && (!settings.clientId || !settings.clientSecret))
 			throw new Error(`Invalid settings for connection ${this.id}`);
@@ -79,10 +73,7 @@ export default class EpicGamesConnection extends Connection {
 		return this.tokenUrl;
 	}
 
-	async exchangeCode(
-		state: string,
-		code: string,
-	): Promise<EpicTokenResponse> {
+	async exchangeCode(state: string, code: string): Promise<EpicTokenResponse> {
 		this.validateState(state);
 
 		const url = this.getTokenUrl();
@@ -90,16 +81,16 @@ export default class EpicGamesConnection extends Connection {
 		return wretch(url.toString())
 			.headers({
 				Accept: "application/json",
-				Authorization: `Basic ${Buffer.from(
-					`${this.settings.clientId}:${this.settings.clientSecret}`,
-				).toString("base64")}`,
+				Authorization: `Basic ${Buffer.from(`${this.settings.clientId}:${this.settings.clientSecret}`).toString(
+					"base64"
+				)}`,
 				"Content-Type": "application/x-www-form-urlencoded",
 			})
 			.body(
 				new URLSearchParams({
 					grant_type: "authorization_code",
 					code,
-				}),
+				})
 			)
 			.post()
 			.json<EpicTokenResponse>()
@@ -110,9 +101,7 @@ export default class EpicGamesConnection extends Connection {
 	}
 
 	async getUser(token: string): Promise<UserResponse[]> {
-		const { sub } = JSON.parse(
-			Buffer.from(token.split(".")[1], "base64").toString("utf8"),
-		);
+		const { sub } = JSON.parse(Buffer.from(token.split(".")[1], "base64").toString("utf8"));
 		const url = new URL(this.userInfoUrl);
 		url.searchParams.append("accountId", sub);
 
@@ -128,9 +117,7 @@ export default class EpicGamesConnection extends Connection {
 			});
 	}
 
-	async handleCallback(
-		params: ConnectionCallbackSchema,
-	): Promise<ConnectedAccount | null> {
+	async handleCallback(params: ConnectionCallbackSchema): Promise<ConnectedAccount | null> {
 		const { state, code } = params;
 		if (!code) throw new Error("No code provided");
 
diff --git a/src/connections/Facebook/index.ts b/src/connections/Facebook/index.ts
index 2bf26f34..bc2ecd25 100644
--- a/src/connections/Facebook/index.ts
+++ b/src/connections/Facebook/index.ts
@@ -43,19 +43,14 @@ interface UserResponse {
 
 export default class FacebookConnection extends Connection {
 	public readonly id = "facebook";
-	public readonly authorizeUrl =
-		"https://www.facebook.com/v14.0/dialog/oauth";
-	public readonly tokenUrl =
-		"https://graph.facebook.com/v14.0/oauth/access_token";
+	public readonly authorizeUrl = "https://www.facebook.com/v14.0/dialog/oauth";
+	public readonly tokenUrl = "https://graph.facebook.com/v14.0/oauth/access_token";
 	public readonly userInfoUrl = "https://graph.facebook.com/v14.0/me";
 	public readonly scopes = ["public_profile"];
 	settings: FacebookSettings = new FacebookSettings();
 
 	init(): void {
-		const settings = ConnectionLoader.getConnectionConfig<FacebookSettings>(
-			this.id,
-			this.settings,
-		);
+		const settings = ConnectionLoader.getConnectionConfig<FacebookSettings>(this.id, this.settings);
 
 		if (settings.enabled && (!settings.clientId || !settings.clientSecret))
 			throw new Error(`Invalid settings for connection ${this.id}`);
@@ -77,19 +72,13 @@ export default class FacebookConnection extends Connection {
 	getTokenUrl(code: string): string {
 		const url = new URL(this.tokenUrl);
 		url.searchParams.append("client_id", this.settings.clientId as string);
-		url.searchParams.append(
-			"client_secret",
-			this.settings.clientSecret as string,
-		);
+		url.searchParams.append("client_secret", this.settings.clientSecret as string);
 		url.searchParams.append("code", code);
 		url.searchParams.append("redirect_uri", this.getRedirectUri());
 		return url.toString();
 	}
 
-	async exchangeCode(
-		state: string,
-		code: string,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+	async exchangeCode(state: string, code: string): Promise<ConnectedAccountCommonOAuthTokenResponse> {
 		this.validateState(state);
 
 		const url = this.getTokenUrl(code);
@@ -121,9 +110,7 @@ export default class FacebookConnection extends Connection {
 			});
 	}
 
-	async handleCallback(
-		params: ConnectionCallbackSchema,
-	): Promise<ConnectedAccount | null> {
+	async handleCallback(params: ConnectionCallbackSchema): Promise<ConnectedAccount | null> {
 		const { state, code } = params;
 		if (!code) throw new Error("No code provided");
 
diff --git a/src/connections/GitHub/index.ts b/src/connections/GitHub/index.ts
index 25e5f89f..938b0686 100644
--- a/src/connections/GitHub/index.ts
+++ b/src/connections/GitHub/index.ts
@@ -42,10 +42,7 @@ export default class GitHubConnection extends Connection {
 	settings: GitHubSettings = new GitHubSettings();
 
 	init(): void {
-		const settings = ConnectionLoader.getConnectionConfig<GitHubSettings>(
-			this.id,
-			this.settings,
-		);
+		const settings = ConnectionLoader.getConnectionConfig<GitHubSettings>(this.id, this.settings);
 
 		if (settings.enabled && (!settings.clientId || !settings.clientSecret))
 			throw new Error(`Invalid settings for connection ${this.id}`);
@@ -65,18 +62,12 @@ export default class GitHubConnection extends Connection {
 	getTokenUrl(code: string): string {
 		const url = new URL(this.tokenUrl);
 		url.searchParams.append("client_id", this.settings.clientId as string);
-		url.searchParams.append(
-			"client_secret",
-			this.settings.clientSecret as string,
-		);
+		url.searchParams.append("client_secret", this.settings.clientSecret as string);
 		url.searchParams.append("code", code);
 		return url.toString();
 	}
 
-	async exchangeCode(
-		state: string,
-		code: string,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+	async exchangeCode(state: string, code: string): Promise<ConnectedAccountCommonOAuthTokenResponse> {
 		this.validateState(state);
 
 		const url = this.getTokenUrl(code);
@@ -108,9 +99,7 @@ export default class GitHubConnection extends Connection {
 			});
 	}
 
-	async handleCallback(
-		params: ConnectionCallbackSchema,
-	): Promise<ConnectedAccount | null> {
+	async handleCallback(params: ConnectionCallbackSchema): Promise<ConnectedAccount | null> {
 		const { state, code } = params;
 		if (!code) throw new Error("No code provided");
 
diff --git a/src/connections/Reddit/index.ts b/src/connections/Reddit/index.ts
index 149cce02..01ac34ed 100644
--- a/src/connections/Reddit/index.ts
+++ b/src/connections/Reddit/index.ts
@@ -54,10 +54,7 @@ export default class RedditConnection extends Connection {
 	settings: RedditSettings = new RedditSettings();
 
 	init(): void {
-		const settings = ConnectionLoader.getConnectionConfig<RedditSettings>(
-			this.id,
-			this.settings,
-		);
+		const settings = ConnectionLoader.getConnectionConfig<RedditSettings>(this.id, this.settings);
 
 		if (settings.enabled && (!settings.clientId || !settings.clientSecret))
 			throw new Error(`Invalid settings for connection ${this.id}`);
@@ -79,10 +76,7 @@ export default class RedditConnection extends Connection {
 		return this.tokenUrl;
 	}
 
-	async exchangeCode(
-		state: string,
-		code: string,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+	async exchangeCode(state: string, code: string): Promise<ConnectedAccountCommonOAuthTokenResponse> {
 		this.validateState(state);
 
 		const url = this.getTokenUrl();
@@ -90,9 +84,9 @@ export default class RedditConnection extends Connection {
 		return wretch(url.toString())
 			.headers({
 				Accept: "application/json",
-				Authorization: `Basic ${Buffer.from(
-					`${this.settings.clientId}:${this.settings.clientSecret}`,
-				).toString("base64")}`,
+				Authorization: `Basic ${Buffer.from(`${this.settings.clientId}:${this.settings.clientSecret}`).toString(
+					"base64"
+				)}`,
 				"Content-Type": "application/x-www-form-urlencoded",
 			})
 			.body(
@@ -100,7 +94,7 @@ export default class RedditConnection extends Connection {
 					grant_type: "authorization_code",
 					code: code,
 					redirect_uri: this.getRedirectUri(),
-				}),
+				})
 			)
 			.post()
 			.json<ConnectedAccountCommonOAuthTokenResponse>()
@@ -124,9 +118,7 @@ export default class RedditConnection extends Connection {
 			});
 	}
 
-	async handleCallback(
-		params: ConnectionCallbackSchema,
-	): Promise<ConnectedAccount | null> {
+	async handleCallback(params: ConnectionCallbackSchema): Promise<ConnectedAccount | null> {
 		const { state, code } = params;
 		if (!code) throw new Error("No code provided");
 
diff --git a/src/connections/Spotify/index.ts b/src/connections/Spotify/index.ts
index ece404d8..6a456b44 100644
--- a/src/connections/Spotify/index.ts
+++ b/src/connections/Spotify/index.ts
@@ -63,10 +63,7 @@ export default class SpotifyConnection extends RefreshableConnection {
 		 * So to prevent spamming the spotify api we disable the ability to refresh.
 		 */
 		this.refreshEnabled = false;
-		const settings = ConnectionLoader.getConnectionConfig<SpotifySettings>(
-			this.id,
-			this.settings,
-		);
+		const settings = ConnectionLoader.getConnectionConfig<SpotifySettings>(this.id, this.settings);
 
 		if (settings.enabled && (!settings.clientId || !settings.clientSecret))
 			throw new Error(`Invalid settings for connection ${this.id}`);
@@ -88,10 +85,7 @@ export default class SpotifyConnection extends RefreshableConnection {
 		return this.tokenUrl;
 	}
 
-	async exchangeCode(
-		state: string,
-		code: string,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+	async exchangeCode(state: string, code: string): Promise<ConnectedAccountCommonOAuthTokenResponse> {
 		this.validateState(state);
 
 		const url = this.getTokenUrl();
@@ -101,9 +95,7 @@ export default class SpotifyConnection extends RefreshableConnection {
 				Accept: "application/json",
 				"Content-Type": "application/x-www-form-urlencoded",
 				Authorization: `Basic ${Buffer.from(
-					`${this.settings.clientId as string}:${
-						this.settings.clientSecret as string
-					}`,
+					`${this.settings.clientId as string}:${this.settings.clientSecret as string}`
 				).toString("base64")}`,
 			})
 			.body(
@@ -111,7 +103,7 @@ export default class SpotifyConnection extends RefreshableConnection {
 					grant_type: "authorization_code",
 					code: code,
 					redirect_uri: this.getRedirectUri(),
-				}),
+				})
 			)
 			.post()
 			.json<ConnectedAccountCommonOAuthTokenResponse>()
@@ -121,11 +113,8 @@ export default class SpotifyConnection extends RefreshableConnection {
 			});
 	}
 
-	async refreshToken(
-		connectedAccount: ConnectedAccount,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
-		if (!connectedAccount.token_data?.refresh_token)
-			throw new Error("No refresh token available.");
+	async refreshToken(connectedAccount: ConnectedAccount): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+		if (!connectedAccount.token_data?.refresh_token) throw new Error("No refresh token available.");
 		const refresh_token = connectedAccount.token_data.refresh_token;
 		const url = this.getTokenUrl();
 
@@ -134,16 +123,14 @@ export default class SpotifyConnection extends RefreshableConnection {
 				Accept: "application/json",
 				"Content-Type": "application/x-www-form-urlencoded",
 				Authorization: `Basic ${Buffer.from(
-					`${this.settings.clientId as string}:${
-						this.settings.clientSecret as string
-					}`,
+					`${this.settings.clientId as string}:${this.settings.clientSecret as string}`
 				).toString("base64")}`,
 			})
 			.body(
 				new URLSearchParams({
 					grant_type: "refresh_token",
 					refresh_token,
-				}),
+				})
 			)
 			.post()
 			.unauthorized(async () => {
@@ -173,9 +160,7 @@ export default class SpotifyConnection extends RefreshableConnection {
 			});
 	}
 
-	async handleCallback(
-		params: ConnectionCallbackSchema,
-	): Promise<ConnectedAccount | null> {
+	async handleCallback(params: ConnectionCallbackSchema): Promise<ConnectedAccount | null> {
 		const { state, code } = params;
 		if (!code) throw new Error("No code provided");
 
diff --git a/src/connections/Twitch/index.ts b/src/connections/Twitch/index.ts
index 9a6cea35..1cb62f9d 100644
--- a/src/connections/Twitch/index.ts
+++ b/src/connections/Twitch/index.ts
@@ -47,18 +47,11 @@ export default class TwitchConnection extends RefreshableConnection {
 	public readonly authorizeUrl = "https://id.twitch.tv/oauth2/authorize";
 	public readonly tokenUrl = "https://id.twitch.tv/oauth2/token";
 	public readonly userInfoUrl = "https://api.twitch.tv/helix/users";
-	public readonly scopes = [
-		"channel_subscriptions",
-		"channel_check_subscription",
-		"channel:read:subscriptions",
-	];
+	public readonly scopes = ["channel_subscriptions", "channel_check_subscription", "channel:read:subscriptions"];
 	settings: TwitchSettings = new TwitchSettings();
 
 	init(): void {
-		const settings = ConnectionLoader.getConnectionConfig<TwitchSettings>(
-			this.id,
-			this.settings,
-		);
+		const settings = ConnectionLoader.getConnectionConfig<TwitchSettings>(this.id, this.settings);
 
 		if (settings.enabled && (!settings.clientId || !settings.clientSecret))
 			throw new Error(`Invalid settings for connection ${this.id}`);
@@ -80,10 +73,7 @@ export default class TwitchConnection extends RefreshableConnection {
 		return this.tokenUrl;
 	}
 
-	async exchangeCode(
-		state: string,
-		code: string,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+	async exchangeCode(state: string, code: string): Promise<ConnectedAccountCommonOAuthTokenResponse> {
 		this.validateState(state);
 
 		const url = this.getTokenUrl();
@@ -100,7 +90,7 @@ export default class TwitchConnection extends RefreshableConnection {
 					client_id: this.settings.clientId as string,
 					client_secret: this.settings.clientSecret as string,
 					redirect_uri: this.getRedirectUri(),
-				}),
+				})
 			)
 			.post()
 			.json<ConnectedAccountCommonOAuthTokenResponse>()
@@ -110,11 +100,8 @@ export default class TwitchConnection extends RefreshableConnection {
 			});
 	}
 
-	async refreshToken(
-		connectedAccount: ConnectedAccount,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
-		if (!connectedAccount.token_data?.refresh_token)
-			throw new Error("No refresh token available.");
+	async refreshToken(connectedAccount: ConnectedAccount): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+		if (!connectedAccount.token_data?.refresh_token) throw new Error("No refresh token available.");
 		const refresh_token = connectedAccount.token_data.refresh_token;
 
 		const url = this.getTokenUrl();
@@ -130,7 +117,7 @@ export default class TwitchConnection extends RefreshableConnection {
 					client_id: this.settings.clientId as string,
 					client_secret: this.settings.clientSecret as string,
 					refresh_token: refresh_token,
-				}),
+				})
 			)
 			.post()
 			.unauthorized(async () => {
@@ -161,9 +148,7 @@ export default class TwitchConnection extends RefreshableConnection {
 			});
 	}
 
-	async handleCallback(
-		params: ConnectionCallbackSchema,
-	): Promise<ConnectedAccount | null> {
+	async handleCallback(params: ConnectionCallbackSchema): Promise<ConnectedAccount | null> {
 		const { state, code } = params;
 		if (!code) throw new Error("No code provided");
 
diff --git a/src/connections/Twitter/index.ts b/src/connections/Twitter/index.ts
index 62fd7da1..424fd455 100644
--- a/src/connections/Twitter/index.ts
+++ b/src/connections/Twitter/index.ts
@@ -55,10 +55,7 @@ export default class TwitterConnection extends RefreshableConnection {
 	settings: TwitterSettings = new TwitterSettings();
 
 	init(): void {
-		const settings = ConnectionLoader.getConnectionConfig<TwitterSettings>(
-			this.id,
-			this.settings,
-		);
+		const settings = ConnectionLoader.getConnectionConfig<TwitterSettings>(this.id, this.settings);
 
 		if (settings.enabled && (!settings.clientId || !settings.clientSecret))
 			throw new Error(`Invalid settings for connection ${this.id}`);
@@ -82,10 +79,7 @@ export default class TwitterConnection extends RefreshableConnection {
 		return this.tokenUrl;
 	}
 
-	async exchangeCode(
-		state: string,
-		code: string,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+	async exchangeCode(state: string, code: string): Promise<ConnectedAccountCommonOAuthTokenResponse> {
 		this.validateState(state);
 
 		const url = this.getTokenUrl();
@@ -95,9 +89,7 @@ export default class TwitterConnection extends RefreshableConnection {
 				Accept: "application/json",
 				"Content-Type": "application/x-www-form-urlencoded",
 				Authorization: `Basic ${Buffer.from(
-					`${this.settings.clientId as string}:${
-						this.settings.clientSecret as string
-					}`,
+					`${this.settings.clientId as string}:${this.settings.clientSecret as string}`
 				).toString("base64")}`,
 			})
 			.body(
@@ -107,7 +99,7 @@ export default class TwitterConnection extends RefreshableConnection {
 					client_id: this.settings.clientId as string,
 					redirect_uri: this.getRedirectUri(),
 					code_verifier: "challenge", // TODO: properly use PKCE challenge
-				}),
+				})
 			)
 			.post()
 			.json<ConnectedAccountCommonOAuthTokenResponse>()
@@ -117,11 +109,8 @@ export default class TwitterConnection extends RefreshableConnection {
 			});
 	}
 
-	async refreshToken(
-		connectedAccount: ConnectedAccount,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
-		if (!connectedAccount.token_data?.refresh_token)
-			throw new Error("No refresh token available.");
+	async refreshToken(connectedAccount: ConnectedAccount): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+		if (!connectedAccount.token_data?.refresh_token) throw new Error("No refresh token available.");
 		const refresh_token = connectedAccount.token_data.refresh_token;
 
 		const url = this.getTokenUrl();
@@ -131,9 +120,7 @@ export default class TwitterConnection extends RefreshableConnection {
 				Accept: "application/json",
 				"Content-Type": "application/x-www-form-urlencoded",
 				Authorization: `Basic ${Buffer.from(
-					`${this.settings.clientId as string}:${
-						this.settings.clientSecret as string
-					}`,
+					`${this.settings.clientId as string}:${this.settings.clientSecret as string}`
 				).toString("base64")}`,
 			})
 			.body(
@@ -143,7 +130,7 @@ export default class TwitterConnection extends RefreshableConnection {
 					client_id: this.settings.clientId as string,
 					redirect_uri: this.getRedirectUri(),
 					code_verifier: "challenge", // TODO: properly use PKCE challenge
-				}),
+				})
 			)
 			.post()
 			.json<ConnectedAccountCommonOAuthTokenResponse>()
@@ -167,9 +154,7 @@ export default class TwitterConnection extends RefreshableConnection {
 			});
 	}
 
-	async handleCallback(
-		params: ConnectionCallbackSchema,
-	): Promise<ConnectedAccount | null> {
+	async handleCallback(params: ConnectionCallbackSchema): Promise<ConnectedAccount | null> {
 		const { state, code } = params;
 		if (!code) throw new Error("No code provided");
 
diff --git a/src/connections/Xbox/index.ts b/src/connections/Xbox/index.ts
index 935ff7ab..9a091315 100644
--- a/src/connections/Xbox/index.ts
+++ b/src/connections/Xbox/index.ts
@@ -51,21 +51,15 @@ interface XboxUserResponse {
 
 export default class XboxConnection extends Connection {
 	public readonly id = "xbox";
-	public readonly authorizeUrl =
-		"https://login.live.com/oauth20_authorize.srf";
+	public readonly authorizeUrl = "https://login.live.com/oauth20_authorize.srf";
 	public readonly tokenUrl = "https://login.live.com/oauth20_token.srf";
-	public readonly userInfoUrl =
-		"https://xsts.auth.xboxlive.com/xsts/authorize";
-	public readonly userAuthUrl =
-		"https://user.auth.xboxlive.com/user/authenticate";
+	public readonly userInfoUrl = "https://xsts.auth.xboxlive.com/xsts/authorize";
+	public readonly userAuthUrl = "https://user.auth.xboxlive.com/user/authenticate";
 	public readonly scopes = ["Xboxlive.signin", "Xboxlive.offline_access"];
 	settings: XboxSettings = new XboxSettings();
 
 	init(): void {
-		const settings = ConnectionLoader.getConnectionConfig<XboxSettings>(
-			this.id,
-			this.settings,
-		);
+		const settings = ConnectionLoader.getConnectionConfig<XboxSettings>(this.id, this.settings);
 
 		if (settings.enabled && (!settings.clientId || !settings.clientSecret))
 			throw new Error(`Invalid settings for connection ${this.id}`);
@@ -104,7 +98,7 @@ export default class XboxConnection extends Connection {
 						SiteName: "user.auth.xboxlive.com",
 						RpsTicket: `d=${token}`,
 					},
-				}),
+				})
 			)
 			.post()
 			.json((res: XboxUserResponse) => res.Token)
@@ -114,10 +108,7 @@ export default class XboxConnection extends Connection {
 			});
 	}
 
-	async exchangeCode(
-		state: string,
-		code: string,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+	async exchangeCode(state: string, code: string): Promise<ConnectedAccountCommonOAuthTokenResponse> {
 		this.validateState(state);
 
 		const url = this.getTokenUrl();
@@ -127,9 +118,7 @@ export default class XboxConnection extends Connection {
 				Accept: "application/json",
 				"Content-Type": "application/x-www-form-urlencoded",
 				Authorization: `Basic ${Buffer.from(
-					`${this.settings.clientId as string}:${
-						this.settings.clientSecret as string
-					}`,
+					`${this.settings.clientId as string}:${this.settings.clientSecret as string}`
 				).toString("base64")}`,
 			})
 			.body(
@@ -139,7 +128,7 @@ export default class XboxConnection extends Connection {
 					client_id: this.settings.clientId as string,
 					redirect_uri: this.getRedirectUri(),
 					scope: this.scopes.join(" "),
-				}),
+				})
 			)
 			.post()
 			.json<ConnectedAccountCommonOAuthTokenResponse>()
@@ -166,7 +155,7 @@ export default class XboxConnection extends Connection {
 						UserTokens: [token],
 						SandboxId: "RETAIL",
 					},
-				}),
+				})
 			)
 			.post()
 			.json<XboxUserResponse>()
@@ -176,9 +165,7 @@ export default class XboxConnection extends Connection {
 			});
 	}
 
-	async handleCallback(
-		params: ConnectionCallbackSchema,
-	): Promise<ConnectedAccount | null> {
+	async handleCallback(params: ConnectionCallbackSchema): Promise<ConnectedAccount | null> {
 		const { state, code } = params;
 		if (!code) throw new Error("No code provided");
 
@@ -187,10 +174,7 @@ export default class XboxConnection extends Connection {
 		const userToken = await this.getUserToken(tokenData.access_token);
 		const userInfo = await this.getUser(userToken);
 
-		const exists = await this.hasConnection(
-			userId,
-			userInfo.DisplayClaims.xui[0].xid,
-		);
+		const exists = await this.hasConnection(userId, userInfo.DisplayClaims.xui[0].xid);
 
 		if (exists) return null;
 
diff --git a/src/connections/Youtube/index.ts b/src/connections/Youtube/index.ts
index 844803cf..9cf6f003 100644
--- a/src/connections/Youtube/index.ts
+++ b/src/connections/Youtube/index.ts
@@ -51,21 +51,14 @@ interface YouTubeConnectionChannelListResult {
 
 export default class YoutubeConnection extends Connection {
 	public readonly id = "youtube";
-	public readonly authorizeUrl =
-		"https://accounts.google.com/o/oauth2/v2/auth";
+	public readonly authorizeUrl = "https://accounts.google.com/o/oauth2/v2/auth";
 	public readonly tokenUrl = "https://oauth2.googleapis.com/token";
-	public readonly userInfoUrl =
-		"https://www.googleapis.com/youtube/v3/channels?mine=true&part=snippet";
-	public readonly scopes = [
-		"https://www.googleapis.com/auth/youtube.readonly",
-	];
+	public readonly userInfoUrl = "https://www.googleapis.com/youtube/v3/channels?mine=true&part=snippet";
+	public readonly scopes = ["https://www.googleapis.com/auth/youtube.readonly"];
 	settings: YoutubeSettings = new YoutubeSettings();
 
 	init(): void {
-		const settings = ConnectionLoader.getConnectionConfig<YoutubeSettings>(
-			this.id,
-			this.settings,
-		);
+		const settings = ConnectionLoader.getConnectionConfig<YoutubeSettings>(this.id, this.settings);
 
 		if (settings.enabled && (!settings.clientId || !settings.clientSecret))
 			throw new Error(`Invalid settings for connection ${this.id}`);
@@ -87,10 +80,7 @@ export default class YoutubeConnection extends Connection {
 		return this.tokenUrl;
 	}
 
-	async exchangeCode(
-		state: string,
-		code: string,
-	): Promise<ConnectedAccountCommonOAuthTokenResponse> {
+	async exchangeCode(state: string, code: string): Promise<ConnectedAccountCommonOAuthTokenResponse> {
 		this.validateState(state);
 
 		const url = this.getTokenUrl();
@@ -107,7 +97,7 @@ export default class YoutubeConnection extends Connection {
 					client_id: this.settings.clientId as string,
 					client_secret: this.settings.clientSecret as string,
 					redirect_uri: this.getRedirectUri(),
-				}),
+				})
 			)
 			.post()
 			.json<ConnectedAccountCommonOAuthTokenResponse>()
@@ -131,9 +121,7 @@ export default class YoutubeConnection extends Connection {
 			});
 	}
 
-	async handleCallback(
-		params: ConnectionCallbackSchema,
-	): Promise<ConnectedAccount | null> {
+	async handleCallback(params: ConnectionCallbackSchema): Promise<ConnectedAccount | null> {
 		const { state, code } = params;
 		if (!code) throw new Error("No code provided");