Skip to content

feat: add Discord service verification and token generation #2419

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Jun 18, 2025

Conversation

joyguptaa
Copy link
Contributor

@joyguptaa joyguptaa commented May 3, 2025

Date: 3 May 2025

Developer Name: Joy Gupta, @pankajjs


Issue Ticket Number

Description

This PR contains an update to the logic of verifyDiscordBot. With these changes, the same middleware could authorize the requests from both the Discord service and the Discord slash.

Documentation Updated?

  • Yes
  • No

Under Feature Flag

  • Yes
  • No

Database Changes

  • Yes
  • No

Breaking Changes

  • Yes
  • No

Development Tested?

  • Yes
  • No

Screenshots

Screenshot 1
screen-capture.1.webm

Test Coverage

Screenshot 2025-05-03 at 1 18 07 PM

Description by Korbit AI

What change is being made?

Add Discord service verification and token generation functionality, including updates to authorization middleware, new test cases, and configuration enhancements for handling Discord Service JWTs.

Why are these changes being made?

To implement authentication for Discord service interactions by validating incoming requests through JWTs, ensuring only authorized Discord services can access protected resources. This approach enhances security by expanding the authorization mechanism to support Discord service communications.

Is this description stale? Ask me to generate a new description by commenting /korbit-generate-pr-description

Copy link

coderabbitai bot commented May 3, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Summary by CodeRabbit

  • New Features

    • Added support for Discord Service authentication via a new header and token verification method.
  • Bug Fixes

    • Improved error handling for expired or malformed Discord Service tokens.
  • Tests

    • Introduced comprehensive tests for Discord Service authorization scenarios, including success and failure cases.
    • Added utilities for generating Discord Service tokens for testing.
  • Chores

    • Updated test configuration to include Discord Service public and private keys.

Walkthrough

A new constant for the Discord service was introduced and integrated into the bot constants. The bot authorization middleware was updated to check for a specific service header and use a new Discord service token verification function when appropriate. This function was implemented to validate JWTs using a dedicated public key. Test configuration was extended to include Discord service RSA keys, and a utility was added to generate Discord service tokens. The middleware's test suite was expanded with cases for Discord service authorization, ensuring correct handling of valid and invalid tokens.

Changes

File(s) Change Summary
constants/bot.ts Added DISCORD_SERVICE constant and included it in exports.
middlewares/authorizeBot.js Updated middleware to check for x-service-name header and use verifyDiscordService for Discord requests.
services/botVerificationService.js Added verifyDiscordService function and exported it.
test/config/test.js Added discordServiceToken object with PEM-encoded public/private RSA keys.
test/unit/middlewares/authorizeBot.test.js Added tests for Discord service authorization logic in the middleware.
test/utils/generateBotToken.js Added generateDiscordServiceToken function and exported it.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Middleware
    participant VerificationService

    Client->>Middleware: Request with Authorization token and x-service-name
    alt x-service-name == DISCORD_SERVICE
        Middleware->>VerificationService: verifyDiscordService(token)
        VerificationService-->>Middleware: Verification result
        alt name == DISCORD_SERVICE
            Middleware->>Client: Proceed (next middleware)
        else name mismatch
            Middleware->>Client: Unauthorized response
        end
    else
        Middleware->>VerificationService: verifyToken(token, CLOUDFLARE_WORKER)
        VerificationService-->>Middleware: Verification result
        alt valid
            Middleware->>Client: Proceed (next middleware)
        else invalid
            Middleware->>Client: Unauthorized response
        end
    end
Loading

Possibly related issues

Poem

A Discord token hops in, quite new,
With headers checked and keys in view.
The middleware sniffs, is this the right hare?
JWTs are verified with utmost care.
Tests now abound for every case,
Discord and Cloudflare—each in their place.
🐰✨ The service is safe, let’s celebrate this race!


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (2)
services/botVerificationService.js (1)

1-1: 💡 Verification agent

🧩 Analysis chain

Verify config module import is present.

The config object is used in the verification functions, but I don't see an import statement for it in this file.

Please verify that the config module is properly imported or globally available. You can check this with:


🏁 Script executed:

#!/bin/bash
# Check if config is properly imported in the file
grep -n "const config" services/botVerificationService.js || echo "config import missing"

# Check if it might be imported with a different name
grep -n "require.*config" services/botVerificationService.js

Length of output: 175


Add missing config import in services/botVerificationService.js

The config object is referenced in your verification functions but isn’t imported in this file. Please add the appropriate import at the top of services/botVerificationService.js:

const config = require('config');

• Location: services/botVerificationService.js — insert as the first line after other require statements.

test/utils/generateBotToken.js (1)

1-1: 💡 Verification agent

🧩 Analysis chain

Verify config module import is present.

Similar to the verification service, the config object is used but I don't see an import statement for it.

Please verify that the config module is properly imported. You can check this with:


🏁 Script executed:

