Skip to content

Commit

Permalink
feat(mv3): Better Default Rules (#1260)
Browse files Browse the repository at this point in the history
* refactor(mv3): blockOrRequest code

Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>

* refactor(mv3): Port Logic for Default Rules is more robust.

Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>

* feat(test): Adding tests for default rule logic.

Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>

---------

Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>
  • Loading branch information
whizzzkid authored Aug 15, 2023
1 parent 5c85d84 commit fca5fe2
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 9 deletions.
25 changes: 17 additions & 8 deletions add-on/src/lib/redirect-handler/blockOrObserve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ interface regexFilterMap {
interface redirectHandlerInput {
originUrl: string
redirectUrl: string
getPort: (state: CompanionState) => string
}

type messageToSelfType = typeof GLOBAL_STATE_CHANGE | typeof GLOBAL_STATE_OPTION_CHANGE | typeof DELETE_RULE_REQUEST
Expand All @@ -34,6 +35,8 @@ interface messageToSelf {
value?: string | Record<string, unknown>
}

const defaultNSRegexStr = `(${[...DEFAULT_NAMESPACES].join('|')})`

// We need to check if the browser supports the declarativeNetRequest API.
// TODO: replace with check for `Blocking` in `chrome.webRequest.OnBeforeRequestOptions`
// which is currently a bug https://bugs.chromium.org/p/chromium/issues/detail?id=1427952
Expand Down Expand Up @@ -80,11 +83,18 @@ const savedRegexFilters: Map<string, regexFilterMap> = new Map()
const DEFAULT_LOCAL_RULES: redirectHandlerInput[] = [
{
originUrl: 'http://127.0.0.1',
redirectUrl: 'http://localhost'
redirectUrl: 'http://localhost',
getPort: ({ gwURLString }): string => new URL(gwURLString).port
},
{
originUrl: 'http://[::1]',
redirectUrl: 'http://localhost'
redirectUrl: 'http://localhost',
getPort: ({ gwURLString }): string => new URL(gwURLString).port
},
{
originUrl: 'http://localhost',
redirectUrl: 'http://127.0.0.1',
getPort: ({ apiURL }): string => new URL(apiURL).port
}
]

Expand Down Expand Up @@ -163,7 +173,7 @@ function constructRegexFilter ({ originUrl, redirectUrl }: redirectHandlerInput)
if (DEFAULT_NAMESPACES.has(subdomainPart as string)) {
// We found a namespace, this is going to match group 2, i.e. namespace.
// e.g https://bafybeib3bzis4mejzsnzsb65od3rnv5ffit7vsllratddjkgfgq4wiamqu.ipfs.dweb.link
regexFilter = `${commonStaticUrlStart}(.*?)\\.(${[...DEFAULT_NAMESPACES].join('|')})${commonStaticUrlEnd}`
regexFilter = `${commonStaticUrlStart}(.*?)\\.${defaultNSRegexStr}${commonStaticUrlEnd}`

regexSubstitution = redirectUrl
.replace(subdomain.reverse().join('.'), '\\1') // replace subdomain or CID.
Expand Down Expand Up @@ -203,7 +213,6 @@ function constructRegexFilter ({ originUrl, redirectUrl }: redirectHandlerInput)
// A redirect like
// https://ipfs.io/ipfs/QmZMxU -> http://localhost:8080/ipfs/QmZMxU
const [originFirst, originLast] = originUrl.split(`/${originNS}/`)
const defaultNSRegexStr = `(${[...DEFAULT_NAMESPACES].join('|')})`
regexFilter = `^${escapeURLRegex(originFirst)}\\/${defaultNSRegexStr}\\/${RULE_REGEX_ENDING}`
.replace(/https?/ig, 'https?')
regexSubstitution = redirectUrl
Expand Down Expand Up @@ -338,11 +347,11 @@ async function reconcileRulesAndRemoveOld (state: CompanionState): Promise<void>
}
}

const { port } = new URL(state.gwURLString)
// make sure that the default rules are added.
for (const { originUrl, redirectUrl } of DEFAULT_LOCAL_RULES) {
const regexFilter = `^${escapeURLRegex(`${originUrl}:${port}`)}${RULE_REGEX_ENDING}`
const regexSubstitution = `${redirectUrl}:${port}/\\1`
for (const { originUrl, redirectUrl, getPort } of DEFAULT_LOCAL_RULES) {
const port = getPort(state)
const regexFilter = `^${escapeURLRegex(`${originUrl}:${port}`)}\\/${defaultNSRegexStr}\\/${RULE_REGEX_ENDING}`
const regexSubstitution = `${redirectUrl}:${port}/\\1/\\2`

if (!savedRegexFilters.has(regexFilter)) {
// We need to add the new rule.
Expand Down
35 changes: 34 additions & 1 deletion test/functional/lib/redirect-handler/blockOrObserve.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ function ensureTabRedirected (url): void {
* @param regexSubstitution
*/
function ensureDeclrativeNetRequetRuleIsAdded ({
addRuleIndex = 0,
addRuleLength = 1,
callIndex = 0,
expectedCondition,
regexSubstitution,
removedRulesIds = [],
}: {
addRuleIndex?: number
addRuleLength?: number
callIndex?: number
expectedCondition: string
Expand All @@ -69,7 +71,7 @@ function ensureDeclrativeNetRequetRuleIsAdded ({
expect(removeRuleIds).to.deep.equal(removedRulesIds)
if (addRuleLength > 0) {
expect(addRules).to.have.lengthOf(addRuleLength)
const [{ id, priority, action, condition }] = addRules
const { id, priority, action, condition } = addRules[addRuleIndex]
expect(id).to.be.a('number')
expect(priority).to.equal(1)
expect(action).to.deep.equal({ type: 'redirect', redirect: { regexSubstitution } })
Expand Down Expand Up @@ -137,6 +139,37 @@ describe('lib/redirect-handler/blockOrObserve', () => {
expect (browserMock.tabs.query.called).to.be.false
})

it('Should add default rules for localhost', async () => {
await addRuleToDynamicRuleSet({
originUrl: 'https://ipfs.io/ipns/en.wikipedia-on-ipfs.org',
redirectUrl: 'http://localhost:8080/ipns/en.wikipedia-on-ipfs.org'
})

ensureDeclrativeNetRequetRuleIsAdded({
addRuleIndex: 0,
addRuleLength: 3,
callIndex: 1,
expectedCondition: `^http\\:\\/\\/127\\.0\\.0\\.1\\:8080\\/(ipfs|ipns)\\/${RULE_REGEX_ENDING}`,
regexSubstitution: 'http://localhost:8080/\\1/\\2'
})

ensureDeclrativeNetRequetRuleIsAdded({
addRuleIndex: 1,
addRuleLength: 3,
callIndex: 1,
expectedCondition: `^http\\:\\/\\/\\[\\:\\:1\\]\\:8080\\/(ipfs|ipns)\\/${RULE_REGEX_ENDING}`,
regexSubstitution: 'http://localhost:8080/\\1/\\2'
})

ensureDeclrativeNetRequetRuleIsAdded({
addRuleIndex: 2,
addRuleLength: 3,
callIndex: 1,
expectedCondition: `^http\\:\\/\\/localhost\\:5001\\/(ipfs|ipns)\\/${RULE_REGEX_ENDING}`,
regexSubstitution: 'http://127.0.0.1:5001/\\1/\\2'
})
})

it('Should allow pages to be recovered', async () => {
// when redirecting to recovery page
await addRuleToDynamicRuleSet({
Expand Down

0 comments on commit fca5fe2

Please sign in to comment.