Skip to content

Commit

Permalink
Merge branch 'rc/3.0-mv3' into feat/redirection-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
whizzzkid authored Aug 4, 2023
2 parents 6bd8c3c + 2d65822 commit 47ea944
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 4 deletions.
24 changes: 24 additions & 0 deletions add-on/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -786,5 +786,29 @@
"recovery_page_update_preferences": {
"message": "Update your IPFS Companion preferences",
"description": "Learn more link on the recovery screen (recovery_page_learn_more)"
},
"request_permissions_page_title": {
"message": "Grant Host Permissions | IPFS Companion",
"description": "Title of the recovery page (recovery_page_title)"
},
"request_permissions_page_sub_header": {
"message": "Just one more thing to do before you're all set! :)",
"description": "Sub-Header on the recovery screen (recovery_page_sub_header)"
},
"request_permissions_page_message_p1": {
"message": "IPFS Companion needs permission to identify IPFS resources on the web.",
"description": "Message Para-1 on the recovery screen (recovery_page_message_p1)"
},
"request_permissions_page_message_p2": {
"message": "The IPFS Companion requires Host permission to access data on all websites. This allows it to inspect all web requests, identify ones for content-addressed IPFS resources, and load them using your local IPFS node. Please click the button below to grant these permissions.",
"description": "Message Para-2 on the recovery screen (recovery_page_message_p2)"
},
"request_permissions_page_button": {
"message": "Grant Permission",
"description": "Button on the recovery screen (recovery_page_button)"
},
"request_permissions_page_learn_more": {
"message": "Learn more about host permissions",
"description": "Learn more link on the recovery screen (recovery_page_learn_more)"
}
}
54 changes: 54 additions & 0 deletions add-on/src/landing-pages/permissions/request.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
@import url('~tachyons/css/tachyons.css');
@import url('~ipfs-css/ipfs.css');

#left-col {
background-image: url('../../../images/stars.png'), linear-gradient(to bottom, #041727 0%, #043b55 100%);
background-size: 100%;
background-repeat: repeat;
}

a:hover {
text-decoration: none;
}

a:visited {
color: inherit;
}

/*
https://github.com/tachyons-css/tachyons-queries
Tachyons: $point == large
*/
@media (min-width: 60em) {
#left-col {
position: fixed;
top: 0;
right: 55%;
width: 45%;
background-image: url('../../../images/stars.png'), linear-gradient(to bottom, #041727 0%, #043b55 100%);
background-size: 100%;
background-repeat: repeat;
}

#right-col {
margin-left: 54%;
margin-right: 6%;
}
}

@media (max-height: 800px) {
#left-col img {
width: 98px !important;
height: 98px !important;
}

#left-col svg {
width: 60px;
}
}

