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获取认证信息