!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache. PHP/8.1.30 

uname -a: Linux server1.tuhinhossain.com 5.15.0-163-generic #173-Ubuntu SMP Tue Oct 14 17:51:00 UTC
2025 x86_64
 

uid=1002(picotech) gid=1003(picotech) groups=1003(picotech),0(root)  

Safe-mode: OFF (not secure)

/home/picotech/domains/note.picotech.app/public_html/src/   drwxr-xr-x
Free 24.75 GB of 117.98 GB (20.98%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     app.js (10.51 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const compression = require('compression');
const rateLimit = require('express-rate-limit');
const csrf = require('csurf');
const path = require('path');

const config = require('./config/config');
const { testConnection } = require('./config/database');
const { syncDatabase, DataDeletionRequest } = require('./models');
const {
  globalErrorHandler,
  handleNotFound,
  handleUnhandledRejection,
  handleUncaughtException,
  handleGracefulShutdown,
} = require('./middleware/errorHandler');

// Import routes
const authRoutes = require('./routes/auth');
const meetingRoutes = require('./routes/meetings');
const noteRoutes = require('./routes/notes');
const recordingRoutes = require('./routes/recordings');
const transcriptRoutes = require('./routes/transcripts');
const summaryRoutes = require('./routes/summaries');
const labelRoutes = require('./routes/labels');
const apiProxyRoutes = require('./routes/apiProxy');

// Import WebSocket services
const LiveTranscriptionService = require('./services/liveTranscriptionService');

// Import job queue service
const { initialize: initializeJobQueue } = require('./services/jobQueue');

// Handle uncaught exceptions
handleUncaughtException();

const app = express();

// Trust proxy (for rate limiting and IP detection)
app.set('trust proxy', 1);

// Security middleware
app.use(helmet({
  crossOriginResourcePolicy: { policy: 'cross-origin' },
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      scriptSrc: ["'self'"],
      imgSrc: ["'self'", "data:", "https:"],
      fontSrc: ["'self'", "https://fonts.gstatic.com"],
      connectSrc: ["'self'", "wss:", "https:"],
      upgradeInsecureRequests: [],
      frameAncestors: ["'none'"],
      baseUri: ["'self'"],
      formAction: ["'self'"],
    },
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  },
  noSniff: true,
  xssFilter: true,
  referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
  dnsPrefetchControl: { allow: false },
  ieNoOpen: true,
  frameguard: { action: 'deny' },
  permittedCrossDomainPolicies: { permittedPolicies: 'none' }
}));

// CSRF Protection - disabled for API routes since JWT provides sufficient protection
// Keeping the middleware setup for potential future use with web clients
const csrfProtection = csrf({ cookie: true });

// Skip CSRF protection for all API routes - JWT tokens provide CSRF protection
app.use('/api/', (req, res, next) => {
  return next();
});

// Add CSRF token to responses
app.use((req, res, next) => {
  // Skip CSRF token for public auth routes
  const publicAuthRoutes = [
    '/api/auth/send-registration-otp',
    '/api/auth/verify-otp',
    '/api/auth/register',
    '/api/auth/login',
    '/api/auth/refresh-token',
    '/api/auth/forgot-password',
    '/api/auth/reset-password',
    '/api/auth/verify-email'
  ];

  if (publicAuthRoutes.some(route => req.path.startsWith(route))) {
    return next();
  }

  // Only set CSRF token if csrfProtection middleware has been applied
  if (req.csrfToken) {
    res.locals.csrfToken = req.csrfToken();
    // Expose CSRF token in header for AJAX requests
    res.setHeader('X-CSRF-Token', req.csrfToken());
  }
  next();
});

// CORS configuration
app.use(cors({
  origin: config.cors.origin,
  credentials: config.cors.credentials,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'X-CSRF-Token'],
  exposedHeaders: ['X-CSRF-Token'],
}));

// Compression middleware
app.use(compression());

// Rate limiting - general API
const limiter = rateLimit({
  windowMs: config.rateLimit.windowMs,
  max: config.rateLimit.max,
  message: {
    success: false,
    message: 'Too many requests from this IP, please try again later.',
    code: 'RATE_LIMIT_EXCEEDED',
  },
  standardHeaders: true,
  legacyHeaders: false,
});

// Stricter rate limiting for authentication endpoints
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 5, // 5 attempts per 15 minutes for auth endpoints
  message: {
    success: false,
    message: 'Too many authentication attempts, please try again later.',
    code: 'AUTH_RATE_LIMIT_EXCEEDED',
  },
  standardHeaders: true,
  legacyHeaders: false,
  skipSuccessfulRequests: true, // Don't count successful requests
});

// Stricter rate limiting for OTP endpoints
const otpLimiter = rateLimit({
  windowMs: 5 * 60 * 1000, // 5 minutes
  max: 3, // 3 OTP requests per 5 minutes
  message: {
    success: false,
    message: 'Too many OTP requests, please try again later.',
    code: 'OTP_RATE_LIMIT_EXCEEDED',
  },
  standardHeaders: true,
  legacyHeaders: false,
});

