Files
eSIM-Tools/server.js
Abner 2c3e30a078 refactor: 项目清理和文档现代化
- 更新README.md技术架构描述,强调Node.js + Netlify Functions架构
- 完全重写Cookie登录设置指南,移除PHP依赖说明
- 新增遗留PHP文件说明文档,明确文件状态和处理方式
- 更新前后端架构分析文档,反映当前Node.js架构
- 完善server.js,添加缺失的GraphQL代理函数引用
- 新增项目清理总结文档,详细记录架构升级过程
- 优化项目结构和文档组织,提高可维护性
- 确保所有文档与当前Node.js架构保持一致
2025-08-01 21:42:06 +08:00

131 lines
4.3 KiB
JavaScript

/**
* 本地开发服务器
* 提供静态文件服务和API代理功能
*/
const express = require('express');
const cors = require('cors');
const path = require('path');
const helmet = require('helmet');
const morgan = require('morgan');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3000;
// 中间件配置
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net", "https://cdnjs.cloudflare.com"],
styleSrc: ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net", "https://cdnjs.cloudflare.com"],
imgSrc: ["'self'", "data:", "https:", "http:"],
connectSrc: ["'self'", "https://api.qrserver.com", "https://appapi.simyo.nl", "https://api.giffgaff.com", "https://id.giffgaff.com", "https://publicapi.giffgaff.com"],
fontSrc: ["'self'", "https://cdn.jsdelivr.net", "https://cdnjs.cloudflare.com"]
}
}
}));
app.use(cors());
app.use(morgan('combined'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 静态文件服务
app.use(express.static('.'));
// API路由 - 模拟Netlify Functions
const giffgaffMfaChallenge = require('./netlify/functions/giffgaff-mfa-challenge');
const giffgaffMfaValidation = require('./netlify/functions/giffgaff-mfa-validation');
const giffgaffGraphql = require('./netlify/functions/giffgaff-graphql');
const verifyCookie = require('./netlify/functions/verify-cookie');
// 包装Netlify Functions为Express路由
function wrapNetlifyFunction(handler) {
return async (req, res) => {
try {
const event = {
httpMethod: req.method,
headers: req.headers,
body: JSON.stringify(req.body),
queryStringParameters: req.query
};
const context = {};
const result = await handler.handler(event, context);
res.status(result.statusCode);
if (result.headers) {
Object.entries(result.headers).forEach(([key, value]) => {
res.set(key, value);
});
}
if (result.body) {
const body = typeof result.body === 'string' ? result.body : JSON.stringify(result.body);
res.send(body);
} else {
res.end();
}
} catch (error) {
console.error('API Error:', error);
res.status(500).json({
error: 'Internal Server Error',
message: error.message
});
}
};
}
// API端点
app.use('/.netlify/functions/giffgaff-mfa-challenge', wrapNetlifyFunction(giffgaffMfaChallenge));
app.use('/.netlify/functions/giffgaff-mfa-validation', wrapNetlifyFunction(giffgaffMfaValidation));
app.use('/.netlify/functions/giffgaff-graphql', wrapNetlifyFunction(giffgaffGraphql));
app.use('/.netlify/functions/verify-cookie', wrapNetlifyFunction(verifyCookie));
// 路由配置
app.get('/giffgaff', (req, res) => {
res.sendFile(path.join(__dirname, 'src/giffgaff/giffgaff_complete_esim.html'));
});
app.get('/simyo', (req, res) => {
res.sendFile(path.join(__dirname, 'src/simyo/simyo_complete_esim.html'));
});
app.get('/simyo-static', (req, res) => {
res.sendFile(path.join(__dirname, 'src/simyo/simyo_static.html'));
});
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'));
});
// 错误处理
app.use((err, req, res, next) => {
console.error('Server Error:', err);
res.status(500).json({
error: 'Internal Server Error',
message: process.env.NODE_ENV === 'development' ? err.message : '服务器内部错误'
});
});
// 404处理
app.use((req, res) => {
res.status(404).json({
error: 'Not Found',
message: '请求的资源不存在'
});
});
// 启动服务器
app.listen(PORT, () => {
console.log(`🚀 eSIM工具服务器已启动`);
console.log(`📍 本地地址: http://localhost:${PORT}`);
console.log(`🔧 Giffgaff工具: http://localhost:${PORT}/giffgaff`);
console.log(`📱 Simyo工具: http://localhost:${PORT}/simyo`);
console.log(`🌐 环境: ${process.env.NODE_ENV || 'development'}`);
});
module.exports = app;