Add OAuth 2.0 authentication support for Jira Data Center

- Add OAuth 2.0 configuration options in backend env.ts
- Create authService.ts for OAuth flow, token management, and sessions
- Create auth.ts routes for login, callback, logout, and user info
- Update JiraAssets service to use user tokens when OAuth is enabled
- Add cookie-parser for session handling
- Create Login.tsx component with Jira OAuth login button
- Add authStore.ts (Zustand) for frontend auth state management
- Update App.tsx to show login page when OAuth is enabled
- Add user menu with logout functionality
- Document OAuth setup in CLAUDE.md

Supports two modes:
1. Service Account: Uses JIRA_PAT for all requests (default)
2. OAuth 2.0: Each user authenticates with their Jira credentials
This commit is contained in:
2026-01-06 15:40:52 +01:00
parent 0b27adc2fb
commit ea1c84262c
11 changed files with 1016 additions and 10 deletions

View File

@@ -2,6 +2,7 @@ import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import rateLimit from 'express-rate-limit';
import cookieParser from 'cookie-parser';
import { config, validateConfig } from './config/env.js';
import { logger } from './services/logger.js';
import { dataService } from './services/dataService.js';
@@ -10,6 +11,8 @@ import classificationsRouter from './routes/classifications.js';
import referenceDataRouter from './routes/referenceData.js';
import dashboardRouter from './routes/dashboard.js';
import configurationRouter from './routes/configuration.js';
import authRouter, { authMiddleware } from './routes/auth.js';
import { jiraAssetsService } from './services/jiraAssets.js';
// Validate configuration
validateConfig();
@@ -19,10 +22,13 @@ const app = express();
// Security middleware
app.use(helmet());
app.use(cors({
origin: config.isDevelopment ? '*' : ['http://localhost:5173', 'http://localhost:3000'],
origin: config.isDevelopment ? ['http://localhost:5173', 'http://localhost:3000'] : [config.frontendUrl],
credentials: true,
}));
// Cookie parser for session handling
app.use(cookieParser());
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
@@ -41,6 +47,24 @@ app.use((req, res, next) => {
next();
});
// Auth middleware - extract session info for all requests
app.use(authMiddleware);
// Set user token on JiraAssets service for each request
app.use((req, res, next) => {
// Set user's OAuth token if available
if (req.accessToken) {
jiraAssetsService.setRequestToken(req.accessToken);
}
// Clear token after response is sent
res.on('finish', () => {
jiraAssetsService.clearRequestToken();
});
next();
});
// Health check
app.get('/health', async (req, res) => {
const jiraConnected = await dataService.testConnection();
@@ -61,6 +85,7 @@ app.get('/api/config', (req, res) => {
});
// API routes
app.use('/api/auth', authRouter);
app.use('/api/applications', applicationsRouter);
app.use('/api/classifications', classificationsRouter);
app.use('/api/reference-data', referenceDataRouter);