mirror of
https://github.com/spacebarchat/server.git
synced 2026-07-31 02:49:42 +00:00
Prettier connections
This commit is contained in:
@@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectedAccount,
|
||||
ConnectedAccountCommonOAuthTokenResponse,
|
||||
Connection,
|
||||
ConnectionLoader,
|
||||
DiscordApiErrors,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectedAccount, ConnectedAccountCommonOAuthTokenResponse, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
|
||||
import wretch from "wretch";
|
||||
import { BattleNetSettings } from "./BattleNetSettings";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
interface BattleNetConnectionUser {
|
||||
sub: string;
|
||||
@@ -47,16 +41,9 @@ export default class BattleNetConnection extends Connection {
|
||||
settings: BattleNetSettings = new BattleNetSettings();
|
||||
|
||||
init(): void {
|
||||
this.settings = ConnectionLoader.getConnectionConfig<BattleNetSettings>(
|
||||
this.id,
|
||||
this.settings,
|
||||
);
|
||||
this.settings = ConnectionLoader.getConnectionConfig<BattleNetSettings>(this.id, this.settings);
|
||||
|
||||
if (
|
||||
this.settings.enabled &&
|
||||
(!this.settings.clientId || !this.settings.clientSecret)
|
||||
)
|
||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
}
|
||||
|
||||
getAuthorizationUrl(userId: string): string {
|
||||
@@ -75,10 +62,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();
|
||||
@@ -118,9 +102,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");
|
||||
|
||||
|
||||
@@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectedAccount,
|
||||
ConnectedAccountCommonOAuthTokenResponse,
|
||||
Connection,
|
||||
ConnectionLoader,
|
||||
DiscordApiErrors,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectedAccount, ConnectedAccountCommonOAuthTokenResponse, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
|
||||
import wretch from "wretch";
|
||||
import { DiscordSettings } from "./DiscordSettings";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
interface UserResponse {
|
||||
id: string;
|
||||
@@ -43,16 +37,9 @@ export default class DiscordConnection extends Connection {
|
||||
settings: DiscordSettings = new DiscordSettings();
|
||||
|
||||
init(): void {
|
||||
this.settings = ConnectionLoader.getConnectionConfig<DiscordSettings>(
|
||||
this.id,
|
||||
this.settings,
|
||||
);
|
||||
this.settings = ConnectionLoader.getConnectionConfig<DiscordSettings>(this.id, this.settings);
|
||||
|
||||
if (
|
||||
this.settings.enabled &&
|
||||
(!this.settings.clientId || !this.settings.clientSecret)
|
||||
)
|
||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
}
|
||||
|
||||
getAuthorizationUrl(userId: string): string {
|
||||
@@ -74,10 +61,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();
|
||||
|
||||
@@ -117,9 +101,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");
|
||||
|
||||
|
||||
@@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectedAccount,
|
||||
ConnectedAccountCommonOAuthTokenResponse,
|
||||
Connection,
|
||||
ConnectionLoader,
|
||||
DiscordApiErrors,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectedAccount, ConnectedAccountCommonOAuthTokenResponse, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
|
||||
import wretch from "wretch";
|
||||
import { EpicGamesSettings } from "./EpicGamesSettings";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
export interface UserResponse {
|
||||
accountId: string;
|
||||
@@ -33,8 +27,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,22 +40,14 @@ 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 {
|
||||
this.settings = ConnectionLoader.getConnectionConfig<EpicGamesSettings>(
|
||||
this.id,
|
||||
this.settings,
|
||||
);
|
||||
this.settings = ConnectionLoader.getConnectionConfig<EpicGamesSettings>(this.id, this.settings);
|
||||
|
||||
if (
|
||||
this.settings.enabled &&
|
||||
(!this.settings.clientId || !this.settings.clientSecret)
|
||||
)
|
||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
}
|
||||
|
||||
getAuthorizationUrl(userId: string): string {
|
||||
@@ -81,10 +66,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();
|
||||
@@ -92,9 +74,7 @@ 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(
|
||||
@@ -112,9 +92,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);
|
||||
|
||||
@@ -130,9 +108,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");
|
||||
|
||||
|
||||
@@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectedAccount,
|
||||
ConnectedAccountCommonOAuthTokenResponse,
|
||||
Connection,
|
||||
ConnectionLoader,
|
||||
DiscordApiErrors,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectedAccount, ConnectedAccountCommonOAuthTokenResponse, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
|
||||
import wretch from "wretch";
|
||||
import { FacebookSettings } from "./FacebookSettings";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
export interface FacebookErrorResponse {
|
||||
error: {
|
||||
@@ -43,25 +37,16 @@ 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 {
|
||||
this.settings = ConnectionLoader.getConnectionConfig<FacebookSettings>(
|
||||
this.id,
|
||||
this.settings,
|
||||
);
|
||||
this.settings = ConnectionLoader.getConnectionConfig<FacebookSettings>(this.id, this.settings);
|
||||
|
||||
if (
|
||||
this.settings.enabled &&
|
||||
(!this.settings.clientId || !this.settings.clientSecret)
|
||||
)
|
||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
}
|
||||
|
||||
getAuthorizationUrl(userId: string): string {
|
||||
@@ -80,19 +65,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);
|
||||
@@ -124,9 +103,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");
|
||||
|
||||
|
||||
@@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectedAccount,
|
||||
ConnectedAccountCommonOAuthTokenResponse,
|
||||
Connection,
|
||||
ConnectionLoader,
|
||||
DiscordApiErrors,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectedAccount, ConnectedAccountCommonOAuthTokenResponse, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
|
||||
import wretch from "wretch";
|
||||
import { GitHubSettings } from "./GitHubSettings";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
interface UserResponse {
|
||||
login: string;
|
||||
@@ -42,16 +36,9 @@ export default class GitHubConnection extends Connection {
|
||||
settings: GitHubSettings = new GitHubSettings();
|
||||
|
||||
init(): void {
|
||||
this.settings = ConnectionLoader.getConnectionConfig<GitHubSettings>(
|
||||
this.id,
|
||||
this.settings,
|
||||
);
|
||||
this.settings = ConnectionLoader.getConnectionConfig<GitHubSettings>(this.id, this.settings);
|
||||
|
||||
if (
|
||||
this.settings.enabled &&
|
||||
(!this.settings.clientId || !this.settings.clientSecret)
|
||||
)
|
||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
}
|
||||
|
||||
getAuthorizationUrl(userId: string): string {
|
||||
@@ -68,18 +55,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);
|
||||
@@ -111,9 +92,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");
|
||||
|
||||
|
||||
@@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectedAccount,
|
||||
ConnectedAccountCommonOAuthTokenResponse,
|
||||
Connection,
|
||||
ConnectionLoader,
|
||||
DiscordApiErrors,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectedAccount, ConnectedAccountCommonOAuthTokenResponse, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
|
||||
import wretch from "wretch";
|
||||
import { RedditSettings } from "./RedditSettings";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
export interface UserResponse {
|
||||
verified: boolean;
|
||||
@@ -54,16 +48,9 @@ export default class RedditConnection extends Connection {
|
||||
settings: RedditSettings = new RedditSettings();
|
||||
|
||||
init(): void {
|
||||
this.settings = ConnectionLoader.getConnectionConfig<RedditSettings>(
|
||||
this.id,
|
||||
this.settings,
|
||||
);
|
||||
this.settings = ConnectionLoader.getConnectionConfig<RedditSettings>(this.id, this.settings);
|
||||
|
||||
if (
|
||||
this.settings.enabled &&
|
||||
(!this.settings.clientId || !this.settings.clientSecret)
|
||||
)
|
||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
}
|
||||
|
||||
getAuthorizationUrl(userId: string): string {
|
||||
@@ -82,10 +69,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();
|
||||
@@ -93,9 +77,7 @@ 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(
|
||||
@@ -127,9 +109,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");
|
||||
|
||||
|
||||
@@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectedAccount,
|
||||
ConnectedAccountCommonOAuthTokenResponse,
|
||||
ConnectionLoader,
|
||||
DiscordApiErrors,
|
||||
RefreshableConnection,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectedAccount, ConnectedAccountCommonOAuthTokenResponse, ConnectionLoader, DiscordApiErrors, RefreshableConnection } from "@spacebar/util";
|
||||
import wretch from "wretch";
|
||||
import { SpotifySettings } from "./SpotifySettings";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
export interface UserResponse {
|
||||
display_name: string;
|
||||
@@ -49,12 +43,7 @@ export default class SpotifyConnection extends RefreshableConnection {
|
||||
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";
|
||||
public readonly scopes = [
|
||||
"user-read-private",
|
||||
"user-read-playback-state",
|
||||
"user-modify-playback-state",
|
||||
"user-read-currently-playing",
|
||||
];
|
||||
public readonly scopes = ["user-read-private", "user-read-playback-state", "user-modify-playback-state", "user-read-currently-playing"];
|
||||
settings: SpotifySettings = new SpotifySettings();
|
||||
|
||||
init(): void {
|
||||
@@ -64,16 +53,9 @@ export default class SpotifyConnection extends RefreshableConnection {
|
||||
*/
|
||||
this.refreshEnabled = false;
|
||||
|
||||
this.settings = ConnectionLoader.getConnectionConfig<SpotifySettings>(
|
||||
this.id,
|
||||
this.settings,
|
||||
);
|
||||
this.settings = ConnectionLoader.getConnectionConfig<SpotifySettings>(this.id, this.settings);
|
||||
|
||||
if (
|
||||
this.settings.enabled &&
|
||||
(!this.settings.clientId || !this.settings.clientSecret)
|
||||
)
|
||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
}
|
||||
|
||||
getAuthorizationUrl(userId: string): string {
|
||||
@@ -92,10 +74,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();
|
||||
@@ -104,11 +83,7 @@ export default class SpotifyConnection extends RefreshableConnection {
|
||||
.headers({
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Authorization: `Basic ${Buffer.from(
|
||||
`${this.settings.clientId as string}:${
|
||||
this.settings.clientSecret as string
|
||||
}`,
|
||||
).toString("base64")}`,
|
||||
Authorization: `Basic ${Buffer.from(`${this.settings.clientId as string}:${this.settings.clientSecret as string}`).toString("base64")}`,
|
||||
})
|
||||
.body(
|
||||
new URLSearchParams({
|
||||
@@ -125,11 +100,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();
|
||||
|
||||
@@ -137,11 +109,7 @@ export default class SpotifyConnection extends RefreshableConnection {
|
||||
.headers({
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Authorization: `Basic ${Buffer.from(
|
||||
`${this.settings.clientId as string}:${
|
||||
this.settings.clientSecret as string
|
||||
}`,
|
||||
).toString("base64")}`,
|
||||
Authorization: `Basic ${Buffer.from(`${this.settings.clientId as string}:${this.settings.clientSecret as string}`).toString("base64")}`,
|
||||
})
|
||||
.body(
|
||||
new URLSearchParams({
|
||||
@@ -177,9 +145,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");
|
||||
|
||||
|
||||
@@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectedAccount,
|
||||
ConnectedAccountCommonOAuthTokenResponse,
|
||||
ConnectionLoader,
|
||||
DiscordApiErrors,
|
||||
RefreshableConnection,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectedAccount, ConnectedAccountCommonOAuthTokenResponse, ConnectionLoader, DiscordApiErrors, RefreshableConnection } from "@spacebar/util";
|
||||
import wretch from "wretch";
|
||||
import { TwitchSettings } from "./TwitchSettings";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
interface TwitchConnectionUserResponse {
|
||||
data: {
|
||||
@@ -47,24 +41,13 @@ 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 {
|
||||
this.settings = ConnectionLoader.getConnectionConfig<TwitchSettings>(
|
||||
this.id,
|
||||
this.settings,
|
||||
);
|
||||
this.settings = ConnectionLoader.getConnectionConfig<TwitchSettings>(this.id, this.settings);
|
||||
|
||||
if (
|
||||
this.settings.enabled &&
|
||||
(!this.settings.clientId || !this.settings.clientSecret)
|
||||
)
|
||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
}
|
||||
|
||||
getAuthorizationUrl(userId: string): string {
|
||||
@@ -83,10 +66,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();
|
||||
@@ -113,11 +93,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();
|
||||
@@ -164,9 +141,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");
|
||||
|
||||
|
||||
@@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectedAccount,
|
||||
ConnectedAccountCommonOAuthTokenResponse,
|
||||
ConnectionLoader,
|
||||
DiscordApiErrors,
|
||||
RefreshableConnection,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectedAccount, ConnectedAccountCommonOAuthTokenResponse, ConnectionLoader, DiscordApiErrors, RefreshableConnection } from "@spacebar/util";
|
||||
import wretch from "wretch";
|
||||
import { TwitterSettings } from "./TwitterSettings";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
interface TwitterUserResponse {
|
||||
data: {
|
||||
@@ -49,22 +43,14 @@ export default class TwitterConnection extends RefreshableConnection {
|
||||
public readonly id = "twitter";
|
||||
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";
|
||||
public readonly userInfoUrl = "https://api.twitter.com/2/users/me?user.fields=created_at%2Cdescription%2Cid%2Cname%2Cusername%2Cverified%2Clocation%2Curl";
|
||||
public readonly scopes = ["users.read", "tweet.read"];
|
||||
settings: TwitterSettings = new TwitterSettings();
|
||||
|
||||
init(): void {
|
||||
this.settings = ConnectionLoader.getConnectionConfig<TwitterSettings>(
|
||||
this.id,
|
||||
this.settings,
|
||||
);
|
||||
this.settings = ConnectionLoader.getConnectionConfig<TwitterSettings>(this.id, this.settings);
|
||||
|
||||
if (
|
||||
this.settings.enabled &&
|
||||
(!this.settings.clientId || !this.settings.clientSecret)
|
||||
)
|
||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
}
|
||||
|
||||
getAuthorizationUrl(userId: string): string {
|
||||
@@ -85,10 +71,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();
|
||||
@@ -97,11 +80,7 @@ export default class TwitterConnection extends RefreshableConnection {
|
||||
.headers({
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Authorization: `Basic ${Buffer.from(
|
||||
`${this.settings.clientId as string}:${
|
||||
this.settings.clientSecret as string
|
||||
}`,
|
||||
).toString("base64")}`,
|
||||
Authorization: `Basic ${Buffer.from(`${this.settings.clientId as string}:${this.settings.clientSecret as string}`).toString("base64")}`,
|
||||
})
|
||||
.body(
|
||||
new URLSearchParams({
|
||||
@@ -120,11 +99,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();
|
||||
@@ -133,11 +109,7 @@ export default class TwitterConnection extends RefreshableConnection {
|
||||
.headers({
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Authorization: `Basic ${Buffer.from(
|
||||
`${this.settings.clientId as string}:${
|
||||
this.settings.clientSecret as string
|
||||
}`,
|
||||
).toString("base64")}`,
|
||||
Authorization: `Basic ${Buffer.from(`${this.settings.clientId as string}:${this.settings.clientSecret as string}`).toString("base64")}`,
|
||||
})
|
||||
.body(
|
||||
new URLSearchParams({
|
||||
@@ -170,9 +142,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");
|
||||
|
||||
|
||||
@@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectedAccount,
|
||||
ConnectedAccountCommonOAuthTokenResponse,
|
||||
Connection,
|
||||
ConnectionLoader,
|
||||
DiscordApiErrors,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectedAccount, ConnectedAccountCommonOAuthTokenResponse, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
|
||||
import wretch from "wretch";
|
||||
import { XboxSettings } from "./XboxSettings";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
interface XboxUserResponse {
|
||||
IssueInstant: string;
|
||||
@@ -51,27 +45,17 @@ 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 {
|
||||
this.settings = ConnectionLoader.getConnectionConfig<XboxSettings>(
|
||||
this.id,
|
||||
this.settings,
|
||||
);
|
||||
this.settings = ConnectionLoader.getConnectionConfig<XboxSettings>(this.id, this.settings);
|
||||
|
||||
if (
|
||||
this.settings.enabled &&
|
||||
(!this.settings.clientId || !this.settings.clientSecret)
|
||||
)
|
||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
}
|
||||
|
||||
getAuthorizationUrl(userId: string): string {
|
||||
@@ -117,10 +101,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();
|
||||
@@ -129,11 +110,7 @@ export default class XboxConnection extends Connection {
|
||||
.headers({
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Authorization: `Basic ${Buffer.from(
|
||||
`${this.settings.clientId as string}:${
|
||||
this.settings.clientSecret as string
|
||||
}`,
|
||||
).toString("base64")}`,
|
||||
Authorization: `Basic ${Buffer.from(`${this.settings.clientId as string}:${this.settings.clientSecret as string}`).toString("base64")}`,
|
||||
})
|
||||
.body(
|
||||
new URLSearchParams({
|
||||
@@ -179,9 +156,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");
|
||||
|
||||
@@ -190,10 +165,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;
|
||||
|
||||
|
||||
@@ -16,16 +16,10 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectedAccount,
|
||||
ConnectedAccountCommonOAuthTokenResponse,
|
||||
Connection,
|
||||
ConnectionLoader,
|
||||
DiscordApiErrors,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectedAccount, ConnectedAccountCommonOAuthTokenResponse, Connection, ConnectionLoader, DiscordApiErrors } from "@spacebar/util";
|
||||
import wretch from "wretch";
|
||||
import { YoutubeSettings } from "./YoutubeSettings";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
interface YouTubeConnectionChannelListResult {
|
||||
items: {
|
||||
@@ -51,27 +45,16 @@ 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 {
|
||||
this.settings = ConnectionLoader.getConnectionConfig<YoutubeSettings>(
|
||||
this.id,
|
||||
this.settings,
|
||||
);
|
||||
this.settings = ConnectionLoader.getConnectionConfig<YoutubeSettings>(this.id, this.settings);
|
||||
|
||||
if (
|
||||
this.settings.enabled &&
|
||||
(!this.settings.clientId || !this.settings.clientSecret)
|
||||
)
|
||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
if (this.settings.enabled && (!this.settings.clientId || !this.settings.clientSecret)) throw new Error(`Invalid settings for connection ${this.id}`);
|
||||
}
|
||||
|
||||
getAuthorizationUrl(userId: string): string {
|
||||
@@ -90,10 +73,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();
|
||||
@@ -134,9 +114,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");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user