Skip to content

Commit be3d561

Browse files
authored
fix(mv3): 👔 Adding better regex replace to remove infinite redirects. (#1210)
* fix(mv3): 👔 Adding better regex replace to remove infinite redirects. * fix(mv3): 🧪 Adding more tests to account for local redirects * fix: 🚨 Linter
1 parent 1a2bcf1 commit be3d561

File tree

2 files changed

+38
-13
lines changed

2 files changed

+38
-13
lines changed

‎add-on/src/lib/redirect-handler/blockOrObserve.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ function constructRegexFilter ({ originUrl, redirectUrl }: redirectHandlerInput)
120120
const regexFilterFirst = escapeURLRegex(originUrl.slice(0, originUrl.length - commonIdx + 1))
121121
// We need to match the rest of the URL, so we can use a wildcard.
122122
const regexEnding = '((?:[^\\.]|$).*)$'
123-
let regexFilter = `^${regexFilterFirst}${regexEnding}`.replace('https', 'https?')
123+
let regexFilter = `^${regexFilterFirst}${regexEnding}`.replace(/https?/ig, 'https?')
124124

125125
// This method does not parse:
126126
// originUrl: "https://awesome.ipfs.io/"
@@ -162,7 +162,7 @@ function validateIfRuleChanged (rule: browser.DeclarativeNetRequest.Rule): boole
162162
/**
163163
* Clean up all the rules, when extension is disabled.
164164
*/
165-
async function cleanupRules (resetInMemory: boolean = false): Promise<void> {
165+
export async function cleanupRules (resetInMemory: boolean = false): Promise<void> {
166166
const existingRules = await browser.declarativeNetRequest.getDynamicRules()
167167
const existingRulesIds = existingRules.map(({ id }): number => id)
168168
await browser.declarativeNetRequest.updateDynamicRules({ addRules: [], removeRuleIds: existingRulesIds })
@@ -349,7 +349,7 @@ export function addRuleToDynamicRuleSetGenerator (
349349
)
350350

351351
// refresh the tab to apply the new rule.
352-
const tabs = await browser.tabs.query({ url: originUrl })
352+
const tabs = await browser.tabs.query({ url: `${originUrl}*` })
353353
await Promise.all(tabs.map(async tab => await browser.tabs.reload(tab.id)))
354354
}
355355

‎test/functional/lib/redirect-handler/blockOrObserve.test.ts

+35-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { expect } from 'chai'
2-
import { before, describe, it } from 'mocha'
1+
import {expect} from 'chai'
2+
import {before, describe, it} from 'mocha'
33
import sinon from 'sinon'
44
import browserMock from 'sinon-chrome'
55

6-
import { optionDefaults } from '../../../../add-on/src/lib/options.js'
7-
import { addRuleToDynamicRuleSetGenerator, isLocalHost } from '../../../../add-on/src/lib/redirect-handler/blockOrObserve'
8-
import { initState } from '../../../../add-on/src/lib/state.js'
6+
import {optionDefaults} from '../../../../add-on/src/lib/options.js'
7+
import {addRuleToDynamicRuleSetGenerator, cleanupRules, isLocalHost} from '../../../../add-on/src/lib/redirect-handler/blockOrObserve'
8+
import {initState} from '../../../../add-on/src/lib/state.js'
99
import DeclarativeNetRequestMock from './declarativeNetRequest.mock.js'
1010

1111
const dynamicRulesConditions = (regexFilter) => ({
@@ -64,10 +64,14 @@ describe('lib/redirect-handler/blockOrObserve', () => {
6464
addRuleToDynamicRuleSet = addRuleToDynamicRuleSetGenerator(() => state)
6565
})
6666

67-
beforeEach(() => {
67+
beforeEach(async () => {
6868
sinonSandbox.restore()
69-
browserMock.flush()
70-
browserMock.tabs.query.resolves([{ id: 1234 }])
69+
browserMock.tabs.query.resetHistory()
70+
browserMock.tabs.reload.resetHistory()
71+
browserMock.declarativeNetRequest = sinonSandbox.spy(new DeclarativeNetRequestMock())
72+
// this cleans up the rules from the previous test stored in memory.
73+
await cleanupRules(true)
74+
// this is just to reset the call count.
7175
browserMock.declarativeNetRequest = sinonSandbox.spy(new DeclarativeNetRequestMock())
7276
})
7377

@@ -126,13 +130,34 @@ describe('lib/redirect-handler/blockOrObserve', () => {
126130
expect(condition).to.deep.equal(dynamicRulesConditions('^https?\\:\\/\\/docs\\.ipfs\\.tech((?:[^\\.]|$).*)$'))
127131
})
128132

133+
it('Should add redirect for local gateway where originUrl is similar to redirectUrl and is not https', async () => {
134+
await addRuleToDynamicRuleSet({
135+
originUrl: 'http://docs.ipfs.tech',
136+
redirectUrl: 'http://localhost:8080/ipns/docs.ipfs.tech'
137+
})
138+
expect(browserMock.declarativeNetRequest.updateDynamicRules.called).to.be.true
139+
const [{ addRules, removeRuleIds }] = browserMock.declarativeNetRequest.updateDynamicRules.firstCall.args
140+
expect(removeRuleIds).to.deep.equal([])
141+
expect(addRules).to.have.lengthOf(1)
142+
const [{ id, priority, action, condition }] = addRules
143+
expect(id).to.be.a('number')
144+
expect(priority).to.equal(1)
145+
expect(action).to.deep.equal({
146+
type: 'redirect', redirect: {
147+
"regexSubstitution": "http://localhost:8080/ipns/docs.ipfs.tech\\1"
148+
}
149+
})
150+
expect(condition).to.deep.equal(dynamicRulesConditions('^https?\\:\\/\\/docs\\.ipfs\\.tech((?:[^\\.]|$).*)$'))
151+
})
152+
129153
it('Should refresh the tab when redirect URL is added', async () => {
154+
browserMock.tabs.query.resolves([{id: 1234}])
130155
await addRuleToDynamicRuleSet({
131156
originUrl: 'https://ipfs.io/ipns/en.wikipedia-on-ipfs.org',
132157
redirectUrl: 'http://localhost:8080/ipns/en.wikipedia-on-ipfs.org'
133158
})
134-
expect(browserMock.tabs.query.calledWith({ url: 'https://ipfs.io/ipns/en.wikipedia-on-ipfs.org' })).to.be.true
135-
expect(browserMock.tabs.reload.calledWith(1234)).to.be.true
159+
sinon.assert.calledWith(browserMock.tabs.query, { url: 'https://ipfs.io/ipns/en.wikipedia-on-ipfs.org*' })
160+
sinon.assert.calledWith(browserMock.tabs.reload, 1234)
136161
})
137162
})
138163
})

0 commit comments

Comments
 (0)