#!/bin/bash
# Check if config is properly imported in the file
grep -n "const config" test/utils/generateBotToken.js || echo "config import missing"

# Check if it might be imported with a different name
grep -n "require.*config" test/utils/generateBotToken.js

Length of output: 167


We still need to find how other modules import the config object to suggest the correct path. Let’s search across the repo for existing config imports:


🏁 Script executed:

#!/bin/bash
# Search for all import/require statements that bring in the config module
grep -R "require.*config" -n .

Length of output: 69708


Add missing config import in generateBotToken.js

The config object is used in test/utils/generateBotToken.js but never imported. Please add the standard import at the top of the file.

• File: test/utils/generateBotToken.js
• Location: immediately after the JWT import

Suggested diff:

 const jwt = require("jsonwebtoken");
+const config = require("config");
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd928e2 and 75f8789.

📒 Files selected for processing (6)
  • constants/bot.ts (1 hunks)
  • middlewares/authorizeBot.js (2 hunks)
  • services/botVerificationService.js (2 hunks)
  • test/config/test.js (1 hunks)
  • test/unit/middlewares/authorizeBot.test.js (2 hunks)
  • test/utils/generateBotToken.js (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: build (22.10.0)
🔇 Additional comments (14)
constants/bot.ts (2)

4-4: LGTM: New constant for Discord service added.

The addition of this constant aligns well with existing naming conventions and will serve as the identifier for the Discord service authorization flow.


11-11: LGTM: Export updated to include new constant.

The module exports have been correctly updated to include the new DISCORD_SERVICE constant.

test/config/test.js (1)

156-195:

✅ Verification successful

Security consideration: Discord service is using identical keys to bot tokens.

I notice that the RSA keys for the Discord service appear to be identical to those used for botToken. For proper security isolation between services, each service should have its own unique keys in a production environment.

If this is only for testing purposes, that's acceptable, but please ensure production uses unique keys. You can verify the key differences by checking:


🏁 Script executed:

#!/bin/bash
# Compare bot token keys and Discord service keys to ensure they're different in production
echo "Checking if bot and Discord service keys are different..."

# Extract keys from environment variables or config files in production
# This is a simplified example - adjust to your actual production config retrieval method
BOT_PUBLIC_KEY=$(grep -A 10 "botToken" /path/to/production/config.js | grep "botPublicKey" | head -1)
DISCORD_PUBLIC_KEY=$(grep -A 10 "discordServiceToken" /path/to/production/config.js | grep "discordServicePublicKey" | head -1)

if [ "$BOT_PUBLIC_KEY" == "$DISCORD_PUBLIC_KEY" ]; then
  echo "WARNING: Bot and Discord service are using identical keys in production"
else
  echo "Keys are different as expected"
fi

Length of output: 654


🏁 Script executed:

#!/bin/bash
echo "Comparing test botToken and discordServiceToken keys in test/config/test.js..."

# Extract botToken public key line
BOT_PUB=$(grep -A5 "botToken" test/config/test.js | grep "botPublicKey" | sed 's/.*"\(.*\)".*/\1/')
# Extract discordServiceToken public key line
DISCORD_PUB=$(grep -A5 "discordServiceToken" test/config/test.js | grep "discordServicePublicKey" | sed 's/.*"\(.*\)".*/\1/')

echo "BOT_PUBLIC_KEY snippet: ${BOT_PUB:0:40}"
echo "DISCORD_PUBLIC_KEY snippet: ${DISCORD_PUB:0:40}"
if [ "$BOT_PUB" == "$DISCORD_PUB" ]; then
  echo "❗ Public keys are identical in test config"
else
  echo "✅ Public keys differ in test config"
fi

echo

# Extract botToken private key line
BOT_PRIV=$(grep -A5 "botToken" test/config/test.js | grep "botPrivateKey" | sed 's/.*"\(.*\)".*/\1/')
# Extract discordServiceToken private key line
DISCORD_PRIV=$(grep -A5 "discordServiceToken" test/config/test.js | grep "discordServicePrivateKey" | sed 's/.*"\(.*\)".*/\1/')

echo "BOT_PRIVATE_KEY snippet: ${BOT_PRIV:0:40}"
echo "DISCORD_PRIVATE_KEY snippet: ${DISCORD_PRIV:0:40}"
if [ "$BOT_PRIV" == "$DISCORD_PRIV" ]; then
  echo "❗ Private keys are identical in test config"
else
  echo "✅ Private keys differ in test config"
fi

Length of output: 1298


🏁 Script executed:

#!/bin/bash
echo "Extracting and comparing full key blocks for botToken vs discordServiceToken..."

# Extract bot public key block
sed -n -e '/botPublicKey:/,/END PUBLIC KEY-----/p' test/config/test.js > /tmp/bot_pub.pem

# Extract discord public key block
sed -n -e '/discordServicePublicKey:/,/END PUBLIC KEY-----/p' test/config/test.js > /tmp/discord_pub.pem

echo "Public key differences:"
diff -u /tmp/bot_pub.pem /tmp/discord_pub.pem || echo "❌ Public keys differ"

echo
# Extract bot private key block
sed -n -e '/botPrivateKey:/,/END RSA PRIVATE KEY-----/p' test/config/test.js > /tmp/bot_priv.pem

# Extract discord private key block
sed -n -e '/discordServicePrivateKey:/,/END RSA PRIVATE KEY-----/p' test/config/test.js > /tmp/discord_priv.pem

echo "Private key differences:"
diff -u /tmp/bot_priv.pem /tmp/discord_priv.pem || echo "❌ Private keys differ"

Length of output: 1587


Security isolation (production only)

✅ I confirmed that in test/config/test.js the RSA key blocks for botToken and discordServiceToken are in fact identical, meaning they share the same key pair in your test setup. This is acceptable for a testing environment, but please ensure that in your production configuration you generate and assign a unique public/private key pair for each service (botToken vs. discordServiceToken).

services/botVerificationService.js (2)

13-21: LGTM: Well-structured Discord service token verification function.

The implementation follows the same pattern as existing verification functions and properly uses the Discord service public key from config.


33-33: LGTM: Export updated correctly.

The module exports have been updated to include the new verification function.

test/utils/generateBotToken.js (2)

16-27: LGTM: Well-implemented token generation function for Discord service.

The implementation follows the same pattern as existing token generation functions, with consistent naming, algorithm, and expiration time.


37-37: LGTM: Export updated correctly.

The module exports have been updated to include the new token generation function.

middlewares/authorizeBot.js (1)

2-2: Good addition of the DISCORD_SERVICE constant import

The import of the new constant aligns with the PR objective of adding Discord service verification support.

test/unit/middlewares/authorizeBot.test.js (6)

5-6: Good addition of required imports

The addition of the jwt library import and DISCORD_SERVICE constant is appropriate for the new test cases.


120-145: Well-structured test for expired/malformed Discord service tokens

This test case effectively verifies that the middleware properly handles expired or malformed tokens for the Discord service path. Good use of sinon stubs to simulate the jwt.verify error and proper cleanup with restore().


147-165: Good coverage of invalid token scenario

This test properly verifies that the middleware rejects invalid tokens coming from the Discord service and responds with a bad request.


167-181: Complete verification of the happy path scenario

This test correctly verifies that valid Discord service tokens are properly authorized by the middleware.


199-213: Good negative test case for Discord service name validation

This test effectively validates that the middleware checks the token's name claim matches DISCORD_SERVICE, rejecting tokens with incorrect name values.


215-229: Comprehensive coverage of Cloudflare worker path

This test ensures that the original Cloudflare worker authorization path still validates the name field correctly, maintaining backward compatibility while adding the new Discord service feature.

@joyguptaa
Copy link
Contributor Author

joyguptaa commented May 14, 2025

  • Can we write integration test for different cases for a particular route which is going to be accessed by discord service?

Can you confirm what additional value integration tests add here, which is not covered by unit tests?

We would be able to verify the api behaviour with discord-service token.

  • The change should be within feature flag?

The header name itself acts as a feature flag.
okay

@pankajjs pankajjs force-pushed the feat/discord-service-auth branch from f5d6040 to b8a4db4 Compare June 1, 2025 13:14
@AnujChhikara
Copy link
Member

@pankajjs do we need to make any changes in the readme to add these keys or not ?

@tejaskh3
Copy link
Member

tejaskh3 commented Jun 4, 2025

LGTM!

@pankajjs pankajjs force-pushed the feat/discord-service-auth branch from 8af484e to 88246d6 Compare June 4, 2025 18:13
@pankajjs pankajjs force-pushed the feat/discord-service-auth branch from 88246d6 to d0e5da0 Compare June 4, 2025 18:37
@pankajjs pankajjs requested a review from tejaskh3 June 8, 2025 07:44
AnujChhikara
AnujChhikara previously approved these changes Jun 11, 2025
pankajjs
pankajjs previously approved these changes Jun 12, 2025
@pankajjs pankajjs dismissed stale reviews from AnujChhikara and themself via a502e2f June 13, 2025 06:57
@pankajjs pankajjs requested a review from AnujChhikara June 13, 2025 06:58
@pankajjs pankajjs self-assigned this Jun 17, 2025
@pankajjs pankajjs self-requested a review June 17, 2025 11:06
@pankajjs pankajjs force-pushed the feat/discord-service-auth branch from 754226f to b447abd Compare June 17, 2025 11:20
@pankajjs pankajjs requested a review from iamitprakash June 17, 2025 14:57
@iamitprakash iamitprakash merged commit d7cef3c into develop Jun 18, 2025
4 of 5 checks passed
@iamitprakash iamitprakash deleted the feat/discord-service-auth branch June 18, 2025 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants