replace node-fetch with wretch
This commit is contained in:
parent
06140fc768
commit
d8ecc4269f
9
package-lock.json
generated
9
package-lock.json
generated
@ -50,6 +50,7 @@
|
||||
"tslib": "^2.4.1",
|
||||
"typeorm": "^0.3.10",
|
||||
"typescript-json-schema": "^0.50.1",
|
||||
"wretch": "^2.3.2",
|
||||
"ws": "^8.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -7988,6 +7989,14 @@
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"node_modules/wretch": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/wretch/-/wretch-2.3.2.tgz",
|
||||
"integrity": "sha512-brN97Z2Mwed+w5z+keYI1u5OwWhPIaW0sJi9CxtKBVxLc3aqP6j1+2FCoIskM7WJq6SUHdxTFx20ox0iDLa0mQ==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.11.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
|
||||
|
@ -105,6 +105,7 @@
|
||||
"tslib": "^2.4.1",
|
||||
"typeorm": "^0.3.10",
|
||||
"typescript-json-schema": "^0.50.1",
|
||||
"wretch": "^2.3.2",
|
||||
"ws": "^8.9.0"
|
||||
},
|
||||
"_moduleAliases": {
|
||||
|
5745
pnpm-lock.yaml
generated
Normal file
5745
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -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({
|
||||
})
|
||||
.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"
|
||||
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;
|
||||
},
|
||||
)
|
||||
.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;
|
||||
});
|
||||
}
|
||||
|
@ -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({
|
||||
})
|
||||
.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"
|
||||
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();
|
||||
})
|
||||
)
|
||||
.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;
|
||||
});
|
||||
}
|
||||
|
@ -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({
|
||||
})
|
||||
.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();
|
||||
})
|
||||
)
|
||||
.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: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
throw new ApiError("Failed to fetch user", 0, 400);
|
||||
}
|
||||
|
||||
return res.json();
|
||||
return wretch(url.toString())
|
||||
.headers({
|
||||
Authorization: `Bearer ${token}`,
|
||||
})
|
||||
.get()
|
||||
.json<UserResponse[]>()
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`Error fetching user for ${this.id} connection: ${e}`,
|
||||
);
|
||||
console.error(e);
|
||||
throw DiscordApiErrors.GENERAL_ERROR;
|
||||
});
|
||||
}
|
||||
|
@ -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: {
|
||||
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;
|
||||
return wretch(url.toString())
|
||||
.headers({
|
||||
Authorization: `Bearer ${token}`,
|
||||
})
|
||||
.get()
|
||||
.json<UserResponse>()
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`Error fetching user for ${this.id} connection: ${e}`,
|
||||
);
|
||||
console.error(e);
|
||||
throw DiscordApiErrors.GENERAL_ERROR;
|
||||
});
|
||||
}
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
@ -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({
|
||||
})
|
||||
.body(
|
||||
new URLSearchParams({
|
||||
grant_type: "authorization_code",
|
||||
code: code,
|
||||
redirect_uri: `${
|
||||
Config.get().cdn.endpointPrivate || "http://localhost:3001"
|
||||
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();
|
||||
})
|
||||
)
|
||||
.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;
|
||||
});
|
||||
}
|
||||
|
@ -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({
|
||||
})
|
||||
.body(
|
||||
new URLSearchParams({
|
||||
grant_type: "authorization_code",
|
||||
code: code,
|
||||
redirect_uri: `${
|
||||
Config.get().cdn.endpointPrivate || "http://localhost:3001"
|
||||
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;
|
||||
},
|
||||
)
|
||||
.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({
|
||||
})
|
||||
.body(
|
||||
new URLSearchParams({
|
||||
grant_type: "refresh_token",
|
||||
refresh_token,
|
||||
}),
|
||||
})
|
||||
.then(async (res) => {
|
||||
if ([400, 401].includes(res.status)) {
|
||||
)
|
||||
.post()
|
||||
.unauthorized(async () => {
|
||||
// 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;
|
||||
},
|
||||
)
|
||||
.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: {
|
||||
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;
|
||||
return wretch(url.toString())
|
||||
.headers({
|
||||
Authorization: `Bearer ${token}`,
|
||||
})
|
||||
.get()
|
||||
.json<UserResponse>()
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`Error fetching user for ${this.id} connection: ${e}`,
|
||||
);
|
||||
console.error(e);
|
||||
throw DiscordApiErrors.GENERAL_ERROR;
|
||||
});
|
||||
}
|
||||
|
@ -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({
|
||||
})
|
||||
.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"
|
||||
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();
|
||||
})
|
||||
)
|
||||
.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({
|
||||
})
|
||||
.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)) {
|
||||
)
|
||||
.post()
|
||||
.unauthorized(async () => {
|
||||
// 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();
|
||||
})
|
||||
.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;
|
||||
});
|
||||
}
|
||||
|
@ -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({
|
||||
})
|
||||
.body(
|
||||
new URLSearchParams({
|
||||
grant_type: "authorization_code",
|
||||
code: code,
|
||||
client_id: this.settings.clientId!,
|
||||
redirect_uri: `${
|
||||
Config.get().cdn.endpointPrivate || "http://localhost:3001"
|
||||
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;
|
||||
},
|
||||
)
|
||||
.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({
|
||||
})
|
||||
.body(
|
||||
new URLSearchParams({
|
||||
grant_type: "refresh_token",
|
||||
refresh_token,
|
||||
client_id: this.settings.clientId!,
|
||||
redirect_uri: `${
|
||||
Config.get().cdn.endpointPrivate || "http://localhost:3001"
|
||||
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;
|
||||
},
|
||||
)
|
||||
.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;
|
||||
});
|
||||
}
|
||||
|
@ -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,14 +75,14 @@ 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({
|
||||
})
|
||||
.body(
|
||||
JSON.stringify({
|
||||
RelyingParty: "http://auth.xboxlive.com",
|
||||
TokenType: "JWT",
|
||||
Properties: {
|
||||
@ -92,20 +91,12 @@ export default class XboxConnection extends Connection {
|
||||
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)
|
||||
)
|
||||
.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,59 +108,45 @@ 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({
|
||||
})
|
||||
.body(
|
||||
new URLSearchParams({
|
||||
grant_type: "authorization_code",
|
||||
code: code,
|
||||
client_id: this.settings.clientId!,
|
||||
redirect_uri: `${
|
||||
Config.get().cdn.endpointPrivate || "http://localhost:3001"
|
||||
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;
|
||||
},
|
||||
)
|
||||
.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({
|
||||
})
|
||||
.body(
|
||||
JSON.stringify({
|
||||
RelyingParty: "http://xboxlive.com",
|
||||
TokenType: "JWT",
|
||||
Properties: {
|
||||
@ -177,22 +154,11 @@ export default class XboxConnection extends Connection {
|
||||
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;
|
||||
})
|
||||
)
|
||||
.post()
|
||||
.json<XboxUserResponse>()
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`Error fetching user for ${this.id} connection: ${e}`,
|
||||
);
|
||||
console.error(e);
|
||||
throw DiscordApiErrors.GENERAL_ERROR;
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user