diff --git a/net/server/internal/api_addChannelTopicAsset.go b/net/server/internal/api_addChannelTopicAsset.go index b3a7352f..42220a33 100644 --- a/net/server/internal/api_addChannelTopicAsset.go +++ b/net/server/internal/api_addChannelTopicAsset.go @@ -172,7 +172,7 @@ func AddChannelTopicAsset(w http.ResponseWriter, r *http.Request) { func isStorageFull(act *store.Account) (full bool, err error) { - storage := getNumConfigValue(CONFIG_STORAGE, 0) * 1048576; + storage := getNumConfigValue(CONFIG_STORAGE, 0); if storage == 0 { return } diff --git a/net/server/internal/api_getNodeStatus.go b/net/server/internal/api_getNodeStatus.go index 4b71b325..7a28c2bf 100644 --- a/net/server/internal/api_getNodeStatus.go +++ b/net/server/internal/api_getNodeStatus.go @@ -18,6 +18,6 @@ func GetNodeStatus(w http.ResponseWriter, r *http.Request) { } return } - WriteResponse(w, false); + WriteResponse(w, false) } diff --git a/net/server/internal/api_setNodeStatus.go b/net/server/internal/api_setNodeStatus.go index 857b7493..2f01cf45 100644 --- a/net/server/internal/api_setNodeStatus.go +++ b/net/server/internal/api_setNodeStatus.go @@ -21,7 +21,7 @@ func SetNodeStatus(w http.ResponseWriter, r *http.Request) { } username, password, res := BasicCredentials(r); - if res != nil { + if res != nil || username != "admin" { LogMsg("invalid credenitals"); w.WriteHeader(http.StatusBadRequest) return diff --git a/net/server/internal/ucAccountConfig_test.go b/net/server/internal/ucAccountConfig_test.go index 851ec5f0..7575cfdb 100644 --- a/net/server/internal/ucAccountConfig_test.go +++ b/net/server/internal/ucAccountConfig_test.go @@ -105,6 +105,7 @@ func TestAccountConfig(t *testing.T) { assert.True(t, accountStatus.Searchable) // add asset to topic +PrintMsg("ADD TOPIC TEST"); assets = &[]Asset{} pathParams = &map[string]string{ "channelId": channel.Id, "topicId": topic.Id } assert.Error(t, ApiTestUpload(AddChannelTopicAsset, "POST", diff --git a/net/web/src/Admin/Admin.jsx b/net/web/src/Admin/Admin.jsx new file mode 100644 index 00000000..11ac293e --- /dev/null +++ b/net/web/src/Admin/Admin.jsx @@ -0,0 +1,47 @@ +import React from 'react' +import { Input, Button, Space } from 'antd'; +import { AdminWrapper, LoginWrapper, TokenInput } from './Admin.styled'; +import { useAdmin } from './useAdmin.hook'; +import { Dashboard } from './Dashboard/Dashboard'; + +export function Admin() { + + const { state, actions } = useAdmin() + + if (state.unclaimed == null) { + return <> + } + + if (state.unclaimed) { + return ( + +
+ + actions.setToken(e.target.value)} /> + + +
+
+ ); + } + + if (!state.access) { + return ( + +
+ + actions.setToken(e.target.value)} /> + + +
+
+ ); + } + + return ( + + + + ) +} + diff --git a/net/web/src/Admin/Admin.styled.js b/net/web/src/Admin/Admin.styled.js new file mode 100644 index 00000000..47fc356f --- /dev/null +++ b/net/web/src/Admin/Admin.styled.js @@ -0,0 +1,47 @@ +import { Input } from 'antd'; +import styled from 'styled-components'; + +export const AdminWrapper = styled.div` + width: 100%; + height: 100%; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + background-color: #8fbea7; + webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + .dashboard { + width: 80%; + min-width: 400px; + max-width: 800px; + max-height: 80%; + background-color: #eeeeee; + border-radius: 4px; + } +`; + +export const LoginWrapper = styled.div` + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + + .login { + padding: 8px; + display: flex; + flex-direction: row; + background-color: #eeeeee; + border-radius: 4px; + } +`; + +export const TokenInput = styled(Input.Password)` + width: 300px; +`; diff --git a/net/web/src/Admin/Dashboard/Dashboard.jsx b/net/web/src/Admin/Dashboard/Dashboard.jsx new file mode 100644 index 00000000..0be7d44e --- /dev/null +++ b/net/web/src/Admin/Dashboard/Dashboard.jsx @@ -0,0 +1,4 @@ +export function Dashboard() { + return (
DASHBOARD
); +} + diff --git a/net/web/src/Admin/useAdmin.hook.js b/net/web/src/Admin/useAdmin.hook.js new file mode 100644 index 00000000..d6d543f4 --- /dev/null +++ b/net/web/src/Admin/useAdmin.hook.js @@ -0,0 +1,62 @@ +import { useContext, useState, useEffect } from 'react'; +import { getNodeStatus } from 'api/getNodeStatus'; +import { setNodeStatus } from 'api/setNodeStatus'; +import { getNodeConfig } from 'api/getNodeConfig'; + +export function useAdmin() { + + const [state, setState] = useState({ + unclaimed: null, + access: null, + token: null, + busy: false, + }); + + const updateState = (value) => { + setState((s) => ({ ...s, ...value })); + } + + const checkStatus = async () => { + try { + let status = await getNodeStatus(); + updateState({ unclaimed: status }); + } + catch(err) { + console.log(err); + window.alert(err); + } + } + + useEffect(() => { + checkStatus(); + }, []); + + + const actions = { + setToken: (value) => { + updateState({ token: value }); + }, + setAccess: async () => { + try { + await setNodeStatus(state.token); + updateState({ access: state.token, unclaimed: false }); + } + catch(err) { + console.log(err); + window.alert(err); + } + }, + getAccess: async () => { + try { + let config = await getNodeConfig(state.token); + updateState({ access: state.token, config }); + } + catch(err) { + console.log(err); + window.alert(err); + } + }, + }; + + return { state, actions }; +} diff --git a/net/web/src/App.js b/net/web/src/App.js index a5ddbf82..c7d34b5d 100644 --- a/net/web/src/App.js +++ b/net/web/src/App.js @@ -8,6 +8,7 @@ import { CardContextProvider } from 'context/CardContext'; import { ChannelContextProvider } from 'context/ChannelContext'; import { ConversationContextProvider } from 'context/ConversationContext'; import { Home } from './Home/Home'; +import { Admin } from './Admin/Admin'; import { Login } from './Login/Login'; import { Create } from './Create/Create'; import { User } from './User/User'; @@ -35,6 +36,7 @@ function App() { } /> } /> + } /> } /> }> } /> diff --git a/net/web/src/api/getNodeConfig.js b/net/web/src/api/getNodeConfig.js new file mode 100644 index 00000000..3005a989 --- /dev/null +++ b/net/web/src/api/getNodeConfig.js @@ -0,0 +1,11 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; +var base64 = require('base-64'); + +export async function getNodeConfig(password) { + let headers = new Headers() + headers.append('Authorization', 'Basic ' + base64.encode("admin:" + password)); + let config = await fetchWithTimeout(`/admin/config`, { method: 'GET', headers }); + checkResponse(config); + return await config.json(); +} + diff --git a/net/web/src/api/getNodeStatus.js b/net/web/src/api/getNodeStatus.js new file mode 100644 index 00000000..9232bf0a --- /dev/null +++ b/net/web/src/api/getNodeStatus.js @@ -0,0 +1,8 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function getNodeStatus() { + let status = await fetchWithTimeout(`/admin/status`, { method: 'GET' }); + checkResponse(status); + return await status.json(); +} + diff --git a/net/web/src/api/setNodeStatus.js b/net/web/src/api/setNodeStatus.js new file mode 100644 index 00000000..9fffa313 --- /dev/null +++ b/net/web/src/api/setNodeStatus.js @@ -0,0 +1,10 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; +var base64 = require('base-64'); + +export async function setNodeStatus(password) { + let headers = new Headers() + headers.append('Credentials', 'Basic ' + base64.encode("admin:" + password)); + let status = await fetchWithTimeout(`/admin/status`, { method: 'PUT', headers }); + checkResponse(status); +} +