mirror of
https://github.com/Silentely/eSIM-Tools.git
synced 2026-09-03 06:24:20 +08:00
- 更新README.md技术架构描述,强调Node.js + Netlify Functions架构 - 完全重写Cookie登录设置指南,移除PHP依赖说明 - 新增遗留PHP文件说明文档,明确文件状态和处理方式 - 更新前后端架构分析文档,反映当前Node.js架构 - 完善server.js,添加缺失的GraphQL代理函数引用 - 新增项目清理总结文档,详细记录架构升级过程 - 优化项目结构和文档组织,提高可维护性 - 确保所有文档与当前Node.js架构保持一致
131 lines
4.3 KiB
JavaScript
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; |