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): blocking by observing #1181

Merged
merged 36 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
4dee9c6
feat(mv3): :sparkles: MV3 Manifest Migration
whizzzkid Mar 3, 2023
54e9edb
fix(mv3): :wastebasket: No longer needed
whizzzkid Mar 3, 2023
937e0f7
fix(mv3): :wrench: Corresponding MV3 Changes
whizzzkid Mar 3, 2023
2de3028
feat(mv3): :package: Adding deps
whizzzkid Mar 3, 2023
98622b7
feat(telemetry): Refactor Metrics Tracking from background service_wo…
whizzzkid Mar 13, 2023
274f7be
feat(mv3): :adhesive_bandage: Patch @protobufjs/inquire to not have eval
whizzzkid Mar 13, 2023
f5dcefd
fix(mv3): :alien: Fixing contextMenus API changes (#1177)
whizzzkid Mar 15, 2023
b05e120
fix(mv3): webpack configs (#1178)
whizzzkid Mar 23, 2023
6819356
feat(mv3): ✨ XHR to Fetch Migration (#1179)
whizzzkid Mar 23, 2023
36b7f74
Fix(mv3): Popup Was Broken (#1180)
whizzzkid Mar 23, 2023
0f99265
fix(mv3): :passport_control: Limiting permissions to chrome-extension
whizzzkid Mar 23, 2023
80dcb0d
Update add-on/src/lib/ipfs-companion.js
whizzzkid Mar 23, 2023
fc74226
fix(types): :label: Refactoring existing type declaration
whizzzkid Mar 23, 2023
4ca1cc0
fix(types): :label: Moving to new types path
whizzzkid Mar 23, 2023
9abfd6f
feat(types): :sparkles: Adding typescript support for transpilation
whizzzkid Mar 23, 2023
0c9aab4
feat(mv3): :sparkles: Adding blocking request tester
whizzzkid Mar 23, 2023
79ffc72
Merge branch 'rc/3.0-mv3' into feat/blocking-by-observing
whizzzkid Mar 24, 2023
f2c678b
fix(mv3): :adhesive_bandage: package.json
whizzzkid Mar 24, 2023
7029569
Merge branch 'rc/3.0-mv3' into feat/blocking-by-observing
whizzzkid Mar 24, 2023
bc07aa9
fix(mv3): :rotating_light: Fix Lint
whizzzkid Mar 24, 2023
abe9208
Merge branch 'rc/3.0-mv3' into feat/blocking-by-observing
whizzzkid Mar 24, 2023
9736b1e
Merge branch 'rc/3.0-mv3' into feat/blocking-by-observing
whizzzkid Mar 24, 2023
be24e8f
fix: :rotating_light: fix lint
whizzzkid Mar 24, 2023
4c3eeb3
fix(mv3): :adhesive_bandage: temp fix to build background context
whizzzkid Mar 27, 2023
7431da1
fix(mv3): :necktie: Detection Logic for MV3 world.
whizzzkid Mar 27, 2023
d8538fa
feat(mv3): :sparkles: Dynamic RegexSubstitution
whizzzkid Mar 28, 2023
dcd51df
fix(types): :arrow_up: Adding .mocharc.json to fix mocha for TS.
whizzzkid Mar 29, 2023
b2dcfeb
fix: :rotating_light: Lint Fix
whizzzkid Mar 29, 2023
27ea2c3
fix(mv3): :recycle: refactor background.service_worker
whizzzkid Mar 29, 2023
78c072a
feat(mv3): :sparkles: Passing state to BlockOrObserve
whizzzkid Mar 30, 2023
04dc26b
fix(recovery): :bug: conditional for recovery
whizzzkid Mar 30, 2023
3d76720
fix: :wastebasket: unneeded @ts-ignore
whizzzkid Apr 4, 2023
3d80737
fix: :bulb: Adding comments
whizzzkid Apr 4, 2023
66e9d9b
fix: fixing string method.
whizzzkid Apr 4, 2023
937e3d0
fix: removing extra space.
whizzzkid Apr 4, 2023
47f5335
fix: removing @ts-nocheck
whizzzkid Apr 4, 2023
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
17 changes: 17 additions & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"diff": true,
"extensions": [".js", ".ts"],
"package": "./package.json",
"require": [
"ignore-styles",
"ts-node/register",
"tsconfig-paths/register"
],
"exit": true,
"recursive": true,
"node-option": [
"es-module-specifier-resolution=node",
"experimental-specifier-resolution=node",
"loader=ts-node/esm"
]
}
6 changes: 4 additions & 2 deletions add-on/manifest.chromium.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"minimum_chrome_version": "72",
"minimum_chrome_version": "101",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the latest.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will be fixed in another PR.

"permissions": [
"clipboardWrite",
"contextMenus",
Expand All @@ -9,7 +9,9 @@
"tabs",
"unlimitedStorage",
"webNavigation",
"webRequest"
"webRequest",
"declarativeNetRequest",
"declarativeNetRequestFeedback"
],
"host_permissions": ["<all_urls>"],
"incognito": "not_allowed"
Expand Down
6 changes: 3 additions & 3 deletions add-on/manifest.common.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
"description": "__MSG_manifest_extensionDescription__",
"homepage_url": "https://github.com/ipfs-shipyard/ipfs-companion",
"author": "IPFS Community",
"background": {
"service_worker": "dist/bundles/backgroundPage.bundle.js"
},
"icons": {
"19": "icons/png/ipfs-logo-on_19.png",
"38": "icons/png/ipfs-logo-on_38.png",
"128": "icons/png/ipfs-logo-on_128.png"
},
"background": {
"service_worker": "dist/bundles/backgroundPage.bundle.js"
},
"action": {
"default_icon": {
"19": "icons/png/ipfs-logo-off_19.png",
Expand Down
26 changes: 22 additions & 4 deletions add-on/src/lib/ipfs-companion.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'
/* eslint-env browser, webextensions */

// @ts-ignore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer @ts-expect-error instead of ts-ignore, but why do we need this? debug should have types IIRC

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just junk my editor added, gonna remove:

Screenshot 2023-04-03 at 6 42 40 PM

import debug from 'debug'

import browser from 'webextension-polyfill'
Expand All @@ -23,6 +24,8 @@ import createRuntimeChecks from './runtime-checks.js'
import { createContextMenus, findValueForContext, contextMenuCopyAddressAtPublicGw, contextMenuCopyRawCid, contextMenuCopyCanonicalAddress, contextMenuViewOnGateway, contextMenuCopyPermalink, contextMenuCopyCidAddress } from './context-menus.js'
import { registerSubdomainProxy } from './http-proxy.js'
import { runPendingOnInstallTasks } from './on-installed.js'
import { getExtraInfoSpec } from './redirect-handler/blockOrObserve.js'

const log = debug('ipfs-companion:main')
log.error = debug('ipfs-companion:main:error')

Expand All @@ -33,7 +36,7 @@ export default async function init (windowedContext = false) {
// INIT
// ===================================================================
let ipfs // ipfs-api instance
/** @type {import('../types.js').CompanionState} */
/** @type {import('../types/companion.js').CompanionState} */
let state // avoid redundant API reads by utilizing local cache of various states
let dnslinkResolver
let ipfsPathValidator
Expand All @@ -54,6 +57,7 @@ export default async function init (windowedContext = false) {
await migrateOptions(browser.storage.local, debug)
const options = await browser.storage.local.get(optionDefaults)
runtime = await createRuntimeChecks(browser)
// @ts-ignore
state = initState(options)
notify = createNotifier(getState)

Expand All @@ -65,6 +69,7 @@ export default async function init (windowedContext = false) {
console.error('[ipfs-companion] Failed to init IPFS client', err)
notify(
'notify_startIpfsNodeErrorTitle',
// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
err.name === 'ValidationError' ? err.details[0].message : err.message
)
}
Expand Down Expand Up @@ -115,9 +120,11 @@ export default async function init (windowedContext = false) {
// Note: we need this for code ensuring kubo-rpc-client can talk to API without setting CORS
onBeforeSendInfoSpec.push('extraHeaders')
}
browser.webRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, { urls: ['<all_urls>'] }, onBeforeSendInfoSpec)
browser.webRequest.onBeforeRequest.addListener(onBeforeRequest, { urls: ['<all_urls>'] })
browser.webRequest.onHeadersReceived.addListener(onHeadersReceived, { urls: ['<all_urls>'] }, ['responseHeaders'])
browser.webRequest.onBeforeSendHeaders.addListener(
// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
onBeforeSendHeaders, { urls: ['<all_urls>'] }, getExtraInfoSpec(onBeforeSendInfoSpec))
browser.webRequest.onBeforeRequest.addListener(onBeforeRequest, { urls: ['<all_urls>'] }, getExtraInfoSpec())
browser.webRequest.onHeadersReceived.addListener(onHeadersReceived, { urls: ['<all_urls>'] }, getExtraInfoSpec(['responseHeaders']))
browser.webRequest.onErrorOccurred.addListener(onErrorOccurred, { urls: ['<all_urls>'], types: ['main_frame'] })
browser.webRequest.onCompleted.addListener(onCompleted, { urls: ['<all_urls>'], types: ['main_frame'] })
browser.storage.onChanged.addListener(onStorageChange)
Expand Down Expand Up @@ -307,6 +314,7 @@ export default async function init (windowedContext = false) {
}
// console.log('onAddFromContext.context', context)
// console.log('onAddFromContext.fetchOptions', fetchOptions)
// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
const response = await fetch(dataSrc, fetchOptions)
const blob = await response.blob()
const url = new URL(response.url)
Expand All @@ -315,6 +323,7 @@ export default async function init (windowedContext = false) {
? url.hostname
: url.pathname.replace(/[\\/]+$/, '').split('/').pop()
data = {
// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
path: decodeURIComponent(filename),
content: blob
}
Expand All @@ -332,13 +341,15 @@ export default async function init (windowedContext = false) {
}
} catch (error) {
console.error('Error in import to IPFS context menu', error)
// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
if (error.message === 'NetworkError when attempting to fetch resource.') {
notify('notify_importErrorTitle', 'notify_importTrackingProtectionErrorMsg')
console.warn('IPFS import often fails because remote file can not be downloaded due to Tracking Protection. See details at: https://github.com/ipfs/ipfs-companion/issues/227')
browser.tabs.create({
url: 'https://github.com/ipfs/ipfs-companion/issues/227'
})
} else {
// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
notify('notify_importErrorTitle', 'notify_inlineErrorMsg', `${error.message}`)
}
}
Expand Down Expand Up @@ -524,6 +535,7 @@ export default async function init (windowedContext = false) {
// Chromium does not support SVG [ticket below is 8 years old, I can't even..]
// https://bugs.chromium.org/p/chromium/issues/detail?id=29683
// Still, we want icon, so we precompute rasters of popular sizes and use them instead
// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
iconDefinition = await rasterIconDefinition(iconPath)
await browser.action.setIcon(iconDefinition)
}
Expand All @@ -537,13 +549,15 @@ export default async function init (windowedContext = false) {
if (state.automaticMode && state.localGwAvailable) {
if (oldPeerCount === offlinePeerCount && newPeerCount > offlinePeerCount && !state.redirect) {
await browser.storage.local.set({ useCustomGateway: true })
// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
reloadIpfsClientOfflinePages(browser, ipfs, state)
} else if (newPeerCount === offlinePeerCount && state.redirect) {
await browser.storage.local.set({ useCustomGateway: false })
}
}
}

// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
async function onStorageChange (changes, area) {
let shouldReloadExtension = false
let shouldRestartIpfsClient = false
Expand Down Expand Up @@ -634,6 +648,7 @@ export default async function init (windowedContext = false) {
await destroyIpfsClient(browser)
} catch (err) {
console.error('[ipfs-companion] Failed to destroy IPFS client', err)
// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
notify('notify_stopIpfsNodeErrorTitle', err.message)
} finally {
ipfs = null
Expand All @@ -648,6 +663,7 @@ export default async function init (windowedContext = false) {
console.error('[ipfs-companion] Failed to init IPFS client', err)
notify(
'notify_startIpfsNodeErrorTitle',
// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
err.name === 'ValidationError' ? err.details[0].message : err.message
)
}
Expand Down Expand Up @@ -715,9 +731,11 @@ export default async function init (windowedContext = false) {
return api
}

// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
const rasterIconDefinition = pMemoize((svgPath) => {
const pngPath = (size) => {
// point at precomputed PNG file
// @ts-ignore
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
const baseName = /\/icons\/(.+)\.svg/.exec(svgPath)[1]
return `/icons/png/${baseName}_${size}.png`
}
Expand Down
48 changes: 42 additions & 6 deletions add-on/src/lib/ipfs-request.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
whizzzkid marked this conversation as resolved.
Show resolved Hide resolved
'use strict'
/* eslint-env browser, webextensions */

Expand All @@ -10,6 +11,7 @@ import { dropSlash, ipfsUri, pathAtHttpGateway, sameGateway } from './ipfs-path.
import { safeURL } from './options.js'
import { braveNodeType } from './ipfs-client/brave.js'
import { recoveryPagePath } from './constants.js'
import { addRuleToDynamicRuleSet, supportsBlock } from './redirect-handler/blockOrObserve.js'

const log = debug('ipfs-companion:request')
log.error = debug('ipfs-companion:request:error')
Expand Down Expand Up @@ -146,20 +148,34 @@ export function createRequestModifier (getState, dnslinkResolver, ipfsPathValida
// to public gateway.
if (!state.nodeActive && request.type === 'main_frame' && sameGateway(request.url, state.gwURL)) {
const publicUri = await ipfsPathValidator.resolveToPublicUrl(request.url, state.pubGwURLString)
return { redirectUrl: `${dropSlash(runtimeRoot)}${recoveryPagePath}#${encodeURIComponent(publicUri)}` }
return handleRedirection({
originUrl: request.url,
redirectUrl: `${dropSlash(runtimeRoot)}${recoveryPagePath}#${encodeURIComponent(publicUri)}`
})
}

// When Subdomain Proxy is enabled we normalize address bar requests made
// to the local gateway and replace raw IP with 'localhost' hostname to
// take advantage of subdomain redirect provided by go-ipfs >= 0.5
if (state.redirect && request.type === 'main_frame' && sameGateway(request.url, state.gwURL)) {
const redirectUrl = safeURL(request.url, { useLocalhostName: state.useSubdomains }).toString()
if (redirectUrl !== request.url) return { redirectUrl }
if (redirectUrl !== request.url) {
return handleRedirection({
originUrl: request.url,
redirectUrl
})
}
}

// For now normalize API to the IP to comply with go-ipfs checks
if (state.redirect && request.type === 'main_frame' && sameGateway(request.url, state.apiURL)) {
const redirectUrl = safeURL(request.url, { useLocalhostName: false }).toString()
if (redirectUrl !== request.url) return { redirectUrl }
if (redirectUrl !== request.url) {
return handleRedirection({
originUrl: request.url,
redirectUrl
})
}
}

// early sanity checks
Expand Down Expand Up @@ -459,6 +475,15 @@ export function createRequestModifier (getState, dnslinkResolver, ipfsPathValida
}
}

function handleRedirection ({ originUrl, redirectUrl }) {
if (supportsBlock) {
return { redirectUrl }
}

// Let browser handle redirection MV3 style.
addRuleToDynamicRuleSet({ originUrl, redirectUrl })
}

// Returns a string with URL at the active gateway (local or public)
async function redirectToGateway (request, url, state, ipfsPathValidator, runtime) {
const { resolveToPublicUrl, resolveToLocalUrl } = ipfsPathValidator
Expand Down Expand Up @@ -507,7 +532,12 @@ async function redirectToGateway (request, url, state, ipfsPathValidator, runtim
}

// return a redirect only if URL changed
if (redirectUrl && request.url !== redirectUrl) return { redirectUrl }
if (redirectUrl && request.url !== redirectUrl) {
return handleRedirection({
originUrl: request.url,
redirectUrl
})
}
}

function isSafeToRedirect (request, runtime) {
Expand Down Expand Up @@ -574,7 +604,10 @@ function normalizedRedirectingProtocolRequest (request, pubGwUrl) {
// additional fixups of the final path
path = fixupDnslinkPath(path) // /ipfs/example.com → /ipns/example.com
if (oldPath !== path && isIPFS.path(path)) {
return { redirectUrl: pathAtHttpGateway(path, pubGwUrl) }
return handleRedirection({
originUrl: request.url,
redirectUrl: pathAtHttpGateway(path, pubGwUrl)
})
}
return null
}
Expand Down Expand Up @@ -616,7 +649,10 @@ function normalizedUnhandledIpfsProtocol (request, pubGwUrl) {
if (isIPFS.path(path)) {
// replace search query with a request to a public gateway
// (will be redirected later, if needed)
return { redirectUrl: pathAtHttpGateway(path, pubGwUrl) }
return handleRedirection({
originUrl: request.url,
redirectUrl: pathAtHttpGateway(path, pubGwUrl)
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion add-on/src/lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import isFQDN from 'is-fqdn'
import { isIPv4, isIPv6 } from 'is-ip'

/**
* @type {Readonly<import('../types.js').CompanionOptions>}
* @type {Readonly<import('../types/companion.js').CompanionOptions>}
*/
export const optionDefaults = Object.freeze({
active: true, // global ON/OFF switch, overrides everything else
Expand Down
Loading