diff --git a/cli/auth.go b/cli/auth.go
new file mode 100644
index 00000000000..f4b5ea13299
--- /dev/null
+++ b/cli/auth.go
@@ -0,0 +1,41 @@
+package cli
+
+import (
+ "fmt"
+
+ "gopkg.in/urfave/cli.v2"
+
+ "github.com/filecoin-project/go-lotus/api"
+)
+
+var authCmd = &cli.Command{
+ Name: "auth",
+ Usage: "Manage RPC permissions",
+ Subcommands: []*cli.Command{
+ authCreateAdminToken,
+ },
+}
+
+var authCreateAdminToken = &cli.Command{
+ Name: "create-admin-token",
+ Usage: "Create admin token",
+ Action: func(cctx *cli.Context) error {
+ napi, err := GetFullNodeAPI(cctx)
+ if err != nil {
+ return err
+ }
+ ctx := ReqContext(cctx)
+
+ // TODO: Probably tell the user how powerful this token is
+
+ token, err := napi.AuthNew(ctx, api.AllPermissions)
+ if err != nil {
+ return err
+ }
+
+ // TODO: Log in audit log when it is implemented
+
+ fmt.Println(string(token))
+ return nil
+ },
+}
diff --git a/cli/cmd.go b/cli/cmd.go
index afeec86b929..631d0d49dc6 100644
--- a/cli/cmd.go
+++ b/cli/cmd.go
@@ -110,6 +110,7 @@ func ReqContext(cctx *cli.Context) context.Context {
}
var Commands = []*cli.Command{
+ authCmd,
chainCmd,
clientCmd,
createMinerCmd,
diff --git a/lotuspond/front/package-lock.json b/lotuspond/front/package-lock.json
index 10b714fb5b3..907aea84d27 100644
--- a/lotuspond/front/package-lock.json
+++ b/lotuspond/front/package-lock.json
@@ -5816,6 +5816,11 @@
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE="
},
+ "gud": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
+ "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
+ },
"gzip-size": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.0.0.tgz",
@@ -5957,6 +5962,19 @@
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
},
+ "history": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
+ "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "loose-envify": "^1.2.0",
+ "resolve-pathname": "^3.0.0",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0",
+ "value-equal": "^1.0.1"
+ }
+ },
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -8378,6 +8396,16 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
},
+ "mini-create-react-context": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz",
+ "integrity": "sha512-2v+OeetEyliMt5VHMXsBhABoJ0/M4RCe7fatd/fBy6SMiKazUSEt3gxxypfnk2SHMkdBYvorHRoQxuGoiwbzAw==",
+ "requires": {
+ "@babel/runtime": "^7.4.0",
+ "gud": "^1.0.0",
+ "tiny-warning": "^1.0.2"
+ }
+ },
"mini-css-extract-plugin": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz",
@@ -10521,6 +10549,60 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA=="
},
+ "react-router": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.0.1.tgz",
+ "integrity": "sha512-EM7suCPNKb1NxcTZ2LEOWFtQBQRQXecLxVpdsP4DW4PbbqYWeRiLyV/Tt1SdCrvT2jcyXAXmVTmzvSzrPR63Bg==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "history": "^4.9.0",
+ "hoist-non-react-statics": "^3.1.0",
+ "loose-envify": "^1.3.1",
+ "mini-create-react-context": "^0.3.0",
+ "path-to-regexp": "^1.7.0",
+ "prop-types": "^15.6.2",
+ "react-is": "^16.6.0",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0"
+ },
+ "dependencies": {
+ "hoist-non-react-statics": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz",
+ "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==",
+ "requires": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "path-to-regexp": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
+ "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
+ "requires": {
+ "isarray": "0.0.1"
+ }
+ }
+ }
+ },
+ "react-router-dom": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.0.1.tgz",
+ "integrity": "sha512-zaVHSy7NN0G91/Bz9GD4owex5+eop+KvgbxXsP/O+iW1/Ln+BrJ8QiIR5a6xNPtrdTvLkxqlDClx13QO1uB8CA==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "history": "^4.9.0",
+ "loose-envify": "^1.3.1",
+ "prop-types": "^15.6.2",
+ "react-router": "5.0.1",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0"
+ }
+ },
"react-scripts": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.0.1.tgz",
@@ -10887,6 +10969,11 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
},
+ "resolve-pathname": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
+ "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
+ },
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -12083,6 +12170,16 @@
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
},
+ "tiny-invariant": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.6.tgz",
+ "integrity": "sha512-FOyLWWVjG+aC0UqG76V53yAWdXfH8bO6FNmyZOuUrzDzK8DI3/JRY25UD7+g49JWM1LXwymsKERB+DzI0dTEQA=="
+ },
+ "tiny-warning": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
+ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
+ },
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -12478,6 +12575,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "value-equal": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
+ "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
+ },
"varint": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/varint/-/varint-5.0.0.tgz",
diff --git a/lotuspond/front/package.json b/lotuspond/front/package.json
index e1adde73a78..a5f3976125a 100644
--- a/lotuspond/front/package.json
+++ b/lotuspond/front/package.json
@@ -11,6 +11,7 @@
"react": "^16.8.6",
"react-cristal": "^0.0.12",
"react-dom": "^16.8.6",
+ "react-router-dom": "^5.0.1",
"react-scripts": "3.0.1",
"rpc-websockets": "^4.5.1",
"styled-components": "^3.3.3",
diff --git a/lotuspond/front/src/Address.js b/lotuspond/front/src/Address.js
index 3b98b0f6f68..b41f3cdcb7c 100644
--- a/lotuspond/front/src/Address.js
+++ b/lotuspond/front/src/Address.js
@@ -105,7 +105,7 @@ class Address extends React.Component {
}
addr = sheet.sheet.insertRule(`.pondaddr-${this.props.addr}, .pondaddr-${this.props.addr} * { color: #11ee11; }`, 0)}
+ onMouseEnter={() => sheet.sheet.insertRule(`.pondaddr-${this.props.addr}, .pondaddr-${this.props.addr} * { color: #11ee11 !important; }`, 0)}
onMouseLeave={() => sheet.sheet.deleteRule(0)}
>{addr}
diff --git a/lotuspond/front/src/App.css b/lotuspond/front/src/App.css
index 02f4c2a8834..2cbf61f5f54 100644
--- a/lotuspond/front/src/App.css
+++ b/lotuspond/front/src/App.css
@@ -1,11 +1,129 @@
+.Index {
+ width: 100vw;
+ height: 100vh;
+ background: #1a1a1a;
+ color: #f0f0f0;
+ font-family: monospace;
+
+ display: grid;
+ grid-template-columns: auto 40vw auto;
+ grid-template-rows: auto auto auto 3em;
+ grid-template-areas:
+ ". . ."
+ ". main ."
+ ". . ."
+ "footer footer footer";
+}
+
+.Index-footer {
+ background: #2a2a2a;
+ grid-area: footer;
+}
+
+.Index-footer > div {
+ padding-left: 0.7em;
+ padding-top: 0.7em;
+}
+
+.Index-nodes {
+ grid-area: main;
+ background: #2a2a2a;
+}
+
+.Index-node {
+ margin: 5px;
+ padding: 15px;
+ background: #1f1f1f;
+}
+
+.Index-addwrap {
+ margin-top: 5px;
+}
+
+/* SingleNode */
+
+
+.SingleNode-connecting {
+ width: 100vw;
+ height: 100vh;
+
+ background: #1a1a1a;
+ color: #ffffff;
+ font-family: monospace;
+
+ display: grid;
+ grid-template-columns: auto min-content auto;
+ grid-template-rows: auto min-content auto;
+ grid-template-areas:
+ ". . ."
+ ". main ."
+ ". . ."
+}
+
+.SingleNode-connecting > div {
+ grid-area: main;
+ padding: 15px;
+ white-space: nowrap;
+ background: #2a2a2a;
+}
+
+
+
+/*****/
+
+a:link {
+ color: #50f020;
+}
+
+a:visited {
+ color: #50f020;
+}
+
+a:hover {
+ color: #30a00a;
+}
+
+.Button {
+ display: inline-block;
+ padding: 15px;
+ background: #1f1f1f;
+ margin-left: 5px;
+}
+
+.Window {
+ background: #2a2a2a !important;
+ color: #e0e0e0;
+}
+
+.Window b {
+ color: #f0f0f0;
+}
+
+.Window > :first-child > :nth-child(2)::before {
+ background: #f0f0f0;
+}
+
+.Window > :first-child > :nth-child(2)::after {
+ background: #f0f0f0;
+}
+
+.Window a:link {
+ color: #30a015;
+}
+
+.Window a:visited {
+ color: #30a015;
+}
+
+/* POND */
+
.App {
min-height: 100vh;
- background: #b7c4cd;
+ background: #1a1a1a;
font-family: monospace;
}
.NodeList {
- background: #f9be77;
user-select: text;
font-family: monospace;
min-width: 40em;
@@ -13,7 +131,6 @@
}
.FullNode {
- background: #f9be77;
user-select: text;
font-family: monospace;
min-width: 50em;
@@ -25,7 +142,6 @@
}
.StorageNode {
- background: #f9be77;
user-select: text;
font-family: monospace;
min-width: 40em;
@@ -33,7 +149,6 @@
}
.Block {
- background: #f9be77;
user-select: text;
font-family: monospace;
min-width: 50em;
@@ -41,7 +156,6 @@
}
.State {
- background: #f9be77;
user-select: text;
font-family: monospace;
min-width: 40em;
@@ -49,7 +163,6 @@
}
.Client {
- background: #f9be77;
user-select: text;
font-family: monospace;
display: inline-block;
@@ -68,19 +181,20 @@
.ChainExplorer {
font-family: monospace;
+ color: #d0d0d0;
}
.ChainExplorer-at {
min-width: 40em;
- background: #77ff77;
+ background: #222222;
}
.ChainExplorer-after {
- background: #cc9c44
+ background: #440000
}
.ChainExplorer-before {
- background: #cccc00
+ background: #444400
}
.Logs {
diff --git a/lotuspond/front/src/App.js b/lotuspond/front/src/App.js
index e2ea90732bd..e5761e0830f 100644
--- a/lotuspond/front/src/App.js
+++ b/lotuspond/front/src/App.js
@@ -1,53 +1,96 @@
import React from 'react';
import './App.css';
-import { Client } from 'rpc-websockets'
-import NodeList from "./NodeList";
+import { BrowserRouter as Router, Route, Link } from "react-router-dom";
+import Pond from "./Pond";
+import SingleNode from "./SingleNode";
-
-class App extends React.Component {
+class Index extends React.Component {
constructor(props) {
super(props)
- const client = new Client('ws://127.0.0.1:2222/rpc/v0')
- client.on('open', () => {
- this.setState(() => ({client: client}))
- })
+ this.state = {rpcUrl: "ws://127.0.0.1:1234/rpc/v0", rpcToken: ''}
- this.state = {
- windows: {},
- nextWindow: 0,
+ const initialState = JSON.parse(window.localStorage.getItem('saved-nodes'))
+ if (initialState) {
+ this.state.nodes = initialState
+ } else {
+ this.state.nodes = []
}
-
- this.mountWindow = this.mountWindow.bind(this)
}
- mountWindow(cb) {
- const id = this.state.nextWindow
- this.setState({nextWindow: id + 1})
-
- const window = cb(() => {
- this.setState(prev => ({windows: {...prev.windows, [id]: undefined}}))
- })
+ componentDidUpdate(prevProps, prevState, snapshot) {
+ window.localStorage.setItem('saved-nodes', JSON.stringify(this.state.nodes))
+ }
- this.setState(prev => ({windows: {...prev.windows, [id]: window}}))
+ onAdd = () => {
+ this.setState({addingNode: true})
}
- render() {
- if (this.state.client === undefined) {
+ update = (name) => (e) => this.setState({ [name]: e.target.value })
+
+ tokenOk = () => {
+ let m = this.state.rpcToken.match(/\.(.+)\./)
+ // TODO: eww
+ if(m && atob(m[1]) === '{"Allow":["read","write","sign","admin"]}') {
return (
+ -Token OK-
lotus auth create-admin-token
): {this.tokenOk()}
+ {keys.slice(0, -1).map((i) => ( | {i} | ))}