fix: giffgaff tutorial link; freeze legacy pages

This commit is contained in:
Abner
2025-12-31 00:21:43 +08:00
parent be8c2b4522
commit 9da2e0bf95
5 changed files with 125 additions and 5 deletions

View File

@@ -10,7 +10,9 @@
"start": "node server.js",
"dev": "nodemon server.js",
"build": "npm run build:static",
"build:static": "node scripts/build-static.js",
"build:static": "node scripts/verify-legacy-frozen.js && node scripts/build-static.js",
"verify:legacy": "node scripts/verify-legacy-frozen.js",
"verify:legacy:update": "node scripts/verify-legacy-frozen.js --update",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",

View File

@@ -0,0 +1,7 @@
{
"algorithm": "sha256",
"files": {
"src/giffgaff/giffgaff_complete_esim.html": "5ed77b006a633642c24fbcd672217d6fabdd24e090c545afb97efa3096da9aff",
"src/simyo/simyo_complete_esim.html": "f7ca167f6fa07d4c2dbc2630d6edf9e8ea247023b9ebd45ea4e2093d7edbc576"
}
}

View File

@@ -0,0 +1,110 @@
#!/usr/bin/env node
/**
* Legacy 页面冻结校验
*
* 目标:确保 /giffgaff-legacy 与 /simyo-legacy 对应的「旧页面源文件」不会被误改动。
* - /giffgaff-legacy -> src/giffgaff/giffgaff_complete_esim.html
* - /simyo-legacy -> src/simyo/simyo_complete_esim.html
*
* 用法:
* - 校验默认node scripts/verify-legacy-frozen.js
* - 更新基线: node scripts/verify-legacy-frozen.js --update
*/
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const projectRoot = path.join(__dirname, '..');
const baselinePath = path.join(__dirname, 'legacy-freeze.json');
function sha256(content) {
return crypto.createHash('sha256').update(content).digest('hex');
}
function readJson(filePath) {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
}
function writeJson(filePath, value) {
fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
}
function resolveProjectPath(relPath) {
return path.join(projectRoot, relPath);
}
function computeFileHash(relPath) {
const fullPath = resolveProjectPath(relPath);
if (!fs.existsSync(fullPath)) {
throw new Error(`missing file: ${relPath}`);
}
const content = fs.readFileSync(fullPath, 'utf8');
return sha256(content);
}
function main() {
const shouldUpdate = process.argv.includes('--update');
if (!fs.existsSync(baselinePath)) {
console.error(`[Legacy Freeze] ✗ 基线文件不存在: ${path.relative(projectRoot, baselinePath)}`);
process.exitCode = 1;
return;
}
const baseline = readJson(baselinePath);
const algorithm = baseline.algorithm || 'sha256';
if (algorithm !== 'sha256') {
console.error(`[Legacy Freeze] ✗ 不支持的 hash 算法: ${algorithm}`);
process.exitCode = 1;
return;
}
const fileMap = baseline.files || {};
const fileEntries = Object.entries(fileMap);
if (fileEntries.length === 0) {
console.error('[Legacy Freeze] ✗ 基线 files 为空,无法校验');
process.exitCode = 1;
return;
}
if (shouldUpdate) {
const next = { algorithm: 'sha256', files: {} };
for (const [relPath] of fileEntries) {
next.files[relPath] = computeFileHash(relPath);
}
writeJson(baselinePath, next);
console.log(`[Legacy Freeze] ✓ 已更新基线: ${path.relative(projectRoot, baselinePath)}`);
return;
}
let hasMismatch = false;
for (const [relPath, expected] of fileEntries) {
let actual;
try {
actual = computeFileHash(relPath);
} catch (err) {
console.error(`[Legacy Freeze] ✗ 缺失文件: ${relPath} (${err.message})`);
hasMismatch = true;
continue;
}
if (actual !== expected) {
console.error(`[Legacy Freeze] ✗ 文件已变更(冻结保护触发): ${relPath}`);
console.error(` expected: ${expected}`);
console.error(` actual: ${actual}`);
hasMismatch = true;
} else {
console.log(`[Legacy Freeze] ✓ OK: ${relPath}`);
}
}
if (hasMismatch) {
console.error('[Legacy Freeze] 解决方式如需有意更新旧页面请运行node scripts/verify-legacy-frozen.js --update');
process.exitCode = 1;
}
}
main();

View File

@@ -65,11 +65,11 @@
<div class="language-switcher">
<button id="languageSwitcher" class="lang-switch" type="button" aria-label="切换语言到英文">🌐 English</button>
</div>
<button id="tutorialBtn" class="login-btn" aria-label="查看教程">
<a id="tutorialBtn" class="login-btn" href="https://github.com/Silentely/eSIM-Tools/blob/main/docs/User_Guide.md" target="_blank" rel="noopener noreferrer" aria-label="查看教程">
<i class="fas fa-book" aria-hidden="true"></i>
<span class="lang-zh">查看教程</span>
<span class="lang-en">View Tutorial</span>
</button>
</a>
<a href="https://github.com/Silentely/eSIM-Tools" target="_blank" class="github-btn" aria-label="打开GitHub仓库">
<i class="fab fa-github" aria-hidden="true"></i> GitHub
</a>

View File

@@ -69,7 +69,8 @@ class DOMManager {
this.elements.tutorialBtn = document.getElementById('tutorialBtn');
// 绑定教程按钮点击事件
if (this.elements.tutorialBtn) {
// 说明:优先使用 <a href target="_blank">,确保在 WebView/PWA 或 JS 初始化失败时也能打开教程
if (this.elements.tutorialBtn && this.elements.tutorialBtn.tagName !== 'A') {
this.elements.tutorialBtn.addEventListener('click', () => {
window.open('https://github.com/Silentely/eSIM-Tools/blob/main/docs/User_Guide.md', '_blank');
});
@@ -401,4 +402,4 @@ class DOMManager {
}
}
export default new DOMManager();
export default new DOMManager();