mirror of
https://github.com/openziti/zrok.git
synced 2025-06-23 11:11:48 +02:00
de-leaked (#221)
This commit is contained in:
parent
d2556b2251
commit
9867067a14
@ -1,19 +1,20 @@
|
|||||||
import LanIcon from "@mui/icons-material/Lan";
|
import LanIcon from "@mui/icons-material/Lan";
|
||||||
|
import {Button, Card, Chip} from "@mui/material";
|
||||||
import DeleteIcon from "@mui/icons-material/Delete";
|
import DeleteIcon from "@mui/icons-material/Delete";
|
||||||
import {Card} from "@mui/material";
|
import {releaseAccess} from "./model/handler.js";
|
||||||
|
|
||||||
const AccessCard = (props) => {
|
const AccessCard = (props) => {
|
||||||
const releaseClicked = () => {
|
const deleteHandler = () => {
|
||||||
props.releaseAccess({frontendToken: props.access.frontendToken}, (err, data) => { console.log("releaseClicked", data); });
|
releaseAccess({ frontendToken: props.access.frontendToken });
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<h2>{props.access.frontendToken} [<LanIcon/>]</h2>
|
<h2><LanIcon /> {props.access.frontendToken}</h2>
|
||||||
<p>
|
<p>
|
||||||
{props.access.token} → {props.access.bindAddress}
|
{props.access.token} → {props.access.bindAddress}
|
||||||
</p>
|
</p>
|
||||||
<p><DeleteIcon onClick={releaseClicked}/></p>
|
<Button variant="outlined" onClick={deleteHandler}><DeleteIcon /></Button>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,34 @@
|
|||||||
import {createBrowserRouter, RouterProvider} from "react-router-dom";
|
|
||||||
import Overview from "./Overview.jsx";
|
|
||||||
import ShareDetail from "./ShareDetail.jsx";
|
|
||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import buildOverview from "./model/overview.js";
|
|
||||||
import NavBar from "./NavBar.jsx";
|
import NavBar from "./NavBar.jsx";
|
||||||
import NewShareModal from "./NewShareModal.jsx";
|
import {getAgentApi} from "./model/handler.js";
|
||||||
|
import {buildOverview} from "./model/overview.js";
|
||||||
|
import Overview from "./Overview.jsx";
|
||||||
import NewAccessModal from "./NewAccessModal.jsx";
|
import NewAccessModal from "./NewAccessModal.jsx";
|
||||||
import {accessHandler, getAgentApi, releaseAccess, releaseShare, shareHandler} from "./model/handler.js";
|
import NewShareModal from "./NewShareModal.jsx";
|
||||||
|
|
||||||
const AgentUi = () => {
|
const AgentUi = () => {
|
||||||
const [version, setVersion] = useState("");
|
const [version, setVersion] = useState("");
|
||||||
const [overview, setOverview] = useState([]);
|
const [overview, setOverview] = useState([]);
|
||||||
|
const [newAccessOpen, setNewAccessOpen] = useState(false);
|
||||||
|
const [newShareOpen, setNewShareOpen] = useState(false);
|
||||||
|
|
||||||
const [newShare, setNewShare] = useState(false);
|
|
||||||
const openNewShare = () => {
|
|
||||||
setNewShare(true);
|
|
||||||
}
|
|
||||||
const closeNewShare = () => {
|
|
||||||
setNewShare(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [newAccess, setNewAccess] = useState(false);
|
|
||||||
const openNewAccess = () => {
|
const openNewAccess = () => {
|
||||||
setNewAccess(true);
|
setNewAccessOpen(true);
|
||||||
}
|
}
|
||||||
const closeNewAccess = () => {
|
const closeNewAccess = () => {
|
||||||
setNewAccess(false);
|
setNewAccessOpen(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const openNewShare = () => {
|
||||||
|
setNewShareOpen(true);
|
||||||
|
}
|
||||||
|
const closeNewShare = () => {
|
||||||
|
setNewShareOpen(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getAgentApi().agentVersion((err, data) => {
|
getAgentApi().agentVersion((e, d) => {
|
||||||
setVersion(data.v);
|
setVersion(d.v);
|
||||||
});
|
});
|
||||||
return () => {
|
return () => {
|
||||||
setVersion("");
|
setVersion("");
|
||||||
@ -39,12 +37,12 @@ const AgentUi = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let interval = setInterval(() => {
|
let interval = setInterval(() => {
|
||||||
getAgentApi().agentStatus((err, data) => {
|
getAgentApi().agentStatus((e, d) => {
|
||||||
if(err) {
|
if(e) {
|
||||||
console.log("agentStatus", err);
|
|
||||||
setOverview([]);
|
setOverview([]);
|
||||||
|
console.log("agentStatus", e);
|
||||||
} else {
|
} else {
|
||||||
setOverview(structuredClone(buildOverview(data)));
|
setOverview(buildOverview(d));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 1000);
|
}, 1000);
|
||||||
@ -54,30 +52,13 @@ const AgentUi = () => {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
|
||||||
{
|
|
||||||
path: "/",
|
|
||||||
element: <Overview
|
|
||||||
releaseShare={releaseShare}
|
|
||||||
releaseAccess={releaseAccess}
|
|
||||||
version={version}
|
|
||||||
overview={overview}
|
|
||||||
shareClick={openNewShare}
|
|
||||||
accessClick={openNewAccess}
|
|
||||||
/>
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/share/:token",
|
|
||||||
element: <ShareDetail version={version} />
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NavBar version={version} shareClick={openNewShare} accessClick={openNewAccess} />
|
<NavBar version={version} shareClick={openNewShare} accessClick={openNewAccess} />
|
||||||
<RouterProvider router={router} />
|
<Overview overview={overview} />
|
||||||
<NewShareModal show={newShare} close={closeNewShare} handler={shareHandler} />
|
<NewAccessModal isOpen={newAccessOpen} close={closeNewAccess} />
|
||||||
<NewAccessModal show={newAccess} close={closeNewAccess} handler={accessHandler} />
|
<NewShareModal isOpen={newShareOpen} close={closeNewShare} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {Box, Button, Modal, TextField} from "@mui/material";
|
import {Box, Button, Modal, TextField} from "@mui/material";
|
||||||
import {useFormik} from "formik";
|
import {useFormik} from "formik";
|
||||||
import {modalStyle} from "./model/theme.js";
|
import {modalStyle} from "./model/theme.js";
|
||||||
|
import {createAccess} from "./model/handler.js";
|
||||||
|
|
||||||
const NewAccessModal = (props) => {
|
const NewAccessModal = (props) => {
|
||||||
const newAccessForm = useFormik({
|
const newAccessForm = useFormik({
|
||||||
@ -9,14 +10,14 @@ const NewAccessModal = (props) => {
|
|||||||
bindAddress: "",
|
bindAddress: "",
|
||||||
},
|
},
|
||||||
onSubmit: (v) => {
|
onSubmit: (v) => {
|
||||||
props.handler(v);
|
createAccess(v);
|
||||||
props.close();
|
props.close();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={props.show}
|
open={props.isOpen}
|
||||||
onClose={props.close}
|
onClose={props.close}
|
||||||
>
|
>
|
||||||
<Box sx={{ ...modalStyle }}>
|
<Box sx={{ ...modalStyle }}>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {Box, Button, MenuItem, Modal, TextField} from "@mui/material";
|
import {Box, Button, MenuItem, Modal, TextField} from "@mui/material";
|
||||||
import {useFormik} from "formik";
|
import {useFormik} from "formik";
|
||||||
import {modalStyle} from "./model/theme.js";
|
import {modalStyle} from "./model/theme.js";
|
||||||
|
import {createShare} from "./model/handler.js";
|
||||||
|
|
||||||
const NewShareModal = (props) => {
|
const NewShareModal = (props) => {
|
||||||
const newShareForm = useFormik({
|
const newShareForm = useFormik({
|
||||||
@ -10,14 +11,14 @@ const NewShareModal = (props) => {
|
|||||||
target: "",
|
target: "",
|
||||||
},
|
},
|
||||||
onSubmit: (v) => {
|
onSubmit: (v) => {
|
||||||
props.handler(v);
|
createShare(v);
|
||||||
props.close();
|
props.close();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={props.show}
|
open={props.isOpen}
|
||||||
onClose={props.close}
|
onClose={props.close}
|
||||||
>
|
>
|
||||||
<Box sx={{ ...modalStyle }}>
|
<Box sx={{ ...modalStyle }}>
|
||||||
|
@ -1,30 +1,38 @@
|
|||||||
import "bootstrap/dist/css/bootstrap.min.css";
|
import "bootstrap/dist/css/bootstrap.min.css";
|
||||||
import ShareCard from "./ShareCard.jsx";
|
|
||||||
import AccessCard from "./AccessCard.jsx";
|
|
||||||
import LanIcon from "@mui/icons-material/Lan";
|
import LanIcon from "@mui/icons-material/Lan";
|
||||||
import ShareIcon from "@mui/icons-material/Share";
|
import ShareIcon from "@mui/icons-material/Share";
|
||||||
import {Card} from "@mui/material";
|
import {Box, Card, Stack} from "@mui/material";
|
||||||
import buildOverview from "./model/overview.js";
|
import AccessCard from "./AccessCard.jsx";
|
||||||
|
import ShareCard from "./ShareCard.jsx";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
const Overview = (props) => {
|
const Overview = (props) => {
|
||||||
let cards = [];
|
let cards = [];
|
||||||
if(props.overview.length > 0) {
|
if(props.overview.length > 0) {
|
||||||
props.overview.forEach((row) => {
|
props.overview.forEach((row) => {
|
||||||
switch(row.type) {
|
switch(row.type) {
|
||||||
case "share":
|
case "access":
|
||||||
cards.push(<ShareCard key={row.v.token} releaseShare={props.releaseShare} share={row.v} />);
|
cards.push(<AccessCard key={row.frontendToken} access={row} />);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "access":
|
case "share":
|
||||||
cards.push(<AccessCard key={row.v.frontendToken} releaseAccess={props.releaseAccess} access={row.v} />);
|
cards.push(<ShareCard key={row.token} share={row} />);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
cards.push(<Card key="empty"><h5>zrok Agent is empty! Add a <a href="#" onClick={props.shareClick}>share <ShareIcon /></a> or <a href={"#"} onClick={props.accessClick}>access <LanIcon /></a> share to get started.</h5></Card>);
|
cards.push(<Card key="empty"><h5>zrok Agent is empty! Add a <a href="#" onClick={props.shareClick}>share <ShareIcon /></a> or <a href={"#"} onClick={props.accessClick}>access <LanIcon /></a> share to get started.</h5></Card>);
|
||||||
}
|
}
|
||||||
|
return (
|
||||||
return <>{cards}</>;
|
<Box sx={{ display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
flexGrow: 1
|
||||||
|
}}>
|
||||||
|
{cards}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Overview;
|
export default Overview;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import ShareIcon from "@mui/icons-material/Share";
|
import ShareIcon from "@mui/icons-material/Share";
|
||||||
|
import {Button, Card} from "@mui/material";
|
||||||
import DeleteIcon from "@mui/icons-material/Delete";
|
import DeleteIcon from "@mui/icons-material/Delete";
|
||||||
import {Card} from "@mui/material";
|
import {releaseShare} from "./model/handler.js";
|
||||||
|
|
||||||
const ShareCard = (props) => {
|
const ShareCard = (props) => {
|
||||||
let frontends = [];
|
let frontends = [];
|
||||||
@ -8,18 +9,18 @@ const ShareCard = (props) => {
|
|||||||
frontends.push(<a key={props.share.token} href={fe.toString()} target={"_"}>{fe}</a>);
|
frontends.push(<a key={props.share.token} href={fe.toString()} target={"_"}>{fe}</a>);
|
||||||
})
|
})
|
||||||
|
|
||||||
const releaseClicked = () => {
|
const deleteHandler = () => {
|
||||||
props.releaseShare({token: props.share.token}, (err, data) => { console.log("releaseClicked", data); });
|
releaseShare({ token: props.share.token });
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<h2>{props.share.token} [<ShareIcon />]</h2>
|
<h2><ShareIcon /> {props.share.token}</h2>
|
||||||
<p>
|
<p>
|
||||||
({props.share.shareMode}, {props.share.backendMode}) <br/>
|
({props.share.shareMode}, {props.share.backendMode}) <br/>
|
||||||
{props.share.backendEndpoint} → {frontends} <br/>
|
{props.share.backendEndpoint} → {frontends} <br/>
|
||||||
<DeleteIcon onClick={releaseClicked}/>
|
|
||||||
</p>
|
</p>
|
||||||
|
<Button variant="outlined" onClick={deleteHandler} ><DeleteIcon /></Button>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,155 +0,0 @@
|
|||||||
/** @module Agent */
|
|
||||||
// Auto-generated, edits will be overwritten
|
|
||||||
import * as gateway from './gateway'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {object} options Optional options
|
|
||||||
* @param {string} [options.token]
|
|
||||||
* @param {string} [options.bindAddress]
|
|
||||||
* @param {string[]} [options.responseHeaders]
|
|
||||||
* @return {Promise<module:types.AccessPrivateResponse>} A successful response.
|
|
||||||
*/
|
|
||||||
export function Agent_AccessPrivate(options) {
|
|
||||||
if (!options) options = {}
|
|
||||||
const parameters = {
|
|
||||||
query: {
|
|
||||||
token: options.token,
|
|
||||||
bindAddress: options.bindAddress,
|
|
||||||
responseHeaders: gateway.formatArrayParam(options.responseHeaders, 'multi', 'responseHeaders')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return gateway.request(Agent_AccessPrivateOperation, parameters)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {object} options Optional options
|
|
||||||
* @param {string} [options.frontendToken]
|
|
||||||
* @return {Promise<module:types.ReleaseAccessResponse>} A successful response.
|
|
||||||
*/
|
|
||||||
export function Agent_ReleaseAccess(options) {
|
|
||||||
if (!options) options = {}
|
|
||||||
const parameters = {
|
|
||||||
query: {
|
|
||||||
frontendToken: options.frontendToken
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return gateway.request(Agent_ReleaseAccessOperation, parameters)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {object} options Optional options
|
|
||||||
* @param {string} [options.token]
|
|
||||||
* @return {Promise<module:types.ReleaseShareResponse>} A successful response.
|
|
||||||
*/
|
|
||||||
export function Agent_ReleaseShare(options) {
|
|
||||||
if (!options) options = {}
|
|
||||||
const parameters = {
|
|
||||||
query: {
|
|
||||||
token: options.token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return gateway.request(Agent_ReleaseShareOperation, parameters)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {object} options Optional options
|
|
||||||
* @param {string} [options.target]
|
|
||||||
* @param {string} [options.backendMode]
|
|
||||||
* @param {boolean} [options.insecure]
|
|
||||||
* @param {boolean} [options.closed]
|
|
||||||
* @param {string[]} [options.accessGrants]
|
|
||||||
* @return {Promise<module:types.SharePrivateResponse>} A successful response.
|
|
||||||
*/
|
|
||||||
export function Agent_SharePrivate(options) {
|
|
||||||
if (!options) options = {}
|
|
||||||
const parameters = {
|
|
||||||
query: {
|
|
||||||
target: options.target,
|
|
||||||
backendMode: options.backendMode,
|
|
||||||
insecure: options.insecure,
|
|
||||||
closed: options.closed,
|
|
||||||
accessGrants: gateway.formatArrayParam(options.accessGrants, 'multi', 'accessGrants')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return gateway.request(Agent_SharePrivateOperation, parameters)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {object} options Optional options
|
|
||||||
* @param {string} [options.target]
|
|
||||||
* @param {string[]} [options.basicAuth]
|
|
||||||
* @param {string[]} [options.frontendSelection]
|
|
||||||
* @param {string} [options.backendMode]
|
|
||||||
* @param {boolean} [options.insecure]
|
|
||||||
* @param {string} [options.oauthProvider]
|
|
||||||
* @param {string[]} [options.oauthEmailAddressPatterns]
|
|
||||||
* @param {string} [options.oauthCheckInterval]
|
|
||||||
* @param {boolean} [options.closed]
|
|
||||||
* @param {string[]} [options.accessGrants]
|
|
||||||
* @return {Promise<module:types.SharePublicResponse>} A successful response.
|
|
||||||
*/
|
|
||||||
export function Agent_SharePublic(options) {
|
|
||||||
if (!options) options = {}
|
|
||||||
const parameters = {
|
|
||||||
query: {
|
|
||||||
target: options.target,
|
|
||||||
basicAuth: gateway.formatArrayParam(options.basicAuth, 'multi', 'basicAuth'),
|
|
||||||
frontendSelection: gateway.formatArrayParam(options.frontendSelection, 'multi', 'frontendSelection'),
|
|
||||||
backendMode: options.backendMode,
|
|
||||||
insecure: options.insecure,
|
|
||||||
oauthProvider: options.oauthProvider,
|
|
||||||
oauthEmailAddressPatterns: gateway.formatArrayParam(options.oauthEmailAddressPatterns, 'multi', 'oauthEmailAddressPatterns'),
|
|
||||||
oauthCheckInterval: options.oauthCheckInterval,
|
|
||||||
closed: options.closed,
|
|
||||||
accessGrants: gateway.formatArrayParam(options.accessGrants, 'multi', 'accessGrants')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return gateway.request(Agent_SharePublicOperation, parameters)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
export function Agent_Status() {
|
|
||||||
return gateway.request(Agent_StatusOperation)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
export function Agent_Version() {
|
|
||||||
return gateway.request(Agent_VersionOperation)
|
|
||||||
}
|
|
||||||
|
|
||||||
const Agent_AccessPrivateOperation = {
|
|
||||||
path: '/v1/agent/accessPrivate',
|
|
||||||
method: 'post'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Agent_ReleaseAccessOperation = {
|
|
||||||
path: '/v1/agent/releaseAccess',
|
|
||||||
method: 'post'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Agent_ReleaseShareOperation = {
|
|
||||||
path: '/v1/agent/releaseShare',
|
|
||||||
method: 'post'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Agent_SharePrivateOperation = {
|
|
||||||
path: '/v1/agent/sharePrivate',
|
|
||||||
method: 'post'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Agent_SharePublicOperation = {
|
|
||||||
path: '/v1/agent/sharePublic',
|
|
||||||
method: 'post'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Agent_StatusOperation = {
|
|
||||||
path: '/v1/agent/status',
|
|
||||||
method: 'get'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Agent_VersionOperation = {
|
|
||||||
path: '/v1/agent/version',
|
|
||||||
method: 'get'
|
|
||||||
}
|
|
@ -1,281 +0,0 @@
|
|||||||
// Auto-generated, edits will be overwritten
|
|
||||||
import spec from './spec'
|
|
||||||
|
|
||||||
export class ServiceError extends Error {}
|
|
||||||
|
|
||||||
let options = {}
|
|
||||||
|
|
||||||
export function init(serviceOptions) {
|
|
||||||
options = serviceOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
export function request(op, parameters, attempt) {
|
|
||||||
if (!attempt) attempt = 1;
|
|
||||||
return acquireRights(op, spec, options)
|
|
||||||
.then(rights => {
|
|
||||||
parameters = parameters || {}
|
|
||||||
const baseUrl = getBaseUrl(spec)
|
|
||||||
let reqInfo = { parameters, baseUrl }
|
|
||||||
if (options.processRequest) {
|
|
||||||
reqInfo = options.processRequest(op, reqInfo)
|
|
||||||
}
|
|
||||||
const req = buildRequest(op, reqInfo.baseUrl, reqInfo.parameters, rights)
|
|
||||||
return makeFetchRequest(req)
|
|
||||||
.then(res => processResponse(req, res, attempt, options), e => processError(req, e))
|
|
||||||
.then(outcome => outcome.retry ? request(op, parameters, attempt + 1) : outcome.res)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function acquireRights(op, spec, options) {
|
|
||||||
if (op.security && options.getAuthorization) {
|
|
||||||
return op.security.reduce((promise, security) => {
|
|
||||||
return promise.then(rights => {
|
|
||||||
const securityDefinition = spec.securityDefinitions[security.id]
|
|
||||||
return options.getAuthorization(security, securityDefinition, op)
|
|
||||||
.then(auth => {
|
|
||||||
rights[security.id] = auth
|
|
||||||
return rights
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}, Promise.resolve({}))
|
|
||||||
}
|
|
||||||
return Promise.resolve({})
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeFetchRequest(req) {
|
|
||||||
let fetchOptions = {
|
|
||||||
compress: true,
|
|
||||||
method: (req.method || 'get').toUpperCase(),
|
|
||||||
headers: req.headers,
|
|
||||||
body: req.body ? JSON.stringify(req.body) : undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.fetchOptions) {
|
|
||||||
const opts = options.fetchOptions
|
|
||||||
const headers = opts.headers
|
|
||||||
? Object.assign(fetchOptions.headers, opts.headers)
|
|
||||||
: fetchOptions.headers
|
|
||||||
|
|
||||||
fetchOptions = Object.assign({}, fetchOptions, opts)
|
|
||||||
fetchOptions.headers = headers
|
|
||||||
}
|
|
||||||
|
|
||||||
let promise = fetch(req.url, fetchOptions)
|
|
||||||
return promise
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildRequest(op, baseUrl, parameters, rights) {
|
|
||||||
let paramGroups = groupParams(op, parameters)
|
|
||||||
paramGroups = applyAuthorization(paramGroups, rights, spec)
|
|
||||||
const url = buildUrl(op, baseUrl, paramGroups, spec)
|
|
||||||
const headers = buildHeaders(op, paramGroups)
|
|
||||||
const body = buildBody(parameters.body)
|
|
||||||
return {
|
|
||||||
method: op.method,
|
|
||||||
url,
|
|
||||||
headers,
|
|
||||||
body
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function groupParams(op, parameters) {
|
|
||||||
const groups = ['header', 'path', 'query', 'formData'].reduce((groups, name) => {
|
|
||||||
groups[name] = formatParamsGroup(groups[name])
|
|
||||||
return groups
|
|
||||||
}, parameters)
|
|
||||||
if (!groups.header) groups.header = {}
|
|
||||||
return groups
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatParamsGroup(groups) {
|
|
||||||
return Object.keys(groups || {}).reduce((g, name) => {
|
|
||||||
const param = groups[name]
|
|
||||||
if (param !== undefined) {
|
|
||||||
g[name] = formatParam(param)
|
|
||||||
}
|
|
||||||
return g
|
|
||||||
}, {})
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatParam(param) {
|
|
||||||
if (param === undefined || param === null) return ''
|
|
||||||
else if (param instanceof Date) return param.toJSON()
|
|
||||||
else if (Array.isArray(param)) return param
|
|
||||||
else return param.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildUrl(op, baseUrl, parameters, spec) {
|
|
||||||
let url = `${baseUrl}${op.path}`
|
|
||||||
if (parameters.path) {
|
|
||||||
url = Object.keys(parameters.path)
|
|
||||||
.reduce((url, name) => url.replace(`{${name}}`, parameters.path[name]), url)
|
|
||||||
}
|
|
||||||
const query = createQueryString(parameters.query)
|
|
||||||
return url + query
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBaseUrl(spec) {
|
|
||||||
return options.url || `${spec.schemes[0] || 'https'}://${spec.host}${spec.basePath}`
|
|
||||||
}
|
|
||||||
|
|
||||||
function createQueryParam(name, value) {
|
|
||||||
const v = formatParam(value)
|
|
||||||
if (v && typeof v === 'string') return `${name}=${encodeURIComponent(v)}`
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createQueryString(query) {
|
|
||||||
const names = Object.keys(query || {})
|
|
||||||
if (!names.length) return ''
|
|
||||||
const params = names.map(name => ({name, value: query[name]}))
|
|
||||||
.reduce((acc, value) => {
|
|
||||||
if (Array.isArray(value.value)) {
|
|
||||||
return acc.concat(value.value)
|
|
||||||
} else {
|
|
||||||
acc.push(createQueryParam(value.name, value.value))
|
|
||||||
return acc
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
return '?' + params.sort().join('&')
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildHeaders(op, parameters) {
|
|
||||||
const headers = {}
|
|
||||||
|
|
||||||
let accepts
|
|
||||||
if (op.accepts && op.accepts.length) accepts = op.accepts
|
|
||||||
else if (spec.accepts && spec.accepts.length) accepts = spec.accepts
|
|
||||||
else accepts = [ 'application/json' ]
|
|
||||||
|
|
||||||
headers.Accept = accepts.join(', ')
|
|
||||||
|
|
||||||
let contentType
|
|
||||||
if (op.contentTypes && op.contentTypes[0]) contentType = op.contentTypes[0]
|
|
||||||
else if (spec.contentTypes && spec.contentTypes[0]) contentType = spec.contentTypes[0]
|
|
||||||
if (contentType) headers['Content-Type'] = contentType
|
|
||||||
|
|
||||||
return Object.assign(headers, parameters.header)
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildBody(bodyParams) {
|
|
||||||
if (bodyParams) {
|
|
||||||
if (bodyParams.body) return bodyParams.body
|
|
||||||
const key = Object.keys(bodyParams)[0]
|
|
||||||
if (key) return bodyParams[key]
|
|
||||||
}
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveAuthHeaderName(headerName){
|
|
||||||
if (options.authorizationHeader && headerName.toLowerCase() === 'authorization') {
|
|
||||||
return options.authorizationHeader
|
|
||||||
} else {
|
|
||||||
return headerName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyAuthorization(req, rights, spec) {
|
|
||||||
Object.keys(rights).forEach(name => {
|
|
||||||
const rightsInfo = rights[name]
|
|
||||||
const definition = spec.securityDefinitions[name]
|
|
||||||
switch (definition.type) {
|
|
||||||
case 'basic':
|
|
||||||
const creds = `${rightsInfo.username}:${rightsInfo.password}`
|
|
||||||
const token = (typeof window !== 'undefined' && window.btoa)
|
|
||||||
? window.btoa(creds)
|
|
||||||
: new Buffer(creds).toString('base64')
|
|
||||||
req.header[resolveAuthHeaderName('Authorization')] = `Basic ${token}`
|
|
||||||
break
|
|
||||||
case 'oauth2':
|
|
||||||
req.header[resolveAuthHeaderName('Authorization')] = `Bearer ${rightsInfo.token}`
|
|
||||||
break
|
|
||||||
case 'apiKey':
|
|
||||||
if (definition.in === 'header') {
|
|
||||||
req.header[resolveAuthHeaderName(definition.name)] = rightsInfo.apiKey
|
|
||||||
} else if (definition.in === 'query') {
|
|
||||||
req.query[definition.name] = rightsInfo.apiKey
|
|
||||||
} else {
|
|
||||||
throw new Error(`Api key must be in header or query not '${definition.in}'`)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
throw new Error(`Security definition type '${definition.type}' not supported`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return req
|
|
||||||
}
|
|
||||||
|
|
||||||
function processResponse(req, response, attempt, options) {
|
|
||||||
const format = response.ok ? formatResponse : formatServiceError
|
|
||||||
const contentType = response.headers.get('content-type') || ''
|
|
||||||
|
|
||||||
let parse
|
|
||||||
if (response.status === 204) {
|
|
||||||
parse = Promise.resolve()
|
|
||||||
} else if (~contentType.indexOf('json')) {
|
|
||||||
parse = response.json()
|
|
||||||
} else if (~contentType.indexOf('octet-stream')) {
|
|
||||||
parse = response.blob()
|
|
||||||
} else if (~contentType.indexOf('text')) {
|
|
||||||
parse = response.text()
|
|
||||||
} else {
|
|
||||||
parse = Promise.resolve()
|
|
||||||
}
|
|
||||||
|
|
||||||
return parse
|
|
||||||
.then(data => format(response, data, options))
|
|
||||||
.then(res => {
|
|
||||||
if (options.processResponse) return options.processResponse(req, res, attempt)
|
|
||||||
else return Promise.resolve({ res })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatResponse(response, data, options) {
|
|
||||||
return { raw: response, data }
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatServiceError(response, data, options) {
|
|
||||||
if (options.formatServiceError) {
|
|
||||||
data = options.formatServiceError(response, data)
|
|
||||||
} else {
|
|
||||||
const serviceError = new ServiceError()
|
|
||||||
if (data) {
|
|
||||||
if (typeof data === 'string') serviceError.message = data
|
|
||||||
else {
|
|
||||||
if (data.message) serviceError.message = data.message
|
|
||||||
if (data.body) serviceError.body = data.body
|
|
||||||
else serviceError.body = data
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.code) serviceError.code = data.code
|
|
||||||
} else {
|
|
||||||
serviceError.message = response.statusText
|
|
||||||
}
|
|
||||||
serviceError.status = response.status
|
|
||||||
data = serviceError
|
|
||||||
}
|
|
||||||
return { raw: response, data, error: true }
|
|
||||||
}
|
|
||||||
|
|
||||||
function processError(req, error) {
|
|
||||||
const { processError } = options
|
|
||||||
const res = { res: { raw: {}, data: error, error: true } }
|
|
||||||
|
|
||||||
return Promise.resolve(processError ? processError(req, res) : res)
|
|
||||||
}
|
|
||||||
|
|
||||||
const COLLECTION_DELIM = { csv: ',', multi: '&', pipes: '|', ssv: ' ', tsv: '\t' }
|
|
||||||
|
|
||||||
export function formatArrayParam(array, format, name) {
|
|
||||||
if (!array) return
|
|
||||||
if (format === 'multi') return array.map(value => createQueryParam(name, value))
|
|
||||||
const delim = COLLECTION_DELIM[format]
|
|
||||||
if (!delim) throw new Error(`Invalid collection format '${format}'`)
|
|
||||||
return array.map(formatParam).join(delim)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function formatDate(date, format) {
|
|
||||||
if (!date) return
|
|
||||||
const str = date.toISOString()
|
|
||||||
return (format === 'date') ? str.split('T')[0] : str
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
// Auto-generated, edits will be overwritten
|
|
||||||
const spec = {
|
|
||||||
'host': 'localhost',
|
|
||||||
'schemes': [
|
|
||||||
'http'
|
|
||||||
],
|
|
||||||
'basePath': '',
|
|
||||||
'contentTypes': [
|
|
||||||
'application/json'
|
|
||||||
],
|
|
||||||
'accepts': [
|
|
||||||
'application/json'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
export default spec
|
|
@ -1,49 +1,39 @@
|
|||||||
import {AgentApi, ApiClient} from "../api/src/index.js";
|
import {AgentApi, ApiClient} from "../api/src/index.js";
|
||||||
|
|
||||||
export const getAgentApi = () => {
|
export const getAgentApi = () => {
|
||||||
return new AgentApi(new ApiClient(window.location.protocol+'//'+window.location.host));
|
return new AgentApi(new ApiClient("http://localhost:5173"));
|
||||||
}
|
}
|
||||||
|
|
||||||
export const shareHandler = (values) => {
|
export const createShare = (opts) => {
|
||||||
let api = getAgentApi();
|
switch(opts.shareMode) {
|
||||||
switch(values.shareMode) {
|
|
||||||
case "public":
|
case "public":
|
||||||
api.agentSharePublic({
|
getAgentApi().agentSharePublic(opts, (e, d) => {
|
||||||
target: values.target,
|
console.log("createShare", e, d);
|
||||||
backendMode: values.backendMode,
|
|
||||||
}, (err, data) => {
|
|
||||||
console.log(err, data);
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "private":
|
case "private":
|
||||||
api.agentSharePrivate({
|
getAgentApi().agentSharePrivate(opts, (e, d) => {
|
||||||
target: values.target,
|
console.log("createShare", e, d);
|
||||||
backendMode: values.backendMode,
|
})
|
||||||
}, (err, data) => {
|
|
||||||
console.log(err, data);
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const accessHandler = (values) => {
|
export const releaseShare = (opts) => {
|
||||||
getAgentApi().agentAccessPrivate({
|
getAgentApi().agentReleaseShare(opts, (e, d) => {
|
||||||
token: values.token,
|
console.log("releaseShare", e, d);
|
||||||
bindAddress: values.bindAddress,
|
})
|
||||||
}, (err, data) => {
|
|
||||||
console.log(err, data);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const releaseShare = (opts) => {
|
export const createAccess = (opts) => {
|
||||||
getAgentApi().agentReleaseShare(opts, (err, data) => {
|
getAgentApi().agentAccessPrivate(opts, (e, d) => {
|
||||||
console.log(data);
|
console.log("createAccess", e, d);
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const releaseAccess = (opts) => {
|
export const releaseAccess = (opts) => {
|
||||||
getAgentApi().agentReleaseAccess(opts, (err, data) => {
|
getAgentApi().agentReleaseAccess(opts, (e, d) => {
|
||||||
console.log(data);
|
console.log("releaseAccess", e, d);
|
||||||
});
|
})
|
||||||
}
|
}
|
@ -1,24 +1,20 @@
|
|||||||
const buildOverview = (status) => {
|
export const buildOverview = (status) => {
|
||||||
let overview = [];
|
let overview = [];
|
||||||
if(status) {
|
if(status) {
|
||||||
if(status.accesses) {
|
if(status.accesses) {
|
||||||
status.accesses.forEach(acc => {
|
status.accesses.forEach(acc => {
|
||||||
overview.push({
|
let o = structuredClone(acc);
|
||||||
type: "access",
|
o["type"] = "access";
|
||||||
v: structuredClone(acc)
|
overview.push(o);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if(status.shares) {
|
if(status.shares) {
|
||||||
status.shares.forEach(shr => {
|
status.shares.forEach(shr => {
|
||||||
overview.push({
|
let o = structuredClone(shr);
|
||||||
type: "share",
|
o["type"] = "share";
|
||||||
v: structuredClone(shr)
|
overview.push(o);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return overview;
|
return overview;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default buildOverview;
|
|
Loading…
x
Reference in New Issue
Block a user