Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(mv3): Better Default Rules #1260

Merged
merged 3 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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