adding admin page

This commit is contained in:
Roland Osborne 2022-06-02 22:05:53 -07:00
parent 66da560302
commit ca238ecc04
12 changed files with 195 additions and 3 deletions

View File

@ -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
}

View File

@ -18,6 +18,6 @@ func GetNodeStatus(w http.ResponseWriter, r *http.Request) {
}
return
}
WriteResponse(w, false);
WriteResponse(w, false)
}

View File

@ -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

View File

@ -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",

View File

@ -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 (
<LoginWrapper>
<div className="login">
<Space>
<TokenInput placeholder="Admin Token" spellcheck="false" onChange={(e) => actions.setToken(e.target.value)} />
<Button loading={state.busy} type="primary" onClick={() => actions.setAccess()}>Set</Button>
</Space>
</div>
</LoginWrapper>
);
}
if (!state.access) {
return (
<LoginWrapper>
<div className="login">
<Space>
<TokenInput placeholder="Admin Token" spellcheck="false" onChange={(e) => actions.setToken(e.target.value)} />
<Button loading={state.busy} type="primary" onClick={() => actions.getAccess()}>Go</Button>
</Space>
</div>
</LoginWrapper>
);
}
return (
<AdminWrapper>
<Dashboard />
</AdminWrapper>
)
}

View File

@ -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;
`;

View File

@ -0,0 +1,4 @@
export function Dashboard() {
return (<div>DASHBOARD</div>);
}

View File

@ -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 };
}

View File

@ -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() {
<Routes>
<Route path="/" element={ <Home /> } />
<Route path="/login" element={ <Login /> } />
<Route path="/admin" element={ <Admin /> } />
<Route path="/create" element={ <Create /> } />
<Route path="/user" element={ <User /> }>
<Route path="profile" element={<Profile />} />

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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);
}