feat: v3.1.0 OSS直连优化与代码质量提升
- 🚀 OSS 直连上传下载(用户直连OSS,不经过后端) - ✨ 新增 Presigned URL 签名接口 - ✨ 支持自定义 OSS endpoint 配置 - 🐛 修复 buildS3Config 不支持自定义 endpoint 的问题 - 🐛 清理残留的 basic-ftp 依赖 - ♻️ 更新 package.json 项目描述和版本号 - 📝 完善 README.md 更新日志和 CORS 配置说明 - 🔒 安全性增强:签名 URL 15分钟/1小时有效期 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -39,12 +39,13 @@ function initDatabase() {
|
||||
email TEXT UNIQUE NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
|
||||
-- FTP配置(可选)
|
||||
ftp_host TEXT,
|
||||
ftp_port INTEGER DEFAULT 22,
|
||||
ftp_user TEXT,
|
||||
ftp_password TEXT,
|
||||
http_download_base_url TEXT,
|
||||
-- OSS配置(可选)
|
||||
oss_provider TEXT,
|
||||
oss_region TEXT,
|
||||
oss_access_key_id TEXT,
|
||||
oss_access_key_secret TEXT,
|
||||
oss_bucket TEXT,
|
||||
oss_endpoint TEXT,
|
||||
|
||||
-- 上传工具API密钥
|
||||
upload_api_key TEXT,
|
||||
@@ -53,7 +54,7 @@ function initDatabase() {
|
||||
is_admin INTEGER DEFAULT 0,
|
||||
is_active INTEGER DEFAULT 1,
|
||||
is_banned INTEGER DEFAULT 0,
|
||||
has_ftp_config INTEGER DEFAULT 0,
|
||||
has_oss_config INTEGER DEFAULT 0,
|
||||
|
||||
-- 时间戳
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
@@ -96,8 +97,10 @@ function initDatabase() {
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_upload_api_key ON users(upload_api_key);
|
||||
CREATE INDEX IF NOT EXISTS idx_shares_code ON shares(share_code);
|
||||
CREATE INDEX IF NOT EXISTS idx_shares_user ON shares(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_shares_expires ON shares(expires_at);
|
||||
`);
|
||||
|
||||
// 数据库迁移:添加upload_api_key字段(如果不存在)
|
||||
@@ -213,7 +216,7 @@ function createDefaultAdmin() {
|
||||
db.prepare(`
|
||||
INSERT INTO users (
|
||||
username, email, password,
|
||||
is_admin, is_active, has_ftp_config, is_verified
|
||||
is_admin, is_active, has_oss_config, is_verified
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
`).run(
|
||||
adminUsername,
|
||||
@@ -221,7 +224,7 @@ function createDefaultAdmin() {
|
||||
hashedPassword,
|
||||
1,
|
||||
1,
|
||||
0, // 管理员不需要FTP配置
|
||||
0, // 管理员不需要OSS配置
|
||||
1 // 管理员默认已验证
|
||||
);
|
||||
|
||||
@@ -238,7 +241,7 @@ const UserDB = {
|
||||
create(userData) {
|
||||
const hashedPassword = bcrypt.hashSync(userData.password, 10);
|
||||
|
||||
const hasFtpConfig = userData.ftp_host && userData.ftp_user && userData.ftp_password ? 1 : 0;
|
||||
const hasOssConfig = userData.oss_provider && userData.oss_access_key_id && userData.oss_access_key_secret && userData.oss_bucket ? 1 : 0;
|
||||
|
||||
// 对验证令牌进行哈希存储(与 VerificationDB.setVerification 保持一致)
|
||||
const hashedVerificationToken = userData.verification_token
|
||||
@@ -248,22 +251,23 @@ const UserDB = {
|
||||
const stmt = db.prepare(`
|
||||
INSERT INTO users (
|
||||
username, email, password,
|
||||
ftp_host, ftp_port, ftp_user, ftp_password, http_download_base_url,
|
||||
has_ftp_config,
|
||||
oss_provider, oss_region, oss_access_key_id, oss_access_key_secret, oss_bucket, oss_endpoint,
|
||||
has_oss_config,
|
||||
is_verified, verification_token, verification_expires_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`);
|
||||
|
||||
const result = stmt.run(
|
||||
userData.username,
|
||||
userData.email,
|
||||
hashedPassword,
|
||||
userData.ftp_host || null,
|
||||
userData.ftp_port || 22,
|
||||
userData.ftp_user || null,
|
||||
userData.ftp_password || null,
|
||||
userData.http_download_base_url || null,
|
||||
hasFtpConfig,
|
||||
userData.oss_provider || null,
|
||||
userData.oss_region || null,
|
||||
userData.oss_access_key_id || null,
|
||||
userData.oss_access_key_secret || null,
|
||||
userData.oss_bucket || null,
|
||||
userData.oss_endpoint || null,
|
||||
hasOssConfig,
|
||||
userData.is_verified !== undefined ? userData.is_verified : 0,
|
||||
hashedVerificationToken,
|
||||
userData.verification_expires_at || null
|
||||
@@ -446,7 +450,7 @@ const ShareDB = {
|
||||
});
|
||||
|
||||
const result = db.prepare(`
|
||||
SELECT s.*, u.username, u.ftp_host, u.ftp_port, u.ftp_user, u.ftp_password, u.http_download_base_url, u.theme_preference
|
||||
SELECT s.*, u.username, u.oss_provider, u.oss_region, u.oss_access_key_id, u.oss_access_key_secret, u.oss_bucket, u.oss_endpoint, u.theme_preference
|
||||
FROM shares s
|
||||
JOIN users u ON s.user_id = u.id
|
||||
WHERE s.share_code = ?
|
||||
@@ -678,6 +682,51 @@ function migrateToV2() {
|
||||
}
|
||||
}
|
||||
|
||||
// 数据库版本迁移 - v3.0 SFTP → OSS
|
||||
function migrateToOss() {
|
||||
try {
|
||||
const columns = db.prepare("PRAGMA table_info(users)").all();
|
||||
const hasOssProvider = columns.some(col => col.name === 'oss_provider');
|
||||
|
||||
if (!hasOssProvider) {
|
||||
console.log('[数据库迁移] 检测到 SFTP 版本,开始升级到 v3.0 OSS...');
|
||||
|
||||
// 添加 OSS 相关字段
|
||||
db.exec(`
|
||||
ALTER TABLE users ADD COLUMN oss_provider TEXT DEFAULT NULL;
|
||||
ALTER TABLE users ADD COLUMN oss_region TEXT DEFAULT NULL;
|
||||
ALTER TABLE users ADD COLUMN oss_access_key_id TEXT DEFAULT NULL;
|
||||
ALTER TABLE users ADD COLUMN oss_access_key_secret TEXT DEFAULT NULL;
|
||||
ALTER TABLE users ADD COLUMN oss_bucket TEXT DEFAULT NULL;
|
||||
ALTER TABLE users ADD COLUMN oss_endpoint TEXT DEFAULT NULL;
|
||||
ALTER TABLE users ADD COLUMN has_oss_config INTEGER DEFAULT 0;
|
||||
`);
|
||||
console.log('[数据库迁移] ✓ OSS 字段已添加');
|
||||
|
||||
// 更新存储权限枚举值:sftp_only → oss_only
|
||||
db.exec(`UPDATE users SET storage_permission = 'oss_only' WHERE storage_permission = 'sftp_only'`);
|
||||
console.log('[数据库迁移] ✓ 存储权限枚举值已更新');
|
||||
|
||||
// 更新存储类型:sftp → oss
|
||||
db.exec(`UPDATE users SET current_storage_type = 'oss' WHERE current_storage_type = 'sftp'`);
|
||||
console.log('[数据库迁移] ✓ 存储类型已更新');
|
||||
|
||||
// 更新分享表的存储类型
|
||||
const shareColumns = db.prepare("PRAGMA table_info(shares)").all();
|
||||
const hasStorageType = shareColumns.some(col => col.name === 'storage_type');
|
||||
if (hasStorageType) {
|
||||
db.exec(`UPDATE shares SET storage_type = 'oss' WHERE storage_type = 'sftp'`);
|
||||
console.log('[数据库迁移] ✓ 分享表存储类型已更新');
|
||||
}
|
||||
|
||||
console.log('[数据库迁移] ✅ 数据库升级到 v3.0 完成!SFTP 已替换为 OSS');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[数据库迁移] OSS 迁移失败:', error);
|
||||
// 不抛出错误,允许服务继续启动
|
||||
}
|
||||
}
|
||||
|
||||
// 系统日志操作
|
||||
const SystemLogDB = {
|
||||
// 日志级别常量
|
||||
@@ -819,6 +868,7 @@ createDefaultAdmin();
|
||||
initDefaultSettings();
|
||||
migrateToV2(); // 执行数据库迁移
|
||||
migrateThemePreference(); // 主题偏好迁移
|
||||
migrateToOss(); // SFTP → OSS 迁移
|
||||
|
||||
module.exports = {
|
||||
db,
|
||||
|
||||
Reference in New Issue
Block a user