迁移聊天消息安全工具
This commit is contained in:
@@ -59,6 +59,55 @@
|
||||
const CHAT_MESSAGE_FLUSH_BATCH_SIZE = 8;
|
||||
const PUBLIC_MESSAGE_NODE_LIMIT = 600;
|
||||
const PRIVATE_MESSAGE_NODE_LIMIT = 300;
|
||||
// Vite 模块稍后会覆盖这些全局工具;这里保留极小同步兜底,避免经典脚本早期事件取不到同名函数。
|
||||
window.escapeHtml = window.escapeHtml || ((text) => {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
});
|
||||
window.normalizeSafeChatUrl = window.normalizeSafeChatUrl || ((url, fallback) => {
|
||||
try {
|
||||
const parsedUrl = new URL(url || fallback, window.location.origin);
|
||||
|
||||
if (!['http:', 'https:'].includes(parsedUrl.protocol) || parsedUrl.origin !== window.location.origin) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
return parsedUrl.toString();
|
||||
} catch (error) {
|
||||
return fallback;
|
||||
}
|
||||
});
|
||||
window.isExpiredChatImageMessage = window.isExpiredChatImageMessage || ((msg) => {
|
||||
if (!msg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (msg.message_type === 'expired_image') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg.message_type !== 'image') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!msg.image_url || !msg.image_thumb_url) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const retentionDays = parseInt(window.chatContext?.chatImageRetentionDays || 3, 10);
|
||||
const sentAtText = String(msg.sent_at || '').replace(' ', 'T');
|
||||
const sentAt = sentAtText ? new Date(sentAtText) : null;
|
||||
|
||||
if (!sentAt || Number.isNaN(sentAt.getTime())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Date.now() >= sentAt.getTime() + retentionDays * 24 * 60 * 60 * 1000;
|
||||
});
|
||||
const escapeHtml = (...args) => window.escapeHtml(...args);
|
||||
const normalizeSafeChatUrl = (...args) => window.normalizeSafeChatUrl(...args);
|
||||
const isExpiredChatImageMessage = (...args) => window.isExpiredChatImageMessage(...args);
|
||||
const initialChatPreferences = normalizeChatPreferences(window.chatContext?.chatPreferences || {});
|
||||
let blockedSystemSenders = new Set(initialChatPreferences.blocked_system_senders);
|
||||
|
||||
@@ -1349,37 +1398,6 @@
|
||||
|
||||
window.showVipPresenceBanner = showVipPresenceBanner;
|
||||
|
||||
/**
|
||||
* 判断图片消息是否已经超过前端允许展示的保留期。
|
||||
*/
|
||||
function isExpiredChatImageMessage(msg) {
|
||||
if (!msg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (msg.message_type === 'expired_image') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg.message_type !== 'image') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!msg.image_url || !msg.image_thumb_url) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const retentionDays = parseInt(window.chatContext?.chatImageRetentionDays || 3, 10);
|
||||
const sentAtText = String(msg.sent_at || '').replace(' ', 'T');
|
||||
const sentAt = sentAtText ? new Date(sentAtText) : null;
|
||||
|
||||
if (!sentAt || Number.isNaN(sentAt.getTime())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Date.now() >= sentAt.getTime() + retentionDays * 24 * 60 * 60 * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建普通聊天消息的正文区域,支持缩略图与过期占位渲染。
|
||||
*/
|
||||
@@ -3832,33 +3850,4 @@
|
||||
setInterval(() => saveExp(true), HEARTBEAT_INTERVAL);
|
||||
setTimeout(() => saveExp(true), 10000);
|
||||
|
||||
|
||||
/**
|
||||
* HTML 转义函数,防止 XSS
|
||||
*/
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* 规整广播携带的链接,只允许当前站点的 http(s) 地址进入 innerHTML。
|
||||
*/
|
||||
function normalizeSafeChatUrl(url, fallback) {
|
||||
try {
|
||||
const parsedUrl = new URL(url || fallback, window.location.origin);
|
||||
if (!['http:', 'https:'].includes(parsedUrl.protocol)) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
if (parsedUrl.origin !== window.location.origin) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
return parsedUrl.toString();
|
||||
} catch (error) {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user