From b9232a1d184592683d1d092aae7f8a27b1494ecb Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Fri, 23 Dec 2022 02:29:06 -0700 Subject: [PATCH 01/35] Adding recovery options --- add-on/src/recovery/recovery.css | 16 ++++++++++++ add-on/src/recovery/recovery.html | 25 ++++++++++++++++++ add-on/src/recovery/recovery.js | 43 +++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 add-on/src/recovery/recovery.css create mode 100644 add-on/src/recovery/recovery.html create mode 100644 add-on/src/recovery/recovery.js diff --git a/add-on/src/recovery/recovery.css b/add-on/src/recovery/recovery.css new file mode 100644 index 000000000..6ba108b96 --- /dev/null +++ b/add-on/src/recovery/recovery.css @@ -0,0 +1,16 @@ +@import url('~tachyons/css/tachyons.css'); +@import url('~ipfs-css/ipfs.css'); + +header { + border-color: #69c4cd; + text-transform: uppercase; +} + +#header-logo { + height: 50px; + width: 117.5px; +} + +.recovery-root { + text-align: center; +} diff --git a/add-on/src/recovery/recovery.html b/add-on/src/recovery/recovery.html new file mode 100644 index 000000000..5eecde4bd --- /dev/null +++ b/add-on/src/recovery/recovery.html @@ -0,0 +1,25 @@ + + + + IPFS Node is Offline + + + + + + + +
+
+ +
+

+
+
+
+ + + +
+ + diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js new file mode 100644 index 000000000..dd74dafd7 --- /dev/null +++ b/add-on/src/recovery/recovery.js @@ -0,0 +1,43 @@ +'use strict' +/* eslint-env browser, webextensions */ + +import choo from 'choo' +import html from 'choo/html/index.js' +import { renderCompanionLogo } from '../landing-pages/welcome/page.js' +import createWelcomePageStore from '../landing-pages/welcome/store.js' +import { i18n, runtime } from 'webextension-polyfill' +import './recovery.css' + +const app = choo() + +// TODO (whizzzkid): refactor base store to be more generic. +app.use(createWelcomePageStore(i18n, runtime)); +// Register our single route +app.route('*', (state) => { + console.log(state) + const openURLFromHash = () => { + const { hash } = window.location; + try { + const url = new URL(decodeURI(hash.slice(1))); + console.log('Opening URL from hash:', url.href); + window.location.href = url.href; + } catch (err) { + console.error('Failed to open URL from hash:', err); + } + } + + return html`
+ ${renderCompanionLogo(i18n, false)} +

${i18n.getMessage('recovery_page_message')}

+ +
` +}) + +// Start the application and render it to the given querySelector +app.mount('#root') + +// Set page title and header translation +document.getElementById('header-text').innerText = i18n.getMessage('recovery_page_header') +document.title = i18n.getMessage('recovery_page_title') From 3ac7e12b8e7467622497688535d7568fe2719756 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Fri, 23 Dec 2022 02:29:18 -0700 Subject: [PATCH 02/35] fixing packages --- add-on/_locales/en/messages.json | 16 ++++++++++++++++ webpack.config.js | 1 + 2 files changed, 17 insertions(+) diff --git a/add-on/_locales/en/messages.json b/add-on/_locales/en/messages.json index 83f433673..363331f8e 100644 --- a/add-on/_locales/en/messages.json +++ b/add-on/_locales/en/messages.json @@ -726,5 +726,21 @@ "page_landingWelcome_projects_title": { "message": "Related Projects", "description": "Projects section title (page_landingWelcome_projects_title)" + }, + "recovery_page_title" : { + "message": "Node Offline | IPFS Companion", + "description": "Title of the recovery page (recovery_page_title)" + }, + "recovery_page_header" : { + "message": "Node is Offline", + "description": "Main header on the recovery screen (recovery_page_header)" + }, + "recovery_page_message": { + "message": "IPFS Companion is unable to connect to the IPFS node. Would you like to connect to a public gateway instead?", + "description": "Message on the recovery screen (recovery_page_message)" + }, + "recovery_page_button": { + "message": "Continue to a public gateway", + "description": "Button on the recovery screen (recovery_page_button)" } } diff --git a/webpack.config.js b/webpack.config.js index 1eac06f08..2f0731617 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -141,6 +141,7 @@ const uiConfig = merge(commonConfig, { browserAction: './add-on/src/popup/browser-action/index.js', importPage: './add-on/src/popup/quick-import.js', optionsPage: './add-on/src/options/options.js', + recoveryPage: './add-on/src/recovery/recovery.js', welcomePage: './add-on/src/landing-pages/welcome/index.js' }, optimization: { From 5103b6033cc6526cc4f0c0246eb6005642214dff Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Fri, 23 Dec 2022 02:29:33 -0700 Subject: [PATCH 03/35] hooking components --- add-on/src/landing-pages/welcome/page.js | 2 +- add-on/src/landing-pages/welcome/store.js | 24 +++++++---------- add-on/src/lib/constants.js | 1 + add-on/src/lib/ipfs-path.js | 15 +++++++++-- add-on/src/lib/ipfs-request.js | 3 ++- add-on/src/lib/ipfsStatus.js | 33 +++++++++++++++++++++++ 6 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 add-on/src/lib/ipfsStatus.js diff --git a/add-on/src/landing-pages/welcome/page.js b/add-on/src/landing-pages/welcome/page.js index 816503f59..1006d08e2 100644 --- a/add-on/src/landing-pages/welcome/page.js +++ b/add-on/src/landing-pages/welcome/page.js @@ -48,7 +48,7 @@ export default function createWelcomePage (i18n) { Render functions for the left side ======================================================== */ -const renderCompanionLogo = (i18n, isIpfsOnline) => { +export const renderCompanionLogo = (i18n, isIpfsOnline) => { const logoPath = '../../../icons' const logoSize = 128 const stateUnknown = isIpfsOnline === null diff --git a/add-on/src/landing-pages/welcome/store.js b/add-on/src/landing-pages/welcome/store.js index aaf32b6a1..3f7cdfaf2 100644 --- a/add-on/src/landing-pages/welcome/store.js +++ b/add-on/src/landing-pages/welcome/store.js @@ -1,29 +1,23 @@ 'use strict' /* eslint-env browser, webextensions */ import browser from 'webextension-polyfill' +import ipfsStatus from '../../lib/ipfsStatus.js' export default function createWelcomePageStore (i18n, runtime) { return function welcomePageStore (state, emitter) { state.isIpfsOnline = null state.peerCount = null state.webuiRootUrl = null - let port emitter.on('DOMContentLoaded', async () => { emitter.emit('render') - port = runtime.connect({ name: 'browser-action-port' }) - port.onMessage.addListener(async (message) => { - if (message.statusUpdate) { - const webuiRootUrl = message.statusUpdate.webuiRootUrl - const peerCount = message.statusUpdate.peerCount - const isIpfsOnline = peerCount > -1 - if (isIpfsOnline !== state.isIpfsOnline || peerCount !== state.peerCount || webuiRootUrl !== state.webuiRootUrl) { - state.webuiRootUrl = webuiRootUrl - state.isIpfsOnline = isIpfsOnline - state.peerCount = peerCount - emitter.emit('render') - } - } - }) + const { webuiRootUrl, isIpfsOnline, peerCount } = ipfsStatus; + if (isIpfsOnline !== state.isIpfsOnline || peerCount !== state.peerCount || webuiRootUrl !== state.webuiRootUrl) { + state.webuiRootUrl = webuiRootUrl + state.isIpfsOnline = isIpfsOnline + state.peerCount = peerCount + emitter.emit('render') + } + }) emitter.on('openWebUi', async (page = '/') => { diff --git a/add-on/src/lib/constants.js b/add-on/src/lib/constants.js index 6de4ce58c..ef2f7c61a 100644 --- a/add-on/src/lib/constants.js +++ b/add-on/src/lib/constants.js @@ -3,4 +3,5 @@ export const welcomePage = '/dist/landing-pages/welcome/index.html' export const optionsPage = '/dist/options/options.html' +export const recoveryPagePath = '/dist/recovery/recovery.html' export const tickMs = 250 // no CPU spike, but still responsive enough diff --git a/add-on/src/lib/ipfs-path.js b/add-on/src/lib/ipfs-path.js index 64ede8bf0..48a33db3e 100644 --- a/add-on/src/lib/ipfs-path.js +++ b/add-on/src/lib/ipfs-path.js @@ -4,12 +4,15 @@ import pMemoize from 'p-memoize' import isIPFS from 'is-ipfs' import isFQDN from 'is-fqdn' +import ipfsStatus from './ipfsStatus.js' +import { runtime } from 'webextension-polyfill' +import { recoveryPagePath } from './constants.js' // For how long more expensive lookups (DAG traversal etc) should be cached const RESULT_TTL_MS = 300000 // 5 minutes // Turns URL or URIencoded path into a content path -export function ipfsContentPath (urlOrPath, opts) { +export function ipfsContentPath(urlOrPath, opts) { opts = opts || {} // ipfs:// → /ipfs/ @@ -40,6 +43,14 @@ export function ipfsContentPath (urlOrPath, opts) { // End if not a content path if (!isIPFS.path(contentPath)) return null + const { isIpfsOnline } = ipfsStatus; + + if (!isIpfsOnline) { + const newPath = runtime.getURL(recoveryPagePath) + '#' + 'ipfs.io'; + console.log(newPath); + return newPath; + } + // Attach suffix with query parameters or hash if explicitly asked to do so if (opts.keepURIParams) return `${contentPath}${url.search}${url.hash}` @@ -48,7 +59,7 @@ export function ipfsContentPath (urlOrPath, opts) { } // Turns URL or URIencoded path into a ipfs:// or ipns:// URI -export function ipfsUri (urlOrPath) { +export function ipfsUri(urlOrPath) { const contentPath = ipfsContentPath(urlOrPath, { keepURIParams: true }) if (!contentPath) return null return contentPath.replace(/^\/(ip[f|n]s)\//, '$1://') diff --git a/add-on/src/lib/ipfs-request.js b/add-on/src/lib/ipfs-request.js index 0b9ffe551..98ac6d936 100644 --- a/add-on/src/lib/ipfs-request.js +++ b/add-on/src/lib/ipfs-request.js @@ -451,7 +451,8 @@ export function createRequestModifier (getState, dnslinkResolver, ipfsPathValida } // Returns a string with URL at the active gateway (local or public) -function redirectToGateway (request, url, state, ipfsPathValidator, runtime) { +function redirectToGateway(request, url, state, ipfsPathValidator, runtime) { + log({ request, url, state, ipfsPathValidator, runtime }); const { resolveToPublicUrl, resolveToLocalUrl } = ipfsPathValidator let redirectUrl = state.localGwAvailable ? resolveToLocalUrl(url) : resolveToPublicUrl(url) diff --git a/add-on/src/lib/ipfsStatus.js b/add-on/src/lib/ipfsStatus.js new file mode 100644 index 000000000..bd65bb7b0 --- /dev/null +++ b/add-on/src/lib/ipfsStatus.js @@ -0,0 +1,33 @@ +import { runtime } from 'webextension-polyfill' + +class IpfsStatus { + constructor() { + this._isIpfsOnline = false + this._peerCount = 0 + this._port = runtime.connect({ name: 'browser-action-port' }) + this._port.onMessage.addListener((msg) => this.listener(msg)) + } + + async listener(message) { + if (message.statusUpdate) { + this._webuiRootUrl = message.statusUpdate.webuiRootUrl + this._peerCount = message.statusUpdate.peerCount + this._isIpfsOnline = this._peerCount > -1 + } + } + + get isIpfsOnline() { + return this._isIpfsOnline; + } + + get peerCount() { + return this._peerCount; + } + + get webuiRootUrl() { + return this._webuiRootUrl; + } +} + +const ipfsStatus = new IpfsStatus() +export default ipfsStatus; From 3a53c02d867422c51ef9667c0592b0e12ee69b83 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 29 Dec 2022 03:42:24 -0700 Subject: [PATCH 04/35] reverting changes --- add-on/src/landing-pages/welcome/store.js | 24 ++++++++++------- add-on/src/lib/ipfs-path.js | 15 ++--------- add-on/src/lib/ipfsStatus.js | 33 ----------------------- 3 files changed, 17 insertions(+), 55 deletions(-) delete mode 100644 add-on/src/lib/ipfsStatus.js diff --git a/add-on/src/landing-pages/welcome/store.js b/add-on/src/landing-pages/welcome/store.js index 3f7cdfaf2..aaf32b6a1 100644 --- a/add-on/src/landing-pages/welcome/store.js +++ b/add-on/src/landing-pages/welcome/store.js @@ -1,23 +1,29 @@ 'use strict' /* eslint-env browser, webextensions */ import browser from 'webextension-polyfill' -import ipfsStatus from '../../lib/ipfsStatus.js' export default function createWelcomePageStore (i18n, runtime) { return function welcomePageStore (state, emitter) { state.isIpfsOnline = null state.peerCount = null state.webuiRootUrl = null + let port emitter.on('DOMContentLoaded', async () => { emitter.emit('render') - const { webuiRootUrl, isIpfsOnline, peerCount } = ipfsStatus; - if (isIpfsOnline !== state.isIpfsOnline || peerCount !== state.peerCount || webuiRootUrl !== state.webuiRootUrl) { - state.webuiRootUrl = webuiRootUrl - state.isIpfsOnline = isIpfsOnline - state.peerCount = peerCount - emitter.emit('render') - } - + port = runtime.connect({ name: 'browser-action-port' }) + port.onMessage.addListener(async (message) => { + if (message.statusUpdate) { + const webuiRootUrl = message.statusUpdate.webuiRootUrl + const peerCount = message.statusUpdate.peerCount + const isIpfsOnline = peerCount > -1 + if (isIpfsOnline !== state.isIpfsOnline || peerCount !== state.peerCount || webuiRootUrl !== state.webuiRootUrl) { + state.webuiRootUrl = webuiRootUrl + state.isIpfsOnline = isIpfsOnline + state.peerCount = peerCount + emitter.emit('render') + } + } + }) }) emitter.on('openWebUi', async (page = '/') => { diff --git a/add-on/src/lib/ipfs-path.js b/add-on/src/lib/ipfs-path.js index 48a33db3e..64ede8bf0 100644 --- a/add-on/src/lib/ipfs-path.js +++ b/add-on/src/lib/ipfs-path.js @@ -4,15 +4,12 @@ import pMemoize from 'p-memoize' import isIPFS from 'is-ipfs' import isFQDN from 'is-fqdn' -import ipfsStatus from './ipfsStatus.js' -import { runtime } from 'webextension-polyfill' -import { recoveryPagePath } from './constants.js' // For how long more expensive lookups (DAG traversal etc) should be cached const RESULT_TTL_MS = 300000 // 5 minutes // Turns URL or URIencoded path into a content path -export function ipfsContentPath(urlOrPath, opts) { +export function ipfsContentPath (urlOrPath, opts) { opts = opts || {} // ipfs:// → /ipfs/ @@ -43,14 +40,6 @@ export function ipfsContentPath(urlOrPath, opts) { // End if not a content path if (!isIPFS.path(contentPath)) return null - const { isIpfsOnline } = ipfsStatus; - - if (!isIpfsOnline) { - const newPath = runtime.getURL(recoveryPagePath) + '#' + 'ipfs.io'; - console.log(newPath); - return newPath; - } - // Attach suffix with query parameters or hash if explicitly asked to do so if (opts.keepURIParams) return `${contentPath}${url.search}${url.hash}` @@ -59,7 +48,7 @@ export function ipfsContentPath(urlOrPath, opts) { } // Turns URL or URIencoded path into a ipfs:// or ipns:// URI -export function ipfsUri(urlOrPath) { +export function ipfsUri (urlOrPath) { const contentPath = ipfsContentPath(urlOrPath, { keepURIParams: true }) if (!contentPath) return null return contentPath.replace(/^\/(ip[f|n]s)\//, '$1://') diff --git a/add-on/src/lib/ipfsStatus.js b/add-on/src/lib/ipfsStatus.js deleted file mode 100644 index bd65bb7b0..000000000 --- a/add-on/src/lib/ipfsStatus.js +++ /dev/null @@ -1,33 +0,0 @@ -import { runtime } from 'webextension-polyfill' - -class IpfsStatus { - constructor() { - this._isIpfsOnline = false - this._peerCount = 0 - this._port = runtime.connect({ name: 'browser-action-port' }) - this._port.onMessage.addListener((msg) => this.listener(msg)) - } - - async listener(message) { - if (message.statusUpdate) { - this._webuiRootUrl = message.statusUpdate.webuiRootUrl - this._peerCount = message.statusUpdate.peerCount - this._isIpfsOnline = this._peerCount > -1 - } - } - - get isIpfsOnline() { - return this._isIpfsOnline; - } - - get peerCount() { - return this._peerCount; - } - - get webuiRootUrl() { - return this._webuiRootUrl; - } -} - -const ipfsStatus = new IpfsStatus() -export default ipfsStatus; From 32564075ad2272649c64ef8da40dfc13a95939d6 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 29 Dec 2022 03:42:46 -0700 Subject: [PATCH 05/35] adding additional state prop getters --- add-on/src/lib/state.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/add-on/src/lib/state.js b/add-on/src/lib/state.js index dd84e126c..aaf0b8fe1 100644 --- a/add-on/src/lib/state.js +++ b/add-on/src/lib/state.js @@ -4,6 +4,7 @@ import { safeURL, isHostname } from './options.js' export const offlinePeerCount = -1 + export function initState (options, overrides) { // we store options and some pregenerated values to avoid async storage // reads and minimize performance impact on overall browsing experience @@ -40,8 +41,15 @@ export function initState (options, overrides) { return false } } - // TODO state.connected ~= state.peerCount > 0 - // TODO state.nodeActive ~= API is online,eg. state.peerCount > offlinePeerCount + // TODO refactor this into a class. It's getting too big and messy. + Object.defineProperty(state, 'connected', { + // TODO: make quick fetch to confirm it works? + get: function () { return this.peerCount > offlinePeerCount + 1 } + }) + Object.defineProperty(state, 'nodeActive', { + // TODO: make quick fetch to confirm it works? + get: function () { return this.peerCount !== offlinePeerCount } + }) Object.defineProperty(state, 'localGwAvailable', { // TODO: make quick fetch to confirm it works? get: function () { return this.ipfsNodeType !== 'embedded' } From fb301e0128abc7cd845b1ad77ec09948e9fd8d60 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 29 Dec 2022 03:43:55 -0700 Subject: [PATCH 06/35] Adding hookup for local gateway down. --- add-on/src/lib/ipfs-request.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/add-on/src/lib/ipfs-request.js b/add-on/src/lib/ipfs-request.js index 98ac6d936..1254be62a 100644 --- a/add-on/src/lib/ipfs-request.js +++ b/add-on/src/lib/ipfs-request.js @@ -9,6 +9,7 @@ import isFQDN from 'is-fqdn' import { pathAtHttpGateway, sameGateway, ipfsUri } from './ipfs-path.js' import { safeURL } from './options.js' import { braveNodeType } from './ipfs-client/brave.js' +import { recoveryPagePath } from './constants.js' const log = debug('ipfs-companion:request') log.error = debug('ipfs-companion:request:error') @@ -140,6 +141,13 @@ export function createRequestModifier (getState, dnslinkResolver, ipfsPathValida const state = getState() if (!state.active) return + // When local IPFS node is disabled, show recovery page where user can redirect + // to public gateway. + if (!state.connected && request.type === 'main_frame' && sameGateway(request.url, state.gwURL)) { + const publicUri = ipfsPathValidator.resolveToPublicUrl(request.url, state.pubGwURLString) + return { redirectUrl: `${runtimeRoot}${recoveryPagePath}#${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 @@ -605,6 +613,7 @@ function unhandledIpfsPath (requestUrl) { function normalizedUnhandledIpfsProtocol (request, pubGwUrl) { let path = unhandledIpfsPath(request.url) path = fixupDnslinkPath(path) // /ipfs/example.com → /ipns/example.com + console.log('^^^^^$', path, request, pubGwUrl) if (isIPFS.path(path)) { // replace search query with a request to a public gateway // (will be redirected later, if needed) From df318340f465cc62f7eddb1b246e8011899ab93f Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 29 Dec 2022 04:12:17 -0700 Subject: [PATCH 07/35] Refactor --- add-on/src/lib/helpers.js | 1 + add-on/src/lib/ipfs-companion.js | 2 +- add-on/src/lib/ipfs-request.js | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 add-on/src/lib/helpers.js diff --git a/add-on/src/lib/helpers.js b/add-on/src/lib/helpers.js new file mode 100644 index 000000000..c49d1816b --- /dev/null +++ b/add-on/src/lib/helpers.js @@ -0,0 +1 @@ +export const dropSlash = url => url.replace(/\/$/, '') diff --git a/add-on/src/lib/ipfs-companion.js b/add-on/src/lib/ipfs-companion.js index fcc3eb0d9..c311c8870 100644 --- a/add-on/src/lib/ipfs-companion.js +++ b/add-on/src/lib/ipfs-companion.js @@ -23,6 +23,7 @@ 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 { dropSlash } from './helpers.js' const log = debug('ipfs-companion:main') log.error = debug('ipfs-companion:main:error') @@ -209,7 +210,6 @@ export default async function init () { async function sendStatusUpdateToBrowserAction () { if (!browserActionPort) return - const dropSlash = url => url.replace(/\/$/, '') const currentTab = await browser.tabs.query({ active: true, currentWindow: true }).then(tabs => tabs[0]) const { version } = browser.runtime.getManifest() const info = { diff --git a/add-on/src/lib/ipfs-request.js b/add-on/src/lib/ipfs-request.js index 1254be62a..fca61d1b5 100644 --- a/add-on/src/lib/ipfs-request.js +++ b/add-on/src/lib/ipfs-request.js @@ -10,6 +10,8 @@ import { pathAtHttpGateway, sameGateway, ipfsUri } from './ipfs-path.js' import { safeURL } from './options.js' import { braveNodeType } from './ipfs-client/brave.js' import { recoveryPagePath } from './constants.js' +import { dropSlash } from './helpers.js' + const log = debug('ipfs-companion:request') log.error = debug('ipfs-companion:request:error') @@ -145,7 +147,7 @@ export function createRequestModifier (getState, dnslinkResolver, ipfsPathValida // to public gateway. if (!state.connected && request.type === 'main_frame' && sameGateway(request.url, state.gwURL)) { const publicUri = ipfsPathValidator.resolveToPublicUrl(request.url, state.pubGwURLString) - return { redirectUrl: `${runtimeRoot}${recoveryPagePath}#${publicUri}` } + return { redirectUrl: `${dropSlash(runtimeRoot)}${recoveryPagePath}#${publicUri}` } } // When Subdomain Proxy is enabled we normalize address bar requests made From a3feda0ec94edf113692f23fec2f2a238c459c7f Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 29 Dec 2022 04:12:58 -0700 Subject: [PATCH 08/35] Marking recovery page as accessible --- add-on/manifest.common.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/add-on/manifest.common.json b/add-on/manifest.common.json index 2e93cc82a..6e634d25c 100644 --- a/add-on/manifest.common.json +++ b/add-on/manifest.common.json @@ -33,7 +33,10 @@ "icons/png/ipfs-logo-off_38.png", "icons/png/ipfs-logo-off_128.png", "icons/ipfs-logo-on.svg", - "icons/ipfs-logo-off.svg" + "icons/ipfs-logo-off.svg", + "dist/recovery/recovery.css", + "dist/recovery/recovery.html", + "dist/recovery/recovery.js" ], "content_security_policy": "script-src 'self'; object-src 'self'; frame-src 'self';", "default_locale": "en" From e389d45f6c41c4c721211db00568b18bc8ab7290 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 29 Dec 2022 04:16:47 -0700 Subject: [PATCH 09/35] unnecessary logging --- add-on/src/lib/ipfs-request.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/add-on/src/lib/ipfs-request.js b/add-on/src/lib/ipfs-request.js index fca61d1b5..7acba22c9 100644 --- a/add-on/src/lib/ipfs-request.js +++ b/add-on/src/lib/ipfs-request.js @@ -462,7 +462,6 @@ export function createRequestModifier (getState, dnslinkResolver, ipfsPathValida // Returns a string with URL at the active gateway (local or public) function redirectToGateway(request, url, state, ipfsPathValidator, runtime) { - log({ request, url, state, ipfsPathValidator, runtime }); const { resolveToPublicUrl, resolveToLocalUrl } = ipfsPathValidator let redirectUrl = state.localGwAvailable ? resolveToLocalUrl(url) : resolveToPublicUrl(url) @@ -615,7 +614,6 @@ function unhandledIpfsPath (requestUrl) { function normalizedUnhandledIpfsProtocol (request, pubGwUrl) { let path = unhandledIpfsPath(request.url) path = fixupDnslinkPath(path) // /ipfs/example.com → /ipns/example.com - console.log('^^^^^$', path, request, pubGwUrl) if (isIPFS.path(path)) { // replace search query with a request to a public gateway // (will be redirected later, if needed) From 133ca93330757d2ee8c00e7bfd288eff07084340 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 29 Dec 2022 04:25:21 -0700 Subject: [PATCH 10/35] lint --- add-on/src/lib/ipfs-request.js | 2 +- add-on/src/recovery/recovery.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/add-on/src/lib/ipfs-request.js b/add-on/src/lib/ipfs-request.js index 7acba22c9..519d714ec 100644 --- a/add-on/src/lib/ipfs-request.js +++ b/add-on/src/lib/ipfs-request.js @@ -461,7 +461,7 @@ export function createRequestModifier (getState, dnslinkResolver, ipfsPathValida } // Returns a string with URL at the active gateway (local or public) -function redirectToGateway(request, url, state, ipfsPathValidator, runtime) { +function redirectToGateway (request, url, state, ipfsPathValidator, runtime) { const { resolveToPublicUrl, resolveToLocalUrl } = ipfsPathValidator let redirectUrl = state.localGwAvailable ? resolveToLocalUrl(url) : resolveToPublicUrl(url) diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js index dd74dafd7..057aa4361 100644 --- a/add-on/src/recovery/recovery.js +++ b/add-on/src/recovery/recovery.js @@ -11,18 +11,18 @@ import './recovery.css' const app = choo() // TODO (whizzzkid): refactor base store to be more generic. -app.use(createWelcomePageStore(i18n, runtime)); +app.use(createWelcomePageStore(i18n, runtime)) // Register our single route app.route('*', (state) => { console.log(state) const openURLFromHash = () => { - const { hash } = window.location; + const { hash } = window.location try { - const url = new URL(decodeURI(hash.slice(1))); - console.log('Opening URL from hash:', url.href); - window.location.href = url.href; + const url = new URL(decodeURI(hash.slice(1))) + console.log('Opening URL from hash:', url.href) + window.location.href = url.href } catch (err) { - console.error('Failed to open URL from hash:', err); + console.error('Failed to open URL from hash:', err) } } From cd5f4bf0c7d9573daccd10fd5c08fb17b3ca8143 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 29 Dec 2022 14:32:53 -0700 Subject: [PATCH 11/35] Fixing UI + encdec URIs --- add-on/src/lib/ipfs-request.js | 2 +- add-on/src/recovery/recovery.js | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/add-on/src/lib/ipfs-request.js b/add-on/src/lib/ipfs-request.js index 519d714ec..cdcbd40ff 100644 --- a/add-on/src/lib/ipfs-request.js +++ b/add-on/src/lib/ipfs-request.js @@ -147,7 +147,7 @@ export function createRequestModifier (getState, dnslinkResolver, ipfsPathValida // to public gateway. if (!state.connected && request.type === 'main_frame' && sameGateway(request.url, state.gwURL)) { const publicUri = ipfsPathValidator.resolveToPublicUrl(request.url, state.pubGwURLString) - return { redirectUrl: `${dropSlash(runtimeRoot)}${recoveryPagePath}#${publicUri}` } + return { redirectUrl: `${dropSlash(runtimeRoot)}${recoveryPagePath}#${encodeURIComponent(publicUri)}` } } // When Subdomain Proxy is enabled we normalize address bar requests made diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js index 057aa4361..ea5934221 100644 --- a/add-on/src/recovery/recovery.js +++ b/add-on/src/recovery/recovery.js @@ -3,9 +3,9 @@ import choo from 'choo' import html from 'choo/html/index.js' +import { i18n, runtime } from 'webextension-polyfill' import { renderCompanionLogo } from '../landing-pages/welcome/page.js' import createWelcomePageStore from '../landing-pages/welcome/store.js' -import { i18n, runtime } from 'webextension-polyfill' import './recovery.css' const app = choo() @@ -13,14 +13,17 @@ const app = choo() // TODO (whizzzkid): refactor base store to be more generic. app.use(createWelcomePageStore(i18n, runtime)) // Register our single route -app.route('*', (state) => { - console.log(state) +app.route('*', () => { + const { hash } = window.location + const { href: publicURI } = new URL(decodeURIComponent(hash.slice(1))) + if (!publicURI) { + return + } + const openURLFromHash = () => { - const { hash } = window.location try { - const url = new URL(decodeURI(hash.slice(1))) - console.log('Opening URL from hash:', url.href) - window.location.href = url.href + console.log('Opening URL from hash:', publicURI) + window.location.href = publicURI } catch (err) { console.error('Failed to open URL from hash:', err) } @@ -29,7 +32,13 @@ app.route('*', (state) => { return html`
${renderCompanionLogo(i18n, false)}

${i18n.getMessage('recovery_page_message')}

-
` From 03c14c6a1c781ad9b547ce334df2c87a732e9e8c Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 29 Dec 2022 21:54:05 -0700 Subject: [PATCH 12/35] Making page recover if node is online. --- add-on/src/recovery/recovery.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js index ea5934221..af8a4ace1 100644 --- a/add-on/src/recovery/recovery.js +++ b/add-on/src/recovery/recovery.js @@ -13,7 +13,7 @@ const app = choo() // TODO (whizzzkid): refactor base store to be more generic. app.use(createWelcomePageStore(i18n, runtime)) // Register our single route -app.route('*', () => { +app.route('*', (state) => { const { hash } = window.location const { href: publicURI } = new URL(decodeURIComponent(hash.slice(1))) if (!publicURI) { @@ -29,6 +29,12 @@ app.route('*', () => { } } + // if the IPFS node is online, open the URL from the hash, this will redirect to the local node. + if (state.isIpfsOnline) { + openURLFromHash() + return + } + return html`
${renderCompanionLogo(i18n, false)}

${i18n.getMessage('recovery_page_message')}

From a438c1919c01c4752d3365f55166bb3f5d25ccb4 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 5 Jan 2023 02:22:41 -0700 Subject: [PATCH 13/35] Refactor + Implement Design Change --- add-on/_locales/en/messages.json | 10 ++++++- add-on/src/landing-pages/welcome/page.js | 15 +++++++---- add-on/src/recovery/recovery.css | 4 ++- add-on/src/recovery/recovery.html | 33 ++++++++++++++--------- add-on/src/recovery/recovery.js | 34 +++++++++++++++--------- 5 files changed, 64 insertions(+), 32 deletions(-) diff --git a/add-on/_locales/en/messages.json b/add-on/_locales/en/messages.json index 363331f8e..76a21dd83 100644 --- a/add-on/_locales/en/messages.json +++ b/add-on/_locales/en/messages.json @@ -735,12 +735,20 @@ "message": "Node is Offline", "description": "Main header on the recovery screen (recovery_page_header)" }, + "recovery_page_sub_header": { + "message": "IPFS Companion is unable to connect to this IPFS node.", + "description": "Sub-Header on the recovery screen (recovery_page_sub_header)" + }, "recovery_page_message": { - "message": "IPFS Companion is unable to connect to the IPFS node. Would you like to connect to a public gateway instead?", + "message": "Your configured node seems to be offline. Would you like to connect to a public gateway instead?", "description": "Message on the recovery screen (recovery_page_message)" }, "recovery_page_button": { "message": "Continue to a public gateway", "description": "Button on the recovery screen (recovery_page_button)" + }, + "recovery_page_learn_more": { + "message": "Learn more about public gateways", + "description": "Learn more link on the recovery screen (recovery_page_learn_more)" } } diff --git a/add-on/src/landing-pages/welcome/page.js b/add-on/src/landing-pages/welcome/page.js index 1006d08e2..969c576ef 100644 --- a/add-on/src/landing-pages/welcome/page.js +++ b/add-on/src/landing-pages/welcome/page.js @@ -47,16 +47,21 @@ export default function createWelcomePage (i18n) { /* ======================================================== Render functions for the left side ======================================================== */ - -export const renderCompanionLogo = (i18n, isIpfsOnline) => { +export const renderLogo = (isIpfsOnline, logoSize = 128) => { const logoPath = '../../../icons' - const logoSize = 128 + + return html` + ${logo({ path: logoPath, size: logoSize, isIpfsOnline })} + ` +} + +export const renderCompanionLogo = (i18n, isIpfsOnline, showTitle = true) => { const stateUnknown = isIpfsOnline === null return html`
- ${logo({ path: logoPath, size: logoSize, isIpfsOnline: isIpfsOnline })} -

${i18n.getMessage('page_landingWelcome_logo_title')}

+ ${renderLogo(isIpfsOnline)} + ${showTitle ? `

${i18n.getMessage('page_landingWelcome_logo_title')}

` : ''}
` } diff --git a/add-on/src/recovery/recovery.css b/add-on/src/recovery/recovery.css index 6ba108b96..edcaba9cf 100644 --- a/add-on/src/recovery/recovery.css +++ b/add-on/src/recovery/recovery.css @@ -12,5 +12,7 @@ header { } .recovery-root { - text-align: center; + width: 100%; + height: 100%; + text-align: left; } diff --git a/add-on/src/recovery/recovery.html b/add-on/src/recovery/recovery.html index 5eecde4bd..cec956367 100644 --- a/add-on/src/recovery/recovery.html +++ b/add-on/src/recovery/recovery.html @@ -9,17 +9,26 @@ -
-
- -
-

-
-
-
- - -
- + +
+
+ +
+

+
+
+
+
+ + + +
diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js index af8a4ace1..ffac57964 100644 --- a/add-on/src/recovery/recovery.js +++ b/add-on/src/recovery/recovery.js @@ -4,7 +4,7 @@ import choo from 'choo' import html from 'choo/html/index.js' import { i18n, runtime } from 'webextension-polyfill' -import { renderCompanionLogo } from '../landing-pages/welcome/page.js' +import { renderLogo } from '../landing-pages/welcome/page.js' import createWelcomePageStore from '../landing-pages/welcome/store.js' import './recovery.css' @@ -35,18 +35,24 @@ app.route('*', (state) => { return } - return html`
- ${renderCompanionLogo(i18n, false)} -

${i18n.getMessage('recovery_page_message')}

-

-

Public URI: ${publicURI}

- + return html`
+
+
+ ${renderLogo(false, 256)} +
+
+

${i18n.getMessage('recovery_page_sub_header')}

+

${i18n.getMessage('recovery_page_message')}

+

Public URI: ${publicURI}

+ +
+
` }) @@ -55,4 +61,6 @@ app.mount('#root') // Set page title and header translation document.getElementById('header-text').innerText = i18n.getMessage('recovery_page_header') +console.log(document.getElementById('learn-more')) +document.getElementById('learn-more').innerText = i18n.getMessage('recovery_page_learn_more') document.title = i18n.getMessage('recovery_page_title') From e31cbbfb97644c2c32dc1b7ed698d478eb9ffc6e Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 12 Jan 2023 19:08:36 -0700 Subject: [PATCH 14/35] Update add-on/src/lib/ipfs-request.js Co-authored-by: Marcin Rataj --- add-on/src/lib/ipfs-request.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add-on/src/lib/ipfs-request.js b/add-on/src/lib/ipfs-request.js index 433df4505..6b38d97f5 100644 --- a/add-on/src/lib/ipfs-request.js +++ b/add-on/src/lib/ipfs-request.js @@ -143,7 +143,7 @@ export function createRequestModifier (getState, dnslinkResolver, ipfsPathValida const state = getState() if (!state.active) return - // When local IPFS node is disabled, show recovery page where user can redirect + // When local IPFS node is unreachable , show recovery page where user can redirect // to public gateway. if (!state.connected && request.type === 'main_frame' && sameGateway(request.url, state.gwURL)) { const publicUri = ipfsPathValidator.resolveToPublicUrl(request.url, state.pubGwURLString) From 0561045ee926c6023bd66fbc1978b3d2554e5948 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 12 Jan 2023 19:09:46 -0700 Subject: [PATCH 15/35] Update add-on/_locales/en/messages.json Co-authored-by: Marcin Rataj --- add-on/_locales/en/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add-on/_locales/en/messages.json b/add-on/_locales/en/messages.json index 89a0f3019..ed7013d00 100644 --- a/add-on/_locales/en/messages.json +++ b/add-on/_locales/en/messages.json @@ -720,7 +720,7 @@ "description": "Main header on the recovery screen (recovery_page_header)" }, "recovery_page_sub_header": { - "message": "IPFS Companion is unable to connect to this IPFS node.", + "message": "Unable to reach the IPFS node :(", "description": "Sub-Header on the recovery screen (recovery_page_sub_header)" }, "recovery_page_message": { From 4a139d8a76ebf9441b4f896a5b328512456cf9a8 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 12 Jan 2023 19:11:54 -0700 Subject: [PATCH 16/35] Update add-on/src/recovery/recovery.js Co-authored-by: Marcin Rataj --- add-on/src/recovery/recovery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js index ffac57964..ba4dddcb5 100644 --- a/add-on/src/recovery/recovery.js +++ b/add-on/src/recovery/recovery.js @@ -23,7 +23,7 @@ app.route('*', (state) => { const openURLFromHash = () => { try { console.log('Opening URL from hash:', publicURI) - window.location.href = publicURI + window.location.replace(publicURI) } catch (err) { console.error('Failed to open URL from hash:', err) } From 5ce8b180d9b27cb47df879264dd1e153b4cfd01f Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 12 Jan 2023 19:12:24 -0700 Subject: [PATCH 17/35] Update add-on/_locales/en/messages.json Co-authored-by: Marcin Rataj --- add-on/_locales/en/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add-on/_locales/en/messages.json b/add-on/_locales/en/messages.json index ed7013d00..4c27815d7 100644 --- a/add-on/_locales/en/messages.json +++ b/add-on/_locales/en/messages.json @@ -732,7 +732,7 @@ "description": "Button on the recovery screen (recovery_page_button)" }, "recovery_page_learn_more": { - "message": "Learn more about public gateways", + "message": "Learn more about node types in IPFS Companion", "description": "Learn more link on the recovery screen (recovery_page_learn_more)" } } From baad76051609ec2b53913d3857a53b1120b2e4ce Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 12 Jan 2023 19:12:52 -0700 Subject: [PATCH 18/35] Update add-on/_locales/en/messages.json Co-authored-by: Marcin Rataj --- add-on/_locales/en/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add-on/_locales/en/messages.json b/add-on/_locales/en/messages.json index 4c27815d7..3a6f65f59 100644 --- a/add-on/_locales/en/messages.json +++ b/add-on/_locales/en/messages.json @@ -728,7 +728,7 @@ "description": "Message on the recovery screen (recovery_page_message)" }, "recovery_page_button": { - "message": "Continue to a public gateway", + "message": "Continue to the public gateway", "description": "Button on the recovery screen (recovery_page_button)" }, "recovery_page_learn_more": { From 4ff97b6ad2dc66a8f7327796516a7c6de3fcf82f Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 12 Jan 2023 19:13:33 -0700 Subject: [PATCH 19/35] Update add-on/src/recovery/recovery.html Co-authored-by: Marcin Rataj --- add-on/src/recovery/recovery.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add-on/src/recovery/recovery.html b/add-on/src/recovery/recovery.html index cec956367..aa25c2821 100644 --- a/add-on/src/recovery/recovery.html +++ b/add-on/src/recovery/recovery.html @@ -23,7 +23,7 @@

Learn More From d3018f43910e11dccd70cebe8428564b12274875 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 12 Jan 2023 19:13:51 -0700 Subject: [PATCH 20/35] Update add-on/src/recovery/recovery.js Co-authored-by: Marcin Rataj --- add-on/src/recovery/recovery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js index ba4dddcb5..001f583f8 100644 --- a/add-on/src/recovery/recovery.js +++ b/add-on/src/recovery/recovery.js @@ -45,7 +45,7 @@ app.route('*', (state) => {

${i18n.getMessage('recovery_page_message')}

Public URI: ${publicURI}

-

+ return html`
+
+ ${renderCompanionLogo(i18n, false)} +

${version}

+
+ +
+ +

${i18n.getMessage('recovery_page_sub_header')}

+

${i18n.getMessage('recovery_page_message_p1')}

+

${i18n.getMessage('recovery_page_message_p2')}

+

Public URL: ${publicURI}

+ +

+ ${learnMoreLink} | ${optionsPageLink} +

` }) @@ -61,5 +74,4 @@ app.mount('#root') // Set page title and header translation document.getElementById('header-text').innerText = i18n.getMessage('recovery_page_header') -document.getElementById('learn-more').innerText = i18n.getMessage('recovery_page_learn_more') document.title = i18n.getMessage('recovery_page_title') From 2ea33c23d8ca89fd166e751858a51003dbf1e6f8 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 12 Jan 2023 23:38:27 -0700 Subject: [PATCH 29/35] lint --- add-on/src/lib/ipfs-companion.js | 3 +-- add-on/src/lib/ipfs-request.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/add-on/src/lib/ipfs-companion.js b/add-on/src/lib/ipfs-companion.js index 9a0e4a805..df3d664d9 100644 --- a/add-on/src/lib/ipfs-companion.js +++ b/add-on/src/lib/ipfs-companion.js @@ -10,7 +10,7 @@ import LRU from 'lru-cache' import all from 'it-all' import { optionDefaults, storeMissingOptions, migrateOptions, guiURLString, safeURL } from './options.js' import { initState, offlinePeerCount } from './state.js' -import { createIpfsPathValidator, sameGateway, safeHostname } from './ipfs-path.js' +import { createIpfsPathValidator, dropSlash, sameGateway, safeHostname } from './ipfs-path.js' import createDnslinkResolver from './dnslink.js' import { createRequestModifier } from './ipfs-request.js' import { initIpfsClient, destroyIpfsClient, reloadIpfsClientOfflinePages } from './ipfs-client/index.js' @@ -23,7 +23,6 @@ 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 { dropSlash } from './ipfs-path.js' const log = debug('ipfs-companion:main') log.error = debug('ipfs-companion:main:error') diff --git a/add-on/src/lib/ipfs-request.js b/add-on/src/lib/ipfs-request.js index 52fd067a1..e20e568ff 100644 --- a/add-on/src/lib/ipfs-request.js +++ b/add-on/src/lib/ipfs-request.js @@ -6,11 +6,10 @@ import debug from 'debug' import LRU from 'lru-cache' import isIPFS from 'is-ipfs' import isFQDN from 'is-fqdn' -import { pathAtHttpGateway, sameGateway, ipfsUri } from './ipfs-path.js' +import { dropSlash, ipfsUri, pathAtHttpGateway, sameGateway } from './ipfs-path.js' import { safeURL } from './options.js' import { braveNodeType } from './ipfs-client/brave.js' import { recoveryPagePath } from './constants.js' -import { dropSlash } from './ipfs-path.js' const log = debug('ipfs-companion:request') log.error = debug('ipfs-companion:request:error') From 4c5642b65f5d4d2d57d34ebf57769873f081095c Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Fri, 13 Jan 2023 00:12:16 -0700 Subject: [PATCH 30/35] feat: Adding regression test --- .../lib/ipfs-request-gateway-redirect.test.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/functional/lib/ipfs-request-gateway-redirect.test.js b/test/functional/lib/ipfs-request-gateway-redirect.test.js index 6389764c4..07d3ccacc 100644 --- a/test/functional/lib/ipfs-request-gateway-redirect.test.js +++ b/test/functional/lib/ipfs-request-gateway-redirect.test.js @@ -33,6 +33,7 @@ describe('modifyRequest.onBeforeRequest:', function () { global.URL = URL global.browser = browser browser.runtime.id = 'testid' + browser.runtime.getURL.returns('chrome-extension://testid/') }) beforeEach(async function () { @@ -425,6 +426,24 @@ describe('modifyRequest.onBeforeRequest:', function () { }) }) + describe('Recovers Page if node is unreachable', function () { + beforeEach(function () { + global.browser = browser + state.ipfsNodeType = 'external' + state.redirect = true + state.peerCount = -1 + state.gwURLString = 'http://localhost:8080' + state.gwURL = new URL('http://localhost:8080') + state.pubGwURLString = 'https://ipfs.io' + state.pubGwURL = new URL('https://ipfs.io') + }) + it('should present recovery page if node is offline', function () { + expect(state.nodeActive).to.be.equal(false) + const request = url2request('https://localhost:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR/foo/bar') + expect(modifyRequest.onBeforeRequest(request).redirectUrl).to.equal('chrome-extension://testid/dist/recovery/recovery.html#https%3A%2F%2Fipfs.io%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%2Ffoo%2Fbar') + }) + }) + after(function () { delete global.URL delete global.browser From ba6e573e8efd5012b878616c95262565c66d1c32 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Mon, 30 Jan 2023 19:33:46 -0700 Subject: [PATCH 31/35] feat: :sparkles: Add telemetry for recovery mechanism --- add-on/src/recovery/recovery.js | 1 + 1 file changed, 1 insertion(+) diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js index 11d462f3f..303f9b658 100644 --- a/add-on/src/recovery/recovery.js +++ b/add-on/src/recovery/recovery.js @@ -20,6 +20,7 @@ const optionsPageLink = html` + + +` + const renderInstallSteps = (i18n, isIpfsOnline) => { const copyClass = 'mv0 white f5 lh-copy' const anchorClass = 'aqua hover-white' const stateUnknown = isIpfsOnline === null - const svgWidth = 130 - - const nodeOffSvg = () => html` - - - - ` const optionsUrl = browser.runtime.getURL(optionsPage) return html` diff --git a/add-on/src/recovery/recovery.css b/add-on/src/recovery/recovery.css index 5e611bdc9..9356c92a6 100644 --- a/add-on/src/recovery/recovery.css +++ b/add-on/src/recovery/recovery.css @@ -43,17 +43,6 @@ a:hover { } } -header { - z-index: 1; - border-color: #69c4cd; - text-transform: uppercase; -} - -#header-logo { - height: 50px; - width: 117.5px; -} - .recovery-root { width: 100%; height: 100%; diff --git a/add-on/src/recovery/recovery.html b/add-on/src/recovery/recovery.html index 64608728c..af492fbe3 100644 --- a/add-on/src/recovery/recovery.html +++ b/add-on/src/recovery/recovery.html @@ -10,13 +10,7 @@ -
-
- -
-

-
-
+
diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js index 303f9b658..227b79223 100644 --- a/add-on/src/recovery/recovery.js +++ b/add-on/src/recovery/recovery.js @@ -5,7 +5,7 @@ import choo from 'choo' import html from 'choo/html/index.js' import icon from 'ipfs-css/icons/stroke_attention.svg' import browser, { i18n, runtime } from 'webextension-polyfill' -import { renderCompanionLogo } from '../landing-pages/welcome/page.js' +import { nodeOffSvg } from '../landing-pages/welcome/page.js' import createWelcomePageStore from '../landing-pages/welcome/store.js' import { optionsPage } from '../lib/constants.js' import './recovery.css' @@ -46,13 +46,13 @@ app.route('*', (state) => { return html`
- ${renderCompanionLogo(i18n, false)} -

${version}

+
+ ${nodeOffSvg(200)} +

${i18n.getMessage('recovery_page_sub_header')}

+
- -

${i18n.getMessage('recovery_page_sub_header')}

${i18n.getMessage('recovery_page_message_p1')}

${i18n.getMessage('recovery_page_message_p2')}

Public URL: ${publicURI}

@@ -74,5 +74,4 @@ app.route('*', (state) => { app.mount('#root') // Set page title and header translation -document.getElementById('header-text').innerText = i18n.getMessage('recovery_page_header') document.title = i18n.getMessage('recovery_page_title') From 97be3933d6efbbf49b3a2eece34ac69164f0e9c9 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Thu, 2 Feb 2023 23:37:41 -0700 Subject: [PATCH 33/35] fix(ux): :lipstick: Fixing CSS --- add-on/src/recovery/recovery.css | 10 +++++++--- add-on/src/recovery/recovery.js | 8 ++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/add-on/src/recovery/recovery.css b/add-on/src/recovery/recovery.css index 9356c92a6..786182825 100644 --- a/add-on/src/recovery/recovery.css +++ b/add-on/src/recovery/recovery.css @@ -8,7 +8,11 @@ } a:hover { - text-decoration: underline; + text-decoration: none; +} + +a:visited { + color: inherit; } /* @@ -27,8 +31,8 @@ a:hover { } #right-col { - margin-left: 57%; - margin-right: 7%; + margin-left: 54%; + margin-right: 6%; } } diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js index 227b79223..9a3548230 100644 --- a/add-on/src/recovery/recovery.js +++ b/add-on/src/recovery/recovery.js @@ -52,18 +52,18 @@ app.route('*', (state) => {
-
+

${i18n.getMessage('recovery_page_message_p1')}

${i18n.getMessage('recovery_page_message_p2')}

-

Public URL: ${publicURI}

+

Public URL: ${publicURI}

-

+

${learnMoreLink} | ${optionsPageLink}

From 3e76bf8527edf21133d10f94e3964d1ce221a1e0 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Fri, 3 Feb 2023 01:58:48 -0700 Subject: [PATCH 34/35] fix: :rotating_light: fix lint --- add-on/src/recovery/recovery.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js index 9a3548230..375556ffe 100644 --- a/add-on/src/recovery/recovery.js +++ b/add-on/src/recovery/recovery.js @@ -3,7 +3,6 @@ import choo from 'choo' import html from 'choo/html/index.js' -import icon from 'ipfs-css/icons/stroke_attention.svg' import browser, { i18n, runtime } from 'webextension-polyfill' import { nodeOffSvg } from '../landing-pages/welcome/page.js' import createWelcomePageStore from '../landing-pages/welcome/store.js' @@ -23,7 +22,6 @@ app.route('*', (state) => { browser.runtime.sendMessage({ telemetry: { trackView: 'recovery' } }) const { hash } = window.location const { href: publicURI } = new URL(decodeURIComponent(hash.slice(1))) - const { version } = browser.runtime.getManifest() if (!publicURI) { return From 6f53132390e68abfc6efa80faa2950631819ec9a Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 3 Feb 2023 14:42:32 +0100 Subject: [PATCH 35/35] style: adjust text and css --- add-on/_locales/en/messages.json | 12 ++++-------- add-on/src/recovery/recovery.js | 6 +++--- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/add-on/_locales/en/messages.json b/add-on/_locales/en/messages.json index c141be673..05e20d2d0 100644 --- a/add-on/_locales/en/messages.json +++ b/add-on/_locales/en/messages.json @@ -752,23 +752,19 @@ "description": "A description for the 'tracking' grouping of metrics we collect (option_telemetryGroupTracking_description)" }, "recovery_page_title" : { - "message": "Node Offline | IPFS Companion", + "message": "Problem with your IPFS node | IPFS Companion", "description": "Title of the recovery page (recovery_page_title)" }, - "recovery_page_header" : { - "message": "Companion", - "description": "Main header on the recovery screen (recovery_page_header)" - }, "recovery_page_sub_header": { - "message": "Unable to reach the IPFS node :(", + "message": "Unable to reach your IPFS node :(", "description": "Sub-Header on the recovery screen (recovery_page_sub_header)" }, "recovery_page_message_p1": { - "message": "Make sure IPFS Desktop is running and provides the HTTP Gateway Functionality.", + "message": "Ensure your IPFS node runs and provides HTTP Gateway.", "description": "Message Para-1 on the recovery screen (recovery_page_message_p1)" }, "recovery_page_message_p2": { - "message": "Alternatively, you can try to open the requested resource using the Public Gateway configured in IPFS Companion. In doing so you will be delegating trust to that HTTP server and the hash verification will no longer occur on your machine.", + "message": "You can also access deserialized version of the requested resource through the preferred public gateway set up in IPFS Companion. This delegates trust to a third-party address below, and skips local hash validation.", "description": "Message Para-2 on the recovery screen (recovery_page_message_p2)" }, "recovery_page_button": { diff --git a/add-on/src/recovery/recovery.js b/add-on/src/recovery/recovery.js index 375556ffe..e749123f8 100644 --- a/add-on/src/recovery/recovery.js +++ b/add-on/src/recovery/recovery.js @@ -11,9 +11,9 @@ import './recovery.css' const app = choo() -const learnMoreLink = html`${i18n.getMessage('recovery_page_learn_more')}` +const learnMoreLink = html`${i18n.getMessage('recovery_page_learn_more')}` -const optionsPageLink = html`${i18n.getMessage('recovery_page_update_preferences')}` +const optionsPageLink = html`${i18n.getMessage('recovery_page_update_preferences')}` // TODO (whizzzkid): refactor base store to be more generic. app.use(createWelcomePageStore(i18n, runtime)) @@ -53,7 +53,7 @@ app.route('*', (state) => {

${i18n.getMessage('recovery_page_message_p1')}

${i18n.getMessage('recovery_page_message_p2')}

-

Public URL: ${publicURI}

+

Public URL: ${publicURI}