Files
FragginWagon 8775f8b1fe Refactor code for improved readability and consistency
- Updated CSRF middleware to enhance cookie value decoding.
- Reformatted OAuth proxy token store initialization for better clarity.
- Adjusted Challonge proxy router for consistent line breaks and readability.
- Enhanced OAuth router error handling and response formatting.
- Improved session router for better readability and consistency in fetching provider records.
- Refactored OAuth token store to improve key derivation logging.
- Cleaned up cookie options utility for better readability.
- Enhanced Challonge client credentials composable for consistent API calls.
- Streamlined OAuth composable for improved logging.
- Refactored main.js for better readability in session initialization.
- Improved Challonge v2.1 service error handling for better clarity.
- Cleaned up API client utility for improved readability.
- Enhanced ApiKeyManager.vue for better text formatting.
- Refactored ChallongeTest.vue for improved readability in composable usage.
2026-02-03 12:50:25 -05:00

131 lines
3.5 KiB
JavaScript

/**
* OAuth Proxy Server for Challonge API
*
* This server handles OAuth token exchange and refresh for the Challonge API.
* It keeps client_secret secure by running on the backend.
*
* Usage:
* Development: node server/oauth-proxy.js
* Production: Deploy with Docker (see docker-compose.production.yml)
*/
import 'dotenv/config';
import express from 'express';
import cors from 'cors';
import cookieParser from 'cookie-parser';
import gamemasterRouter from './gamemaster-api.js';
import { createAuthRouter } from './routes/auth.js';
import { createOAuthRouter } from './routes/oauth.js';
import { createSessionRouter } from './routes/session.js';
import { createChallongeProxyRouter } from './routes/challonge.js';
import { createDiscordRouter } from './routes/discord.js';
import { validateOrExit, getConfig } from './utils/env-validator.js';
import logger, { requestLogger, errorLogger } from './utils/logger.js';
import {
setupGracefulShutdown,
createHealthCheckMiddleware
} from './utils/graceful-shutdown.js';
import { sidMiddleware } from './middleware/sid.js';
import { csrfMiddleware } from './middleware/csrf.js';
import { createOAuthTokenStore } from './services/oauth-token-store.js';
// Validate environment variables
validateOrExit();
// Get validated configuration
const config = getConfig();
const app = express();
// Behind nginx reverse proxy in production
app.set('trust proxy', 1);
// Middleware
app.use(
cors({
origin: config.cors.origin,
credentials: true
})
);
app.use(cookieParser());
app.use(express.json());
app.use(requestLogger);
// Per-session identity (httpOnly signed SID cookie)
app.use(
sidMiddleware({
sessionSecret: config.session.secret,
config
})
);
// Encrypted per-session provider token store
const tokenStore = createOAuthTokenStore({
sessionSecret: config.session.secret
});
// Mount API routes (nginx strips /api/ prefix before forwarding)
app.use('/gamemaster', gamemasterRouter);
app.use(
'/auth',
createAuthRouter({
secret: config.secret,
adminPassword: config.adminPassword
})
);
// Session + CSRF helpers
app.use('/session', createSessionRouter({ config, tokenStore }));
// Provider OAuth (server-owned tokens; browser never receives access/refresh tokens)
app.use(
'/oauth',
csrfMiddleware({
requireOriginCheck: config.isProduction,
allowedOrigin: config.cors.origin
})
);
app.use('/oauth', createOAuthRouter({ config, tokenStore }));
// Provider API proxies (no split brain)
app.use('/challonge', createChallongeProxyRouter({ config, tokenStore }));
app.use('/discord', createDiscordRouter({ tokenStore }));
/**
* Health check endpoint (with graceful shutdown support)
* GET /health
*/
app.get('/health', createHealthCheckMiddleware());
// Error logging middleware (must be after routes)
app.use(errorLogger);
// Start server
const server = app.listen(config.port, () => {
logger.info('🔐 OAuth Proxy Server started', {
port: config.port,
nodeEnv: config.nodeEnv,
challongeConfigured: config.challonge.configured
});
if (!config.challonge.configured) {
logger.warn(
'⚠️ Challonge OAuth not configured - OAuth endpoints disabled'
);
logger.warn(
' Set CHALLONGE_CLIENT_ID and CHALLONGE_CLIENT_SECRET to enable'
);
}
logger.info('✅ Ready to handle requests');
});
// Setup graceful shutdown
setupGracefulShutdown(server, {
timeout: 30000,
onShutdown: async () => {
logger.info('Running cleanup tasks...');
// Add any cleanup tasks here (close DB connections, etc.)
}
});