mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 12:39:17 +00:00
updating web app output path
This commit is contained in:
parent
74244b920d
commit
f93b51c862
@ -12,8 +12,15 @@ import (
|
|||||||
|
|
||||||
func AddAccount(w http.ResponseWriter, r *http.Request) {
|
func AddAccount(w http.ResponseWriter, r *http.Request) {
|
||||||
var token *store.AccountToken
|
var token *store.AccountToken
|
||||||
|
var res error
|
||||||
|
|
||||||
if r.Header.Get("Authorization") == "" {
|
if r.FormValue("token") != "" {
|
||||||
|
token, _, res = AccessToken(r)
|
||||||
|
if res != nil || token.TokenType != APP_TOKENCREATE {
|
||||||
|
ErrResponse(w, http.StatusUnauthorized, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if available, err := getAvailableAccounts(); err != nil {
|
if available, err := getAvailableAccounts(); err != nil {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
@ -21,13 +28,6 @@ func AddAccount(w http.ResponseWriter, r *http.Request) {
|
|||||||
ErrResponse(w, http.StatusForbidden, errors.New("no open accounts available"))
|
ErrResponse(w, http.StatusForbidden, errors.New("no open accounts available"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
token, err = BearerAccountToken(r);
|
|
||||||
if err != nil || token.TokenType != APP_TOKENCREATE {
|
|
||||||
ErrResponse(w, http.StatusUnauthorized, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
username, password, ret := BasicCredentials(r);
|
username, password, ret := BasicCredentials(r);
|
||||||
|
@ -11,21 +11,19 @@ type accountUsername struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetAccountUsername(w http.ResponseWriter, r *http.Request) {
|
func GetAccountUsername(w http.ResponseWriter, r *http.Request) {
|
||||||
var token *store.AccountToken
|
|
||||||
|
|
||||||
if r.Header.Get("Authorization") == "" {
|
if r.FormValue("token") != "" {
|
||||||
|
token, _, res := AccessToken(r)
|
||||||
|
if res != nil || token.TokenType != APP_TOKENCREATE {
|
||||||
|
ErrResponse(w, http.StatusUnauthorized, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if available, err := getAvailableAccounts(); err != nil {
|
if available, err := getAvailableAccounts(); err != nil {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
} else if available == 0 {
|
} else if available == 0 {
|
||||||
ErrResponse(w, http.StatusUnauthorized, errors.New("no open accounts available"))
|
ErrResponse(w, http.StatusForbidden, errors.New("no open accounts available"))
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
token, err = BearerAccountToken(r);
|
|
||||||
if err != nil || token.TokenType != APP_TOKENCREATE {
|
|
||||||
ErrResponse(w, http.StatusUnauthorized, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ func NewRouter() *mux.Router {
|
|||||||
Handler(handler)
|
Handler(handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
fs := http.FileServer(http.Dir("/data/databag/net/web/build/"))
|
fs := http.FileServer(http.Dir("/app/databag/net/web/build/"))
|
||||||
router.PathPrefix("/").Handler(http.StripPrefix("/", fs))
|
router.PathPrefix("/").Handler(http.StripPrefix("/", fs))
|
||||||
|
|
||||||
return router
|
return router
|
||||||
|
@ -45,7 +45,7 @@ export function AccountItem({ token, item, remove }) {
|
|||||||
<div class="control">
|
<div class="control">
|
||||||
<Tooltip placement="topLeft" title="Account Login Link">
|
<Tooltip placement="topLeft" title="Account Login Link">
|
||||||
<ResetButton type="text" size="large" icon={<UnlockOutlined />}
|
<ResetButton type="text" size="large" icon={<UnlockOutlined />}
|
||||||
onClick={() => actions.setAccessLink()}></ResetButton>
|
loading={state.accessBusy} onClick={() => actions.setAccessLink()}></ResetButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Enable />
|
<Enable />
|
||||||
<Tooltip placement="topLeft" title="Delete Account">
|
<Tooltip placement="topLeft" title="Delete Account">
|
||||||
@ -53,7 +53,7 @@ export function AccountItem({ token, item, remove }) {
|
|||||||
loading={state.removeBusy} onClick={() => actions.remove()}></DeleteButton>
|
loading={state.removeBusy} onClick={() => actions.remove()}></DeleteButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<Modal title="Access Link" visible={state.showAccess} centered width="fitContent"
|
<Modal title="Access Account Link" visible={state.showAccess} centered width="fitContent"
|
||||||
footer={[ <Button type="primary" onClick={() => actions.setShowAccess(false)}>OK</Button> ]}
|
footer={[ <Button type="primary" onClick={() => actions.setShowAccess(false)}>OK</Button> ]}
|
||||||
onCancel={() => actions.setShowAccess(false)}>
|
onCancel={() => actions.setShowAccess(false)}>
|
||||||
<AccessLayout>
|
<AccessLayout>
|
||||||
|
@ -8,6 +8,7 @@ export function useAccountItem(token, item, remove) {
|
|||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
statusBusy: false,
|
statusBusy: false,
|
||||||
removeBusy: false,
|
removeBusy: false,
|
||||||
|
accessBusy: false,
|
||||||
showAccess: false,
|
showAccess: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -29,8 +30,17 @@ export function useAccountItem(token, item, remove) {
|
|||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
setAccessLink: async () => {
|
setAccessLink: async () => {
|
||||||
let access = await addAccountAccess(token, item.accountId);
|
if (!state.accessBusy) {
|
||||||
updateState({ accessToken: access, showAccess: true });
|
updateState({ accessBusy: true });
|
||||||
|
try {
|
||||||
|
let access = await addAccountAccess(token, item.accountId);
|
||||||
|
updateState({ accessToken: access, showAccess: true });
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
window.alert(err);
|
||||||
|
}
|
||||||
|
updateState({ accessBusy: false });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setShowAccess: (showAccess) => {
|
setShowAccess: (showAccess) => {
|
||||||
updateState({ showAccess });
|
updateState({ showAccess });
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { DashboardWrapper, SettingsButton, AddButton, SettingsLayout } from './Dashboard.styled';
|
import { DashboardWrapper, SettingsButton, AddButton, SettingsLayout, CreateLayout } from './Dashboard.styled';
|
||||||
import { Tooltip, Button, Modal, Input, InputNumber, Space, List } from 'antd';
|
import { Tooltip, Button, Modal, Input, InputNumber, Space, List } from 'antd';
|
||||||
import { SettingOutlined, UserAddOutlined, LogoutOutlined, ReloadOutlined } from '@ant-design/icons';
|
import { SettingOutlined, CopyOutlined, UserAddOutlined, LogoutOutlined, ReloadOutlined } from '@ant-design/icons';
|
||||||
import { useDashboard } from './useDashboard.hook';
|
import { useDashboard } from './useDashboard.hook';
|
||||||
import { AccountItem } from './AccountItem/AccountItem';
|
import { AccountItem } from './AccountItem/AccountItem';
|
||||||
|
|
||||||
@ -8,6 +8,14 @@ export function Dashboard({ token, config, logout }) {
|
|||||||
|
|
||||||
const { state, actions } = useDashboard(token, config);
|
const { state, actions } = useDashboard(token, config);
|
||||||
|
|
||||||
|
const onClipboard = (value) => {
|
||||||
|
navigator.clipboard.writeText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const createLink = () => {
|
||||||
|
return window.location.origin + '/#/create?add=' + state.createToken;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardWrapper>
|
<DashboardWrapper>
|
||||||
|
|
||||||
@ -34,7 +42,8 @@ export function Dashboard({ token, config, logout }) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="add">
|
<div class="add">
|
||||||
<Tooltip placement="topRight" title="Create Account Link">
|
<Tooltip placement="topRight" title="Create Account Link">
|
||||||
<AddButton type="text" size="large" icon={<UserAddOutlined />}></AddButton>
|
<AddButton type="text" size="large" icon={<UserAddOutlined />}
|
||||||
|
loading={state.createBusy} onClick={() => actions.setCreateLink()}></AddButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -60,13 +69,22 @@ export function Dashboard({ token, config, logout }) {
|
|||||||
value={state.host} />
|
value={state.host} />
|
||||||
</div>
|
</div>
|
||||||
<div class="storage">
|
<div class="storage">
|
||||||
<div>Account Storage (GB): </div>
|
<div>Storage Limit (GB) / Account: </div>
|
||||||
<InputNumber defaultValue={8} onChange={(e) => actions.setStorage(e)}
|
<InputNumber defaultValue={8} onChange={(e) => actions.setStorage(e)}
|
||||||
placeholder="0 for unrestricted" value={state.storage} />
|
placeholder="0 for unrestricted" value={state.storage} />
|
||||||
</div>
|
</div>
|
||||||
</SettingsLayout>
|
</SettingsLayout>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<Modal title="Create Account Link" visible={state.showCreate} centered width="fitContent"
|
||||||
|
footer={[ <Button type="primary" onClick={() => actions.setShowCreate(false)}>OK</Button> ]}
|
||||||
|
onCancel={() => actions.setShowCreate(false)}>
|
||||||
|
<CreateLayout>
|
||||||
|
<div>{createLink()}</div>
|
||||||
|
<Button icon={<CopyOutlined />} size="small"
|
||||||
|
onClick={() => onClipboard(createLink())}
|
||||||
|
/>
|
||||||
|
</CreateLayout>
|
||||||
|
</Modal>
|
||||||
</DashboardWrapper>
|
</DashboardWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -84,3 +84,7 @@ export const SettingsLayout = styled(Space)`
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const CreateLayout = styled(Space)`
|
||||||
|
white-space: nowrap;
|
||||||
|
`
|
||||||
|
@ -2,6 +2,7 @@ import { useState, useEffect } from 'react';
|
|||||||
import { setNodeConfig } from 'api/setNodeConfig';
|
import { setNodeConfig } from 'api/setNodeConfig';
|
||||||
import { getNodeAccounts } from 'api/getNodeAccounts';
|
import { getNodeAccounts } from 'api/getNodeAccounts';
|
||||||
import { removeAccount } from 'api/removeAccount';
|
import { removeAccount } from 'api/removeAccount';
|
||||||
|
import { addAccountCreate } from 'api/addAccountCreate';
|
||||||
|
|
||||||
export function useDashboard(token, config) {
|
export function useDashboard(token, config) {
|
||||||
|
|
||||||
@ -12,6 +13,8 @@ export function useDashboard(token, config) {
|
|||||||
busy: false,
|
busy: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
accounts: [],
|
accounts: [],
|
||||||
|
createBusy: false,
|
||||||
|
showCreate: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateState = (value) => {
|
const updateState = (value) => {
|
||||||
@ -19,6 +22,22 @@ export function useDashboard(token, config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
|
setCreateLink: async () => {
|
||||||
|
if (!state.createBusy) {
|
||||||
|
updateState({ createBusy: true });
|
||||||
|
try {
|
||||||
|
let create = await addAccountCreate(token)
|
||||||
|
updateState({ createToken: create, showCreate: true });
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
window.alert(err);
|
||||||
|
}
|
||||||
|
updateState({ createBusy: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setShowCreate: (showCreate) => {
|
||||||
|
updateState({ showCreate });
|
||||||
|
},
|
||||||
removeAccount: async (accountId) => {
|
removeAccount: async (accountId) => {
|
||||||
await removeAccount(token, accountId);
|
await removeAccount(token, accountId);
|
||||||
actions.getAccounts();
|
actions.getAccounts();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useContext, useState, useEffect, useRef } from 'react';
|
import { useContext, useState, useEffect, useRef } from 'react';
|
||||||
import { AppContext } from 'context/AppContext';
|
import { AppContext } from 'context/AppContext';
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate, useLocation } from "react-router-dom";
|
||||||
|
|
||||||
export function useCreate() {
|
export function useCreate() {
|
||||||
const [checked, setChecked] = useState(true)
|
const [checked, setChecked] = useState(true)
|
||||||
@ -10,10 +10,12 @@ export function useCreate() {
|
|||||||
confirmed: '',
|
confirmed: '',
|
||||||
conflict: '',
|
conflict: '',
|
||||||
spinning: false,
|
spinning: false,
|
||||||
|
token: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const app = useContext(AppContext);
|
const app = useContext(AppContext);
|
||||||
|
const { search } = useLocation();
|
||||||
const debounce = useRef(null)
|
const debounce = useRef(null)
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
@ -41,7 +43,7 @@ export function useCreate() {
|
|||||||
if (!state.spinning) {
|
if (!state.spinning) {
|
||||||
actions.updateState({ spinning: true })
|
actions.updateState({ spinning: true })
|
||||||
try {
|
try {
|
||||||
await app.actions.create(state.username, state.password)
|
await app.actions.create(state.username, state.password, state.token)
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
window.alert(err);
|
window.alert(err);
|
||||||
@ -64,7 +66,7 @@ export function useCreate() {
|
|||||||
actions.updateState({ conflict: '' })
|
actions.updateState({ conflict: '' })
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let valid = await app.actions.username(name)
|
let valid = await app.actions.username(name, state.token)
|
||||||
setChecked(true)
|
setChecked(true)
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
actions.updateState({ conflict: 'not available' })
|
actions.updateState({ conflict: 'not available' })
|
||||||
@ -82,8 +84,12 @@ export function useCreate() {
|
|||||||
if (app.state.access === 'user') {
|
if (app.state.access === 'user') {
|
||||||
navigate('/user')
|
navigate('/user')
|
||||||
}
|
}
|
||||||
if (app.state.access === 'admin') {
|
else {
|
||||||
navigate('/admin')
|
let params = new URLSearchParams(search);
|
||||||
|
let token = params.get("add");
|
||||||
|
if (token) {
|
||||||
|
actions.updateState({ token });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,10 +43,16 @@ export function ChannelLabel({ item }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (item?.data?.channelDetail?.data) {
|
if (item?.data?.channelDetail?.data) {
|
||||||
let data = JSON.parse(item.data.channelDetail.data);
|
try {
|
||||||
if (data.subject != '' && data.subject != null) {
|
let data = JSON.parse(item.data.channelDetail.data);
|
||||||
setSubject(data.subject);
|
if (data.subject != '' && data.subject != null) {
|
||||||
return
|
setSubject(data.subject);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
setSubject(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setSubject(contacts.join(', '));
|
setSubject(contacts.join(', '));
|
||||||
|
15
net/web/src/api/addAccount.js
Normal file
15
net/web/src/api/addAccount.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
var base64 = require('base-64');
|
||||||
|
|
||||||
|
export async function addAccount(username, password, token) {
|
||||||
|
let access = "";
|
||||||
|
if (token) {
|
||||||
|
access = `?token=${token}`
|
||||||
|
}
|
||||||
|
let headers = new Headers()
|
||||||
|
headers.append('Credentials', 'Basic ' + base64.encode(username + ":" + password));
|
||||||
|
let profile = await fetchWithTimeout(`/account/profile${access}`, { method: 'POST', headers: headers })
|
||||||
|
checkResponse(profile);
|
||||||
|
return await profile.json()
|
||||||
|
}
|
||||||
|
|
8
net/web/src/api/addAccountCreate.js
Normal file
8
net/web/src/api/addAccountCreate.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
|
||||||
|
export async function addAccountCreate(token) {
|
||||||
|
let access = await fetchWithTimeout(`/admin/accounts?token=${token}`, { method: 'POST' })
|
||||||
|
checkResponse(access);
|
||||||
|
return await access.json()
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,11 @@
|
|||||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
|
||||||
export async function getUsername(name) {
|
export async function getUsername(name, token) {
|
||||||
let available = await fetchWithTimeout('/account/username?name=' + encodeURIComponent(name), { method: 'GET' })
|
let access = "";
|
||||||
|
if (token) {
|
||||||
|
access = `&token=${token}`
|
||||||
|
}
|
||||||
|
let available = await fetchWithTimeout('/account/username?name=' + encodeURIComponent(name) + access, { method: 'GET' })
|
||||||
checkResponse(available)
|
checkResponse(available)
|
||||||
return await available.json()
|
return await available.json()
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,6 @@ export async function getAvailable() {
|
|||||||
return await available.json()
|
return await available.json()
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUsername(name) {
|
|
||||||
let available = await fetchWithTimeout('/account/username?name=' + encodeURIComponent(name), { method: 'GET', timeout: FETCH_TIMEOUT })
|
|
||||||
checkResponse(available)
|
|
||||||
return await available.json()
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function setLogin(username, password) {
|
export async function setLogin(username, password) {
|
||||||
let headers = new Headers()
|
let headers = new Headers()
|
||||||
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
|
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import { useEffect, useState, useRef, useContext } from 'react';
|
import { useEffect, useState, useRef, useContext } from 'react';
|
||||||
import { useNavigate, useLocation, useParams } from "react-router-dom";
|
import { useNavigate, useLocation, useParams } from "react-router-dom";
|
||||||
import { getAvailable, getUsername, setLogin, createAccount } from './fetchUtil';
|
import { getAvailable, setLogin } from './fetchUtil';
|
||||||
import { setAccountAccess } from 'api/setAccountAccess';
|
import { setAccountAccess } from 'api/setAccountAccess';
|
||||||
|
import { addAccount } from 'api/addAccount';
|
||||||
|
import { getUsername } from 'api/getUsername';
|
||||||
import { AccountContext } from './AccountContext';
|
import { AccountContext } from './AccountContext';
|
||||||
import { ProfileContext } from './ProfileContext';
|
import { ProfileContext } from './ProfileContext';
|
||||||
import { ArticleContext } from './ArticleContext';
|
import { ArticleContext } from './ArticleContext';
|
||||||
@ -9,8 +11,8 @@ import { GroupContext } from './GroupContext';
|
|||||||
import { CardContext } from './CardContext';
|
import { CardContext } from './CardContext';
|
||||||
import { ChannelContext } from './ChannelContext';
|
import { ChannelContext } from './ChannelContext';
|
||||||
|
|
||||||
async function appCreate(username, password, updateState, setWebsocket) {
|
async function appCreate(username, password, token, updateState, setWebsocket) {
|
||||||
await createAccount(username, password);
|
await addAccount(username, password, token);
|
||||||
let access = await setLogin(username, password)
|
let access = await setLogin(username, password)
|
||||||
updateState({ token: access, access: 'user' });
|
updateState({ token: access, access: 'user' });
|
||||||
setWebsocket(access)
|
setWebsocket(access)
|
||||||
@ -95,8 +97,8 @@ export function useAppContext() {
|
|||||||
login: async (username, password) => {
|
login: async (username, password) => {
|
||||||
await appLogin(username, password, updateState, setWebsocket)
|
await appLogin(username, password, updateState, setWebsocket)
|
||||||
},
|
},
|
||||||
create: async (username, password) => {
|
create: async (username, password, token) => {
|
||||||
await appCreate(username, password, updateState, setWebsocket)
|
await appCreate(username, password, token, updateState, setWebsocket)
|
||||||
},
|
},
|
||||||
username: getUsername,
|
username: getUsername,
|
||||||
available: getAvailable,
|
available: getAvailable,
|
||||||
|
Loading…
Reference in New Issue
Block a user