import express from 'express'; import cors from 'cors'; import helmet from 'helmet'; import rateLimit from 'express-rate-limit'; import dotenv from 'dotenv'; import path from 'path'; import { fileURLToPath } from 'url'; import authRoutes from './routes/auth.js'; import pptRoutes from './routes/ppt.js'; import publicRoutes from './routes/public.js'; import { authenticateToken } from './middleware/auth.js'; import { errorHandler } from './middleware/errorHandler.js'; dotenv.config(); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const app = express(); const PORT = process.env.PORT || 7860; // 修改为7860端口 // 设置trust proxy用于Huggingface Space app.set('trust proxy', true); // 安全中间件 app.use(helmet({ contentSecurityPolicy: false, // 为了兼容前端静态文件 })); // 限流中间件 const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15分钟 max: 100, // 每个IP每15分钟最多100个请求 message: 'Too many requests from this IP, please try again later.' }); app.use('/api', limiter); // CORS配置 app.use(cors({ origin: process.env.FRONTEND_URL || '*', credentials: true })); app.use(express.json({ limit: '50mb' })); app.use(express.urlencoded({ extended: true, limit: '50mb' })); // 提供前端静态文件 app.use(express.static(path.join(__dirname, '../../frontend/dist'))); // 提供数据文件 app.use('/data', express.static(path.join(__dirname, '../../frontend/public/mocks'))); // 直接提供测试页面路由 app.get('/test.html', (req, res) => { try { // 检查文件是否存在 const testFilePath = path.join(__dirname, '../../test.html'); console.log('Looking for test.html at:', testFilePath); // 发送测试页面 res.sendFile(testFilePath, (err) => { if (err) { console.error('Error serving test.html:', err); // 如果文件不存在,返回一个简单的测试页面 res.send(` Test Page

PPTist API Test

Test file not found at: ${testFilePath}

`); } }); } catch (error) { console.error('Test page error:', error); res.status(500).send('Test page error: ' + error.message); } }); // 添加内置测试页面端点 app.get('/test', (req, res) => { res.send(` PPTist API 测试页面

🚀 PPTist API 测试控制台

🔗 基础连接测试

🔐 用户认证测试

当前Token: 未登录

📄 PPT管理测试

🌐 公共分享测试

`); }); // API路由 console.log('Registering API routes...'); // 健康检查 - 需要在其他路由之前 app.get('/api/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); // GitHub连接状态检查 app.get('/api/github/status', async (req, res) => { try { const { default: githubService } = await import('./services/githubService.js'); const validation = await githubService.validateConnection(); res.json({ github: validation, environment: { tokenConfigured: !!process.env.GITHUB_TOKEN, tokenPreview: process.env.GITHUB_TOKEN ? `${process.env.GITHUB_TOKEN.substring(0, 8)}...` : 'Not set', reposConfigured: !!process.env.GITHUB_REPOS, reposList: process.env.GITHUB_REPOS ? process.env.GITHUB_REPOS.split(',') : [], nodeEnv: process.env.NODE_ENV } }); } catch (error) { res.status(500).json({ error: error.message, stack: error.stack }); } }); // 添加GitHub测试路由 app.get('/api/github/test', async (req, res) => { try { console.log('=== GitHub Connection Test ==='); console.log('GITHUB_TOKEN exists:', !!process.env.GITHUB_TOKEN); console.log('GITHUB_REPOS:', process.env.GITHUB_REPOS); const { default: githubService } = await import('./services/githubService.js'); // 测试基本配置 const config = { hasToken: !!githubService.token, useMemoryStorage: githubService.useMemoryStorage, repositories: githubService.repositories, apiUrl: githubService.apiUrl }; console.log('GitHub Service Config:', config); // 如果有token,测试连接 let connectionTest = null; if (githubService.token) { console.log('Testing GitHub API connection...'); connectionTest = await githubService.validateConnection(); console.log('Connection test result:', connectionTest); } res.json({ timestamp: new Date().toISOString(), config, connectionTest, environment: { tokenLength: process.env.GITHUB_TOKEN ? process.env.GITHUB_TOKEN.length : 0, nodeEnv: process.env.NODE_ENV } }); } catch (error) { console.error('GitHub test error:', error); res.status(500).json({ error: error.message, stack: process.env.NODE_ENV === 'development' ? error.stack : undefined }); } }); // 添加仓库初始化端点 app.post('/api/github/initialize', async (req, res) => { try { console.log('=== Manual Repository Initialization ==='); const { default: githubService } = await import('./services/githubService.js'); if (githubService.useMemoryStorage) { return res.status(400).json({ error: 'Cannot initialize repository: using memory storage mode', reason: 'GitHub token not configured' }); } const { repoIndex = 0 } = req.body; console.log(`Initializing repository at index: ${repoIndex}`); const result = await githubService.initializeRepository(repoIndex); if (result.success) { res.json({ success: true, message: 'Repository initialized successfully', commit: result.commit, timestamp: new Date().toISOString() }); } else { res.status(500).json({ success: false, error: result.error, reason: result.reason }); } } catch (error) { console.error('Repository initialization error:', error); res.status(500).json({ error: error.message, stack: process.env.NODE_ENV === 'development' ? error.stack : undefined }); } }); // 添加路由注册日志 console.log('Importing route modules...'); console.log('Auth routes imported:', !!authRoutes); console.log('PPT routes imported:', !!pptRoutes); console.log('Public routes imported:', !!publicRoutes); // 认证相关路由(不需要认证) app.use('/api/auth', authRoutes); // 公共访问路由(不需要认证) app.use('/api/public', publicRoutes); // 添加测试路由来验证 PPT 路由是否工作(不需要认证) app.get('/api/ppt/test', (req, res) => { res.json({ message: 'PPT routes are working', timestamp: new Date().toISOString() }); }); // PPT管理路由(需要认证) app.use('/api/ppt', (req, res, next) => { console.log(`PPT route accessed: ${req.method} ${req.path}`); next(); }, authenticateToken, pptRoutes); console.log('All routes registered successfully'); // 添加调试中间件 - 处理未匹配的API路由 app.use('/api/*', (req, res) => { console.log(`Unmatched API route: ${req.method} ${req.path}`); res.status(404).json({ error: 'API route not found', path: req.path }); }); // 前端路由处理 - 必须在API路由之后 app.get('*', (req, res) => { res.sendFile(path.join(__dirname, '../../frontend/dist/index.html')); }); // 错误处理中间件 app.use(errorHandler); app.listen(PORT, '0.0.0.0', () => { console.log(`Server is running on port ${PORT}`); console.log(`Environment: ${process.env.NODE_ENV || 'development'}`); });