修正getAllUsers(),修正启动时自动迁移执行多次
This commit is contained in:
@@ -55,6 +55,7 @@ export const API_CONFIG = {
|
|||||||
|
|
||||||
// 在模块加载时根据环境决定配置来源
|
// 在模块加载时根据环境决定配置来源
|
||||||
let cachedConfig: AdminConfig;
|
let cachedConfig: AdminConfig;
|
||||||
|
let configInitPromise: Promise<AdminConfig> | null = null;
|
||||||
|
|
||||||
|
|
||||||
// 从配置文件补充管理员配置
|
// 从配置文件补充管理员配置
|
||||||
@@ -303,57 +304,69 @@ export async function getConfig(): Promise<AdminConfig> {
|
|||||||
return cachedConfig;
|
return cachedConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读 db
|
// 如果正在初始化,等待初始化完成
|
||||||
let adminConfig: AdminConfig | null = null;
|
if (configInitPromise) {
|
||||||
let dbReadFailed = false;
|
return configInitPromise;
|
||||||
try {
|
|
||||||
adminConfig = await db.getAdminConfig();
|
|
||||||
} catch (e) {
|
|
||||||
console.error('获取管理员配置失败:', e);
|
|
||||||
dbReadFailed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// db 中无配置,执行一次初始化
|
// 创建初始化 Promise
|
||||||
if (!adminConfig) {
|
configInitPromise = (async () => {
|
||||||
if (dbReadFailed) {
|
// 读 db
|
||||||
// 数据库读取失败,使用默认配置但不保存,避免覆盖数据库
|
let adminConfig: AdminConfig | null = null;
|
||||||
console.warn('数据库读取失败,使用临时默认配置(不会保存到数据库)');
|
let dbReadFailed = false;
|
||||||
adminConfig = await getInitConfig("");
|
|
||||||
} else {
|
|
||||||
// 数据库中确实没有配置,首次初始化并保存
|
|
||||||
console.log('首次初始化配置');
|
|
||||||
adminConfig = await getInitConfig("");
|
|
||||||
await db.saveAdminConfig(adminConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
adminConfig = configSelfCheck(adminConfig);
|
|
||||||
cachedConfig = adminConfig;
|
|
||||||
|
|
||||||
// 自动迁移用户(如果配置中有用户且V2存储支持)
|
|
||||||
// 过滤掉站长后检查是否有需要迁移的用户
|
|
||||||
const nonOwnerUsers = adminConfig.UserConfig.Users.filter(
|
|
||||||
(u) => u.username !== process.env.USERNAME
|
|
||||||
);
|
|
||||||
if (!dbReadFailed && nonOwnerUsers.length > 0) {
|
|
||||||
try {
|
try {
|
||||||
// 检查是否支持V2存储
|
adminConfig = await db.getAdminConfig();
|
||||||
const storage = (db as any).storage;
|
} catch (e) {
|
||||||
if (storage && typeof storage.createUserV2 === 'function') {
|
console.error('获取管理员配置失败:', e);
|
||||||
console.log('检测到配置中有用户,开始自动迁移...');
|
dbReadFailed = true;
|
||||||
await db.migrateUsersFromConfig(adminConfig);
|
|
||||||
// 迁移完成后,清空配置中的用户列表并保存
|
|
||||||
adminConfig.UserConfig.Users = [];
|
|
||||||
await db.saveAdminConfig(adminConfig);
|
|
||||||
cachedConfig = adminConfig;
|
|
||||||
console.log('用户自动迁移完成');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('自动迁移用户失败:', error);
|
|
||||||
// 不影响主流程,继续执行
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return cachedConfig;
|
// db 中无配置,执行一次初始化
|
||||||
|
if (!adminConfig) {
|
||||||
|
if (dbReadFailed) {
|
||||||
|
// 数据库读取失败,使用默认配置但不保存,避免覆盖数据库
|
||||||
|
console.warn('数据库读取失败,使用临时默认配置(不会保存到数据库)');
|
||||||
|
adminConfig = await getInitConfig("");
|
||||||
|
} else {
|
||||||
|
// 数据库中确实没有配置,首次初始化并保存
|
||||||
|
console.log('首次初始化配置');
|
||||||
|
adminConfig = await getInitConfig("");
|
||||||
|
await db.saveAdminConfig(adminConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
adminConfig = configSelfCheck(adminConfig);
|
||||||
|
cachedConfig = adminConfig;
|
||||||
|
|
||||||
|
// 自动迁移用户(如果配置中有用户且V2存储支持)
|
||||||
|
// 过滤掉站长后检查是否有需要迁移的用户
|
||||||
|
const nonOwnerUsers = adminConfig.UserConfig.Users.filter(
|
||||||
|
(u) => u.username !== process.env.USERNAME
|
||||||
|
);
|
||||||
|
if (!dbReadFailed && nonOwnerUsers.length > 0) {
|
||||||
|
try {
|
||||||
|
// 检查是否支持V2存储
|
||||||
|
const storage = (db as any).storage;
|
||||||
|
if (storage && typeof storage.createUserV2 === 'function') {
|
||||||
|
console.log('检测到配置中有用户,开始自动迁移...');
|
||||||
|
await db.migrateUsersFromConfig(adminConfig);
|
||||||
|
// 迁移完成后,清空配置中的用户列表并保存
|
||||||
|
adminConfig.UserConfig.Users = [];
|
||||||
|
await db.saveAdminConfig(adminConfig);
|
||||||
|
cachedConfig = adminConfig;
|
||||||
|
console.log('用户自动迁移完成');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('自动迁移用户失败:', error);
|
||||||
|
// 不影响主流程,继续执行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除初始化 Promise
|
||||||
|
configInitPromise = null;
|
||||||
|
return cachedConfig;
|
||||||
|
})();
|
||||||
|
|
||||||
|
return configInitPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function configSelfCheck(adminConfig: AdminConfig): AdminConfig {
|
export function configSelfCheck(adminConfig: AdminConfig): AdminConfig {
|
||||||
|
|||||||
@@ -645,13 +645,12 @@ export abstract class BaseRedisStorage implements IStorage {
|
|||||||
|
|
||||||
// ---------- 获取全部用户 ----------
|
// ---------- 获取全部用户 ----------
|
||||||
async getAllUsers(): Promise<string[]> {
|
async getAllUsers(): Promise<string[]> {
|
||||||
const keys = await this.withRetry(() => this.client.keys('u:*:pwd'));
|
// 从新版用户列表获取
|
||||||
return keys
|
const userListKey = this.userListKey();
|
||||||
.map((k) => {
|
const users = await this.withRetry(() =>
|
||||||
const match = k.match(/^u:(.+?):pwd$/);
|
this.client.zRange(userListKey, 0, -1)
|
||||||
return match ? ensureString(match[1]) : undefined;
|
);
|
||||||
})
|
return users.map(u => ensureString(u));
|
||||||
.filter((u): u is string => typeof u === 'string');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- 管理员配置 ----------
|
// ---------- 管理员配置 ----------
|
||||||
|
|||||||
@@ -673,13 +673,12 @@ export class UpstashRedisStorage implements IStorage {
|
|||||||
|
|
||||||
// ---------- 获取全部用户 ----------
|
// ---------- 获取全部用户 ----------
|
||||||
async getAllUsers(): Promise<string[]> {
|
async getAllUsers(): Promise<string[]> {
|
||||||
const keys = await withRetry(() => this.client.keys('u:*:pwd'));
|
// 从新版用户列表获取
|
||||||
return keys
|
const userListKey = this.userListKey();
|
||||||
.map((k) => {
|
const users = await withRetry(() =>
|
||||||
const match = k.match(/^u:(.+?):pwd$/);
|
this.client.zrange(userListKey, 0, -1)
|
||||||
return match ? ensureString(match[1]) : undefined;
|
);
|
||||||
})
|
return users.map(u => ensureString(u));
|
||||||
.filter((u): u is string => typeof u === 'string');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- 管理员配置 ----------
|
// ---------- 管理员配置 ----------
|
||||||
|
|||||||
Reference in New Issue
Block a user