app.use('/api/', limiter);
app.use('/api/auth/login', authLimiter);
app.use('/api/auth/register', authLimiter);
app.use('/api/auth/forgot-password', authLimiter);
app.use('/api/auth/send-otp', otpLimiter);
app.use('/api/auth/verify-otp', otpLimiter);

// Body parsing middleware (skip for multipart/form-data)
app.use((req, res, next) => {
  if (req.headers['content-type'] && req.headers['content-type'].includes('multipart/form-data')) {
    return next();
  }
  express.json({ limit: '10mb' })(req, res, next);
});

app.use((req, res, next) => {
  if (req.headers['content-type'] && req.headers['content-type'].includes('multipart/form-data')) {
    return next();
  }
  express.urlencoded({ extended: true, limit: '10mb' })(req, res, next);
});

// Static file serving for uploads
app.use('/uploads', express.static(path.join(__dirname, '../uploads')));

// Health check endpoint
app.get('/health', (req, res) => {
  res.json({
    success: true,
    message: 'PicoNote API is running',
    timestamp: new Date().toISOString(),
    version: '1.0.0',
    environment: config.nodeEnv,
  });
});

// Default HTML page for root URL
app.get('/', (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>PicoNote API</title>
      <style>
        body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
        h1 { color: #333; }
        p { color: #666; }
      </style>
    </head>
    <body>
      <h1>Welcome to PicoNote</h1>
      <p>Your AI-powered meeting notes and transcription service.</p>
      <p><a href="/api">API Documentation</a></p>
      <p><a href="/health">Health Check</a></p>
    </body>
    </html>
  `);
});

// Privacy policy page
app.get('/privacy', (req, res) => {
  res.sendFile(path.join(__dirname, '../privacy.html'));
});

// Delete your data page
app.get('/delete-your-data', (req, res) => {
  res.sendFile(path.join(__dirname, '../delete-data.html'));
});

// Handle delete data form submission
app.post('/delete-your-data', async (req, res) => {
  try {
    const { name, email, reason } = req.body;

    if (!name || !email || !reason) {
      return res.status(400).json({
        success: false,
        message: 'All fields are required.',
      });
    }

    await DataDeletionRequest.create({
      name,
      email,
      reason,
    });

    res.send(`
      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Request Submitted - PicoNote</title>
        <style>
          body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
          h1 { color: #333; }
          p { color: #666; }
        </style>
      </head>
      <body>
        <h1>Request Submitted</h1>
        <p>Your data deletion request has been submitted successfully. We will process it within 30 days.</p>
        <p><a href="/">Back to Home</a></p>
      </body>
      </html>
    `);
  } catch (error) {
    console.error('Error submitting deletion request:', error);
    res.status(500).json({
      success: false,
      message: 'An error occurred while submitting your request.',
    });
  }
});

// API routes
app.use('/api/auth', authRoutes);
app.use('/api/meetings', meetingRoutes);
app.use('/api/notes', noteRoutes);
app.use('/api/recordings', recordingRoutes);
app.use('/api/transcripts', transcriptRoutes);
app.use('/api/summaries', summaryRoutes);
app.use('/api/labels', labelRoutes);
app.use('/api/proxy', apiProxyRoutes);

// API documentation endpoint
app.get('/api', (req, res) => {
  res.json({
    success: true,
    message: 'PicoNote API v1.0.0',
    documentation: {
      auth: '/api/auth - Authentication endpoints',
      meetings: '/api/meetings - Meeting management',
      notes: '/api/notes - Note management',
      recordings: '/api/recordings - Audio recording management',
      transcripts: '/api/transcripts - Transcription management',
      summaries: '/api/summaries - Meeting summary management',
      labels: '/api/labels - Label management',
    },
    endpoints: {
      health: 'GET /health - Health check',
      docs: 'GET /api - This documentation',
    },
  });
});

// Handle 404 for unmatched routes
app.use(handleNotFound);

// Global error handling middleware
app.use(globalErrorHandler);

// Handle unhandled promise rejections
handleUnhandledRejection();

// Start server
const startServer = async () => {
  try {
    // Test database connection
    await testConnection();

    // Sync database models
   // await syncDatabase({ alter: config.nodeEnv === 'development' });

    const server = app.listen(config.port, () => {
      console.log(`🚀 PicoNote API server running on port ${config.port}`);
      console.log(`📝 Environment: ${config.nodeEnv}`);
      console.log(`🔗 Health check: http://localhost:${config.port}/health`);
      console.log(`📚 API docs: http://localhost:${config.port}/api`);

      if (config.nodeEnv === 'development') {
        console.log(`🎯 CORS enabled for: ${config.cors.origin.join(', ')}`);
      }
    });

    // Initialize WebSocket services
    const liveTranscriptionService = LiveTranscriptionService(server);
    console.log('🔴 Live transcription WebSocket service initialized');

    // Initialize job queue
    await initializeJobQueue();
    console.log('⚙️ Job queue initialized');

    // Handle graceful shutdown
    handleGracefulShutdown(server, () => {
      liveTranscriptionService.cleanup();
    });

    return server;
  } catch (error) {
    console.error('❌ Failed to start server:', error);
    process.exit(1);
  }
};

// Start the server if this file is run directly
if (require.main === module) {
  startServer();
}

module.exports = { app, startServer };

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0037 ]--