diff --git a/omega-target-chromium-extension/src/module/proxy/proxy_impl.coffee b/omega-target-chromium-extension/src/module/proxy/proxy_impl.coffee index e52c748..0a69e99 100644 --- a/omega-target-chromium-extension/src/module/proxy/proxy_impl.coffee +++ b/omega-target-chromium-extension/src/module/proxy/proxy_impl.coffee @@ -50,7 +50,12 @@ class ProxyImpl ) profilePac = profilePacCache.get(profile) profilePacKey = referenced_profiles.map( - (_profile) -> _profile.name + '_' + (_profile.revision or 1) + (_profile) -> + revision = _profile.revision or 1 + # remote pacScript and rule list use sha256 to ensue uniqueId + if OmegaPac.Profiles.updateUrl(_profile) and _profile.sha256 + revision = _profile.sha256 + _profile.name + '_' + revision ).join(',') if profilePac?[profilePacKey] return profilePac[profilePacKey] diff --git a/omega-target/src/options.coffee b/omega-target/src/options.coffee index fb3c5f3..b694cd5 100644 --- a/omega-target/src/options.coffee +++ b/omega-target/src/options.coffee @@ -6,8 +6,25 @@ OmegaPac = require 'omega-pac' jsondiffpatch = require 'jsondiffpatch' +generateSHA256 = (text) -> + return new Promise((resolve, reject) -> + encoder = new TextEncoder() + data = encoder.encode(text) + crypto.subtle.digest("SHA-256", data).then((hashBuffer) -> + # 将 ArrayBuffer 转换为十六进制字符串 + hashArray = Array.from(new Uint8Array(hashBuffer)) + hashHex = hashArray.map((byte) -> + byte.toString(16).padStart(2, '0')).join('') + # 输出 SHA-256 哈希值 + resolve(hashHex) + ).catch((e) -> + console.log('eee', e) + reject(e) + ) + ) PROFILETEMPPACKEY = '__tempZeroRuleListPac' +transformValueKeys = ['lastUpdate', 'ruleList', 'pacScript', 'sha256'] generateProfileTempPac = (profile) -> tempProfile = OmegaPac.Profiles.create(PROFILETEMPPACKEY, profile.profileType) @@ -76,7 +93,7 @@ class Options if OmegaPac.Profiles.updateUrl(value) profile = {} for k, v of value - continue if k == 'lastUpdate' || k == 'ruleList' || k == 'pacScript' + continue if transformValueKeys.indexOf(k) >= 0 profile[k] = v value = profile return value @@ -136,7 +153,8 @@ class Options @sync.init({gistId, gistToken}).catch((e) -> console.log('sync init fail::', e) ) - @_syncWatchStop = @sync.watchAndPull(@_storage) + @_syncWatchStop = + @sync.watchAndPull(@_storage, @updateProfile.bind(this)) @sync.copyTo(@_storage).catch(Storage.StorageUnavailableError, => console.error('Warning: Sync storage is not available in this ' + 'browser! Disabling options sync.') @@ -745,16 +763,18 @@ class Options # rejected by fetchUrl and will not end up here. # So empty data indicates success without any update (e.g. 304). return profile unless data - profile = OmegaPac.Profiles.byKey(key, @_options) - profile.lastUpdate = new Date().toISOString() - if OmegaPac.Profiles.update(profile, data) - OmegaPac.Profiles.dropCache(profile) - OmegaPac.Profiles.updateRevision(profile) - changes = {} - changes[key] = profile - @_setOptions(changes).return(profile) - else - return profile + generateSHA256(data).then((dataSHA256) => + profile = OmegaPac.Profiles.byKey(key, @_options) + profile.lastUpdate = new Date().toISOString() + if OmegaPac.Profiles.update(profile, data) or not profile.sha256 + profile.sha256 = dataSHA256 + OmegaPac.Profiles.dropCache(profile) + changes = {} + changes[key] = profile + @_setOptions(changes).return(profile) + else + return profile + ) ).catch (reason) -> if reason instanceof Error then reason else new Error(reason) @@ -1157,7 +1177,8 @@ class Options @sync.enabled = true @_syncWatchStop?() @sync.requestPush(@_options) - @_syncWatchStop = @sync.watchAndPull(@_storage) + @_syncWatchStop = + @sync.watchAndPull(@_storage, @updateProfile.bind(this)) if args.useBuiltInSync @sync.toggleBuiltInSync(true) else diff --git a/omega-target/src/options_sync.coffee b/omega-target/src/options_sync.coffee index 041604e..79f8e73 100644 --- a/omega-target/src/options_sync.coffee +++ b/omega-target/src/options_sync.coffee @@ -2,7 +2,7 @@ Promise = require 'bluebird' Storage = require './storage' Log = require './log' -{Revision} = require 'omega-pac' +{Revision, Profiles} = require 'omega-pac' jsondiffpatch = require 'jsondiffpatch' TokenBucket = require('limiter').TokenBucket @@ -197,7 +197,7 @@ class OptionsSync # @param {Storage} local The local storage to be written to # @returns {function} Calling the returned function will stop watching. ### - watchAndPull: (local) -> + watchAndPull: (local, updateProfile) -> pullScheduled = null pull = {} doPull = => @@ -208,7 +208,14 @@ class OptionsSync Storage.operationsForChanges(changes, base: base, merge: @merge) ).then (operations) => @_logOperations('OptionsSync::pull', operations) - local.apply(operations) + local.apply(operations).then( -> + updateProfileNames = [] + Object.values(operations.set).forEach((profile) -> + if typeof profile is 'object' and Profiles.updateUrl(profile) + updateProfileNames.push(profile.name) + ) + updateProfile?(updateProfileNames) + ).return(operations) @storage.watch null, (changes, opts = {}) => for own key, value of changes