feat(private_clipboard): 新增私有剪贴板文件访问接口并调整url返回逻辑
不再直接暴露本地文件路径作为文件url,改用api接口代理访问;新增对应路由处理文件的预览和下载请求,完善响应头配置。
This commit is contained in:
@@ -101,8 +101,7 @@ const saveFile = (raw, name, mime) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const formatRow = (row) => {
|
const formatRow = (row) => {
|
||||||
const filePath = row.file_path ? String(row.file_path) : ''
|
const url = row && row.id && row.file_path ? `/api/private_clipboard/file/${row.id}` : ''
|
||||||
const url = filePath ? '/' + filePath.replace(/^\/+/, '') : ''
|
|
||||||
return {
|
return {
|
||||||
id: row.id,
|
id: row.id,
|
||||||
type: row.type,
|
type: row.type,
|
||||||
@@ -402,6 +401,30 @@ const createRouter = () => {
|
|||||||
// ===== 以下业务路由需要登录 =====
|
// ===== 以下业务路由需要登录 =====
|
||||||
router.use(mustAuth)
|
router.use(mustAuth)
|
||||||
|
|
||||||
|
router.get('/file/:id', (req, res) => {
|
||||||
|
try {
|
||||||
|
const id = Number.parseInt(String(req.params.id || ''), 10)
|
||||||
|
if (!id) return res.status(400).json({ ok: false, error: 'invalid_id' })
|
||||||
|
const row = getDb().prepare('SELECT id, type, file_name, file_mime, file_path FROM clipboard_items WHERE id = ?').get(id)
|
||||||
|
if (!row || !row.file_path) return res.status(404).json({ ok: false, error: 'file_not_found' })
|
||||||
|
const rel = String(row.file_path || '').replace(/^\/+/, '')
|
||||||
|
const abs = path.join(process.cwd(), rel)
|
||||||
|
if (!fs.existsSync(abs)) return res.status(404).json({ ok: false, error: 'file_not_found' })
|
||||||
|
const mime = String(row.file_mime || '').trim() || 'application/octet-stream'
|
||||||
|
res.setHeader('Content-Type', mime)
|
||||||
|
res.setHeader('Cache-Control', 'private, no-store, max-age=0')
|
||||||
|
const safeName = normalizeName(row.file_name || 'file')
|
||||||
|
const isImage = String(row.type || '').toLowerCase() === 'image' || mime.toLowerCase().startsWith('image/')
|
||||||
|
const dispositionType = isImage ? 'inline' : 'attachment'
|
||||||
|
const fallbackName = safeName.replace(/[^\x20-\x7E]/g, '_')
|
||||||
|
const utf8Name = encodeURIComponent(safeName)
|
||||||
|
res.setHeader('Content-Disposition', `${dispositionType}; filename="${fallbackName}"; filename*=UTF-8''${utf8Name}`)
|
||||||
|
return res.sendFile(abs)
|
||||||
|
} catch (e) {
|
||||||
|
return res.status(500).json({ ok: false, error: String(e.message || e) })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
router.get('/list', (req, res) => {
|
router.get('/list', (req, res) => {
|
||||||
try {
|
try {
|
||||||
const pageSizeRaw = String((req.query && req.query.page_size) || '50').trim().toLowerCase()
|
const pageSizeRaw = String((req.query && req.query.page_size) || '50').trim().toLowerCase()
|
||||||
|
|||||||
Reference in New Issue
Block a user