diff --git a/backend/package.json b/backend/package.json index 732865f..f4b7462 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.14.178", + "version": "2.14.179", "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.", "main": "src/main.js", "scripts": { diff --git a/backend/src/products/cron-sync-artifacts.js b/backend/src/products/cron-sync-artifacts.js index b598b77..8ea95dc 100644 --- a/backend/src/products/cron-sync-artifacts.js +++ b/backend/src/products/cron-sync-artifacts.js @@ -40,7 +40,7 @@ async function doSync() { platform: artifact.platform, }); - files[artifact.name] = { + files[encodeURIComponent(artifact.name)] = { content: output, }; } @@ -54,10 +54,9 @@ async function doSync() { if (artifact.sync) { artifact.updated = new Date().getTime(); // extract real url from gist - artifact.url = body.files[artifact.name].raw_url.replace( - /\/raw\/[^/]*\/(.*)/, - '/raw/$1', - ); + artifact.url = body.files[ + encodeURIComponent(artifact.name) + ]?.raw_url.replace(/\/raw\/[^/]*\/(.*)/, '/raw/$1'); } } diff --git a/backend/src/restful/artifacts.js b/backend/src/restful/artifacts.js index 76afa20..8f2b75d 100644 --- a/backend/src/restful/artifacts.js +++ b/backend/src/restful/artifacts.js @@ -50,20 +50,32 @@ async function restoreArtifacts(_, res) { throw new Error(`找不到 Sub-Store Gist 文件列表`); } const allArtifacts = $.read(ARTIFACTS_KEY); + const failed = []; Object.keys(gist.files).map((key) => { const filename = gist.files[key]?.filename; if (filename) { - const artifact = findByName(allArtifacts, filename); - if (artifact) { - updateByName(allArtifacts, filename, { - ...artifact, - url: gist.files[key]?.raw_url, - }); + if (encodeURIComponent(filename) !== filename) { + $.error(`文件名 ${filename} 未编码 不保存`); + failed.push(filename); } else { - allArtifacts.push({ - name: `${filename}`, - url: gist.files[key]?.raw_url, - }); + const artifact = findByName(allArtifacts, filename); + if (artifact) { + updateByName(allArtifacts, filename, { + ...artifact, + url: gist.files[key]?.raw_url.replace( + /\/raw\/[^/]*\/(.*)/, + '/raw/$1', + ), + }); + } else { + allArtifacts.push({ + name: `${filename}`, + url: gist.files[key]?.raw_url.replace( + /\/raw\/[^/]*\/(.*)/, + '/raw/$1', + ), + }); + } } } }); @@ -193,9 +205,15 @@ async function deleteArtifact(req, res) { if (artifact.updated) { // delete gist const files = {}; - files[artifact.name] = { + files[encodeURIComponent(artifact.name)] = { content: '', }; + if (encodeURIComponent(artifact.name) !== artifact.name) { + files[artifact.name] = { + content: '', + }; + } + // 当别的Sub 删了同步订阅 或 gist里面删了 当前设备没有删除 时 无法删除的bug try { await syncToGist(files); diff --git a/backend/src/restful/sync.js b/backend/src/restful/sync.js index 78437a8..378aa8c 100644 --- a/backend/src/restful/sync.js +++ b/backend/src/restful/sync.js @@ -447,23 +447,44 @@ async function syncArtifacts() { const files = {}; try { + const invalid = []; await Promise.all( allArtifacts.map(async (artifact) => { - if (artifact.sync && artifact.source) { - $.info(`正在同步云配置:${artifact.name}...`); - const output = await produceArtifact({ - type: artifact.type, - name: artifact.source, - platform: artifact.platform, - }); + try { + if (artifact.sync && artifact.source) { + $.info(`正在同步云配置:${artifact.name}...`); + const output = await produceArtifact({ + type: artifact.type, + name: artifact.source, + platform: artifact.platform, + produceOpts: { + 'include-unsupported-proxy': + artifact.includeUnsupportedProxy, + }, + }); - files[artifact.name] = { - content: output, - }; + // if (!output || output.length === 0) + // throw new Error('该配置的结果为空 不进行上传'); + + files[encodeURIComponent(artifact.name)] = { + content: output, + }; + } + } catch (e) { + $.error( + `同步配置 ${artifact.name} 发生错误: ${e.message ?? e}`, + ); + invalid.push(artifact.name); } }), ); + if (invalid.length > 0) { + throw new Error( + `同步配置 ${invalid.join(', ')} 发生错误 详情请查看日志`, + ); + } + const resp = await syncToGist(files); const body = JSON.parse(resp.body); @@ -471,10 +492,9 @@ async function syncArtifacts() { if (artifact.sync) { artifact.updated = new Date().getTime(); // extract real url from gist - artifact.url = body.files[artifact.name].raw_url.replace( - /\/raw\/[^/]*\/(.*)/, - '/raw/$1', - ); + artifact.url = body.files[ + encodeURIComponent(artifact.name) + ]?.raw_url.replace(/\/raw\/[^/]*\/(.*)/, '/raw/$1'); } } @@ -541,6 +561,9 @@ async function syncArtifact(req, res) { type: artifact.type, name: artifact.source, platform: artifact.platform, + produceOpts: { + 'include-unsupported-proxy': artifact.includeUnsupportedProxy, + }, }); $.info( @@ -550,6 +573,8 @@ async function syncArtifact(req, res) { 2, )}`, ); + // if (!output || output.length === 0) + // throw new Error('该配置的结果为空 不进行上传'); const resp = await syncToGist({ [encodeURIComponent(artifact.name)]: { content: output, @@ -559,11 +584,11 @@ async function syncArtifact(req, res) { const body = JSON.parse(resp.body); artifact.url = body.files[ encodeURIComponent(artifact.name) - ].raw_url.replace(/\/raw\/[^/]*\/(.*)/, '/raw/$1'); + ]?.raw_url.replace(/\/raw\/[^/]*\/(.*)/, '/raw/$1'); $.write(allArtifacts, ARTIFACTS_KEY); success(res, artifact); } catch (err) { - $.error(`远程配置 ${artifact.name} 发生错误: ${err}`); + $.error(`远程配置 ${artifact.name} 发生错误: ${err.message ?? err}`); failed( res, new InternalServerError(