Files
2026-03-16 09:24:05 +08:00

217 lines
12 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>临时邮箱</title>
<!-- 运行时注入域名列表(从 env.MAIL_DOMAIN 解析),用于前端域名选择 -->
<meta name="mail-domains" content="">
<link rel="preload" href="/html/app.html" as="fetch" crossorigin>
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<link rel="icon" href="favicon.svg" type="image/svg+xml" />
<link rel="shortcut icon" href="favicon.svg" type="image/svg+xml" />
<link rel="stylesheet" href="/css/app.css" />
<link rel="stylesheet" href="/css/app-mobile.css" media="(max-width: 900px)" />
<script src="/js/toast-utils.js"></script>
<script src="/js/mock.js"></script>
<!-- 提前内联保存 hash保证最早阶段即可保留路由信息 -->
<script>
try{ if (location.hash){ sessionStorage.setItem('mf:preservedHash', location.hash); } }catch(_){ }
</script>
<script src="/js/auth-guard.js"></script>
<script src="/js/app-router.js" defer></script>
</head>
<body>
<div id="app"></div>
<script>
// 改进的路由守卫逻辑:优先使用 loading 页面进行权限检查,避免登录页闪屏
(function() {
try{
// 检查是否是从其他页面导航过来(非地址栏直接访问)
var isDirectAccess = !document.referrer || window.history.length <= 1;
// 检查近期认证标记10秒内- 延长时间窗口以减少重复检查
var ts = 0;
try{ ts = Number(sessionStorage.getItem('auth_checked_ts') || '0'); }catch(_){ }
var recentlyChecked = ts && (Date.now() - ts) < 10000;
// 如果最近已验证过,直接加载应用
if (recentlyChecked && !isDirectAccess){
var s1 = document.createElement('script');
s1.type='module';
s1.src='/js/app.js';
document.body.appendChild(s1);
try{
if (window.matchMedia && window.matchMedia('(max-width: 900px)').matches){
var sm1=document.createElement('script');
sm1.type='module';
sm1.src='/js/app-mobile.js';
document.body.appendChild(sm1);
}
}catch(_){ }
return;
}
// 地址栏直接访问或长时间未验证:先尝试快速判断是否已有登录 Cookie
if (isDirectAccess){
try{
var hasCookie = document.cookie.split(';').some(function(c){ return c.trim().indexOf('iding-session=') === 0; });
if (hasCookie){
// 已有登录 Cookie优化验证逻辑减少不必要的登录页跳转
const controller = new AbortController();
const tid = setTimeout(function(){ try{ controller.abort(); }catch(_){ } }, 3000); // 延长超时时间到3秒
fetch('/api/session', { headers:{'Cache-Control':'no-cache'}, signal: controller.signal, credentials: 'include' })
.then(function(r){
clearTimeout(tid);
if (!r || !r.ok) {
// 对于有cookie但验证失败的情况直接加载应用让其内部处理
// 避免跳转到登录页造成页面闪烁
try{ sessionStorage.setItem('auth_checked','true'); sessionStorage.setItem('auth_checked_ts', String(Date.now())); }catch(_){ }
var s1=document.createElement('script'); s1.type='module'; s1.src='/js/app.js'; document.body.appendChild(s1);
try{ if (window.matchMedia && window.matchMedia('(max-width: 900px)').matches){ var sm=document.createElement('script'); sm.type='module'; sm.src='/js/app-mobile.js'; document.body.appendChild(sm); } }catch(_){ }
return;
}
return r.json();
})
.then(function(s){
if (!s) return;
if (s.role === 'mailbox') { window.location.replace('/html/mailbox.html'); return; }
try{ sessionStorage.setItem('auth_checked','true'); sessionStorage.setItem('auth_checked_ts', String(Date.now())); }catch(_){ }
// 加载应用
var s1=document.createElement('script'); s1.type='module'; s1.src='/js/app.js'; document.body.appendChild(s1);
try{ if (window.matchMedia && window.matchMedia('(max-width: 900px)').matches){ var sm=document.createElement('script'); sm.type='module'; sm.src='/js/app-mobile.js'; document.body.appendChild(sm); } }catch(_){ }
})
.catch(function(){
// 网络错误时如果有cookie就直接加载应用让应用内部处理认证状态
// 这样避免了网络问题导致的不必要登录页跳转
try{ sessionStorage.setItem('auth_checked','true'); sessionStorage.setItem('auth_checked_ts', String(Date.now())); }catch(_){ }
var s1=document.createElement('script'); s1.type='module'; s1.src='/js/app.js'; document.body.appendChild(s1);
try{ if (window.matchMedia && window.matchMedia('(max-width: 900px)').matches){ var sm=document.createElement('script'); sm.type='module'; sm.src='/js/app-mobile.js'; document.body.appendChild(sm); } }catch(_){ }
});
return;
}
}catch(_){ }
// 显示 loading 界面,同时进行权限检查
var loadingDiv = document.createElement('div');
loadingDiv.innerHTML = '<div style="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#f8fafc;z-index:9999"><div style="text-align:center"><div style="font-size:3rem;margin-bottom:1rem">📧</div><div style="width:40px;height:40px;border:3px solid rgba(59,130,246,0.2);border-top:3px solid #3b82f6;border-radius:50%;animation:spin 1s linear infinite;margin:0 auto"></div><style>@keyframes spin{to{transform:rotate(360deg)}}</style></div></div>';
document.body.appendChild(loadingDiv);
// 并行进行权限检查
const controller = new AbortController();
const tid = setTimeout(function(){ try{ controller.abort(); }catch(_){ } }, 2500); // 延长超时到2.5秒
fetch('/api/session', {
headers: { 'Cache-Control': 'no-cache' },
signal: controller.signal,
credentials: 'include'
})
.then(function(r){
clearTimeout(tid);
if (r && r.ok){
return r.json().then(function(s){
if (s && s.role === 'mailbox') { window.location.replace('/html/mailbox.html'); return null; }
return s;
});
} else {
// 跳转到 loading 页面进行更完整的权限检查
window.location.replace('/templates/loading.html?redirect=/');
return null;
}
})
.then(function(s){
if (!s) return;
try{
sessionStorage.setItem('auth_checked','true');
sessionStorage.setItem('auth_checked_ts', String(Date.now()));
}catch(_){ }
// 移除 loading 界面
if (loadingDiv) loadingDiv.remove();
// 加载应用
var s = document.createElement('script');
s.type = 'module';
s.src = '/js/app.js';
document.body.appendChild(s);
try{
if (window.matchMedia && window.matchMedia('(max-width: 900px)').matches){
var sm=document.createElement('script');
sm.type='module';
sm.src='/js/app-mobile.js';
document.body.appendChild(sm);
}
}catch(_){ }
})
.catch(function(){
// 网络错误时跳转到 loading 页面
window.location.replace('/templates/loading.html?redirect=/');
});
} else {
// 非直接访问:快速权限检查
var hasCookie = false;
try{ hasCookie = document.cookie.split(';').some(function(c){ return c.trim().indexOf('iding-session=') === 0; }); }catch(_){ }
const controller = new AbortController();
const tid = setTimeout(function(){ try{ controller.abort(); }catch(_){ } }, 2000); // 延长超时到2秒
fetch('/api/session', {
headers: { 'Cache-Control': 'no-cache' },
signal: controller.signal,
credentials: 'include'
})
.then(function(r){
clearTimeout(tid);
if (r && r.ok){
return r.json().then(function(s){
if (s && s.role === 'mailbox') { window.location.replace('/html/mailbox.html'); return null; }
return s;
});
} else {
// 如果有cookie但验证失败让应用内部处理而不是立即跳转到登录页
if (hasCookie) {
try{ sessionStorage.setItem('auth_checked','true'); sessionStorage.setItem('auth_checked_ts', String(Date.now())); }catch(_){ }
var s1 = document.createElement('script'); s1.type = 'module'; s1.src = '/js/app.js'; document.body.appendChild(s1);
try{ if (window.matchMedia && window.matchMedia('(max-width: 900px)').matches){ var sm=document.createElement('script'); sm.type='module'; sm.src='/js/app-mobile.js'; document.body.appendChild(sm); } }catch(_){ }
return null;
}
window.location.replace('/html/login.html');
return null;
}
})
.then(function(s){
if (!s) return;
try{
sessionStorage.setItem('auth_checked','true');
sessionStorage.setItem('auth_checked_ts', String(Date.now()));
}catch(_){ }
var s1 = document.createElement('script');
s1.type = 'module';
s1.src = '/js/app.js';
document.body.appendChild(s1);
try{
if (window.matchMedia && window.matchMedia('(max-width: 900px)').matches){
var sm=document.createElement('script');
sm.type='module';
sm.src='/js/app-mobile.js';
document.body.appendChild(sm);
}
}catch(_){ }
})
.catch(function(){
// 网络错误时如果有cookie就直接加载应用
if (hasCookie) {
try{ sessionStorage.setItem('auth_checked','true'); sessionStorage.setItem('auth_checked_ts', String(Date.now())); }catch(_){ }
var s1 = document.createElement('script'); s1.type = 'module'; s1.src = '/js/app.js'; document.body.appendChild(s1);
try{ if (window.matchMedia && window.matchMedia('(max-width: 900px)').matches){ var sm=document.createElement('script'); sm.type='module'; sm.src='/js/app-mobile.js'; document.body.appendChild(sm); } }catch(_){ }
} else {
window.location.replace('/html/login.html');
}
});
}
}catch(_){
window.location.replace('/templates/loading.html?redirect=/');
}
})();
</script>
</body>
</html>