ideas-generator/server/index.js
DJP 013f57fe60 Implement hybrid Azure AD SSO + Password authentication system
 Backend Implementation:
- Add Azure AD JWT token validation middleware
- Create hybrid authentication system supporting both Azure AD and password auth
- Implement auto-provisioning for new Azure AD users
- Add admin controls to toggle password authentication
- Update all API routes to use hybrid authentication
- Add database fields for authentication (password, lastLoginAt)
- Create comprehensive auth routes with validation endpoints

 Frontend Implementation:
- Install and configure Azure MSAL browser library
- Create Azure AD authentication service with popup/redirect support
- Build hybrid authentication service managing both auth methods
- Update Login.vue with modern dual-authentication UI
- Implement dynamic password auth toggle based on admin settings
- Update App.vue for proper session management and validation
- Modify API service to handle both token types

 Security Features:
- Azure AD tenant validation (Oliver Agency)
- Role-based access control with auto-admin assignment
- JWT token validation for both auth methods
- Automatic user provisioning with proper defaults
- Session validation and automatic logout on token expiry

 Admin Features:
- Toggle password authentication on/off
- Manage users from both authentication methods
- Full role and agent access control
- Azure AD user auto-provisioning as regular users

 Configuration:
- Azure AD: Tenant e519c2e6-bc6d-4fdf-8d9c-923c2f002385
- Client ID: 9079054c-9620-4757-a256-23413042f1ef
- Development redirect URI support
- Fallback password authentication for testing

🔧 Technical Stack:
- Azure MSAL Browser & Node libraries
- JWT token validation and hybrid middleware
- Database schema updates with migrations
- Vue.js integration with MSAL
- Express.js hybrid authentication routes

🚀 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-09 16:14:02 -04:00

119 lines
No EOL
3.8 KiB
JavaScript

const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
require('dotenv').config();
const { testConnection } = require('./config/database');
const { generalLimiter } = require('./middleware/rateLimiter');
const errorHandler = require('./middleware/errorHandler');
const authRouter = require('./routes/auth');
const chatRouter = require('./routes/chat');
const assistantsRouter = require('./routes/assistants');
const usersRouter = require('./routes/users');
const analyticsRouter = require('./routes/analytics');
const vectorStoresRouter = require('./routes/vectorStores');
const filesRouter = require('./routes/files');
const app = express();
const PORT = process.env.PORT || 3000;
// Security middleware
app.use(helmet());
// CORS middleware - permissive for development
app.use(cors({
origin: process.env.NODE_ENV === 'development' ? true : ['http://localhost:8080', 'https://ai-sandbox.oliver.solutions'],
credentials: true
}));
// Request logging
app.use(morgan('combined'));
// Body parsing middleware
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
// Rate limiting
app.use(generalLimiter);
// Health check endpoint
app.get('/health', (req, res) => {
res.json({
status: 'ok',
timestamp: new Date().toISOString(),
environment: process.env.NODE_ENV,
version: '1.0.0',
service: 'Ideas Generator 2025 Backend'
});
});
// API routes
app.use('/api/auth', authRouter);
app.use('/api/chat', chatRouter);
app.use('/api/assistants', assistantsRouter);
app.use('/api/users', usersRouter);
app.use('/api/analytics', analyticsRouter);
app.use('/api/vector-stores', vectorStoresRouter);
app.use('/api/files', filesRouter);
// API info endpoint
app.get('/api', (req, res) => {
res.json({
message: 'Ideas Generator 2025 API',
version: '1.0.0',
status: 'Active',
endpoints: {
health: '/health',
api: '/api',
auth: '/api/auth',
chat: '/api/chat/completions',
assistants: '/api/assistants',
conversations: '/api/chat/conversations/:id/messages'
}
});
});
// Error handling middleware
app.use(errorHandler);
// 404 handler
app.use((req, res) => {
res.status(404).json({
error: 'Not Found',
message: `Route ${req.originalUrl} not found`,
availableRoutes: ['/health', '/api']
});
});
// Start server
app.listen(PORT, async () => {
console.log(`🚀 Ideas Gen 2025 Server running on port ${PORT}`);
console.log(`🏥 Health check: http://localhost:${PORT}/health`);
console.log(`🔧 API endpoint: http://localhost:${PORT}/api`);
console.log(`💬 Chat endpoint: http://localhost:${PORT}/api/chat/completions`);
console.log(`🤖 Assistants endpoint: http://localhost:${PORT}/api/assistants`);
console.log(`📊 Environment: ${process.env.NODE_ENV}`);
console.log(`📁 Database: ${process.env.DATABASE_NAME || 'Not configured'}`);
// Test database connection
await testConnection();
// Log important environment status
if (!process.env.OPENAI_API_KEY || process.env.OPENAI_API_KEY.includes('your-actual')) {
console.warn('⚠️ WARNING: OpenAI API key not configured! Update .env file.');
} else {
console.log('✅ OpenAI API key configured');
}
});
// Graceful shutdown
process.on('SIGINT', () => {
console.log('\n🛑 Received SIGINT. Graceful shutdown...');
process.exit(0);
});
process.on('SIGTERM', () => {
console.log('\n🛑 Received SIGTERM. Graceful shutdown...');
process.exit(0);
});