mirror of
https://github.com/netbirdio/dashboard.git
synced 2026-09-23 00:30:43 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
899f56acdc | ||
|
|
dc2760d5ff | ||
|
|
5ae4fd31f1 | ||
|
|
54d9d7c768 | ||
|
|
3a73781fca | ||
|
|
f3c5d4df6a | ||
|
|
b4c9135c58 | ||
|
|
a280d9c67c | ||
|
|
5caf06b086 | ||
|
|
95af1c4e32 | ||
|
|
d247e7f3ed | ||
|
|
391e534253 | ||
|
|
a7f64d4a15 | ||
|
|
53ed514803 | ||
|
|
6cadce1598 | ||
|
|
c03d4b8a4b | ||
|
|
bc1053fbb4 | ||
|
|
d154bfb799 |
No files matched your search
@@ -43,6 +43,7 @@ fi
|
||||
|
||||
export AUTH_AUTHORITY=${AUTH_AUTHORITY:-https://$AUTH0_DOMAIN}
|
||||
export AUTH_CLIENT_ID=${AUTH_CLIENT_ID:-$AUTH0_CLIENT_ID}
|
||||
export AUTH_CLIENT_SECRET=${AUTH_CLIENT_SECRET}
|
||||
export AUTH_AUDIENCE=${AUTH_AUDIENCE:-$AUTH0_AUDIENCE}
|
||||
export AUTH_REDIRECT_URI=${AUTH_REDIRECT_URI}
|
||||
export AUTH_SILENT_REDIRECT_URI=${AUTH_SILENT_REDIRECT_URI}
|
||||
@@ -57,7 +58,7 @@ export NETBIRD_TOKEN_SOURCE=${NETBIRD_TOKEN_SOURCE:-accessToken}
|
||||
echo "NetBird latest version: ${NETBIRD_LATEST_VERSION}"
|
||||
|
||||
# replace ENVs in the config
|
||||
ENV_STR="\$\$USE_AUTH0 \$\$AUTH_AUDIENCE \$\$AUTH_AUTHORITY \$\$AUTH_CLIENT_ID \$\$AUTH_SUPPORTED_SCOPES \$\$NETBIRD_MGMT_API_ENDPOINT \$\$NETBIRD_MGMT_GRPC_API_ENDPOINT \$\$NETBIRD_HOTJAR_TRACK_ID \$\$AUTH_REDIRECT_URI \$\$AUTH_SILENT_REDIRECT_URI \$\$NETBIRD_TOKEN_SOURCE"
|
||||
ENV_STR="\$\$USE_AUTH0 \$\$AUTH_AUDIENCE \$\$AUTH_AUTHORITY \$\$AUTH_CLIENT_ID \$\$AUTH_CLIENT_SECRET \$\$AUTH_SUPPORTED_SCOPES \$\$NETBIRD_MGMT_API_ENDPOINT \$\$NETBIRD_MGMT_GRPC_API_ENDPOINT \$\$NETBIRD_HOTJAR_TRACK_ID \$\$AUTH_REDIRECT_URI \$\$AUTH_SILENT_REDIRECT_URI \$\$NETBIRD_TOKEN_SOURCE"
|
||||
|
||||
MAIN_JS=$(find /usr/share/nginx/html/static/js/main.*js)
|
||||
OIDC_TRUSTED_DOMAINS="/usr/share/nginx/html/OidcTrustedDomains.js"
|
||||
|
||||
Generated
+18
-18
@@ -10395,9 +10395,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
},
|
||||
@@ -15701,9 +15701,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tsconfig-paths/node_modules/json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
},
|
||||
@@ -16110,9 +16110,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/webpack": {
|
||||
"version": "5.74.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz",
|
||||
"integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==",
|
||||
"version": "5.76.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz",
|
||||
"integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==",
|
||||
"dependencies": {
|
||||
"@types/eslint-scope": "^3.7.3",
|
||||
"@types/estree": "^0.0.51",
|
||||
@@ -24411,9 +24411,9 @@
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA=="
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.1.0",
|
||||
@@ -28108,9 +28108,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
}
|
||||
@@ -28411,9 +28411,9 @@
|
||||
"integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w=="
|
||||
},
|
||||
"webpack": {
|
||||
"version": "5.74.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz",
|
||||
"integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==",
|
||||
"version": "5.76.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz",
|
||||
"integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==",
|
||||
"requires": {
|
||||
"@types/eslint-scope": "^3.7.3",
|
||||
"@types/estree": "^0.0.51",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="29.435" height="7.636" viewBox="0 0 29.435 7.636">
|
||||
<path id="direct_bi" d="M3.64,8.158-.178,4.34,3.64.522,4.3,1.17l-2.7,2.7h25.89l-2.7-2.7.656-.648L29.257,4.34,27.213,6.384,25.439,8.158,24.783,7.5l2.7-2.693H1.595L4.3,7.5Z" transform="translate(0.178 -0.522)" fill="#1e429f"/>
|
||||
<svg width="39" height="6" viewBox="0 0 39 6" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.451731 2.66267C0.315048 2.79935 0.315048 3.02096 0.451731 3.15764L2.67912 5.38503C2.8158 5.52171 3.03741 5.52171 3.17409 5.38503C3.31078 5.24835 3.31078 5.02674 3.17409 4.89006L1.19419 2.91016L3.17409 0.930257C3.31078 0.793574 3.31078 0.571966 3.17409 0.435282C3.03741 0.298599 2.8158 0.298599 2.67912 0.435282L0.451731 2.66267ZM38.3807 3.15764C38.5174 3.02096 38.5174 2.79935 38.3807 2.66267L36.1533 0.435282C36.0166 0.298599 35.795 0.298599 35.6583 0.435282C35.5216 0.571966 35.5216 0.793574 35.6583 0.930257L37.6382 2.91016L35.6583 4.89006C35.5216 5.02674 35.5216 5.24835 35.6583 5.38503C35.795 5.52171 36.0166 5.52171 36.1533 5.38503L38.3807 3.15764ZM0.699219 3.26016H38.1332V2.56016H0.699219V3.26016Z" fill="#03543F"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 837 B |
@@ -1,3 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="29.497" height="7.636" viewBox="0 0 29.497 7.636">
|
||||
<path id="direct_out" d="M26.589,8l-.656-.656,2.7-2.693H.91V3.713H28.635l-2.7-2.7.656-.648,3.818,3.818Z" transform="translate(-0.91 -0.364)" fill="#03543f"/>
|
||||
<svg width="39" height="6" viewBox="0 0 39 6" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M38.3807 3.15764C38.5174 3.02096 38.5174 2.79935 38.3807 2.66267L36.1533 0.435282C36.0166 0.298599 35.795 0.298599 35.6583 0.435282C35.5216 0.571966 35.5216 0.793574 35.6583 0.930257L37.6382 2.91016L35.6583 4.89006C35.5216 5.02674 35.5216 5.24835 35.6583 5.38503C35.795 5.52171 36.0166 5.52171 36.1533 5.38503L38.3807 3.15764ZM0.699219 3.26016H38.1332V2.56016H0.699219V3.26016Z" fill="#1E429F"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 265 B After Width: | Height: | Size: 506 B |
+672
-399
File diff suppressed because it is too large.
Load diff
+893
-525
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+601
-539
File diff suppressed because it is too large.
Load diff
+385
-227
File diff suppressed because it is too large.
Load diff
@@ -49,7 +49,7 @@ export const AddPeerPopup: React.FC<Props> = ({
|
||||
},
|
||||
{
|
||||
key: "3",
|
||||
label: <span><AppleFilled/>macOS</span>,
|
||||
label: <span><AppleFilled/>MacOS</span>,
|
||||
children: <MacTab/>,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import React, {useState} from 'react';
|
||||
|
||||
import {Button, Typography} from "antd";
|
||||
import {Button, Divider, Row, Tooltip, Typography} from "antd";
|
||||
import TabSteps from "./TabSteps";
|
||||
import {StepCommand} from "./types"
|
||||
import {formatNetBirdUP} from "./common"
|
||||
import {Collapse} from "antd";
|
||||
import SyntaxHighlighter from "react-syntax-highlighter";
|
||||
const { Panel } = Collapse;
|
||||
import {QuestionCircleOutlined} from "@ant-design/icons";
|
||||
|
||||
const {Panel} = Collapse;
|
||||
|
||||
const {Text} = Typography;
|
||||
|
||||
@@ -15,10 +17,28 @@ export const LinuxTab = () => {
|
||||
const [quickSteps, setQuickSteps] = useState([
|
||||
{
|
||||
key: 1,
|
||||
title: 'Download and run installer:',
|
||||
title: (
|
||||
<Row>
|
||||
<Text>Download and run MacOS installer: </Text>
|
||||
<Tooltip title={
|
||||
<text>If you don't know what chip your Mac has, you can find out by clicking on the Apple logo
|
||||
in the top left corner of your screen and selecting 'About This Mac'. For more information
|
||||
click <a href="https://support.apple.com/en-us/HT211814" target="_blank">here</a></text>
|
||||
}
|
||||
className={"ant-form-item-tooltip"}>
|
||||
<QuestionCircleOutlined
|
||||
style={{color: "rgba(0, 0, 0, 0.45)", cursor: "help", marginLeft: "3px"}}/>
|
||||
</Tooltip>
|
||||
</Row>
|
||||
|
||||
),
|
||||
commands: (
|
||||
<Button style={{marginTop: "5px"}} type="primary" href="https://pkgs.netbird.io/windows/x64"
|
||||
target="_blank">Download NetBird</Button>
|
||||
<Row style={{paddingTop: "5px"}}>
|
||||
<Button style={{marginRight: "10px"}} type="primary" href="https://pkgs.netbird.io/macos/amd64">Download
|
||||
for Intel</Button>
|
||||
<Button style={{marginRight: "10px"}} type="default" href="https://pkgs.netbird.io/macos/arm64">Download
|
||||
for M1 & M2</Button>
|
||||
</Row>
|
||||
),
|
||||
copied: false
|
||||
} as StepCommand,
|
||||
@@ -78,35 +98,38 @@ export const LinuxTab = () => {
|
||||
showCopyButton: true
|
||||
} as StepCommand
|
||||
])
|
||||
|
||||
return (
|
||||
<div style={{marginTop: 10}}>
|
||||
<Text style={{fontWeight: "bold"}}>
|
||||
Install with one command
|
||||
Install on MacOS
|
||||
</Text>
|
||||
<div style={{fontSize: ".85em", marginTop: 5, marginBottom: 25}}>
|
||||
<SyntaxHighlighter language="bash">
|
||||
curl -fsSL https://pkgs.netbird.io/install.sh | sh
|
||||
</SyntaxHighlighter>
|
||||
</div>
|
||||
<Text style={{fontWeight: "bold"}}>
|
||||
Or install manually with HomeBrew
|
||||
</Text>
|
||||
<div style={{marginTop: 5}}>
|
||||
<TabSteps stepsItems={steps}/>
|
||||
</div>
|
||||
</div>
|
||||
/*<div style={{marginTop: 5}}>
|
||||
<div style={{marginTop: 5, marginBottom: 5}}>
|
||||
<TabSteps stepsItems={quickSteps}/>
|
||||
</div>*/
|
||||
/*<div style={{marginTop: 10}}>
|
||||
<Text style={{fontWeight: "bold"}}>
|
||||
Install on macOS with Homebrew
|
||||
</Text>
|
||||
<div style={{marginTop: 5}}>
|
||||
<TabSteps stepsItems={steps}/>
|
||||
</div>
|
||||
</div>*/
|
||||
<div style={{marginTop: 0}}/>
|
||||
{/*<Divider style={{marginTop: "5px"}} />*/}
|
||||
<Collapse bordered={false} style={{backgroundColor: "unset"}}>
|
||||
<Panel className="CustomPopupCollapse" header={<Text strong={true}>Or install via command line</Text>}
|
||||
key="1">
|
||||
<div style={{marginLeft: "25px"}}>
|
||||
<Text style={{fontWeight: "bold"}}>
|
||||
Install with one command
|
||||
</Text>
|
||||
<div style={{fontSize: ".85em", marginTop: 5, marginBottom: 25}}>
|
||||
<SyntaxHighlighter language="bash">
|
||||
curl -fsSL https://pkgs.netbird.io/install.sh | sh
|
||||
</SyntaxHighlighter>
|
||||
</div>
|
||||
<Text style={{fontWeight: "bold"}}>
|
||||
Or install manually with HomeBrew
|
||||
</Text>
|
||||
<div style={{marginTop: 5}}>
|
||||
<TabSteps stepsItems={steps}/>
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
</Collapse>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"auth0Auth": "$USE_AUTH0",
|
||||
"authAuthority": "$AUTH_AUTHORITY",
|
||||
"authClientId": "$AUTH_CLIENT_ID",
|
||||
"authClientSecret": "$AUTH_CLIENT_SECRET",
|
||||
"authScopesSupported": "$AUTH_SUPPORTED_SCOPES",
|
||||
"authAudience": "$AUTH_AUDIENCE",
|
||||
|
||||
|
||||
+2
-1
@@ -28,8 +28,9 @@ export function getConfig() {
|
||||
|
||||
return {
|
||||
auth0Auth: configJson.auth0Auth == "true", //due to substitution we can't use boolean in the config
|
||||
authority: configJson.authAuthority,
|
||||
authority: configJson.authAuthority.replace(/\/+$/, ''),
|
||||
clientId: configJson.authClientId,
|
||||
clientSecret: configJson.authClientSecret,
|
||||
scopesSupported: configJson.authScopesSupported,
|
||||
apiOrigin: configJson.apiOrigin,
|
||||
grpcApiOrigin: configJson.grpcApiOrigin,
|
||||
|
||||
+38
-9
@@ -5,6 +5,7 @@ body {
|
||||
background-color: #f0f2f5;
|
||||
}
|
||||
|
||||
|
||||
.ant-layout-header {
|
||||
background: #fff;
|
||||
padding: 0;
|
||||
@@ -23,12 +24,12 @@ body {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.ant-menu-horizontal > .ant-menu-item a {
|
||||
.ant-menu-horizontal>.ant-menu-item a {
|
||||
color: rgba(107, 114, 128, 1);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ant-menu-horizontal > .ant-menu-item-selected a {
|
||||
.ant-menu-horizontal>.ant-menu-item-selected a {
|
||||
color: rgba(17, 24, 39, 1);
|
||||
}
|
||||
|
||||
@@ -47,23 +48,25 @@ body {
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.space-align-block {
|
||||
flex: none;
|
||||
margin: 8px 4px;
|
||||
padding: 4px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.space-align-block .mock-block {
|
||||
display: inline-block;
|
||||
padding: 32px 8px 16px;
|
||||
background: rgba(150, 150, 150, 0.2);
|
||||
}
|
||||
|
||||
.bg-indigo-600{
|
||||
.bg-indigo-600 {
|
||||
background-color: rgb(79, 70, 229);
|
||||
}
|
||||
|
||||
.card-table-no-placeholder .ant-table-placeholder{
|
||||
.card-table-no-placeholder .ant-table-placeholder {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -75,9 +78,10 @@ body {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.card-table .ant-table-ping-left:not(.ant-table-has-fix-left) .ant-table-container::before {
|
||||
.card-table .ant-table-ping-left:not(.ant-table-has-fix-left) .ant-table-container::before {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.card-table .ant-table-ping-right:not(.ant-table-has-fix-right) .ant-table-container::after {
|
||||
box-shadow: none;
|
||||
}
|
||||
@@ -119,15 +123,17 @@ body {
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
.ant-steps-item-icon{
|
||||
.ant-steps-item-icon {
|
||||
background: #EBEBEB !important;
|
||||
border-color: #EBEBEB !important;
|
||||
}
|
||||
.ant-steps-icon-dot{
|
||||
|
||||
.ant-steps-icon-dot {
|
||||
background: #EBEBEB !important;
|
||||
border-color: #EBEBEB !important;
|
||||
}
|
||||
.ant-steps-icon {
|
||||
|
||||
.ant-steps-icon {
|
||||
background: #EBEBEB !important;
|
||||
border: none;
|
||||
color: black !important;
|
||||
@@ -145,10 +151,33 @@ td.non-highlighted-table-column {
|
||||
background-color: #FFFFFF !important;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr.ant-table-row:hover > td {
|
||||
.ant-table-tbody>tr.ant-table-row:hover>td {
|
||||
background: #FAFAFA !important;
|
||||
}
|
||||
|
||||
.ant-table-thead .ant-table-cell {
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
.CustomPopupCollapse .ant-collapse-content-box,
|
||||
.CustomPopupCollapse .ant-collapse-header {
|
||||
padding-left: 0 !important;
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
.system-info-panel .ant-collapse-header {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.system-info-panel .ant-collapse-content-box {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.peers-form .ant-layout-header {
|
||||
line-height: 25px;
|
||||
height: auto;
|
||||
min-height: auto;
|
||||
padding-bottom: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
+2
-1
@@ -34,7 +34,8 @@ const providerConfig = {
|
||||
// service_worker_relative_url:'/OidcServiceWorker.js',
|
||||
service_worker_only: false,
|
||||
authority_configuration: config.auth0Auth ? auth0AuthorityConfig : undefined,
|
||||
...(config.audience ? {extras: {audience: config.audience}} : null)
|
||||
...(config.audience ? {extras: {audience: config.audience}} : null),
|
||||
...(config.clientSecret ? {token_request_extras: {client_secret: config.clientSecret}} : null)
|
||||
};
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
|
||||
+3
-1
@@ -5,6 +5,7 @@ import { composeWithDevTools } from 'redux-devtools-extension';
|
||||
import { sagas as peerSagas } from './peer';
|
||||
import { sagas as setupKeySagas } from './setup-key';
|
||||
import { sagas as userSagas } from './user';
|
||||
import { sagas as policySagas } from './policy';
|
||||
import { sagas as ruleSagas } from './rule';
|
||||
import { sagas as groupSagas } from './group';
|
||||
import { sagas as routeSagas } from './route';
|
||||
@@ -28,6 +29,7 @@ sagaMiddleware.run(peerSagas);
|
||||
sagaMiddleware.run(setupKeySagas);
|
||||
sagaMiddleware.run(userSagas);
|
||||
sagaMiddleware.run(ruleSagas);
|
||||
sagaMiddleware.run(policySagas);
|
||||
sagaMiddleware.run(groupSagas);
|
||||
sagaMiddleware.run(routeSagas);
|
||||
sagaMiddleware.run(nameserverGroupSagas);
|
||||
@@ -36,4 +38,4 @@ sagaMiddleware.run(dnsSettingsSagas);
|
||||
sagaMiddleware.run(accountSagas);
|
||||
sagaMiddleware.run(personalAccessTokenSagas);
|
||||
|
||||
export { apiClient, rootReducer, store };
|
||||
export { apiClient, rootReducer, store };
|
||||
@@ -0,0 +1,34 @@
|
||||
import { ActionType, createAction, createAsyncAction } from 'typesafe-actions';
|
||||
import { Policy, PolicyToSave } from './types';
|
||||
import { ApiError, CreateResponse, DeleteResponse, RequestPayload } from '../../services/api-client/types';
|
||||
|
||||
const actions = {
|
||||
getPolicies: createAsyncAction(
|
||||
'GET_POLICIES_REQUEST',
|
||||
'GET_POLICIES_SUCCESS',
|
||||
'GET_POLICIES_FAILURE',
|
||||
)<RequestPayload<null>, Policy[], ApiError>(),
|
||||
|
||||
savePolicy: createAsyncAction(
|
||||
'SAVE_POLICY_REQUEST',
|
||||
'SAVE_POLICY_SUCCESS',
|
||||
'SAVE_POLICY_FAILURE',
|
||||
)<RequestPayload<PolicyToSave>, CreateResponse<Policy | null>, CreateResponse<Policy | null>>(),
|
||||
setSavedPolicy: createAction('SET_CREATE_POLICY')<CreateResponse<Policy | null>>(),
|
||||
resetSavedPolicy: createAction('RESET_CREATE_POLICY')<null>(),
|
||||
|
||||
deletePolicy: createAsyncAction(
|
||||
'DELETE_POLICY_REQUEST',
|
||||
'DELETE_POLICY_SUCCESS',
|
||||
'DELETE_POLICY_FAILURE'
|
||||
)<RequestPayload<string>, DeleteResponse<string | null>, DeleteResponse<string | null>>(),
|
||||
setDeletedPolicy: createAction('SET_DELETED_POLICY')<DeleteResponse<string | null>>(),
|
||||
resetDeletedPolicy: createAction('RESET_DELETED_POLICY')<null>(),
|
||||
removePolicy: createAction('REMOVE_POLICY')<string>(),
|
||||
|
||||
setPolicy: createAction('SET_POLICY')<Policy>(),
|
||||
setSetupNewPolicyVisible: createAction('SET_SETUP_NEW_POLICY_VISIBLE')<boolean>()
|
||||
};
|
||||
|
||||
export type ActionTypes = ActionType<typeof actions>;
|
||||
export default actions;
|
||||
@@ -0,0 +1,7 @@
|
||||
import actions, { ActionTypes as _actionTypes } from './actions';
|
||||
import reducer from './reducer';
|
||||
import sagas from './sagas';
|
||||
|
||||
export type ActionTypes = _actionTypes;
|
||||
|
||||
export { actions, reducer, sagas };
|
||||
@@ -0,0 +1,89 @@
|
||||
import { createReducer } from 'typesafe-actions';
|
||||
import { combineReducers } from 'redux';
|
||||
import { Policy } from './types';
|
||||
import actions, { ActionTypes } from './actions';
|
||||
import { ApiError, DeleteResponse, CreateResponse } from "../../services/api-client/types";
|
||||
|
||||
type StateType = Readonly<{
|
||||
data: Policy[] | null;
|
||||
policy: Policy | null;
|
||||
loading: boolean;
|
||||
failed: ApiError | null;
|
||||
saving: boolean;
|
||||
deletePolicy: DeleteResponse<string | null>;
|
||||
savedPolicy: CreateResponse<Policy | null>;
|
||||
setupNewPolicyVisible: boolean
|
||||
}>;
|
||||
|
||||
const initialState: StateType = {
|
||||
data: [],
|
||||
policy: null,
|
||||
loading: false,
|
||||
failed: null,
|
||||
saving: false,
|
||||
deletePolicy: <DeleteResponse<string | null>>{
|
||||
loading: false,
|
||||
success: false,
|
||||
failure: false,
|
||||
error: null,
|
||||
data: null
|
||||
},
|
||||
savedPolicy: <CreateResponse<Policy | null>>{
|
||||
loading: false,
|
||||
success: false,
|
||||
failure: false,
|
||||
error: null,
|
||||
data: null
|
||||
},
|
||||
setupNewPolicyVisible: false
|
||||
};
|
||||
|
||||
const data = createReducer<Policy[], ActionTypes>(initialState.data as Policy[])
|
||||
.handleAction(actions.getPolicies.success, (_, action) => action.payload)
|
||||
.handleAction(actions.getPolicies.failure, () => []);
|
||||
|
||||
const policy = createReducer<Policy, ActionTypes>(initialState.policy as Policy)
|
||||
.handleAction(actions.setPolicy, (store, action) => action.payload);
|
||||
|
||||
const loading = createReducer<boolean, ActionTypes>(initialState.loading)
|
||||
.handleAction(actions.getPolicies.request, () => true)
|
||||
.handleAction(actions.getPolicies.success, () => false)
|
||||
.handleAction(actions.getPolicies.failure, () => false);
|
||||
|
||||
const failed = createReducer<ApiError | null, ActionTypes>(initialState.failed)
|
||||
.handleAction(actions.getPolicies.request, () => null)
|
||||
.handleAction(actions.getPolicies.success, () => null)
|
||||
.handleAction(actions.getPolicies.failure, (store, action) => action.payload);
|
||||
|
||||
const saving = createReducer<boolean, ActionTypes>(initialState.saving)
|
||||
.handleAction(actions.getPolicies.request, () => true)
|
||||
.handleAction(actions.getPolicies.success, () => false)
|
||||
.handleAction(actions.getPolicies.failure, () => false);
|
||||
|
||||
const deletedPolicy = createReducer<DeleteResponse<string | null>, ActionTypes>(initialState.deletePolicy)
|
||||
.handleAction(actions.deletePolicy.request, () => initialState.deletePolicy)
|
||||
.handleAction(actions.deletePolicy.success, (store, action) => action.payload)
|
||||
.handleAction(actions.deletePolicy.failure, (store, action) => action.payload)
|
||||
.handleAction(actions.setDeletedPolicy, (store, action) => action.payload)
|
||||
.handleAction(actions.resetDeletedPolicy, () => initialState.deletePolicy)
|
||||
|
||||
const savedPolicy = createReducer<CreateResponse<Policy | null>, ActionTypes>(initialState.savedPolicy)
|
||||
.handleAction(actions.savePolicy.request, () => initialState.savedPolicy)
|
||||
.handleAction(actions.savePolicy.success, (store, action) => action.payload)
|
||||
.handleAction(actions.savePolicy.failure, (store, action) => action.payload)
|
||||
.handleAction(actions.setSavedPolicy, (store, action) => action.payload)
|
||||
.handleAction(actions.resetSavedPolicy, () => initialState.savedPolicy)
|
||||
|
||||
const setupNewPolicyVisible = createReducer<boolean, ActionTypes>(initialState.setupNewPolicyVisible)
|
||||
.handleAction(actions.setSetupNewPolicyVisible, (store, action) => action.payload)
|
||||
|
||||
export default combineReducers({
|
||||
data,
|
||||
policy,
|
||||
loading,
|
||||
failed,
|
||||
saving,
|
||||
deletedPolicy,
|
||||
savedPolicy,
|
||||
setupNewPolicyVisible
|
||||
});
|
||||
@@ -0,0 +1,223 @@
|
||||
import { all, call, put, select, takeLatest } from "redux-saga/effects";
|
||||
import {
|
||||
ApiError,
|
||||
ApiResponse,
|
||||
CreateResponse,
|
||||
DeleteResponse,
|
||||
} from "../../services/api-client/types";
|
||||
import { Policy, PolicyRule } from "./types";
|
||||
import service from "./service";
|
||||
import serviceGroup from "../group/service";
|
||||
import actions from "./actions";
|
||||
import { actions as groupActions } from "../group";
|
||||
import { Group } from "../group/types";
|
||||
|
||||
export function* getPolicies(
|
||||
action: ReturnType<typeof actions.getPolicies.request>
|
||||
): Generator {
|
||||
try {
|
||||
yield put(
|
||||
actions.setDeletedPolicy({
|
||||
loading: false,
|
||||
success: false,
|
||||
failure: false,
|
||||
error: null,
|
||||
data: null,
|
||||
} as DeleteResponse<string | null>)
|
||||
);
|
||||
|
||||
const effect = yield call(service.getPolicies, action.payload);
|
||||
const response = effect as ApiResponse<Policy[]>;
|
||||
|
||||
yield put(actions.getPolicies.success(response.body));
|
||||
} catch (err) {
|
||||
yield put(actions.getPolicies.failure(err as ApiError));
|
||||
}
|
||||
}
|
||||
|
||||
export function* setCreatedPolicy(
|
||||
action: ReturnType<typeof actions.setSavedPolicy>
|
||||
): Generator {
|
||||
yield put(actions.setSavedPolicy(action.payload));
|
||||
}
|
||||
|
||||
function getNewGroupIds(dataString: string[], responses: Group[]): string[] {
|
||||
return responses
|
||||
.filter((r) => dataString.includes(r.name))
|
||||
.map((r) => r.id || "");
|
||||
}
|
||||
|
||||
export function* savePolicy(
|
||||
action: ReturnType<typeof actions.savePolicy.request>
|
||||
): Generator {
|
||||
try {
|
||||
yield put(
|
||||
actions.setSavedPolicy({
|
||||
loading: true,
|
||||
success: false,
|
||||
failure: false,
|
||||
error: null,
|
||||
data: null,
|
||||
} as CreateResponse<Policy | null>)
|
||||
);
|
||||
|
||||
const policyToSave = action.payload.payload;
|
||||
const groupsToSave = policyToSave.groupsToSave
|
||||
? policyToSave.groupsToSave
|
||||
: [];
|
||||
const responsesGroup = yield all(
|
||||
groupsToSave.map((g) =>
|
||||
call(serviceGroup.createGroup, {
|
||||
getAccessTokenSilently: action.payload.getAccessTokenSilently,
|
||||
payload: { name: g },
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
const resGroups = (responsesGroup as ApiResponse<Policy>[])
|
||||
.filter((r) => r.statusCode === 200)
|
||||
.map((r) => r.body as Group);
|
||||
|
||||
const currentGroups = [
|
||||
...((yield select((state) => state.group.data)) as Policy[]),
|
||||
];
|
||||
const newGroups = [...currentGroups, ...resGroups];
|
||||
yield put(groupActions.getGroups.success(newGroups));
|
||||
|
||||
const newSources = getNewGroupIds(
|
||||
policyToSave.sourcesNoId ? policyToSave.sourcesNoId : [],
|
||||
resGroups
|
||||
);
|
||||
const newDestinations = getNewGroupIds(
|
||||
policyToSave.destinationsNoId ? policyToSave.destinationsNoId : [],
|
||||
resGroups
|
||||
);
|
||||
|
||||
const payloadToSave = {
|
||||
getAccessTokenSilently: action.payload.getAccessTokenSilently,
|
||||
payload: {
|
||||
name: policyToSave.name,
|
||||
description: policyToSave.description,
|
||||
enabled: policyToSave.enabled,
|
||||
query: policyToSave.query,
|
||||
} as Policy,
|
||||
};
|
||||
if (policyToSave.rules.length > 0) {
|
||||
payloadToSave.payload.rules = [];
|
||||
}
|
||||
policyToSave.rules.forEach((r) => {
|
||||
payloadToSave.payload.rules.push({
|
||||
name: r.name,
|
||||
description: r.description,
|
||||
enabled: r.enabled,
|
||||
sources: [...(r.sources as string[]), ...newSources],
|
||||
destinations: [...(r.destinations as string[]), ...newDestinations],
|
||||
bidirectional: r.bidirectional,
|
||||
protocol: r.protocol,
|
||||
ports: r.ports,
|
||||
action: r.action,
|
||||
} as PolicyRule);
|
||||
});
|
||||
|
||||
let effect;
|
||||
if (!policyToSave.id) {
|
||||
effect = yield call(service.createPolicy, payloadToSave);
|
||||
} else {
|
||||
payloadToSave.payload.id = policyToSave.id;
|
||||
effect = yield call(service.editPolicy, payloadToSave);
|
||||
}
|
||||
|
||||
const response = effect as ApiResponse<Policy>;
|
||||
|
||||
yield put(
|
||||
actions.savePolicy.success({
|
||||
loading: false,
|
||||
success: true,
|
||||
failure: false,
|
||||
error: null,
|
||||
data: response.body,
|
||||
} as CreateResponse<Policy | null>)
|
||||
);
|
||||
|
||||
yield put(
|
||||
groupActions.getGroups.request({
|
||||
getAccessTokenSilently: action.payload.getAccessTokenSilently,
|
||||
payload: null,
|
||||
})
|
||||
);
|
||||
yield put(
|
||||
actions.getPolicies.request({
|
||||
getAccessTokenSilently: action.payload.getAccessTokenSilently,
|
||||
payload: null,
|
||||
})
|
||||
);
|
||||
} catch (err) {
|
||||
yield put(
|
||||
actions.savePolicy.failure({
|
||||
loading: false,
|
||||
success: false,
|
||||
failure: true,
|
||||
error: err as ApiError,
|
||||
data: null,
|
||||
} as CreateResponse<Policy | null>)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function* setDeletePolicy(
|
||||
action: ReturnType<typeof actions.setDeletedPolicy>
|
||||
): Generator {
|
||||
yield put(actions.setDeletedPolicy(action.payload));
|
||||
}
|
||||
|
||||
export function* deletePolicy(
|
||||
action: ReturnType<typeof actions.deletePolicy.request>
|
||||
): Generator {
|
||||
try {
|
||||
yield call(actions.setDeletedPolicy, {
|
||||
loading: true,
|
||||
success: false,
|
||||
failure: false,
|
||||
error: null,
|
||||
data: null,
|
||||
} as DeleteResponse<string | null>);
|
||||
|
||||
const effect = yield call(service.deletedPolicy, action.payload);
|
||||
const response = effect as ApiResponse<any>;
|
||||
|
||||
yield put(
|
||||
actions.deletePolicy.success({
|
||||
loading: false,
|
||||
success: true,
|
||||
failure: false,
|
||||
error: null,
|
||||
data: response.body,
|
||||
} as DeleteResponse<string | null>)
|
||||
);
|
||||
|
||||
const policies = (yield select((state) => state.policy.data)) as Policy[];
|
||||
yield put(
|
||||
actions.getPolicies.success(
|
||||
policies.filter((p: Policy) => p.id !== action.payload.payload)
|
||||
)
|
||||
);
|
||||
} catch (err) {
|
||||
yield put(
|
||||
actions.deletePolicy.failure({
|
||||
loading: false,
|
||||
success: false,
|
||||
failure: false,
|
||||
error: err as ApiError,
|
||||
data: null,
|
||||
} as DeleteResponse<string | null>)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default function* sagas(): Generator {
|
||||
yield all([
|
||||
takeLatest(actions.getPolicies.request, getPolicies),
|
||||
takeLatest(actions.savePolicy.request, savePolicy),
|
||||
takeLatest(actions.deletePolicy.request, deletePolicy),
|
||||
]);
|
||||
}
|
||||
Loaded 20 of 31 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user