Skip to content

Commit

Permalink
fix(Discord Node): When using OAuth2 authentication, check if user is…
Browse files Browse the repository at this point in the history
… a guild member when sending direct message (#9183)
  • Loading branch information
michael-radency authored and ivov committed Apr 25, 2024
1 parent 44bcc03 commit d0250b2
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const description = updateDisplayOptions(displayOptions, properties);

export async function execute(
this: IExecuteFunctions,
guildId: string,
_guildId: string,
userGuilds: IDataObject[],
): Promise<INodeExecutionData[]> {
const returnData: INodeExecutionData[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const description = updateDisplayOptions(displayOptions, properties);

export async function execute(
this: IExecuteFunctions,
guildId: string,
_guildId: string,
userGuilds: IDataObject[],
): Promise<INodeExecutionData[]> {
const returnData: INodeExecutionData[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const description = updateDisplayOptions(displayOptions, properties);

export async function execute(
this: IExecuteFunctions,
guildId: string,
_guildId: string,
userGuilds: IDataObject[],
): Promise<INodeExecutionData[]> {
const returnData: INodeExecutionData[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const description = updateDisplayOptions(displayOptions, properties);

export async function execute(
this: IExecuteFunctions,
guildId: string,
_guildId: string,
userGuilds: IDataObject[],
): Promise<INodeExecutionData[]> {
const returnData: INodeExecutionData[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const description = updateDisplayOptions(displayOptions, properties);

export async function execute(
this: IExecuteFunctions,
guildId: string,
_guildId: string,
userGuilds: IDataObject[],
): Promise<INodeExecutionData[]> {
const returnData: INodeExecutionData[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const description = updateDisplayOptions(displayOptions, properties);

export async function execute(
this: IExecuteFunctions,
guildId: string,
_guildId: string,
userGuilds: IDataObject[],
): Promise<INodeExecutionData[]> {
const returnData: INodeExecutionData[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const description = updateDisplayOptions(displayOptions, properties);

export async function execute(
this: IExecuteFunctions,
guildId: string,
_guildId: string,
userGuilds: IDataObject[],
): Promise<INodeExecutionData[]> {
const returnData: INodeExecutionData[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {
INodeExecutionData,
INodeProperties,
} from 'n8n-workflow';
import { NodeOperationError } from 'n8n-workflow';
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
import { updateDisplayOptions } from '../../../../../utils/utilities';
import { discordApiMultiPartRequest, discordApiRequest } from '../../transport';
import {
Expand Down Expand Up @@ -153,7 +153,7 @@ export async function execute(
};

if (embeds) {
body.embeds = prepareEmbeds.call(this, embeds, i);
body.embeds = prepareEmbeds.call(this, embeds);
}

try {
Expand All @@ -166,11 +166,39 @@ export async function execute(
extractValue: true,
}) as string;

if (isOAuth2) {
try {
await discordApiRequest.call(this, 'GET', `/guilds/${guildId}/members/${userId}`);
} catch (error) {
if (error instanceof NodeApiError && error.httpCode === '404') {
throw new NodeOperationError(
this.getNode(),
`User with the id ${userId} is not a member of the selected guild`,
{
itemIndex: i,
},
);
}

throw new NodeOperationError(this.getNode(), error, {
itemIndex: i,
});
}
}

channelId = (
(await discordApiRequest.call(this, 'POST', '/users/@me/channels', {
recipient_id: userId,
})) as IDataObject
).id as string;

if (!channelId) {
throw new NodeOperationError(
this.getNode(),
'Could not create a channel to send direct message to',
{ itemIndex: i },
);
}
}

if (sendTo === 'channel') {
Expand All @@ -179,11 +207,13 @@ export async function execute(
}) as string;
}

if (!channelId) {
throw new NodeOperationError(this.getNode(), 'Channel ID is required');
if (isOAuth2 && sendTo !== 'user') {
await checkAccessToChannel.call(this, channelId, userGuilds, i);
}

if (isOAuth2) await checkAccessToChannel.call(this, channelId, userGuilds, i);
if (!channelId) {
throw new NodeOperationError(this.getNode(), 'Channel ID is required', { itemIndex: i });
}

let response: IDataObject[] = [];

Expand Down
6 changes: 3 additions & 3 deletions packages/nodes-base/nodes/Discord/v2/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ export function prepareOptions(options: IDataObject, guildId?: string) {
return options;
}

export function prepareEmbeds(this: IExecuteFunctions, embeds: IDataObject[], i = 0) {
export function prepareEmbeds(this: IExecuteFunctions, embeds: IDataObject[]) {
return embeds
.map((embed, index) => {
.map((embed) => {
let embedReturnData: IDataObject = {};

if (embed.inputMethod === 'json') {
Expand Down Expand Up @@ -261,7 +261,7 @@ export async function checkAccessToChannel(
if (!guildId) {
throw new NodeOperationError(
this.getNode(),
`Could not fing server for channel with the id ${channelId}`,
`Could not find server for channel with the id ${channelId}`,
{
itemIndex,
},
Expand Down
2 changes: 1 addition & 1 deletion packages/nodes-base/nodes/Discord/v2/methods/listSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export async function categorySearch(this: ILoadOptionsFunctions): Promise<INode

export async function userSearch(
this: ILoadOptionsFunctions,
filter?: string,
_filter?: string,
paginationToken?: string,
): Promise<INodeListSearchResult> {
const guildId = await getGuildId.call(this);
Expand Down
4 changes: 2 additions & 2 deletions packages/nodes-base/nodes/Discord/v2/transport/discord.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export async function discordApiRequest(
if (remaining === 0) {
await sleep(resetAfter);
} else {
await sleep(20); //prevent excing global rate limit of 50 requests per second
await sleep(20); //prevent exceeding global rate limit of 50 requests per second
}

return response.body || { success: true };
Expand Down Expand Up @@ -91,7 +91,7 @@ export async function discordApiMultiPartRequest(
if (remaining === 0) {
await sleep(resetAfter);
} else {
await sleep(20); //prevent excing global rate limit of 50 requests per second
await sleep(20); //prevent exceeding global rate limit of 50 requests per second
}

return jsonParse<IDataObject[]>(response.body);
Expand Down

0 comments on commit d0250b2

Please sign in to comment.