mirror of
https://github.com/Silentely/eSIM-Tools.git
synced 2026-09-06 15:58:25 +08:00
安全修复: - 修复 dom.js 和 simyo/app.js 中的 innerHTML XSS 注入风险 - 使用 HTMLSanitizer.escapeHtml/escapeAttr 替代直接模板拼接 - 将 onclick 内联事件替换为 data-* 属性 + addEventListener - 移除 server.js 中硬编码的 Simyo X-Client-Token 架构优化: - 新增 _shared/rate-limiter.js 分布式限流模块 (Netlify Blobs) - verify-cookie.js 内存限流替换为 KV 跨实例共享方案 - giffgaff/utils.js debounce/throttle 改为委托共享实现 - simyo/app.js 会话存储迁移至 SecureStorage (自动 TTL 过期) - 合并 notifications-internal.js 至 notifications.js 消除双维护路径
99 lines
2.1 KiB
JavaScript
99 lines
2.1 KiB
JavaScript
'use strict';
|
||
|
||
/**
|
||
* 通知消息API
|
||
* 提供系统通知消息的查询接口
|
||
*/
|
||
|
||
const { withAuth } = require('./_shared/middleware');
|
||
|
||
// 通知消息数据(可以从JSON文件或数据库读取)
|
||
const NOTIFICATIONS = [
|
||
{
|
||
id: 'fix-giffgaff-oauth',
|
||
message: 'giffgaff的oauth登录方式已变更,请阅读新方法使用',
|
||
type: 'info',
|
||
timestamp: '2026-01-22T13:50:00Z',
|
||
active: true,
|
||
priority: 1
|
||
},
|
||
{
|
||
id: 'fix-simyo-api',
|
||
message: '已更新Simyo端点,完善更换流程',
|
||
type: 'success',
|
||
timestamp: '2026-01-13T00:30:00Z',
|
||
active: true,
|
||
priority: 2
|
||
},
|
||
{
|
||
id: 'fix-400-error',
|
||
message: '已修复Oauth交换时报错400问题,优化了MFA验证流程',
|
||
type: 'success',
|
||
timestamp: '2025-11-30T10:00:00Z',
|
||
active: false,
|
||
priority: 1
|
||
},
|
||
{
|
||
id: 'new-feature-oauth',
|
||
message: '新功能:支持OAuth 2.0 PKCE认证流程',
|
||
type: 'info',
|
||
timestamp: '2025-06-20T15:30:00Z',
|
||
active: false,
|
||
priority: 2
|
||
}
|
||
];
|
||
|
||
/**
|
||
* 获取活跃通知
|
||
*/
|
||
function getActiveNotifications() {
|
||
return NOTIFICATIONS
|
||
.filter(n => n.active)
|
||
.sort((a, b) => a.priority - b.priority);
|
||
}
|
||
|
||
/**
|
||
* 获取最新通知
|
||
*/
|
||
function getLatestNotification() {
|
||
const active = getActiveNotifications();
|
||
return active.length > 0 ? active[0] : null;
|
||
}
|
||
|
||
/**
|
||
* 主处理函数
|
||
*/
|
||
exports.handler = withAuth(async (event, context, { auth }) => {
|
||
const { httpMethod, queryStringParameters } = event;
|
||
|
||
// 仅支持GET请求
|
||
if (httpMethod !== 'GET') {
|
||
return {
|
||
statusCode: 405,
|
||
body: JSON.stringify({ error: 'Method not allowed' })
|
||
};
|
||
}
|
||
|
||
const mode = queryStringParameters?.mode || 'all';
|
||
|
||
let data;
|
||
switch (mode) {
|
||
case 'latest':
|
||
data = getLatestNotification();
|
||
break;
|
||
case 'all':
|
||
default:
|
||
data = getActiveNotifications();
|
||
break;
|
||
}
|
||
|
||
return {
|
||
statusCode: 200,
|
||
body: JSON.stringify({
|
||
success: true,
|
||
data,
|
||
timestamp: new Date().toISOString()
|
||
})
|
||
};
|
||
}, { requireAuth: false }); // 公开接口,不需要认证
|