diff --git a/README.md b/README.md index 1edc849..8d414ec 100644 --- a/README.md +++ b/README.md @@ -268,6 +268,13 @@ dockge/komodo 等 docker compose UI 也有自动更新功能 | VIDEOINFO_CACHE_MINUTES | 私人影库视频信息在内存中的缓存时长(分钟) | 正整数 | 1440(1天) | | NEXT_PUBLIC_ENABLE_SOURCE_SEARCH | 是否开启源站寻片功能 | true/false | true | | MAX_PLAY_RECORDS_PER_USER | 单个用户播放记录清理阈值(超过此数量将自动清理旧记录) | 正整数 | 100 | +| INIT_CONFIG | 初始配置(JSON 格式,包含 api_site、custom_category、lives 等) | JSON 字符串 | (空) | +| CONFIG_SUBSCRIPTION_URL | 配置订阅 URL(Base58 编码的配置文件地址,优先级高于 INIT_CONFIG) | URL | (空) | +| TMDB_API_KEY | TMDB API 密钥 | 任意字符串 | (空) | +| TMDB_PROXY | TMDB 代理地址 | URL | (空) | +| TMDB_REVERSE_PROXY | TMDB 反向代理地址 | URL | (空) | +| DANMAKU_API_BASE | 弹幕 API 地址 | URL | http://localhost:9321 | +| DANMAKU_API_TOKEN | 弹幕 API Token | 任意字符串 | 87654321 | NEXT_PUBLIC_DOUBAN_PROXY_TYPE 选项解释: diff --git a/src/app/api/login/route.ts b/src/app/api/login/route.ts index 6ee58f4..a0b20ae 100644 --- a/src/app/api/login/route.ts +++ b/src/app/api/login/route.ts @@ -129,10 +129,11 @@ export async function POST(req: NextRequest) { // 验证成功,设置认证cookie const response = NextResponse.json({ ok: true }); + const username = process.env.USERNAME || 'default'; const cookieValue = await generateAuthCookie( - undefined, + username, password, - 'user', + 'owner', true ); // localstorage 模式包含 password const expires = new Date(); diff --git a/src/app/warning/page.tsx b/src/app/warning/page.tsx index dcc70f8..498e80d 100644 --- a/src/app/warning/page.tsx +++ b/src/app/warning/page.tsx @@ -47,15 +47,6 @@ export default function WarningPage() {

-
-

- 📢 重要更新说明 -

-

- 自 v205.0.0 版本起,已不再支持无数据库部署方式,请配置数据库相关环境变量。 -

-
-

主要风险 diff --git a/src/lib/config.ts b/src/lib/config.ts index 8d8d86a..74ad294 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -194,13 +194,37 @@ async function getInitConfig(configFile: string, subConfig: { LastCheck: "", }): Promise { let cfgFile: ConfigFileStruct; + + // 优先从环境变量读取订阅 URL + const envSubUrl = process.env.CONFIG_SUBSCRIPTION_URL || ""; + + if (envSubUrl) { + try { + const response = await fetch(envSubUrl); + if (response.ok) { + const configContent = await response.text(); + const bs58 = (await import('bs58')).default; + const decodedBytes = bs58.decode(configContent); + const decodedContent = new TextDecoder().decode(decodedBytes); + configFile = decodedContent; + console.log('已从订阅 URL 获取配置'); + } + } catch (e) { + console.error('从订阅 URL 获取配置失败:', e); + } + } + + // 优先从环境变量读取配置 + const envConfig = process.env.INIT_CONFIG || ""; + const configSource = envConfig || configFile; + try { - cfgFile = JSON.parse(configFile) as ConfigFileStruct; + cfgFile = JSON.parse(configSource) as ConfigFileStruct; } catch (e) { cfgFile = {} as ConfigFileStruct; } const adminConfig: AdminConfig = { - ConfigFile: configFile, + ConfigFile: configSource, ConfigSubscribtion: subConfig, SiteConfig: { SiteName: process.env.NEXT_PUBLIC_SITE_NAME || 'MoonTVPlus', @@ -224,9 +248,9 @@ async function getInitConfig(configFile: string, subConfig: { DanmakuApiBase: process.env.DANMAKU_API_BASE || 'http://localhost:9321', DanmakuApiToken: process.env.DANMAKU_API_TOKEN || '87654321', // TMDB配置 - TMDBApiKey: '', - TMDBProxy: '', - TMDBReverseProxy: '', + TMDBApiKey: process.env.TMDB_API_KEY || '', + TMDBProxy: process.env.TMDB_PROXY || '', + TMDBReverseProxy: process.env.TMDB_REVERSE_PROXY || '', // 评论功能开关 EnableComments: false, }, @@ -245,13 +269,21 @@ async function getInitConfig(configFile: string, subConfig: { } catch (e) { console.error('获取用户列表失败:', e); } - const allUsers = userNames.filter((u) => u !== process.env.USERNAME).map((u) => ({ + + // localStorage 模式下,只使用环境变量中的站长账号 + const storageType = process.env.NEXT_PUBLIC_STORAGE_TYPE || 'localstorage'; + if (storageType === 'localstorage') { + userNames = []; + } + + const ownerUsername = process.env.USERNAME || 'default'; + const allUsers = userNames.filter((u) => u !== ownerUsername).map((u) => ({ username: u, role: 'user', banned: false, })); allUsers.unshift({ - username: process.env.USERNAME!, + username: ownerUsername, role: 'owner', banned: false, }); @@ -313,6 +345,17 @@ export async function getConfig(): Promise { // 创建初始化 Promise configInitPromise = (async () => { + const storageType = process.env.NEXT_PUBLIC_STORAGE_TYPE || 'localstorage'; + + // localStorage 模式下直接从环境变量初始化 + if (storageType === 'localstorage') { + console.log('localStorage 模式:从环境变量初始化配置'); + const adminConfig = await getInitConfig(""); + cachedConfig = configSelfCheck(adminConfig); + configInitPromise = null; + return cachedConfig; + } + // 读 db let adminConfig: AdminConfig | null = null; let dbReadFailed = false; @@ -564,6 +607,12 @@ export async function getAvailableApiSites(user?: string): Promise { return allApiSites; } + // localStorage 模式下直接返回所有可用源 + const storageType = process.env.NEXT_PUBLIC_STORAGE_TYPE || 'localstorage'; + if (storageType === 'localstorage') { + return allApiSites; + } + // 从V2存储中获取用户信息 const userInfoV2 = await db.getUserInfoV2(user); if (!userInfoV2) { diff --git a/src/middleware.ts b/src/middleware.ts index 32b3727..43a9a15 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -14,10 +14,10 @@ export async function middleware(request: NextRequest) { const storageType = process.env.NEXT_PUBLIC_STORAGE_TYPE || 'localstorage'; - if (!process.env.USERNAME || !process.env.NEXT_PUBLIC_STORAGE_TYPE || !process.env.PASSWORD) { - // 如果未配置必要的环境变量,重定向到警告页面 + if (!process.env.PASSWORD) { + // 如果未配置密码,重定向到警告页面 const warningUrl = new URL('/warning', request.url); - return NextResponse.redirect(warningUrl); + return warningUrl.pathname === pathname ? NextResponse.next() : NextResponse.redirect(warningUrl); } // 从cookie获取认证信息