diff --git a/packages/bot/src/helpers.ts b/packages/bot/src/helpers.ts index e5c8bbc5d..a1e7d009f 100644 --- a/packages/bot/src/helpers.ts +++ b/packages/bot/src/helpers.ts @@ -255,11 +255,11 @@ export function createBotHelpers(bot: Bot): BotHelpers { getCurrentAuthenticationInfo: async (bearerToken) => { return await bot.rest.getCurrentAuthenticationInfo(bearerToken) }, - exchangeToken: async (options) => { - return await bot.rest.exchangeToken(options) + exchangeToken: async (clientId, clientSecret, options) => { + return await bot.rest.exchangeToken(clientId, clientSecret, options) }, - revokeToken: async (options) => { - return await bot.rest.revokeToken(options) + revokeToken: async (clientId, clientSecret, options) => { + return await bot.rest.revokeToken(clientId, clientSecret, options) }, getApplicationCommandPermission: async (guildId, commandId, options) => { const res = await bot.rest.getApplicationCommandPermission(guildId, commandId, options) @@ -749,8 +749,8 @@ export interface BotHelpers { getActiveThreads: (guildId: BigString) => Promise<{ threads: Channel[]; members: ThreadMember[] }> getApplicationInfo: () => Promise getCurrentAuthenticationInfo: (bearerToken: string) => Promise - exchangeToken: (options: CamelizedDiscordTokenExchange) => Promise - revokeToken: (options: CamelizedDiscordTokenRevocation) => Promise + exchangeToken: (clientId: BigString, clientSecret: string, options: CamelizedDiscordTokenExchange) => Promise + revokeToken: (clientId: BigString, clientSecret: string, options: CamelizedDiscordTokenRevocation) => Promise getApplicationCommandPermission: ( guildId: BigString, commandId: BigString, diff --git a/packages/rest/src/manager.ts b/packages/rest/src/manager.ts index 101a5911d..007150de0 100644 --- a/packages/rest/src/manager.ts +++ b/packages/rest/src/manager.ts @@ -2,7 +2,7 @@ /* eslint-disable no-const-assign */ import { Buffer } from 'node:buffer' -import { calculateBits, camelToSnakeCase, camelize, delay, getBotIdFromToken, logger, processReactionString, urlToBase64 } from '@discordeno/utils' +import { calculateBits, camelize, camelToSnakeCase, delay, getBotIdFromToken, logger, processReactionString, urlToBase64 } from '@discordeno/utils' import { createInvalidRequestBucket } from './invalidBucket.js' import { Queue } from './queue.js' @@ -974,30 +974,33 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage }) }, - async exchangeToken(body) { + async exchangeToken(clientId, clientSecret, body) { + const basicCredentials = Buffer.from(`${clientId}:${clientSecret}`) + const restOptions: MakeRequestOptions = { body, headers: { 'content-type': 'application/x-www-form-urlencoded', + authorization: `Basic ${basicCredentials.toString('base64')}`, }, unauthorized: true, } if (body.grantType === 'client_credentials') { - const basicCredentials = Buffer.from(`${body.clientId}:${body.clientSecret}`) - restOptions.headers!.authorization = `Basic ${basicCredentials.toString('base64')}` - restOptions.body.scope = body.scope.join(' ') } return await rest.post(rest.routes.oauth2.tokenExchange(), restOptions) }, - async revokeToken(body) { + async revokeToken(clientId, clientSecret, body) { + const basicCredentials = Buffer.from(`${clientId}:${clientSecret}`) + await rest.post(rest.routes.oauth2.tokenRevoke(), { body, headers: { 'content-type': 'application/x-www-form-urlencoded', + authorization: `Basic ${basicCredentials.toString('base64')}`, }, unauthorized: true, }) diff --git a/packages/rest/src/types.ts b/packages/rest/src/types.ts index 991c96b79..e006a223f 100644 --- a/packages/rest/src/types.ts +++ b/packages/rest/src/types.ts @@ -86,8 +86,8 @@ import type { GetInvite, GetMessagesOptions, GetReactions, - GetScheduledEventUsers, GetScheduledEvents, + GetScheduledEventUsers, GetUserGuilds, GetWebhookMessageOptions, InteractionCallbackData, @@ -1497,15 +1497,19 @@ export interface RestManager { /** * Exchange the information to get a OAuth2 accessToken token * + * @param clientId - Application's client id + * @param clientSecret - application's client secret * @param options - The options to make the exchange with discord */ - exchangeToken: (options: CamelizedDiscordTokenExchange) => Promise + exchangeToken: (clientId: BigString, clientSecret: string, options: CamelizedDiscordTokenExchange) => Promise /** * Revoke an access_token * + * @param clientId - Application's client id + * @param clientSecret - application's client secret * @param options - The options to revoke the access_token */ - revokeToken: (options: CamelizedDiscordTokenRevocation) => Promise + revokeToken: (clientId: BigString, clientSecret: string, options: CamelizedDiscordTokenRevocation) => Promise /** * Gets the permissions of a guild application command. * diff --git a/packages/types/src/discord.ts b/packages/types/src/discord.ts index f2cbdb25f..e2d6f6d6b 100644 --- a/packages/types/src/discord.ts +++ b/packages/types/src/discord.ts @@ -6,7 +6,6 @@ import type { ApplicationCommandTypes, ApplicationFlags, AuditLogEvents, - BigString, ButtonStyles, ChannelFlags, ChannelTypes, @@ -377,10 +376,6 @@ export interface DiscordApplication { export type DiscordTokenExchange = DiscordTokenExchangeAuthorizationCode | DiscordTokenExchangeRefreshToken | DiscordTokenExchangeClientCredentials export interface DiscordTokenExchangeAuthorizationCode { - /** Application's client id */ - client_id: BigString - /** application's client secret */ - client_secret: string grant_type: 'authorization_code' /** The code for the token exchange */ code: string @@ -390,10 +385,6 @@ export interface DiscordTokenExchangeAuthorizationCode { /** https://discord.com/developers/docs/topics/oauth2#client-credentials-grant */ export interface DiscordTokenExchangeRefreshToken { - /** Application's client id */ - client_id: BigString - /** application's client secret */ - client_secret: string grant_type: 'refresh_token' /** the user's refresh token */ refresh_token: string @@ -401,10 +392,6 @@ export interface DiscordTokenExchangeRefreshToken { /** https://discord.com/developers/docs/topics/oauth2#client-credentials-grant */ export interface DiscordTokenExchangeClientCredentials { - /** Application's client id */ - client_id: BigString - /** application's client secret */ - client_secret: string grant_type: 'client_credentials' /** The scope(s) for the access token */ scope: OAuth2Scope[] @@ -433,12 +420,10 @@ export interface DiscordAccessTokenResponse { } export interface DiscordTokenRevocation { - /** Application's client id */ - client_id: BigString - /** application's client secret */ - client_secret: string /** The access token to revoke */ token: string + /** Optional, the type of token you are using for the revocation */ + token_type_hint?: 'access_token' | 'refresh_token' } /** https://discord.com/developers/docs/topics/oauth2#get-current-authorization-information-response-structure */