Make connections more verbose and include some setup instructions

This commit is contained in:
Rory&
2026-04-19 00:33:42 +02:00
parent ee2ec492e1
commit 9f82daf602
24 changed files with 122 additions and 247 deletions

View File

@@ -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 @@ interface BattleNetConnectionUser {
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 @@ export default class BattleNetConnection extends Connection {
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);

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
export class DiscordSettings {
enabled: boolean = false;
clientId: string | null = null;
clientSecret: string | null = null;
}

View File

@@ -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 @@ interface UserResponse {
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 @@ export default class DiscordConnection extends Connection {
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);

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
export class EpicGamesSettings {
enabled: boolean = false;
clientId: string | null = null;
clientSecret: string | null = null;
}

View File

@@ -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 interface EpicTokenResponse extends ConnectedAccountCommonOAuthTokenRespo
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 @@ export default class EpicGamesConnection extends Connection {
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);

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
export class FacebookSettings {
enabled: boolean = false;
clientId: string | null = null;
clientSecret: string | null = null;
}

View File

@@ -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 @@ interface UserResponse {
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 @@ export default class FacebookConnection extends Connection {
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);

View File

@@ -1,22 +1,22 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
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 <https://www.gnu.org/licenses/>.
*/
export class BattleNetSettings {
export class GenericOAuthSettings {
enabled: boolean = false;
clientId: string | null = null;
clientSecret: string | null = null;

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
export class GitHubSettings {
enabled: boolean = false;
clientId: string | null = null;
clientSecret: string | null = null;
}

View File

@@ -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 @@ interface UserResponse {
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 @@ export default class GitHubConnection extends Connection {
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);

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
export class RedditSettings {
enabled: boolean = false;
clientId: string | null = null;
clientSecret: string | null = null;
}

View File

@@ -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 interface ErrorResponse {
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 @@ export default class RedditConnection extends Connection {
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);

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
export class SpotifySettings {
enabled: boolean = false;
clientId: string | null = null;
clientSecret: string | null = null;
}

View File

@@ -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 interface ErrorResponse {
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 @@ export default class SpotifyConnection extends RefreshableConnection {
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);

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
export class TwitchSettings {
enabled: boolean = false;
clientId: string | null = null;
clientSecret: string | null = null;
}

View File

@@ -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 @@ interface TwitchConnectionUserResponse {
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 @@ export default class TwitchConnection extends RefreshableConnection {
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);

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
export class TwitterSettings {
enabled: boolean = false;
clientId: string | null = null;
clientSecret: string | null = null;
}

View File

@@ -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 @@ interface TwitterUserResponse {
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 @@ export default class TwitterConnection extends RefreshableConnection {
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);

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
export class XboxSettings {
enabled: boolean = false;
clientId: string | null = null;
clientSecret: string | null = null;
}

View File

@@ -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 @@ interface XboxUserResponse {
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 @@ export default class XboxConnection extends Connection {
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);

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
export class YoutubeSettings {
enabled: boolean = false;
clientId: string | null = null;
clientSecret: string | null = null;
}

View File

@@ -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 @@ interface YouTubeConnectionChannelListResult {
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 @@ export default class YoutubeConnection extends Connection {
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);

View File

@@ -29,8 +29,17 @@ export abstract class Connection {
settings: { enabled: boolean };
states: Map<string, string> = 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

View File

@@ -21,6 +21,7 @@ import fs from "fs";
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 @@ export class ConnectionLoader {
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}`);
}
}
});
}