Move redirect uri generation to getRedirectUri function of Connection class.

Use api_endpointPublic instead of cdn_endpointPublic
This commit is contained in:
Madeline 2023-01-24 18:15:26 +11:00 committed by Puyodead1
parent 9d5c5a8292
commit c7277efbad
No known key found for this signature in database
GPG Key ID: A4FA4FEC0DD353FC
15 changed files with 45 additions and 138 deletions

5
package-lock.json generated
View File

@ -14178,6 +14178,11 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}, },
"wretch": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/wretch/-/wretch-2.3.2.tgz",
"integrity": "sha512-brN97Z2Mwed+w5z+keYI1u5OwWhPIaW0sJi9CxtKBVxLc3aqP6j1+2FCoIskM7WJq6SUHdxTFx20ox0iDLa0mQ=="
},
"ws": { "ws": {
"version": "8.11.0", "version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",

View File

@ -3,7 +3,7 @@ import {
ConnectedAccount, ConnectedAccount,
ConnectionUpdateSchema, ConnectionUpdateSchema,
DiscordApiErrors, DiscordApiErrors,
emitEvent emitEvent,
} from "@fosscord/util"; } from "@fosscord/util";
import { Request, Response, Router } from "express"; import { Request, Response, Router } from "express";
const router = Router(); const router = Router();
@ -38,10 +38,12 @@ router.patch(
if (!connection) return DiscordApiErrors.UNKNOWN_CONNECTION; if (!connection) return DiscordApiErrors.UNKNOWN_CONNECTION;
// TODO: do we need to do anything if the connection is revoked? // TODO: do we need to do anything if the connection is revoked?
//@ts-ignore For some reason the client sends this as a boolean, even tho docs say its a number? if (typeof body.visibility === "boolean")
if (typeof body.visibility === "boolean") body.visibility = body.visibility ? 1 : 0; //@ts-expect-error For some reason the client sends this as a boolean, even tho docs say its a number?
//@ts-ignore For some reason the client sends this as a boolean, even tho docs say its a number? body.visibility = body.visibility ? 1 : 0;
if (typeof body.show_activity === "boolean") body.show_activity = body.show_activity ? 1 : 0; if (typeof body.show_activity === "boolean")
//@ts-expect-error For some reason the client sends this as a boolean, even tho docs say its a number?
body.show_activity = body.show_activity ? 1 : 0;
connection.assign(req.body); connection.assign(req.body);

View File

@ -1,5 +1,4 @@
import { import {
Config,
ConnectedAccount, ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse, ConnectedAccountCommonOAuthTokenResponse,
ConnectionCallbackSchema, ConnectionCallbackSchema,
@ -41,13 +40,7 @@ export default class BattleNetConnection extends Connection {
const url = new URL(this.authorizeUrl); const url = new URL(this.authorizeUrl);
url.searchParams.append("client_id", this.settings.clientId!); url.searchParams.append("client_id", this.settings.clientId!);
// TODO: probably shouldn't rely on cdn as this could be different from what we actually want. we should have an api endpoint setting. url.searchParams.append("redirect_uri", this.getRedirectUri());
url.searchParams.append(
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
url.searchParams.append("scope", this.scopes.join(" ")); url.searchParams.append("scope", this.scopes.join(" "));
url.searchParams.append("state", state); url.searchParams.append("state", state);
url.searchParams.append("response_type", "code"); url.searchParams.append("response_type", "code");
@ -76,10 +69,7 @@ export default class BattleNetConnection extends Connection {
code: code, code: code,
client_id: this.settings.clientId!, client_id: this.settings.clientId!,
client_secret: this.settings.clientSecret!, client_secret: this.settings.clientSecret!,
redirect_uri: `${ redirect_uri: this.getRedirectUri(),
Config.get().cdn.endpointPrivate ||
"http://localhost:3001"
}/connections/${this.id}/callback`,
}), }),
) )
.post() .post()

View File

@ -1,5 +1,4 @@
import { import {
Config,
ConnectedAccount, ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse, ConnectedAccountCommonOAuthTokenResponse,
ConnectionCallbackSchema, ConnectionCallbackSchema,
@ -42,14 +41,7 @@ export default class DiscordConnection extends Connection {
url.searchParams.append("response_type", "code"); url.searchParams.append("response_type", "code");
// controls whether, on repeated authorizations, the consent screen is shown // controls whether, on repeated authorizations, the consent screen is shown
url.searchParams.append("consent", "none"); url.searchParams.append("consent", "none");
url.searchParams.append("redirect_uri", this.getRedirectUri());
// TODO: probably shouldn't rely on cdn as this could be different from what we actually want. we should have an api endpoint setting.
url.searchParams.append(
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
return url.toString(); return url.toString();
} }
@ -76,10 +68,7 @@ export default class DiscordConnection extends Connection {
client_secret: this.settings.clientSecret!, client_secret: this.settings.clientSecret!,
grant_type: "authorization_code", grant_type: "authorization_code",
code: code, code: code,
redirect_uri: `${ redirect_uri: this.getRedirectUri(),
Config.get().cdn.endpointPrivate ||
"http://localhost:3001"
}/connections/${this.id}/callback`,
}), }),
) )
.post() .post()

