-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Summary
Implement Discord OAuth endpoints that RallyRound can use for authentication. DiscordStats will be the OAuth provider, and RallyRound will validate tokens against our /auth/validate endpoint.
Background
RallyRound is building a live speaker management system for Discord voice channels. Users need to authenticate with their Discord identity to participate in sessions. Rather than duplicating OAuth logic, DiscordStats will serve as the central OAuth provider.
Requirements
Endpoints to Implement
1. GET /auth/discord
Initiates the Discord OAuth flow.
Query Parameters:
redirect_uri(optional): Where to redirect after auth (default: DiscordStats dashboard)state(optional): CSRF prevention token
Behavior:
- Generate state token if not provided
- Store state in session/Redis for verification
- Redirect to Discord authorization URL with scopes:
identify,guilds
2. GET /auth/discord/callback
Handles the OAuth callback from Discord.
Query Parameters:
code: Authorization code from Discordstate: State token for CSRF verification
Behavior:
- Verify state token matches stored value
- Exchange code for access token with Discord API
- Fetch user info from Discord API
- Generate JWT containing user info
- Redirect to
redirect_uriwith?token={jwt}
3. GET /auth/validate
Validates a JWT token (called by RallyRound on every API request).
Headers:
Authorization: Bearer {token}
Success Response (200):
{
"valid": true,
"user": {
"id": "123456789012345678",
"username": "alice",
"discriminator": "1234",
"avatar": "abc123hash",
"email": "alice@example.com"
},
"expiresAt": 1735200000
}Error Response (401):
{
"valid": false,
"error": "Token expired"
}4. GET /auth/user
Returns full user profile for authenticated user.
Headers:
Authorization: Bearer {token}
Response: User object with guilds array
JWT Token Structure
interface TokenPayload {
sub: string; // Discord user ID
username: string;
discriminator: string;
avatar?: string;
email?: string;
iat: number; // Issued at
exp: number; // Expires at (24 hours recommended)
}Environment Variables Needed
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
JWT_SECRET= # For signing tokens
RALLYROUND_URL= # Allowed redirect origin
Acceptance Criteria
-
/auth/discordredirects to Discord OAuth with correct scopes -
/auth/discord/callbackexchanges code and issues JWT -
/auth/validatecorrectly validates tokens and returns user info -
/auth/userreturns full profile with guilds - Tokens expire after 24 hours
- CORS configured to allow requests from RallyRound origin
- State token prevents CSRF attacks
- Invalid/expired tokens return 401 with clear error message
Testing
- Manual flow: Click login → Discord auth → Redirect with token
- Validate token with curl:
curl -H "Authorization: Bearer {token}" /auth/validate - Test expired token handling
- Test invalid token handling
Related
- RallyRound API Specification: See
docs/design/api-specification.mdin RallyRound repo - RallyRound will call
/auth/validateon every API request