diff --git a/src/connections/BattleNet/BattleNetSettings.ts b/src/connections/BattleNet/BattleNetSettings.ts
deleted file mode 100644
index 661fdeb..0000000
--- a/src/connections/BattleNet/BattleNetSettings.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-export class BattleNetSettings {
- enabled: boolean = false;
- clientId: string | null = null;
- clientSecret: string | null = null;
-}
diff --git a/src/connections/BattleNet/index.ts b/src/connections/BattleNet/index.ts
index f7d08cb..30488e3 100644
--- a/src/connections/BattleNet/index.ts
+++ b/src/connections/BattleNet/index.ts
@@ -18,7 +18,7 @@
import { ConnectedAccount, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
import wretch from "wretch";
-import { BattleNetSettings } from "./BattleNetSettings";
+import { GenericOAuthSettings as BattleNetSettings } from "../GenericOAuthSettings";
import { ConnectedAccountCommonOAuthTokenResponse, ConnectionCallbackSchema } from "@spacebar/schemas";
interface BattleNetConnectionUser {
@@ -34,6 +34,10 @@
export default class BattleNetConnection extends Connection {
public readonly id = "battlenet";
+ public readonly friendlyName = "Battle.net";
+ public readonly setupUrl = "(missing - contributions welcome)";
+ public readonly requiredScopes = [];
+
public readonly authorizeUrl = "https://oauth.battle.net/authorize";
public readonly tokenUrl = "https://oauth.battle.net/token";
public readonly userInfoUrl = "https://us.battle.net/oauth/userinfo";
@@ -46,6 +50,10 @@
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
}
+ public get isConfigured(): boolean {
+ return !!this.settings.clientId && !!this.settings.clientSecret;
+ }
+
getAuthorizationUrl(userId: string): string {
const state = this.createState(userId);
const url = new URL(this.authorizeUrl);
diff --git a/src/connections/Discord/DiscordSettings.ts b/src/connections/Discord/DiscordSettings.ts
deleted file mode 100644
index af0b8d6..0000000
--- a/src/connections/Discord/DiscordSettings.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-export class DiscordSettings {
- enabled: boolean = false;
- clientId: string | null = null;
- clientSecret: string | null = null;
-}
diff --git a/src/connections/Discord/index.ts b/src/connections/Discord/index.ts
index f209a81..5a15f09 100644
--- a/src/connections/Discord/index.ts
+++ b/src/connections/Discord/index.ts
@@ -18,7 +18,7 @@
import { ConnectedAccount, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
import wretch from "wretch";
-import { DiscordSettings } from "./DiscordSettings";
+import { GenericOAuthSettings as DiscordSettings } from "../GenericOAuthSettings";
import { ConnectedAccountCommonOAuthTokenResponse, ConnectionCallbackSchema } from "@spacebar/schemas";
interface UserResponse {
@@ -30,6 +30,10 @@
export default class DiscordConnection extends Connection {
public readonly id = "discord";
+ public readonly friendlyName = "Discord";
+ public readonly setupUrl = "https://discord.com/developers/applications";
+ public readonly requiredScopes = ["identify"];
+
public readonly authorizeUrl = "https://discord.com/api/oauth2/authorize";
public readonly tokenUrl = "https://discord.com/api/oauth2/token";
public readonly userInfoUrl = "https://discord.com/api/users/@me";
@@ -42,6 +46,10 @@
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
}
+ public get isConfigured(): boolean {
+ return !!this.settings.clientId && !!this.settings.clientSecret;
+ }
+
getAuthorizationUrl(userId: string): string {
const state = this.createState(userId);
const url = new URL(this.authorizeUrl);
diff --git a/src/connections/EpicGames/EpicGamesSettings.ts b/src/connections/EpicGames/EpicGamesSettings.ts
deleted file mode 100644
index fbe5c7a..0000000
--- a/src/connections/EpicGames/EpicGamesSettings.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-export class EpicGamesSettings {
- enabled: boolean = false;
- clientId: string | null = null;
- clientSecret: string | null = null;
-}
diff --git a/src/connections/EpicGames/index.ts b/src/connections/EpicGames/index.ts
index 959192e..5fc2701 100644
--- a/src/connections/EpicGames/index.ts
+++ b/src/connections/EpicGames/index.ts
@@ -18,7 +18,7 @@
import { ConnectedAccount, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
import wretch from "wretch";
-import { EpicGamesSettings } from "./EpicGamesSettings";
+import { GenericOAuthSettings as EpicGamesSettings } from "../GenericOAuthSettings";
import { ConnectedAccountCommonOAuthTokenResponse, ConnectionCallbackSchema } from "@spacebar/schemas";
export interface UserResponse {
@@ -38,6 +38,10 @@
export default class EpicGamesConnection extends Connection {
public readonly id = "epicgames";
+ public readonly friendlyName = "Epic Games";
+ public readonly setupUrl = "https://dev.epicgames.com/portal";
+ public readonly requiredScopes = [];
+
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";
@@ -50,6 +54,9 @@
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
}
+ public get isConfigured(): boolean {
+ return !!this.settings.clientId && !!this.settings.clientSecret;
+ }
getAuthorizationUrl(userId: string): string {
const state = this.createState(userId);
const url = new URL(this.authorizeUrl);
diff --git a/src/connections/Facebook/FacebookSettings.ts b/src/connections/Facebook/FacebookSettings.ts
deleted file mode 100644
index f130358..0000000
--- a/src/connections/Facebook/FacebookSettings.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-export class FacebookSettings {
- enabled: boolean = false;
- clientId: string | null = null;
- clientSecret: string | null = null;
-}
diff --git a/src/connections/Facebook/index.ts b/src/connections/Facebook/index.ts
index 29317c2..3abd566 100644
--- a/src/connections/Facebook/index.ts
+++ b/src/connections/Facebook/index.ts
@@ -18,7 +18,7 @@
import { ConnectedAccount, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
import wretch from "wretch";
-import { FacebookSettings } from "./FacebookSettings";
+import { GenericOAuthSettings as FacebookSettings } from "../GenericOAuthSettings";
import { ConnectedAccountCommonOAuthTokenResponse, ConnectionCallbackSchema } from "@spacebar/schemas";
export interface FacebookErrorResponse {
@@ -37,6 +37,10 @@
export default class FacebookConnection extends Connection {
public readonly id = "facebook";
+ public readonly friendlyName = "Facebook";
+ public readonly setupUrl = "(missing - contributions welcome)";
+ public readonly requiredScopes = [];
+
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";
@@ -49,6 +53,10 @@
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
}
+ public get isConfigured(): boolean {
+ return !!this.settings.clientId && !!this.settings.clientSecret;
+ }
+
getAuthorizationUrl(userId: string): string {
const state = this.createState(userId);
const url = new URL(this.authorizeUrl);
diff --git a/src/connections/GenericOAuthSettings.ts b/src/connections/GenericOAuthSettings.ts
new file mode 100644
index 0000000..d4ccb35
--- /dev/null
+++ b/src/connections/GenericOAuthSettings.ts
@@ -0,0 +1,23 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2026 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+export class GenericOAuthSettings {
+ enabled: boolean = false;
+ clientId: string | null = null;
+ clientSecret: string | null = null;
+}
diff --git a/src/connections/GitHub/GitHubSettings.ts b/src/connections/GitHub/GitHubSettings.ts
deleted file mode 100644
index f744a77..0000000
--- a/src/connections/GitHub/GitHubSettings.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-export class GitHubSettings {
- enabled: boolean = false;
- clientId: string | null = null;
- clientSecret: string | null = null;
-}
diff --git a/src/connections/GitHub/index.ts b/src/connections/GitHub/index.ts
index df64912..a5e0f70 100644
--- a/src/connections/GitHub/index.ts
+++ b/src/connections/GitHub/index.ts
@@ -18,7 +18,7 @@
import { ConnectedAccount, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
import wretch from "wretch";
-import { GitHubSettings } from "./GitHubSettings";
+import { GenericOAuthSettings as GitHubSettings } from "../GenericOAuthSettings";
import { ConnectedAccountCommonOAuthTokenResponse, ConnectionCallbackSchema } from "@spacebar/schemas";
interface UserResponse {
@@ -29,6 +29,10 @@
export default class GitHubConnection extends Connection {
public readonly id = "github";
+ public friendlyName = "GitHub";
+ public setupUrl = "https://github.com/settings/developers";
+ public requiredScopes: string[];
+
public readonly authorizeUrl = "https://github.com/login/oauth/authorize";
public readonly tokenUrl = "https://github.com/login/oauth/access_token";
public readonly userInfoUrl = "https://api.github.com/user";
@@ -41,6 +45,10 @@
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
}
+ public get isConfigured(): boolean {
+ return !!this.settings.clientId && !!this.settings.clientSecret;
+ }
+
getAuthorizationUrl(userId: string): string {
const state = this.createState(userId);
const url = new URL(this.authorizeUrl);
diff --git a/src/connections/Reddit/RedditSettings.ts b/src/connections/Reddit/RedditSettings.ts
deleted file mode 100644
index 083af8e..0000000
--- a/src/connections/Reddit/RedditSettings.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-export class RedditSettings {
- enabled: boolean = false;
- clientId: string | null = null;
- clientSecret: string | null = null;
-}
diff --git a/src/connections/Reddit/index.ts b/src/connections/Reddit/index.ts
index 781e097..92f3737 100644
--- a/src/connections/Reddit/index.ts
+++ b/src/connections/Reddit/index.ts
@@ -18,7 +18,7 @@
import { ConnectedAccount, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
import wretch from "wretch";
-import { RedditSettings } from "./RedditSettings";
+import { GenericOAuthSettings as RedditSettings } from "../GenericOAuthSettings";
import { ConnectedAccountCommonOAuthTokenResponse, ConnectionCallbackSchema } from "@spacebar/schemas";
export interface UserResponse {
@@ -41,6 +41,10 @@
export default class RedditConnection extends Connection {
public readonly id = "reddit";
+ public friendlyName = "Reddit";
+ public setupUrl = "https://www.reddit.com/prefs/apps";
+ public requiredScopes = []; // Does not seem to offer platform-side scope controls
+
public readonly authorizeUrl = "https://www.reddit.com/api/v1/authorize";
public readonly tokenUrl = "https://www.reddit.com/api/v1/access_token";
public readonly userInfoUrl = "https://oauth.reddit.com/api/v1/me";
@@ -53,6 +57,10 @@
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
}
+ public get isConfigured(): boolean {
+ return !!this.settings.clientId && !!this.settings.clientSecret;
+ }
+
getAuthorizationUrl(userId: string): string {
const state = this.createState(userId);
const url = new URL(this.authorizeUrl);
diff --git a/src/connections/Spotify/SpotifySettings.ts b/src/connections/Spotify/SpotifySettings.ts
deleted file mode 100644
index e2db486..0000000
--- a/src/connections/Spotify/SpotifySettings.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-export class SpotifySettings {
- enabled: boolean = false;
- clientId: string | null = null;
- clientSecret: string | null = null;
-}
diff --git a/src/connections/Spotify/index.ts b/src/connections/Spotify/index.ts
index 2186396..e64626b 100644
--- a/src/connections/Spotify/index.ts
+++ b/src/connections/Spotify/index.ts
@@ -18,7 +18,7 @@
import { ConnectedAccount, ConnectionLoader, DiscordApiErrors, RefreshableConnection } from "@spacebar/util";
import wretch from "wretch";
-import { SpotifySettings } from "./SpotifySettings";
+import { GenericOAuthSettings as SpotifySettings } from "../GenericOAuthSettings";
import { ConnectedAccountCommonOAuthTokenResponse, ConnectionCallbackSchema } from "@spacebar/schemas";
export interface UserResponse {
@@ -40,6 +40,10 @@
export default class SpotifyConnection extends RefreshableConnection {
public readonly id = "spotify";
+ public friendlyName = "Spotify";
+ public setupUrl = "https://developer.spotify.com";
+ public requiredScopes = ["Requires instance admin to have spotify premium"];
+
public readonly authorizeUrl = "https://accounts.spotify.com/authorize";
public readonly tokenUrl = "https://accounts.spotify.com/api/token";
public readonly userInfoUrl = "https://api.spotify.com/v1/me";
@@ -58,6 +62,10 @@
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
}
+ public get isConfigured(): boolean {
+ return !!this.settings.clientId && !!this.settings.clientSecret;
+ }
+
getAuthorizationUrl(userId: string): string {
const state = this.createState(userId);
const url = new URL(this.authorizeUrl);
diff --git a/src/connections/Twitch/TwitchSettings.ts b/src/connections/Twitch/TwitchSettings.ts
deleted file mode 100644
index fcd0a0d..0000000
--- a/src/connections/Twitch/TwitchSettings.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-export class TwitchSettings {
- enabled: boolean = false;
- clientId: string | null = null;
- clientSecret: string | null = null;
-}
diff --git a/src/connections/Twitch/index.ts b/src/connections/Twitch/index.ts
index 5952caf..116b319 100644
--- a/src/connections/Twitch/index.ts
+++ b/src/connections/Twitch/index.ts
@@ -18,7 +18,7 @@
import { ConnectedAccount, ConnectionLoader, DiscordApiErrors, RefreshableConnection } from "@spacebar/util";
import wretch from "wretch";
-import { TwitchSettings } from "./TwitchSettings";
+import { GenericOAuthSettings as TwitchSettings } from "../GenericOAuthSettings";
import { ConnectedAccountCommonOAuthTokenResponse, ConnectionCallbackSchema } from "@spacebar/schemas";
interface TwitchConnectionUserResponse {
@@ -38,6 +38,10 @@
export default class TwitchConnection extends RefreshableConnection {
public readonly id = "twitch";
+ public friendlyName = "Twitch.tv";
+ public setupUrl = "https://dev.twitch.tv/console/apps/create";
+ public requiredScopes: string[];
+
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";
@@ -50,6 +54,10 @@
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
}
+ public get isConfigured(): boolean {
+ return !!this.settings.clientId && !!this.settings.clientSecret;
+ }
+
getAuthorizationUrl(userId: string): string {
const state = this.createState(userId);
const url = new URL(this.authorizeUrl);
diff --git a/src/connections/Twitter/TwitterSettings.ts b/src/connections/Twitter/TwitterSettings.ts
deleted file mode 100644
index f9b2f5a..0000000
--- a/src/connections/Twitter/TwitterSettings.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-export class TwitterSettings {
- enabled: boolean = false;
- clientId: string | null = null;
- clientSecret: string | null = null;
-}
diff --git a/src/connections/Twitter/index.ts b/src/connections/Twitter/index.ts
index 3c79515..7a56aa4 100644
--- a/src/connections/Twitter/index.ts
+++ b/src/connections/Twitter/index.ts
@@ -18,7 +18,7 @@
import { ConnectedAccount, ConnectionLoader, DiscordApiErrors, RefreshableConnection } from "@spacebar/util";
import wretch from "wretch";
-import { TwitterSettings } from "./TwitterSettings";
+import { GenericOAuthSettings as TwitterSettings } from "../GenericOAuthSettings";
import { ConnectedAccountCommonOAuthTokenResponse, ConnectionCallbackSchema } from "@spacebar/schemas";
interface TwitterUserResponse {
@@ -41,6 +41,10 @@
export default class TwitterConnection extends RefreshableConnection {
public readonly id = "twitter";
+ public friendlyName = "Twitter";
+ public setupUrl = "https://console.x.com";
+ public requiredScopes = []; //no scopes nessecary
+
public readonly authorizeUrl = "https://twitter.com/i/oauth2/authorize";
public readonly tokenUrl = "https://api.twitter.com/2/oauth2/token";
public readonly userInfoUrl = "https://api.twitter.com/2/users/me?user.fields=created_at%2Cdescription%2Cid%2Cname%2Cusername%2Cverified%2Clocation%2Curl";
@@ -53,6 +57,10 @@
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
}
+ public get isConfigured(): boolean {
+ return !!this.settings.clientId && !!this.settings.clientSecret;
+ }
+
getAuthorizationUrl(userId: string): string {
const state = this.createState(userId);
const url = new URL(this.authorizeUrl);
diff --git a/src/connections/Xbox/XboxSettings.ts b/src/connections/Xbox/XboxSettings.ts
deleted file mode 100644
index b7e97de..0000000
--- a/src/connections/Xbox/XboxSettings.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-export class XboxSettings {
- enabled: boolean = false;
- clientId: string | null = null;
- clientSecret: string | null = null;
-}
diff --git a/src/connections/Xbox/index.ts b/src/connections/Xbox/index.ts
index 59d4a00..95cd6ec 100644
--- a/src/connections/Xbox/index.ts
+++ b/src/connections/Xbox/index.ts
@@ -18,7 +18,7 @@
import { ConnectedAccount, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
import wretch from "wretch";
-import { XboxSettings } from "./XboxSettings";
+import { GenericOAuthSettings as XboxSettings } from "../GenericOAuthSettings";
import { ConnectedAccountCommonOAuthTokenResponse, ConnectionCallbackSchema } from "@spacebar/schemas";
interface XboxUserResponse {
@@ -45,6 +45,10 @@
export default class XboxConnection extends Connection {
public readonly id = "xbox";
+ public readonly friendlyName = "Xbox Live";
+ public readonly setupUrl = "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade";
+ public readonly requiredScopes = []; // these are part of the URL and don't need to be assigned
+
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";
@@ -58,6 +62,10 @@
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
}
+ public get isConfigured(): boolean {
+ return !!this.settings.clientId && !!this.settings.clientSecret;
+ }
+
getAuthorizationUrl(userId: string): string {
const state = this.createState(userId);
const url = new URL(this.authorizeUrl);
diff --git a/src/connections/Youtube/YoutubeSettings.ts b/src/connections/Youtube/YoutubeSettings.ts
deleted file mode 100644
index b2f7c1b..0000000
--- a/src/connections/Youtube/YoutubeSettings.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
- Copyright (C) 2023 Spacebar and Spacebar Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-export class YoutubeSettings {
- enabled: boolean = false;
- clientId: string | null = null;
- clientSecret: string | null = null;
-}
diff --git a/src/connections/Youtube/index.ts b/src/connections/Youtube/index.ts
index 2db9289..64debb8 100644
--- a/src/connections/Youtube/index.ts
+++ b/src/connections/Youtube/index.ts
@@ -18,7 +18,7 @@
import { ConnectedAccount, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
import wretch from "wretch";
-import { YoutubeSettings } from "./YoutubeSettings";
+import { GenericOAuthSettings as YoutubeSettings } from "../GenericOAuthSettings";
import { ConnectedAccountCommonOAuthTokenResponse, ConnectionCallbackSchema } from "@spacebar/schemas";
interface YouTubeConnectionChannelListResult {
@@ -45,6 +45,10 @@
export default class YoutubeConnection extends Connection {
public readonly id = "youtube";
+ public readonly friendlyName = "YouTube";
+ public readonly setupUrl = "https://console.cloud.google.com/apis/api/youtube.googleapis.com";
+ public readonly requiredScopes = ["/auth/youtube.readonly"];
+
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";
@@ -57,6 +61,10 @@
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
}
+ public get isConfigured(): boolean {
+ return !!this.settings.clientId && !!this.settings.clientSecret;
+ }
+
getAuthorizationUrl(userId: string): string {
const state = this.createState(userId);
const url = new URL(this.authorizeUrl);
diff --git a/src/util/connections/Connection.ts b/src/util/connections/Connection.ts
index e48b13a..d593416 100644
--- a/src/util/connections/Connection.ts
+++ b/src/util/connections/Connection.ts
@@ -29,9 +29,18 @@
settings: { enabled: boolean };
states: Map = new Map();
+ public abstract readonly friendlyName: string;
+ public abstract readonly setupUrl: string;
+ public abstract readonly requiredScopes: string[];
+
abstract init(): void;
/**
+ * Returns whether a connection has all the required settings
+ */
+ public abstract get isConfigured(): boolean;
+
+ /**
* Generates an authorization url for the connection.
* @param userId the user id to generate the url for
* @returns the authorization url
diff --git a/src/util/connections/ConnectionLoader.ts b/src/util/connections/ConnectionLoader.ts
index f75b430..021ef3a 100644
--- a/src/util/connections/ConnectionLoader.ts
+++ b/src/util/connections/ConnectionLoader.ts
@@ -21,6 +21,7 @@
import path from "path";
import { ConnectionConfig } from "./ConnectionConfig";
import { ConnectionStore } from "./ConnectionStore";
+import { greenBright, redBright } from "picocolors";
const root = path.join(__dirname, "..", "..", "connections");
const connectionsLoaded = false;
@@ -44,7 +45,15 @@
ConnectionStore.connections.set(mod.id, mod);
mod.init();
- // console.log(`[Connections] Loaded connection '${mod.id}'`);
+ console.log(`[Connections] Loaded connection '${mod.id}' (${mod.friendlyName}) -`, mod.settings.enabled ? greenBright("enabled") : redBright("disabled"));
+ if (mod.settings.enabled && !mod.isConfigured) {
+ console.log(`[Connections/${mod.id}] Connection is enabled, but not configured! Users will not be able to successfully link with ${mod.friendlyName}!`);
+ if (mod.requiredScopes.length > 0) {
+ console.log(`[Connections/${mod.id}] Configuring this connection requires setting scopes, or has additional requirements:`);
+ for (const scope in mod.requiredScopes) console.log(`[Connections/${mod.id}] - ${scope}`);
+ console.log(`[Connections/${mod.id}] You can obtain the required credentials here: ${mod.setupUrl}`);
+ }
+ }
});
}