diff --git a/src/connections/BattleNet/index.ts b/src/connections/BattleNet/index.ts
index 8e8eeeed..96c3993c 100644
--- a/src/connections/BattleNet/index.ts
+++ b/src/connections/BattleNet/index.ts
@@ -1,5 +1,4 @@
import {
- ApiError,
Config,
ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse,
@@ -7,7 +6,7 @@ import {
ConnectionLoader,
DiscordApiErrors,
} from "@fosscord/util";
-import fetch from "node-fetch";
+import wretch from "wretch";
import Connection from "../../util/connections/Connection";
import { BattleNetSettings } from "./BattleNetSettings";
@@ -67,68 +66,40 @@ export default class BattleNetConnection extends Connection {
const url = this.getTokenUrl();
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
- },
- body: new URLSearchParams({
- grant_type: "authorization_code",
- code: code,
- client_id: this.settings.clientId!,
- client_secret: this.settings.clientSecret!,
- redirect_uri: `${
- Config.get().cdn.endpointPrivate || "http://localhost:3001"
- }/connections/${this.id}/callback`,
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to exchange code", 0, 400);
- }
-
- return res.json();
})
- .then(
- (
- res: ConnectedAccountCommonOAuthTokenResponse &
- BattleNetErrorResponse,
- ) => {
- if (res.error) throw new Error(res.error_description);
- return res;
- },
+ .body(
+ new URLSearchParams({
+ grant_type: "authorization_code",
+ code: code,
+ client_id: this.settings.clientId!,
+ client_secret: this.settings.clientSecret!,
+ redirect_uri: `${
+ Config.get().cdn.endpointPrivate ||
+ "http://localhost:3001"
+ }/connections/${this.id}/callback`,
+ }),
)
+ .post()
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error exchanging token for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
async getUser(token: string): Promise<BattleNetConnectionUser> {
const url = new URL(this.userInfoUrl);
- return fetch(url.toString(), {
- method: "GET",
- headers: {
+ return wretch(url.toString())
+ .headers({
Authorization: `Bearer ${token}`,
- },
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to fetch user", 0, 400);
- }
-
- return res.json();
- })
- .then((res: BattleNetConnectionUser & BattleNetErrorResponse) => {
- if (res.error) throw new Error(res.error_description);
- return res;
})
+ .get()
+ .json<BattleNetConnectionUser>()
.catch((e) => {
- console.error(
- `Error fetching user for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
diff --git a/src/connections/Discord/index.ts b/src/connections/Discord/index.ts
index 23f5d978..52fc9ffd 100644
--- a/src/connections/Discord/index.ts
+++ b/src/connections/Discord/index.ts
@@ -1,5 +1,4 @@
import {
- ApiError,
Config,
ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse,
@@ -7,7 +6,7 @@ import {
ConnectionLoader,
DiscordApiErrors,
} from "@fosscord/util";
-import fetch from "node-fetch";
+import wretch from "wretch";
import Connection from "../../util/connections/Connection";
import { DiscordSettings } from "./DiscordSettings";
@@ -66,56 +65,41 @@ export default class DiscordConnection extends Connection {
this.validateState(state);
const url = this.getTokenUrl();
- return fetch(url, {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
- },
- body: new URLSearchParams({
- client_id: this.settings.clientId!,
- client_secret: this.settings.clientSecret!,
- grant_type: "authorization_code",
- code: code,
- redirect_uri: `${
- Config.get().cdn.endpointPrivate || "http://localhost:3001"
- }/connections/${this.id}/callback`,
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to exchange token", 0, 400);
- }
-
- return res.json();
})
+ .body(
+ new URLSearchParams({
+ client_id: this.settings.clientId!,
+ client_secret: this.settings.clientSecret!,
+ grant_type: "authorization_code",
+ code: code,
+ redirect_uri: `${
+ Config.get().cdn.endpointPrivate ||
+ "http://localhost:3001"
+ }/connections/${this.id}/callback`,
+ }),
+ )
+ .post()
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error exchanging token for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
async getUser(token: string): Promise<UserResponse> {
const url = new URL(this.userInfoUrl);
- return fetch(url.toString(), {
- method: "GET",
- headers: {
+ return wretch(url.toString())
+ .headers({
Authorization: `Bearer ${token}`,
- },
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to fetch user", 0, 400);
- }
-
- return res.json();
})
+ .get()
+ .json<UserResponse>()
.catch((e) => {
- console.error(
- `Error fetching user for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
diff --git a/src/connections/EpicGames/index.ts b/src/connections/EpicGames/index.ts
index c720dc5d..247d2435 100644
--- a/src/connections/EpicGames/index.ts
+++ b/src/connections/EpicGames/index.ts
@@ -1,5 +1,4 @@
import {
- ApiError,
Config,
ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse,
@@ -7,7 +6,7 @@ import {
ConnectionLoader,
DiscordApiErrors,
} from "@fosscord/util";
-import fetch from "node-fetch";
+import wretch from "wretch";
import Connection from "../../util/connections/Connection";
import { EpicGamesSettings } from "./EpicGamesSettings";
@@ -73,31 +72,24 @@ export default class EpicGamesConnection extends Connection {
const url = this.getTokenUrl();
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
Authorization: `Basic ${Buffer.from(
`${this.settings.clientId}:${this.settings.clientSecret}`,
).toString("base64")}`,
"Content-Type": "application/x-www-form-urlencoded",
- },
- body: new URLSearchParams({
- grant_type: "authorization_code",
- code,
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to exchange code", 0, 400);
- }
-
- return res.json();
})
+ .body(
+ new URLSearchParams({
+ grant_type: "authorization_code",
+ code,
+ }),
+ )
+ .post()
+ .json<EpicTokenResponse>()
.catch((e) => {
- console.error(
- `Error exchanging token for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
@@ -108,23 +100,15 @@ export default class EpicGamesConnection extends Connection {
);
const url = new URL(this.userInfoUrl);
url.searchParams.append("accountId", sub);
- return fetch(url.toString(), {
- method: "GET",
- headers: {
+
+ return wretch(url.toString())
+ .headers({
Authorization: `Bearer ${token}`,
- },
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to fetch user", 0, 400);
- }
-
- return res.json();
})
+ .get()
+ .json<UserResponse[]>()
.catch((e) => {
- console.error(
- `Error fetching user for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
diff --git a/src/connections/Facebook/index.ts b/src/connections/Facebook/index.ts
index 67f8da79..5413f867 100644
--- a/src/connections/Facebook/index.ts
+++ b/src/connections/Facebook/index.ts
@@ -1,5 +1,4 @@
import {
- ApiError,
Config,
ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse,
@@ -7,7 +6,7 @@ import {
ConnectionLoader,
DiscordApiErrors,
} from "@fosscord/util";
-import fetch from "node-fetch";
+import wretch from "wretch";
import Connection from "../../util/connections/Connection";
import { FacebookSettings } from "./FacebookSettings";
@@ -83,59 +82,29 @@ export default class FacebookConnection extends Connection {
const url = this.getTokenUrl(code);
- return fetch(url.toString(), {
- method: "GET",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
- },
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to exchange code", 0, 400);
- }
-
- return res.json();
})
- .then(
- (
- res: ConnectedAccountCommonOAuthTokenResponse &
- FacebookErrorResponse,
- ) => {
- if (res.error) throw new Error(res.error.message);
- return res;
- },
- )
+ .get()
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error exchanging token for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
async getUser(token: string): Promise<UserResponse> {
const url = new URL(this.userInfoUrl);
- return fetch(url.toString(), {
- method: "GET",
- headers: {
+
+ return wretch(url.toString())
+ .headers({
Authorization: `Bearer ${token}`,
- },
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to fetch user", 0, 400);
- }
-
- return res.json();
- })
- .then((res: UserResponse & FacebookErrorResponse) => {
- if (res.error) throw new Error(res.error.message);
- return res;
})
+ .get()
+ .json<UserResponse>()
.catch((e) => {
- console.error(
- `Error fetching user for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
diff --git a/src/connections/GitHub/index.ts b/src/connections/GitHub/index.ts
index aa686b03..8380e765 100644
--- a/src/connections/GitHub/index.ts
+++ b/src/connections/GitHub/index.ts
@@ -1,5 +1,4 @@
import {
- ApiError,
Config,
ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse,
@@ -7,7 +6,7 @@ import {
ConnectionLoader,
DiscordApiErrors,
} from "@fosscord/util";
-import fetch from "node-fetch";
+import wretch from "wretch";
import Connection from "../../util/connections/Connection";
import { GitHubSettings } from "./GitHubSettings";
@@ -65,46 +64,29 @@ export default class GitHubConnection extends Connection {
const url = this.getTokenUrl(code);
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
- },
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to exchange code", 0, 400);
- }
-
- return res.json();
})
+
+ .post()
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error exchanging code for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
async getUser(token: string): Promise<UserResponse> {
const url = new URL(this.userInfoUrl);
- return fetch(url.toString(), {
- method: "GET",
- headers: {
+ return wretch(url.toString())
+ .headers({
Authorization: `Bearer ${token}`,
- },
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to fetch user", 0, 400);
- }
-
- return res.json();
})
+ .get()
+ .json<UserResponse>()
.catch((e) => {
- console.error(
- `Error fetching user for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
diff --git a/src/connections/Reddit/index.ts b/src/connections/Reddit/index.ts
index 06fbcbe5..70b4a8af 100644
--- a/src/connections/Reddit/index.ts
+++ b/src/connections/Reddit/index.ts
@@ -1,5 +1,4 @@
import {
- ApiError,
Config,
ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse,
@@ -7,7 +6,7 @@ import {
ConnectionLoader,
DiscordApiErrors,
} from "@fosscord/util";
-import fetch from "node-fetch";
+import wretch from "wretch";
import Connection from "../../util/connections/Connection";
import { RedditSettings } from "./RedditSettings";
@@ -74,57 +73,42 @@ export default class RedditConnection extends Connection {
const url = this.getTokenUrl();
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
Authorization: `Basic ${Buffer.from(
`${this.settings.clientId}:${this.settings.clientSecret}`,
).toString("base64")}`,
"Content-Type": "application/x-www-form-urlencoded",
- },
- body: new URLSearchParams({
- grant_type: "authorization_code",
- code: code,
- redirect_uri: `${
- Config.get().cdn.endpointPrivate || "http://localhost:3001"
- }/connections/${this.id}/callback`,
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to code", 0, 400);
- }
-
- return res.json();
})
+ .body(
+ new URLSearchParams({
+ grant_type: "authorization_code",
+ code: code,
+ redirect_uri: `${
+ Config.get().cdn.endpointPrivate ||
+ "http://localhost:3001"
+ }/connections/${this.id}/callback`,
+ }),
+ )
+ .post()
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error exchanging code for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
async getUser(token: string): Promise<UserResponse> {
const url = new URL(this.userInfoUrl);
- return fetch(url.toString(), {
- method: "GET",
- headers: {
+ return wretch(url.toString())
+ .headers({
Authorization: `Bearer ${token}`,
- },
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to fetch user", 0, 400);
- }
-
- return res.json();
})
+ .get()
+ .json<UserResponse>()
.catch((e) => {
- console.error(
- `Error fetching user for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
diff --git a/src/connections/Spotify/index.ts b/src/connections/Spotify/index.ts
index 44a4bc28..54ec2696 100644
--- a/src/connections/Spotify/index.ts
+++ b/src/connections/Spotify/index.ts
@@ -1,5 +1,4 @@
import {
- ApiError,
Config,
ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse,
@@ -7,7 +6,7 @@ import {
ConnectionLoader,
DiscordApiErrors,
} from "@fosscord/util";
-import fetch from "node-fetch";
+import wretch from "wretch";
import RefreshableConnection from "../../util/connections/RefreshableConnection";
import { SpotifySettings } from "./SpotifySettings";
@@ -83,122 +82,78 @@ export default class SpotifyConnection extends RefreshableConnection {
const url = this.getTokenUrl();
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `Basic ${Buffer.from(
`${this.settings.clientId!}:${this.settings.clientSecret!}`,
).toString("base64")}`,
- },
- body: new URLSearchParams({
- grant_type: "authorization_code",
- code: code,
- redirect_uri: `${
- Config.get().cdn.endpointPrivate || "http://localhost:3001"
- }/connections/${this.id}/callback`,
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to refresh token", 0, 400);
- }
-
- return res.json();
})
- .then(
- (
- res: ConnectedAccountCommonOAuthTokenResponse &
- TokenErrorResponse,
- ) => {
- if (res.error)
- throw new ApiError(res.error_description, 0, 400);
- return res;
- },
+ .body(
+ new URLSearchParams({
+ grant_type: "authorization_code",
+ code: code,
+ redirect_uri: `${
+ Config.get().cdn.endpointPrivate ||
+ "http://localhost:3001"
+ }/connections/${this.id}/callback`,
+ }),
)
+ .post()
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error exchanging code for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
- async refreshToken(connectedAccount: ConnectedAccount) {
+ 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();
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `Basic ${Buffer.from(
`${this.settings.clientId!}:${this.settings.clientSecret!}`,
).toString("base64")}`,
- },
- body: new URLSearchParams({
- grant_type: "refresh_token",
- refresh_token,
- }),
- })
- .then(async (res) => {
- if ([400, 401].includes(res.status)) {
- // assume the token was revoked
- await connectedAccount.revoke();
- return DiscordApiErrors.CONNECTION_REVOKED;
- }
- // otherwise throw a general error
- if (!res.ok) {
- throw new ApiError("Failed to refresh token", 0, 400);
- }
-
- return await res.json();
})
- .then(
- (
- res: ConnectedAccountCommonOAuthTokenResponse &
- TokenErrorResponse,
- ) => {
- if (res.error)
- throw new ApiError(res.error_description, 0, 400);
- return res;
- },
+ .body(
+ new URLSearchParams({
+ grant_type: "refresh_token",
+ refresh_token,
+ }),
)
+ .post()
+ .unauthorized(async () => {
+ // assume the token was revoked
+ await connectedAccount.revoke();
+ return DiscordApiErrors.CONNECTION_REVOKED;
+ })
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error refreshing token for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
async getUser(token: string): Promise<UserResponse> {
const url = new URL(this.userInfoUrl);
- return fetch(url.toString(), {
- method: "GET",
- headers: {
+
+ return wretch(url.toString())
+ .headers({
Authorization: `Bearer ${token}`,
- },
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to fetch user", 0, 400);
- }
-
- return res.json();
- })
- .then((res: UserResponse & ErrorResponse) => {
- if (res.error) throw new Error(res.error.message);
- return res;
})
+ .get()
+ .json<UserResponse>()
.catch((e) => {
- console.error(
- `Error fetching user for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
diff --git a/src/connections/Twitch/index.ts b/src/connections/Twitch/index.ts
index ce04f098..264db3cc 100644
--- a/src/connections/Twitch/index.ts
+++ b/src/connections/Twitch/index.ts
@@ -1,5 +1,4 @@
import {
- ApiError,
Config,
ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse,
@@ -7,7 +6,7 @@ import {
ConnectionLoader,
DiscordApiErrors,
} from "@fosscord/util";
-import fetch from "node-fetch";
+import wretch from "wretch";
import RefreshableConnection from "../../util/connections/RefreshableConnection";
import { TwitchSettings } from "./TwitchSettings";
@@ -75,33 +74,27 @@ export default class TwitchConnection extends RefreshableConnection {
const url = this.getTokenUrl();
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
- },
- body: new URLSearchParams({
- grant_type: "authorization_code",
- code: code,
- client_id: this.settings.clientId!,
- client_secret: this.settings.clientSecret!,
- redirect_uri: `${
- Config.get().cdn.endpointPrivate || "http://localhost:3001"
- }/connections/${this.id}/callback`,
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to exchange code", 0, 400);
- }
-
- return res.json();
})
+ .body(
+ new URLSearchParams({
+ grant_type: "authorization_code",
+ code: code,
+ client_id: this.settings.clientId!,
+ client_secret: this.settings.clientSecret!,
+ redirect_uri: `${
+ Config.get().cdn.endpointPrivate ||
+ "http://localhost:3001"
+ }/connections/${this.id}/callback`,
+ }),
+ )
+ .post()
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error exchanging code for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
@@ -115,60 +108,44 @@ export default class TwitchConnection extends RefreshableConnection {
const url = this.getTokenUrl();
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
- },
- body: new URLSearchParams({
- grant_type: "refresh_token",
- client_id: this.settings.clientId!,
- client_secret: this.settings.clientSecret!,
- refresh_token: refresh_token,
- }),
- })
- .then(async (res) => {
- if ([400, 401].includes(res.status)) {
- // assume the token was revoked
- await connectedAccount.revoke();
- return DiscordApiErrors.CONNECTION_REVOKED;
- }
- // otherwise throw a general error
- if (!res.ok) {
- throw new ApiError("Failed to refresh token", 0, 400);
- }
-
- return await res.json();
})
+ .body(
+ new URLSearchParams({
+ grant_type: "refresh_token",
+ client_id: this.settings.clientId!,
+ client_secret: this.settings.clientSecret!,
+ refresh_token: refresh_token,
+ }),
+ )
+ .post()
+ .unauthorized(async () => {
+ // assume the token was revoked
+ await connectedAccount.revoke();
+ return DiscordApiErrors.CONNECTION_REVOKED;
+ })
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error refreshing token for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
async getUser(token: string): Promise<TwitchConnectionUserResponse> {
const url = new URL(this.userInfoUrl);
- return fetch(url.toString(), {
- method: "GET",
- headers: {
+
+ return wretch(url.toString())
+ .headers({
Authorization: `Bearer ${token}`,
"Client-Id": this.settings.clientId!,
- },
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to fetch user", 0, 400);
- }
-
- return res.json();
})
+ .get()
+ .json<TwitchConnectionUserResponse>()
.catch((e) => {
- console.error(
- `Error fetching user for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
diff --git a/src/connections/Twitter/index.ts b/src/connections/Twitter/index.ts
index d8a765ac..ad9d55d4 100644
--- a/src/connections/Twitter/index.ts
+++ b/src/connections/Twitter/index.ts
@@ -1,5 +1,4 @@
import {
- ApiError,
Config,
ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse,
@@ -7,7 +6,7 @@ import {
ConnectionLoader,
DiscordApiErrors,
} from "@fosscord/util";
-import fetch from "node-fetch";
+import wretch from "wretch";
import RefreshableConnection from "../../util/connections/RefreshableConnection";
import { TwitterSettings } from "./TwitterSettings";
@@ -77,45 +76,30 @@ export default class TwitterConnection extends RefreshableConnection {
const url = this.getTokenUrl();
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `Basic ${Buffer.from(
`${this.settings.clientId!}:${this.settings.clientSecret!}`,
).toString("base64")}`,
- },
- body: new URLSearchParams({
- grant_type: "authorization_code",
- code: code,
- client_id: this.settings.clientId!,
- redirect_uri: `${
- Config.get().cdn.endpointPrivate || "http://localhost:3001"
- }/connections/${this.id}/callback`,
- code_verifier: "challenge", // TODO: properly use PKCE challenge
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to exchange code", 0, 400);
- }
-
- return res.json();
})
- .then(
- (
- res: ConnectedAccountCommonOAuthTokenResponse &
- TwitterErrorResponse,
- ) => {
- if (res.error) throw new Error(res.error_description);
- return res;
- },
+ .body(
+ new URLSearchParams({
+ grant_type: "authorization_code",
+ code: code,
+ client_id: this.settings.clientId!,
+ redirect_uri: `${
+ Config.get().cdn.endpointPrivate ||
+ "http://localhost:3001"
+ }/connections/${this.id}/callback`,
+ code_verifier: "challenge", // TODO: properly use PKCE challenge
+ }),
)
+ .post()
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error exchanging code for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
@@ -129,72 +113,44 @@ export default class TwitterConnection extends RefreshableConnection {
const url = this.getTokenUrl();
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `Basic ${Buffer.from(
`${this.settings.clientId!}:${this.settings.clientSecret!}`,
).toString("base64")}`,
- },
- body: new URLSearchParams({
- grant_type: "refresh_token",
- refresh_token,
- client_id: this.settings.clientId!,
- redirect_uri: `${
- Config.get().cdn.endpointPrivate || "http://localhost:3001"
- }/connections/${this.id}/callback`,
- code_verifier: "challenge", // TODO: properly use PKCE challenge
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to exchange code", 0, 400);
- }
-
- return res.json();
})
- .then(
- (
- res: ConnectedAccountCommonOAuthTokenResponse &
- TwitterErrorResponse,
- ) => {
- if (res.error) throw new Error(res.error_description);
- return res;
- },
+ .body(
+ new URLSearchParams({
+ grant_type: "refresh_token",
+ refresh_token,
+ client_id: this.settings.clientId!,
+ redirect_uri: `${
+ Config.get().cdn.endpointPrivate ||
+ "http://localhost:3001"
+ }/connections/${this.id}/callback`,
+ code_verifier: "challenge", // TODO: properly use PKCE challenge
+ }),
)
+ .post()
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error exchanging code for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
async getUser(token: string): Promise<TwitterUserResponse> {
const url = new URL(this.userInfoUrl);
- return fetch(url.toString(), {
- method: "GET",
- headers: {
+ return wretch(url.toString())
+ .headers({
Authorization: `Bearer ${token}`,
- },
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to fetch user", 0, 400);
- }
-
- return res.json();
- })
- .then((res: TwitterUserResponse & TwitterErrorResponse) => {
- if (res.error) throw new Error(res.error_description);
- return res;
})
+ .get()
+ .json<TwitterUserResponse>()
.catch((e) => {
- console.error(
- `Error fetching user for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
diff --git a/src/connections/Xbox/index.ts b/src/connections/Xbox/index.ts
index eb0e2496..80a04dea 100644
--- a/src/connections/Xbox/index.ts
+++ b/src/connections/Xbox/index.ts
@@ -1,5 +1,4 @@
import {
- ApiError,
Config,
ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse,
@@ -7,7 +6,7 @@ import {
ConnectionLoader,
DiscordApiErrors,
} from "@fosscord/util";
-import fetch from "node-fetch";
+import wretch from "wretch";
import Connection from "../../util/connections/Connection";
import { XboxSettings } from "./XboxSettings";
@@ -76,36 +75,28 @@ export default class XboxConnection extends Connection {
}
async getUserToken(token: string): Promise<string> {
- return fetch(this.userAuthUrl, {
- method: "POST",
- headers: {
+ return wretch(this.userAuthUrl)
+ .headers({
"x-xbl-contract-version": "3",
"Content-Type": "application/json",
Accept: "application/json",
- },
- body: JSON.stringify({
- RelyingParty: "http://auth.xboxlive.com",
- TokenType: "JWT",
- Properties: {
- AuthMethod: "RPS",
- SiteName: "user.auth.xboxlive.com",
- RpsTicket: `d=${token}`,
- },
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to get user token", 0, 400);
- }
-
- return res.json();
})
- .then((res) => res.Token)
+ .body(
+ JSON.stringify({
+ RelyingParty: "http://auth.xboxlive.com",
+ TokenType: "JWT",
+ Properties: {
+ AuthMethod: "RPS",
+ SiteName: "user.auth.xboxlive.com",
+ RpsTicket: `d=${token}`,
+ },
+ }),
+ )
+ .post()
+ .json((res: XboxUserResponse) => res.Token)
.catch((e) => {
- console.error(
- `Error getting user token for ${this.id} connection: ${e}`,
- );
- throw DiscordApiErrors.INVALID_OAUTH_TOKEN;
+ console.error(e);
+ throw DiscordApiErrors.GENERAL_ERROR;
});
}
@@ -117,82 +108,57 @@ export default class XboxConnection extends Connection {
const url = this.getTokenUrl();
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+ return wretch(url.toString())
+ .headers({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `Basic ${Buffer.from(
`${this.settings.clientId!}:${this.settings.clientSecret!}`,
).toString("base64")}`,
- },
- body: new URLSearchParams({
- grant_type: "authorization_code",
- code: code,
- client_id: this.settings.clientId!,
- redirect_uri: `${
- Config.get().cdn.endpointPrivate || "http://localhost:3001"
- }/connections/${this.id}/callback`,
- scope: this.scopes.join(" "),
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to exchange code", 0, 400);
- }
-
- return res.json();
})
- .then(
- (
- res: ConnectedAccountCommonOAuthTokenResponse &
- XboxErrorResponse,
- ) => {
- if (res.error) throw new Error(res.error_description);
- return res;
- },
+ .body(
+ new URLSearchParams({
+ grant_type: "authorization_code",
+ code: code,
+ client_id: this.settings.clientId!,
+ redirect_uri: `${
+ Config.get().cdn.endpointPrivate ||
+ "http://localhost:3001"
+ }/connections/${this.id}/callback`,
+ scope: this.scopes.join(" "),
+ }),
)
+ .post()
+ .json<ConnectedAccountCommonOAuthTokenResponse>()
.catch((e) => {
- console.error(
- `Error exchanging code for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
async getUser(token: string): Promise<XboxUserResponse> {
const url = new URL(this.userInfoUrl);
- return fetch(url.toString(), {
- method: "POST",
- headers: {
+
+ return wretch(url.toString())
+ .headers({
"x-xbl-contract-version": "3",
"Content-Type": "application/json",
Accept: "application/json",
- },
- body: JSON.stringify({
- RelyingParty: "http://xboxlive.com",
- TokenType: "JWT",
- Properties: {
- UserTokens: [token],
- SandboxId: "RETAIL",
- },
- }),
- })
- .then((res) => {
- if (!res.ok) {
- throw new ApiError("Failed to fetch user", 0, 400);
- }
-
- return res.json();
- })
- .then((res: XboxUserResponse & XboxErrorResponse) => {
- if (res.error) throw new Error(res.error_description);
- return res;
})
+ .body(
+ JSON.stringify({
+ RelyingParty: "http://xboxlive.com",
+ TokenType: "JWT",
+ Properties: {
+ UserTokens: [token],
+ SandboxId: "RETAIL",
+ },
+ }),
+ )
+ .post()
+ .json<XboxUserResponse>()
.catch((e) => {
- console.error(
- `Error fetching user for ${this.id} connection: ${e}`,
- );
+ console.error(e);
throw DiscordApiErrors.GENERAL_ERROR;
});
}
|