Upload 4 files
Browse files- manifest.json +18 -0
- middleware.js +61 -0
- nodemon.json +21 -0
- render.yaml +8 -0
manifest.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "LibreTV",
|
| 3 |
+
"short_name": "LibreTV",
|
| 4 |
+
"description": "免费在线视频搜索与观看平台",
|
| 5 |
+
"start_url": ".",
|
| 6 |
+
"display": "standalone",
|
| 7 |
+
"background_color": "#0f1622",
|
| 8 |
+
"theme_color": "#000000",
|
| 9 |
+
"apple-mobile-web-app-capable": "yes",
|
| 10 |
+
"apple-mobile-web-app-status-bar-style": "black",
|
| 11 |
+
"icons": [
|
| 12 |
+
{
|
| 13 |
+
"src": "image/logo-black.png",
|
| 14 |
+
"sizes": "512x512",
|
| 15 |
+
"type": "image/png"
|
| 16 |
+
}
|
| 17 |
+
]
|
| 18 |
+
}
|
middleware.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { sha256 } from './js/sha256.js'; // 需新建或引入SHA-256实现
|
| 2 |
+
|
| 3 |
+
// Vercel Middleware to inject environment variables
|
| 4 |
+
export default async function middleware(request) {
|
| 5 |
+
// Get the URL from the request
|
| 6 |
+
const url = new URL(request.url);
|
| 7 |
+
|
| 8 |
+
// Only process HTML pages
|
| 9 |
+
const isHtmlPage = url.pathname.endsWith('.html') || url.pathname.endsWith('/');
|
| 10 |
+
if (!isHtmlPage) {
|
| 11 |
+
return; // Let the request pass through unchanged
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
// Fetch the original response
|
| 15 |
+
const response = await fetch(request);
|
| 16 |
+
|
| 17 |
+
// Check if it's an HTML response
|
| 18 |
+
const contentType = response.headers.get('content-type') || '';
|
| 19 |
+
if (!contentType.includes('text/html')) {
|
| 20 |
+
return response; // Return the original response if not HTML
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
// Get the HTML content
|
| 24 |
+
const originalHtml = await response.text();
|
| 25 |
+
|
| 26 |
+
// Replace the placeholder with actual environment variable
|
| 27 |
+
// If PASSWORD is not set, replace with empty string
|
| 28 |
+
const password = process.env.PASSWORD || '';
|
| 29 |
+
let passwordHash = '';
|
| 30 |
+
if (password) {
|
| 31 |
+
passwordHash = await sha256(password);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
const adminpassword = process.env.ADMINPASSWORD || '';
|
| 35 |
+
let adminpasswordHash = '';
|
| 36 |
+
if (adminpassword) {
|
| 37 |
+
adminpasswordHash = await sha256(adminpassword); // 修复变量名
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
// 合并两次替换为一次操作
|
| 41 |
+
let modifiedHtml = originalHtml
|
| 42 |
+
.replace(
|
| 43 |
+
'window.__ENV__.PASSWORD = "{{PASSWORD}}";',
|
| 44 |
+
`window.__ENV__.PASSWORD = "${passwordHash}"; // SHA-256 hash`
|
| 45 |
+
)
|
| 46 |
+
.replace(
|
| 47 |
+
'window.__ENV__.ADMINPASSWORD = "{{ADMINPASSWORD}}";',
|
| 48 |
+
`window.__ENV__.ADMINPASSWORD = "${adminpasswordHash}"; // SHA-256 hash`
|
| 49 |
+
);
|
| 50 |
+
|
| 51 |
+
// 修复Response构造
|
| 52 |
+
return new Response(modifiedHtml, {
|
| 53 |
+
status: response.status,
|
| 54 |
+
statusText: response.statusText,
|
| 55 |
+
headers: response.headers
|
| 56 |
+
});
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
export const config = {
|
| 60 |
+
matcher: ['/', '/((?!api|_next/static|_vercel|favicon.ico).*)'],
|
| 61 |
+
};
|
nodemon.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"watch": [
|
| 3 |
+
"server.mjs",
|
| 4 |
+
"*.html",
|
| 5 |
+
".env"
|
| 6 |
+
],
|
| 7 |
+
"ext": "js,mjs,json,html,css",
|
| 8 |
+
"ignore": [
|
| 9 |
+
"node_modules/**/*",
|
| 10 |
+
".git/**/*"
|
| 11 |
+
],
|
| 12 |
+
"delay": "500",
|
| 13 |
+
"env": {
|
| 14 |
+
"NODE_ENV": "development"
|
| 15 |
+
},
|
| 16 |
+
"execMap": {
|
| 17 |
+
"mjs": "node"
|
| 18 |
+
},
|
| 19 |
+
"verbose": true,
|
| 20 |
+
"restartable": "rs"
|
| 21 |
+
}
|
render.yaml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
services:
|
| 2 |
+
- type: web
|
| 3 |
+
name: libretv
|
| 4 |
+
runtime: node
|
| 5 |
+
plan: free
|
| 6 |
+
buildCommand: 'npm install'
|
| 7 |
+
startCommand: 'node server.mjs'
|
| 8 |
+
autoDeploy: true
|