#!/usr/bin/env node /** * 七牛云存储桶设置更新脚本 * * 用途:更新存储桶的防覆盖等设置 * * 用法: * node update-bucket-setting.js * * 示例: * node update-bucket-setting.js mybucket noOverwrite 0 # 允许覆盖 * node update-bucket-setting.js mybucket noOverwrite 1 # 禁止覆盖 */ const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); const https = require('https'); const http = require('http'); const DEFAULT_CONFIG_PATH = path.join(process.env.HOME || process.env.USERPROFILE, '.openclaw/credentials/qiniu-config.json'); function loadConfig() { if (!fs.existsSync(DEFAULT_CONFIG_PATH)) { throw new Error(`配置文件不存在:${DEFAULT_CONFIG_PATH}`); } return JSON.parse(fs.readFileSync(DEFAULT_CONFIG_PATH, 'utf-8')); } function hmacSha1(data, secret) { return crypto.createHmac('sha1', secret).update(data).digest(); } function urlSafeBase64(data) { return Buffer.from(data).toString('base64') .replace(/\+/g, '-') .replace(/\//g, '_'); } function generateAccessToken(accessKey, secretKey, method, path, body = '') { const host = 'api.qiniu.com'; const contentType = 'application/json'; const signData = `${method} ${path}\nHost: ${host}\nContent-Type: ${contentType}\n\n${body}`; const signature = hmacSha1(signData, secretKey); const encodedSign = urlSafeBase64(signature); return `Qiniu ${accessKey}:${encodedSign}`; } function httpRequest(url, options, body = null) { return new Promise((resolve, reject) => { const protocol = url.startsWith('https') ? https : http; const req = protocol.request(url, options, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { try { const json = JSON.parse(data); resolve({ status: res.statusCode, data: json }); } catch (e) { resolve({ status: res.statusCode, data: data }); } }); }); req.on('error', reject); if (body) { req.write(body); } req.end(); }); } async function updateBucketSetting(bucketName, setting, value) { const config = loadConfig(); const bucketConfig = config.buckets['default']; if (!bucketConfig) { throw new Error(`默认存储桶配置不存在`); } const { accessKey, secretKey, bucket } = bucketConfig; console.log('🔄 更新存储桶设置...\n'); console.log(`存储桶:${bucket}`); console.log(`设置项:${setting}`); console.log(`值:${value}`); console.log(''); // 七牛云存储桶设置 API // 文档:https://developer.qiniu.com/kodo/api/1313/bucket-settings-update const updateUrl = `https://api.qiniu.com/buckets/${bucket}/settings`; const body = JSON.stringify({ [setting]: value === '1' || value === 'true' ? 1 : 0 }); const accessToken = generateAccessToken(accessKey, secretKey, 'PUT', `/buckets/${bucket}/settings`, body); const options = { method: 'PUT', headers: { 'Host': 'api.qiniu.com', 'Content-Type': 'application/json', 'Content-Length': body.length, 'Authorization': accessToken } }; console.log('📤 发送更新请求...'); const result = await httpRequest(updateUrl, options, body); if (result.status !== 200) { console.error('❌ 更新失败:', result.data); console.log('\n可能原因:'); console.log('1. AccessKey/SecretKey 权限不足,需要存储桶管理权限'); console.log('2. 存储桶名称不正确'); console.log('3. 设置项不支持通过 API 修改'); return; } console.log('✅ 设置已更新成功!\n'); console.log('提示:设置可能需要几分钟生效,请稍后重试上传。'); } function printUsage() { console.log(` 用法:node update-bucket-setting.js 设置项: noOverwrite - 防覆盖设置 (0=允许覆盖,1=禁止覆盖) 示例: node update-bucket-setting.js mybucket noOverwrite 0 # 允许覆盖 node update-bucket-setting.js mybucket noOverwrite 1 # 禁止覆盖 `); } async function main() { const args = process.argv.slice(2); if (args.length < 3) { printUsage(); process.exit(1); } const [bucketName, setting, value] = args; try { await updateBucketSetting(bucketName, setting, value); } catch (error) { console.error('❌ 错误:', error.message); process.exit(1); } } if (require.main === module) { main(); } module.exports = { updateBucketSetting };