Re_Backend/src/app.ts

185 lines
5.2 KiB
TypeScript

import express from 'express';
import helmet from 'helmet';
import morgan from 'morgan';
import dotenv from 'dotenv';
import cookieParser from 'cookie-parser';
import { UserService } from './services/user.service';
import { SSOUserData } from './types/auth.types';
import { sequelize } from './config/database';
import { corsMiddleware } from './middlewares/cors.middleware';
import routes from './routes/index';
import { ensureUploadDir, UPLOAD_DIR } from './config/storage';
import path from 'path';
// Load environment variables
dotenv.config();
const app: express.Application = express();
const userService = new UserService();
// Initialize database connection
const initializeDatabase = async () => {
try {
await sequelize.authenticate();
} catch (error) {
console.error('❌ Database connection failed:', error);
}
};
// Initialize database
initializeDatabase();
// CORS middleware - MUST be before other middleware
app.use(corsMiddleware);
// Security middleware - Configure Helmet to work with CORS
app.use(helmet({
crossOriginEmbedderPolicy: false,
crossOriginResourcePolicy: { policy: "cross-origin" },
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
scriptSrc: ["'self'"],
imgSrc: ["'self'", "data:", "https:"],
},
},
}));
// Cookie parser middleware - MUST be before routes
app.use(cookieParser());
// Body parsing middleware
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
// Logging middleware
app.use(morgan('combined'));
// Health check endpoint
app.get('/health', (_req: express.Request, res: express.Response) => {
res.status(200).json({
status: 'OK',
timestamp: new Date(),
uptime: process.uptime(),
environment: process.env.NODE_ENV || 'development'
});
});
// Mount API routes
app.use('/api/v1', routes);
// Serve uploaded files statically
ensureUploadDir();
app.use('/uploads', express.static(UPLOAD_DIR));
// Root endpoint
app.get('/', (_req: express.Request, res: express.Response) => {
res.status(200).json({
message: 'Royal Enfield Workflow Management System API',
version: '1.0.0',
status: 'running',
timestamp: new Date()
});
});
// Legacy SSO Callback endpoint for user creation/update (kept for backward compatibility)
app.post('/api/v1/auth/sso-callback', async (req: express.Request, res: express.Response): Promise<void> => {
try {
const ssoData: SSOUserData = req.body;
// Validate required fields - email and oktaSub are required
if (!ssoData.email || !ssoData.oktaSub) {
res.status(400).json({
success: false,
message: 'Missing required fields: email and oktaSub are required',
timestamp: new Date()
});
return;
}
// Create or update user
const user = await userService.createOrUpdateUser(ssoData);
res.status(200).json({
success: true,
message: 'User processed successfully',
data: {
user: {
userId: user.userId,
employeeId: user.employeeId || null,
oktaSub: user.oktaSub,
email: user.email,
firstName: user.firstName || null,
lastName: user.lastName || null,
displayName: user.displayName || null,
department: user.department || null,
designation: user.designation || null,
phone: user.phone || null,
location: user.location || null,
isAdmin: user.isAdmin,
lastLogin: user.lastLogin
},
isNewUser: user.createdAt.getTime() === user.updatedAt.getTime()
},
timestamp: new Date()
});
} catch (error) {
console.error('❌ SSO Callback failed:', error);
res.status(500).json({
success: false,
message: 'Internal server error',
timestamp: new Date()
});
}
});
// Get all users endpoint
app.get('/api/v1/users', async (_req: express.Request, res: express.Response): Promise<void> => {
try {
const users = await userService.getAllUsers();
res.status(200).json({
success: true,
message: 'Users retrieved successfully',
data: {
users: users.map(user => ({
userId: user.userId,
employeeId: user.employeeId || null,
oktaSub: user.oktaSub,
email: user.email,
firstName: user.firstName || null,
lastName: user.lastName || null,
displayName: user.displayName || null,
department: user.department || null,
designation: user.designation || null,
phone: user.phone || null,
location: user.location || null,
isAdmin: user.isAdmin,
lastLogin: user.lastLogin,
createdAt: user.createdAt
})),
total: users.length
},
timestamp: new Date()
});
} catch (error) {
console.error('❌ Get Users failed:', error);
res.status(500).json({
success: false,
message: 'Internal server error',
timestamp: new Date()
});
}
});
// Error handling middleware
app.use((req: express.Request, res: express.Response) => {
res.status(404).json({
success: false,
message: `Route ${req.originalUrl} not found`,
timestamp: new Date(),
});
});
export default app;