Upgrade to material ui 4
Add user management and roles - TBA Menu Label Renames - TBA
This commit is contained in:
parent
685420aaed
commit
0c630f0f93
571
interface/package-lock.json
generated
571
interface/package-lock.json
generated
@ -890,68 +890,105 @@
|
||||
"resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz",
|
||||
"integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw=="
|
||||
},
|
||||
"@emotion/hash": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.7.1.tgz",
|
||||
"integrity": "sha512-OYpa/Sg+2GDX+jibUfpZVn1YqSVRpYmTLF2eyAfrFTIJSbwyIrc+YscayoykvaOME/wV4BV0Sa0yqdMrgse6mA=="
|
||||
},
|
||||
"@material-ui/core": {
|
||||
"version": "3.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-3.9.3.tgz",
|
||||
"integrity": "sha512-REIj62+zEvTgI/C//YL4fZxrCVIySygmpZglsu/Nl5jPqy3CDjZv1F9ubBYorHqmRgeVPh64EghMMWqk4egmfg==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.0.0.tgz",
|
||||
"integrity": "sha512-mLEGTuzgUALRKFI3hkRcS0gi/cB3XV0JA4F5PT3rGUt7Dc4liu8/IGiHF7iQh+p337FMk8vkEMxMVdYd9JXKMQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.2.0",
|
||||
"@material-ui/system": "^3.0.0-alpha.0",
|
||||
"@material-ui/utils": "^3.0.0-alpha.2",
|
||||
"@types/jss": "^9.5.6",
|
||||
"@types/react-transition-group": "^2.0.8",
|
||||
"brcast": "^3.0.1",
|
||||
"classnames": "^2.2.5",
|
||||
"@material-ui/styles": "^4.0.0",
|
||||
"@material-ui/system": "^4.0.0",
|
||||
"@material-ui/types": "^4.0.0",
|
||||
"@material-ui/utils": "^4.0.0",
|
||||
"@types/react-transition-group": "^2.0.16",
|
||||
"clsx": "^1.0.2",
|
||||
"convert-css-length": "^1.0.2",
|
||||
"csstype": "^2.5.2",
|
||||
"debounce": "^1.1.0",
|
||||
"deepmerge": "^3.0.0",
|
||||
"dom-helpers": "^3.2.1",
|
||||
"hoist-non-react-statics": "^3.2.1",
|
||||
"is-plain-object": "^2.0.4",
|
||||
"jss": "^9.8.7",
|
||||
"jss-camel-case": "^6.0.0",
|
||||
"jss-default-unit": "^8.0.2",
|
||||
"jss-global": "^3.0.0",
|
||||
"jss-nested": "^6.0.1",
|
||||
"jss-props-sort": "^6.0.0",
|
||||
"jss-vendor-prefixer": "^7.0.0",
|
||||
"normalize-scroll-left": "^0.1.2",
|
||||
"popper.js": "^1.14.1",
|
||||
"prop-types": "^15.6.0",
|
||||
"react-event-listener": "^0.6.2",
|
||||
"react-transition-group": "^2.2.1",
|
||||
"recompose": "0.28.0 - 0.30.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-event-listener": "^0.6.6",
|
||||
"react-transition-group": "^4.0.0",
|
||||
"warning": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"@material-ui/icons": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-3.0.2.tgz",
|
||||
"integrity": "sha512-QY/3gJnObZQ3O/e6WjH+0ah2M3MOgLOzCy8HTUoUx9B6dDrS18vP7Ycw3qrDEKlB6q1KNxy6CZHm5FCauWGy2g==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.0.0.tgz",
|
||||
"integrity": "sha512-hXoKnVLmVer+kic84ypoyG3Amym3a8q3pvDg4KYjeKW9fxGru7x/IkelBJODQL0jO+nAPz1+9RNpFWC75v35dg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.2.0"
|
||||
}
|
||||
},
|
||||
"@material-ui/styles": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.0.0.tgz",
|
||||
"integrity": "sha512-TUpmXlyZDVOl6E2//+UzsZxgi2E+2L753QY02nNkbAC6PPx8FUBqvnjYSGqX0V/BjTJ/fD4CkoS6ZpY3lHf+Gg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.2.0",
|
||||
"recompose": "0.28.0 - 0.30.0"
|
||||
"@emotion/hash": "^0.7.1",
|
||||
"@material-ui/types": "^4.0.0",
|
||||
"@material-ui/utils": "^4.0.0",
|
||||
"clsx": "^1.0.2",
|
||||
"deepmerge": "^3.0.0",
|
||||
"hoist-non-react-statics": "^3.2.1",
|
||||
"jss": "^10.0.0-alpha.16",
|
||||
"jss-plugin-camel-case": "^10.0.0-alpha.16",
|
||||
"jss-plugin-default-unit": "^10.0.0-alpha.16",
|
||||
"jss-plugin-global": "^10.0.0-alpha.16",
|
||||
"jss-plugin-nested": "^10.0.0-alpha.16",
|
||||
"jss-plugin-props-sort": "^10.0.0-alpha.16",
|
||||
"jss-plugin-rule-value-function": "^10.0.0-alpha.16",
|
||||
"jss-plugin-vendor-prefixer": "^10.0.0-alpha.16",
|
||||
"prop-types": "^15.7.2",
|
||||
"warning": "^4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"jss": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-HmKNNnr82TR5jkWjBcbrx/uim2ief588pWp7zsf4GQpL125zRkEaWYL1SXv5bR6bBvAoTtvJsTAOxDIlLxUNZg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@material-ui/system": {
|
||||
"version": "3.0.0-alpha.2",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-3.0.0-alpha.2.tgz",
|
||||
"integrity": "sha512-odmxQ0peKpP7RQBQ8koly06YhsPzcoVib1vByVPBH4QhwqBXuYoqlCjt02846fYspAqkrWzjxnWUD311EBbxOA==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.0.0.tgz",
|
||||
"integrity": "sha512-SIsqIwjix98Mqw9LVAmRqTs10E4S/SP5n5mlBlhHVHI+2XG2c+MaCPzOF2Zxq0KdqOMgTb7/aevR3mG9UmODxg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.2.0",
|
||||
"deepmerge": "^3.0.0",
|
||||
"prop-types": "^15.6.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"warning": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"@material-ui/types": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/types/-/types-4.0.0.tgz",
|
||||
"integrity": "sha512-wuiQMo8nSljZR1oWh57UQYssdtFqaU+Cbhr16uLohzzTllpCAK4LkH0slnH3n+5vCa2dgOdNlZTrmsIDDwvRJQ=="
|
||||
},
|
||||
"@material-ui/utils": {
|
||||
"version": "3.0.0-alpha.3",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-3.0.0-alpha.3.tgz",
|
||||
"integrity": "sha512-rwMdMZptX0DivkqBuC+Jdq7BYTXwqKai5G5ejPpuEDKpWzi1Oxp+LygGw329FrKpuKeiqpcymlqJTjmy+quWng==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.0.0.tgz",
|
||||
"integrity": "sha512-gjz52hO1hkIbKPMng1diQybVgtfgCptOCrulUs4emSCHHKUoR1zfT+IUrjgOaKIpYZNOgS/CI7KDMp689+FzeQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.2.0",
|
||||
"prop-types": "^15.6.0",
|
||||
"react-is": "^16.6.3"
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^16.8.0"
|
||||
}
|
||||
},
|
||||
"@mrmlnc/readdir-enhanced": {
|
||||
@ -1107,24 +1144,15 @@
|
||||
"loader-utils": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"@types/jss": {
|
||||
"version": "9.5.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/jss/-/jss-9.5.8.tgz",
|
||||
"integrity": "sha512-bBbHvjhm42UKki+wZpR89j73ykSXg99/bhuKuYYePtpma3ZAnmeGnl0WxXiZhPGsIfzKwCUkpPC0jlrVMBfRxA==",
|
||||
"requires": {
|
||||
"csstype": "^2.0.0",
|
||||
"indefinite-observable": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "11.13.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.4.tgz",
|
||||
"integrity": "sha512-+rabAZZ3Yn7tF/XPGHupKIL5EcAbrLxnTr/hgQICxbeuAfWtT0UZSfULE+ndusckBItcv4o6ZeOJplQikVcLvQ=="
|
||||
},
|
||||
"@types/prop-types": {
|
||||
"version": "15.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.0.tgz",
|
||||
"integrity": "sha512-eItQyV43bj4rR3JPV0Skpl1SncRCdziTEK9/v8VwXmV6d/qOUO8/EuWeHBbCZcsfSHfzI5UyMJLCSXtxxznyZg=="
|
||||
"version": "15.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz",
|
||||
"integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg=="
|
||||
},
|
||||
"@types/q": {
|
||||
"version": "1.5.2",
|
||||
@ -1132,18 +1160,18 @@
|
||||
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw=="
|
||||
},
|
||||
"@types/react": {
|
||||
"version": "16.8.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.13.tgz",
|
||||
"integrity": "sha512-otJ4ntMuHGrvm67CdDJMAls4WqotmAmW0g3HmWi9LCjSWXrxoXY/nHXrtmMfvPEEmGFNm6NdgMsJmnfH820Qaw==",
|
||||
"version": "16.8.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.18.tgz",
|
||||
"integrity": "sha512-lUXdKzRqWR4FebR5tGHkLCqnvQJS4fdXKCBrNGGbglqZg2gpU+J82pMONevQODUotATs9fc9k66bx3/St8vReg==",
|
||||
"requires": {
|
||||
"@types/prop-types": "*",
|
||||
"csstype": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"@types/react-transition-group": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-2.9.0.tgz",
|
||||
"integrity": "sha512-hP7vUaZMVSWKxo133P8U51U6UZ7+pbY+eAQb8+p6SZ2rB1rj3mOTDgTzhhi+R2SCB4S+sWekAAGoxdiZPG0ReQ==",
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-2.9.1.tgz",
|
||||
"integrity": "sha512-1usq4DRUVBFnxc9KGJAlJO9EpQrLZGDDEC8wDOn2+2ODSyudYo8FiIzPDRaX/hfQjHqGeeoNaNdA2bj0l35hZQ==",
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
@ -2686,11 +2714,6 @@
|
||||
"repeat-element": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"brcast": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.1.tgz",
|
||||
"integrity": "sha512-eI3yqf9YEqyGl9PCNTR46MGvDylGtaHjalcz6Q3fAPnP/PhpKkkve52vFdfGpwp4VUvK6LUr4TQN+2stCrEwTg=="
|
||||
},
|
||||
"brorand": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
||||
@ -2960,11 +2983,6 @@
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"change-emitter": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz",
|
||||
"integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU="
|
||||
},
|
||||
"chardet": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
||||
@ -3616,11 +3634,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"classnames": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
|
||||
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
|
||||
},
|
||||
"clean-css": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
|
||||
@ -3679,6 +3692,11 @@
|
||||
"shallow-clone": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"clsx": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.0.4.tgz",
|
||||
"integrity": "sha512-1mQ557MIZTrL/140j+JVdRM6e31/OA4vTYxXgqIIZlndyfjHpyawKZia1Im05Vp9BWmImkcNrNtFYQMyFcgJDg=="
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||
@ -3859,6 +3877,11 @@
|
||||
"date-now": "^0.1.4"
|
||||
}
|
||||
},
|
||||
"console-polyfill": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/console-polyfill/-/console-polyfill-0.1.2.tgz",
|
||||
"integrity": "sha1-ls/tUcr3gYn2mVcubxgnHcN8DjA="
|
||||
},
|
||||
"constants-browserify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
|
||||
@ -3879,6 +3902,15 @@
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||
},
|
||||
"convert-css-length": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/convert-css-length/-/convert-css-length-1.0.2.tgz",
|
||||
"integrity": "sha512-ecV7j3hXyXN1X2XfJBzhMR0o1Obv0v3nHmn0UiS3ACENrzbxE/EknkiunS/fCwQva0U62X1GChi8GaPh4oTlLg==",
|
||||
"requires": {
|
||||
"console-polyfill": "^0.1.2",
|
||||
"parse-unit": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"convert-source-map": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
|
||||
@ -4257,14 +4289,6 @@
|
||||
"resolved": "https://registry.npmjs.org/css-url-regex/-/css-url-regex-1.1.0.tgz",
|
||||
"integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w="
|
||||
},
|
||||
"css-vendor": {
|
||||
"version": "0.3.8",
|
||||
"resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz",
|
||||
"integrity": "sha1-ZCHP0wNM5mT+dnOXL9ARn8KJQfo=",
|
||||
"requires": {
|
||||
"is-in-browser": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"css-what": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
|
||||
@ -4449,9 +4473,9 @@
|
||||
}
|
||||
},
|
||||
"csstype": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.3.tgz",
|
||||
"integrity": "sha512-rINUZXOkcBmoHWEyu7JdHu5JMzkGRoMX4ov9830WNgxf5UYxcBUO0QTKAqeJ5EZfSdlrcJYkC8WwfVW7JYi4yg=="
|
||||
"version": "2.6.4",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.4.tgz",
|
||||
"integrity": "sha512-lAJUJP3M6HxFXbqtGRc0iZrdyeN+WzOWeY0q/VnFzI+kqVrYIzC7bWlKqCW7oCIdzoPkvfp82EVvrTlQ8zsWQg=="
|
||||
},
|
||||
"cyclist": {
|
||||
"version": "0.2.2",
|
||||
@ -7993,14 +8017,6 @@
|
||||
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
||||
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
|
||||
},
|
||||
"indefinite-observable": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-1.0.2.tgz",
|
||||
"integrity": "sha512-Mps0898zEduHyPhb7UCgNmfzlqNZknVmaFz5qzr0mm04YQ5FGLhAyK/dJ+NaRxGyR6juQXIxh5Ev0xx+qq0nYA==",
|
||||
"requires": {
|
||||
"symbol-observable": "1.2.0"
|
||||
}
|
||||
},
|
||||
"indexes-of": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
|
||||
@ -8230,11 +8246,6 @@
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
|
||||
},
|
||||
"is-function": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz",
|
||||
"integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU="
|
||||
},
|
||||
"is-generator-fn": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz",
|
||||
@ -9195,148 +9206,242 @@
|
||||
}
|
||||
},
|
||||
"jss": {
|
||||
"version": "9.8.7",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz",
|
||||
"integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==",
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-HmKNNnr82TR5jkWjBcbrx/uim2ief588pWp7zsf4GQpL125zRkEaWYL1SXv5bR6bBvAoTtvJsTAOxDIlLxUNZg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"symbol-observable": "^1.1.0",
|
||||
"warning": "^3.0.0"
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"jss-plugin-camel-case": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-nki+smHEsFyoZ0OlOYtaxVqcQA0ZHVJCE1slRnk+1TklbmxbBiO4TwITMTEaNIDv0U0Uyb0Z8wVgFgRwCCIFog==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"hyphenate-style-name": "^1.0.3",
|
||||
"jss": "10.0.0-alpha.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"warning": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
|
||||
"integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
|
||||
"jss": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-HmKNNnr82TR5jkWjBcbrx/uim2ief588pWp7zsf4GQpL125zRkEaWYL1SXv5bR6bBvAoTtvJsTAOxDIlLxUNZg==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jss-camel-case": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-6.1.0.tgz",
|
||||
"integrity": "sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ==",
|
||||
"jss-plugin-compose": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-compose/-/jss-plugin-compose-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-MeOc5RuDSqB3czoUFM32pBq370+sKKjG1K4aamVWpAUWpsphLi/YlotrFOkk/FCb2So1ga4W7/zrCc/50OeRAQ==",
|
||||
"requires": {
|
||||
"hyphenate-style-name": "^1.0.2"
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.0.0-alpha.16",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"jss-compose": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-compose/-/jss-compose-5.0.0.tgz",
|
||||
"integrity": "sha512-YofRYuiA0+VbeOw0VjgkyO380sA4+TWDrW52nSluD9n+1FWOlDzNbgpZ/Sb3Y46+DcAbOS21W5jo6SAqUEiuwA==",
|
||||
"jss-plugin-default-unit": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-jjGW4F/r9yKvoyUk22M8nWhdMfvoWzJw/oFO2cDRXCk2onnWFiRALfqeUsEDyocwdZbyVF9WhZbSHn4GL03kSw==",
|
||||
"requires": {
|
||||
"warning": "^3.0.0"
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.0.0-alpha.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"warning": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
|
||||
"integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
|
||||
"jss": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-HmKNNnr82TR5jkWjBcbrx/uim2ief588pWp7zsf4GQpL125zRkEaWYL1SXv5bR6bBvAoTtvJsTAOxDIlLxUNZg==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jss-default-unit": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-8.0.2.tgz",
|
||||
"integrity": "sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg=="
|
||||
},
|
||||
"jss-expand": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-expand/-/jss-expand-5.3.0.tgz",
|
||||
"integrity": "sha512-NiM4TbDVE0ykXSAw6dfFmB1LIqXP/jdd0ZMnlvlGgEMkMt+weJIl8Ynq1DsuBY9WwkNyzWktdqcEW2VN0RAtQg=="
|
||||
},
|
||||
"jss-extend": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-extend/-/jss-extend-6.2.0.tgz",
|
||||
"integrity": "sha512-YszrmcB6o9HOsKPszK7NeDBNNjVyiW864jfoiHoMlgMIg2qlxKw70axZHqgczXHDcoyi/0/ikP1XaHDPRvYtEA==",
|
||||
"jss-plugin-expand": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-expand/-/jss-plugin-expand-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-Q3m0PDWGojfcmWBCkegRJxonq2q9lI6ZfixoFgvTvi+b9zKza0KXkHBUzGjeFyM36U/WRWj43SC33dajcI9jAg==",
|
||||
"requires": {
|
||||
"warning": "^3.0.0"
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.0.0-alpha.16"
|
||||
}
|
||||
},
|
||||
"jss-plugin-extend": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-extend/-/jss-plugin-extend-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-nJ8H5b/dBZlqaPYCLNmcaHRQgzSlnAwhZUcIo30s0IgvhTtN/TaiRtEbrJZjfXPzatTsnFoRwZzJqs8Sakev+A==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.0.0-alpha.16",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"jss-plugin-global": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-B1mm2ZF9OEsWPmzkG5ZUXqV88smDqpc4unILLXhWVuj0U5JeT0DNitH+QbXFrSueDJzkWVfvqyckvWDR/0qeDg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.0.0-alpha.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"warning": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
|
||||
"integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
|
||||
"jss": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-HmKNNnr82TR5jkWjBcbrx/uim2ief588pWp7zsf4GQpL125zRkEaWYL1SXv5bR6bBvAoTtvJsTAOxDIlLxUNZg==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jss-global": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-global/-/jss-global-3.0.0.tgz",
|
||||
"integrity": "sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q=="
|
||||
},
|
||||
"jss-nested": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-6.0.1.tgz",
|
||||
"integrity": "sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA==",
|
||||
"jss-plugin-nested": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-3l/MB6COnIpq4GOXQFae6UydoaIPa81UxhuBTEQuiAojgTeUla9L7nB3h18Q4zAhQQpjxaEsyppAKuEzIP7kPQ==",
|
||||
"requires": {
|
||||
"warning": "^3.0.0"
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.0.0-alpha.16",
|
||||
"tiny-warning": "^1.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"warning": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
|
||||
"integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
|
||||
"jss": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-HmKNNnr82TR5jkWjBcbrx/uim2ief588pWp7zsf4GQpL125zRkEaWYL1SXv5bR6bBvAoTtvJsTAOxDIlLxUNZg==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jss-plugin-props-sort": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-+Yn9nugHAH58nf/d43H2uxMvlCFPDgLKRSmKO4Q4m1IGYjMbHsWt1Rk2HfC9IiCanqcqpc8hstwtzf+HG7PWFQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.0.0-alpha.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"jss": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-HmKNNnr82TR5jkWjBcbrx/uim2ief588pWp7zsf4GQpL125zRkEaWYL1SXv5bR6bBvAoTtvJsTAOxDIlLxUNZg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jss-plugin-rule-value-function": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-MQap9ne6ZGZH0NlpSQTMSm6QalBTF0hYpd2uaGQwam+GlT7IKeO+sTjd46I1WgO3kyOmwb0pIY6CnuLQGXKtSA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.0.0-alpha.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"jss": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-HmKNNnr82TR5jkWjBcbrx/uim2ief588pWp7zsf4GQpL125zRkEaWYL1SXv5bR6bBvAoTtvJsTAOxDIlLxUNZg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jss-plugin-rule-value-observable": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-rule-value-observable/-/jss-plugin-rule-value-observable-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-Gmj1sVKWM2KVZpG0Wn3Z+SArvskdXEtSCrww43g/OO+j8DN9O+UEV47tM/HYfdiyLICnvKHc2XGmhNz9LHcpNQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.0.0-alpha.16",
|
||||
"symbol-observable": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"jss-plugin-template": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-template/-/jss-plugin-template-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-L1epTMTDINJPUZkFuyohCXQtJDTMj1CNTBv9ysqVyMc3qjkifAvPEws6XuoRSC9jy1ZvqDTWlxPfbmoJ2r6BWg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.0.0-alpha.16",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"jss-plugin-vendor-prefixer": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-70yJ6QE5dN8VlPUGKld5jK2SKyrteheEL/ismexpybIufunMs6iJgkhDndbOfv8ia13yZgUVqeakMdhRKYwK1A==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"css-vendor": "^2.0.1",
|
||||
"jss": "10.0.0-alpha.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"css-vendor": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.2.tgz",
|
||||
"integrity": "sha512-Xn5ZAlI00d8HaQ8/oQ8d+iBzSF//NCc77LPzsucM32X/R/yTqmXy6otVsAM0XleXk6HjPuXoVZwXsayky/fsFQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"is-in-browser": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"jss": {
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-HmKNNnr82TR5jkWjBcbrx/uim2ief588pWp7zsf4GQpL125zRkEaWYL1SXv5bR6bBvAoTtvJsTAOxDIlLxUNZg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jss-preset-default": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-4.5.0.tgz",
|
||||
"integrity": "sha512-qZbpRVtHT7hBPpZEBPFfafZKWmq3tA/An5RNqywDsZQGrlinIF/mGD9lmj6jGqu8GrED2SMHZ3pPKLmjCZoiaQ==",
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-YBq2XE4iJdl16klxfw0xTaKksfAIXSoC2kPZQ4dmw4n/KMFOz/A26eN30FwWixyObfDMKyZp94vwCKal7711IQ==",
|
||||
"requires": {
|
||||
"jss-camel-case": "^6.1.0",
|
||||
"jss-compose": "^5.0.0",
|
||||
"jss-default-unit": "^8.0.2",
|
||||
"jss-expand": "^5.3.0",
|
||||
"jss-extend": "^6.2.0",
|
||||
"jss-global": "^3.0.0",
|
||||
"jss-nested": "^6.0.1",
|
||||
"jss-props-sort": "^6.0.0",
|
||||
"jss-template": "^1.0.1",
|
||||
"jss-vendor-prefixer": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"jss-props-sort": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-6.0.0.tgz",
|
||||
"integrity": "sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g=="
|
||||
},
|
||||
"jss-template": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jss-template/-/jss-template-1.0.1.tgz",
|
||||
"integrity": "sha512-m5BqEWha17fmIVXm1z8xbJhY6GFJxNB9H68GVnCWPyGYfxiAgY9WTQyvDAVj+pYRgrXSOfN5V1T4+SzN1sJTeg==",
|
||||
"requires": {
|
||||
"warning": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"warning": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
|
||||
"integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jss-vendor-prefixer": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz",
|
||||
"integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==",
|
||||
"requires": {
|
||||
"css-vendor": "^0.3.8"
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.0.0-alpha.16",
|
||||
"jss-plugin-camel-case": "10.0.0-alpha.16",
|
||||
"jss-plugin-compose": "10.0.0-alpha.16",
|
||||
"jss-plugin-default-unit": "10.0.0-alpha.16",
|
||||
"jss-plugin-expand": "10.0.0-alpha.16",
|
||||
"jss-plugin-extend": "10.0.0-alpha.16",
|
||||
"jss-plugin-global": "10.0.0-alpha.16",
|
||||
"jss-plugin-nested": "10.0.0-alpha.16",
|
||||
"jss-plugin-props-sort": "10.0.0-alpha.16",
|
||||
"jss-plugin-rule-value-function": "10.0.0-alpha.16",
|
||||
"jss-plugin-rule-value-observable": "10.0.0-alpha.16",
|
||||
"jss-plugin-template": "10.0.0-alpha.16",
|
||||
"jss-plugin-vendor-prefixer": "10.0.0-alpha.16"
|
||||
}
|
||||
},
|
||||
"jsx-ast-utils": {
|
||||
@ -10455,6 +10560,11 @@
|
||||
"json-parse-better-errors": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"parse-unit": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parse-unit/-/parse-unit-1.0.1.tgz",
|
||||
"integrity": "sha1-fhu21b7zh0wo45JSaiVBFwKR7s8="
|
||||
},
|
||||
"parse5": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
|
||||
@ -13013,6 +13123,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-display-name": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-display-name/-/react-display-name-0.2.4.tgz",
|
||||
"integrity": "sha512-zvU6iouW+SWwHTyThwxGICjJYCMZFk/6r/+jmOdC7ntQoPlS/Pqb81MkxaMf2bHTSq9TN3K3zX2/ayMW/jCtyA=="
|
||||
},
|
||||
"react-dom": {
|
||||
"version": "16.8.6",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz",
|
||||
@ -13054,22 +13169,17 @@
|
||||
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA=="
|
||||
},
|
||||
"react-jss": {
|
||||
"version": "8.6.1",
|
||||
"resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.6.1.tgz",
|
||||
"integrity": "sha512-SH6XrJDJkAphp602J14JTy3puB2Zxz1FkM3bKVE8wON+va99jnUTKWnzGECb3NfIn9JPR5vHykge7K3/A747xQ==",
|
||||
"version": "10.0.0-alpha.16",
|
||||
"resolved": "https://registry.npmjs.org/react-jss/-/react-jss-10.0.0-alpha.16.tgz",
|
||||
"integrity": "sha512-nGIerGVDV9V6cpRXhkJZgoV0MsoJbKMdAiCoPzCDnsdR+om6zLyhQEvVHNtd0mB16dO+pzNaovhBvElhdj/3ug==",
|
||||
"requires": {
|
||||
"hoist-non-react-statics": "^2.5.0",
|
||||
"jss": "^9.7.0",
|
||||
"jss-preset-default": "^4.3.0",
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"hoist-non-react-statics": "^3.2.0",
|
||||
"jss": "10.0.0-alpha.16",
|
||||
"jss-preset-default": "10.0.0-alpha.16",
|
||||
"prop-types": "^15.6.0",
|
||||
"theming": "^1.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"hoist-non-react-statics": {
|
||||
"version": "2.5.5",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
|
||||
"integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
|
||||
}
|
||||
"theming": "^3.0.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"react-lifecycles-compat": {
|
||||
@ -13171,14 +13281,13 @@
|
||||
}
|
||||
},
|
||||
"react-transition-group": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
|
||||
"integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.0.1.tgz",
|
||||
"integrity": "sha512-SsLcBYhO4afXJC9esL8XMxi/y0ZvEc7To0TvtrBELqzpjXQHPZOTxvuPh2/4EhYc0uSMfp2SExIxsyJ0pBdNzg==",
|
||||
"requires": {
|
||||
"dom-helpers": "^3.4.0",
|
||||
"loose-envify": "^1.4.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-lifecycles-compat": "^3.0.4"
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"read-pkg": {
|
||||
@ -13514,26 +13623,6 @@
|
||||
"util.promisify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"recompose": {
|
||||
"version": "0.30.0",
|
||||
"resolved": "https://registry.npmjs.org/recompose/-/recompose-0.30.0.tgz",
|
||||
"integrity": "sha512-ZTrzzUDa9AqUIhRk4KmVFihH0rapdCSMFXjhHbNrjAWxBuUD/guYlyysMnuHjlZC/KRiOKRtB4jf96yYSkKE8w==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"change-emitter": "^0.1.2",
|
||||
"fbjs": "^0.8.1",
|
||||
"hoist-non-react-statics": "^2.3.1",
|
||||
"react-lifecycles-compat": "^3.0.2",
|
||||
"symbol-observable": "^1.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"hoist-non-react-statics": {
|
||||
"version": "2.5.5",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
|
||||
"integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"recursive-readdir": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
|
||||
@ -15184,14 +15273,14 @@
|
||||
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
|
||||
},
|
||||
"theming": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/theming/-/theming-1.3.0.tgz",
|
||||
"integrity": "sha512-ya5Ef7XDGbTPBv5ENTwrwkPUexrlPeiAg/EI9kdlUAZhNlRbCdhMKRgjNX1IcmsmiPcqDQZE6BpSaH+cr31FKw==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/theming/-/theming-3.2.0.tgz",
|
||||
"integrity": "sha512-n0fSNYXkX63rcFBBeAthy14IcgPZLHp0OGkGZheaj64j7cBoP7INLd6+7HIXqWVjFn1M5cYSiZ1nszi+jo/Szg==",
|
||||
"requires": {
|
||||
"brcast": "^3.0.1",
|
||||
"is-function": "^1.0.1",
|
||||
"is-plain-object": "^2.0.1",
|
||||
"prop-types": "^15.5.8"
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"prop-types": "^15.5.8",
|
||||
"react-display-name": "^0.2.4",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"throat": {
|
||||
|
@ -3,8 +3,8 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@material-ui/core": "^3.9.3",
|
||||
"@material-ui/icons": "^3.0.2",
|
||||
"@material-ui/core": "^4.0.0",
|
||||
"@material-ui/icons": "^4.0.0",
|
||||
"compression-webpack-plugin": "^2.0.0",
|
||||
"jwt-decode": "^2.2.0",
|
||||
"moment": "^2.24.0",
|
||||
@ -12,7 +12,7 @@
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-form-validator-core": "^0.6.2",
|
||||
"react-jss": "^8.6.1",
|
||||
"react-jss": "^10.0.0-alpha.16",
|
||||
"react-material-ui-form-validator": "^2.0.7",
|
||||
"react-router": "^5.0.0",
|
||||
"react-router-dom": "^5.0.0",
|
||||
|
@ -10,14 +10,12 @@ import orange from '@material-ui/core/colors/orange';
|
||||
import red from '@material-ui/core/colors/red';
|
||||
import green from '@material-ui/core/colors/green';
|
||||
|
||||
import JssProvider from 'react-jss/lib/JssProvider';
|
||||
import { create } from 'jss';
|
||||
import { StylesProvider, jssPreset } from '@material-ui/styles';
|
||||
|
||||
import {
|
||||
MuiThemeProvider,
|
||||
createMuiTheme,
|
||||
createGenerateClassName,
|
||||
jssPreset,
|
||||
createMuiTheme
|
||||
} from '@material-ui/core/styles';
|
||||
|
||||
// Our theme
|
||||
@ -35,20 +33,17 @@ const theme = createMuiTheme({
|
||||
// JSS instance
|
||||
const jss = create(jssPreset());
|
||||
|
||||
// Class name generator.
|
||||
const generateClassName = createGenerateClassName();
|
||||
|
||||
class App extends Component {
|
||||
render() {
|
||||
return (
|
||||
<JssProvider jss={jss} generateClassName={generateClassName}>
|
||||
<StylesProvider jss={jss}>
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<SnackbarNotification>
|
||||
<CssBaseline />
|
||||
<AppRouting />
|
||||
</SnackbarNotification>
|
||||
</MuiThemeProvider>
|
||||
</JssProvider>
|
||||
</StylesProvider>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import NTPConfiguration from './containers/NTPConfiguration';
|
||||
import OTAConfiguration from './containers/OTAConfiguration';
|
||||
import APConfiguration from './containers/APConfiguration';
|
||||
import SignInPage from './containers/SignInPage';
|
||||
import UserConfiguration from './containers/UserConfiguration';
|
||||
import Security from './containers/Security';
|
||||
|
||||
class AppRouting extends Component {
|
||||
|
||||
@ -31,7 +31,7 @@ class AppRouting extends Component {
|
||||
<AuthenticatedRoute exact path="/ap-configuration" component={APConfiguration} />
|
||||
<AuthenticatedRoute exact path="/ntp-configuration" component={NTPConfiguration} />
|
||||
<AuthenticatedRoute exact path="/ota-configuration" component={OTAConfiguration} />
|
||||
<AuthenticatedRoute exact path="/user-configuration" component={UserConfiguration} />
|
||||
<AuthenticatedRoute exact path="/security" component={Security} />
|
||||
<Redirect to="/" />
|
||||
</Switch>
|
||||
</AuthenticationWrapper>
|
||||
|
@ -22,7 +22,7 @@ import SystemUpdateIcon from '@material-ui/icons/SystemUpdate';
|
||||
import AccessTimeIcon from '@material-ui/icons/AccessTime';
|
||||
import AccountCircleIcon from '@material-ui/icons/AccountCircle';
|
||||
import SettingsInputAntennaIcon from '@material-ui/icons/SettingsInputAntenna';
|
||||
import PeopleIcon from '@material-ui/icons/People';
|
||||
import LockIcon from '@material-ui/icons/Lock';
|
||||
|
||||
import { APP_NAME } from '../constants/App';
|
||||
import { withAuthenticationContext } from '../authentication/Context.js';
|
||||
@ -112,31 +112,31 @@ class MenuAppBar extends React.Component {
|
||||
<ListItemIcon>
|
||||
<WifiIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="WiFi Configuration" />
|
||||
<ListItemText primary="WiFi Connection" />
|
||||
</ListItem>
|
||||
<ListItem button component={Link} to='/ap-configuration'>
|
||||
<ListItemIcon>
|
||||
<SettingsInputAntennaIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="AP Configuration" />
|
||||
<ListItemText primary="Access Point" />
|
||||
</ListItem>
|
||||
<ListItem button component={Link} to='/ntp-configuration'>
|
||||
<ListItemIcon>
|
||||
<AccessTimeIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="NTP Configuration" />
|
||||
<ListItemText primary="Network Time" />
|
||||
</ListItem>
|
||||
<ListItem button component={Link} to='/ota-configuration'>
|
||||
<ListItemIcon>
|
||||
<SystemUpdateIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="OTA Configuration" />
|
||||
<ListItemText primary="OTA Updates" />
|
||||
</ListItem>
|
||||
<ListItem button component={Link} to='/user-configuration'>
|
||||
<ListItem button component={Link} to='/security'>
|
||||
<ListItemIcon>
|
||||
<PeopleIcon />
|
||||
<LockIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="User Configuration" />
|
||||
<ListItemText primary="Security" />
|
||||
</ListItem>
|
||||
<Divider />
|
||||
<ListItem button onClick={authenticationContext.signOut}>
|
||||
|
@ -16,7 +16,7 @@ function SectionContent(props) {
|
||||
const { children, classes, title } = props;
|
||||
return (
|
||||
<Paper className={classes.content}>
|
||||
<Typography variant="h4">
|
||||
<Typography variant="h6">
|
||||
{title}
|
||||
</Typography>
|
||||
{children}
|
||||
|
@ -7,17 +7,18 @@ import Typography from '@material-ui/core/Typography';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
||||
import Avatar from '@material-ui/core/Avatar';
|
||||
import Divider from '@material-ui/core/Divider';
|
||||
import SettingsInputAntennaIcon from '@material-ui/icons/SettingsInputAntenna';
|
||||
import DeviceHubIcon from '@material-ui/icons/DeviceHub';
|
||||
import ComputerIcon from '@material-ui/icons/Computer';
|
||||
|
||||
import {restComponent} from '../components/RestComponent';
|
||||
import { restComponent } from '../components/RestComponent';
|
||||
import SectionContent from '../components/SectionContent'
|
||||
|
||||
import * as Highlight from '../constants/Highlight';
|
||||
import { AP_STATUS_ENDPOINT } from '../constants/Endpoints';
|
||||
import { AP_STATUS_ENDPOINT } from '../constants/Endpoints';
|
||||
|
||||
const styles = theme => ({
|
||||
["apStatus_" + Highlight.SUCCESS]: {
|
||||
@ -42,40 +43,48 @@ class APStatus extends Component {
|
||||
this.props.loadData();
|
||||
}
|
||||
|
||||
apStatusHighlight(data){
|
||||
apStatusHighlight(data) {
|
||||
return data.active ? Highlight.SUCCESS : Highlight.IDLE;
|
||||
}
|
||||
|
||||
apStatus(data){
|
||||
apStatus(data) {
|
||||
return data.active ? "Active" : "Inactive";
|
||||
}
|
||||
|
||||
createListItems(data, classes){
|
||||
createListItems(data, classes) {
|
||||
return (
|
||||
<Fragment>
|
||||
<ListItem>
|
||||
<Avatar className={classes["apStatus_" + this.apStatusHighlight(data)]}>
|
||||
<SettingsInputAntennaIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar className={classes["apStatus_" + this.apStatusHighlight(data)]}>
|
||||
<SettingsInputAntennaIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="Status" secondary={this.apStatus(data)} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<Avatar>IP</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>IP</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="IP Address" secondary={data.ip_address} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<DeviceHubIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<DeviceHubIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="MAC Address" secondary={data.mac_address} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<ComputerIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<ComputerIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="AP Clients" secondary={data.station_num} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
@ -83,8 +92,8 @@ class APStatus extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderAPStatus(data, classes){
|
||||
return (
|
||||
renderAPStatus(data, classes) {
|
||||
return (
|
||||
<div>
|
||||
<List>
|
||||
<Fragment>
|
||||
@ -99,30 +108,30 @@ class APStatus extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data, fetched, errorMessage, classes } = this.props;
|
||||
const { data, fetched, errorMessage, classes } = this.props;
|
||||
|
||||
return (
|
||||
<SectionContent title="AP Status">
|
||||
{
|
||||
!fetched ?
|
||||
<div>
|
||||
<LinearProgress className={classes.fetching}/>
|
||||
<Typography variant="h4" className={classes.fetching}>
|
||||
Loading...
|
||||
!fetched ?
|
||||
<div>
|
||||
<LinearProgress className={classes.fetching} />
|
||||
<Typography variant="h4" className={classes.fetching}>
|
||||
Loading...
|
||||
</Typography>
|
||||
</div>
|
||||
:
|
||||
data ? this.renderAPStatus(data, classes)
|
||||
:
|
||||
<div>
|
||||
<Typography variant="h4" className={classes.fetching}>
|
||||
{errorMessage}
|
||||
</Typography>
|
||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
||||
Refresh
|
||||
</div>
|
||||
:
|
||||
data ? this.renderAPStatus(data, classes)
|
||||
:
|
||||
<div>
|
||||
<Typography variant="h4" className={classes.fetching}>
|
||||
{errorMessage}
|
||||
</Typography>
|
||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
||||
Refresh
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</SectionContent>
|
||||
)
|
||||
}
|
||||
|
@ -1,30 +1,27 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { USERS_ENDPOINT } from '../constants/Endpoints';
|
||||
import {restComponent} from '../components/RestComponent';
|
||||
import SectionContent from '../components/SectionContent';
|
||||
import { USERS_ENDPOINT } from '../constants/Endpoints';
|
||||
import { restComponent } from '../components/RestComponent';
|
||||
import ManageUsersForm from '../forms/ManageUsersForm';
|
||||
|
||||
class ManageUsers extends Component {
|
||||
|
||||
componentDidMount() {
|
||||
this.props.loadData();
|
||||
this.props.loadData();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data, fetched, errorMessage } = this.props;
|
||||
return (
|
||||
<SectionContent title="Manage Users">
|
||||
<ManageUsersForm
|
||||
users={data}
|
||||
usersFetched={fetched}
|
||||
errorMessage={errorMessage}
|
||||
onSubmit={this.props.saveData}
|
||||
onReset={this.props.loadData}
|
||||
handleValueChange={this.props.handleValueChange}
|
||||
handleCheckboxChange={this.props.handleCheckboxChange}
|
||||
/>
|
||||
</SectionContent>
|
||||
<ManageUsersForm
|
||||
userData={data}
|
||||
userDataFetched={fetched}
|
||||
errorMessage={errorMessage}
|
||||
onSubmit={this.props.saveData}
|
||||
onReset={this.props.loadData}
|
||||
setData={this.props.setData}
|
||||
handleValueChange={this.props.handleValueChange}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import LinearProgress from '@material-ui/core/LinearProgress';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import Avatar from '@material-ui/core/Avatar';
|
||||
import Divider from '@material-ui/core/Divider';
|
||||
@ -16,10 +17,10 @@ import TimerIcon from '@material-ui/icons/Timer';
|
||||
import UpdateIcon from '@material-ui/icons/Update';
|
||||
import AvTimerIcon from '@material-ui/icons/AvTimer';
|
||||
|
||||
import { isSynchronized, ntpStatusHighlight, ntpStatus } from '../constants/NTPStatus';
|
||||
import { isSynchronized, ntpStatusHighlight, ntpStatus } from '../constants/NTPStatus';
|
||||
import * as Highlight from '../constants/Highlight';
|
||||
import { unixTimeToTimeAndDate } from '../constants/TimeFormat';
|
||||
import { NTP_STATUS_ENDPOINT } from '../constants/Endpoints';
|
||||
import { NTP_STATUS_ENDPOINT } from '../constants/Endpoints';
|
||||
import { restComponent } from '../components/RestComponent';
|
||||
import SectionContent from '../components/SectionContent';
|
||||
|
||||
@ -51,52 +52,61 @@ class NTPStatus extends Component {
|
||||
this.props.loadData();
|
||||
}
|
||||
|
||||
createListItems(data, classes){
|
||||
createListItems(data, classes) {
|
||||
return (
|
||||
<Fragment>
|
||||
<ListItem>
|
||||
<Avatar className={classes["ntpStatus_" + ntpStatusHighlight(data)]}>
|
||||
<UpdateIcon />
|
||||
</Avatar>
|
||||
<ListItem >
|
||||
<ListItemAvatar>
|
||||
<Avatar className={classes["ntpStatus_" + ntpStatusHighlight(data)]}>
|
||||
<UpdateIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="Status" secondary={ntpStatus(data)} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
{ isSynchronized(data) &&
|
||||
{isSynchronized(data) &&
|
||||
<Fragment>
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<AccessTimeIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<AccessTimeIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="Time Now" secondary={unixTimeToTimeAndDate(data.now)} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<SwapVerticalCircleIcon />
|
||||
</Avatar>
|
||||
<ListItemText primary="Last Sync" secondary={data.last_sync > 0 ? unixTimeToTimeAndDate(data.last_sync) : "never" } />
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<SwapVerticalCircleIcon />
|
||||
</Avatar></ListItemAvatar>
|
||||
<ListItemText primary="Last Sync" secondary={data.last_sync > 0 ? unixTimeToTimeAndDate(data.last_sync) : "never"} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
</Fragment>
|
||||
}
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<DNSIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<DNSIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="NTP Server" secondary={data.server} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<TimerIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<TimerIcon />
|
||||
</Avatar></ListItemAvatar>
|
||||
<ListItemText primary="Sync Interval" secondary={moment.duration(data.interval, 'seconds').humanize()} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<AvTimerIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<AvTimerIcon />
|
||||
</Avatar></ListItemAvatar>
|
||||
<ListItemText primary="Uptime" secondary={moment.duration(data.uptime, 'seconds').humanize()} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
@ -104,8 +114,8 @@ class NTPStatus extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderNTPStatus(data, classes){
|
||||
return (
|
||||
renderNTPStatus(data, classes) {
|
||||
return (
|
||||
<div>
|
||||
<List>
|
||||
{this.createListItems(data, classes)}
|
||||
@ -118,30 +128,30 @@ class NTPStatus extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data, fetched, errorMessage, classes } = this.props;
|
||||
const { data, fetched, errorMessage, classes } = this.props;
|
||||
|
||||
return (
|
||||
<SectionContent title="NTP Status">
|
||||
{
|
||||
!fetched ?
|
||||
<div>
|
||||
<LinearProgress className={classes.fetching}/>
|
||||
<Typography variant="h4" className={classes.fetching}>
|
||||
Loading...
|
||||
!fetched ?
|
||||
<div>
|
||||
<LinearProgress className={classes.fetching} />
|
||||
<Typography variant="h4" className={classes.fetching}>
|
||||
Loading...
|
||||
</Typography>
|
||||
</div>
|
||||
:
|
||||
data ? this.renderNTPStatus(data, classes)
|
||||
:
|
||||
<div>
|
||||
<Typography variant="h4" className={classes.fetching}>
|
||||
{errorMessage}
|
||||
</Typography>
|
||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
||||
Refresh
|
||||
</div>
|
||||
:
|
||||
data ? this.renderNTPStatus(data, classes)
|
||||
:
|
||||
<div>
|
||||
<Typography variant="h4" className={classes.fetching}>
|
||||
{errorMessage}
|
||||
</Typography>
|
||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
||||
Refresh
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</SectionContent>
|
||||
)
|
||||
}
|
||||
|
@ -2,14 +2,14 @@ import React, { Component } from 'react';
|
||||
import MenuAppBar from '../components/MenuAppBar';
|
||||
import ManageUsers from './ManageUsers';
|
||||
|
||||
class UserConfiguration extends Component {
|
||||
class Security extends Component {
|
||||
render() {
|
||||
return (
|
||||
<MenuAppBar sectionTitle="User Configuration">
|
||||
<MenuAppBar sectionTitle="Security">
|
||||
<ManageUsers />
|
||||
</MenuAppBar>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UserConfiguration
|
||||
export default Security
|
@ -8,6 +8,7 @@ import Typography from '@material-ui/core/Typography';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
||||
|
||||
import Avatar from '@material-ui/core/Avatar';
|
||||
import Divider from '@material-ui/core/Divider';
|
||||
@ -63,9 +64,11 @@ class WiFiStatus extends Component {
|
||||
return (
|
||||
<Fragment>
|
||||
<ListItem>
|
||||
<Avatar className={classes["wifiStatus_" + connectionStatusHighlight(data)]}>
|
||||
<WifiIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar className={classes["wifiStatus_" + connectionStatusHighlight(data)]}>
|
||||
<WifiIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="Connection Status" secondary={connectionStatus(data)} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
@ -73,40 +76,52 @@ class WiFiStatus extends Component {
|
||||
isConnected(data) &&
|
||||
<Fragment>
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<SettingsInputAntennaIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<SettingsInputAntennaIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="SSID" secondary={data.ssid} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<Avatar>IP</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>IP</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="IP Address" secondary={data.local_ip} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<DeviceHubIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<DeviceHubIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="MAC Address" secondary={data.mac_address} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<Avatar>#</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>#</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="Subnet Mask" secondary={data.subnet_mask} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<SettingsInputComponentIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<SettingsInputComponentIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="Gateway IP" secondary={data.gateway_ip ? data.gateway_ip : "none"} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<DNSIcon />
|
||||
</Avatar>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<DNSIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="DNS Server IP" secondary={this.dnsServers(data)} />
|
||||
</ListItem>
|
||||
<Divider variant="inset" component="li" />
|
||||
|
@ -1,23 +1,26 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { ValidatorForm } from 'react-material-ui-form-validator';
|
||||
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import LinearProgress from '@material-ui/core/LinearProgress';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
import Table from '@material-ui/core/Table';
|
||||
import TableBody from '@material-ui/core/TableBody';
|
||||
import TableCell from '@material-ui/core/TableCell';
|
||||
import TableFooter from '@material-ui/core/TableFooter';
|
||||
import TableHead from '@material-ui/core/TableHead';
|
||||
import TableRow from '@material-ui/core/TableRow';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import Chip from '@material-ui/core/Chip';
|
||||
|
||||
import EditIcon from '@material-ui/icons/Edit';
|
||||
import DeleteIcon from '@material-ui/icons/Delete';
|
||||
import Chip from '@material-ui/core/Chip';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
|
||||
import SectionContent from '../components/SectionContent';
|
||||
import UserForm from './UserForm';
|
||||
|
||||
const styles = theme => ({
|
||||
loadingSettings: {
|
||||
@ -43,95 +46,198 @@ const styles = theme => ({
|
||||
margin: theme.spacing.unit,
|
||||
},
|
||||
table: {
|
||||
'& td, & th': {padding: theme.spacing.unit}
|
||||
'& td, & th': { padding: theme.spacing.unit }
|
||||
},
|
||||
actions: {
|
||||
color: theme.palette.text.secondary,
|
||||
}
|
||||
});
|
||||
|
||||
function compareUsers(a, b) {
|
||||
if (a.username < b.username) {
|
||||
return -1;
|
||||
}
|
||||
if (a.username > b.username) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
class ManageUsersForm extends React.Component {
|
||||
|
||||
render() {
|
||||
const { classes, users, usersFetched, errorMessage, onSubmit, onReset } = this.props;
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
!usersFetched ?
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
createUser = () => {
|
||||
this.setState({
|
||||
creating: true,
|
||||
user: {
|
||||
username: "",
|
||||
password: "",
|
||||
roles: []
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
uniqueUsername = username => {
|
||||
return !this.props.userData.users.find(u => u.username === username);
|
||||
}
|
||||
|
||||
usersValid = username => {
|
||||
return !!this.props.userData.users.find(u => u.roles.includes("admin"));
|
||||
}
|
||||
|
||||
startEditingUser = user => {
|
||||
this.setState({
|
||||
creating: false,
|
||||
user
|
||||
});
|
||||
};
|
||||
|
||||
cancelEditingUser = () => {
|
||||
this.setState({
|
||||
user: undefined
|
||||
});
|
||||
}
|
||||
|
||||
sortedUsers(users) {
|
||||
return users.sort(compareUsers);
|
||||
}
|
||||
|
||||
doneEditingUser = () => {
|
||||
const { user } = this.state;
|
||||
const { userData } = this.props;
|
||||
let { users } = userData;
|
||||
users = users.filter(u => u.username !== user.username);
|
||||
users.push(user);
|
||||
this.props.setData({ ...userData, users });
|
||||
this.setState({
|
||||
user: undefined
|
||||
});
|
||||
};
|
||||
|
||||
handleUserValueChange = name => event => {
|
||||
const { user } = this.state;
|
||||
if (user) {
|
||||
this.setState({
|
||||
user: {
|
||||
...user, [name]: event.target.value
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { classes, userData, userDataFetched, errorMessage, onSubmit, onReset, handleValueChange } = this.props;
|
||||
const { user, creating } = this.state;
|
||||
return (
|
||||
<SectionContent title="Manage Users">
|
||||
{
|
||||
!userDataFetched ?
|
||||
<div className={classes.loadingSettings}>
|
||||
<LinearProgress className={classes.loadingSettingsDetails} />
|
||||
<Typography variant="h4" className={classes.loadingSettingsDetails}>
|
||||
Loading...
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
: users ?
|
||||
|
||||
<ValidatorForm onSubmit={onSubmit}>
|
||||
<Table className={classes.table}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Username</TableCell>
|
||||
<TableCell>Password</TableCell>
|
||||
<TableCell align="center">Role(s)</TableCell>
|
||||
<TableCell align="center">Action</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{users.users.map(user => (
|
||||
<TableRow key={user.username}>
|
||||
<TableCell component="th" scope="row">
|
||||
{user.username}
|
||||
</TableCell>
|
||||
<TableCell>{user.password}</TableCell>
|
||||
<TableCell align="center">
|
||||
<Chip label={user.role} className={classes.chip} />
|
||||
:
|
||||
userData ?
|
||||
user ?
|
||||
<UserForm
|
||||
user={user}
|
||||
creating={creating}
|
||||
roles={userData.roles}
|
||||
onDoneEditing={this.doneEditingUser}
|
||||
onCancelEditing={this.cancelEditingUser}
|
||||
handleValueChange={this.handleUserValueChange}
|
||||
uniqueUsername={this.uniqueUsername}
|
||||
/>
|
||||
:
|
||||
<ValidatorForm onSubmit={onSubmit}>
|
||||
<Table className={classes.table}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Username</TableCell>
|
||||
<TableCell align="center">Role(s)</TableCell>
|
||||
<TableCell align="center">Action</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{this.sortedUsers(userData.users).map(user => (
|
||||
<TableRow key={user.username}>
|
||||
<TableCell component="th" scope="row">
|
||||
{user.username}
|
||||
</TableCell>
|
||||
<TableCell align="center">
|
||||
{
|
||||
user.roles.map(role => (
|
||||
<Chip label={role} className={classes.chip} />
|
||||
))
|
||||
}
|
||||
</TableCell>
|
||||
<TableCell align="center">
|
||||
<IconButton aria-label="Delete">
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
<IconButton aria-label="Edit" onClick={() => this.startEditingUser(user)}>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
<TableFooter>
|
||||
<TableRow>
|
||||
<TableCell colSpan={2}>
|
||||
{
|
||||
!this.usersValid() &&
|
||||
<Typography variant="body1" color="error">
|
||||
You must have at least one admin user configured.
|
||||
</Typography>
|
||||
}
|
||||
</TableCell>
|
||||
<TableCell align="center">
|
||||
<IconButton aria-label="Delete">
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
<IconButton aria-label="Edit">
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.createUser}>
|
||||
Add User
|
||||
</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
||||
Save
|
||||
</Button>
|
||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||
Reset
|
||||
</Button>
|
||||
|
||||
</ValidatorForm>
|
||||
|
||||
</TableFooter>
|
||||
</Table>
|
||||
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
||||
Save
|
||||
</Button>
|
||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||
Reset
|
||||
</Button>
|
||||
</ValidatorForm>
|
||||
:
|
||||
|
||||
<div className={classes.loadingSettings}>
|
||||
<SectionContent title="Manage Users">
|
||||
<Typography variant="h4" className={classes.loadingSettingsDetails}>
|
||||
{errorMessage}
|
||||
</Typography>
|
||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||
Reset
|
||||
</Button>
|
||||
</div>
|
||||
</Button>
|
||||
</SectionContent>
|
||||
}
|
||||
</div>
|
||||
</SectionContent>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ManageUsersForm.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
users: PropTypes.object,
|
||||
usersFetched: PropTypes.bool.isRequired,
|
||||
userData: PropTypes.object,
|
||||
userDataFetched: PropTypes.bool.isRequired,
|
||||
errorMessage: PropTypes.string,
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
onReset: PropTypes.func.isRequired,
|
||||
handleValueChange: PropTypes.func.isRequired,
|
||||
handleCheckboxChange: PropTypes.func.isRequired,
|
||||
setData: PropTypes.func.isRequired,
|
||||
handleValueChange: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default withStyles(styles)(ManageUsersForm);
|
||||
|
112
interface/src/forms/UserForm.js
Normal file
112
interface/src/forms/UserForm.js
Normal file
@ -0,0 +1,112 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
|
||||
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
||||
import PasswordValidator from '../components/PasswordValidator';
|
||||
|
||||
import Input from '@material-ui/core/Input';
|
||||
import InputLabel from '@material-ui/core/InputLabel';
|
||||
import MenuItem from '@material-ui/core/MenuItem';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
import Select from '@material-ui/core/Select';
|
||||
import Chip from '@material-ui/core/Chip';
|
||||
|
||||
const styles = theme => ({
|
||||
textField: {
|
||||
width: "100%"
|
||||
},
|
||||
checkboxControl: {
|
||||
width: "100%"
|
||||
},
|
||||
chips: {
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
chip: {
|
||||
marginRight: theme.spacing.unit,
|
||||
},
|
||||
button: {
|
||||
marginRight: theme.spacing.unit * 2,
|
||||
marginTop: theme.spacing.unit * 2,
|
||||
}
|
||||
});
|
||||
|
||||
class UserForm extends React.Component {
|
||||
|
||||
componentWillMount() {
|
||||
ValidatorForm.addValidationRule('uniqueUsername', this.props.uniqueUsername);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes, user, roles, creating, handleValueChange, onDoneEditing, onCancelEditing } = this.props;
|
||||
return (
|
||||
<ValidatorForm onSubmit={onDoneEditing}>
|
||||
<TextValidator
|
||||
validators={creating ? ['required', 'uniqueUsername', 'matchRegexp:^[a-zA-Z0-9_\\.]{1,24}$'] : []}
|
||||
errorMessages={creating ? ['Username is required', "That username already exists", "Must be 1-24 characters: alpha numberic, '_' or '.'"] : []}
|
||||
name="username"
|
||||
label="Username"
|
||||
className={classes.textField}
|
||||
value={user.username}
|
||||
disabled={!creating}
|
||||
onChange={handleValueChange('username')}
|
||||
margin="normal"
|
||||
/>
|
||||
<PasswordValidator
|
||||
validators={['required', 'matchRegexp:^.{0,64}$']}
|
||||
errorMessages={['Password is required', 'Password must be 64 characters or less']}
|
||||
name="password"
|
||||
label="Password"
|
||||
className={classes.textField}
|
||||
value={user.password}
|
||||
onChange={handleValueChange('password')}
|
||||
margin="normal"
|
||||
/>
|
||||
<FormControl className={classes.textField}>
|
||||
<InputLabel htmlFor="roles">Roles</InputLabel>
|
||||
<Select
|
||||
multiple
|
||||
value={user.roles}
|
||||
onChange={handleValueChange('roles')}
|
||||
input={<Input id="roles" />}
|
||||
renderValue={selected => (
|
||||
<div className={classes.chips}>
|
||||
{selected.map(value => (
|
||||
<Chip key={value} label={value} className={classes.chip} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
{roles.map(name => (
|
||||
<MenuItem key={name} value={name}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
||||
Save
|
||||
</Button>
|
||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onCancelEditing}>
|
||||
Back
|
||||
</Button>
|
||||
</ValidatorForm>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
UserForm.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
user: PropTypes.object.isRequired,
|
||||
creating: PropTypes.bool.isRequired,
|
||||
roles: PropTypes.array.isRequired,
|
||||
onDoneEditing: PropTypes.func.isRequired,
|
||||
onCancelEditing: PropTypes.func.isRequired,
|
||||
uniqueUsername: PropTypes.func.isRequired,
|
||||
handleValueChange: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default withStyles(styles)(UserForm);
|
@ -7,10 +7,9 @@
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; http://docs.platformio.org/page/projectconf.html
|
||||
[env:esp12e]
|
||||
platform = espressif8266
|
||||
board = esp12e
|
||||
board_build.f_cpu = 160000000L
|
||||
[env:node32s]
|
||||
platform = espressif32
|
||||
board = node32s
|
||||
|
||||
framework = arduino
|
||||
;upload_flags = --port=8266 --auth=esp-react
|
||||
|
@ -1,9 +1,6 @@
|
||||
#include <SecurityManager.h>
|
||||
|
||||
SecurityManager::SecurityManager(AsyncWebServer* server, FS* fs) : SettingsPersistence(fs, SECURITY_SETTINGS_FILE) {
|
||||
server->on(USERS_PATH, HTTP_GET, std::bind(&SecurityManager::fetchUsers, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
SecurityManager::SecurityManager(AsyncWebServer* server, FS* fs) : SettingsService(server, fs, USERS_PATH, SECURITY_SETTINGS_FILE) {}
|
||||
SecurityManager::~SecurityManager() {}
|
||||
|
||||
void SecurityManager::readFromJsonObject(JsonObject& root) {
|
||||
@ -22,16 +19,19 @@ void SecurityManager::readFromJsonObject(JsonObject& root) {
|
||||
// users
|
||||
_users.clear();
|
||||
if (root["users"].is<JsonArray>()) {
|
||||
JsonArray users = root["users"];
|
||||
for (JsonVariant user : users) {
|
||||
String username = user["username"];
|
||||
String password = user["password"];
|
||||
String role = user["role"];
|
||||
_users.push_back(User(username, password, role));
|
||||
for (JsonVariant user : root["users"].as<JsonArray>()) {
|
||||
std::list<String> roles;
|
||||
if (user["roles"].is<JsonArray>()) {
|
||||
for (JsonVariant role : user["roles"].as<JsonArray>()) {
|
||||
roles.push_back(role.as<String>());
|
||||
}
|
||||
}
|
||||
_users.push_back(User(user["username"], user["password"], roles));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SecurityManager::writeToJsonObject(JsonObject& root) {
|
||||
// secret
|
||||
root["jwt_secret"] = _jwtSecret;
|
||||
@ -48,18 +48,13 @@ void SecurityManager::writeToJsonObject(JsonObject& root) {
|
||||
JsonObject user = users.createNestedObject();
|
||||
user["username"] = _user.getUsername();
|
||||
user["password"] = _user.getPassword();
|
||||
user["role"] = _user.getRole();
|
||||
JsonArray roles = user.createNestedArray("roles");
|
||||
for (String _role : _user.getRoles()){
|
||||
roles.add(_role);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityManager::fetchUsers(AsyncWebServerRequest *request) {
|
||||
AsyncJsonResponse * response = new AsyncJsonResponse(MAX_USERS_SIZE);
|
||||
JsonObject jsonObject = response->getRoot();
|
||||
writeToJsonObject(jsonObject);
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void SecurityManager::begin() {
|
||||
// read config
|
||||
readFromFS();
|
||||
@ -105,7 +100,10 @@ Authentication SecurityManager::authenticate(String username, String password) {
|
||||
|
||||
inline void populateJWTPayload(JsonObject &payload, User *user) {
|
||||
payload["username"] = user->getUsername();
|
||||
payload["role"] = user->getRole();
|
||||
JsonArray roles = payload.createNestedArray("roles");
|
||||
for (String _role : user->getRoles()){
|
||||
roles.add(_role);
|
||||
}
|
||||
}
|
||||
|
||||
boolean SecurityManager::validatePayload(JsonObject &parsedPayload, User *user) {
|
||||
|
@ -28,17 +28,17 @@ class User {
|
||||
private:
|
||||
String _username;
|
||||
String _password;
|
||||
String _role;
|
||||
std::list<String> _roles;
|
||||
public:
|
||||
User(String username, String password, String role): _username(username), _password(password), _role(role) {}
|
||||
User(String username, String password, std::list<String> roles): _username(username), _password(password), _roles(roles) {}
|
||||
String getUsername() {
|
||||
return _username;
|
||||
}
|
||||
String getPassword() {
|
||||
return _password;
|
||||
}
|
||||
String getRole() {
|
||||
return _role;
|
||||
std::list<String> getRoles() {
|
||||
return _roles;
|
||||
}
|
||||
};
|
||||
|
||||
@ -62,7 +62,7 @@ class Authentication {
|
||||
}
|
||||
};
|
||||
|
||||
class SecurityManager : public SettingsPersistence {
|
||||
class SecurityManager : public SettingsService {
|
||||
|
||||
public:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user