From f241e7191d151aefc83f63ff52f708abd2f34fd5 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 23 May 2019 12:43:55 +0200 Subject: [PATCH] Introduce the enable() interface (prompts user) (#20) * Introduce the enable() interface * Provider * Add auth requests to state * injector comments * Background extension list, spprove & reject * Cleanups * Untested, but the UI parts are there (test next) * linting * Not pretty, but seems to auth * Small styling adjustments * Adjust Box layout slightly * Small styling adjustments * signing -> transactions * isDanger for links * Styling defaults --- README.md | 44 +++-- .../src/Popup/Accounts/Account.tsx | 7 +- .../src/Popup/Authorize/Request.tsx | 56 ++++++ .../src/Popup/Authorize/index.tsx | 33 ++++ packages/extension-ui/src/Popup/Create.tsx | 4 +- packages/extension-ui/src/Popup/Forget.tsx | 4 +- packages/extension-ui/src/Popup/Import.tsx | 4 +- .../src/Popup/Signing/Request.tsx | 12 +- .../extension-ui/src/Popup/Signing/Unlock.tsx | 1 + .../extension-ui/src/Popup/Signing/index.tsx | 10 +- packages/extension-ui/src/Popup/index.tsx | 43 +++-- packages/extension-ui/src/components/Box.tsx | 5 +- .../extension-ui/src/components/Header.tsx | 1 - packages/extension-ui/src/components/Link.tsx | 52 +++++ packages/extension-ui/src/components/Tip.tsx | 1 + packages/extension-ui/src/components/View.tsx | 15 -- .../extension-ui/src/components/contexts.tsx | 28 ++- .../extension-ui/src/components/defaults.ts | 8 +- packages/extension-ui/src/components/index.ts | 1 + packages/extension-ui/src/components/types.ts | 5 +- packages/extension-ui/src/messaging.ts | 20 +- packages/extension-ui/src/partials/Back.tsx | 3 +- packages/extension/public/popup.html | 2 +- .../extension/src/background/RawPayload.ts | 49 +---- .../src/background/handlers/Extension.ts | 53 +++++- .../background/handlers/SigningRequests.ts | 64 ------- .../src/background/handlers/State.ts | 178 ++++++++++++++++++ .../extension/src/background/handlers/Tabs.ts | 30 +-- .../src/background/handlers/index.ts | 8 +- packages/extension/src/background/types.ts | 16 +- packages/extension/src/inject/Injected.ts | 6 +- packages/extension/src/inject/index.ts | 51 +++-- packages/extension/src/inject/types.ts | 12 +- packages/extension/webpack.config.js | 3 +- 34 files changed, 582 insertions(+), 247 deletions(-) create mode 100644 packages/extension-ui/src/Popup/Authorize/Request.tsx create mode 100644 packages/extension-ui/src/Popup/Authorize/index.tsx create mode 100644 packages/extension-ui/src/components/Link.tsx delete mode 100644 packages/extension/src/background/handlers/SigningRequests.ts create mode 100644 packages/extension/src/background/handlers/State.ts diff --git a/README.md b/README.md index 46141338..a8cf7184 100644 --- a/README.md +++ b/README.md @@ -24,29 +24,45 @@ Once added, you can create an account (via a generated seed) or import via an ex The extension injects `injectedWeb3` into the global `window` object, exposing the following: ```js -// a version that identifies the actual injection version (future-use) -type Version = 0; +window.injectedWeb3 = { + // this is the name for this extension, there could be multiples injected, + // each with their own keys + 'polkadot-js': { + // same as above, just easier to manage having accessible here + name: 'polkadot-js', + // semver for the package + version: '0.1.0', -// an interface describing an account -interface Account { - readonly address: string; // ss-58 encoded address - readonly name?: string; // optional name for display + // this is called to enable the injection, and returns an injected + // object containing the accounts, signer and provider interfaces + // (or it will reject if not authorized) + enable (originName: string): Promise + } +} +``` + +When there is more than one extension, each will populate an entry above, so from an extension implementation perspective, the structure should not be overridded. The injected interface, when returned via `enable`, contains the following - + +```js +interface Injected { + readonly accounts: Accounts; + readonly signer: Signer; + // not injected as of yet, subscriptable provider for polkadot-js injection + // readonly provider: Provider } // exposes accounts interface Accounts { - get: () => Promise>; + get (): Promise>; } // a signer that communicates with the extension via sendMessage interface Signer extends SignerInterface { - // no specific signer extensions -} - -interface Injected { - readonly accounts: Accounts; - readonly signer: Signer; - readonly version: Version; + // no specific signer extensions, exposes the `sign` interface for use by + // the polkadot-js API } ``` diff --git a/packages/extension-ui/src/Popup/Accounts/Account.tsx b/packages/extension-ui/src/Popup/Accounts/Account.tsx index 23148a07..292c1341 100644 --- a/packages/extension-ui/src/Popup/Accounts/Account.tsx +++ b/packages/extension-ui/src/Popup/Accounts/Account.tsx @@ -5,9 +5,8 @@ import { OnActionFromCtx } from '../../components/types'; import React, { useState } from 'react'; -import { Link } from 'react-router-dom'; -import { ActionBar, Address, withAction } from '../../components'; +import { ActionBar, Address, Link, withOnAction } from '../../components'; import { editAccount } from '../../messaging'; import { Name } from '../../partials'; @@ -53,11 +52,11 @@ function Account ({ address, className, onAction }: Props) { } > - Edit + Edit Forget ); } -export default withAction(Account); +export default withOnAction(Account); diff --git a/packages/extension-ui/src/Popup/Authorize/Request.tsx b/packages/extension-ui/src/Popup/Authorize/Request.tsx new file mode 100644 index 00000000..17e25067 --- /dev/null +++ b/packages/extension-ui/src/Popup/Authorize/Request.tsx @@ -0,0 +1,56 @@ +// Copyright 2019 @polkadot/extension-ui authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { MessageAuthorize } from '@polkadot/extension/background/types'; +import { OnActionFromCtx } from '../../components/types'; + +import React from 'react'; +import styled from 'styled-components'; + +import { ActionBar, Box, Button, Link, defaults, withOnAction } from '../../components'; +import { approveAuthRequest, rejectAuthRequest } from '../../messaging'; + +type Props = { + authId: number, + className?: string, + isFirst: boolean, + onAction: OnActionFromCtx, + request: MessageAuthorize, + url: string +}; + +function Request ({ authId, className, isFirst, onAction, request: { origin }, url }: Props) { + const onApprove = (): Promise => + approveAuthRequest(authId) + .then(() => onAction()) + .catch(console.error); + const onReject = (): void => { + rejectAuthRequest(authId) + .then(() => onAction()) + .catch(console.error); + }; + + return ( + +
The application, identified as
{origin}
is requesting access from
{url}
to the accounts and signing capabilities of this extension. Only approve the request if you trust the application.
+ + Reject + + {isFirst && ( +