View File

@ -1,5 +1,4 @@
import { import {
Config,
ConnectedAccount, ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse, ConnectedAccountCommonOAuthTokenResponse,
ConnectionCallbackSchema, ConnectionCallbackSchema,
@ -47,13 +46,7 @@ export default class EpicGamesConnection extends Connection {
const url = new URL(this.authorizeUrl); const url = new URL(this.authorizeUrl);
url.searchParams.append("client_id", this.settings.clientId!); url.searchParams.append("client_id", this.settings.clientId!);
// TODO: probably shouldn't rely on cdn as this could be different from what we actually want. we should have an api endpoint setting. url.searchParams.append("redirect_uri", this.getRedirectUri());
url.searchParams.append(
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
url.searchParams.append("response_type", "code"); url.searchParams.append("response_type", "code");
url.searchParams.append("scope", this.scopes.join(" ")); url.searchParams.append("scope", this.scopes.join(" "));
url.searchParams.append("state", state); url.searchParams.append("state", state);

View File

@ -1,5 +1,4 @@
import { import {
Config,
ConnectedAccount, ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse, ConnectedAccountCommonOAuthTokenResponse,
ConnectionCallbackSchema, ConnectionCallbackSchema,
@ -46,13 +45,7 @@ export default class FacebookConnection extends Connection {
const url = new URL(this.authorizeUrl); const url = new URL(this.authorizeUrl);
url.searchParams.append("client_id", this.settings.clientId!); url.searchParams.append("client_id", this.settings.clientId!);
// TODO: probably shouldn't rely on cdn as this could be different from what we actually want. we should have an api endpoint setting. url.searchParams.append("redirect_uri", this.getRedirectUri());
url.searchParams.append(
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
url.searchParams.append("state", state); url.searchParams.append("state", state);
url.searchParams.append("response_type", "code"); url.searchParams.append("response_type", "code");
url.searchParams.append("scope", this.scopes.join(" ")); url.searchParams.append("scope", this.scopes.join(" "));
@ -65,12 +58,7 @@ export default class FacebookConnection extends Connection {
url.searchParams.append("client_id", this.settings.clientId!); url.searchParams.append("client_id", this.settings.clientId!);
url.searchParams.append("client_secret", this.settings.clientSecret!); url.searchParams.append("client_secret", this.settings.clientSecret!);
url.searchParams.append("code", code); url.searchParams.append("code", code);
url.searchParams.append( url.searchParams.append("redirect_uri", this.getRedirectUri());
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
return url.toString(); return url.toString();
} }

View File

@ -1,5 +1,4 @@
import { import {
Config,
ConnectedAccount, ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse, ConnectedAccountCommonOAuthTokenResponse,
ConnectionCallbackSchema, ConnectionCallbackSchema,
@ -36,13 +35,7 @@ export default class GitHubConnection extends Connection {
const url = new URL(this.authorizeUrl); const url = new URL(this.authorizeUrl);
url.searchParams.append("client_id", this.settings.clientId!); url.searchParams.append("client_id", this.settings.clientId!);
// TODO: probably shouldn't rely on cdn as this could be different from what we actually want. we should have an api endpoint setting. url.searchParams.append("redirect_uri", this.getRedirectUri());
url.searchParams.append(
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
url.searchParams.append("scope", this.scopes.join(" ")); url.searchParams.append("scope", this.scopes.join(" "));
url.searchParams.append("state", state); url.searchParams.append("state", state);
return url.toString(); return url.toString();

View File

@ -1,5 +1,4 @@
import { import {
Config,
ConnectedAccount, ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse, ConnectedAccountCommonOAuthTokenResponse,
ConnectionCallbackSchema, ConnectionCallbackSchema,
@ -48,13 +47,7 @@ export default class RedditConnection extends Connection {
const url = new URL(this.authorizeUrl); const url = new URL(this.authorizeUrl);
url.searchParams.append("client_id", this.settings.clientId!); url.searchParams.append("client_id", this.settings.clientId!);
// TODO: probably shouldn't rely on cdn as this could be different from what we actually want. we should have an api endpoint setting. url.searchParams.append("redirect_uri", this.getRedirectUri());
url.searchParams.append(
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
url.searchParams.append("response_type", "code"); url.searchParams.append("response_type", "code");
url.searchParams.append("scope", this.scopes.join(" ")); url.searchParams.append("scope", this.scopes.join(" "));
url.searchParams.append("state", state); url.searchParams.append("state", state);
@ -85,10 +78,7 @@ export default class RedditConnection extends Connection {
new URLSearchParams({ new URLSearchParams({
grant_type: "authorization_code", grant_type: "authorization_code",
code: code, code: code,
redirect_uri: `${ redirect_uri: this.getRedirectUri(),
Config.get().cdn.endpointPrivate ||
"http://localhost:3001"
}/connections/${this.id}/callback`,
}), }),
) )
.post() .post()

View File

@ -1,5 +1,4 @@
import { import {
Config,
ConnectedAccount, ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse, ConnectedAccountCommonOAuthTokenResponse,
ConnectionCallbackSchema, ConnectionCallbackSchema,
@ -57,13 +56,7 @@ export default class SpotifyConnection extends RefreshableConnection {
const url = new URL(this.authorizeUrl); const url = new URL(this.authorizeUrl);
url.searchParams.append("client_id", this.settings.clientId!); url.searchParams.append("client_id", this.settings.clientId!);
// TODO: probably shouldn't rely on cdn as this could be different from what we actually want. we should have an api endpoint setting. url.searchParams.append("redirect_uri", this.getRedirectUri());
url.searchParams.append(
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
url.searchParams.append("response_type", "code"); url.searchParams.append("response_type", "code");
url.searchParams.append("scope", this.scopes.join(" ")); url.searchParams.append("scope", this.scopes.join(" "));
url.searchParams.append("state", state); url.searchParams.append("state", state);
@ -94,10 +87,7 @@ export default class SpotifyConnection extends RefreshableConnection {
new URLSearchParams({ new URLSearchParams({
grant_type: "authorization_code", grant_type: "authorization_code",
code: code, code: code,
redirect_uri: `${ redirect_uri: this.getRedirectUri(),
Config.get().cdn.endpointPrivate ||
"http://localhost:3001"
}/connections/${this.id}/callback`,
}), }),
) )
.post() .post()

View File

@ -1,5 +1,4 @@
import { import {
Config,
ConnectedAccount, ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse, ConnectedAccountCommonOAuthTokenResponse,
ConnectionCallbackSchema, ConnectionCallbackSchema,
@ -49,13 +48,7 @@ export default class TwitchConnection extends RefreshableConnection {
const url = new URL(this.authorizeUrl); const url = new URL(this.authorizeUrl);
url.searchParams.append("client_id", this.settings.clientId!); url.searchParams.append("client_id", this.settings.clientId!);
// TODO: probably shouldn't rely on cdn as this could be different from what we actually want. we should have an api endpoint setting. url.searchParams.append("redirect_uri", this.getRedirectUri());
url.searchParams.append(
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
url.searchParams.append("response_type", "code"); url.searchParams.append("response_type", "code");
url.searchParams.append("scope", this.scopes.join(" ")); url.searchParams.append("scope", this.scopes.join(" "));
url.searchParams.append("state", state); url.searchParams.append("state", state);
@ -85,10 +78,7 @@ export default class TwitchConnection extends RefreshableConnection {
code: code, code: code,
client_id: this.settings.clientId!, client_id: this.settings.clientId!,
client_secret: this.settings.clientSecret!, client_secret: this.settings.clientSecret!,
redirect_uri: `${ redirect_uri: this.getRedirectUri(),
Config.get().cdn.endpointPrivate ||
"http://localhost:3001"
}/connections/${this.id}/callback`,
}), }),
) )
.post() .post()

View File

@ -1,5 +1,4 @@
import { import {
Config,
ConnectedAccount, ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse, ConnectedAccountCommonOAuthTokenResponse,
ConnectionCallbackSchema, ConnectionCallbackSchema,
@ -49,13 +48,7 @@ export default class TwitterConnection extends RefreshableConnection {
const url = new URL(this.authorizeUrl); const url = new URL(this.authorizeUrl);
url.searchParams.append("client_id", this.settings.clientId!); url.searchParams.append("client_id", this.settings.clientId!);
// TODO: probably shouldn't rely on cdn as this could be different from what we actually want. we should have an api endpoint setting. url.searchParams.append("redirect_uri", this.getRedirectUri());
url.searchParams.append(
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
url.searchParams.append("response_type", "code"); url.searchParams.append("response_type", "code");
url.searchParams.append("scope", this.scopes.join(" ")); url.searchParams.append("scope", this.scopes.join(" "));
url.searchParams.append("state", state); url.searchParams.append("state", state);
@ -89,10 +82,7 @@ export default class TwitterConnection extends RefreshableConnection {
grant_type: "authorization_code", grant_type: "authorization_code",
code: code, code: code,
client_id: this.settings.clientId!, client_id: this.settings.clientId!,
redirect_uri: `${ redirect_uri: this.getRedirectUri(),
Config.get().cdn.endpointPrivate ||
"http://localhost:3001"
}/connections/${this.id}/callback`,
code_verifier: "challenge", // TODO: properly use PKCE challenge code_verifier: "challenge", // TODO: properly use PKCE challenge
}), }),
) )
@ -126,10 +116,7 @@ export default class TwitterConnection extends RefreshableConnection {
grant_type: "refresh_token", grant_type: "refresh_token",
refresh_token, refresh_token,
client_id: this.settings.clientId!, client_id: this.settings.clientId!,
redirect_uri: `${ redirect_uri: this.getRedirectUri(),
Config.get().cdn.endpointPrivate ||
"http://localhost:3001"
}/connections/${this.id}/callback`,
code_verifier: "challenge", // TODO: properly use PKCE challenge code_verifier: "challenge", // TODO: properly use PKCE challenge
}), }),
) )

View File

@ -1,5 +1,4 @@
import { import {
Config,
ConnectedAccount, ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse, ConnectedAccountCommonOAuthTokenResponse,
ConnectionCallbackSchema, ConnectionCallbackSchema,
@ -56,13 +55,7 @@ export default class XboxConnection extends Connection {
const url = new URL(this.authorizeUrl); const url = new URL(this.authorizeUrl);
url.searchParams.append("client_id", this.settings.clientId!); url.searchParams.append("client_id", this.settings.clientId!);
// TODO: probably shouldn't rely on cdn as this could be different from what we actually want. we should have an api endpoint setting. url.searchParams.append("redirect_uri", this.getRedirectUri());
url.searchParams.append(
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
url.searchParams.append("response_type", "code"); url.searchParams.append("response_type", "code");
url.searchParams.append("scope", this.scopes.join(" ")); url.searchParams.append("scope", this.scopes.join(" "));
url.searchParams.append("state", state); url.searchParams.append("state", state);
@ -121,10 +114,7 @@ export default class XboxConnection extends Connection {
grant_type: "authorization_code", grant_type: "authorization_code",
code: code, code: code,
client_id: this.settings.clientId!, client_id: this.settings.clientId!,
redirect_uri: `${ redirect_uri: this.getRedirectUri(),
Config.get().cdn.endpointPrivate ||
"http://localhost:3001"
}/connections/${this.id}/callback`,
scope: this.scopes.join(" "), scope: this.scopes.join(" "),
}), }),
) )

View File

@ -1,5 +1,4 @@
import { import {
Config,
ConnectedAccount, ConnectedAccount,
ConnectedAccountCommonOAuthTokenResponse, ConnectedAccountCommonOAuthTokenResponse,
ConnectionCallbackSchema, ConnectionCallbackSchema,
@ -56,13 +55,7 @@ export default class YoutubeConnection extends Connection {
const url = new URL(this.authorizeUrl); const url = new URL(this.authorizeUrl);
url.searchParams.append("client_id", this.settings.clientId!); url.searchParams.append("client_id", this.settings.clientId!);
// TODO: probably shouldn't rely on cdn as this could be different from what we actually want. we should have an api endpoint setting. url.searchParams.append("redirect_uri", this.getRedirectUri());
url.searchParams.append(
"redirect_uri",
`${
Config.get().cdn.endpointPrivate || "http://localhost:3001"
}/connections/${this.id}/callback`,
);
url.searchParams.append("response_type", "code"); url.searchParams.append("response_type", "code");
url.searchParams.append("scope", this.scopes.join(" ")); url.searchParams.append("scope", this.scopes.join(" "));
url.searchParams.append("state", state); url.searchParams.append("state", state);
@ -92,10 +85,7 @@ export default class YoutubeConnection extends Connection {
code: code, code: code,
client_id: this.settings.clientId!, client_id: this.settings.clientId!,
client_secret: this.settings.clientSecret!, client_secret: this.settings.clientSecret!,
redirect_uri: `${ redirect_uri: this.getRedirectUri(),
Config.get().cdn.endpointPrivate ||
"http://localhost:3001"
}/connections/${this.id}/callback`,
}), }),
) )
.post() .post()

View File

@ -20,5 +20,5 @@ export class ApiConfiguration {
defaultVersion: string = "9"; defaultVersion: string = "9";
activeVersions: string[] = ["6", "7", "8", "9"]; activeVersions: string[] = ["6", "7", "8", "9"];
useFosscordEnhancements: boolean = true; useFosscordEnhancements: boolean = true;
endpointPublic: string = "/api"; endpointPublic: string | null = null;
} }

View File

@ -1,7 +1,7 @@
import crypto from "crypto"; import crypto from "crypto";
import { ConnectedAccount } from "../entities"; import { ConnectedAccount } from "../entities";
import { ConnectedAccountSchema, ConnectionCallbackSchema } from "../schemas"; import { ConnectedAccountSchema, ConnectionCallbackSchema } from "../schemas";
import { DiscordApiErrors } from "../util"; import { Config, DiscordApiErrors } from "../util";
/** /**
* A connection that can be used to connect to an external service. * A connection that can be used to connect to an external service.
@ -19,6 +19,16 @@ export default abstract class Connection {
*/ */
abstract getAuthorizationUrl(userId: string): string; abstract getAuthorizationUrl(userId: string): string;
/**
* Returns the redirect_uri for a connection type
* @returns redirect_uri for this connection
*/
getRedirectUri() {
const endpointPublic =
Config.get().api.endpointPublic ?? "http://localhost:3001";
return `${endpointPublic}/connections/${this.id}/callback`;
}
/** /**
* Processes the callback * Processes the callback
* @param args Callback arguments * @param args Callback arguments