Skip to content

Commit

Permalink
feat: manifest v3 (#142)
Browse files Browse the repository at this point in the history
* feat: manifest v3 changes

* feat: add library

* fix: manifest v3 fixes

* fix: manifest v3 fixes

* test: fix manifest v3 tests

* fix: fix global postage batch in interceptors

* fix: fix subdomain redirection

* chore: fix merge issues

* ci: build library in ci

* test: fix hashes of test pages

* ci: whitelist bzz protocol

* ci: fix whitelist script

* ci: fix ci script

* ci: tests fix

* test: log bzz page errors

* test: add timeout

* fix: remove google blocker

* Revert "fix: remove google blocker"

This reverts commit 7dde3fc.

* feat: library improvements (#144)

* fix: various fixes

* chore: update library readme

* fix: various fixes

* fix: dapp registration

* fix: various manifest v3 fixes

* chore: test fixes

* chore: fix eslint conflict

* fix: declarative request handlers fix

* test: fix tests

* feat: add subdomain redirection (#147)

* feat: add subdomain redirection

* fix: fix interceptor ids

* feat: support hash sign in url

* feat: add echo debug method (#148)

* feat: add echo debug method

* chore: update library readme

* chore: fix library redme example

* chore: update readme

* feat: remove session-id from url (#150)

* chore: update readme

* fix: fix subdomain redirection

* fix: fix cors error

* feat: change default bee address

* chore: update readme

* chore: fix typo in readme
  • Loading branch information
tomicvladan authored Nov 18, 2022
1 parent 961a9c2 commit 287edee
Show file tree
Hide file tree
Showing 83 changed files with 12,437 additions and 1,564 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dist/**
test/**/swarm/**
9 changes: 8 additions & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
fetch-depth: 1

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
Expand All @@ -45,6 +45,13 @@ jobs:
- name: Compile
run: npm run compile

- name: Install library npm deps
if: steps.cache-npm-lib.outputs.cache-hit != 'true'
run: cd library && npm ci && cd ..

- name: Build library
run: cd library && npm run build && cd ..

- name: Install fdp-play
run: npm install -g @fairdatasociety/fdp-play

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ extension.zip

# Dependency directory
node_modules

# test library
test/**/swarm
26 changes: 15 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

**Warning: This project has Proof of Concept state now. There will be breaking changes continuously in the future. Also, no guarantees can be made about its stability, efficiency, and security at this stage. It only provides a platform currently to show workarounds and examples for the current problems in dApp environments top on Swarm**


**Info: For manifest v3 version of the extension, dApps should interact with the extension using the `Swarm Extension Library`. Check how it works [here](library/README.md).**

This browser extension provides an alternative to have a web3 environment in a web2 browser for users and dApps.

Users can interact with the Swarm network in two ways: by running their own Bee client or using a gateway solution.
Expand All @@ -27,6 +30,15 @@ npm run compile

commands. If everything went right, then a `dist` folder appeared in the root of the project folder. That folder has to be [added to your browser extensions](chrome://extensions/) as an unpacked extension. You can load unpacked extensions only if you checked in the `Developer mode` (top-right corner).

## Manifest V3 Changes

Since manifest v2 extensions won't be allowed from June 2023, the Swarm Extension now supports manifest v3. But that brings some limitations, not present in v2. Here are the key changes in v3:

- The `swarm` object won't be injected into dApp pages. Instead each dApp should include the [Swarm Extension Library](library/README.md) into its code to comunicate with the extension.
- Blocking interceptors are not allowed in manifest v3, so the new implementation uses the [Declarative Network Request API](https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/). This requirement prevents the extension from checking session ID for fake URL requests. That means the extension cannot check the security context of the links that are being accessed.
- If bee URL is set to `localhost`, then fake URL links are redirected to subdomain based bee URLs. For example, trying to access the `bzz://site.eth` URL will result in accessing the `http://site.swarm.localhost:1633/` URL.


## Fake URL

There is a need to separate dApp context from the user context in order to restrict dApp actions work with keys and resources of the user.
Expand All @@ -42,8 +54,6 @@ The extension can keep these keys and configurations on the side of the user
and it does not expose the secrets to the applications that initialize the call.
In this sense it also works like a `proxy`.

During the redirection, the extension creates separated context by `root content IDs` and performs the action according to that.
(E.g. restrict calls towards the targeted service, cache the returned cookies from the response in the content context, etc.)
This architecture also allows changing the default URLs of decentralized services (Bee) to any arbitrary one,
meanwhile dApps do not have to guess this address.
For example Bee client has default `http://127.0.0.1:1633`, user can change it to any other port or even other gateway host,
Expand All @@ -65,10 +75,6 @@ The Swarm protocol to address other P2P content is `bzz`. It makes a redirection
If you type `bzz://{content-address}` into the address bar, the page will be redirected to `http(s)://{your-bzz-node-host}/bzz/{content-address}`. This requires the default search engine of the browser to be set to Google.
It also behaves the same on simple google searches on `https://google.com`.

Additionally, the extension currently [injects a script](src/contentscript/index.ts) on document load so that dApp pages could refer any other P2P resources.
These references will request the configured Bee client of the user.
It is injected to every page basically, so any frontend application can utilize this feature.

There will be need for other Swarm specific protocols (or extend the current one), which handle different type of feeds and mutable content.

You can read about it in more detail in the following section
Expand Down Expand Up @@ -96,14 +102,11 @@ All requests towards the `bzz.link` gateways will be cancelled and tunneled to t

The consequence of this behaviour the dApps which use external bzz.link references in their HTML code and want to available via both bzz.link gateways and private extension connections have to use [Swarm HTML elements](#Swarm-HTML).

Additinonally, the extension provides an injected library `swarm.bzzLink` to get CID of a swarm content hash (and vica versa).

## dApp origin instead of host-based origin

All Swarm content that the extension renders will be put into _sandbox_ mode even in root level by _Content Security Policy_ headers.
All Swarm content that the extension renders, without using subdomain, will be put into _sandbox_ mode even in root level by _Content Security Policy_ headers.
It means dApps will act like a different, distinct webpage from the Bee host that serves those.
Therefore no traditional _cookies_ or _localStorage_ is available for dApps, but equivalent services of those are.
(Cookie support is planned in the future, it is possible by this current architecture).

In order to substitue these traditional stateful behaviours of the applications with something else, the Swarm Extension introduces
the `dApp Security Context` as a new abstraction of origins.
Expand All @@ -118,7 +121,7 @@ the handling of `localStorage` method happens based on the `sessionId` of the dA

Thereby even if the user changes its P2P client host, the state and their session will remain - unlike using only subdomain content address URLs with the traditional `localStorage`.

Of course, it is not necessary to set any ID manually, just call the usual `localStorage` methods but under the `swarm` object:
Of course, it is not necessary to set any ID manually, just call the usual `localStorage` methods but under the `swarm` object, created as an instance of the [Swarm Class](library/README.md#swarm-class):
instead of `window.localStorage.setItem('swarm', 'bzz')` you can call `swarm.localStorage.setItem('swarm', 'bzz')` in order to persist data in the browser.

The `setItem` and `getItem` methods here are `async` methods, so these return with `Promise`.
Expand Down Expand Up @@ -170,5 +173,6 @@ In its [index page](test/bzz-test-page/index.html), you see how you can refer to

- [nugaon](https://github.com/nugaon)
- [Cafe137](https://github.com/Cafe137)
- [tomicvladan](https://github.com/tomicvladan)

See what "Maintainer" means [here](https://github.com/ethersphere/repo-maintainer).
2 changes: 2 additions & 0 deletions library/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/**
test/**/swarm/**
86 changes: 86 additions & 0 deletions library/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
module.exports = {
extends: ['prettier'],
parserOptions: {
sourceType: 'module',
ecmaVersion: 2018,
},
globals: {
browser: true,
page: true,
},
rules: {
'array-bracket-newline': ['error', { multiline: true }],
strict: ['error', 'safe'],
curly: 'error',
'block-scoped-var': 'error',
complexity: 'warn',
'default-case': 'error',
'dot-notation': 'warn',
eqeqeq: 'error',
'guard-for-in': 'warn',
'linebreak-style': ['warn', 'unix'],
'no-alert': 'error',
'no-case-declarations': 'error',
'no-constant-condition': 'error',
'no-div-regex': 'error',
'no-empty': 'warn',
'no-empty-pattern': 'error',
'no-implicit-coercion': 'error',
'prefer-arrow-callback': 'warn',
'no-labels': 'error',
'no-loop-func': 'error',
'no-nested-ternary': 'warn',
'no-script-url': 'error',
'no-warning-comments': 'warn',
'quote-props': ['error', 'as-needed'],
'require-yield': 'error',
'max-nested-callbacks': ['error', 4],
'max-depth': ['error', 4],
'require-await': 'error',
'@typescript-eslint/no-non-null-assertion': 'off',
'space-before-function-paren': [
'error',
{
anonymous: 'never',
named: 'never',
asyncArrow: 'always',
},
],
'padding-line-between-statements': [
'error',
{ blankLine: 'always', prev: '*', next: 'if' },
{ blankLine: 'always', prev: '*', next: 'function' },
{ blankLine: 'always', prev: '*', next: 'return' },
],
'no-useless-constructor': 'off',
'no-dupe-class-members': 'off',
'no-unused-expressions': 'off',
curly: ['error', 'multi-line'],
'object-curly-spacing': ['error', 'always'],
'comma-dangle': ['error', 'always-multiline'],
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/no-unused-expressions': 'error',
'@typescript-eslint/member-delimiter-style': [
'error',
{
multiline: {
delimiter: 'none',
requireLast: true,
},
singleline: {
delimiter: 'semi',
requireLast: false,
},
},
],
},
overrides: [
{
files: ['*.spec.ts'],
rules: {
// '@typescript-eslint/ban-ts-ignore': 'off',
'max-nested-callbacks': ['error', 10], // allow describe/it nesting
},
},
],
}
2 changes: 2 additions & 0 deletions library/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
build
13 changes: 13 additions & 0 deletions library/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"printWidth": 110,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"semi": false,
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "all",
"endOfLine": "lf",
"arrowParens": "avoid",
"proseWrap": "always"
}
90 changes: 90 additions & 0 deletions library/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Swarm Browser Extension JS Library

Library for interaction with the Swarm Browser Extension, from Dapps or other browser extensions.

## Installation

The library can be installed via npm:

```bash
npm install --save @ethersphere/swarm-extension
```

## Usage

### Swarm class

All interaction with the Swarm browser extension is established through the Swarm class:

```typescript
import { Swarm } from '@fairdatasociety/swarm-extension'
```

By default the class will connect to the Swarm browser extension using its ID from the Google store. If you
are running your version of the extension the class can be configured with a different extension ID.

```typescript
const swarm = new Swarm() // Using the default Swarm ID from the Google store
```

```typescript
const swarm = new Swarm('Swarm Extension ID...') // Using custom Swarm ID
```

To test if connection with the Swarm extension is established, call the `echo` method:

```typescript
const text = await swarm.echo<string>('test')
console.log(text) // 'test'
```

### Swarm class functionalities

Before interacting with the library, Dapp should register new session by calling:

```typescript
await swarm.register()
```

or new session will be implicitly created when calling any method for the first time.

After registering a new session, session ID will be available as:

```typescript
swarm.sessionId
```

There are four different objects available in the Swarm calass:

- swarm.bzzLink - utility functions for converting bzz links
- swarm.localStorage - methods for interacting with local storage
- swarm.postageBatch - checking postage batch status
- swarm.web2Helper - getting information about bee URL

### Terminating connection

Once when the instance of the Swarm class is not needed anymore, connection with the extension can be terminated.

```typescript
swarm.closeConnection()
```

### Swarm HTML

To enable Swarm HTML features, include the `swarm-html.js` script into HTML page. For more details check [Swarm HTML in the main readme](../README.md#swarm-html)

## Development

To watch for changes in the source code and recompile the library on change:

```bash
npm start
```

## Build

To build the library:

```bash
npm run build
```
Loading

0 comments on commit 287edee

Please sign in to comment.