.recovery-root {
width: 100%;
height: 100%;
text-align: left;
}
20 changes: 20 additions & 0 deletions add-on/src/landing-pages/permissions/request.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>IPFS Node is Offline</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlo89/56ZQ/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUjDu1lo89/6mhTP+zrVP/nplD/5+aRK8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHNiIS6Wjz3/ubFY/761W/+vp1D/urRZ/8vDZf/GvmH/nplD/1BNIm8AAAAAAAAAAAAAAAAAAAAAAAAAAJaPPf+knEj/vrVb/761W/++tVv/r6dQ/7q0Wf/Lw2X/y8Nl/8vDZf+tpk7/nplD/wAAAAAAAAAAAAAAAJaPPf+2rVX/vrVb/761W/++tVv/vrVb/6+nUP+6tFn/y8Nl/8vDZf/Lw2X/y8Nl/8G6Xv+emUP/AAAAAAAAAACWjz3/vrVb/761W/++tVv/vrVb/761W/+vp1D/urRZ/8vDZf/Lw2X/y8Nl/8vDZf/Lw2X/nplD/wAAAAAAAAAAlo89/761W/++tVv/vrVb/761W/++tVv/r6dQ/7q0Wf/Lw2X/y8Nl/8vDZf/Lw2X/y8Nl/56ZQ/8AAAAAAAAAAJaPPf++tVv/vrVb/761W/++tVv/vbRa/5aPPf+emUP/y8Nl/8vDZf/Lw2X/y8Nl/8vDZf+emUP/AAAAAAAAAACWjz3/vrVb/761W/++tVv/vrVb/5qTQP+inkb/op5G/6KdRv/Lw2X/y8Nl/8vDZf/Lw2X/nplD/wAAAAAAAAAAlo89/761W/++tVv/sqlS/56ZQ//LxWb/0Mlp/9DJaf/Kw2X/oJtE/7+3XP/Lw2X/y8Nl/56ZQ/8AAAAAAAAAAJaPPf+9tFr/mJE+/7GsUv/Rymr/0cpq/9HKav/Rymr/0cpq/9HKav+xrFL/nplD/8vDZf+emUP/AAAAAAAAAACWjz3/op5G/9HKav/Rymr/0cpq/9HKav/Rymr/0cpq/9HKav/Rymr/0cpq/9HKav+inkb/nplD/wAAAAAAAAAAAAAAAKKeRv+3slb/0cpq/9HKav/Rymr/0cpq/9HKav/Rymr/0cpq/9HKav+1sFX/op5G/wAAAAAAAAAAAAAAAAAAAAAAAAAAop5GUKKeRv/Nxmf/0cpq/9HKav/Rymr/0cpq/83GZ/+inkb/op5GSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAop5G16KeRv/LxWb/y8Vm/6KeRv+inkaPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAop5G/6KeRtcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/n8AAPgfAADwDwAAwAMAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAwAMAAPAPAAD4HwAA/n8AAA==" />
<link rel="stylesheet" href="/dist/bundles/uiCommons.css">
<link rel="stylesheet" href="/dist/bundles/requestPermissionsPage.css">
</head>
<body class="navy bg-white sans-serif">
<app class="flex flex-column transition-all vh-100">
<main class="bg-white flex-grow-1">
<div id="root"></div>
</main>
<script src="/dist/bundles/uiCommons.bundle.js"></script>
<script src="/dist/bundles/requestPermissionsPage.bundle.js"></script>
</app>
</body>
</html>
56 changes: 56 additions & 0 deletions add-on/src/landing-pages/permissions/request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use strict'
/* eslint-env browser, webextensions */

import choo from 'choo'
import html from 'choo/html/index.js'
import { i18n, runtime, permissions } from 'webextension-polyfill'
import { nodeOffSvg } from '../welcome/page.js'
import createWelcomePageStore from '../welcome/store.js'
import { optionsPage } from '../../lib/constants.js'
import './request.css'

const app = choo()

const learnMoreLink = html`<a class="navy link underline-under hover-aqua" href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/host_permissions#requested_permissions_and_user_prompts" target="_blank" rel="noopener noreferrer">${i18n.getMessage('request_permissions_page_learn_more')}</a>`

const optionsPageLink = html`<a class="navy link underline-under hover-aqua" id="learn-more" href="${optionsPage}" target="_blank" rel="noopener noreferrer">${i18n.getMessage('recovery_page_update_preferences')}</a>`

