fix: 改用 better-sqlite3 兼容 GLIBC 环境

This commit is contained in:
Cuishibing
2026-04-26 10:00:42 +08:00
parent fdae636637
commit b885dbac0f
3 changed files with 55 additions and 14 deletions

View File

@@ -100,13 +100,30 @@
} }
async function setup() { async function setup() {
// 检查是否已有 key
const savedKey = localStorage.getItem('myoss_api_key');
if (savedKey) {
apiKey = savedKey;
location.reload();
return;
}
const name = document.getElementById('setup-name').value; const name = document.getElementById('setup-name').value;
const res = await fetch(API_BASE + '/api/keys/bootstrap', { const res = await fetch('/api/keys/bootstrap', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name }) body: JSON.stringify({ name })
}); });
const data = await res.json(); const data = await res.json();
if (data.error) {
// 已初始化过,提示用户输入已有 key
const key = prompt('服务已初始化,请输入已有的 API Key:');
if (key) {
localStorage.setItem('myoss_api_key', key);
location.reload();
}
return;
}
apiKey = data.key; apiKey = data.key;
localStorage.setItem('myoss_api_key', apiKey); localStorage.setItem('myoss_api_key', apiKey);
location.reload(); location.reload();
@@ -143,10 +160,14 @@
for (const file of files) { for (const file of files) {
const formData = new FormData(); const formData = new FormData();
formData.append('file', file); formData.append('file', file);
await request('/api/files', { const data = await request('/api/files', {
method: 'POST', method: 'POST',
body: formData body: formData
}); });
if (data.error) {
alert(data.error);
return;
}
} }
alert('上传成功'); alert('上传成功');
loadFiles(); loadFiles();
@@ -154,6 +175,10 @@
async function loadFiles() { async function loadFiles() {
const files = await request('/api/files'); const files = await request('/api/files');
renderFiles(files);
}
function renderFiles(files) {
const tbody = document.getElementById('files-tbody'); const tbody = document.getElementById('files-tbody');
if (!files || !files.length) { if (!files || !files.length) {
tbody.innerHTML = '<tr><td colspan="3" class="empty">暂无文件</td></tr>'; tbody.innerHTML = '<tr><td colspan="3" class="empty">暂无文件</td></tr>';
@@ -167,7 +192,7 @@
</td> </td>
<td>${formatSize(f.size)}</td> <td>${formatSize(f.size)}</td>
<td class="actions"> <td class="actions">
<a href="${API_BASE}/api/files/${f.fileKey}/download" target="_blank">下载</a> <a href="/api/files/${f.fileKey}/download?key=${apiKey}" target="_blank">下载</a>
<button class="danger" onclick="deleteFile('${f.fileKey}')">删除</button> <button class="danger" onclick="deleteFile('${f.fileKey}')">删除</button>
</td> </td>
</tr> </tr>
@@ -189,20 +214,34 @@
async function init() { async function init() {
if (!apiKey) { if (!apiKey) {
// 先检查是否已有 bootstrap key
try {
const res = await fetch('/api/files', {
headers: { 'X-API-Key': 'check' }
});
if (res.status === 401 || res.status === 404) {
document.getElementById('setup-card').classList.remove('hidden');
return;
}
} catch (e) {}
document.getElementById('setup-card').classList.remove('hidden'); document.getElementById('setup-card').classList.remove('hidden');
return; return;
} }
const res = await fetch(API_BASE + '/api/files', { try {
headers: { 'X-API-Key': apiKey } const files = await request('/api/files');
}); if (!files) {
document.getElementById('setup-card').classList.remove('hidden');
document.getElementById('main-card').classList.remove('hidden'); return;
document.getElementById('upload-card').classList.remove('hidden'); }
document.getElementById('files-card').classList.remove('hidden'); document.getElementById('main-card').classList.remove('hidden');
document.getElementById('current-key').textContent = apiKey; document.getElementById('upload-card').classList.remove('hidden');
document.getElementById('files-card').classList.remove('hidden');
loadFiles(); document.getElementById('current-key').textContent = apiKey;
renderFiles(files);
} catch (e) {
document.getElementById('setup-card').classList.remove('hidden');
}
} }
init(); init();

View File

@@ -1,7 +1,7 @@
const { APIKey } = require('../models'); const { APIKey } = require('../models');
const authMiddleware = async (req, res, next) => { const authMiddleware = async (req, res, next) => {
const apiKey = req.headers['x-api-key']; const apiKey = req.headers['x-api-key'] || req.query.key;
if (!apiKey) { if (!apiKey) {
return res.status(401).json({ error: 'Missing X-API-Key header' }); return res.status(401).json({ error: 'Missing X-API-Key header' });
} }

View File

@@ -1,10 +1,12 @@
const { Sequelize, DataTypes } = require('sequelize'); const { Sequelize, DataTypes } = require('sequelize');
const config = require('../../config'); const config = require('../../config');
const BetterSqlite3 = require('better-sqlite3');
const sequelize = new Sequelize({ const sequelize = new Sequelize({
dialect: 'sqlite', dialect: 'sqlite',
storage: config.storage.databasePath, storage: config.storage.databasePath,
logging: false, logging: false,
dialectModule: BetterSqlite3,
}); });
const APIKey = sequelize.define('APIKey', { const APIKey = sequelize.define('APIKey', {