From 2ca187bd34a8cf2ac4ac7f2bdaecd0506c5b40bd Mon Sep 17 00:00:00 2001 From: Jacob Morrison Date: Mon, 19 Aug 2024 10:07:46 -0400 Subject: [PATCH] feat: Add support for Automated Message nonce handling (#10381) * Add support for Automated Message nonce handling * Fix options property * Address PR feedback * Handled case where it was explicitly set to false for that iteration to not generate a nonce, and PR feedback * Fix lint issue * Fix lint issue * Move to MessagePayload.resolveBody instead * Fix test errors * Update packages/discord.js/src/structures/MessagePayload.js Co-authored-by: Almeida * PR feedback * Merge * Let and not const --------- Co-authored-by: Almeida Co-authored-by: Almeida --- packages/discord.js/src/client/Client.js | 3 +++ .../discord.js/src/structures/MessagePayload.js | 15 ++++++++++++--- packages/discord.js/src/util/Options.js | 2 ++ packages/discord.js/typings/index.d.ts | 1 + 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/discord.js/src/client/Client.js b/packages/discord.js/src/client/Client.js index f45b0388b2cb..bbf1af478fc9 100644 --- a/packages/discord.js/src/client/Client.js +++ b/packages/discord.js/src/client/Client.js @@ -535,6 +535,9 @@ class Client extends BaseClient { if (typeof options.failIfNotExists !== 'boolean') { throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'failIfNotExists', 'a boolean'); } + if (typeof options.enforceNonce !== 'boolean') { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'enforceNonce', 'a boolean'); + } if ( (typeof options.allowedMentions !== 'object' && options.allowedMentions !== undefined) || options.allowedMentions === null diff --git a/packages/discord.js/src/structures/MessagePayload.js b/packages/discord.js/src/structures/MessagePayload.js index b8058d0f7aae..f21c9bbbc0cf 100644 --- a/packages/discord.js/src/structures/MessagePayload.js +++ b/packages/discord.js/src/structures/MessagePayload.js @@ -2,6 +2,7 @@ const { Buffer } = require('node:buffer'); const { lazy, isJSONEncodable } = require('@discordjs/util'); +const { DiscordSnowflake } = require('@sapphire/snowflake'); const { MessageFlags } = require('discord-api-types/v10'); const ActionRowBuilder = require('./ActionRowBuilder'); const { DiscordjsError, DiscordjsRangeError, ErrorCodes } = require('../errors'); @@ -133,9 +134,17 @@ class MessagePayload { } } - const enforce_nonce = Boolean(this.options.enforceNonce); - if (enforce_nonce && nonce === undefined) { - throw new DiscordjsError(ErrorCodes.MessageNonceRequired); + let enforce_nonce = Boolean(this.options.enforceNonce); + + // If `nonce` isn't provided, generate one & set `enforceNonce` + // Unless `enforceNonce` is explicitly set to `false`(not just falsy) + if (nonce === undefined) { + if (this.options.enforceNonce !== false && this.client.options.enforceNonce) { + nonce = DiscordSnowflake.generate().toString(); + enforce_nonce = true; + } else if (enforce_nonce) { + throw new DiscordjsError(ErrorCodes.MessageNonceRequired); + } } const components = this.options.components?.map(component => diff --git a/packages/discord.js/src/util/Options.js b/packages/discord.js/src/util/Options.js index 9e674b76d781..04ec75840c5e 100644 --- a/packages/discord.js/src/util/Options.js +++ b/packages/discord.js/src/util/Options.js @@ -41,6 +41,7 @@ const { version } = require('../../package.json'); * @property {WebsocketOptions} [ws] Options for the WebSocket * @property {RESTOptions} [rest] Options for the REST manager * @property {Function} [jsonTransformer] A function used to transform outgoing json data + * @property {boolean} [enforceNonce=false] The default value for {@link MessageReplyOptions#enforceNonce} */ /** @@ -117,6 +118,7 @@ class Options extends null { makeCache: this.cacheWithLimits(this.DefaultMakeCacheSettings), partials: [], failIfNotExists: true, + enforceNonce: false, presence: {}, sweepers: this.DefaultSweeperSettings, ws: { diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index b1071e1d3558..1b50d8f606b5 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -5311,6 +5311,7 @@ export interface ClientOptions { ws?: WebSocketOptions; rest?: Partial; jsonTransformer?: (obj: unknown) => unknown; + enforceNonce?: boolean; } export type ClientPresenceStatus = 'online' | 'idle' | 'dnd';