// TODO (whizzzkid): refactor base store to be more generic.
app.use(createWelcomePageStore(i18n, runtime))
// Register our single route
app.route('*', () => {
runtime.sendMessage({ telemetry: { trackView: 'request-permissions' } })
const requestPermission = async () => {
await permissions.request({ origins: ['<all_urls>'] })
runtime.reload()
}

return html`<div class="flex flex-column flex-row-l">
<div id="left-col" class="min-vh-100 flex flex-column justify-center items-center bg-navy white">
<div class="mb4 flex flex-column justify-center items-center">
${nodeOffSvg(200)}
<p class="mt0 mb0 f3 tc">${i18n.getMessage('request_permissions_page_sub_header')}</p>
</div>
</div>
<div id="right-col" class="pt7 mt5 w-100 flex flex-column justify-around items-center">
<p class="f3 fw5">${i18n.getMessage('request_permissions_page_message_p1')}</p>
<p class="f4 fw4">${i18n.getMessage('request_permissions_page_message_p2')}</p>
<button
class="fade-in ba bw1 b--teal bg-teal snow f7 ph2 pv3 br2 ma4 pointer"
onclick=${requestPermission}
>
<span class="f5 fw6">${i18n.getMessage('request_permissions_page_button')}</span>
</button>
<p class="f5 fw2 pt5">
${learnMoreLink} | ${optionsPageLink}
</span>
</div>
</div>`
})

// Start the application and render it to the given querySelector
app.mount('#root')

// Set page title and header translation
document.title = i18n.getMessage('request_permissions_page_title')
1 change: 1 addition & 0 deletions add-on/src/lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,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 requestRequiredPermissionsPage = '/dist/landing-pages/permissions/request.html'
export const tickMs = 250 // no CPU spike, but still responsive enough
2 changes: 1 addition & 1 deletion add-on/src/lib/ipfs-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export function createRequestModifier (getState, dnslinkResolver, ipfsPathValida
const { requestHeaders } = request

if (isCompanionRequest(request)) {
// '403 - Forbidden' fix for Chrome and Firefox
// '403 - Forbidden' fix for browsers that support blocking webRequest API (e.g. Firefox)
// --------------------------------------------
// We update "Origin: *-extension://" HTTP headers in requests made to API
// by js-kubo-rpc-client running in the background page of browser
Expand Down
11 changes: 10 additions & 1 deletion add-on/src/lib/on-installed.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import browser from 'webextension-polyfill'
import debug from 'debug'
import { welcomePage } from './constants.js'
import { requestRequiredPermissionsPage, welcomePage } from './constants.js'
import { brave, braveNodeType } from './ipfs-client/brave.js'

const { version } = browser.runtime.getManifest()
Expand All @@ -21,6 +21,15 @@ export async function onInstalled (details) {
export async function runPendingOnInstallTasks () {
const { onInstallTasks, displayReleaseNotes } = await browser.storage.local.get(['onInstallTasks', 'displayReleaseNotes'])
await browser.storage.local.remove('onInstallTasks')
// this is needed because `permissions.request` cannot be called from a script. If that happens the browser will
// throws: Error: permissions.request may only be called from a user input handler
// To avoid this, we open a new tab with the permissions page and ask the user to grant the permissions.
// That makes the request valid and allows us to gain access to the permissions.
if (!(await browser.permissions.contains({ origins: ['<all_urls>'] }))) {
return browser.tabs.create({
url: requestRequiredPermissionsPage
})
}
switch (onInstallTasks) {
case 'onFirstInstall':
await useNativeNodeIfFeasible(browser)
Expand Down
2 changes: 1 addition & 1 deletion add-on/src/recovery/recovery.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const optionsPageLink = html`<a class="navy link underline-under hover-aqua" id=
app.use(createWelcomePageStore(i18n, runtime))
// Register our single route
app.route('*', (state) => {
browser.runtime.sendMessage({ telemetry: { trackView: 'recovery' } })
runtime.sendMessage({ telemetry: { trackView: 'recovery' } })
const { hash } = window.location
const { href: publicURI } = new URL(decodeURIComponent(hash.slice(1)))

Expand Down
3 changes: 2 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ const uiConfig = merge(commonConfig, {
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'
welcomePage: './add-on/src/landing-pages/welcome/index.js',
requestPermissionsPage: './add-on/src/landing-pages/permissions/request.js',
},
optimization: {
splitChunks: {
Expand Down

0 comments on commit 47ea944

Please sign in to comment.