🔑 Add OAuth token exchange endpoint with support for Discord and error handling
This commit is contained in:
@@ -176,5 +176,108 @@ export function createAuthRouter({ secret, adminPassword } = {}) {
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /oauth/token
|
||||
* Exchange OAuth authorization code for access token
|
||||
* Supports multiple providers (Discord, Challonge, etc.)
|
||||
*/
|
||||
router.post('/oauth/token', async (req, res) => {
|
||||
const { code, provider } = req.body;
|
||||
|
||||
if (!code) {
|
||||
return res.status(400).json({
|
||||
error: 'Authorization code is required',
|
||||
code: 'MISSING_CODE'
|
||||
});
|
||||
}
|
||||
|
||||
if (!provider) {
|
||||
return res.status(400).json({
|
||||
error: 'Provider is required',
|
||||
code: 'MISSING_PROVIDER'
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
// Handle Discord OAuth
|
||||
if (provider === 'discord') {
|
||||
const clientId = process.env.VITE_DISCORD_CLIENT_ID;
|
||||
const clientSecret = process.env.DISCORD_CLIENT_SECRET;
|
||||
const redirectUri = process.env.VITE_DISCORD_REDIRECT_URI;
|
||||
|
||||
if (!clientId || !clientSecret) {
|
||||
console.error('Discord OAuth not configured:', {
|
||||
hasClientId: !!clientId,
|
||||
hasClientSecret: !!clientSecret
|
||||
});
|
||||
return res.status(500).json({
|
||||
error: 'Discord OAuth not configured on server',
|
||||
code: 'OAUTH_NOT_CONFIGURED'
|
||||
});
|
||||
}
|
||||
|
||||
// Exchange code for token with Discord
|
||||
const tokenResponse = await fetch(
|
||||
'https://discord.com/api/oauth2/token',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
grant_type: 'authorization_code',
|
||||
code: code,
|
||||
redirect_uri: redirectUri
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
if (!tokenResponse.ok) {
|
||||
const errorData = await tokenResponse.text();
|
||||
console.error('Discord token exchange failed:', errorData);
|
||||
return res.status(tokenResponse.status).json({
|
||||
error: 'Failed to exchange code with Discord',
|
||||
code: 'DISCORD_TOKEN_EXCHANGE_FAILED',
|
||||
details: errorData
|
||||
});
|
||||
}
|
||||
|
||||
const tokenData = await tokenResponse.json();
|
||||
|
||||
// Return tokens to client
|
||||
return res.json({
|
||||
access_token: tokenData.access_token,
|
||||
refresh_token: tokenData.refresh_token,
|
||||
token_type: tokenData.token_type,
|
||||
expires_in: tokenData.expires_in,
|
||||
scope: tokenData.scope
|
||||
});
|
||||
}
|
||||
|
||||
// Handle Challonge OAuth (if needed in the future)
|
||||
if (provider === 'challonge') {
|
||||
// Challonge uses the existing /api/oauth/token endpoint via oauth-proxy.js
|
||||
return res.status(400).json({
|
||||
error: 'Use /api/oauth/token for Challonge OAuth',
|
||||
code: 'WRONG_ENDPOINT'
|
||||
});
|
||||
}
|
||||
|
||||
// Unknown provider
|
||||
return res.status(400).json({
|
||||
error: `Unknown provider: ${provider}`,
|
||||
code: 'UNKNOWN_PROVIDER'
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('OAuth token exchange error:', err);
|
||||
return res.status(500).json({
|
||||
error: err.message || 'Failed to exchange OAuth code',
|
||||
code: 'TOKEN_EXCHANGE_ERROR'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user